]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
storage: Introduce virStorageVolInfoFlags
authorJohn Ferlan <jferlan@redhat.com>
Tue, 29 Nov 2016 15:44:36 +0000 (10:44 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 20 Dec 2016 18:52:39 +0000 (13:52 -0500)
https://bugzilla.redhat.com/show_bug.cgi?id=1332019

This function will essentially be a wrapper to virStorageVolInfo in order
to provide a mechanism to have the "physical" size of the volume returned
instead of the "allocation" size. This will provide similar capabilities to
the virDomainBlockInfo which can return both allocation and physical of a
domain storage volume.

NB: Since we're reusing the _virStorageVolInfo and not creating a new
_virStorageVolInfoFlags structure, we'll need to generate the rpc APIs
remoteStorageVolGetInfoFlags and remoteDispatchStorageVolGetInfoFlags
(although both were originally created from gendispatch.pl and then
just copied into daemon/remote.c and src/remote/remote_driver.c).

The new API will allow the usage of a VIR_STORAGE_VOL_GET_PHYSICAL flag
and will make the decision to return the physical or allocation value
into the allocation field.

In order to get that physical value, virStorageBackendUpdateVolTargetInfoFD
adds logic to fill in physical value matching logic in qemuStorageLimitsRefresh
used by virDomainBlockInfo when the domain is inactive.

Signed-off-by: John Ferlan <jferlan@redhat.com>
daemon/remote.c
include/libvirt/libvirt-storage.h
src/driver-storage.h
src/libvirt-storage.c
src/libvirt_public.syms
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs
src/storage/storage_driver.c

index 46773da63407a8fa03b5b8994682e826748f5ada..23c9de429afb6b88a6dfe5815ec37409fb66249a 100644 (file)
@@ -6594,6 +6594,44 @@ remoteDispatchDomainInterfaceAddresses(virNetServerPtr server ATTRIBUTE_UNUSED,
 }
 
 
+static int
+remoteDispatchStorageVolGetInfoFlags(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                     virNetMessageErrorPtr rerr,
+                                     remote_storage_vol_get_info_flags_args *args,
+                                     remote_storage_vol_get_info_flags_ret *ret)
+{
+    int rv = -1;
+    virStorageVolPtr vol = NULL;
+    virStorageVolInfo tmp;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
+
+    if (!priv->conn) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (!(vol = get_nonnull_storage_vol(priv->conn, args->vol)))
+        goto cleanup;
+
+    if (virStorageVolGetInfoFlags(vol, &tmp, args->flags) < 0)
+        goto cleanup;
+
+    ret->type = tmp.type;
+    ret->capacity = tmp.capacity;
+    ret->allocation = tmp.allocation;
+    rv = 0;
+
+ cleanup:
+    if (rv < 0)
+        virNetMessageSaveError(rerr);
+    virObjectUnref(vol);
+    return rv;
+}
+
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
index 0974f6ed2951c68d8ae8b65504919250dfefdb84..8a861e4340521476d5bf084e24f8e581f9ed0bd1 100644 (file)
@@ -167,6 +167,14 @@ typedef enum {
 # endif
 } virStorageVolWipeAlgorithm;
 
+typedef enum {
+    VIR_STORAGE_VOL_USE_ALLOCATION = 0,
+
+    /* Return the physical size in allocation */
+    VIR_STORAGE_VOL_GET_PHYSICAL = 1 << 0,
+
+} virStorageVolInfoFlags;
+
 typedef struct _virStorageVolInfo virStorageVolInfo;
 
 struct _virStorageVolInfo {
@@ -359,6 +367,9 @@ int                     virStorageVolFree               (virStorageVolPtr vol);
 
 int                     virStorageVolGetInfo            (virStorageVolPtr vol,
                                                          virStorageVolInfoPtr info);
+int                     virStorageVolGetInfoFlags       (virStorageVolPtr vol,
+                                                         virStorageVolInfoPtr info,
+                                                         unsigned int flags);
 char *                  virStorageVolGetXMLDesc         (virStorageVolPtr pool,
                                                          unsigned int flags);
 
index afcb12bc84bada971d84cfcb15155890aaef1256..48e588a5461135e64386b59b4d1be3a6add831b5 100644 (file)
@@ -158,6 +158,11 @@ typedef int
 (*virDrvStorageVolGetInfo)(virStorageVolPtr vol,
                            virStorageVolInfoPtr info);
 
+typedef int
+(*virDrvStorageVolGetInfoFlags)(virStorageVolPtr vol,
+                                virStorageVolInfoPtr info,
+                                unsigned int flags);
+
 typedef char *
 (*virDrvStorageVolGetXMLDesc)(virStorageVolPtr pool,
                               unsigned int flags);
@@ -257,6 +262,7 @@ struct _virStorageDriver {
     virDrvStorageVolWipe storageVolWipe;
     virDrvStorageVolWipePattern storageVolWipePattern;
     virDrvStorageVolGetInfo storageVolGetInfo;
+    virDrvStorageVolGetInfoFlags storageVolGetInfoFlags;
     virDrvStorageVolGetXMLDesc storageVolGetXMLDesc;
     virDrvStorageVolGetPath storageVolGetPath;
     virDrvStorageVolResize storageVolResize;
index 48996ba4c9c8dbd09576afec01698cee19c74b1e..05eec8a9d421a31dce01035f8bb930da66b2d052 100644 (file)
@@ -1913,6 +1913,57 @@ virStorageVolGetInfo(virStorageVolPtr vol,
 }
 
 
+/**
+ * virStorageVolGetInfoFlags:
+ * @vol: pointer to storage volume
+ * @info: pointer at which to store info
+ * @flags: bitwise-OR of virStorageVolInfoFlags
+ *
+ * Fetches volatile information about the storage
+ * volume such as its current allocation.
+ *
+ * If the @flags argument is VIR_STORAGE_VOL_GET_PHYSICAL, then the physical
+ * bytes used for the volume will be returned in the @info allocation field.
+ * This is useful for sparse files and certain volume file types where the
+ * physical on disk usage can be different than the calculated allocation value
+ * as is the case with qcow2 files.
+ *
+ * Returns 0 on success, or -1 on failure
+ */
+int
+virStorageVolGetInfoFlags(virStorageVolPtr vol,
+                          virStorageVolInfoPtr info,
+                          unsigned int flags)
+{
+    virConnectPtr conn;
+    VIR_DEBUG("vol=%p, info=%p, flags=%x", vol, info, flags);
+
+    virResetLastError();
+
+    if (info)
+        memset(info, 0, sizeof(*info));
+
+    virCheckStorageVolReturn(vol, -1);
+    virCheckNonNullArgGoto(info, error);
+
+    conn = vol->conn;
+
+    if (conn->storageDriver->storageVolGetInfoFlags) {
+        int ret;
+        ret = conn->storageDriver->storageVolGetInfoFlags(vol, info, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(vol->conn);
+    return -1;
+}
+
+
 /**
  * virStorageVolGetXMLDesc:
  * @vol: pointer to storage volume
index e01604cad8540ef1e8604e3ad6b089b368bb2146..12ef085c51bc016c9ccf53f8baa72b268edaab5d 100644 (file)
@@ -746,4 +746,9 @@ LIBVIRT_2.2.0 {
         virConnectNodeDeviceEventDeregisterAny;
 } LIBVIRT_2.0.0;
 
+LIBVIRT_3.0.0 {
+    global:
+        virStorageVolGetInfoFlags;
+} LIBVIRT_2.2.0;
+
 # .... define new API here using predicted next version number ....
index 888052045eeb3a39d0e498a4c136fb2b30b1ac72..46da06f0a403b0778febb6634181b4629f0672c6 100644 (file)
@@ -7842,6 +7842,42 @@ remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags)
 }
 
 
+static int
+remoteStorageVolGetInfoFlags(virStorageVolPtr vol,
+                             virStorageVolInfoPtr result,
+                             unsigned int flags)
+{
+    int rv = -1;
+    struct private_data *priv = vol->conn->privateData;
+    remote_storage_vol_get_info_flags_args args;
+    remote_storage_vol_get_info_flags_ret ret;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_storage_vol(&args.vol, vol);
+    args.flags = flags;
+
+    memset(&ret, 0, sizeof(ret));
+
+    if (call(vol->conn, priv, 0, REMOTE_PROC_STORAGE_VOL_GET_INFO_FLAGS,
+             (xdrproc_t)xdr_remote_storage_vol_get_info_flags_args,
+             (char *)&args,
+             (xdrproc_t)xdr_remote_storage_vol_get_info_flags_ret,
+             (char *)&ret) == -1) {
+        goto done;
+    }
+
+    result->type = ret.type;
+    result->capacity = ret.capacity;
+    result->allocation = ret.allocation;
+    rv = 0;
+
+ done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
  * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
  * These can return NULL if underlying memory allocations fail,
@@ -8290,6 +8326,7 @@ static virStorageDriver storage_driver = {
     .storageVolWipe = remoteStorageVolWipe, /* 0.8.0 */
     .storageVolWipePattern = remoteStorageVolWipePattern, /* 0.9.10 */
     .storageVolGetInfo = remoteStorageVolGetInfo, /* 0.4.1 */
+    .storageVolGetInfoFlags = remoteStorageVolGetInfoFlags, /* 3.0.0 */
     .storageVolGetXMLDesc = remoteStorageVolGetXMLDesc, /* 0.4.1 */
     .storageVolGetPath = remoteStorageVolGetPath, /* 0.4.1 */
     .storageVolResize = remoteStorageVolResize, /* 0.9.10 */
index e8382dc51d4103d85b479d9bed948d7f539c7d76..b846ef21381e124b2f3a1e91ebdd2f5246f1375a 100644 (file)
@@ -1941,6 +1941,17 @@ struct remote_storage_vol_get_info_ret { /* insert@1 */
     unsigned hyper allocation;
 };
 
+struct remote_storage_vol_get_info_flags_args {
+    remote_nonnull_storage_vol vol;
+    unsigned int flags;
+};
+
+struct remote_storage_vol_get_info_flags_ret { /* insert@1 */
+    char type;
+    unsigned hyper capacity;
+    unsigned hyper allocation;
+};
+
 struct remote_storage_vol_get_path_args {
     remote_nonnull_storage_vol vol;
 };
@@ -5934,5 +5945,12 @@ enum remote_procedure {
      * @generate: both
      * @acl: none
      */
-    REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE = 377
+    REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE = 377,
+
+    /**
+     * @generate: none
+     * @priority: high
+     * @acl: storage_vol:read
+     */
+    REMOTE_PROC_STORAGE_VOL_GET_INFO_FLAGS = 378
 };
index b71accc073333158ce9a2b448f604fd70115c48b..41bc3bd247cc390de6948981205b1a6fa918acac 100644 (file)
@@ -1472,6 +1472,15 @@ struct remote_storage_vol_get_info_ret {
         uint64_t                   capacity;
         uint64_t                   allocation;
 };
+struct remote_storage_vol_get_info_flags_args {
+        remote_nonnull_storage_vol vol;
+        u_int                      flags;
+};
+struct remote_storage_vol_get_info_flags_ret {
+        char                       type;
+        uint64_t                   capacity;
+        uint64_t                   allocation;
+};
 struct remote_storage_vol_get_path_args {
         remote_nonnull_storage_vol vol;
 };
@@ -3169,4 +3178,5 @@ enum remote_procedure {
         REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_DEREGISTER_ANY = 375,
         REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE = 376,
         REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE = 377,
+        REMOTE_PROC_STORAGE_VOL_GET_INFO_FLAGS = 378,
 };
index a79acc6f06f582569290feeac6cd9735b85ac044..5fc706634a5db1749b97a603f5f99c2efcf41e02 100644 (file)
@@ -2620,18 +2620,21 @@ storageVolWipe(virStorageVolPtr obj,
 
 
 static int
-storageVolGetInfo(virStorageVolPtr obj,
-                  virStorageVolInfoPtr info)
+storageVolGetInfoFlags(virStorageVolPtr obj,
+                       virStorageVolInfoPtr info,
+                       unsigned int flags)
 {
     virStoragePoolObjPtr pool;
     virStorageBackendPtr backend;
     virStorageVolDefPtr vol;
     int ret = -1;
 
+    virCheckFlags(VIR_STORAGE_VOL_GET_PHYSICAL, -1);
+
     if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
         return -1;
 
-    if (virStorageVolGetInfoEnsureACL(obj->conn, pool->def, vol) < 0)
+    if (virStorageVolGetInfoFlagsEnsureACL(obj->conn, pool->def, vol) < 0)
         goto cleanup;
 
     if (backend->refreshVol &&
@@ -2641,7 +2644,10 @@ storageVolGetInfo(virStorageVolPtr obj,
     memset(info, 0, sizeof(*info));
     info->type = vol->type;
     info->capacity = vol->target.capacity;
-    info->allocation = vol->target.allocation;
+    if (flags & VIR_STORAGE_VOL_GET_PHYSICAL)
+        info->allocation = vol->target.physical;
+    else
+        info->allocation = vol->target.allocation;
     ret = 0;
 
  cleanup:
@@ -2649,6 +2655,15 @@ storageVolGetInfo(virStorageVolPtr obj,
     return ret;
 }
 
+
+static int
+storageVolGetInfo(virStorageVolPtr obj,
+                  virStorageVolInfoPtr info)
+{
+    return storageVolGetInfoFlags(obj, info, 0);
+}
+
+
 static char *
 storageVolGetXMLDesc(virStorageVolPtr obj,
                      unsigned int flags)
@@ -2803,6 +2818,7 @@ static virStorageDriver storageDriver = {
     .storageVolWipe = storageVolWipe, /* 0.8.0 */
     .storageVolWipePattern = storageVolWipePattern, /* 0.9.10 */
     .storageVolGetInfo = storageVolGetInfo, /* 0.4.0 */
+    .storageVolGetInfoFlags = storageVolGetInfoFlags, /* 3.0.0 */
     .storageVolGetXMLDesc = storageVolGetXMLDesc, /* 0.4.0 */
     .storageVolGetPath = storageVolGetPath, /* 0.4.0 */
     .storageVolResize = storageVolResize, /* 0.9.10 */