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 :|