[libvirt] [PATCH 5/7] Move file info functions to libvirt_util

Mark McLoughlin markmc at redhat.com
Fri Sep 25 13:27:31 UTC 2009


Rename virStorageBackendUpdateVolTargetInfo to virStorageFileGetInfo()
and move to util/storage_file.[ch]

* src/storage/storage_backend.[ch]: move code from here ...

* src/util/storage_file.[ch]: ... to here

* src/libvirt_private.syms: export new functions

* src/storage/storage_backend_fs.c, src/storage/storage_backend_mpath.c,
  src/storage/storage_backend_scsi.c: update from above changes

* po/POTFILES.in: add storage_file.c
---
 po/POTFILES.in                      |    1 +
 src/libvirt_private.syms            |    2 +
 src/storage/storage_backend.c       |  148 ++-------------------------------
 src/storage/storage_backend.h       |    9 --
 src/storage/storage_backend_fs.c    |   18 ++--
 src/storage/storage_backend_mpath.c |    7 +-
 src/storage/storage_backend_scsi.c  |    7 +-
 src/util/storage_file.c             |  157 +++++++++++++++++++++++++++++++++++
 src/util/storage_file.h             |   13 +++
 9 files changed, 194 insertions(+), 168 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9f21459..30c52f5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -45,6 +45,7 @@ src/util/iptables.c
 src/util/logging.c
 src/util/pci.c
 src/util/storage_encryption.c
+src/util/storage_file.c
 src/util/util.c
 src/util/uuid.c
 src/util/virterror.c
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 76a6e1b..9b6f4a7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -393,6 +393,8 @@ virStorageGenerateQcowPassphrase;
 # storage_file.h
 virStorageFileFormatTypeToString;
 virStorageFileFormatTypeFromString;
+virStorageFileGetInfo;
+virStorageFileGetInfoFromFD;
 
 # threads.h
 virMutexInit;
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 18a69be..e214c3f 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -73,10 +73,6 @@
 #include "storage_backend_fs.h"
 #endif
 
-#ifndef DEV_BSIZE
-#define DEV_BSIZE 512
-#endif
-
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
 static virStorageBackendPtr backends[] = {
@@ -768,33 +764,6 @@ virStorageBackendForType(int type) {
     return NULL;
 }
 
-
-int
-virStorageBackendUpdateVolTargetInfo(virConnectPtr conn,
-                                     virStorageVolTargetPtr target,
-                                     unsigned long long *allocation,
-                                     unsigned long long *capacity)
-{
-    int ret, fd;
-
-    if ((fd = open(target->path, O_RDONLY)) < 0) {
-        virReportSystemError(conn, errno,
-                             _("cannot open volume '%s'"),
-                             target->path);
-        return -1;
-    }
-
-    ret = virStorageBackendUpdateVolTargetInfoFD(conn,
-                                                 target,
-                                                 fd,
-                                                 allocation,
-                                                 capacity);
-
-    close(fd);
-
-    return ret;
-}
-
 int
 virStorageBackendUpdateVolInfo(virConnectPtr conn,
                                virStorageVolDefPtr vol,
@@ -802,122 +771,23 @@ virStorageBackendUpdateVolInfo(virConnectPtr conn,
 {
     int ret;
 
-    if ((ret = virStorageBackendUpdateVolTargetInfo(conn,
-                                                    &vol->target,
-                                                    &vol->allocation,
-                                                    withCapacity ? &vol->capacity : NULL)) < 0)
+    if ((ret = virStorageFileGetInfo(conn,
+                                     vol->target.path,
+                                     &vol->target.perms,
+                                     &vol->allocation,
+                                     withCapacity ? &vol->capacity : NULL)) < 0)
         return ret;
 
     if (vol->backingStore.path &&
-        (ret = virStorageBackendUpdateVolTargetInfo(conn,
-                                                    &vol->backingStore,
-                                                    NULL, NULL)) < 0)
+        (ret = virStorageFileGetInfo(conn,
+                                     vol->backingStore.path,
+                                     &vol->backingStore.perms,
+                                     NULL, NULL)) < 0)
         return ret;
 
     return 0;
 }
 
-/*
- * virStorageBackendUpdateVolTargetInfoFD:
- * @conn: connection to report errors on
- * @target: target definition ptr of volume to update
- * @fd: fd of storage volume to update
- * @allocation: If not NULL, updated allocation information will be stored
- * @capacity: If not NULL, updated capacity info will be stored
- *
- * Returns 0 for success-1 on a legitimate error condition,
- *    -2 if passed FD isn't a regular, char, or block file.
- */
-int
-virStorageBackendUpdateVolTargetInfoFD(virConnectPtr conn,
-                                       virStorageVolTargetPtr target,
-                                       int fd,
-                                       unsigned long long *allocation,
-                                       unsigned long long *capacity)
-{
-    struct stat sb;
-#if HAVE_SELINUX
-    security_context_t filecon = NULL;
-#endif
-
-    if (fstat(fd, &sb) < 0) {
-        virReportSystemError(conn, errno,
-                             _("cannot stat file '%s'"),
-                             target->path);
-        return -1;
-    }
-
-    if (!S_ISREG(sb.st_mode) &&
-        !S_ISCHR(sb.st_mode) &&
-        !S_ISBLK(sb.st_mode))
-        return -2;
-
-    if (allocation) {
-        if (S_ISREG(sb.st_mode)) {
-#ifndef __MINGW32__
-            *allocation = (unsigned long long)sb.st_blocks *
-                          (unsigned long long)DEV_BSIZE;
-#else
-            *allocation = sb.st_size;
-#endif
-            /* Regular files may be sparse, so logical size (capacity) is not same
-             * as actual allocation above
-             */
-            if (capacity)
-                *capacity = sb.st_size;
-        } else {
-            off_t end;
-            /* XXX this is POSIX compliant, but doesn't work for for CHAR files,
-             * only BLOCK. There is a Linux specific ioctl() for getting
-             * size of both CHAR / BLOCK devices we should check for in
-             * configure
-             */
-            end = lseek(fd, 0, SEEK_END);
-            if (end == (off_t)-1) {
-                virReportSystemError(conn, errno,
-                                     _("cannot seek to end of file '%s'"),
-                                     target->path);
-                return -1;
-            }
-            *allocation = end;
-            if (capacity)
-                *capacity = end;
-        }
-    }
-
-    target->perms.mode = sb.st_mode & S_IRWXUGO;
-    target->perms.uid = sb.st_uid;
-    target->perms.gid = sb.st_gid;
-
-    VIR_FREE(target->perms.label);
-
-#if HAVE_SELINUX
-    /* XXX: make this a security driver call */
-    if (fgetfilecon(fd, &filecon) == -1) {
-        if (errno != ENODATA && errno != ENOTSUP) {
-            virReportSystemError(conn, errno,
-                                 _("cannot get file context of '%s'"),
-                                 target->path);
-            return -1;
-        } else {
-            target->perms.label = NULL;
-        }
-    } else {
-        target->perms.label = strdup(filecon);
-        if (target->perms.label == NULL) {
-            virReportOOMError(conn);
-            return -1;
-        }
-        freecon(filecon);
-    }
-#else
-    target->perms.label = NULL;
-#endif
-
-    return 0;
-}
-
-
 struct diskType {
     int part_table_type;
     unsigned short offset;
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 88c6161..550bd32 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -82,15 +82,6 @@ int virStorageBackendUpdateVolInfo(virConnectPtr conn,
                                    virStorageVolDefPtr vol,
                                    int withCapacity);
 
-int virStorageBackendUpdateVolTargetInfo(virConnectPtr conn,
-                                         virStorageVolTargetPtr target,
-                                         unsigned long long *allocation,
-                                         unsigned long long *capacity);
-int virStorageBackendUpdateVolTargetInfoFD(virConnectPtr conn,
-                                           virStorageVolTargetPtr target,
-                                           int fd,
-                                           unsigned long long *allocation,
-                                           unsigned long long *capacity);
 int
 virStorageBackendUpdateVolTargetFormatFD(virConnectPtr conn,
                                          virStorageVolTargetPtr target,
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index e7a3ca9..49cfc6f 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -305,9 +305,9 @@ static int virStorageBackendProbeTarget(virConnectPtr conn,
         return -1;
     }
 
-    if ((ret = virStorageBackendUpdateVolTargetInfoFD(conn, target, fd,
-                                                      allocation,
-                                                      capacity)) < 0) {
+    if ((ret = virStorageFileGetInfoFromFD(conn, target->path, fd,
+                                           &target->perms,
+                                           allocation, capacity)) < 0) {
         close(fd);
         return ret; /* Take care to propagate ret, it is not always -1 */
     }
@@ -934,10 +934,8 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn,
                         memmove(backingStore, path, strlen(path) + 1);
                         vol->backingStore.path = backingStore;
 
-                        if (virStorageBackendUpdateVolTargetInfo(conn,
-                                                                 &vol->backingStore,
-                                                                 NULL,
-                                                                 NULL) < 0)
+                        if (virStorageFileGetInfo(conn, vol->backingStore.path,
+                                                  &vol->backingStore.perms, NULL, NULL) < 0)
                             VIR_FREE(vol->backingStore);
                     }
                 }
@@ -1167,9 +1165,9 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
     }
 
     /* Refresh allocation / permissions info, but not capacity */
-    if (virStorageBackendUpdateVolTargetInfoFD(conn, &vol->target, fd,
-                                               &vol->allocation,
-                                               NULL) < 0) {
+    if (virStorageFileGetInfoFromFD(conn, vol->target.path, fd,
+                                    &vol->target.perms, &vol->allocation,
+                                    NULL) < 0) {
         close(fd);
         return -1;
     }
diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c
index fcc38ba..71e86d0 100644
--- a/src/storage/storage_backend_mpath.c
+++ b/src/storage/storage_backend_mpath.c
@@ -55,11 +55,8 @@ virStorageBackendMpathUpdateVolTargetInfo(virConnectPtr conn,
         goto out;
     }
 
-    if (virStorageBackendUpdateVolTargetInfoFD(conn,
-                                               target,
-                                               fd,
-                                               allocation,
-                                               capacity) < 0) {
+    if (virStorageFileGetInfoFromFD(conn, target->path, fd, &target->perms,
+                                    allocation, capacity) < 0) {
 
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                           _("Failed to update volume target info for '%s'"),
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
index c70b1ed..f9eb0ab 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -149,11 +149,8 @@ virStorageBackendSCSIUpdateVolTargetInfo(virConnectPtr conn,
         return -1;
     }
 
-    if (virStorageBackendUpdateVolTargetInfoFD(conn,
-                                               target,
-                                               fd,
-                                               allocation,
-                                               capacity) < 0)
+    if (virStorageFileGetInfoFromFD(conn, target->path, fd, &target->perms,
+                                    allocation, capacity) < 0)
         goto cleanup;
 
     /* make sure to set the target format "unknown" to begin with */
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index e66ec8a..c1eec9b 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -24,8 +24,165 @@
 #include <config.h>
 #include "storage_file.h"
 
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#if HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#include "memory.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
 VIR_ENUM_IMPL(virStorageFileFormat,
               VIR_STORAGE_FILE_LAST,
               "raw", "dir", "bochs",
               "cloop", "cow", "dmg", "iso",
               "qcow", "qcow2", "vmdk", "vpc")
+
+#ifndef DEV_BSIZE
+#define DEV_BSIZE 512
+#endif
+
+/*
+ * virStorageFileGetInfoFromFD:
+ * @conn: connection to report errors on
+ * @path: path of the file
+ * @fd: file description of the open file
+ * @permissions: If not NULL, file permsions info to update
+ * @allocation: If not NULL, updated allocation information will be stored
+ * @capacity: If not NULL, updated capacity info will be stored
+ *
+ * Returns 0 for success-1 on a legitimate error condition,
+ *    -2 if passed FD isn't a regular, char, or block file.
+ */
+int
+virStorageFileGetInfoFromFD(virConnectPtr conn,
+                            const char *path,
+                            int fd,
+                            virStorageFilePermsPtr perms,
+                            unsigned long long *allocation,
+                            unsigned long long *capacity)
+{
+    struct stat sb;
+#if HAVE_SELINUX
+    security_context_t filecon = NULL;
+#endif
+
+    if (fstat(fd, &sb) < 0) {
+        virReportSystemError(conn, errno,
+                             _("cannot stat file '%s'"), path);
+        return -1;
+    }
+
+    if (!S_ISREG(sb.st_mode) &&
+        !S_ISCHR(sb.st_mode) &&
+        !S_ISBLK(sb.st_mode))
+        return -2;
+
+    if (allocation) {
+        if (S_ISREG(sb.st_mode)) {
+#ifndef __MINGW32__
+            *allocation = (unsigned long long)sb.st_blocks *
+                          (unsigned long long)DEV_BSIZE;
+#else
+            *allocation = sb.st_size;
+#endif
+            /* Regular files may be sparse, so logical size (capacity) is not same
+             * as actual allocation above
+             */
+            if (capacity)
+                *capacity = sb.st_size;
+        } else {
+            off_t end;
+            /* XXX this is POSIX compliant, but doesn't work for for CHAR files,
+             * only BLOCK. There is a Linux specific ioctl() for getting
+             * size of both CHAR / BLOCK devices we should check for in
+             * configure
+             */
+            end = lseek(fd, 0, SEEK_END);
+            if (end == (off_t)-1) {
+                virReportSystemError(conn, errno,
+                                     _("cannot seek to end of file '%s'"), path);
+                return -1;
+            }
+            *allocation = end;
+            if (capacity)
+                *capacity = end;
+        }
+    }
+
+    if (!perms)
+        return 0;
+
+    perms->mode = sb.st_mode & S_IRWXUGO;
+    perms->uid = sb.st_uid;
+    perms->gid = sb.st_gid;
+
+    VIR_FREE(perms->label);
+
+#if HAVE_SELINUX
+    /* XXX: make this a security driver call */
+    if (fgetfilecon(fd, &filecon) == -1) {
+        if (errno != ENODATA && errno != ENOTSUP) {
+            virReportSystemError(conn, errno,
+                                 _("cannot get file context of '%s'"), path);
+            return -1;
+        } else {
+            perms->label = NULL;
+        }
+    } else {
+        perms->label = strdup(filecon);
+        if (perms->label == NULL) {
+            virReportOOMError(conn);
+            return -1;
+        }
+        freecon(filecon);
+    }
+#else
+    perms->label = NULL;
+#endif
+
+    return 0;
+}
+
+/*
+ * virFileGetInfo:
+ *
+ * @path: path of the file
+ * @perms: If not NULL, file permissions information will be stored
+ * @allocation: If not NULL, file allocation information will be stored
+ * @capacity: If not NULL, file capacity info will be stored
+ *
+ * Returns 0 for success-1 on a legitimate error condition,
+ *    -2 if passed FD isn't a regular, char, or block file.
+ */
+int
+virStorageFileGetInfo(virConnectPtr conn,
+                      const char *path,
+                      virStorageFilePermsPtr perms,
+                      unsigned long long *allocation,
+                      unsigned long long *capacity)
+{
+    int ret, fd;
+
+    if ((fd = open(path, O_RDONLY)) < 0) {
+        virReportSystemError(conn, errno,
+                             _("cannot open volume '%s'"), path);
+        return -1;
+    }
+
+    ret = virStorageFileGetInfoFromFD(conn, path, fd, perms,
+                                      allocation, capacity);
+
+    close(fd);
+
+    return ret;
+}
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index e2f1478..efacc65 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -52,4 +52,17 @@ struct _virStorageFilePerms {
     char *label;
 };
 
+int virStorageFileGetInfo(virConnectPtr conn,
+                          const char *path,
+                          virStorageFilePermsPtr perms,
+                          unsigned long long *allocation,
+                          unsigned long long *capacity);
+
+int virStorageFileGetInfoFromFD(virConnectPtr conn,
+                                const char *path,
+                                int fd,
+                                virStorageFilePermsPtr perms,
+                                unsigned long long *allocation,
+                                unsigned long long *capacity);
+
 #endif /* __VIR_STORAGE_FILE_H__ */
-- 
1.6.2.5




More information about the libvir-list mailing list