[libvirt] [PATCH v4 1/3] virFile: Add APIs for extended attributes handling
Daniel P. Berrange
berrange at redhat.com
Fri Mar 15 14:17:54 UTC 2013
On Fri, Mar 15, 2013 at 03:12:01PM +0100, Michal Privoznik wrote:
> Currently, only three wrappers are being implemented:
> virFileSetAttr for setting attributes
> virFileGetAttr for querying attributes (note we need to call it twice,
> first time to get length of attribute value, second to get actual value)
> virFileRemoveAttr for removing attributes
> ---
>
> diff to v3:
> -set errno=ENOSYS when building without WITH_ATTR for easier check within callee.
>
> diff to v2:
> -drop multiple check for libattr
>
> src/libvirt_private.syms | 3 ++
> src/util/virfile.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++
> src/util/virfile.h | 14 ++++++
> 3 files changed, 125 insertions(+)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 5cad990..5a2cbe8 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1252,8 +1252,11 @@ virFileClose;
> virFileDirectFdFlag;
> virFileFclose;
> virFileFdopen;
> +virFileGetAttr;
> virFileLoopDeviceAssociate;
> +virFileRemoveAttr;
> virFileRewrite;
> +virFileSetAttr;
> virFileTouch;
> virFileUpdatePerm;
> virFileWrapperFdClose;
> diff --git a/src/util/virfile.c b/src/util/virfile.c
> index 4a9fa81..be50e83 100644
> --- a/src/util/virfile.c
> +++ b/src/util/virfile.c
> @@ -37,6 +37,10 @@
> # include <sys/ioctl.h>
> #endif
>
> +#ifdef WITH_ATTR
> +# include <attr/xattr.h>
> +#endif
> +
> #include "vircommand.h"
> #include "configmake.h"
> #include "viralloc.h"
> @@ -644,3 +648,107 @@ int virFileLoopDeviceAssociate(const char *file,
> }
>
> #endif /* __linux__ */
> +
> +#ifdef WITH_ATTR
> +int
> +virFileSetAttr(const char *file,
> + const char *name,
> + const char *value)
> +{
> + size_t valueSize = strlen(value);
> + if (setxattr(file, name, value, valueSize, 0) < 0) {
> + virReportSystemError(errno,
> + _("Unable to set extended attribute '%s' on '%s'"),
> + name, file);
> + return -1;
> + }
> + return 0;
> +}
> +
> +int
> +virFileGetAttr(const char *file,
> + const char *name,
> + char **value)
> +{
> + int ret = -1;
> + char *buf = NULL;
> + ssize_t valueSize;
> +
> + /* get attribute length */
> + if ((valueSize = getxattr(file, name, NULL, 0)) < 0) {
> + /* The Linux kernel does not define ENOATTR, but maps it to ENODATA. */
> + if (errno == ENOATTR || errno == ENODATA) {
> + *value = NULL;
> + return 0;
> + } else {
> + virReportSystemError(errno,
> + _("Unable to get extended attribute '%s' on '%s'"),
> + name, file);
> + return ret;
> + }
> + }
> +
> + if (VIR_ALLOC_N(buf, valueSize) < 0) {
> + virReportOOMError();
> + return ret;
> + }
> +
> + if ((ret = getxattr(file, name, buf, valueSize)) < 0) {
> + VIR_FREE(buf);
> + virReportSystemError(errno,
> + _("Unable to get extended attribute '%s' on '%s'"),
> + name, file);
> + } else {
> + *value = buf;
> + }
> +
> + return ret;
> +}
> +
> +int
> +virFileRemoveAttr(const char *file,
> + const char *name)
> +{
> + if (removexattr(file, name) < 0) {
> + virReportSystemError(errno,
> + _("Unable to remove extended attribute '%s' on '%s'"),
> + name, file);
> + return -1;
> + }
> + return 0;
> +}
> +
> +#else /* WITH_ATTR */
> +
> +int
> +virFileSetAttr(const char *file ATTRIBUTE_UNUSED,
> + const char *name ATTRIBUTE_UNUSED,
> + const char *value ATTRIBUTE_UNUSED)
> +{
> + errno = ENOSYS;
> + virReportSystemError(errno, "%s",
> + _("Unable to set extended attributes"));
> + return -1;
> +}
> +
> +int
> +virFileGetAttr(const char *file ATTRIBUTE_UNUSED,
> + const char *name ATTRIBUTE_UNUSED,
> + char **value ATTRIBUTE_UNUSED)
> +{
> + errno = ENOSYS;
> + virReportSystemError(errno, "%s",
> + _("Unable to get extended attributes"));
> + return -1;
> +}
> +
> +int
> +virFileRemoveAttr(const char *file ATTRIBUTE_UNUSED,
> + const char *name ATTRIBUTE_UNUSED)
> +{
> + errno = ENOSYS;
NACK to this addition. Callers have absolutely no business accessing
'errno' for any function which uses libvirt error reporting - we make
no guarnatees that the value will be preserved by any cleanup code in
such methods. If callers want to check errno values they should do this:
virErrorPtr err = virGetLastError()
if (err &&
err->code == VIR_ERR_SYSTEM_ERROR &&
err->int1 == ENOSYS)
....
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list