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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list