]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
storage: Add file storage APIs in the default storage driver
authorPeter Krempa <pkrempa@redhat.com>
Mon, 3 Feb 2014 15:12:57 +0000 (16:12 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 14 Feb 2014 09:47:56 +0000 (10:47 +0100)
Add APIs that will allow to use the storage driver to assist in
operations on files even for remote filesystems without native
representation as files in the host.

src/storage/storage_backend.c
src/storage/storage_backend.h
src/storage/storage_driver.c
src/storage/storage_driver.h
tests/Makefile.am

index 19fb1f05e08955adb2c23168a05798e7fc63bb29..b59b5b7b80549bfa446e6d3132cc9fb843fa26f3 100644 (file)
@@ -121,6 +121,12 @@ static virStorageBackendPtr backends[] = {
     NULL
 };
 
+
+static virStorageFileBackendPtr fileBackends[] = {
+    NULL
+};
+
+
 enum {
     TOOL_QEMU_IMG,
     TOOL_KVM_IMG,
@@ -1152,6 +1158,37 @@ virStorageBackendForType(int type)
 }
 
 
+virStorageFileBackendPtr
+virStorageFileBackendForType(int type,
+                             int protocol)
+{
+    size_t i;
+
+    for (i = 0; fileBackends[i]; i++) {
+        if (fileBackends[i]->type == type) {
+            if (type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
+                fileBackends[i]->protocol != protocol)
+                continue;
+
+            return fileBackends[i];
+        }
+    }
+
+    if (type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("missing storage backend for network files "
+                         "using %s protocol"),
+                       virDomainDiskProtocolTypeToString(protocol));
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("missing storage backend for '%s' storage"),
+                       virDomainDiskTypeToString(type));
+    }
+
+    return NULL;
+}
+
+
 /*
  * Allows caller to silently ignore files with improper mode
  *
index 378bc4d4bc98c7f074f3557775f5fc177ec08b0c..1c7ad1e72d5979183ea05b9ca957e0be231626a5 100644 (file)
@@ -29,6 +29,7 @@
 # include "internal.h"
 # include "storage_conf.h"
 # include "vircommand.h"
+# include "storage_driver.h"
 
 typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn,
                                                    const char *srcSpec,
@@ -189,4 +190,44 @@ virStorageBackendCreateQemuImgCmd(virConnectPtr conn,
                                   const char *create_tool,
                                   int imgformat);
 
+/* ------- virStorageFile backends ------------ */
+typedef int
+(*virStorageFileBackendInit)(virStorageFilePtr file);
+
+typedef void
+(*virStorageFileBackendDeinit)(virStorageFilePtr file);
+
+typedef int
+(*virStorageFileBackendCreate)(virStorageFilePtr file);
+
+typedef int
+(*virStorageFileBackendUnlink)(virStorageFilePtr file);
+
+typedef int
+(*virStorageFileBackendStat)(virStorageFilePtr file,
+                             struct stat *st);
+
+typedef struct _virStorageFileBackend virStorageFileBackend;
+typedef virStorageFileBackend *virStorageFileBackendPtr;
+
+virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol);
+
+struct _virStorageFileBackend {
+    int type;
+    int protocol;
+
+    /* All storage file callbacks may be omitted if not implemented */
+
+    /* The following group of callbacks is expected to set a libvirt
+     * error on failure. */
+    virStorageFileBackendInit backendInit;
+    virStorageFileBackendDeinit backendDeinit;
+
+    /* The following group of callbacks is expected to set errno
+     * and return -1 on error. No libvirt error shall be reported */
+    virStorageFileBackendCreate storageFileCreate;
+    virStorageFileBackendUnlink storageFileUnlink;
+    virStorageFileBackendStat   storageFileStat;
+};
+
 #endif /* __VIR_STORAGE_BACKEND_H__ */
index 2f7b2e559a04d589a504fe07f6fee1e57760c76b..64451c572a18663702994a7eee38afe6082e490b 100644 (file)
@@ -2589,6 +2589,7 @@ cleanup:
     return ret;
 }
 
+
 static virStorageDriver storageDriver = {
     .name = "storage",
     .storageOpen = storageOpen, /* 0.4.0 */
@@ -2653,3 +2654,147 @@ int storageRegister(void)
     virRegisterStateDriver(&stateDriver);
     return 0;
 }
+
+
+/* ----------- file handlers cooperating with storage driver --------------- */
+void
+virStorageFileFree(virStorageFilePtr file)
+{
+    if (!file)
+        return;
+
+    if (file->backend &&
+        file->backend->backendDeinit)
+        file->backend->backendDeinit(file);
+
+    VIR_FREE(file->path);
+    virDomainDiskHostDefFree(file->nhosts, file->hosts);
+    VIR_FREE(file);
+}
+
+
+static virStorageFilePtr
+virStorageFileInitInternal(int type,
+                           const char *path,
+                           int protocol,
+                           size_t nhosts,
+                           virDomainDiskHostDefPtr hosts)
+{
+    virStorageFilePtr file = NULL;
+
+    if (VIR_ALLOC(file) < 0)
+        return NULL;
+
+    file->type = type;
+    file->protocol = protocol;
+    file->nhosts = nhosts;
+
+    if (VIR_STRDUP(file->path, path) < 0)
+        goto error;
+
+    if (!(file->hosts = virDomainDiskHostDefCopy(nhosts, hosts)))
+        goto error;
+
+    if (!(file->backend = virStorageFileBackendForType(file->type,
+                                                       file->protocol)))
+        goto error;
+
+    if (file->backend->backendInit &&
+        file->backend->backendInit(file) < 0)
+        goto error;
+
+    return file;
+
+error:
+    VIR_FREE(file->path);
+    virDomainDiskHostDefFree(file->nhosts, file->hosts);
+    VIR_FREE(file);
+    return NULL;
+}
+
+
+virStorageFilePtr
+virStorageFileInitFromDiskDef(virDomainDiskDefPtr disk)
+{
+    return virStorageFileInitInternal(virDomainDiskGetActualType(disk),
+                                      disk->src,
+                                      disk->protocol,
+                                      disk->nhosts,
+                                      disk->hosts);
+}
+
+
+virStorageFilePtr
+virStorageFileInitFromSnapshotDef(virDomainSnapshotDiskDefPtr disk)
+{
+    return virStorageFileInitInternal(virDomainSnapshotDiskGetActualType(disk),
+                                      disk->file,
+                                      disk->protocol,
+                                      disk->nhosts,
+                                      disk->hosts);
+}
+
+
+
+/**
+ * virStorageFileCreate: Creates an empty storage file via storage driver
+ *
+ * @file: file structure pointing to the file
+ *
+ * Returns 0 on success, -2 if the function isn't supported by the backend,
+ * -1 on other failure. Errno is set in case of failure.
+ */
+int
+virStorageFileCreate(virStorageFilePtr file)
+{
+    if (!file->backend->storageFileCreate) {
+        errno = ENOSYS;
+        return -2;
+    }
+
+    return file->backend->storageFileCreate(file);
+}
+
+
+/**
+ * virStorageFileUnlink: Unlink storage file via storage driver
+ *
+ * @file: file structure pointing to the file
+ *
+ * Unlinks the file described by the @file structure.
+ *
+ * Returns 0 on success, -2 if the function isn't supported by the backend,
+ * -1 on other failure. Errno is set in case of failure.
+ */
+int
+virStorageFileUnlink(virStorageFilePtr file)
+{
+    if (!file->backend->storageFileUnlink) {
+        errno = ENOSYS;
+        return -2;
+    }
+
+    return file->backend->storageFileUnlink(file);
+}
+
+
+/**
+ * virStorageFileStat: returns stat struct of a file via storage driver
+ *
+ * @file: file structure pointing to the file
+ * @stat: stat structure to return data
+ *
+ * Returns 0 on success, -2 if the function isn't supported by the backend,
+ * -1 on other failure. Errno is set in case of failure.
+*/
+int
+virStorageFileStat(virStorageFilePtr file,
+                   struct stat *st)
+{
+    if (!(file->backend->storageFileStat)) {
+        errno = ENOSYS;
+        return -2;
+    }
+
+    return file->backend->storageFileStat(file, st);
+}
index 8ccfd75dd53020830e34377108ebc63a7be662f3..993bba5e3c918d48de58fc0ff10845d1b1322976 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * storage_driver.h: core driver for storage APIs
  *
- * Copyright (C) 2006-2008 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2014 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
 # define __VIR_STORAGE_DRIVER_H__
 
 # include "storage_conf.h"
+# include "conf/domain_conf.h"
+# include "conf/snapshot_conf.h"
+
+typedef struct _virStorageFileBackend virStorageFileBackend;
+typedef virStorageFileBackend *virStorageFileBackendPtr;
+
+typedef struct _virStorageFile virStorageFile;
+typedef virStorageFile *virStorageFilePtr;
+struct _virStorageFile {
+    virStorageFileBackendPtr backend;
+    void *priv;
+
+    char *path;
+    int type;
+    int protocol;
+
+    size_t nhosts;
+    virDomainDiskHostDefPtr hosts;
+};
+
+virStorageFilePtr
+virStorageFileInitFromDiskDef(virDomainDiskDefPtr disk);
+virStorageFilePtr
+virStorageFileInitFromSnapshotDef(virDomainSnapshotDiskDefPtr disk);
+void virStorageFileFree(virStorageFilePtr file);
+
+int virStorageFileCreate(virStorageFilePtr file);
+int virStorageFileUnlink(virStorageFilePtr file);
+int virStorageFileStat(virStorageFilePtr file,
+                       struct stat *stat);
 
 int storageRegister(void);
 
index 62a19cbfc3dde151c7ef72e9332d3d28f70778d3..0718a691738b43e1df980113bd361dc8aa8fb8c9 100644 (file)
@@ -433,6 +433,9 @@ qemu_LDADDS = ../src/libvirt_driver_qemu_impl.la
 if WITH_NETWORK
 qemu_LDADDS += ../src/libvirt_driver_network_impl.la
 endif WITH_NETWORK
+if WITH_STORAGE
+qemu_LDADDS += ../src/libvirt_driver_storage_impl.la
+endif WITH_STORAGE
 if WITH_DTRACE_PROBES
 qemu_LDADDS += ../src/libvirt_qemu_probes.lo
 endif WITH_DTRACE_PROBES