[libvirt] [PATCH 0/6] Add build options to pool create[-as] and start

https://bugzilla.redhat.com/show_bug.cgi?id=830056 Add the capability to build the pool during pool creation or startup NOTE: If patches 2-4 regarding usage of #define for repeated command options are acceptible, I can start doing the same for other virsh commands. I just found it easier and I think better than the need to continually cut-n-paste for each command option entry. If it's preferred to keep cut-n-paste'ing, then I can modify patch 5 & 6 to follow that model. NOTE: Based loosely on patches posted quite a while ago by Osier Yang before he left Red Hat, see: (Cover) https://www.redhat.com/archives/libvir-list/2012-July/msg00494.html and (libvirt API, storage driver changes) https://www.redhat.com/archives/libvir-list/2012-July/msg01328.html and (virsh changes) https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html John Ferlan (6): storage: Add flags to allow building pool during create processing virsh: Create macro for "pool" option virsh: Create macro for "file" option virsh: Create macro for "overwrite" and no-overwrite" options virsh: Create a macro for pool-define-as and pool-create-as options virsh: Add build flags to pool-create[-as] and pool-start include/libvirt/libvirt-storage.h | 16 +- src/libvirt-storage.c | 4 +- src/storage/storage_driver.c | 42 ++++- tools/virsh-pool.c | 360 ++++++++++++++++++++++---------------- tools/virsh.pod | 25 ++- 5 files changed, 288 insertions(+), 159 deletions(-) -- 2.5.0

https://bugzilla.redhat.com/show_bug.cgi?id=830056 Add flags handling to the virStoragePoolCreate and virStoragePoolCreateXML API's which will allow the caller to provide the capability for the storage pool create API's to also perform a pool build during creation rather than requiring the additional buildPool step. This will allow transient pools to be defined, built, and started. The new flags are: * VIR_STORAGE_POOL_CREATE_WITH_BUILD Perform buildPool without any flags passed. * VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE Perform buildPool using VIR_STORAGE_POOL_BUILD_OVERWRITE flag. * VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE Perform buildPool using VIR_STORAGE_POOL_BUILD_NO_OVERWRITE flag. It is up to the backend to handle the processing of build flags. The overwrite and no-overwrite flags are mutually exclusive. NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see: https://www.redhat.com/archives/libvir-list/2012-July/msg01328.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/libvirt-storage.h | 16 ++++++++++++++- src/libvirt-storage.c | 4 ++-- src/storage/storage_driver.c | 42 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 9fc3c2d..996a726 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -57,7 +57,6 @@ typedef enum { # endif } virStoragePoolState; - typedef enum { VIR_STORAGE_POOL_BUILD_NEW = 0, /* Regular build from scratch */ VIR_STORAGE_POOL_BUILD_REPAIR = (1 << 0), /* Repair / reinitialize */ @@ -71,6 +70,21 @@ typedef enum { VIR_STORAGE_POOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ } virStoragePoolDeleteFlags; +typedef enum { + VIR_STORAGE_POOL_CREATE_NORMAL = 0, + + /* Create the pool and perform pool build without any flags */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD = 1 << 0, + + /* Create the pool and perform pool build using the + * VIR_STORAGE_POOL_BUILD_OVERWRITE flag */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE = 1 << 1, + + /* Create the pool and perform pool build using the + * VIR_STORAGE_POOL_BUILD_NO_OVERWRITE flag */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE = 1 << 2, +} virStoragePoolCreateFlags; + typedef struct _virStoragePoolInfo virStoragePoolInfo; struct _virStoragePoolInfo { diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c index 66dd9f0..238a6cd 100644 --- a/src/libvirt-storage.c +++ b/src/libvirt-storage.c @@ -505,7 +505,7 @@ virStoragePoolLookupByVolume(virStorageVolPtr vol) * virStoragePoolCreateXML: * @conn: pointer to hypervisor connection * @xmlDesc: XML description for new pool - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virStoragePoolCreateFlags * * Create a new storage based on its XML description. The * pool is not persistent, so its definition will disappear @@ -670,7 +670,7 @@ virStoragePoolUndefine(virStoragePoolPtr pool) /** * virStoragePoolCreate: * @pool: pointer to storage pool - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virStoragePoolCreateFlags * * Starts an inactive storage pool * diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index bbf21f6..59a18bf 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -671,8 +671,11 @@ storagePoolCreateXML(virConnectPtr conn, virStoragePoolPtr ret = NULL; virStorageBackendPtr backend; char *stateFile = NULL; + unsigned int build_flags = 0; - virCheckFlags(0, NULL); + virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL); storageDriverLock(); if (!(def = virStoragePoolDefParseString(xml))) @@ -694,6 +697,22 @@ storagePoolCreateXML(virConnectPtr conn, goto cleanup; def = NULL; + if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (build_flags || + (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { + if (backend->buildPool(conn, pool, build_flags) < 0) { + virStoragePoolObjRemove(&driver->pools, pool); + pool = NULL; + goto cleanup; + } + } + } + if (backend->startPool && backend->startPool(conn, pool) < 0) { virStoragePoolObjRemove(&driver->pools, pool); @@ -845,8 +864,11 @@ storagePoolCreate(virStoragePoolPtr obj, virStorageBackendPtr backend; int ret = -1; char *stateFile = NULL; + unsigned int build_flags = 0; - virCheckFlags(0, -1); + virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL); if (!(pool = virStoragePoolObjFromStoragePool(obj))) return -1; @@ -864,6 +886,22 @@ storagePoolCreate(virStoragePoolPtr obj, goto cleanup; } + if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (build_flags || + (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { + if (backend->buildPool(obj->conn, pool, build_flags) < 0) { + virStoragePoolObjRemove(&driver->pools, pool); + pool = NULL; + goto cleanup; + } + } + } + VIR_INFO("Starting up storage pool '%s'", pool->def->name); if (backend->startPool && backend->startPool(obj->conn, pool) < 0) -- 2.5.0

On 25.11.2015 20:11, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=830056
Add flags handling to the virStoragePoolCreate and virStoragePoolCreateXML API's which will allow the caller to provide the capability for the storage pool create API's to also perform a pool build during creation rather than requiring the additional buildPool step. This will allow transient pools to be defined, built, and started.
The new flags are:
* VIR_STORAGE_POOL_CREATE_WITH_BUILD Perform buildPool without any flags passed.
* VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE Perform buildPool using VIR_STORAGE_POOL_BUILD_OVERWRITE flag.
* VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE Perform buildPool using VIR_STORAGE_POOL_BUILD_NO_OVERWRITE flag.
It is up to the backend to handle the processing of build flags. The overwrite and no-overwrite flags are mutually exclusive.
NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see:
https://www.redhat.com/archives/libvir-list/2012-July/msg01328.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/libvirt-storage.h | 16 ++++++++++++++- src/libvirt-storage.c | 4 ++-- src/storage/storage_driver.c | 42 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 9fc3c2d..996a726 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -57,7 +57,6 @@ typedef enum { # endif } virStoragePoolState;
- typedef enum { VIR_STORAGE_POOL_BUILD_NEW = 0, /* Regular build from scratch */ VIR_STORAGE_POOL_BUILD_REPAIR = (1 << 0), /* Repair / reinitialize */ @@ -71,6 +70,21 @@ typedef enum { VIR_STORAGE_POOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ } virStoragePoolDeleteFlags;
+typedef enum { + VIR_STORAGE_POOL_CREATE_NORMAL = 0, + + /* Create the pool and perform pool build without any flags */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD = 1 << 0, + + /* Create the pool and perform pool build using the + * VIR_STORAGE_POOL_BUILD_OVERWRITE flag */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE = 1 << 1, + + /* Create the pool and perform pool build using the + * VIR_STORAGE_POOL_BUILD_NO_OVERWRITE flag */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE = 1 << 2,
So _OVERWRITE and _NO_OVERWRITE flags are mutually exclusive then, right? Probably worth noting.
+} virStoragePoolCreateFlags; + typedef struct _virStoragePoolInfo virStoragePoolInfo;
struct _virStoragePoolInfo { diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c index 66dd9f0..238a6cd 100644 --- a/src/libvirt-storage.c +++ b/src/libvirt-storage.c @@ -505,7 +505,7 @@ virStoragePoolLookupByVolume(virStorageVolPtr vol) * virStoragePoolCreateXML: * @conn: pointer to hypervisor connection * @xmlDesc: XML description for new pool - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virStoragePoolCreateFlags * * Create a new storage based on its XML description. The * pool is not persistent, so its definition will disappear @@ -670,7 +670,7 @@ virStoragePoolUndefine(virStoragePoolPtr pool) /** * virStoragePoolCreate: * @pool: pointer to storage pool - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virStoragePoolCreateFlags * * Starts an inactive storage pool * diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index bbf21f6..59a18bf 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -671,8 +671,11 @@ storagePoolCreateXML(virConnectPtr conn, virStoragePoolPtr ret = NULL; virStorageBackendPtr backend; char *stateFile = NULL; + unsigned int build_flags = 0;
- virCheckFlags(0, NULL); + virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL);
How about VIR_EXCLUSIVE_FLAGS_RET(_OVERWRITE, _NO_OVERWRITE, NULL);
storageDriverLock(); if (!(def = virStoragePoolDefParseString(xml))) @@ -694,6 +697,22 @@ storagePoolCreateXML(virConnectPtr conn, goto cleanup; def = NULL;
+ if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (build_flags || + (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) {
a-ha! So I need to pass _BUILD flag, and optionally one of _OVERWRITE and _NO_OVERWRITE too. Okay.
+ if (backend->buildPool(conn, pool, build_flags) < 0) { + virStoragePoolObjRemove(&driver->pools, pool); + pool = NULL; + goto cleanup; + } + } + } + if (backend->startPool && backend->startPool(conn, pool) < 0) { virStoragePoolObjRemove(&driver->pools, pool); @@ -845,8 +864,11 @@ storagePoolCreate(virStoragePoolPtr obj, virStorageBackendPtr backend; int ret = -1; char *stateFile = NULL; + unsigned int build_flags = 0;
- virCheckFlags(0, -1); + virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL);
s/NULL/-1/. The function is returning an integer, not a pointer. Plus it would be nice if we check the mutually exclusive flags here too.
if (!(pool = virStoragePoolObjFromStoragePool(obj))) return -1; @@ -864,6 +886,22 @@ storagePoolCreate(virStoragePoolPtr obj, goto cleanup; }
+ if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (build_flags || + (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { + if (backend->buildPool(obj->conn, pool, build_flags) < 0) { + virStoragePoolObjRemove(&driver->pools, pool); + pool = NULL; + goto cleanup; + } + } + } + VIR_INFO("Starting up storage pool '%s'", pool->def->name); if (backend->startPool && backend->startPool(obj->conn, pool) < 0)
Otherwise looking good. ACK. Michal

On 12/16/2015 08:18 AM, Michal Privoznik wrote:
On 25.11.2015 20:11, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=830056
Add flags handling to the virStoragePoolCreate and virStoragePoolCreateXML API's which will allow the caller to provide the capability for the storage pool create API's to also perform a pool build during creation rather than requiring the additional buildPool step. This will allow transient pools to be defined, built, and started.
The new flags are:
* VIR_STORAGE_POOL_CREATE_WITH_BUILD Perform buildPool without any flags passed.
* VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE Perform buildPool using VIR_STORAGE_POOL_BUILD_OVERWRITE flag.
* VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE Perform buildPool using VIR_STORAGE_POOL_BUILD_NO_OVERWRITE flag.
It is up to the backend to handle the processing of build flags. The overwrite and no-overwrite flags are mutually exclusive.
NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see:
https://www.redhat.com/archives/libvir-list/2012-July/msg01328.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/libvirt-storage.h | 16 ++++++++++++++- src/libvirt-storage.c | 4 ++-- src/storage/storage_driver.c | 42 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 9fc3c2d..996a726 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -57,7 +57,6 @@ typedef enum { # endif } virStoragePoolState;
- typedef enum { VIR_STORAGE_POOL_BUILD_NEW = 0, /* Regular build from scratch */ VIR_STORAGE_POOL_BUILD_REPAIR = (1 << 0), /* Repair / reinitialize */ @@ -71,6 +70,21 @@ typedef enum { VIR_STORAGE_POOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ } virStoragePoolDeleteFlags;
+typedef enum { + VIR_STORAGE_POOL_CREATE_NORMAL = 0, + + /* Create the pool and perform pool build without any flags */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD = 1 << 0, + + /* Create the pool and perform pool build using the + * VIR_STORAGE_POOL_BUILD_OVERWRITE flag */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE = 1 << 1, + + /* Create the pool and perform pool build using the + * VIR_STORAGE_POOL_BUILD_NO_OVERWRITE flag */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE = 1 << 2,
So _OVERWRITE and _NO_OVERWRITE flags are mutually exclusive then, right? Probably worth noting.
+} virStoragePoolCreateFlags; + typedef struct _virStoragePoolInfo virStoragePoolInfo;
struct _virStoragePoolInfo { diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c index 66dd9f0..238a6cd 100644 --- a/src/libvirt-storage.c +++ b/src/libvirt-storage.c @@ -505,7 +505,7 @@ virStoragePoolLookupByVolume(virStorageVolPtr vol) * virStoragePoolCreateXML: * @conn: pointer to hypervisor connection * @xmlDesc: XML description for new pool - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virStoragePoolCreateFlags * * Create a new storage based on its XML description. The * pool is not persistent, so its definition will disappear @@ -670,7 +670,7 @@ virStoragePoolUndefine(virStoragePoolPtr pool) /** * virStoragePoolCreate: * @pool: pointer to storage pool - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virStoragePoolCreateFlags * * Starts an inactive storage pool * diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index bbf21f6..59a18bf 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -671,8 +671,11 @@ storagePoolCreateXML(virConnectPtr conn, virStoragePoolPtr ret = NULL; virStorageBackendPtr backend; char *stateFile = NULL; + unsigned int build_flags = 0;
- virCheckFlags(0, NULL); + virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL);
How about VIR_EXCLUSIVE_FLAGS_RET(_OVERWRITE, _NO_OVERWRITE, NULL);
The disk and fs backends do check as well, but I can add it here.
storageDriverLock(); if (!(def = virStoragePoolDefParseString(xml))) @@ -694,6 +697,22 @@ storagePoolCreateXML(virConnectPtr conn, goto cleanup; def = NULL;
+ if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (build_flags || + (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) {
a-ha! So I need to pass _BUILD flag, and optionally one of _OVERWRITE and _NO_OVERWRITE too. Okay.
Right - if you want to build prior to start, then use one of the flags. Leaving it up to the backend buildPool function to decide how to handle the overwrite when that option isn't provided.
+ if (backend->buildPool(conn, pool, build_flags) < 0) { + virStoragePoolObjRemove(&driver->pools, pool); + pool = NULL; + goto cleanup; + } + } + } + if (backend->startPool && backend->startPool(conn, pool) < 0) { virStoragePoolObjRemove(&driver->pools, pool); @@ -845,8 +864,11 @@ storagePoolCreate(virStoragePoolPtr obj, virStorageBackendPtr backend; int ret = -1; char *stateFile = NULL; + unsigned int build_flags = 0;
- virCheckFlags(0, -1); + virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE | + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL);
s/NULL/-1/. The function is returning an integer, not a pointer.
Ah right - dang that cut-n-paste...
Plus it would be nice if we check the mutually exclusive flags here too.
Sure. tks - John
if (!(pool = virStoragePoolObjFromStoragePool(obj))) return -1; @@ -864,6 +886,22 @@ storagePoolCreate(virStoragePoolPtr obj, goto cleanup; }
+ if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (build_flags || + (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { + if (backend->buildPool(obj->conn, pool, build_flags) < 0) { + virStoragePoolObjRemove(&driver->pools, pool); + pool = NULL; + goto cleanup; + } + } + } + VIR_INFO("Starting up storage pool '%s'", pool->def->name); if (backend->startPool && backend->startPool(obj->conn, pool) < 0)
Otherwise looking good. ACK.
Michal

Rather than continually cut/paste the "pool" option for pool command option structures, generate a macro which will commonly define it for any command. Then of course use that macro. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 91 +++++++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 60 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index cf5a8f3..6922ad5 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -33,6 +33,13 @@ #include "conf/storage_conf.h" #include "virstring.h" +#define OPT_POOL_COMMON \ + {.name = "pool", \ + .type = VSH_OT_DATA, \ + .flags = VSH_OFLAG_REQ, \ + .help = N_("pool name or uuid") \ + }, \ + virStoragePoolPtr virshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char **name, unsigned int flags) @@ -85,11 +92,8 @@ static const vshCmdInfo info_pool_autostart[] = { }; static const vshCmdOptDef opts_pool_autostart[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = "disable", .type = VSH_OT_BOOL, .help = N_("disable autostarting") @@ -500,11 +504,8 @@ static const vshCmdInfo info_pool_build[] = { }; static const vshCmdOptDef opts_pool_build[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = "no-overwrite", .type = VSH_OT_BOOL, .help = N_("do not overwrite an existing pool of this type") @@ -559,11 +560,8 @@ static const vshCmdInfo info_pool_destroy[] = { }; static const vshCmdOptDef opts_pool_destroy[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -602,11 +600,8 @@ static const vshCmdInfo info_pool_delete[] = { }; static const vshCmdOptDef opts_pool_delete[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -645,11 +640,8 @@ static const vshCmdInfo info_pool_refresh[] = { }; static const vshCmdOptDef opts_pool_refresh[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -688,11 +680,8 @@ static const vshCmdInfo info_pool_dumpxml[] = { }; static const vshCmdOptDef opts_pool_dumpxml[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = "inactive", .type = VSH_OT_BOOL, .help = N_("show inactive defined XML") @@ -1542,11 +1531,8 @@ static const vshCmdInfo info_pool_info[] = { }; static const vshCmdOptDef opts_pool_info[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -1622,11 +1608,8 @@ static const vshCmdInfo info_pool_name[] = { }; static const vshCmdOptDef opts_pool_name[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -1657,11 +1640,8 @@ static const vshCmdInfo info_pool_start[] = { }; static const vshCmdOptDef opts_pool_start[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("name or uuid of the inactive pool") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -1700,11 +1680,8 @@ static const vshCmdInfo info_pool_undefine[] = { }; static const vshCmdOptDef opts_pool_undefine[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -1743,11 +1720,8 @@ static const vshCmdInfo info_pool_uuid[] = { }; static const vshCmdOptDef opts_pool_uuid[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name") - }, + OPT_POOL_COMMON + {.name = NULL} }; @@ -1783,11 +1757,8 @@ static const vshCmdInfo info_pool_edit[] = { }; static const vshCmdOptDef opts_pool_edit[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = NULL} }; -- 2.5.0

On 25.11.2015 20:11, John Ferlan wrote:
Rather than continually cut/paste the "pool" option for pool command option structures, generate a macro which will commonly define it for any command. Then of course use that macro.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 91 +++++++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 60 deletions(-)
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index cf5a8f3..6922ad5 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -33,6 +33,13 @@ #include "conf/storage_conf.h" #include "virstring.h"
+#define OPT_POOL_COMMON \ + {.name = "pool", \ + .type = VSH_OT_DATA, \ + .flags = VSH_OFLAG_REQ, \ + .help = N_("pool name or uuid") \ + }, \ + virStoragePoolPtr virshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char **name, unsigned int flags) @@ -85,11 +92,8 @@ static const vshCmdInfo info_pool_autostart[] = { };
static const vshCmdOptDef opts_pool_autostart[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = "disable", .type = VSH_OT_BOOL, .help = N_("disable autostarting")
Nice. ACK Should we do something similar to domain, network, ... in the rest of virsh? Michal

[...]
static const vshCmdOptDef opts_pool_autostart[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON + {.name = "disable", .type = VSH_OT_BOOL, .help = N_("disable autostarting")
Nice. ACK
Should we do something similar to domain, network, ... in the rest of virsh?
I think it would make certain things easier - I did remark on this in the cover letter. It gets a bit tedious to do and review; however, I think in the long run makes things more consistent. There are a few options with "slight" differences, but nothing that cannot be worked out. John

On Wed, Dec 16, 2015 at 08:24:43 -0500, John Ferlan wrote:
[...]
static const vshCmdOptDef opts_pool_autostart[] = { - {.name = "pool", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("pool name or uuid") - }, + OPT_POOL_COMMON
VSH_POOL_OPT_COMMON for consistency with basically all the other macros. Also please don't include the trailing comma in the macro, it looks weird c-wise, and will make possible regex matches for code consistency really weird.
+ {.name = "disable", .type = VSH_OT_BOOL, .help = N_("disable autostarting")
Nice. ACK
Should we do something similar to domain, network, ... in the rest of virsh?
Hiding stuff behind macros can be confusing sometimes, but for the most commonly used objects it would be reasonable.
I think it would make certain things easier - I did remark on this in the cover letter. It gets a bit tedious to do and review; however, I think in the long run makes things more consistent. There are a few options with "slight" differences, but nothing that cannot be worked out.
Easier? not really, it would just introduce less code when adding new stuff at the slight cost of having to resolve the macro when looking up what the stuff is doing. That's why only the most common objects should be converted. Peter

Rather than continually cut/paste the "file" option for pool command option structures, generate a macro which will commonly define it for any command. Then of course use that macro. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index 6922ad5..4b4fea0 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -40,6 +40,13 @@ .help = N_("pool name or uuid") \ }, \ +#define OPT_FILE_COMMON \ + {.name = "file", \ + .type = VSH_OT_DATA, \ + .flags = VSH_OFLAG_REQ, \ + .help = N_("file containing an XML pool description") \ + }, \ + virStoragePoolPtr virshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char **name, unsigned int flags) @@ -145,11 +152,8 @@ static const vshCmdInfo info_pool_create[] = { }; static const vshCmdOptDef opts_pool_create[] = { - {.name = "file", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("file containing an XML pool description") - }, + OPT_FILE_COMMON + {.name = NULL} }; @@ -410,11 +414,8 @@ static const vshCmdInfo info_pool_define[] = { }; static const vshCmdOptDef opts_pool_define[] = { - {.name = "file", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("file containing an XML pool description") - }, + OPT_FILE_COMMON + {.name = NULL} }; -- 2.5.0

On 25.11.2015 20:11, John Ferlan wrote:
Rather than continually cut/paste the "file" option for pool command option structures, generate a macro which will commonly define it for any command. Then of course use that macro.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
ACK Michal

Although not currently used in more than one command, it soon will be so create a common macro to be used in the new command location. Additionally, add the ".flags = 0," for both to match the expections of the structure being predefined. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index 4b4fea0..ff77039 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -47,6 +47,20 @@ .help = N_("file containing an XML pool description") \ }, \ +#define OPT_NO_OVERWRITE_COMMON \ + {.name = "no-overwrite", \ + .type = VSH_OT_BOOL, \ + .flags = 0, \ + .help = N_("do not overwrite an existing pool of this type") \ + }, \ + +#define OPT_OVERWRITE_COMMON \ + {.name = "overwrite", \ + .type = VSH_OT_BOOL, \ + .flags = 0, \ + .help = N_("overwrite any existing data") \ + }, \ + virStoragePoolPtr virshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char **name, unsigned int flags) @@ -506,15 +520,9 @@ static const vshCmdInfo info_pool_build[] = { static const vshCmdOptDef opts_pool_build[] = { OPT_POOL_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON - {.name = "no-overwrite", - .type = VSH_OT_BOOL, - .help = N_("do not overwrite an existing pool of this type") - }, - {.name = "overwrite", - .type = VSH_OT_BOOL, - .help = N_("overwrite any existing data") - }, {.name = NULL} }; -- 2.5.0

On 25.11.2015 20:11, John Ferlan wrote:
Although not currently used in more than one command, it soon will be so create a common macro to be used in the new command location.
Additionally, add the ".flags = 0," for both to match the expections of the structure being predefined.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
ACK Michal

On Wed, Dec 16, 2015 at 14:18:22 +0100, Michal Privoznik wrote:
On 25.11.2015 20:11, John Ferlan wrote:
Although not currently used in more than one command, it soon will be so create a common macro to be used in the new command location.
Additionally, add the ".flags = 0," for both to match the expections of the structure being predefined.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
ACK
I don't really fancy this one. It introduces the macro for a very uncommon option value. If it will be used more that 10 times it would make sense. For 2 or 3 uses it does not. Peter

On 12/16/2015 08:35 AM, Peter Krempa wrote:
On Wed, Dec 16, 2015 at 14:18:22 +0100, Michal Privoznik wrote:
On 25.11.2015 20:11, John Ferlan wrote:
Although not currently used in more than one command, it soon will be so create a common macro to be used in the new command location.
Additionally, add the ".flags = 0," for both to match the expections of the structure being predefined.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
ACK
I don't really fancy this one. It introduces the macro for a very uncommon option value. If it will be used more that 10 times it would make sense. For 2 or 3 uses it does not.
Peter
So then in your opinion and using the same logic, patch 3 is also nixed? This one will get used in patch 6. Like I noted in the cover letter - I see value in having the macros and I also see the pain (having to go look them up). Adjusting the changes to remove/use commas is fine - just made the initial cut-n-paste easier John

On Wed, Dec 16, 2015 at 08:44:50 -0500, John Ferlan wrote:
On 12/16/2015 08:35 AM, Peter Krempa wrote:
On Wed, Dec 16, 2015 at 14:18:22 +0100, Michal Privoznik wrote:
On 25.11.2015 20:11, John Ferlan wrote:
Although not currently used in more than one command, it soon will be so create a common macro to be used in the new command location.
Additionally, add the ".flags = 0," for both to match the expections of the structure being predefined.
The compiler already does zero init for fields that are not specified explicitly.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
ACK
I don't really fancy this one. It introduces the macro for a very uncommon option value. If it will be used more that 10 times it would make sense. For 2 or 3 uses it does not.
Peter
So then in your opinion and using the same logic, patch 3 is also nixed? This one will get used in patch 6.
With that use it will result in total 4 uses. I won't object if you fix the macro name and remove the comma Patch 3 attempts to create a universal macro for any "file" option, but that can't be really done universally. See for yourself: git grep -A 4 '\.name = "file"' The name of the macro would really need to be specific for pool XML file name. Any other attempt will create confusion and I don't think it's worth.
Like I noted in the cover letter - I see value in having the macros and I also see the pain (having to go look them up).
Adjusting the changes to remove/use commas is fine - just made the initial cut-n-paste easier
John

[...]
So then in your opinion and using the same logic, patch 3 is also nixed? This one will get used in patch 6.
With that use it will result in total 4 uses. I won't object if you fix the macro name and remove the comma
Hmm. by name change do you mean "OPT_POOL_FILE_COMMON", "OPT_POOL_OVERWRITE_COMMON", etc.? I guess I was thinking less globally available macros, e.g. module specific rather than adding them to some more generally included virsh*.h file.
Patch 3 attempts to create a universal macro for any "file" option, but that can't be really done universally. See for yourself:
git grep -A 4 '\.name = "file"'
Yeah - 'file' is one of those that isn't universal for all virsh*.c files. This started out of a desire to not copy all the opts_pool_X_as options as was done by Osier in his initial changes (see link in cover) for pool-create-as and pool-define-as. Then I thought - oh we have so many duplicated elements, why not generate module specific macros to handle. John
The name of the macro would really need to be specific for pool XML file name. Any other attempt will create confusion and I don't think it's worth.
Like I noted in the cover letter - I see value in having the macros and I also see the pain (having to go look them up).
Adjusting the changes to remove/use commas is fine - just made the initial cut-n-paste easier
John

On 12/16/2015 10:32 AM, John Ferlan wrote:
[...]
So then in your opinion and using the same logic, patch 3 is also nixed? This one will get used in patch 6.
With that use it will result in total 4 uses. I won't object if you fix the macro name and remove the comma
Hmm. by name change do you mean "OPT_POOL_FILE_COMMON", "OPT_POOL_OVERWRITE_COMMON", etc.? I guess I was thinking less globally available macros, e.g. module specific rather than adding them to some more generally included virsh*.h file.
nm... patch 2 comment... you'd rather see VSH_POOL_OPT_COMMON than OPT_POOL_COMMON John

Although they both are the same now, a future patch will add new options to pool-create-as. So create a common macro to capture commonality, then use that in the command specific structure. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 151 ++++++++++++++++++++++++++++------------------------- 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index ff77039..cb91cd3 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -61,6 +61,74 @@ .help = N_("overwrite any existing data") \ }, \ +#define OPTS_POOL_COMMON_X_AS \ + {.name = "name", \ + .type = VSH_OT_DATA, \ + .flags = VSH_OFLAG_REQ, \ + .help = N_("name of the pool") \ + }, \ + {.name = "type", \ + .type = VSH_OT_DATA, \ + .flags = VSH_OFLAG_REQ, \ + .help = N_("type of the pool") \ + }, \ + {.name = "print-xml", \ + .type = VSH_OT_BOOL, \ + .help = N_("print XML document, but don't define/create") \ + }, \ + {.name = "source-host", \ + .type = VSH_OT_STRING, \ + .help = N_("source-host for underlying storage") \ + }, \ + {.name = "source-path", \ + .type = VSH_OT_STRING, \ + .help = N_("source path for underlying storage") \ + }, \ + {.name = "source-dev", \ + .type = VSH_OT_STRING, \ + .help = N_("source device for underlying storage") \ + }, \ + {.name = "source-name", \ + .type = VSH_OT_STRING, \ + .help = N_("source name for underlying storage") \ + }, \ + {.name = "target", \ + .type = VSH_OT_STRING, \ + .help = N_("target for underlying storage") \ + }, \ + {.name = "source-format", \ + .type = VSH_OT_STRING, \ + .help = N_("format for underlying storage") \ + }, \ + {.name = "auth-type", \ + .type = VSH_OT_STRING, \ + .help = N_("auth type to be used for underlying storage") \ + }, \ + {.name = "auth-username", \ + .type = VSH_OT_STRING, \ + .help = N_("auth username to be used for underlying storage") \ + }, \ + {.name = "secret-usage", \ + .type = VSH_OT_STRING, \ + .help = N_("auth secret usage to be used for underlying storage") \ + }, \ + {.name = "adapter-name", \ + .type = VSH_OT_STRING, \ + .help = N_("adapter name to be used for underlying storage") \ + }, \ + {.name = "adapter-wwnn", \ + .type = VSH_OT_STRING, \ + .help = N_("adapter wwnn to be used for underlying storage") \ + }, \ + {.name = "adapter-wwpn", \ + .type = VSH_OT_STRING, \ + .help = N_("adapter wwpn to be used for underlying storage") \ + }, \ + {.name = "adapter-parent", \ + .type = VSH_OT_STRING, \ + .help = N_("adapter parent to be used for underlying storage") \ + }, \ + virStoragePoolPtr virshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char **name, unsigned int flags) @@ -200,76 +268,9 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) return ret; } -/* - * XML Building helper for pool-define-as and pool-create-as - */ -static const vshCmdOptDef opts_pool_X_as[] = { - {.name = "name", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("name of the pool") - }, - {.name = "type", - .type = VSH_OT_DATA, - .flags = VSH_OFLAG_REQ, - .help = N_("type of the pool") - }, - {.name = "print-xml", - .type = VSH_OT_BOOL, - .help = N_("print XML document, but don't define/create") - }, - {.name = "source-host", - .type = VSH_OT_STRING, - .help = N_("source-host for underlying storage") - }, - {.name = "source-path", - .type = VSH_OT_STRING, - .help = N_("source path for underlying storage") - }, - {.name = "source-dev", - .type = VSH_OT_STRING, - .help = N_("source device for underlying storage") - }, - {.name = "source-name", - .type = VSH_OT_STRING, - .help = N_("source name for underlying storage") - }, - {.name = "target", - .type = VSH_OT_STRING, - .help = N_("target for underlying storage") - }, - {.name = "source-format", - .type = VSH_OT_STRING, - .help = N_("format for underlying storage") - }, - {.name = "auth-type", - .type = VSH_OT_STRING, - .help = N_("auth type to be used for underlying storage") - }, - {.name = "auth-username", - .type = VSH_OT_STRING, - .help = N_("auth username to be used for underlying storage") - }, - {.name = "secret-usage", - .type = VSH_OT_STRING, - .help = N_("auth secret usage to be used for underlying storage") - }, - {.name = "adapter-name", - .type = VSH_OT_STRING, - .help = N_("adapter name to be used for underlying storage") - }, - {.name = "adapter-wwnn", - .type = VSH_OT_STRING, - .help = N_("adapter wwnn to be used for underlying storage") - }, - {.name = "adapter-wwpn", - .type = VSH_OT_STRING, - .help = N_("adapter wwpn to be used for underlying storage") - }, - {.name = "adapter-parent", - .type = VSH_OT_STRING, - .help = N_("adapter parent to be used for underlying storage") - }, +static const vshCmdOptDef opts_pool_define_as[] = { + OPTS_POOL_COMMON_X_AS + {.name = NULL} }; @@ -383,6 +384,12 @@ static const vshCmdInfo info_pool_create_as[] = { {.name = NULL} }; +static const vshCmdOptDef opts_pool_create_as[] = { + OPTS_POOL_COMMON_X_AS + + {.name = NULL} +}; + static bool cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) { @@ -1850,7 +1857,7 @@ const vshCmdDef storagePoolCmds[] = { }, {.name = "pool-create-as", .handler = cmdPoolCreateAs, - .opts = opts_pool_X_as, + .opts = opts_pool_create_as, .info = info_pool_create_as, .flags = 0 }, @@ -1862,7 +1869,7 @@ const vshCmdDef storagePoolCmds[] = { }, {.name = "pool-define-as", .handler = cmdPoolDefineAs, - .opts = opts_pool_X_as, + .opts = opts_pool_define_as, .info = info_pool_define_as, .flags = 0 }, -- 2.5.0

On 25.11.2015 20:11, John Ferlan wrote:
Although they both are the same now, a future patch will add new options to pool-create-as. So create a common macro to capture commonality, then use that in the command specific structure.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 151 ++++++++++++++++++++++++++++------------------------- 1 file changed, 79 insertions(+), 72 deletions(-)
ACK Michal

https://bugzilla.redhat.com/show_bug.cgi?id=830056 Utilize recently added VIR_STORAGE_POOL_CREATE_WITH_BUILD* flags in order to pass the flags along to the virStoragePoolCreateXML and virStoragePoolCreate API's. This affects the 'virsh pool-create', 'virsh pool-create-as', and 'virsh pool-start' commands. While it could be argued that pool-start doesn't need the flags, they could prove useful for someone trying to do one command build --overwrite and start command processing or essentially starting with a clean slate. NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see: https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 25 ++++++++++++++++++- 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index cb91cd3..1bb987d 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -47,6 +47,13 @@ .help = N_("file containing an XML pool description") \ }, \ +#define OPT_BUILD_COMMON \ + {.name = "build", \ + .type = VSH_OT_BOOL, \ + .flags = 0, \ + .help = N_("build the pool as normal") \ + }, \ + #define OPT_NO_OVERWRITE_COMMON \ {.name = "no-overwrite", \ .type = VSH_OT_BOOL, \ @@ -235,6 +242,9 @@ static const vshCmdInfo info_pool_create[] = { static const vshCmdOptDef opts_pool_create[] = { OPT_FILE_COMMON + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON {.name = NULL} }; @@ -246,15 +256,32 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = true; char *buffer; + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData; if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false; + build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite); + + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) return false; - pool = virStoragePoolCreateXML(priv->conn, buffer, 0); + pool = virStoragePoolCreateXML(priv->conn, buffer, flags); VIR_FREE(buffer); if (pool != NULL) { @@ -386,6 +413,9 @@ static const vshCmdInfo info_pool_create_as[] = { static const vshCmdOptDef opts_pool_create_as[] = { OPTS_POOL_COMMON_X_AS + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON {.name = NULL} }; @@ -397,8 +427,25 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) const char *name; char *xml; bool printXML = vshCommandOptBool(cmd, "print-xml"); + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData; + build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite); + + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (!virshBuildPoolXML(ctl, cmd, &name, &xml)) return false; @@ -406,7 +453,7 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%s", xml); VIR_FREE(xml); } else { - pool = virStoragePoolCreateXML(priv->conn, xml, 0); + pool = virStoragePoolCreateXML(priv->conn, xml, flags); VIR_FREE(xml); if (pool != NULL) { @@ -1657,6 +1704,9 @@ static const vshCmdInfo info_pool_start[] = { static const vshCmdOptDef opts_pool_start[] = { OPT_POOL_COMMON + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON {.name = NULL} }; @@ -1667,11 +1717,28 @@ cmdPoolStart(vshControl *ctl, const vshCmd *cmd) virStoragePoolPtr pool; bool ret = true; const char *name = NULL; + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; if (!(pool = virshCommandOptPool(ctl, cmd, "pool", &name))) return false; - if (virStoragePoolCreate(pool, 0) == 0) { + build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite); + + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + + if (virStoragePoolCreate(pool, flags) == 0) { vshPrint(ctl, _("Pool %s started\n"), name); } else { vshError(ctl, _("Failed to start pool %s"), name); diff --git a/tools/virsh.pod b/tools/virsh.pod index 21ae4a3..107fc32 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -3181,15 +3181,23 @@ specified or it's been determined that the disk doesn't already have one, by the pool source format type or "dos" if not specified for the pool. =item B<pool-create> I<file> +[I<--build>] [[I<--overwrite>] | [I<--no-overwrite>]] Create and start a pool object from the XML I<file>. +[I<--build>] [[I<--overwrite>] | [I<--no-overwrite>]] perform a +B<pool-build> after creation in order to remove the need for a +follow-up command to build the pool. The I<--overwrite> and +I<--no-overwrite> flags follow the same rules as B<pool-build>. If +just I<--build> is provided, then B<pool-build> is called with no flags. + =item B<pool-create-as> I<name> I<type> [I<--print-xml>] [I<--source-host hostname>] [I<--source-path path>] [I<--source-dev path>] [I<--source-name name>] [I<--target path>] [I<--source-format format>] [I<--auth-type authtype> I<--auth-username username> I<--secret-usage usage>] [[I<--adapter-name name>] | [I<--adapter-wwnn> I<--adapter-wwpn>] [I<--adapter-parent parent>]] +[I<--build>] [[I<--overwrite>] | [I<--no-overwrite>]] Create and start a pool object I<name> from the raw parameters. If @@ -3233,6 +3241,12 @@ the wwnn and wwpn to be used for the fc_host adapter type pool. The parent optionally provides the name of the scsi_hostN node device to be used for the vHBA. +[I<--build>] [[I<--overwrite>] | [I<--no-overwrite>]] perform a +B<pool-build> after creation in order to remove the need for a +follow-up command to build the pool. The I<--overwrite> and +I<--no-overwrite> flags follow the same rules as B<pool-build>. If +just I<--build> is provided, then B<pool-build> is called with no flags. + =item B<pool-define> I<file> Define an inactive persistent storage pool or modify an existing persistent one @@ -3250,7 +3264,8 @@ I<--print-xml> is specified, then print the XML of the pool object without defining the pool. Otherwise, the pool has the specified I<type>. -Use the same arguments as B<pool-create-as>. +Use the same arguments as B<pool-create-as>, except for the I<--build>, +I<--overwrite>, and I<--no-overwrite> options. =item B<pool-destroy> I<pool-or-uuid> @@ -3326,9 +3341,17 @@ Convert the I<uuid> to a pool name. Refresh the list of volumes contained in I<pool>. =item B<pool-start> I<pool-or-uuid> +[I<--build>] [[I<--overwrite>] | [I<--no-overwrite>]] Start the storage I<pool>, which is previously defined but inactive. +[I<--build>] [[I<--overwrite>] | [I<--no-overwrite>]] perform a +B<pool-build> prior to B<pool-start> to ensure the pool environment is +in an expected state rather than needing to run the build command prior +to startup. The I<--overwrite> and I<--no-overwrite> flags follow the +same rules as B<pool-build>. If just I<--build> is provided, then +B<pool-build> is called with no flags. + B<Note>: A storage pool that relies on remote resources such as an "iscsi" or a (v)HBA backed "scsi" pool may need to be refreshed multiple times in order to have all the volumes detected (see B<pool-refresh>). -- 2.5.0

On 25.11.2015 20:11, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=830056
Utilize recently added VIR_STORAGE_POOL_CREATE_WITH_BUILD* flags in order to pass the flags along to the virStoragePoolCreateXML and virStoragePoolCreate API's.
This affects the 'virsh pool-create', 'virsh pool-create-as', and 'virsh pool-start' commands. While it could be argued that pool-start doesn't need the flags, they could prove useful for someone trying to do one command build --overwrite and start command processing or essentially starting with a clean slate.
NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see:
https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 25 ++++++++++++++++++- 2 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index cb91cd3..1bb987d 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -47,6 +47,13 @@ .help = N_("file containing an XML pool description") \ }, \
+#define OPT_BUILD_COMMON \ + {.name = "build", \ + .type = VSH_OT_BOOL, \ + .flags = 0, \ + .help = N_("build the pool as normal") \ + }, \ + #define OPT_NO_OVERWRITE_COMMON \ {.name = "no-overwrite", \ .type = VSH_OT_BOOL, \ @@ -235,6 +242,9 @@ static const vshCmdInfo info_pool_create[] = {
static const vshCmdOptDef opts_pool_create[] = { OPT_FILE_COMMON + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON
{.name = NULL} }; @@ -246,15 +256,32 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = true; char *buffer; + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData;
if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false;
+ build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite);
A-HA! I knew it! These are mutually exclusive. So please do fix 1/6.
+ + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) return false;
- pool = virStoragePoolCreateXML(priv->conn, buffer, 0); + pool = virStoragePoolCreateXML(priv->conn, buffer, flags); VIR_FREE(buffer);
if (pool != NULL) {
ACK Michal

On Wed, Nov 25, 2015 at 14:11:08 -0500, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=830056
Utilize recently added VIR_STORAGE_POOL_CREATE_WITH_BUILD* flags in order to pass the flags along to the virStoragePoolCreateXML and virStoragePoolCreate API's.
This affects the 'virsh pool-create', 'virsh pool-create-as', and 'virsh pool-start' commands. While it could be argued that pool-start doesn't need the flags, they could prove useful for someone trying to do one command build --overwrite and start command processing or essentially starting with a clean slate.
NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see:
https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 25 ++++++++++++++++++- 2 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index cb91cd3..1bb987d 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -47,6 +47,13 @@ .help = N_("file containing an XML pool description") \ }, \
+#define OPT_BUILD_COMMON \ + {.name = "build", \ + .type = VSH_OT_BOOL, \ + .flags = 0, \ + .help = N_("build the pool as normal") \ + }, \ + #define OPT_NO_OVERWRITE_COMMON \ {.name = "no-overwrite", \ .type = VSH_OT_BOOL, \ @@ -235,6 +242,9 @@ static const vshCmdInfo info_pool_create[] = {
static const vshCmdOptDef opts_pool_create[] = { OPT_FILE_COMMON + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON
These look terrible without commas between entries.
{.name = NULL} }; @@ -246,15 +256,32 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = true; char *buffer; + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData;
if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false;
+ build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite);
This should be used only if the name of the variable matches the name of the option flag since the variable name is used in the error message in place of the option flag name.
+ + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) return false;
- pool = virStoragePoolCreateXML(priv->conn, buffer, 0); + pool = virStoragePoolCreateXML(priv->conn, buffer, flags); VIR_FREE(buffer);
if (pool != NULL) { @@ -386,6 +413,9 @@ static const vshCmdInfo info_pool_create_as[] = {
static const vshCmdOptDef opts_pool_create_as[] = { OPTS_POOL_COMMON_X_AS + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON
{.name = NULL} }; @@ -397,8 +427,25 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) const char *name; char *xml; bool printXML = vshCommandOptBool(cmd, "print-xml"); + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData;
+ build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite);
See above.
+ + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (!virshBuildPoolXML(ctl, cmd, &name, &xml)) return false;
Peter

On 12/16/2015 08:42 AM, Peter Krempa wrote:
On Wed, Nov 25, 2015 at 14:11:08 -0500, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=830056
Utilize recently added VIR_STORAGE_POOL_CREATE_WITH_BUILD* flags in order to pass the flags along to the virStoragePoolCreateXML and virStoragePoolCreate API's.
This affects the 'virsh pool-create', 'virsh pool-create-as', and 'virsh pool-start' commands. While it could be argued that pool-start doesn't need the flags, they could prove useful for someone trying to do one command build --overwrite and start command processing or essentially starting with a clean slate.
NB: This patch is loosely based upon code originally authored by Osier Yang that were not reviewed and pushed, see:
https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 25 ++++++++++++++++++- 2 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index cb91cd3..1bb987d 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -47,6 +47,13 @@ .help = N_("file containing an XML pool description") \ }, \
+#define OPT_BUILD_COMMON \ + {.name = "build", \ + .type = VSH_OT_BOOL, \ + .flags = 0, \ + .help = N_("build the pool as normal") \ + }, \ + #define OPT_NO_OVERWRITE_COMMON \ {.name = "no-overwrite", \ .type = VSH_OT_BOOL, \ @@ -235,6 +242,9 @@ static const vshCmdInfo info_pool_create[] = {
static const vshCmdOptDef opts_pool_create[] = { OPT_FILE_COMMON + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON
These look terrible without commas between entries.
OK - so all fixed and the names are now: VSH_POOL_OPT_COMMON VSH_POOL_FILE_OPT_COMMON VSH_POOL_BUILD_OPT_COMMON VSH_POOL_NO_OVERWRITE_OPT_COMMON VSH_POOL_OVERWRITE_OPT_COMMON VSH_POOL_X_AS_OPT_COMMON Each would require a comma when used within an opts_pool* struct
{.name = NULL} }; @@ -246,15 +256,32 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = true; char *buffer; + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData;
if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false;
+ build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite);
This should be used only if the name of the variable matches the name of the option flag since the variable name is used in the error message in place of the option flag name.
Oh yeah - I remember reading that.. I think at one time I had used the VSH_EXCLUSIVE_OPTIONS_EXPR instead, but I cannot remember what happened to cause me to use this one. Both instances now changed to: VSH_EXCLUSIVE_OPTIONS_EXPR("overwrite", overwrite, "no-overwrite", no_overwrite); Is it preferable to see a v2 or are the edits as I've described sufficient? John
+ + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) return false;
- pool = virStoragePoolCreateXML(priv->conn, buffer, 0); + pool = virStoragePoolCreateXML(priv->conn, buffer, flags); VIR_FREE(buffer);
if (pool != NULL) { @@ -386,6 +413,9 @@ static const vshCmdInfo info_pool_create_as[] = {
static const vshCmdOptDef opts_pool_create_as[] = { OPTS_POOL_COMMON_X_AS + OPT_BUILD_COMMON + OPT_NO_OVERWRITE_COMMON + OPT_OVERWRITE_COMMON
{.name = NULL} }; @@ -397,8 +427,25 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) const char *name; char *xml; bool printXML = vshCommandOptBool(cmd, "print-xml"); + bool build; + bool overwrite; + bool no_overwrite; + unsigned int flags = 0; virshControlPtr priv = ctl->privData;
+ build = vshCommandOptBool(cmd, "build"); + overwrite = vshCommandOptBool(cmd, "overwrite"); + no_overwrite = vshCommandOptBool(cmd, "no-overwrite"); + + VSH_EXCLUSIVE_OPTIONS_VAR(overwrite, no_overwrite);
See above.
+ + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (!virshBuildPoolXML(ctl, cmd, &name, &xml)) return false;
Peter

ping? tks John On 11/25/2015 02:11 PM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=830056
Add the capability to build the pool during pool creation or startup
NOTE: If patches 2-4 regarding usage of #define for repeated command options are acceptible, I can start doing the same for other virsh commands. I just found it easier and I think better than the need to continually cut-n-paste for each command option entry. If it's preferred to keep cut-n-paste'ing, then I can modify patch 5 & 6 to follow that model.
NOTE: Based loosely on patches posted quite a while ago by Osier Yang before he left Red Hat, see:
(Cover) https://www.redhat.com/archives/libvir-list/2012-July/msg00494.html
and
(libvirt API, storage driver changes) https://www.redhat.com/archives/libvir-list/2012-July/msg01328.html
and
(virsh changes) https://www.redhat.com/archives/libvir-list/2012-July/msg00497.html
John Ferlan (6): storage: Add flags to allow building pool during create processing virsh: Create macro for "pool" option virsh: Create macro for "file" option virsh: Create macro for "overwrite" and no-overwrite" options virsh: Create a macro for pool-define-as and pool-create-as options virsh: Add build flags to pool-create[-as] and pool-start
include/libvirt/libvirt-storage.h | 16 +- src/libvirt-storage.c | 4 +- src/storage/storage_driver.c | 42 ++++- tools/virsh-pool.c | 360 ++++++++++++++++++++++---------------- tools/virsh.pod | 25 ++- 5 files changed, 288 insertions(+), 159 deletions(-)
participants (3)
-
John Ferlan
-
Michal Privoznik
-
Peter Krempa