FSATTR(7)            Standards, Environments, and Macros           FSATTR(7)
NAME
       fsattr - extended file attributes
DESCRIPTION
       Attributes are logically supported as files within the file system.
       The file system is therefore augmented with an orthogonal name space
       of file attributes.  Any file (including attribute files) can have an
       arbitrarily deep attribute tree associated with it. Attribute values
       are accessed by file descriptors obtained through a special attribute
       interface.  This logical view of "attributes as files" allows the
       leveraging of existing file system interface functionality to support
       the construction, deletion, and manipulation of attributes.
       The special files "." and ".." retain their accustomed semantics
       within the attribute hierarchy.  The "." attribute file refers to the
       current directory and the ".." attribute file refers to the parent
       directory.  The unnamed directory at the head of each attribute tree
       is considered the "child" of the file it is associated with and the
       ".." file refers to the associated file.  For any non-directory file
       with attributes, the ".." entry in the unnamed directory refers to a
       file that is not a directory.
       Conceptually, the attribute model is fully general. Extended
       attributes can be any type of file (doors, links, directories, and so
       forth) and can even have their own attributes (fully recursive).  As
       a result, the attributes associated with a file could be an
       arbitrarily deep directory hierarchy where each attribute could have
       an equally complex attribute tree associated with it.  Not all
       implementations are able to, or want to, support the full model.
       Implementation are therefore permitted to reject operations that are
       not supported.  For example, the implementation for the UFS file
       system allows only regular files as attributes (for example, no sub-
       directories) and rejects attempts to place attributes on attributes.
       The following list details the operations that are rejected in the
       current implementation:       
link                                Any attempt to create links between
                                attribute and non-attribute space is
                                rejected to prevent security-related or
                                otherwise sensitive attributes from being
                                exposed, and therefore manipulable, as
                                regular files.       
rename                                Any attempt to rename between attribute and
                                non-attribute space is rejected to prevent
                                an already linked file from being renamed
                                and thereby circumventing the 
link                                restriction above.       
mkdir, 
symlink, 
mknod                                Any attempt to create a "non-regular" file
                                in attribute space is rejected to reduce the
                                functionality, and therefore exposure and
                                risk, of the initial implementation.
       The entire available name space has been allocated to "general use"
       to bring the implementation in line with the NFSv4 draft standard
       [NFSv4]. That standard defines "named attributes" (equivalent to
       Solaris Extended Attributes) with no naming restrictions.  All Sun
       applications making use of opaque extended attributes will use the
       prefix "SUNW".   
Shell-level API       The command interface for extended attributes is the set of
       applications provided by Solaris for the manipulation of attributes
       from the command line.  This interface consists of a set of existing
       utilities that have been extended to be "attribute-aware", plus the       
runat utility designed to "expose" the extended attribute space so
       that extended attributes can be manipulated as regular files.
       The 
-@ option enable utilities to manipulate extended attributes. As
       a rule, this option enables the utility to enter into attribute space
       when the utility is performing a recursive traversal of file system
       space. This is a fully recursive concept. If the underlying file
       system supports recursive attributes and directory structures, the 
-@       option opens these spaces to the file tree-walking algorithms.
       The following utilities accommodate extended attributes (see the
       individual manual pages for details):       
cp               By default, 
cp ignores attributes and copies only file data.
               This is intended to maintain the semantics implied by 
cp               currently, where attributes (such as owner and mode) are not
               copied unless the 
-p option is specified. With the 
-@ (or 
-p)
               option, 
cp attempts to copy all attributes along with the
               file data.       
cpio               The 
-@ option informs 
cpio to archive attributes, but by
               default 
cpio ignores extended attributes. See 
Extended               Archive Formats below for a description of the new archive
               records.       
du               File sizes computed include the space allocated for any
               extended attributes present.       
find               By default, 
find ignores attributes.  The 
-xattr expression
               provides support for searches involving attribute space. It
               returns true if extended attributes are present on the
               current file.       
fsck               The 
fsck utility manages extended attribute data on the disk.
               A file system with extended attributes can be mounted on
               versions of Solaris that are not attribute-aware (versions
               prior to Solaris 9), but the attributes will not be
               accessible and 
fsck will strip them from the files and place
               them in 
lost+found. Once the attributes have been stripped
               the file system is completely stable on Solaris versions that
               are not attribute-aware, but would now be considered
               corrupted on attribute-aware versions of Solaris. The
               attribute-aware 
fsck utility should be run to stabilize the
               file system before using it in an attribute-aware
               environment.       
fsdb               This 
fsdb utility is able to find the inode for the "hidden"
               extended attribute directory.       
ls               The 
ls -@ command displays an "@" following the mode
               information when extended attributes are present.  More
               precisely, the output line for a given file contains an "@"
               character following the mode characters if the 
pathconf(2)               variable 
XATTR_EXISTS is set to true. See the 
pathconf()               section below.  The 
-@ option uses the same general output
               format as the 
-l option.       
mv               When a file is moved, all attributes are carried along with
               the file rename.  When a file is moved across a file system
               boundary, the copy command invoked is similar to the 
cp -p               variant described above and extended attributes are "moved".
               If the extended file attributes cannot be replicated, the
               move operation fails and the source file is not removed.       
pax               The 
-@ option informs 
pax to archive attributes, but by
               default 
pax ignores extended attributes.  The 
pax(1) utility
               is a generic replacement for both 
tar(1) and 
cpio(1) and is
               able to produce either output format in its archive.  See               
Extended Archive Formats below for a description of the new
               archive records.       
tar               In the default case, 
tar does not attempt to place attributes
               in the archive.  If the 
-@ option is specified, however, 
tar               traverses into the attribute space of all files being placed
               in the archive and attempts to add the attributes to the
               archive. A new record type has been introduced for extended
               attribute entries in 
tar archive files (the same is true for               
pax and 
cpio archives) similar to the way ACLs records were
               defined. See 
Extended Archive Formats below for a description
               of the new archive records.
       There is a class of utilities (
chmod, 
chown, 
chgrp) that one might
       expect to be modified in a manner similar to those listed above. For
       example, one might expect that performing 
chmod on a file would not
       only affect the file itself but would also affect at least the
       extended attribute directory if not any existing extended attribute
       files.  This is not the case.  The model chosen for extended
       attributes implies that the attribute directory and the attributes
       themselves are all file objects in their own right, and can therefore
       have independent file status attributes associated with them  (a
       given implementation cannot support this, for example, for intrinsic
       attributes).  The relationship is left undefined and a fine-grained
       control mechanism (
runat(1)) is provided to allow manipulation of
       extended attribute status attributes as necessary.
       The 
runat utility has the following syntax:
         runat 
filename [
command]
       The 
runat utility executes the supplied command in the context of the
       "attribute space" associated with the indicated file.  If no command
       argument is supplied, a shell is invoked. See 
runat(1) for details.   
Application-level API       The primary interface required to access extended attributes at the
       programmatic level is the 
openat(2) function. Once a file descriptor
       has been obtained for an attribute file by an 
openat() call, all
       normal file system semantics apply. There is no attempt to place
       special semantics on 
read(2), 
write(2), 
ftruncate(3C), or other
       functions when applied to attribute file descriptors relative to
       "normal" file descriptors.
       The set of existing attributes can be browsed by calling 
openat()       with "." as the file name and the 
O_XATTR flag set, resulting in a
       file descriptor for the attribute directory.  The list of attributes
       is obtained by calls to 
getdents(2) on the returned file descriptor.
       If the target file did not previously have any attributes associated
       with it, an empty top-level attribute directory is created for the
       file and subsequent 
getdents() calls will return only "." and "..".
       While the owner of the parent file owns the extended attribute
       directory, it is not charged against its quota if the directory is
       empty.  Attribute files themselves, however, are charged against the
       user quota as any other regular file.
       Additional system calls have been provided as convenience functions.
       These include the 
fchownat(2), 
fstatat(2), 
futimesat(2), 
renameat(2),       
unlinkat(2). These new functions, along with 
openat(), provide a
       mechanism to access files relative to an arbitrary point in the file
       system, rather than only the current working directory.  This
       mechanism is particularly useful in situations when a file descriptor
       is available with no path. The 
openat() function, in particular, can
       be used in many contexts where 
chdir() or 
fchdir() is currently
       required.  See 
chdir(2).
   Open a file relative to a file descriptor
         int openat (int 
fd, const char *
path, int 
oflag [, mode_t 
mode])
       The 
openat(2) function behaves exactly as 
open(2) except when given a
       relative path.  Where 
open() resolves a relative path from the
       current working directory, 
openat() resolves the path based on the
       vnode indicated by the supplied file descriptor. When 
oflag is       
O_XATTR, 
openat() interprets the 
path argument as an extended
       attribute reference. The following code fragment uses 
openat() to
       examine the attributes of some already opened file:
         dfd = openat(fd, ".", O_RDONLY|O_XATTR);
         (void)getdents(dfd, buf, nbytes);
       If 
openat() is passed the special value 
AT_FDCWD as its first (
fd)
       argument, its behavior is identical to 
open() and the relative path
       arguments are interpreted relative to the current working directory.
       If the 
O_XATTR flag is provided to 
openat() or to 
open(), the
       supplied path is interpreted as a reference to an extended attribute
       on the current working directory.
   Unlink a file relative to a directory file descriptor
         int unlinkat (int 
dirfd, const char *path
flag, int flag
flag)
       The 
unlinkat(2) function deletes an entry from a directory.  The 
path       argument indicates the name of the entry to remove. If 
path an
       absolute path, the 
dirfd argument is ignored. If it is a relative
       path, it is interpreted relative to the directory indicated by the       
dirfd argument. If 
dirfd does not refer to a valid directory, the
       function returns 
ENOTDIR.  If the special value 
AT_FDCWD is specified
       for 
dirfd, a relative path argument is resolved relative to the
       current working directory.  If the 
flag argument is 0, all other
       semantics of this function are equivalent to 
unlink(2).  If 
flag is
       set to 
AT_REMOVEDIR, all other semantics of this function are
       equivalent to 
rmdir(2).
   Rename a file relative to directories
         int renameat (int 
fromfd, const char *
old, int 
tofd, const char *
new)
       The 
renameat(2) function renames an entry in a directory, possibly
       moving the entry into a different directory.  The 
old argument
       indicates the name of the entry to rename.  If this argument is a
       relative path, it is interpreted relative to the directory indicated
       by the 
fd argument. If it is an absolute path, the 
fromfd argument is
       ignored.  The 
new argument indicates the new name for the entry.  If
       this argument is a relative path, it is interpreted relative to the
       directory indicated by the 
tofd argument. If it is an absolute path,
       the 
tofd argument is ignored.
       In the relative path cases, if the directory file descriptor
       arguments do not refer to a valid directory, the function returns       
ENOTDIR.  All other semantics of this function are equivalent to       
rename(2).
       If a special value 
AT_FDCWD is specified for either the 
fromfd or       
tofd arguments, their associated path arguments (
old and 
new) are
       interpreted relative to the current working directory if they are not
       specified as absolute paths. Any attempt to use 
renameat() to move a
       file that is not an extended attribute into an extended attribute
       directory (so that it becomes an extended attribute) will fail. The
       same is true for an attempt to move a file that is an extended
       attribute into a directory that is not an extended attribute
       directory.
   Obtain information about a file
         int fstatat (int 
fd, const char *
path, struct stat* 
buf, int 
flag)
       The 
fstatat(2) function obtains information about a file.  If the       
path argument is relative, it is resolved relative to the 
fd argument
       file descriptor, otherwise the 
fd argument is ignored.  If the 
fd       argument is a special value 
AT_FDCWD the path is resolved relative to
       the current working directory.  If the 
path argument is a null
       pointer, the function returns information about the file referenced
       by the 
fd argument.  In all other relative path cases, if the 
fd       argument does not refer to a valid directory, the function returns       
ENOTDIR. If 
AT_SYMLINK_NOFOLLOW is set in the 
flag argument, the
       function will not automatically traverse a symbolic link at the
       position of the path. If 
_AT_TRIGGER is set in the 
flag argument and
       the vnode is a trigger mount point, the mount is performed and the
       function returns the attributes of the root of the mounted
       filesystem. The 
fstatat() function is a multipurpose function that
       can be used in place of 
stat(), 
lstat(), or 
fstat(). See 
stat(2)       The function call 
stat(path, buf) is identical to 
fstatat(AT_FDCWD,       
path, buf, 0).
       The function call 
lstat(path, buf) is identical to 
fstatat(AT_FDCWD,       
path, buf, 
AT_SYMLINK_NOFOLLOW)       The function call 
fstat(fildes, buf) is identical to 
fstatat(fildes,       
NULL, 
buf, 
0).
   Set owner and group ID
         int fchownat (int 
fd, const char *
path, uid_t 
owner, gid_t 
group, \
                   int 
flag)
       The 
fchownat(2) function sets the owner ID and group ID for a file.
       If the 
path argument is relative, it is resolved relative to the 
fd       argument file descriptor, otherwise the 
fd argument is ignored.  If
       the 
fd argument is a special value 
AT_FDCWD the path is resolved
       relative to the current working directory.  If the path argument is a
       null pointer, the function sets the owner and group ID of the file
       referenced by the 
fd argument.  In all other relative path cases, if
       the 
fd argument does not refer to a valid directory, the function
       returns 
ENOTDIR. If the 
flag argument is set to 
AT_SYMLINK_NOFOLLOW,
       the function will not automatically traverse a symbolic link at the
       position of the path. The 
fchownat() function is a multi-purpose
       function that can be used in place of 
chown(), 
lchown(), or 
fchown().
       See 
chown(2).
       The function call 
chown(path, owner, group) is equivalent to       
fchownat(AT_FDCWD, 
path, owner, group, 0).
       The function call 
lchown(path, owner, group) is equivalent to       
fchownat(AT_FDCWD, 
path, owner, group, AT_SYMLINK_NOFOLLOW).
   Set file access and modification times
         int futimesat (int 
fd, const char *
path, const struct timeval \                       
times[2])
       The 
futimesat(2) function sets the access and modification times for
       a file.  If the 
path argument is relative, it is resolved relative to
       the 
fd argument file descriptor; otherwise the 
fd argument is
       ignored.  If the 
fd argument is the special value 
AT_FDCWD, the path
       is resolved relative to the current working directory.  If the 
path       argument is a null pointer, the function sets the access and
       modification times of the file referenced by the 
fd argument. In all
       other relative path cases, if the 
fd argument does not refer to a
       valid directory, the function returns 
ENOTDIR.  The 
futimesat()       function can be used in place of 
utimes(2).
       The function call 
utimes(path, times) is equivalent to       
futimesat(AT_FDCWD, 
path, times).   
New pathconf() functionality         long int pathconf(const char *
path, int 
name)
       Two variables have been added to 
pathconf(2) to provide enhanced
       support for extended attribute manipulation. The 
XATTR_ENABLED       variable allows an application to determine if attribute support is
       currently enabled for the file in question. The 
XATTR_EXISTS variable
       allows an application to determine whether there are any extended
       attributes associated with the supplied path.   
Open/Create an attribute file         int attropen (const char *
path, const char *
attrpath, int 
oflag \
                  [, mode_t 
mode])
       The 
attropen(3C) function returns a file descriptor for the named
       attribute, 
attrpath, of the file indicated by 
path. The 
oflag and       
mode arguments are identical to the 
open(2) arguments and are applied
       to the open operation on the attribute file (for example, using the       
O_CREAT flag creates a new attribute).  Once opened, all normal file
       system operations can be used on the attribute file descriptor.  The       
attropen() function is a convenience function and is equivalent to
       the following sequence of operations:
         fd = open (path, O_RDONLY);
         attrfd = openat(fd, attrpath, oflag|O_XATTR, mode);
         close(fd);
       The set of existing attributes can be browsed by calling 
attropen()       with "." as the attribute name.  The list of attributes is obtained
       by calling 
getdents(2) (or 
fdopendir(3C) followed by 
readdir(3C), see
       below) on the returned file descriptor.
   Convert an open file descriptor for a directory into a directory
       descriptor         DIR * fdopendir (const int 
fd)
       The 
fdopendir(3C) function promotes a file descriptor for a directory
       to a directory pointer suitable for use with the 
readdir(3C)       function. The originating file descriptor should not be used again
       following the call to 
fdopendir(). The directory pointer should be
       closed with a call to 
closedir(3C). If the provided file descriptor
       does not reference a directory, the function returns 
ENOTDIR. This
       function is useful in circumstances where the only available handle
       on a directory is a file descriptor. See 
attropen(3C) and 
openat(2).
   Using the API
       The following examples demonstrate how the API might be used to
       perform basic operations on extended attributes:
       Example 1: List extended attributes on a file.
         attrdirfd = attropen("test", ".", O_RDONLY);
         dirp = fdopendir(attrdirfd);
         while (dp = readdir(dirp)) {
         ...
       Example 2: Open an extended attribute.
         attrfd = attropen("test", dp->d_name, O_RDONLY);
       or
         attrfd = openat(attrdirfd, dp->d_name, O_RDONLY);
       Example 3: Read from an extended attribute.
         while (read(attrfd, buf, 512) > 0) {
         ...
       Example 4: Create an extended attribute.
         newfd = attropen("test", "attr", O_CREAT|O_RDWR);
       or
         newfd = openat(attrdirfd, "attr", O_CREAT|O_RDWR);
       Example 5: Write to an extended attribute.
         count = write(newfd, buf, length);
       Example 6: Delete an extended attribute.
         error = unlinkat(attrdirfd, "attr");
       Applications intending to access the interfaces defined here as well
       as the POSIX and X/Open specification-conforming interfaces should
       define the macro 
_ATFILE_SOURCE to be 1 and set whichever feature
       test macros are appropriate to obtain the desired environment. See       
standards(7).
   Extended Archive Formats
       As noted above in the description of command utilities modified to
       provide support for extended attributes, the archive formats for       
tar(1) and 
cpio(1) have been extended to provide support for
       archiving extended attributes. This section describes the specifics
       of the archive format extensions.
   Extended tar format
       The 
tar archive is made up of a series of 512 byte blocks. Each
       archived file is represented by a header block and zero or more data
       blocks containing the file contents. The header block is structured
       as shown in the following table.
       Field Name   Length (in Octets)             Description
       Name         100                  File name string
       Mode         8                    12 file mode bits
       Uid          8                    User ID of file owner
       Gid          8                    Group ID of file owner
       Size         12                   Size of file
       Mtime        12                   File modification time
       Chksum       8                    File contents checksum
       Typeflag     1                    File type flag
       Linkname     100                  Link target name if file linked
       Magic        6                    "ustar"
       Version      2                    "00"
       Uname        32                   User name of file owner
       Gname        32                   Group name of file owner
       Devmajor     8                    Major device ID if special file
       Devminor     8                    Minor device ID if special file
       Prefix       155                  Path prefix string for file
       The extended attribute project extends the above header format by
       defining a new header type (for the 
Typeflag field). The type 'E' is
       defined to be used for all extended attribute files. Attribute files
       are stored in the 
tar archive as a sequence of two 
<header ,data>       pairs. The first file contains the data necessary to locate and name
       the extended attribute in the file system. The second file contains
       the actual attribute file data.  Both files use an 'E' type header.
       The prefix and name fields in extended attribute headers are ignored,
       though they should be set to meaningful values for the benefit of
       archivers that do not process these headers. Solaris archivers set
       the prefix field to "
/dev/null" to prevent archivers that do not
       understand the type 'E' header from trying to restore extended
       attribute files in inappropriate places.
   Extended cpio format
       The 
cpio archive format is octet-oriented rather than block-oriented.
       Each file entry in the archive includes a header that describes the
       file, followed by the file name, followed by the contents of the
       file.  These data are arranged as described in the following table.       
Field Name   Length (in Octets)             Description       
c_magic      6                    70707       
c_dev        6                    First half of unique file ID       
c_ino        6                    Second half of unique file ID       
c_mode       6                    File mode bits       
c_uid        6                    User ID of file owner       
c_gid        6                    Group ID of file owner       
c_nlink      6                    Number of links referencing file       
c_rdev       6                    Information for special files       
c_mtime      11                   Modification time of file       
c_namesize   6                    Length of file pathname       
c_filesize   11                   Length of file content       
c_name       c_namesize           File pathname       
c_filedata   c_filesize           File content
       The basic archive file structure is not changed for extended
       attributes. The file type bits stored in the 
c_mode field for an
       attribute file are set to 
0xB000. As with the 
tar archive format,
       extended attributes are stored in 
cpio archives as two consecutive
       file entries. The first file describes the location/name for the
       extended attribute. The second file contains the actual attribute
       file content. The 
c_name field in extended attribute headers is
       ignored, though it should be set to a meaningful value for the
       benefit of archivers that do not process these headers.  Solaris
       archivers start the pathname with "
/dev/null/"to prevent archivers
       that do not understand the type 'E' header from trying to restore
       extended attribute files in inappropriate places.
   Attribute identification data format
       Both the 
tar and 
cpio archive formats can contain the special files
       described above, always paired with the extended attribute data
       record, for identifying the precise location of the extended
       attribute.  These special data files are necessary because there is
       no simple naming mechanism for extended attribute files. Extended
       attributes are not visible in the file system name space. The
       extended attribute name space must be "tunneled into" using the       
openat() function. The attribute identification data must support not
       only the flat naming structure for extended attributes, but also the
       possibility of future extensions allowing for attribute directory
       hierarchies and recursive attributes. The data file is therefore
       composed of a sequence of records. It begins with a fixed length
       header describing  the content. The following table describes the
       format of this data file.
         Field Name      Length (in Octets)              Description       
h_version         7                    Name file version       
h_size            10                   Length of data file       
h_component_len   10                   Total length of all path segments       
h_link_comp_len   10                   Total length of all link segments       
path              h_component_len      Complex path       
link_path         h_link_comp_len      Complex link path
       As demonstrated above, the header is followed by a record describing
       the "path" to the attribute file. This path is composed of two or
       more path segments separated by a null character. Each segment
       describes a path rooted at the hidden extended attribute directory of
       the leaf file of the previous segment, making it possible to name
       attributes on attributes.  The first segment is always the path to
       the parent file that roots the entire sequence in the normal name
       space. The following table describes the format of each segment.
       Field Name   Length (in Octets)              Description
       ---------------------------------------------------------------------       
h_namesz     7                    Length of segment path       
h_typeflag   1                    Actual file type of attribute file       
h_names      h_namesz             Parent path + segment path
       If the attribute file is linked to another file, the path record is
       followed by a second record describing the location of the
       referencing file.  The structure of this record is identical to the
       record described above.
SEE ALSO
       cp(1), 
cpio(1), 
du(1), 
find(1), 
ls(1), 
mv(1), 
pax(1), 
runat(1),       
tar(1), 
chown(2), 
link(2), 
open(2), 
pathconf(2), 
rename(2), 
stat(2),       
unlink(2), 
utimes(2), 
attropen(3C), 
standards(7), 
fsck(8)                              October 10, 2007                     FSATTR(7)