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