btrfs-ioctl

package: btrfs-progs

title: btrfs-ioctl(2)

summary: documentation about btrfs ioctls

text:
# btrfs-ioctl(2)

## NAME
btrfs-ioctl - documentation about btrfs ioctls

## NAME
btrfs-ioctl - documentation for the ioctl interface to btrfs

## DESCRIPTION
The ioctl() system call is a way how to request custom actions performed on a filesystem beyond the standard interfaces (like syscalls). An ioctl is specified by a number and an associated data structure that implement a feature, usually not available in other filesystems. The number of ioctls grows over time and in some cases get promoted to a VFS-level ioctl once other filesystems adopt the functionality. Backward compatibility is maintained and a formerly private ioctl number could become available on the VFS level.

## OVERVIEW
The ioctls are defined by a number and associated with a data structure that contains further information. All ioctls use file descriptor (fd) as a reference point, it could be the filesystem or a directory inside the filesystem.

An ioctl can be used in the following schematic way:

```
struct btrfs_ioctl_args args;
memset(&args, 0, sizeof(args));
args.key = value;
ret = ioctl(fd, BTRFS_IOC_NUMBER, &args);
```

The fd is the entry point to the filesystem and for most ioctls it does not matter which directory is that. A distinction between files and directories sometimes matter, when it matters it's explicitly mentioned. The args is the associated data structure for the request. It's strongly recommended to initialize the whole structure to zeros as this is future-proof when the ioctl gets further extensions. Not doing that could lead to mismatch of old userspace and new kernel versions, or vice versa. The BTRFS_IOC_NUMBER is says which operation should be done on the given arguments. Some ioctls take a specific data structure, some of them share a common one, no argument structure ioctls exist too. The data passed to an ioctl can be input, output or both.

The library libbtrfsutil wraps a few ioctls for convenience. Using raw ioctls is not discouraged but may be cumbersome though it does not need additional library dependency. Backward compatibility is guaranteed and incompatible changes usually lead to a new version of the ioctl. Enhancements of existing ioctls can happen and depend on additional flags to be set. Zeroed unused space is commonly understood as a mechanism to communicate the compatibility between kernel and userspace and thus zeroing is really important. In exceptional cases this is not enough and further flags need to be passed to distinguish between zero as implicit unused initialization and a valid zero value. Such cases are documented.

File descriptors of regular files are obtained by int fd = open(), directories opened as DIR *dir = opendir() can be converted to the corresponding file descriptor by fd = dirfd(dir).

## LIST OF IOCTLS
Name

Description

Data

BTRFS_IOC_SNAP_CREATE

(obsolete) create a snapshot of a subvolume

struct btrfs_ioctl_vol_args

BTRFS_IOC_DEFRAG

BTRFS_IOC_RESIZE

BTRFS_IOC_SCAN_DEV

scan and register a given device path with filesystem module

struct btrfs_ioctl_vol_args

BTRFS_IOC_SYNC

Sync the filesystem, possibly process queued up work

NULL

BTRFS_IOC_CLONE

BTRFS_IOC_ADD_DEV

add a device to the filesystem by path

struct btrfs_ioctl_vol_args

BTRFS_IOC_RM_DEV

delete a device from the filesystem by path

struct btrfs_ioctl_vol_args

BTRFS_IOC_BALANCE

BTRFS_IOC_CLONE_RANGE

BTRFS_IOC_SUBVOL_CREATE

(obsolete) create a subvolume

struct btrfs_ioctl_vol_args

BTRFS_IOC_SNAP_DESTROY

(obsolete) delete a subvolume

struct btrfs_ioctl_vol_args

BTRFS_IOC_DEFRAG_RANGE

BTRFS_IOC_TREE_SEARCH

BTRFS_IOC_TREE_SEARCH_V2

BTRFS_IOC_INO_LOOKUP

resolve inode number to path, or lookup containing subvolume id

struct btrfs_ioctl_ino_lookup_args

BTRFS_IOC_DEFAULT_SUBVOL

set the default subvolume id

uint64_t

BTRFS_IOC_SPACE_INFO

BTRFS_IOC_START_SYNC

BTRFS_IOC_WAIT_SYNC

BTRFS_IOC_SNAP_CREATE_V2

create a snapshot of a subvolume

struct btrfs_ioctl_vol_args_v2

BTRFS_IOC_SUBVOL_CREATE_V2

create a subvolume

struct btrfs_ioctl_vol_args_v2

BTRFS_IOC_SUBVOL_GETFLAGS

get flags of a subvolume

uint64_t

BTRFS_IOC_SUBVOL_SETFLAGS

set flags of a subvolume

uint64_t

BTRFS_IOC_SCRUB

BTRFS_IOC_SCRUB_CANCEL

BTRFS_IOC_SCRUB_PROGRESS

BTRFS_IOC_DEV_INFO

get information about a device (UUIDs, used size, total size)

struct btrfs_ioctl_dev_info_args

BTRFS_IOC_FS_INFO

get information about filesystem (device count, fsid, ...)

struct btrfs_ioctl_fs_info_args

BTRFS_IOC_BALANCE_V2

BTRFS_IOC_BALANCE_CTL

BTRFS_IOC_BALANCE_PROGRESS

BTRFS_IOC_INO_PATHS

BTRFS_IOC_LOGICAL_INO

BTRFS_IOC_SET_RECEIVED_SUBVOL

BTRFS_IOC_SEND

BTRFS_IOC_DEVICES_READY

BTRFS_IOC_QUOTA_CTL

BTRFS_IOC_QGROUP_ASSIGN

BTRFS_IOC_QGROUP_CREATE

BTRFS_IOC_QGROUP_LIMIT

BTRFS_IOC_QUOTA_RESCAN

BTRFS_IOC_QUOTA_RESCAN_STATUS

BTRFS_IOC_QUOTA_RESCAN_WAIT

BTRFS_IOC_GET_FSLABEL

read filesystem label

char buffer[BTRFS_LABEL_SIZE]

BTRFS_IOC_SET_FSLABEL

set the filesystem label

char buffer[BTRFS_LABEL_SIZE]

BTRFS_IOC_GET_DEV_STATS

BTRFS_IOC_DEV_REPLACE

BTRFS_IOC_FILE_EXTENT_SAME

BTRFS_IOC_GET_FEATURES

get features set on the filesystem

struct btrfs_ioctl_feature_flags

BTRFS_IOC_SET_FEATURES

set features on the filesystem

struct btrfs_ioctl_feature_flags

BTRFS_IOC_GET_SUPPORTED_FEATURES

get available filesystem feature sets

struct btrfs_ioctl_feature_flags[3]

BTRFS_IOC_RM_DEV_V2

BTRFS_IOC_LOGICAL_INO_V2

BTRFS_IOC_GET_SUBVOL_INFO

get information about a subvolume

struct btrfs_ioctl_get_subvol_info_args

BTRFS_IOC_GET_SUBVOL_ROOTREF

BTRFS_IOC_INO_LOOKUP_USER

BTRFS_IOC_SNAP_DESTROY_V2

destroy a (snapshot or regular) subvolume

struct btrfs_ioctl_vol_args_v2

BTRFS_IOC_ENCODED_READ

BTRFS_IOC_ENCODED_WRITE

BTRFS_IOC_SUBVOL_SYNC_WAIT

Wait until a deleted subvolume is cleaned or query the state.

struct btrfs_ioctl_subvol_wait

BTRFS_IOC_SHUTDOWN

Force filesystem IO shutdown and turn it read-only.

uint64_t

## DATA STRUCTURES AND DEFINITIONS

```
struct btrfs_ioctl_vol_args {

        __s64 fd;

        char name[BTRFS_PATH_NAME_MAX + 1];
};
```

```
#define BTRFS_SUBVOL_RDONLY                  (1ULL << 1)
#define BTRFS_SUBVOL_QGROUP_INHERIT          (1ULL << 2)
#define BTRFS_DEVICE_SPEC_BY_ID              (1ULL << 3)
#define BTRFS_SUBVOL_SPEC_BY_ID              (1ULL << 4)
struct btrfs_ioctl_vol_args_v2 {

        __s64 fd;

        __u64 transid;

        __u64 flags;

        union {

                struct {

                        __u64 size;

                        struct btrfs_qgroup_inherit __user *qgroup_inherit;

                };

                __u64 unused[4];

        };

        union {

                char name[BTRFS_SUBVOL_NAME_MAX + 1];

                __u64 devid;

                __u64 subvolid;

        };
};
```

```
#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE         (1ULL << 0)
/*

 * Older kernels (< 4.9) on big-endian systems produced broken free space tree

 * bitmaps, and btrfs-progs also used to corrupt the free space tree (versions

 * < 4.7.3).  If this bit is clear, then the free space tree cannot be trusted.

 * btrfs-progs can also intentionally clear this bit to ask the kernel to

 * rebuild the free space tree, however this might not work on older kernels

 * that do not know about this bit. If not sure, clear the cache manually on

 * first mount when booting older kernel versions.

 */
#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID   (1ULL << 1)
#define BTRFS_FEATURE_COMPAT_RO_VERITY                  (1ULL << 2)
#define BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE        (1ULL << 3)
#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF            (1ULL << 0)
#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL           (1ULL << 1)
#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS             (1ULL << 2)
#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO             (1ULL << 3)
#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD            (1ULL << 4)
#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA             (1ULL << 5)
#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF            (1ULL << 6)
#define BTRFS_FEATURE_INCOMPAT_RAID56                   (1ULL << 7)
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA          (1ULL << 8)
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES                 (1ULL << 9)
#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID            (1ULL << 10)
#define BTRFS_FEATURE_INCOMPAT_RAID1C34                 (1ULL << 11)
#define BTRFS_FEATURE_INCOMPAT_ZONED                    (1ULL << 12)
#define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2           (1ULL << 13)
#define BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE         (1ULL << 14)
#define BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA             (1ULL << 16)
struct btrfs_ioctl_feature_flags {

        __u64 compat_flags;

        __u64 compat_ro_flags;

        __u64 incompat_flags;
};
```

```
struct btrfs_ioctl_get_subvol_info_args {

        /* Id of this subvolume */

        __u64 treeid;

        /* Name of this subvolume, used to get the real name at mount point */

        char name[BTRFS_VOL_NAME_MAX + 1];

        /*

         * Id of the subvolume which contains this subvolume.

         * Zero for top-level subvolume or a deleted subvolume.

         */

        __u64 parent_id;

        /*

         * Inode number of the directory which contains this subvolume.

         * Zero for top-level subvolume or a deleted subvolume

         */

        __u64 dirid;

        /* Latest transaction id of this subvolume */

        __u64 generation;

        /* Flags of this subvolume */

        __u64 flags;

        /* UUID of this subvolume */

        __u8 uuid[BTRFS_UUID_SIZE];

        /*

         * UUID of the subvolume of which this subvolume is a snapshot.

         * All zero for a non-snapshot subvolume.

         */

        __u8 parent_uuid[BTRFS_UUID_SIZE];

        /*

         * UUID of the subvolume from which this subvolume was received.

         * All zero for non-received subvolume.

         */

        __u8 received_uuid[BTRFS_UUID_SIZE];

        /* Transaction id indicating when change/create/send/receive happened */

        __u64 ctransid;

        __u64 otransid;

        __u64 stransid;

        __u64 rtransid;

        /* Time corresponding to c/o/s/rtransid */

        struct btrfs_ioctl_timespec ctime;

        struct btrfs_ioctl_timespec otime;

        struct btrfs_ioctl_timespec stime;

        struct btrfs_ioctl_timespec rtime;

        /* Must be zero */

        __u64 reserved[8];
};
```

```
#define BTRFS_QGROUP_INHERIT_SET_LIMITS         (1ULL << 0)
struct btrfs_qgroup_inherit {

        __u64 flags;

        __u64 num_qgroups;

        __u64 num_ref_copies;

        __u64 num_excl_copies;

        struct btrfs_qgroup_limit lim;

        __u64 qgroups[];
};
```

```
#define BTRFS_QGROUP_LIMIT_MAX_RFER             (1ULL << 0)
#define BTRFS_QGROUP_LIMIT_MAX_EXCL             (1ULL << 1)
#define BTRFS_QGROUP_LIMIT_RSV_RFER             (1ULL << 2)
#define BTRFS_QGROUP_LIMIT_RSV_EXCL             (1ULL << 3)
#define BTRFS_QGROUP_LIMIT_RFER_CMPR            (1ULL << 4)
#define BTRFS_QGROUP_LIMIT_EXCL_CMPR            (1ULL << 5)
struct btrfs_qgroup_limit {

        __u64 flags;

        __u64 max_rfer;

        __u64 max_excl;

        __u64 rsv_rfer;

        __u64 rsv_excl;
};
```

```
struct btrfs_ioctl_dev_info_args {

     __u64 devid;                            /* in/out */

     __u8 uuid[BTRFS_UUID_SIZE];             /* in/out */

     __u64 bytes_used;                       /* out */

     __u64 total_bytes;                      /* out */

     /*

      * Optional, out.

      *

      * Showing the fsid of the device, allowing user space to check if this

      * device is a seeding one.

      *

      * Introduced in v6.3, thus user space still needs to check if kernel

      * changed this value.  Older kernel will not touch the values here.

      */

     __u8 fsid[BTRFS_UUID_SIZE];

     __u64 unused[377];                      /* pad to 4k */

     __u8 path[BTRFS_DEVICE_PATH_NAME_MAX];  /* out */
};
```

```
/* Request information about checksum type and size */
#define BTRFS_FS_INFO_FLAG_CSUM_INFO                    (1U << 0)
/* Request information about filesystem generation */
#define BTRFS_FS_INFO_FLAG_GENERATION                   (1U << 1)
/* Request information about filesystem metadata UUID */
#define BTRFS_FS_INFO_FLAG_METADATA_UUID                (1U << 2)
struct btrfs_ioctl_fs_info_args {

        __u64 max_id;                           /* out */

        __u64 num_devices;                      /* out */

        __u8 fsid[BTRFS_FSID_SIZE];             /* out */

        __u32 nodesize;                         /* out */

        __u32 sectorsize;                       /* out */

        __u32 clone_alignment;                  /* out */

        /* See BTRFS_FS_INFO_FLAG_* */

        __u16 csum_type;                        /* out */

        __u16 csum_size;                        /* out */

        __u64 flags;                            /* in/out */

        __u64 generation;                       /* out */

        __u8 metadata_uuid[BTRFS_FSID_SIZE];    /* out */

        __u8 reserved[944];                     /* pad to 1k */
};
```

```
#define BTRFS_INO_LOOKUP_PATH_MAX               4080
struct btrfs_ioctl_ino_lookup_args {

        __u64 treeid;

        __u64 objectid;

        char name[BTRFS_INO_LOOKUP_PATH_MAX];
};
```

```
/* Specify the subvolid. */
#define BTRFS_SUBVOL_SYNC_WAIT_FOR_ONE         (0)
/* Wait for all currently queued. */
#define BTRFS_SUBVOL_SYNC_WAIT_FOR_QUEUED      (1)
/* Count number of queued subvolumes. */
#define BTRFS_SUBVOL_SYNC_COUNT                (2)
/*

 * Read which is the first in the queue (to be cleaned or being cleaned already),

 * or 0 if the queue is empty.

 */
#define BTRFS_SUBVOL_SYNC_PEEK_FIRST           (3)
/* Read the last subvolid in the queue, or 0 if the queue is empty. */
#define BTRFS_SUBVOL_SYNC_PEEK_LAST            (4)
struct btrfs_ioctl_subvol_wait {

       __u64 subvolid;

       __u32 mode;

       __u32 count;
};
```

Constant name

Value

BTRFS_UUID_SIZE

16

BTRFS_FSID_SIZE

16

BTRFS_SUBVOL_NAME_MAX

4039

BTRFS_PATH_NAME_MAX

4087

BTRFS_VOL_NAME_MAX

255

BTRFS_LABEL_SIZE

256

BTRFS_FIRST_FREE_OBJECTID

256

## DETAILED DESCRIPTION

### BTRFS_IOC_SNAP_CREATE
Note:

obsoleted by BTRFS_IOC_SNAP_CREATE_V2

(since: 3.0, obsoleted: 4.0) Create a snapshot of a subvolume.

Field

Description

ioctl fd

file descriptor of the parent directory of the new subvolume

ioctl args

struct btrfs_ioctl_vol_args

args.fd

file descriptor of any directory inside the subvolume to snapshot, must be on the same filesystem

args.name

name of the subvolume, although the buffer can be almost 4KiB, the file size is limited by Linux VFS to 255 characters and must not contain a slash ('/')

### BTRFS_IOC_SCAN_DEV
Scan and register a given device in the filesystem module, which can be later used for automatic device and filesystem association at mount time. This operates on the control device, not files from a mounted filesystem. Can be safely called repeatedly with same device path.

Field

Description

ioctl fd

file descriptor of the control device /dev/btrfs-control

ioctl args

struct btrfs_ioctl_vol_args

args.fd

ignored

args.name

full path of the device

### BTRFS_IOC_SYNC
Sync the filesystem data as would sync() syscall do, additionally wake up the internal transaction thread that may trigger actions like subvolume cleaning or queued defragmentation.

Field

Description

ioctl fd

file descriptor of any file or directory in the filesystem

ioctl args

NULL

### BTRFS_IOC_ADD_DEV
Add a given block device to the filesystem. Unlike the command btrfs device add there's are no safety checks (like existence of another filesystem on the device), device preparation (like TRIM or zone reset), so use it with care.

This is a filesystem-exclusive operation and it will fail if there's another one already running, with one exception, when there's a paused balance.

Required permissions: CAP_SYS_ADMIN

Field

Description

ioctl fd

file descriptor of any file or directory in the filesystem

ioctl args

struct btrfs_ioctl_vol_args

args.fd

ignored

args.name

full path of the block device to be added

### BTRFS_IOC_RM_DEV
Remove a device from the filesystem specified by it's path, or cancel a running device deletion by special path cancel.

This is a filesystem-exclusive operation and it will fail if there's another one already running.

Required permissions: CAP_SYS_ADMIN

Field

Description

ioctl fd

file descriptor of any file or directory in the filesystem

ioctl args

struct btrfs_ioctl_vol_args

args.fd

ignored

args.name

full path of the block device to be deleted or string "cancel"

### BTRFS_IOC_SUBVOL_CREATE
Note:

obsoleted by BTRFS_IOC_SUBVOL_CREATE_V2

(since: 3.0, obsoleted: 4.0) Create a subvolume.

Field

Description

ioctl fd

file descriptor of the parent directory of the new subvolume

ioctl args

struct btrfs_ioctl_vol_args

args.fd

ignored

args.name

name of the subvolume, although the buffer can be almost 4KiB, the file size is limited by Linux VFS to 255 characters and must not contain a slash ('/')

### BTRFS_IOC_SNAP_DESTROY
Note:

obsoleted by BTRFS_IOC_SNAP_DESTROY_V2

(since: 2.6.33, obsoleted: 5.7) Delete a subvolume.

Field

Description

ioctl fd

file descriptor of the parent directory of the new subvolume

ioctl args

struct btrfs_ioctl_vol_args

args.fd

ignored

args.name

name of the subvolume, although the buffer can be almost 4KiB, the file size is limited by Linux VFS to 255 characters and must not contain a slash ('/')

### BTRFS_IOC_INO_LOOKUP
Resolve inode number to a path (requires CAP_SYS_ADMIN), or read a containing subvolume id of the given file (unrestricted, special case). The size of the path name buffer is shorter than PATH_MAX (4096), it's possible that the path is trimmed due to that. Also implemented by btrfs inspect-internal rootid <#man-inspect-rootid>.

The general case needs CAP_SYS_ADMIN and can resolve any file to its path. The special case for reading the containing subvolume is not restricted:

```
struct btrfs_ioctl_ino_lookup_args args;
fd = open("file", ...);
args.treeid = 0;
args.objectid = BTRFS_FIRST_FREE_OBJECTID;
ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
/* args.treeid now contains the subvolume id */
```

Field

Description

ioctl fd

file descriptor of the file or directory to lookup the subvolumeid

ioctl args

struct btrfs_ioctl_ino_lookup_args

args.treeid

subvolume id against which the path should be resolved (needs CAP_SYS_ADMIN), or 0 so the subvolume containing fd will be used

args.objectid

inode number to lookup, INODE_REF_KEY with that key.objectid, or BTRFS_FIRST_FREE_OBJECTID as special case to read only the tree id and clear the args.name buffer

args.name

path relative to the toplevel subvolume, or empty string

### BTRFS_IOC_DEFAULT_SUBVOL
Set the given subvolume id as the default one when mounting the filesystem without subvol=path or subvolid=id options.

Field

Description

ioctl fd

file descriptor of the directory inside which to create the new snapshot

ioctl args

numeric value of subvolume to become default (uint64_t)

### BTRFS_IOC_SNAP_CREATE_V2
Create a snapshot of a subvolume.

Field

Description

ioctl fd

file descriptor of the directory inside which to create the new snapshot

ioctl args

struct btrfs_ioctl_vol_args_v2

args.fd

file descriptor of any directory inside the subvolume to snapshot, must be on the filesystem

args.transid

ignored

args.flags

any subset of BTRFS_SUBVOL_RDONLY to make the new snapshot read-only, or BTRFS_SUBVOL_QGROUP_INHERIT to apply the qgroup_inherit field

args.name

the name, under the ioctl fd, for the new subvolume

### BTRFS_IOC_SUBVOL_CREATE_V2
(since: 3.6) Create a subvolume, qgroup inheritance and limits can be specified.

Field

Description

ioctl fd

file descriptor of the parent directory of the new subvolume

ioctl args

struct btrfs_ioctl_vol_args_v2

args.fd

ignored

args.transid

ignored

args.flags

flags to set on the subvolume, BTRFS_SUBVOL_RDONLY for readonly, BTRFS_SUBVOL_QGROUP_INHERIT if the qgroup related fields should be processed

args.size

number of entries in args.qgroup_inherit

args.qgroup_inherit

inherit the given qgroups (struct btrfs_qgroup_inherit) and limits (struct btrfs_qgroup_limit)

name

name of the subvolume, although the buffer can be almost 4KiB, the file size is limited by Linux VFS to 255 characters and must not contain a slash ('/')

### BTRFS_IOC_SUBVOL_GETFLAGS
Read the flags of a subvolume. The returned flags are either 0 or BTRFS_SUBVOL_RDONLY.

Field

Description

ioctl fd

file descriptor of the subvolume to examine

ioctl args

uint64_t

### BTRFS_IOC_SUBVOL_SETFLAGS
Change the flags of a subvolume.

Field

Description

ioctl fd

file descriptor of the subvolume to modify

ioctl args

uint64_t, either 0 or BTRFS_SUBVOL_RDONLY

### BTRFS_IOC_GET_FSLABEL
Read the label of the filesystem into a given buffer. Alternatively it can be read from /sys/fs/btrfs/FSID/label though it requires to know the FSID of the filesystem.

Field

Description

ioctl fd

file descriptor of any file/directory in the filesystem

ioctl args

char buffer[BTRFS_LABEL_SIZE]

### BTRFS_IOC_SET_FSLABEL
Set the label of filesystem from given buffer. The maximum length also accounts for terminating NUL character. Alternatively it can be also set by writing to /sys/fs/btrfs/FSID/label though it requires to know the FSID of the filesystem (and an explicit commit before the change is permanent).

Required permissions: CAP_SYS_ADMIN

Field

Description

ioctl fd

file descriptor of any file/directory in the filesystem

ioctl args

char buffer[BTRFS_LABEL_SIZE]

### BTRFS_IOC_DEV_INFO
Read some basic information about a device, requested by the devid or device UUID.

Field

Description

ioctl fd

file descriptor of any file/directory in the filesystem

ioctl args

struct btrfs_ioctl_dev_info_args

### BTRFS_IOC_FS_INFO
Read internal information about the filesystem. The data can be exchanged both ways and part of the structure could be optionally filled. The reserved bytes can be used to get new kind of information in the future, always depending on the flags set.

Field

Description

ioctl fd

file descriptor of any file/directory in the filesystem

ioctl args

struct btrfs_ioctl_fs_info_args

### BTRFS_IOC_GET_FEATURES
Get the actually set feature bits on the filesystem (the bits are stored in the super block). There are three sets related to backward compatibility:

- incompat: not backward compatible, mount on older kernel will fail.

- compat_ro: backward compatible for read-only mount.

- compat: backward compatible with read-write support, only marked as as individual feature.

Field

Description

ioctl fd

file descriptor of the subvolume to examine

ioctl args

struct btrfs_ioctl_feature_flags

If a bit is set then there may be some data structures on the filesystem of the related feature, but not necessarily.

Some of the features are turned on automatically when used, e.g. compression or when a balance filter converts to yet unused block group profile. In some cases the feature can be turned on or off by btrfstune(8) <>.

### BTRFS_IOC_SET_FEATURES
Set a feature bit on the filesystem if possible. Some features may require extensive changes, new data structures or conversion (like free-space-tree). Bits representing possible existence of data structures related to the feature can be set without actually creating anything, e.g. ZSTD compressed extents.

Field

Description

ioctl fd

file descriptor of the subvolume to examine

ioctl args

struct btrfs_ioctl_feature_flags

### BTRFS_IOC_GET_SUPPORTED_FEATURES
Get feature sets supported by the kernel module, in three groups:

- supported: (index 0) all supported compat/compat_ro/incompat features

- safe to set: (index 1) features that can be enabled on a mounted filesystem

- safe to clear: (index 2) features that can be disabled on a mounted filesystem

The features are also listed in /sys/fs/btrfs/features.

Field

Description

ioctl fd

file descriptor of the subvolume to examine

ioctl args

struct btrfs_ioctl_feature_flags[3]

### BTRFS_IOC_GET_SUBVOL_INFO
Get information about a subvolume.

Field

Description

ioctl fd

file descriptor of the subvolume to examine

ioctl args

struct btrfs_ioctl_get_subvol_info_args

### BTRFS_IOC_SNAP_DESTROY_V2
Destroy a subvolume, which may or may not be a snapshot.

Field

Description

ioctl fd

if flags does not include BTRFS_SUBVOL_SPEC_BY_ID, or if executing in a non-root user namespace, file descriptor of the parent directory containing the subvolume to delete; otherwise, file descriptor of any directory on the same filesystem as the subvolume to delete, but not within the same subvolume

ioctl args

struct btrfs_ioctl_vol_args_v2

args.fd

ignored

args.transid

ignored

args.flags

0 if the name field identifies the subvolume by name in the specified directory, or BTRFS_SUBVOL_SPEC_BY_ID if the subvolid field specifies the ID of the subvolume

args.name

only if flags does not contain BTRFS_SUBVOL_SPEC_BY_ID, the name (within the directory identified by fd) of the subvolume to delete

args.subvolid

only if flags contains BTRFS_SUBVOL_SPEC_BY_ID, the subvolume ID of the subvolume to delete

### BTRFS_IOC_SUBVOL_SYNC_WAIT
(since: 6.13) Wait until a deleted subvolume is cleaned or query the state.

There are several modes of operation, where the most common ones are to wait on a specific subvolume or all currently queued for cleaning. This is utilized e.g. in backup applications that delete subvolumes and wait until they're cleaned to check for remaining space.

The other modes are for flexibility, e.g. for monitoring or checkpoints in the queue of deleted subvolumes, again without the need to use SEARCH_TREE.

Notes:

- waiting is interruptible, the timeout is set to 1 second and is not configurable

- repeated calls to the ioctl see a different state, so this is inherently racy when using e.g. the count or peek next/last

Use cases (definition of constants):

- a subvolume A was deleted, wait for cleaning (WAIT_FOR_ONE)

- a bunch of subvolumes were deleted, wait for all (WAIT_FOR_QUEUED or PEEK_LAST + WAIT_FOR_ONE)

- count how many are queued (not blocking), for monitoring purposes

- report progress (PEEK_NEXT), may miss some if cleaning is quick

- own waiting in user space (PEEK_LAST until it's 0)

Field

Description

ioctl fd

file descriptor of any file or directory in the filesystem

ioctl args

struct btrfs_ioctl_subvol_wait

args.subvolid

Depending on the mode, the numeric id of subvolume to wait for, or the one queried by PEEK modes

args.mode

mode of operation described above

args.count

if mode is set to COUNT the number of subvolumes queued for cleaning

### BTRFS_IOC_SHUTDOWN
(since 7.1) Force filesystem IO shutdown and turn it read-only.

Field

Description

ioctl fd

file descriptor of any file or directory in the filesystem

ioctl args

uint64_t, mode described below

The argument is an int with modes affecting flushing of pending writes:

- BTRFS_SHUTDOWN_FLAGS_DEFAULT (0x0) - choose default (LOGFLUSH mode)

- BTRFS_SHUTDOWN_FLAGS_LOGFLUSH (0x1) - flush everything, the filesystem is frozen, shut down and thawn

- BTRFS_SHUTDOWN_FLAGS_NOLOGFLUSH (0x2) - shut down the filesystem right away

Additionally the fserror reporting facility is used to notify about the event.

## AVAILABILITY
btrfs is part of btrfs-progs. Please refer to the documentation at <https://btrfs.readthedocs.io>.

## SEE ALSO
ioctl(2) <https://man7.org/linux/man-pages/man2/ioctl.2.html>

branch: sisyphus


package: libapparmor-devel-doc

title: aa_change_hat(2)

summary: change to or from a hat within a AppArmor profile

text:
# aa_change_hat(2)

## NAME
aa_change_hat - change to or from a "hat" within a AppArmor profile

## SYNOPSIS
\#include <sys/apparmor.h>

int aa_change_hat (char *subprofile, unsigned long magic_token);

int aa_change_hatv (char *subprofiles[], unsigned long magic_token);

int aa_change_hat_vargs (unsigned long magic_token, ...);

Link with -lapparmor when compiling.

## DESCRIPTION
An AppArmor profile applies to an executable program; if a portion of the program needs different access permissions than other portions, the program can "change hats" to a different role, also known as a subprofile.

To change into a new hat, it calls one of the family of change_hat functions to do so. It passes in a pointer to the subprofile which it wants to change into, and a 64bit magic_token. The magic_token is used to return out of the subprofile at a later time.

The aa_change_hat() function allows specifying the name of a single subprofile that the application wants to change into. A pointer to the name of the subprofile is passed along with the magic_token. If the profile is not present the call will fail with the appropriate error.

The aa_change_hatv() function allows passing a NULL terminated vector of pointers to subprofile names which will be tried in order. The first subprofile in the vector that exists will be transitioned to and if none of the subprofiles exist the call will fail with the appropriate error.

The aa_change_hat_vargs() function is a convenience wrapper for the aa_change_hatv() function. After the magic_token it takes an arbitrary number of pointers to subprofile names. Similar to execl(3), aa_change_hat_vargs() assembles the list of subprofile names into a vector and calls aa_change_hatv().

If a program wants to return out of the current subprofile to the original profile, it calls aa_change_hat() with a pointer to NULL as the subprofile, and the original magic_token value. If the magic_token does not match the original magic_token passed into the kernel when the program entered the subprofile, the change back to the original profile will not happen, and the current task will be killed. If the magic_token matches the original token, then the process will change back to the original profile.

As both read(2) and write(2) are mediated, a file must be listed in a subprofile definition if the file is to be accessed while the process is in a "hat".

## RETURN VALUE
On success zero is returned. On error, -1 is returned, and errno(3) is set appropriately.

## ERRORS
EINVAL

The apparmor kernel module is not loaded or the communication via the /proc/*/attr/current file did not conform to protocol.

ENOMEM

Insufficient kernel memory was available.

EPERM

The calling application is not confined by apparmor, the specified subprofile is not a hat profile, the task is being ptraced and the tracing task does not have permission to trace the specified subprofile or the no_new_privs execution bit is enabled.

ECHILD

The application's profile has no hats defined for it.

ENOENT

The specified subprofile does not exist in this profile but other hats are defined.

EACCES

The specified magic token did not match, and permissions to change to the specified subprofile has been denied. This will in most situations also result in the task being killed, to prevent brute force attacks.

## EXAMPLE
The following code examples shows simple, if contrived, uses of aa_change_hat(); a typical use of aa_change_hat() will separate privileged portions of a process from unprivileged portions of a process, such as keeping unauthenticated network traffic handling separate from authenticated network traffic handling in OpenSSH or executing user-supplied CGI scripts in apache.

The use of random(3) is simply illustrative. Use of /dev/urandom is recommended.

First, a simple high-level overview of aa_change_hat() use:

```
 void foo (void) {
        unsigned long magic_token;
        /* get a random magic token value
        from our huge entropy pool */
        magic_token = random_function();
        /* change into the subprofile while
         * we do stuff we don't trust */
        aa_change_hat("stuff_we_dont_trust", magic_token);
        /* Go do stuff we don't trust -- this is all
         * done in *this* process space, no separate
         * fork()/exec()'s are done. */
        interpret_perl_stuff(stuff_from_user);
        /* now change back to our original profile */
        aa_change_hat(NULL, magic_token);
 }
```

Second, an example to show that files not listed in a subprofile ("hat") aren't accessible after an aa_change_hat() call:

```
 #include <stdlib.h>
 #include <string.h>
 #include <sys/apparmor.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
 int main(int argc, char *argv[]) {
        int fd;
        unsigned long tok;
        char buf[10];
        /* random() is a poor choice */
        tok = random();
        /* open /etc/passwd outside of any hat */
        if ((fd=open("/etc/passwd", O_RDONLY)) < 0)
                perror("Failure opening /etc/passwd");
        /* confirm for ourselves that we can really read /etc/passwd */
        memset(&buf, 0, 10);
        if (read(fd, &buf, 10) == -1) {
                perror("Failure reading /etc/passwd pre-hat");
                _exit(1);
        }
        buf[9] = '\0';
        printf("/etc/passwd: %s\n", buf);
        /* change hat to the "hat" subprofile, which should not have
         * read access to /etc/passwd -- even though we have a valid
         * file descriptor at the time of the aa_change_hat() call. */
        if (aa_change_hat("hat", tok)) {
                perror("Failure changing hat -- aborting");
                _exit(1);
        }
        /* confirm that we cannot read /etc/passwd */
        lseek(fd,0,SEEK_SET);
        memset(&buf, 0, 10);
        if (read(fd, &buf, 10) == -1)
                perror("Failure reading /etc/passwd post-hat");
        buf[9] = '\0';
        printf("/etc/passwd: %s\n", buf);
        return 0;
 }
```

This code example requires the following profile to be loaded with apparmor_parser(8):

```
 /tmp/ch {
   /etc/ld.so.cache               mr,
   /etc/locale/**                 r,
   /etc/localtime                 r,
   /usr/share/locale/**           r,
   /usr/share/zoneinfo/**         r,
   /usr/lib/locale/**             mr,
   /usr/lib/gconv/*.so            mr,
   /usr/lib/gconv/gconv-modules*  mr,
   /lib/ld-*.so*         mrix,
   /lib/libc*.so*        mr,
   /lib/libapparmor*.so* mr,
   /dev/pts/*            rw,
   /tmp/ch               mr,
   /etc/passwd           r,
   ^hat {
     /dev/pts/*     rw,
   }
 }
```

The output when run:

```
 $ /tmp/ch
 /etc/passwd: root:x:0:
 Failure reading /etc/passwd post-hat: Permission denied
 /etc/passwd:
 $
```

## BUGS
None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>. Note that aa_change_hat(2) provides no memory barriers between different areas of a program; if address space separation is required, then separate processes should be used.

## SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), aa_change_profile(2), aa_getcon(2) and <https://wiki.apparmor.net>.


title: aa_change_profile(2)

summary: change a tasks profile

text:
# aa_change_profile(2)

## NAME
aa_change_profile, aa_change_onexec - change a tasks profile

## SYNOPSIS
\#include <sys/apparmor.h>

int aa_change_profile(const char *profile);

int aa_change_onexec(const char *profile);

Link with -lapparmor when compiling.

## DESCRIPTION
An AppArmor profile applies to an executable program; if a portion of the program needs different access permissions than other portions, the program can "change profile" to a different profile. To change into a new profile, it can use the aa_change_profile() function to do so. It passes in a pointer to the profile to transition to. Confined programs wanting to use aa_change_profile() need to have rules permitting changing to the named profile. See apparmor.d(8) for details.

If a program wants to return out of the current profile to the original profile, it may use aa_change_hat(2). Otherwise, the two profiles must have rules permitting changing between the two profiles.

Open file descriptors may not be remediated after a call to aa_change_profile() so the calling program must close(2) open file descriptors to ensure they are not available after calling aa_change_profile(). As aa_change_profile() is typically used just before execve(2), you may want to use open(2) or fcntl(2) with close-on-exec.

The aa_change_onexec() function is like the aa_change_profile() function except it specifies that the profile transition should take place on the next exec instead of immediately. The delayed profile change takes precedence over any exec transition rules within the confining profile. Delaying the profile boundary has a couple of advantages, it removes the need for stub transition profiles and the exec boundary is a natural security layer where potentially sensitive memory is unmapped.

## RETURN VALUE
On success zero is returned. On error, -1 is returned, and errno(3) is set appropriately.

## ERRORS
EINVAL

The apparmor kernel module is not loaded, neither a profile nor a namespace was specified, or the communication via the /proc/*/attr/current file did not conform to protocol.

ENOMEM

Insufficient kernel memory was available.

EPERM

The calling application is confined by apparmor and the no_new_privs bit is set.

EACCES

The task does not have sufficient permissions to change its domain.

ENOENT

The specified profile does not exist, or is not visible from the current Namespace.

## EXAMPLE
The following example shows a simple, if contrived, use of aa_change_profile(); a typical use of aa_change_profile() will aa_change_profile() just before an execve(2) so that the new child process is permanently confined.

```
 #include <stdlib.h>
 #include <string.h>
 #include <sys/apparmor.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
 int main(int argc, char * argv[])
 {
         int fd;
         char buf[10];
         char *execve_args[4];
         printf("Before aa_change_profile():\n");
         if ((fd=open("/etc/passwd", O_RDONLY)) < 0) {
                perror("Failure opening /etc/passwd");
                return 1;
         }
         /* Confirm for ourselves that we can really read /etc/passwd */
         memset(&buf, 0, 10);
         if (read(fd, &buf, 10) == -1) {
                 perror("Failure reading /etc/passwd");
                 return 1;
         }
         buf[9] = '\0';
         printf("/etc/passwd: %s\n", buf);
         close(fd);
         printf("After aa_change_profile():\n");
         /* change profile to the "i_cant_be_trusted_anymore" profile, which
          * should not have read access to /etc/passwd. */
         if (aa_change_profile("i_cant_be_trusted_anymore") < 0) {
             perror("Failure changing profile -- aborting");
             _exit(1);
         }
         /* confirm that we cannot read /etc/passwd */
         execve_args[0] = "/usr/bin/head";
         execve_args[1] = "-1";
         execve_args[2] = "/etc/passwd";
         execve_args[3] = NULL;
         execve("/usr/bin/head", execve_args, NULL);
         perror("execve");
         _exit(1);
 }
```

This code example requires a profile similar to the following to be loaded with apparmor_parser(8):

```
 profile i_cant_be_trusted_anymore {
     /etc/ld.so.cache      mr,
     /lib/ld-*.so*         mrix,
     /lib/libc*.so*        mr,
     /usr/bin/head ix,
 }
```

The output when run:

```
 $ /tmp/change_p
 Before aa_change_profile():
 /etc/passwd: root:x:0:
 After aa_change_profile():
 /usr/bin/head: cannot open `/etc/passwd' for reading: Permission denied
 $
```

If /tmp/change_p is to be confined as well, then the following profile can be used (in addition to the one for 'i_cant_be_trusted_anymore', above):

```
 # Confine change_p to be able to read /etc/passwd and aa_change_profile()
 # to the 'i_cant_be_trusted_anymore' profile.
 /tmp/change_p {
     /etc/ld.so.cache          mr,
     /lib/ld-*.so*             mrix,
     /lib/libc*.so*            mr,
     /etc/passwd               r,
     # Needed for aa_change_profile()
     /usr/lib/libapparmor*.so* mr,
     /proc/[0-9]*/attr/current w,
     change_profile -> i_cant_be_trusted_anymore,
 }
```

## BUGS
None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>. Note that using aa_change_profile(2) without execve(2) provides no memory barriers between different areas of a program; if address space separation is required, then separate processes should be used.

## SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), aa_change_hat(2) and <https://wiki.apparmor.net>.


title: aa_find_mountpoint(2)

summary: determine if apparmor is available

text:
# aa_find_mountpoint(2)

## NAME
aa_is_enabled - determine if apparmor is available

aa_find_mountpoint - find where the apparmor interface filesystem is mounted

## SYNOPSIS
\#include <sys/apparmor.h>

int aa_is_enabled(void);

int aa_find_mountpoint(char **mnt);

Link with -lapparmor when compiling.

## DESCRIPTION
The aa_is_enabled function returns true (1) if apparmor is enabled. If it isn't it sets the errno(3) to reflect the reason it is not enabled and returns 0.

The aa_find_mountpoint function finds where the apparmor filesystem is mounted on the system, and returns a string containing the mount path. It is the caller's responsibility to free(3) the returned path.

## RETURN VALUE
aa_is_enabled On success 1 is returned. On error, 0 is returned, and errno(3) is set appropriately.

aa_find_mountpoint On success zero is returned. On error, -1 is returned, and errno(3) is set appropriately.

## ERRORS
aa_is_enabled

ENOSYS

AppArmor extensions to the system are not available.

ECANCELED

AppArmor is available on the system but has been disabled at boot.

EBUSY

AppArmor is available but only via private interfaces.

ENOENT

AppArmor is available (and maybe even enforcing policy) but the interface is not available.

ENOMEM

Insufficient memory was available.

EPERM

Did not have sufficient permissions to determine if AppArmor is enabled.

EACCES

Did not have sufficient permissions to determine if AppArmor is enabled.

EBUSY

AppArmor is enabled but does not have access to shared interfaces, and only private interfaces are available.

aa_find_mountpoint

ENOMEM

Insufficient memory was available.

EACCES

Access to the required paths was denied.

ENOENT

The apparmor filesystem mount could not be found

## BUGS
None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>.

## SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), and <https://wiki.apparmor.net>.


title: aa_getcon(2)

summary: read and parse procattr data

text:
# aa_getcon(2)

## NAME
aa_getprocattr_raw, aa_getprocattr - read and parse procattr data

aa_getcon, aa_gettaskcon - get task confinement information

aa_getpeercon - get the confinement of a socket's other end (peer)

## SYNOPSIS
\#include <sys/apparmor.h>

int aa_getprocattr_raw(pid_t tid, const char *attr, char *buf, int len, char **mode);

int aa_getprocattr(pid_t tid, const char *attr, char **label, char **mode);

int aa_gettaskcon(pid_t target, char **label, char **mode);

int aa_getcon(char **label, char **mode);

int aa_getpeercon_raw(int fd, char *buf, int *len, char **mode);

int aa_getpeercon(int fd, char **label, char **mode);

Link with -lapparmor when compiling.

## DESCRIPTION
The aa_getcon function gets the current AppArmor confinement context for the current task. The confinement context consists of a label and a mode. The label is usually just the name of the AppArmor profile restricting the task, but it may include the profile namespace or in some cases a set of profile names (known as a stack of profiles). The mode is a string that describes how the kernel is enforcing the policy defined in the profile. Profiles loaded in "enforce" mode will result in enforcement of the policy defined in the profile as well as reporting policy violation attempts. Profiles in "complain" mode will not enforce policy but instead report policy violation attempts.

Some examples of possible returned *label strings are "unconfined", "/sbin/dhclient", and "Firefox". The string can consist of any non-NUL characters but it will be NUL-terminated. The *label string must be freed using free().

The possible *mode strings are "enforce" and "complain". Additionally, *mode may be NULL when *label is "unconfined". The *mode string must not be freed. The *label and *mode strings come from a single buffer allocation and are separated by a NUL character.

The aa_gettaskcon function is like the aa_getcon function except it will work for any arbitrary task in the system.

The aa_getpeercon function is similar to that of aa_gettaskcon except that it returns the confinement information for task on the other end of a socket connection.

The aa_getpeercon_raw function is the backend for the aa_getpeercon function and does not handle buffer allocation.

The aa_getprocattr function is the backend for the aa_getcon and aa_gettaskcon functions and handles the reading and parsing of the confinement data from different arbitrary attr files and returns the processed results in an allocated buffer.

The aa_getprocattr_raw() is the backend for the aa_getprocattr function and does not handle buffer allocation.

## RETURN VALUE
On success size of data placed in the buffer is returned, this includes the mode if present and any terminating characters. On error, -1 is returned, and errno(3) is set appropriately.

## ERRORS
EINVAL

The apparmor kernel module is not loaded or the communication via the /proc/*/attr/file did not conform to protocol.

ENOMEM

Insufficient kernel memory was available.

EACCES

Access to the specified file/task was denied.

ENOENT

The specified file/task does not exist or is not visible.

ERANGE

The confinement data is too large to fit in the supplied buffer.

ENOPROTOOPT

The kernel doesn't support the SO_PEERLABEL option in sockets. This happens mainly when the kernel lacks 'fine grained unix mediation' support. It also can happen on LSM stacking kernels where another LSM has claimed this interface and decides to return this error, although this is really a corner case.

## NOTES
If aa_getpeercon_raw returns -1 and errno is ERANGE, the value of *len can be used to reallocate buf so that it is sufficiently large enough to store the confinement data.

## BUGS
None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>.

## SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), aa_change_profile(2), aa_splitcon(3) and <https://wiki.apparmor.net>.


title: aa_query_label(2)

text:
# aa_query_label(2)

## NAME
aa_query_label - query access permission associated with a label

aa_query_file_path, aa_query_file_path_len - query access permissions of a file path

aa_query_link_path, aa_query_link_path_len - query access permissions of a link path

## SYNOPSIS
\#include <sys/apparmor.h>

int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed, int *audited);

int aa_query_file_path(uint32_t mask, const char *label, size_t label_len, const char *path, int *allowed, int *audited);

int aa_query_file_path_len(uint32_t mask, const char *label, size_t label_len, const char *path, size_t path_len, int *allowed, int *audited);

int aa_query_link_path(const char *label, const char *target, const char *link, int *allowed, int *audited);

int aa_query_link_path_len(const char *label, size_t label_len, const char *target, size_t target_len, const char *link, size_t link_len, int *allowed, int *audited);

Link with -lapparmor when compiling.

## DESCRIPTION
The aa_query_label function fetches the current permissions granted by the specified label in the query string.

The query is a raw binary formatted query, containing the label and permission query to make. The returned allowed and audited values are interpreted boolean values, simply stating whether the query is allowed and if it is audited.

The mask of the query string is a bit mask of permissions to query and is class type dependent (see AA_CLASS_xxx entries in sys/apparmor.h).

The format of the query string is also dependent on the AA_CLASS and as such the aa_query_xxx helper functions should usually be used instead of directly using aa_query_label. If directly using the interface the query string is required to have a header of AA_QUERY_CMD_LABEL_SIZE that will be used by aa_query_label.

The aa_query_file_path and aa_query_file_path_len functions are helper function that assemble a properly formatted file path query for the aa_query_label function. The label is a valid apparmor label as returned by aa_splitcon with label_len being the length of the label. The path is any valid filesystem path to query permissions for. For the aa_query_file_path_len variant the path_len parameter specifies the number of bytes in the path to use as part of the query.

The aa_query_link_path and aa_query_link_path_len functions are helper functions that assemble a properly formatted link path query for the aa_query_label function. The link_len and target_len parameters specify the number of bytes in the link and target to use as part of the query.

## RETURN VALUE
On success 0 is returned, and the allowed and audited parameters contain a boolean value of 0 not allowed/audited or 1 allowed/audited. On error, -1 is returned, and errno(3) is set appropriately.

## ERRORS
EINVAL

The requested mask is empty. The size of the query is less than the query AA_QUERY_CMD_LABEL_SIZE

The apparmor kernel module is not loaded or the kernel interface access interface is not available

ENOMEM

Insufficient memory was available.

EACCES

Access to the specified label or query interface was denied.

ENOENT

The specified label does not exist or is not visible.

ERANGE

The confinement data is too large to fit in the supplied buffer.

## NOTES
The label permissions returned are only valid for the time of the query and can change at any point in the future.

## BUGS
None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>.

## SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), aa_getcon(2), aa_splitcon(3) and <https://wiki.apparmor.net>.


title: aa_stack_profile(2)

text:
# aa_stack_profile(2)

## NAME
aa_stack_profile, aa_stack_onexec - combine multiple profiles to confine a task

## SYNOPSIS
\#include <sys/apparmor.h>

int aa_stack_profile(const char *profile);

int aa_stack_onexec(const char *profile);

Link with -lapparmor when compiling.

## DESCRIPTION
AppArmor supports stacking two or more profiles when confining a task. The result is an intersection of all profiles which are stacked. Stacking profiles together is desirable when wanting to ensure that confinement will never become more permissive. When changing between two profiles, as performed with aa_change_profile(2), there is always the possibility that the new profile is more permissive than the old profile but that possibility is eliminated when using aa_stack_profile().

To stack a profile with the current confinement context, a task can use the aa_stack_profile() function. The profile parameter is a NUL-terminated string indicating a profile name that should be stacked with the current confinement.

Calling aa_stack_profile("profile_a") while unconfined is equivalent to calling aa_change_profile("profile_a") since the intersection of unconfined and "profile_a" is "profile_a". Calling aa_stack_profile("profile_b") while confined by "profile_a" results in the task's confinement to be the intersection of "profile_a" and "profile_b". The resulting confinement context will be represented as "profile_a//&profile_b" in audit log messages, the return value of aa_getcon(2), etc.

Confined programs wanting to use aa_stack_profile() need to have rules permitting stacking the named profile. See apparmor.d(8) for details.

Open file descriptors may not be remediated after a call to aa_stack_profile() so the calling program must close(2) open file descriptors to ensure they are not available after calling aa_stack_profile().

The aa_stack_onexec() function is like the aa_stack_profile() function except it specifies that the stacking should take place on the next exec instead of immediately. The delayed profile change takes precedence over any exec transition rules within the confining profile. Delaying the stacking boundary has a couple of advantages, it removes the need for stub transition profiles and the exec boundary is a natural security layer where potentially sensitive memory is unmapped.

## RETURN VALUE
On success zero is returned. On error, -1 is returned, and errno(3) is set appropriately.

## ERRORS
EINVAL

AppArmor is not loaded, neither a profile nor a namespace was specified, or the communication via the /proc/*/attr/current file did not conform to protocol.

ENOMEM

Insufficient kernel memory was available.

ENOENT

The specified profile does not exist, or is not visible from the current namespace.

## NOTES
Using aa_stack_profile() and related libapparmor functions are the only way to ensure compatibility between varying kernel versions. However, there may be some situations where libapparmor is not available and directly interacting with the AppArmor filesystem is required to stack a profile.

To immediately stack a profile named "profile_a", as performed with aa_stack_profile("profile_a"), the equivalent of this shell command can be used:

```
 $ echo -n "stack profile_a" > /proc/self/attr/current
```

To stack a profile named "profile_a" at the next exec, as performed with aa_stack_onexec("profile_a"), the equivalent of this shell command can be used:

```
 $ echo -n "stack profile_a" > /proc/self/attr/exec
```

These raw AppArmor filesystem operations must only be used when using libapparmor is not a viable option.

## EXAMPLE
The following example shows a simple, if contrived, use of aa_stack_profile().

```
 #include <stdlib.h>
 #include <string.h>
 #include <sys/apparmor.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
 static void read_passwd()
 {
         int fd;
         char buf[10];
         if ((fd=open("/etc/passwd", O_RDONLY)) < 0) {
                perror("Failure opening /etc/passwd");
                _exit(1);
         }
         /* Verify that we can read /etc/passwd */
         memset(&buf, 0, 10);
         if (read(fd, &buf, 10) == -1) {
                 perror("Failure reading /etc/passwd");
                 _exit(1);
         }
         buf[9] = '\0';
         printf("/etc/passwd: %s\n", buf);
         close(fd);
 }
 int main(int argc, char * argv[])
 {
         printf("Before aa_stack_profile():\n");
         read_passwd();
         /* stack the "i_cant_be_trusted_anymore" profile, which
          * should not have read access to /etc/passwd. */
         if (aa_stack_profile("i_cant_be_trusted_anymore") < 0) {
             perror("Failure changing profile -- aborting");
             _exit(1);
         }
         printf("After aa_stack_profile():\n");
         read_passwd();
         _exit(0);
 }
```

This code example requires a profile similar to the following to be loaded with apparmor_parser(8):

```
 # Confine stack_p to be able to read /etc/passwd and aa_stack_profile()
 # to the 'i_cant_be_trusted_anymore' profile.
 /tmp/stack_p {
     /etc/ld.so.cache          mr,
     /lib/ld-*.so*             mrix,
     /lib/libc*.so*            mr,
     /etc/passwd               r,
     # Needed for aa_stack_profile()
     change-profile -> &i_cant_be_trusted_anymore,
     /usr/lib/libapparmor*.so* mr,
     /proc/[0-9]*/attr/current w,
 }
```

As well as the profile to stack:

```
 profile i_cant_be_trusted_anymore {
     /etc/ld.so.cache      mr,
     /lib/ld-*.so*         mrix,
     /lib/libc*.so*        mr,
 }
```

The output when run:

```
 $ /tmp/stack_p
 Before aa_stack_profile():
 /etc/passwd: root:x:0:
 After aa_stack_profile():
 Failure opening /etc/passwd: Permission denied
 $
```

## BUGS
None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>. Note that using aa_stack_profile(2) without execve(2) provides no memory barriers between different areas of a program; if address space separation is required, then separate processes should be used.

## SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), aa_change_profile(2), aa_getcon(2) and <https://wiki.apparmor.net>.


kqueue

package: libkqueue-devel

title: kqueue(2)

summary: kernel event notification mechanism

text:
# kqueue(2)

## NAME
kqueue, kevent — kernel event notification mechanism

## SYNOPSIS
\#include <sys/types.h>

\#include <sys/event.h>

\#include <sys/time.h>

int

kqueue(void);

int

kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout);

EV_SET(&kev, ident, filter, flags, fflags, data, udata);

## DESCRIPTION
The kqueue() system call provides a generic method of notifying the user when an event happens or a condition holds, based on the results of small pieces of kernel code termed filters. A kevent is identified by the (ident, filter) pair; there may only be one unique kevent per kqueue.

The filter is executed upon the initial registration of a kevent in order to detect whether a preexisting condition is present, and is also executed whenever an event is passed to the filter for evaluation. If the filter determines that the condition should be reported, then the kevent is placed on the kqueue for the user to retrieve.

The filter is also run when the user attempts to retrieve the kevent from the kqueue. If the filter indicates that the condition that triggered the event no longer holds, the kevent is removed from the kqueue and is not returned.

Multiple events which trigger the filter do not result in multiple kevents being placed on the kqueue; instead, the filter will aggregate the events into a single struct kevent. Calling close() on a file descriptor will remove any kevents that reference the descriptor.

The kqueue() system call creates a new kernel event queue and returns a descriptor. The queue is not inherited by a child created with fork(2). However, if rfork(2) is called without the RFFDG flag, then the descriptor table is shared, which will allow sharing of the kqueue between two processes.

The kevent() system call is used to register events with the queue, and return any pending events to the user. The changelist argument is a pointer to an array of kevent structures, as defined in <sys/event.h>. All changes contained in the changelist are applied before any pending events are read from the queue. The nchanges argument gives the size of changelist. The eventlist argument is a pointer to an array of kevent structures. The nevents argument determines the size of eventlist. When nevents is zero, kevent() will return immediately even if there is a timeout specified unlike select(2). If timeout is a non-NULL pointer, it specifies a maximum interval to wait for an event, which will be interpreted as a struct timespec. If timeout is a NULL pointer, kevent() waits indefinitely. To effect a poll, the timeout argument should be non-NULL, pointing to a zero-valued timespec structure. The same array may be used for the changelist and eventlist.

The EV_SET() macro is provided for ease of initializing a kevent structure.

The kevent structure is defined as:

```
struct kevent {
	uintptr_t ident;	/* identifier for this event */
	short	  filter;	/* filter for event */
	u_short	  flags;	/* action flags for kqueue */
	u_int	  fflags;	/* filter flag value */
	intptr_t  data;		/* filter data value */
	void	  *udata;	/* opaque user data identifier */
};
```

The fields of struct kevent are:

ident

Value used to identify this event. The exact interpretation is determined by the attached filter, but often is a file descriptor.

filter

Identifies the kernel filter used to process this event. The pre-defined system filters are described below.

flags

Actions to perform on the event.

fflags

Filter-specific flags.

data

Filter-specific data value.

udata

Opaque user-defined value passed through the kernel unchanged.

The flags field can contain the following values:

EV_ADD

Adds the event to the kqueue. Re-adding an existing event will modify the parameters of the original event, and not result in a duplicate entry. Adding an event automatically enables it, unless overridden by the EV_DISABLE flag.

EV_ENABLE

Permit kevent() to return the event if it is triggered.

EV_DISABLE

Disable the event so kevent() will not return it. The filter itself is not disabled.

EV_DISPATCH

Disable the event source immediately after delivery of an event. See EV_DISABLE above.

EV_DELETE

Removes the event from the kqueue. Events which are attached to file descriptors are automatically deleted on the last close of the descriptor.

EV_RECEIPT

This flag is useful for making bulk changes to a kqueue without draining any pending events. When passed as input, it forces EV_ERROR to always be returned. When a filter is successfully added the data field will be zero.

EV_ONESHOT

Causes the event to return only the first occurrence of the filter being triggered. After the user retrieves the event from the kqueue, it is deleted.

EV_CLEAR

After the event is retrieved by the user, its state is reset. This is useful for filters which report state transitions instead of the current state. Note that some filters may automatically set this flag internally.

EV_EOF

Filters may set this flag to indicate filter-specific EOF condition.

EV_ERROR

See RETURN VALUES below.

The predefined system filters are listed below. Arguments may be passed to and from the filter via the fflags and data fields in the kevent structure.

EVFILT_READ

Takes a descriptor as the identifier, and returns whenever there is data available to read. The behavior of the filter is slightly different depending on the descriptor type. Sockets

Sockets which have previously been passed to listen() return when there is an incoming connection pending. data contains the size of the listen backlog. Other socket descriptors return when there is data to be read, subject to the SO_RCVLOWAT value of the socket buffer. This may be overridden with a per-filter low water mark at the time the filter is added by setting the NOTE_LOWAT flag in fflags, and specifying the new low water mark in data. On return, data contains the number of bytes of protocol data available to read.

If the read direction of the socket has shutdown, then the filter also sets EV_EOF in flags, and returns the socket error (if any) in fflags. It is possible for EOF to be returned (indicating the connection is gone) while there is still data pending in the socket buffer.

Vnodes

Returns when the file pointer is not at the end of file. data contains the offset from current position to end of file, and may be negative.

Fifos, Pipes

Returns when the there is data to read; data contains the number of bytes available. When the last writer disconnects, the filter will set EV_EOF in flags. This may be cleared by passing in EV_CLEAR, at which point the filter will resume waiting for data to become available before returning.

BPF devices

Returns when the BPF buffer is full, the BPF timeout has expired, or when the BPF has “immediate mode” enabled and there is any data to read; data contains the number of bytes available.

EVFILT_WRITE

Takes a descriptor as the identifier, and returns whenever it is possible to write to the descriptor. For sockets, pipes and fifos, data will contain the amount of space remaining in the write buffer. The filter will set EV_EOF when the reader disconnects, and for the fifo case, this may be cleared by use of EV_CLEAR. Note that this filter is not supported for vnodes or BPF devices. For sockets, the low water mark and socket error handling is identical to the EVFILT_READ case.

EVFILT_VNODE

Takes a file descriptor as the identifier and the events to watch for in fflags, and returns when one or more of the requested events occurs on the descriptor. The events to monitor are: NOTE_DELETE

The unlink() system call was called on the file referenced by the descriptor.

NOTE_WRITE

A write occurred on the file referenced by the descriptor.

NOTE_EXTEND

The file referenced by the descriptor was extended.

NOTE_ATTRIB

The file referenced by the descriptor had its attributes changed.

NOTE_LINK

The link count on the file changed.

NOTE_RENAME

The file referenced by the descriptor was renamed.

On return, fflags contains the events which triggered the filter.

EVFILT_SIGNAL

Takes the signal number to monitor as the identifier and returns when the given signal is delivered to the process. This overrides the signal() and sigaction() facilities, and has a higher precedence. The filter will record all attempts to deliver a signal to a process, even if the signal has been marked as SIG_IGN. data returns the number of times the signal has occurred since the last call to kevent(). This filter automatically sets the EV_CLEAR flag internally.

EVFILT_TIMER

Establishes an arbitrary timer identified by ident. When adding a timer, data specifies the timeout period in milliseconds. The timer will be periodic unless EV_ONESHOT is specified. On return, data contains the number of times the timeout has expired since the last call to kevent(). This filter automatically sets the EV_CLEAR flag internally. There is a system wide limit on the number of timers which is controlled by the kern.kq_calloutmax sysctl.

EVFILT_USER

Establishes a user event identified by ident which is not assosicated with any kernel mechanism but is triggered by user level code. The lower 24 bits of the fflags may be used for user defined flags and manipulated using the following: NOTE_FFNOP

Ignore the input fflags.

NOTE_FFAND

Bitwise AND fflags.

NOTE_FFOR

Bitwise OR fflags.

NOTE_COPY

Copy fflags.

NOTE_FFCTRLMASK

Control mask for fflags.

NOTE_FFLAGSMASK

User defined flag mask for fflags.

A user event is triggered for output with the following:

NOTE_TRIGGER

Cause the event to be triggered.

On return, fflags contains the users defined flags in the lower 24 bits.

## RETURN VALUES
The kqueue() system call creates a new kernel event queue and returns a file descriptor. If there was an error creating the kernel event queue, a value of -1 is returned and errno set.

The kevent() system call returns the number of events placed in the eventlist, up to the value given by nevents. If an error occurs while processing an element of the changelist and there is enough room in the eventlist, then the event will be placed in the eventlist with EV_ERROR set in flags and the system error in data. Otherwise, -1 will be returned, and errno will be set to indicate the error condition. If the time limit expires, then kevent() returns 0.

## ERRORS
The kqueue() system call fails if:

[ENOMEM]

The kernel failed to allocate enough memory for the kernel queue.

[EMFILE]

The per-process descriptor table is full.

[ENFILE]

The system file table is full.

The kevent() system call fails if:

[EACCES]

The process does not have permission to register a filter.

[EFAULT]

There was an error reading or writing the kevent structure.

[EBADF]

The specified descriptor is invalid.

[EINTR]

A signal was delivered before the timeout expired and before any events were placed on the kqueue for return.

[EINVAL]

The specified time limit or filter is invalid.

[ENOENT]

The event could not be found to be modified or deleted.

[ENOMEM]

No memory was available to register the event or, in the special case of a timer, the maximum number of timers has been exceeded. This maximum is configurable via the kern.kq_calloutmax sysctl.

[ESRCH]

The specified process to attach to does not exist.

## SEE ALSO
aio_error(2), aio_read(2), aio_return(2), poll(2), read(2), select(2), sigaction(2), write(2), signal(3)

## HISTORY
The kqueue() and kevent() system calls first appeared in FreeBSD 4.1.

## AUTHORS
The kqueue() system and this manual page were written by Jonathan Lemon ⟨jlemon@FreeBSD.org⟩.


package: libnvme-devel

title: nbft_control(2)

text:
# nbft_control(2)

## NAME
struct nbft_control - NBFT Table - Control Descriptor (Figure 8)

## SYNOPSIS
struct nbft_control {

__u8 structure_id;

__u8 major_revision;

__u8 minor_revision;

__u8 reserved1;

__le16 csl;

__u8 flags;

__u8 reserved2;

struct nbft_heap_obj hdesc;

__u8 hsv;

__u8 reserved3;

__le32 hfio;

__le16 hfil;

__u8 hfiv;

__u8 num_hfi;

__le32 ssnso;

__le16 ssnsl;

__u8 ssnsv;

__u8 num_ssns;

__le32 seco;

__le16 secl;

__u8 secv;

__u8 num_sec;

__le32 disco;

__le16 discl;

__u8 discv;

__u8 num_disc;

__u8 reserved4[16];

};

## Members
structure_id

Structure ID: This field specifies the element (refer to enum nbft_desc_type). This field shall be set to 1h (i.e., Control, #NBFT_DESC_CONTROL).

major_revision

Major Revision: The major revision of the structure corresponding to the Signature field. Larger major revision numbers should not be assumed backward compatible to lower major revision numbers with the same signature.

minor_revision

Minor Revision: The minor revision of the structure corresponding to the signature field. If the major revision numbers are the same, any minor revision number differences shall be backwards compatible with the same signature.

reserved1

Reserved.

csl

Control Structure Length (CSL): This field indicates the length in bytes of the Control Descriptor.

flags

Flags, see enum nbft_control_flags.

reserved2

Reserved.

hdesc

Host Descriptor (HDESC): This field indicates the location and length of the Host Descriptor (see struct nbft_host).

hsv

Host Descriptor Version (HSV): This field indicates the version of the Host Descriptor.

reserved3

Reserved.

hfio

HFI Descriptor List Offset (HFIO): If this field is set to a non-zero value, then this field indicates the offset in bytes of the HFI Descriptor List, if any, from byte offset 0h of the NBFT Table Header. If the num_hfi field is cleared to 0h, then this field is reserved.

hfil

HFI Descriptor Length (HFIL): This field indicates the length in bytes of each HFI Descriptor, if any. If the num_hfi field is cleared to 0h, then this field is reserved.

hfiv

HFI Descriptor Version (HFIV): This field indicates the version of each HFI Descriptor.

num_hfi

Number of Host Fabric Interface Descriptors (NumHFI): This field indicates the number of HFI Descriptors (see struct nbft_hfi) in the HFI Descriptor List, if any. If no interfaces have been configured, then this field shall be cleared to 0h.

ssnso

SSNS Descriptor List Offset (SSNSO):: This field indicates the offset in bytes of the SSNS Descriptor List, if any, from byte offset 0h of the NBFT Table Header. If the num_ssns field is cleared to 0h, then this field is reserved.

ssnsl

SSNS Descriptor Length (SSNSL): This field indicates the length in bytes of each SSNS Descriptor, if any. If the num_ssns field is cleared to 0h, then this field is reserved.

ssnsv

SSNS Descriptor Version (SSNSV): This field indicates the version of the SSNS Descriptor.

num_ssns

Number of Subsystem and Namespace Descriptors (NumSSNS): This field indicates the number of Subsystem Namespace (SSNS) Descriptors (see struct nbft_ssns) in the SSNS Descriptor List, if any.

seco

Security Profile Descriptor List Offset (SECO): This field indicates the offset in bytes of the Security Profile Descriptor List, if any, from byte offset 0h of the NBFT Table Header. If the num_sec field is cleared to 0h, then this field is reserved.

secl

Security Profile Descriptor Length (SECL): This field indicates the length in bytes of each Security Profile Descriptor, if any. If the num_sec field is cleared to 0h, then this field is reserved.

secv

Security Profile Descriptor Version (SECV): This field indicates the version of the Security Profile Descriptor.

num_sec

Number of Security Profile Descriptors (NumSec): This field indicates the number of Security Profile Descriptors (see struct nbft_security), if any, in the Security Profile Descriptor List.

disco

Discovery Descriptor Offset (DISCO): This field indicates the offset in bytes of the Discovery Descriptor List, if any, from byte offset 0h of the NBFT Table Header. If the num_disc field is cleared to 0h, then this field is reserved.

discl

Discovery Descriptor Length (DISCL): This field indicates the length in bytes of each Discovery Descriptor, if any. If the num_disc field is cleared to 0h, then this field is reserved.

discv

Discovery Descriptor Version (DISCV): This field indicates the version of the Discovery Descriptor.

num_disc

Number of Discovery Descriptors (NumDisc): This field indicates the number of Discovery Descriptors (see struct nbft_discovery), if any, in the Discovery Descriptor List, if any.

reserved4

Reserved.


title: nbft_control_flags(2)

summary: Control Descriptor Flags

text:
# nbft_control_flags(2)

## NAME
enum nbft_control_flags - Control Descriptor Flags

## SYNOPSIS
enum nbft_control_flags {

NBFT_CONTROL_VALID

};

## Constants
NBFT_CONTROL_VALID

Block Valid: indicates that the structure is valid.


title: nbft_desc_type(2)

text:
# nbft_desc_type(2)

## NAME
enum nbft_desc_type - NBFT Elements - Descriptor Types (Figure 5)

## SYNOPSIS
enum nbft_desc_type {

NBFT_DESC_HEADER ,

NBFT_DESC_CONTROL ,

NBFT_DESC_HOST ,

NBFT_DESC_HFI ,

NBFT_DESC_SSNS ,

NBFT_DESC_SECURITY ,

NBFT_DESC_DISCOVERY ,

NBFT_DESC_HFI_TRINFO ,

NBFT_DESC_RESERVED_8 ,

NBFT_DESC_SSNS_EXT_INFO

};

## Constants
NBFT_DESC_HEADER

Header: an ACPI structure header with some additional NBFT specific info.

NBFT_DESC_CONTROL

Control Descriptor: indicates the location of host, HFI, SSNS, security, and discovery descriptors.

NBFT_DESC_HOST

Host Descriptor: host information.

NBFT_DESC_HFI

HFI Descriptor: an indexable table of HFI Descriptors, one for each fabric interface on the host.

NBFT_DESC_SSNS

Subsystem Namespace Descriptor: an indexable table of SSNS Descriptors.

NBFT_DESC_SECURITY

Security Descriptor: an indexable table of Security descriptors.

NBFT_DESC_DISCOVERY

Discovery Descriptor: an indexable table of Discovery Descriptors.

NBFT_DESC_HFI_TRINFO

HFI Transport Descriptor: indicated by an HFI Descriptor, corresponds to a specific transport for a single HFI.

NBFT_DESC_RESERVED_8

Reserved.

NBFT_DESC_SSNS_EXT_INFO

SSNS Extended Info Descriptor: indicated by an SSNS Descriptor if required.


title: nbft_discovery(2)

summary: Discovery Descriptor (Figure 24)

text:
# nbft_discovery(2)

## NAME
struct nbft_discovery - Discovery Descriptor (Figure 24)

## SYNOPSIS
struct nbft_discovery {

__u8 structure_id;

__u8 flags;

__u8 index;

__u8 hfi_index;

__u8 sec_index;

__u8 reserved1;

struct nbft_heap_obj discovery_ctrl_addr_obj;

struct nbft_heap_obj discovery_ctrl_nqn_obj;

__u8 reserved2[14];

};

## Members
structure_id

Structure ID: This field shall be set to 6h (i.e., Discovery Descriptor; #NBFT_DESC_DISCOVERY).

flags

Discovery Descriptor Flags, see enum nbft_discovery_flags.

index

Discovery Descriptor Index: This field indicates the number of this Discovery Descriptor in the Discovery Descriptor List.

hfi_index

HFI Descriptor Index: This field indicates the value of the HFI Descriptor Index field of the HFI Descriptor associated with this Discovery Descriptor. If multiple HFIs share a common Discovery controller, there shall be multiple Discovery Descriptor entries with one per HFI.

sec_index

Security Profile Descriptor Index: This field indicates the value of the Security Profile Descriptor Index field of the Security Descriptor associated with this Discovery Descriptor.

reserved1

Reserved.

discovery_ctrl_addr_obj

Discovery Controller Address Heap Object Reference: This field indicates the location and size of a heap object containing a URI which indicates an NVMe Discovery controller associated with this Discovery Descriptor. If this field is cleared to 0h, then no URI is specified.

discovery_ctrl_nqn_obj

Discovery Controller NQN Heap Object Reference: If set to a non-zero value, this field indicates the location and size of a heap object containing an NVMe Discovery controller NQN. If the NVMe Discovery controller referenced by this record requires secure authentication with a well known Subsystem NQN, this field indicates the unique NQN for that NVMe Discovery controller. This record is involved formatted as an NQN string. If this field is cleared to 0h, then this field is reserved and the OS shall use the well known discovery NQN for this record.

reserved2

Reserved.


title: nbft_discovery_flags(2)

summary: Discovery Descriptor Flags

text:
# nbft_discovery_flags(2)

## NAME
enum nbft_discovery_flags - Discovery Descriptor Flags

## SYNOPSIS
enum nbft_discovery_flags {

NBFT_DISCOVERY_VALID

};

## Constants
NBFT_DISCOVERY_VALID

Descriptor Valid: if set to 1h, then this descriptor is valid. If cleared to 0h, then this descriptor is reserved.


title: nbft_header(2)

summary: NBFT Table - Header (Figure 8)

text:
# nbft_header(2)

## NAME
struct nbft_header - NBFT Table - Header (Figure 8)

## SYNOPSIS
struct nbft_header {

char signature[4];

__le32 length;

__u8 major_revision;

__u8 checksum;

char oem_id[6];

char oem_table_id[8];

__le32 oem_revision;

__le32 creator_id;

__le32 creator_revision;

__le32 heap_offset;

__le32 heap_length;

struct nbft_heap_obj driver_dev_path_sig;

__u8 minor_revision;

__u8 reserved[13];

};

## Members
signature

Signature: An ASCII string representation of the table identifier. This field shall be set to the value 4E424654h (i.e. "NBFT", see #NBFT_HEADER_SIG).

length

Length: The length of the table, in bytes, including the header, starting from offset 0h. This field is used to record the size of the entire table.

major_revision

Major Revision: The major revision of the structure corresponding to the Signature field. Larger major revision numbers should not be assumed backward compatible to lower major revision numbers with the same signature.

checksum

Checksum: The entire table, including the Checksum field, shall sum to 0h to be considered valid.

oem_id

OEMID shall be populated by the NBFT driver writer by an OEM-supplied string that identifies the OEM. All trailing bytes shall be NULL.

oem_table_id

OEM Table ID: This field shall be populated by the NBFT driver writer with an OEM-supplied string that the OEM uses to identify the particular data table. This field is particularly useful when defining a definition block to distinguish definition block functions. The OEM assigns each dissimilar table a new OEM Table ID.

oem_revision

OEM Revision: An OEM-supplied revision number. Larger numbers are assumed to be newer revisions.

creator_id

Creator ID: Vendor ID of utility that created the table. For instance, this may be the ID for the ASL Compiler.

creator_revision

Creator Revision: Revision of utility that created the table. For instance, this may be the ID for the ASL Compiler.

heap_offset

Heap Offset (HO): This field indicates the offset in bytes of the heap, if any, from byte offset 0h of the NBFT Table Header.

heap_length

Heap Length (HL): The length of the heap, if any.

driver_dev_path_sig

Driver Signature Heap Object Reference: This field indicates the offset in bytes of a heap object containing the Driver Signature, if any, from byte offset 0h of the NBFT Table Header.

minor_revision

Minor Revision: The minor revision of the structure corresponding to the Signature field. If the major revision numbers are the same, any minor revision number differences shall be backwards compatible with the same signature.

reserved

Reserved.


title: nbft_heap_obj(2)

summary: NBFT Header Driver Signature

text:
# nbft_heap_obj(2)

## NAME
struct nbft_heap_obj - NBFT Header Driver Signature

## SYNOPSIS
struct nbft_heap_obj {

__le32 offset;

__le16 length;

};

## Members
offset

Offset in bytes of the heap object, if any, from byte offset 0h of the NBFT Table Header.

length

Length in bytes of the heap object, if any.


title: nbft_hfi(2)

text:
# nbft_hfi(2)

## NAME
struct nbft_hfi - Host Fabric Interface (HFI) Descriptor (Figure 11)

## SYNOPSIS
struct nbft_hfi {

__u8 structure_id;

__u8 index;

__u8 flags;

__u8 trtype;

__u8 reserved1[12];

struct nbft_heap_obj trinfo_obj;

__u8 reserved2[10];

};

## Members
structure_id

Structure ID: This field shall be set to 3h (i.e., Host Fabric Interface Descriptor; #NBFT_DESC_HFI).

index

HFI Descriptor Index: This field indicates the number of this HFI Descriptor in the Host Fabric Interface Descriptor List.

flags

HFI Descriptor Flags, see enum nbft_hfi_flags.

trtype

HFI Transport Type, see enum nbft_trtype.

reserved1

Reserved.

trinfo_obj

HFI Transport Info Descriptor Heap Object Reference: If this field is set to a non-zero value, then this field indicates the location and size of a heap object containing a HFI Transport Info.

reserved2

Reserved.


title: nbft_hfi_flags(2)

summary: HFI Descriptor Flags

text:
# nbft_hfi_flags(2)

## NAME
enum nbft_hfi_flags - HFI Descriptor Flags

## SYNOPSIS
enum nbft_hfi_flags {

NBFT_HFI_VALID

};

## Constants
NBFT_HFI_VALID

Descriptor Valid: If set to 1h, then this descriptor is valid. If cleared to 0h, then this descriptor is reserved.


title: nbft_hfi_info_tcp(2)

text:
# nbft_hfi_info_tcp(2)

## NAME
struct nbft_hfi_info_tcp - HFI Transport Info Descriptor - NVMe/TCP (Figure 13)

## SYNOPSIS
struct nbft_hfi_info_tcp {

__u8 structure_id;

__u8 version;

__u8 trtype;

__u8 trinfo_version;

__le16 hfi_index;

__u8 flags;

__le32 pci_sbdf;

__u8 mac_addr[6];

__le16 vlan;

__u8 ip_origin;

__u8 ip_address[16];

__u8 subnet_mask_prefix;

__u8 ip_gateway[16];

__u8 reserved1;

__le16 route_metric;

__u8 primary_dns[16];

__u8 secondary_dns[16];

__u8 dhcp_server[16];

struct nbft_heap_obj host_name_obj;

__u8 reserved2[18];

};

## Members
structure_id

Structure ID: This field shall be set to 7h (i.e., HFI Transport Info; #NBFT_DESC_HFI_TRINFO).

version

Version: This field shall be set to 1h.

trtype

HFI Transport Type, see enum nbft_trtype: This field shall be set to 03h (i.e., NVMe/TCP; #NBFT_TRTYPE_TCP).

trinfo_version

Transport Info Version: Implementations compliant to this specification shall set this field to 1h.

hfi_index

HFI Descriptor Index: The value of the HFI Descriptor Index field of the HFI Descriptor (see struct nbft_hfi.index) whose HFI Transport Info Descriptor Heap Object Reference field indicates this HFI Transport Info Descriptor.

flags

HFI Transport Flags, see enum nbft_hfi_info_tcp_flags.

pci_sbdf

PCI Express Routing ID for the HFI Transport Function: This field indicates the PCI Express Routing ID as specified in the PCI Express Base Specification.

mac_addr

MAC Address: The MAC address of this HFI, in EUI-48TM format, as defined in the IEEE Guidelines for Use of Extended Unique Identifiers. This field shall be set to a non-zero value.

vlan

VLAN: If this field is set to a non-zero value, then this field contains the VLAN identifier if the VLAN associated with this HFI, as defined in IEEE 802.1q-2018. If no VLAN is associated with this HFI, then this field shall be cleared to 0h.

ip_origin

IP Origin: If this field is set to a non-zero value, then this field indicates the source of Ethernet L3 configuration information used by the driver for this interface. Valid values are defined in the Win 32 API: NL_PREFIX_ORIGIN enumeration specification. This field should be cleared to 0h if the IP Origin field is unused by driver.

ip_address

IP Address: This field indicates the IPv4 or IPv6 address of this HFI. This field shall be set to a non-zero value.

subnet_mask_prefix

Subnet Mask Prefix: This field indicates the IPv4 or IPv6 subnet mask in CIDR routing prefix notation.

ip_gateway

IP Gateway: If this field is set to a non-zero value, this field indicates the IPv4 or IPv6 address of the IP gateway for this HFI. If this field is cleared to 0h, then no IP gateway is specified.

reserved1

Reserved.

route_metric

Route Metric: If this field is set to a non-zero value, this field indicates the cost value for the route indicated by this HF. This field contains the value utilized by the pre-OS driver when chosing among all available routes. Lower values relate to higher priority. Refer to IETF RFC 4249. If the pre-OS driver supports routing and did not configure a specific route metric for this interface, then the pre-OS driver should set this value to 500. If the pre-OS driver does not support routing, then this field should be cleared to 0h.

primary_dns

Primary DNS: If this field is set to a non-zero value, this field indicates the IPv4 or IPv6 address of the Primary DNS server for this HFI, if any, from byte offset 0h of the NBFT Table Header. If this field is cleared to 0h, then no Primary DNS is specified.

secondary_dns

Secondary DNS: If this field is set to a non-zero value, this field indicates the IPv4 or IPv6 address of the Secondary DNS server for this HFI, if any, from byte offset 0h of the NBFT Table Header. If this field is cleared to 0h, then no Secondary DNS is specified.

dhcp_server

DHCP Server: If the DHCP Override bit is set to 1h, then this field indicates the IPv4 or IPv6 address of the DHCP server used to assign this HFI address. If that bit is cleared to 0h, then this field is reserved.

host_name_obj

Host Name Heap Object Reference: If this field is set to a non-zero value, then this field indicates the location and size of a heap object containing a Host Name string.

reserved2

Reserved.


title: nbft_hfi_info_tcp_flags(2)

summary: HFI Transport Flags

text:
# nbft_hfi_info_tcp_flags(2)

## NAME
enum nbft_hfi_info_tcp_flags - HFI Transport Flags

## SYNOPSIS
enum nbft_hfi_info_tcp_flags {

NBFT_HFI_INFO_TCP_VALID ,

NBFT_HFI_INFO_TCP_GLOBAL_ROUTE ,

NBFT_HFI_INFO_TCP_DHCP_OVERRIDE

};

## Constants
NBFT_HFI_INFO_TCP_VALID

Descriptor Valid: if set to 1h, then this descriptor is valid. If cleared to 0h, then this descriptor is reserved.

NBFT_HFI_INFO_TCP_GLOBAL_ROUTE

Global Route vs. Link Local Override Flag: if set to 1h, then the BIOS utilized this interface described by HFI to be the default route with highest priority. If cleared to 0h, then routes are local to their own scope.

NBFT_HFI_INFO_TCP_DHCP_OVERRIDE

DHCP Override: if set to 1, then HFI information was populated by consuming the DHCP on this interface. If cleared to 0h, then the HFI information was set administratively by a configuration interface to the driver and pre-OS envrionment.


title: nbft_host(2)

summary: Host Descriptor (Figure 9)

text:
# nbft_host(2)

## NAME
struct nbft_host - Host Descriptor (Figure 9)

## SYNOPSIS
struct nbft_host {

__u8 structure_id;

__u8 flags;

__u8 host_id[16];

struct nbft_heap_obj host_nqn_obj;

__u8 reserved[8];

};

## Members
structure_id

Structure ID: This field shall be set to 2h (i.e., Host Descriptor; #NBFT_DESC_HOST).

flags

Host Flags, see enum nbft_host_flags.

host_id

Host ID: This field shall be set to the Host Identifier. This field shall not be empty if the NBFT and NVMe Boot are supported by the Platform.

host_nqn_obj

Host NQN Heap Object Reference: this field indicates a heap object containing a Host NQN. This object shall not be empty if the NBFT and NVMe Boot are supported by the Platform.

reserved

Reserved.


title: nbft_host_flags(2)

summary: Host Flags

text:
# nbft_host_flags(2)

## NAME
enum nbft_host_flags - Host Flags

## SYNOPSIS
enum nbft_host_flags {

NBFT_HOST_VALID ,

NBFT_HOST_HOSTID_CONFIGURED ,

NBFT_HOST_HOSTNQN_CONFIGURED ,

NBFT_HOST_PRIMARY_ADMIN_MASK ,

NBFT_HOST_PRIMARY_ADMIN_NOT_INDICATED ,

NBFT_HOST_PRIMARY_ADMIN_UNSELECTED ,

NBFT_HOST_PRIMARY_ADMIN_SELECTED

};

## Constants
NBFT_HOST_VALID

Descriptor Valid: If set to 1h, then this descriptor is valid. If cleared to 0h, then this descriptor is reserved.

NBFT_HOST_HOSTID_CONFIGURED

HostID Configured: If set to 1h, then the Host ID field contains an administratively-configured value. If cleared to 0h, then the Host ID field contains a driver default value.

NBFT_HOST_HOSTNQN_CONFIGURED

Host NQN Configured: If set to 1h, then the Host NQN indicated by the Host NQN Heap Object Reference field (struct nbft_host.host_nqn) contains an administratively-configured value. If cleared to 0h, then the Host NQN indicated by the Host NQN Offset field contains a driver default value.

NBFT_HOST_PRIMARY_ADMIN_MASK

Mask to get Primary Administrative Host Descriptor: indicates whether the Host Descriptor in this NBFT was selected as the primary NBFT for administrative purposes of platform identity as a hint to the OS. If multiple NBFT tables are present, only one NBFT should be administratively selected. There is no enforcement mechanism for this to be coordinated between multiple NBFT tables, but this field should be set to Selected (#NBFT_HOST_PRIMARY_ADMIN_SELECTED) if more than one NBFT is present.

NBFT_HOST_PRIMARY_ADMIN_NOT_INDICATED

Not Indicated by Driver: The driver that created this NBFT provided no administrative priority hint for this NBFT.

NBFT_HOST_PRIMARY_ADMIN_UNSELECTED

Unselected: The driver that created this NBFT explicitly indicated that this NBFT should not be prioritized over any other NBFT.

NBFT_HOST_PRIMARY_ADMIN_SELECTED

Selected: The driver that created this NBFT explicitly indicated that this NBFT should be prioritized over any other NBFT.


title: nbft_info(2)

summary: The parsed NBFT table data.

text:
# nbft_info(2)

## NAME
struct nbft_info - The parsed NBFT table data.

## SYNOPSIS
struct nbft_info {

char *filename;

__u8 *raw_nbft;

ssize_t raw_nbft_size;

struct nbft_info_host host;

struct nbft_info_hfi **hfi_list;

struct nbft_info_security **security_list;

struct nbft_info_discovery **discovery_list;

struct nbft_info_subsystem_ns **subsystem_ns_list;

};

## Members
filename

Path to the NBFT table.

raw_nbft

The original NBFT table contents.

raw_nbft_size

Size of raw_nbft.

host

The Host Descriptor (should match other NBFTs).

hfi_list

The HFI Descriptor List (null-terminated array).

security_list

The Security Profile Descriptor List (null-terminated array).

discovery_list

The Discovery Descriptor List (null-terminated array).

subsystem_ns_list

The SSNS Descriptor List (null-terminated array).


title: nbft_info_discovery(2)

summary: Discovery Descriptor

text:
# nbft_info_discovery(2)

## NAME
struct nbft_info_discovery - Discovery Descriptor

## SYNOPSIS
struct nbft_info_discovery {

int index;

struct nbft_info_security *security;

struct nbft_info_hfi *hfi;

char *uri;

char *nqn;

};

## Members
index

The number of this Discovery Descriptor in the Discovery Descriptor List.

security

The Security Profile Descriptor, see struct nbft_info_security.

hfi

The HFI Descriptor associated with this Discovery Descriptor. See struct nbft_info_hfi.

uri

A URI which indicates an NVMe Discovery controller associated with this Discovery Descriptor.

nqn

An NVMe Discovery controller NQN.


title: nbft_info_hfi(2)

summary: Host Fabric Interface (HFI) Descriptor

text:
# nbft_info_hfi(2)

## NAME
struct nbft_info_hfi - Host Fabric Interface (HFI) Descriptor

## SYNOPSIS
struct nbft_info_hfi {

int index;

char transport[8];

struct nbft_info_hfi_info_tcp tcp_info;

};

## Members
index

HFI Descriptor Index: indicates the number of this HFI Descriptor in the Host Fabric Interface Descriptor List.

transport

Transport Type string (e.g. 'tcp').

tcp_info

The HFI Transport Info Descriptor, see struct nbft_info_hfi_info_tcp.


title: nbft_info_hfi_info_tcp(2)

text:
# nbft_info_hfi_info_tcp(2)

## NAME
struct nbft_info_hfi_info_tcp - HFI Transport Info Descriptor - NVMe/TCP

## SYNOPSIS
struct nbft_info_hfi_info_tcp {

__u32 pci_sbdf;

__u8 mac_addr[6];

__u16 vlan;

__u8 ip_origin;

char ipaddr[40];

__u8 subnet_mask_prefix;

char gateway_ipaddr[40];

__u16 route_metric;

char primary_dns_ipaddr[40];

char secondary_dns_ipaddr[40];

char dhcp_server_ipaddr[40];

char *host_name;

bool this_hfi_is_default_route;

bool dhcp_override;

};

## Members
pci_sbdf

PCI Express Routing ID for the HFI Transport Function.

mac_addr

MAC Address: The MAC address of this HFI, in EUI-48TM format.

vlan

The VLAN identifier if the VLAN is associated with this HFI, as defined in IEEE 802.1q-2018 or zeroes if no VLAN is associated with this HFI.

ip_origin

The source of Ethernet L3 configuration information used by the driver or 0 if not used.

ipaddr

The IPv4 or IPv6 address of this HFI.

subnet_mask_prefix

The IPv4 or IPv6 subnet mask in CIDR routing prefix notation.

gateway_ipaddr

The IPv4 or IPv6 address of the IP gateway for this HFI or zeroes if no IP gateway is specified.

route_metric

The cost value for the route indicated by this HFI.

primary_dns_ipaddr

The IPv4 or IPv6 address of the Primary DNS server for this HFI.

secondary_dns_ipaddr

The IPv4 or IPv6 address of the Secondary DNS server for this HFI.

dhcp_server_ipaddr

The IPv4 or IPv6 address of the DHCP server used to assign this HFI address.

host_name

The Host Name string.

this_hfi_is_default_route

If True, then the BIOS utilized this interface described by HFI to be the default route with highest priority. If False, then routes are local to their own scope.

dhcp_override

If True, then HFI information was populated by consuming the DHCP on this interface. If False, then the HFI information was set administratively by a configuration interface to the driver and pre-OS envrionment.


title: nbft_info_host(2)

summary: Host Descriptor

text:
# nbft_info_host(2)

## NAME
struct nbft_info_host - Host Descriptor

## SYNOPSIS
struct nbft_info_host {

unsigned char *id;

char *nqn;

bool host_id_configured;

bool host_nqn_configured;

enum nbft_info_primary_admin_host_flag primary;

};

## Members
id

Host ID (raw UUID, length = 16 bytes).

nqn

Host NQN.

host_id_configured

HostID Configured Flag: value of True indicates that id contains administratively-configured value, or driver default value if False.

host_nqn_configured

Host NQN Configured Flag: value of True indicates that nqn contains administratively-configured value, or driver default value if False.

primary

Primary Administrative Host Descriptor, see enum nbft_info_primary_admin_host_flag.


title: nbft_info_nid_type(2)

summary: Namespace Identifier Type (NIDT)

text:
# nbft_info_nid_type(2)

## NAME
enum nbft_info_nid_type - Namespace Identifier Type (NIDT)

## SYNOPSIS
enum nbft_info_nid_type {

NBFT_INFO_NID_TYPE_NONE ,

NBFT_INFO_NID_TYPE_EUI64 ,

NBFT_INFO_NID_TYPE_NGUID ,

NBFT_INFO_NID_TYPE_NS_UUID

};

## Constants
NBFT_INFO_NID_TYPE_NONE

No identifier available.

NBFT_INFO_NID_TYPE_EUI64

The EUI-64 identifier.

NBFT_INFO_NID_TYPE_NGUID

The NSGUID identifier.

NBFT_INFO_NID_TYPE_NS_UUID

The UUID identifier.


title: nbft_info_primary_admin_host_flag(2)

text:
# nbft_info_primary_admin_host_flag(2)

## NAME
enum nbft_info_primary_admin_host_flag - Primary Administrative Host Descriptor Flags

## SYNOPSIS
enum nbft_info_primary_admin_host_flag {

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_NOT_INDICATED ,

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_UNSELECTED ,

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_SELECTED ,

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_RESERVED

};

## Constants
NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_NOT_INDICATED

Not Indicated by Driver: The driver that created this NBFT provided no administrative priority hint for this NBFT.

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_UNSELECTED

Unselected: The driver that created this NBFT explicitly indicated that this NBFT should not be prioritized over any other NBFT.

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_SELECTED

Selected: The driver that created this NBFT explicitly indicated that this NBFT should be prioritized over any other NBFT.

NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_RESERVED

Reserved.


title: nbft_info_security(2)

summary: Security Profile Descriptor

text:
# nbft_info_security(2)

## NAME
struct nbft_info_security - Security Profile Descriptor

## SYNOPSIS
struct nbft_info_security {

int index;

};

## Members
index

The number of this Security Profile Descriptor in the Security Profile Descriptor List.


title: nbft_info_subsystem_ns(2)

summary: Subsystem Namespace (SSNS) info

text:
# nbft_info_subsystem_ns(2)

## NAME
struct nbft_info_subsystem_ns - Subsystem Namespace (SSNS) info

## SYNOPSIS
struct nbft_info_subsystem_ns {

int index;

struct nbft_info_discovery *discovery;

struct nbft_info_security *security;

int num_hfis;

struct nbft_info_hfi **hfis;

char transport[8];

char traddr[40];

char *trsvcid;

__u16 subsys_port_id;

__u32 nsid;

enum nbft_info_nid_type nid_type;

__u8 *nid;

char *subsys_nqn;

bool pdu_header_digest_required;

bool data_digest_required;

int controller_id;

int asqsz;

char *dhcp_root_path_string;

bool discovered;

bool unavailable;

};

## Members
index

SSNS Descriptor Index in the descriptor list.

discovery

Primary Discovery Controller associated with this SSNS Descriptor.

security

Security Profile Descriptor associated with this namespace.

num_hfis

Number of HFIs.

hfis

List of HFIs associated with this namespace. Includes the primary HFI at the first position and all secondary HFIs. This array is null-terminated.

transport

Transport Type string (e.g. 'tcp').

traddr

Subsystem Transport Address.

trsvcid

Subsystem Transport Service Identifier.

subsys_port_id

The Subsystem Port ID.

nsid

The Namespace ID of this descriptor or when nid should be used instead.

nid_type

Namespace Identifier Type, see enum nbft_info_nid_type.

nid

The Namespace Identifier value.

subsys_nqn

Subsystem and Namespace NQN.

pdu_header_digest_required

PDU Header Digest (HDGST) Flag: the use of NVM Header Digest Enabled is required.

data_digest_required

Data Digest (DDGST) Flag: the use of NVM Data Digest Enabled is required.

controller_id

Controller ID (SSNS Extended Information Descriptor): The controller ID associated with the Admin Queue or 0 if not supported.

asqsz

Admin Submission Queue Size (SSNS Extended Information Descriptor) or 0 if not supported.

dhcp_root_path_string

DHCP Root Path Override string (SSNS Extended Information Descriptor).

discovered

Indicates that this namespace was acquired through discovery.

unavailable

Namespace is unavailable as indicated by the pre-OS driver.