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
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 3 ++
src/util/virfile.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/virfile.h | 13 ++++++
3 files changed, 127 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d4006ae..c1a51b2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1369,6 +1369,7 @@ virFileExists;
virFileFclose;
virFileFdopen;
virFileFindMountPoint;
+virFileGetAttr;
virFileHasSuffix;
virFileIsAbsPath;
virFileIsDir;
@@ -1386,10 +1387,12 @@ virFileOpenTty;
virFilePrintf;
virFileReadAll;
virFileReadLimFD;
+virFileRemoveAttr;
virFileResolveAllLinks;
virFileResolveLink;
virFileRewrite;
virFileSanitizePath;
+virFileSetAttr;
virFileSkipRoot;
virFileStripSuffix;
virFileTouch;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 2b07ac9..064ea2f 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -48,6 +48,10 @@
# include <sys/ioctl.h>
#endif
+#ifdef WITH_ATTR
+# include <attr/xattr.h>
+#endif
+
#include "configmake.h"
#include "viralloc.h"
#include "vircommand.h"
@@ -2362,3 +2366,110 @@ cleanup:
return ret;
}
+
+#ifdef WITH_ATTR
+int
+virFileSetAttr(const char *file,
+ const char *name,
+ const char *value)
+{
+ int ret = -1;
+ size_t valueSize = strlen(value);
+
+ if (setxattr(file, name, value, valueSize, 0) < 0) {
+ virReportSystemError(errno,
+ _("Unable to set extended attribute
'%s':'%s' on '%s'"),
+ name, value, file);
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ return ret;
+}
+
+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 maps ENOATTR to ENODATA */
+ if (errno == ENOATTR || errno == ENODATA) {
+ *value = NULL;
+ return 0;
+ }
+ virReportSystemError(errno,
+ _("Unable to get extended attribute '%s' on
'%s'"),
+ name, file);
+ return ret;
+ }
+
+ if (VIR_ALLOC_N(buf, valueSize) < 0)
+ 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)
+{
+ int ret = -1;
+ if (removexattr(file, name) < 0) {
+ virReportSystemError(errno,
+ _("Unable to remove extended attribute '%s' on
'%s'"),
+ name, file);
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ return ret;
+}
+
+#else /* WITH_ATTR */
+
+int
+virFileSetAttr(const char *file ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ const char *value ATTRIBUTE_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Unable to set extended attributes"));
+ return -1;
+}
+
+int
+virFileGetAttr(const char *file ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ char **value ATTRIBUTE_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Unable to get extended attributes"));
+ return -1;
+}
+
+int
+virFileRemoveAttr(const char *file ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Unable to remove attributes"));
+ return -1;
+}
+#endif /* WITH_ATTR */
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 72d35ce..08c59b0 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -232,4 +232,17 @@ int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL;
int virFilePrintf(FILE *fp, const char *msg, ...)
ATTRIBUTE_FMT_PRINTF(2, 3);
+int virFileSetAttr(const char *file,
+ const char *name,
+ const char *value)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+int virFileGetAttr(const char *file,
+ const char *name,
+ char **value)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+int virFileRemoveAttr(const char *file,
+ const char *name)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
#endif /* __VIR_FILE_H */
--
1.8.1.5