apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Davi Arnaut <d...@apache.org>
Subject Re: Extended Attributes Support
Date Fri, 21 Dec 2007 08:15:11 GMT
Hi Michael,

Michael Clark wrote:
> Hi Folks,
> 
> I have been doing some work on implementing extended attributes
> support for apr.

Great. This is one of the features that I always miss in the APR.

> I am doing this as I would like to add a property provider to
> mod_dav_fs that uses extended attributes instead of a db per file
> (TwistedDAV on Mac OS X also uses extended attributes for this BTW)
> and I want to do this portably so it could potentially be included.

Good, this can also be useful to a lot of apache modules out there (in
particular, I would like to use it to store per cache file headers).

> Extended attributes can also be used for setting mime-types on files
> (mod_mime_xattr uses the native Linux API so this could be ported
> to use portable apr xattrs and work on more platforms). Another nice
> idea is setting file listing 'description' attributes and getting
> mod_autoindex to look at them.

Also good.

> I have looked at a few of the OS extended attributes interface and
> have come up with an API proposal (at the end of this mail).
> 
> It addresses:
>   * setting, getting, listing and removing of 'user' extended attributes
>     on a file specified by its filepath.
> 
> It does not address:
>   * system namespaces on platforms with more than one attribute namespace
>     (only the user namespace is accessible on platforms with multiple
>      attr namespaces, new flags could potentially be added to access
>      platform specific system namespaces)
>   * setting, getting, listing and removing attributes on a file
>     specified by a file descriptor (apr_os_file_t)
> 
> I have working sample implementations for Linux, Mac OS X, FreeBSD 6
> and Solaris 10 (which each have different APIs BTW):
> 
> * Linux impl use l?(get|set|list|remove)xattr
> * Mac OS X impl use (get|set|list|remove)xattr (different args to linux)
> * FreeBSD impl uses extattr_(get|set|list|delete)_(file|link)
> * Solaris impl uses subfiles (attropen,unlinkat and friends)
> 
> Not implemented:
> 
> * Windows - should be able to use named :streams (similar to Solaris)
> * OS/2 - it has extended attributes but that's all I know.
> * Irix/HPUX/AIX/OS390/netware/... - unknown? do they have them?

I may look into implementing it on Windows/HPUX later.

> Any ideas on feasibility on these and other apr supported platforms?
> 
> I'll send some initial patches soon. They still need a little work
> and some more test cases.
> 
> I have some questions on build structure...
> 
> Should I put the declarations in apr_file_info.h or would it be
> better to add a apr_file_xattr.h header?

I prefer a new apr_file_xattr.h header.

> I have all the unix implementations rolled into one file
> (file_io/unix/xattr.c) with many #if's. Should I perhaps have
> a linux.c, darwin.c, freebsd.c, solaris.c in a subdirectory?
> Not sure how I would integrate this into the build (perhaps
> having a single #if that create empty compilation units for
> the inactive platforms?).

Hum, I tend to prefer separate separate files having the #if to empty,
maybe in file_io/unix/xattr/ subdirectory. You can also put internal
headers in include/arch/...

> Test cases should go into a new unit - not linked into testall?
> 
> Also what is the procedure for proposing and adding a new API like
> this. I guess my patch should have it disabled by default and enabled
> with a configure flag - say --enable-xattrs (or autodetected and enabled
> on supported platforms)?

Auto detected, with a configure option to disable (--disable-xattrs).

> Proposed API:
> 
> /**
>   * @defgroup apr_file_xattr File Extended Attribute Functions
>   * @{
>   */
> 
> /** Don't follow symbolic links flag for apr_file_xattr functions */
> #define APR_XATTR_NOFOLLOW    1
> 
> /** When setting values, fail if the attribute already exists */
> #define APR_XATTR_CREATE      2
> 
> /** When setting values, fail if the attribute does not already exist */
> #define APR_XATTR_REPLACE     4
> 
> /**
> * Set an extended attribute on the file specificed by filepath

s/specificed/specified/
s/filepath/file path/

> * @param filepath the full path to the file
> * @param name the attribute name to set
> * @param value the attribute value
> * @param size the size in bytes of the attribute value
> * @param flags to control how the attribute is set
> * <PRE>
> *         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
> *                               attribute will be set on the link.
> *         APR_XATTR_CREATE      return an error if the attribute name
> *                               already exists.
> *         APR_XATTR_REPLACE     return an error if the attribute name
> *                               does not already exist.
> * </PRE>
> * @param p the pool to allocate any memory from if required
> * @remark if neither flag APR_XATTR_CREATE or APR_XATTR_REPLACE are
> * given then the attribute will either be created if it does not
> * already exist or replaced if it does exist.
> */
> APR_DECLARE(apr_status_t) apr_file_xattr_set(const char *filepath,
>                                              const char *name,
>                                              const void *value,
>                                              apr_size_t size,
>                                              apr_int32_t flags,

apr_uint32_t

>                                              apr_pool_t *p);

What was the reasoning for not using a apr_file_t based implementation
and using fsetxattr and likes?

> /**
> * Get an extended attribute from the file specificed by filepath

Same as above.

> * @param filepath the full path to the file
> * @param name the attribute name to get
> * @param value the returned attribute value, if value is NULL then only
> * the size of the attribute value is returned

Would be nice to have some kind of option to allocate from the pool,
otherwise it doesn't make much sense to pass void **.

> * @param size the returned size of the attribute value
> * @param flags to control how the attribute is got
> * <PRE>
> *         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
> *                               attribute will be gotten from the link.
> * </PRE>
> * @param p the pool to allocate any memory from if required
> */
> APR_DECLARE(apr_status_t) apr_file_xattr_get(const char *filepath,
>                                              const char *name,
>                                              void **value,
>                                              apr_size_t *size,
>                                              apr_int32_t flags,
>                                              apr_pool_t *p);
> 
> /**
>   * List the extended attributes for the file specificed by filepath

Same as above.

>   * @param filepath the full path to the file
>   * @param list the returned array of attributes names
>   * @param flags to control how the file is listed
>   * <PRE>
>   *         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
>   *                               attributes of the link will be listed.
>   * </PRE>
>   * @param p the pool to allocate any memory from if required
>   * @remark list is an array containing simple null terminated strings.
>   */
> APR_DECLARE(apr_status_t) apr_file_xattr_list(const char *filepath,
>                                                apr_array_header_t **list,
>                                                apr_int32_t flags,
>                                                apr_pool_t *p);
> 
> /**
> * Remove an extended attribute from the file specificed by filepath

Same as above.

> * @param filepath the full path to the file
> * @param name the attribute name to remove
> * @param flags to control how the attribute is removed
> * <PRE>
> *         APR_XATTR_NOFOLLOW    if the file is a symbolic link then the
> *                               attribute will be removed from the link.
> * </PRE>
> * @param p the pool to allocate any memory from if required
> */
> APR_DECLARE(apr_status_t) apr_file_xattr_remove(const char *filepath,
>                                                 const char *name,
>                                                 apr_int32_t flags,

apr_uint32_t

>                                                 apr_pool_t *p);
> 
> /** @} */
> 

Looks go so far.

Regards,

Davi Arnaut

Mime
View raw message