[libvirt] [PATCH 0/2 v3] Storage: Allow pool building while creating it

v2 - v3: * Just rebase on the top. We tries to start the pool while creating a transicient pool, if the pool target is not existed yet, we must fail on starting, and thus we see many users raise up the problem on either list or bugzilla. Patch 2/3 and 3/3 are to fix the problem by introducing flags to allow the pool building for APIs virStoragePoolCreate and virStoragePoolCreateXML, and expose the flags to commands pool-create/pool-create-as/pool-start. Osier Yang (2): storage: New flags to allow building the pool while creating it virsh: New options for the 3 pool commands to allow pool building include/libvirt/libvirt.h.in | 13 +++++ src/libvirt.c | 4 +- src/storage/storage_driver.c | 38 +++++++++++++++- tools/virsh-pool.c | 100 +++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 27 ++++++++++- 5 files changed, 169 insertions(+), 13 deletions(-) -- 1.7.7.3

We see the requirement for allowing to build the pool while pool-create /pool-create-as/pool-start often in either upstream list or bugzilla, so this patch introduces the flags virStoragePoolCreateFlags for both virStoragePoolCreate and virStoragePoolCreateXML. VIR_STORAGE_POOL_CREATE_WITH_BUILD allows to build the pool as normal (for a filesystem pool, means only making the directory), VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE allows to build the pool with overwriting the existed pool data. Oppositely, VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE doesn't allow to overwrite anything. --- include/libvirt/libvirt.h.in | 13 +++++++++++++ src/libvirt.c | 4 ++-- src/storage/storage_driver.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index d21d029..c5d7326 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2415,6 +2415,19 @@ 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 with regular building */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD = 1 << 0, + + /* Create the pool with building, overwrite the existing pool data */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE = 1 << 1, + + /* Create the pool with building, don't overwrite the existing pool data */ + VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE = 1 << 2, +} virStoragePoolCreateFlags; + typedef struct _virStoragePoolInfo virStoragePoolInfo; struct _virStoragePoolInfo { diff --git a/src/libvirt.c b/src/libvirt.c index 893d380..81c4c48 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -11602,7 +11602,7 @@ error: * 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 @@ -11786,7 +11786,7 @@ error: /** * 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 3dc66db..3d30db9 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -518,8 +518,11 @@ storagePoolCreate(virConnectPtr conn, virStoragePoolObjPtr pool = NULL; virStoragePoolPtr ret = NULL; virStorageBackendPtr backend; + 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(driver); if (!(def = virStoragePoolDefParseString(xml))) @@ -538,6 +541,21 @@ storagePoolCreate(virConnectPtr conn, goto cleanup; def = NULL; + if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD) + build_flags |= VIR_STORAGE_POOL_BUILD_NEW; + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + 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); @@ -670,8 +688,11 @@ storagePoolStart(virStoragePoolPtr obj, virStoragePoolObjPtr pool; virStorageBackendPtr backend; int ret = -1; + unsigned int start_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, -1); storageDriverLock(driver); pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); @@ -691,6 +712,19 @@ storagePoolStart(virStoragePoolPtr obj, "%s", _("pool already active")); goto cleanup; } + + if (backend->buildPool) { + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD) + start_flags |= VIR_STORAGE_POOL_BUILD_NEW; + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + start_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) + start_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + + if (backend->buildPool(obj->conn, pool, start_flags) < 0) + goto cleanup; + } + if (backend->startPool && backend->startPool(obj->conn, pool) < 0) goto cleanup; -- 1.7.7.3

On 08/17/2012 08:58 AM, Osier Yang wrote:
We see the requirement for allowing to build the pool while pool-create /pool-create-as/pool-start often in either upstream list or bugzilla, so this patch introduces the flags virStoragePoolCreateFlags for both virStoragePoolCreate and virStoragePoolCreateXML.
VIR_STORAGE_POOL_CREATE_WITH_BUILD allows to build the pool as normal (for a filesystem pool, means only making the directory), VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE allows to build the pool with overwriting the existed pool data. Oppositely, VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE doesn't allow to overwrite anything. --- include/libvirt/libvirt.h.in | 13 +++++++++++++ src/libvirt.c | 4 ++-- src/storage/storage_driver.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 4 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

New options --build, --build-overwrite, and --build-no-overwrite are added to commands pool-create/pool-create-as/pool-start. Perhaps it's not that necessary to allow pool building for pool-start, but it doesn't hurt to have them. --- The documents of pool-build is not that correct, as the flags --overwrite and --no-overwrite are also supported by disk backend, but it will be a follow up patch, with fixing the documents for the new options together. --- tools/virsh-pool.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 27 ++++++++++++-- 2 files changed, 118 insertions(+), 9 deletions(-) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index af80427..ad6aef6 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -124,6 +124,10 @@ static const vshCmdInfo info_pool_create[] = { static const vshCmdOptDef opts_pool_create[] = { {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("file containing an XML pool description")}, + {"build", VSH_OT_BOOL, 0, N_("build the pool as normal")}, + {"build-overwrite", VSH_OT_BOOL, 0, N_("build the pool without overwriting the " + "existed pool data")}, + {"build-no-overwrite", VSH_OT_BOOL, 0, N_("build the pool with overwriting anything")}, {NULL, 0, 0, NULL} }; @@ -134,6 +138,10 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = true; char *buffer; + bool build; + bool build_overwrite; + bool build_no_overwrite; + unsigned int flags = 0; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -141,10 +149,27 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptString(cmd, "file", &from) <= 0) return false; + build = vshCommandOptBool(cmd, "build"); + build_overwrite = vshCommandOptBool(cmd, "build-overwrite"); + build_no_overwrite = vshCommandOptBool(cmd, "build-no-overwrite"); + + if (build + build_overwrite + build_no_overwrite > 1) { + vshError(ctl, _("build, build-overwrite, and build-no-overwrite must " + "be sepcified exclusively")); + return false; + } + + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (build_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (build_no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - pool = virStoragePoolCreateXML(ctl->conn, buffer, 0); + pool = virStoragePoolCreateXML(ctl->conn, buffer, flags); VIR_FREE(buffer); if (pool != NULL) { @@ -161,7 +186,7 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) /* * XML Building helper for pool-define-as and pool-create-as */ -static const vshCmdOptDef opts_pool_X_as[] = { +static const vshCmdOptDef opts_pool_define_as[] = { {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name of the pool")}, {"print-xml", VSH_OT_BOOL, 0, N_("print XML document, but don't define/create")}, {"type", VSH_OT_DATA, VSH_OFLAG_REQ, N_("type of the pool")}, @@ -237,6 +262,23 @@ cleanup: /* * "pool-create-as" command */ +static const vshCmdOptDef opts_pool_create_as[] = { + {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name of the pool")}, + {"print-xml", VSH_OT_BOOL, 0, N_("print XML document, but don't define/create")}, + {"type", VSH_OT_DATA, VSH_OFLAG_REQ, N_("type of the pool")}, + {"source-host", VSH_OT_DATA, 0, N_("source-host for underlying storage")}, + {"source-path", VSH_OT_DATA, 0, N_("source path for underlying storage")}, + {"source-dev", VSH_OT_DATA, 0, N_("source device for underlying storage")}, + {"source-name", VSH_OT_DATA, 0, N_("source name for underlying storage")}, + {"target", VSH_OT_DATA, 0, N_("target for underlying storage")}, + {"source-format", VSH_OT_STRING, 0, N_("format for underlying storage")}, + {"build", VSH_OT_BOOL, 0, N_("build the pool as normal")}, + {"build-overwrite", VSH_OT_BOOL, 0, N_("build the pool without overwriting " + "the existed pool data")}, + {"build-no-overwrite", VSH_OT_BOOL, 0, N_("build the pool with overwriting anything")}, + {NULL, 0, 0, NULL} +}; + static const vshCmdInfo info_pool_create_as[] = { {"help", N_("create a pool from a set of args")}, {"desc", N_("Create a pool.")}, @@ -250,6 +292,10 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) const char *name; char *xml; bool printXML = vshCommandOptBool(cmd, "print-xml"); + bool build; + bool build_overwrite; + bool build_no_overwrite; + unsigned int flags = 0; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -257,11 +303,28 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) if (!buildPoolXML(cmd, &name, &xml)) return false; + build = vshCommandOptBool(cmd, "build"); + build_overwrite = vshCommandOptBool(cmd, "build-overwrite"); + build_no_overwrite = vshCommandOptBool(cmd, "build-no-overwrite"); + + if (build + build_overwrite + build_no_overwrite > 1) { + vshError(ctl, _("build, build-overwrite, and build-no-overwrite must " + "be sepcified exclusively")); + return false; + } + + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (build_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (build_no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + if (printXML) { vshPrint(ctl, "%s", xml); VIR_FREE(xml); } else { - pool = virStoragePoolCreateXML(ctl->conn, xml, 0); + pool = virStoragePoolCreateXML(ctl->conn, xml, flags); VIR_FREE(xml); if (pool != NULL) { @@ -1244,6 +1307,10 @@ static const vshCmdInfo info_pool_start[] = { static const vshCmdOptDef opts_pool_start[] = { {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name or uuid of the inactive pool")}, + {"build", VSH_OT_BOOL, 0, N_("build the pool as normal")}, + {"build-overwrite", VSH_OT_BOOL, 0, N_("build the pool without overwriting the " + "existed pool data")}, + {"build-no-overwrite", VSH_OT_BOOL, 0, N_("build the pool with overwriting anything")}, {NULL, 0, 0, NULL} }; @@ -1253,6 +1320,10 @@ cmdPoolStart(vshControl *ctl, const vshCmd *cmd) virStoragePoolPtr pool; bool ret = true; const char *name = NULL; + bool build; + bool build_overwrite; + bool build_no_overwrite; + unsigned int flags = 0; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -1260,7 +1331,24 @@ cmdPoolStart(vshControl *ctl, const vshCmd *cmd) if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) return false; - if (virStoragePoolCreate(pool, 0) == 0) { + build = vshCommandOptBool(cmd, "build"); + build_overwrite = vshCommandOptBool(cmd, "build-overwrite"); + build_no_overwrite = vshCommandOptBool(cmd, "build-no-overwrite"); + + if (build + build_overwrite + build_no_overwrite > 1) { + vshError(ctl, _("build, build-overwrite, and build-no-overwrite must " + "be sepcified exclusively")); + return false; + } + + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (build_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (build_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); @@ -1421,9 +1509,9 @@ static const vshCmdDef storagePoolCmds[] = { {"pool-autostart", cmdPoolAutostart, opts_pool_autostart, info_pool_autostart, 0}, {"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build, 0}, - {"pool-create-as", cmdPoolCreateAs, opts_pool_X_as, info_pool_create_as, 0}, + {"pool-create-as", cmdPoolCreateAs, opts_pool_create_as, info_pool_create_as, 0}, {"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create, 0}, - {"pool-define-as", cmdPoolDefineAs, opts_pool_X_as, info_pool_define_as, 0}, + {"pool-define-as", cmdPoolDefineAs, opts_pool_define_as, info_pool_define_as, 0}, {"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define, 0}, {"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete, 0}, {"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index 35613c4..bcc944a 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2097,19 +2097,33 @@ if exists, or using mkfs to format the target device if not; If I<--overwrite> is specified, mkfs is always executed, any existed data on the target device is overwritten unconditionally. -=item B<pool-create> I<file> +=item B<pool-create> I<file> [[I<--build>] | [I<--build-overwrite>] | +[I<--build-no-overwrite>]] Create and start a pool object from the XML I<file>. +Options I<--build>, I<--build-overwrite>, and I<--build-no-overwrite> +can be used for a filesystem pool to build the pool before starting it. +If I<--build> is specified, it only makes the directory on the filesystem +pool. I<--build-overwrite> and I<--build-no-overwrite> has the same +meaning as I<--overwrite> and I<--no-overwrite> for B<pool-build>. + =item B<pool-create-as> I<name> I<--print-xml> I<type> [I<source-host>] [I<source-path>] [I<source-dev>] [I<source-name>] [<target>] -[I<--source-format format>] +[I<--source-format format>] [[I<--build>] | [I<--build-overwrite>] | +[I<--build-no-overwrite>]] Create and start a pool object I<name> from the raw parameters. If I<--print-xml> is specified, then print the XML of the pool object without creating the pool. Otherwise, the pool has the specified I<type>. +Options I<--build>, I<--build-overwrite>, and I<--build-no-overwrite> +can be used for a filesystem pool to build the pool before starting it. +If I<--build> is specified, it only makes the directory on the filesystem +pool. I<--build-overwrite> and I<--build-no-overwrite> has the same +meaning as I<--overwrite> and I<--no-overwrite> for B<pool-build>. + =item B<pool-define> I<file> Create, but do not start, a pool object from the XML I<file>. @@ -2177,10 +2191,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> +=item B<pool-start> I<pool-or-uuid> [[I<--build>] | [I<--build-overwrite>] | +[I<--build-no-overwrite>]] Start the storage I<pool>, which is previously defined but inactive. +Options I<--build>, I<--build-overwrite>, and I<--build-no-overwrite> +can be used for a filesystem pool to build the pool before starting it. +If I<--build> is specified, it only makes the directory on the filesystem +pool. I<--build-overwrite> and I<--build-no-overwrite> has the same +meaning as I<--overwrite> and I<--no-overwrite> for B<pool-build>. + =item B<pool-undefine> I<pool-or-uuid> Undefine the configuration for an inactive I<pool>. -- 1.7.7.3

On 08/17/2012 08:58 AM, Osier Yang wrote:
New options --build, --build-overwrite, and --build-no-overwrite are added to commands pool-create/pool-create-as/pool-start. Perhaps it's not that necessary to allow pool building for pool-start, but it doesn't hurt to have them.
+++ b/tools/virsh-pool.c @@ -124,6 +124,10 @@ static const vshCmdInfo info_pool_create[] = { static const vshCmdOptDef opts_pool_create[] = { {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("file containing an XML pool description")}, + {"build", VSH_OT_BOOL, 0, N_("build the pool as normal")}, + {"build-overwrite", VSH_OT_BOOL, 0, N_("build the pool without overwriting the " + "existed pool data")},
s/existed/existing/
+ {"build-no-overwrite", VSH_OT_BOOL, 0, N_("build the pool with overwriting anything")},
Aren't those two descriptions backwards?
+ if (build + build_overwrite + build_no_overwrite > 1) { + vshError(ctl, _("build, build-overwrite, and build-no-overwrite must " + "be sepcified exclusively"));
s/sepcified/specified/ If they are mutually exclusive, it might be better to enforce that exclusivity at the src/libvirt.c layer (all callers benefit from the check) rather than at the virsh.c layer. If they are not mutually exclusive in the background, then virsh is filtering out a useful combination.
- pool = virStoragePoolCreateXML(ctl->conn, buffer, 0); + pool = virStoragePoolCreateXML(ctl->conn, buffer, flags); VIR_FREE(buffer);
I think you need fallback code - if this API fails because of unknown flags, you should try again with flags==0 then follow up with your own separate call to virStoragePoolBuild with appropriate flags.
+ {"build", VSH_OT_BOOL, 0, N_("build the pool as normal")}, + {"build-overwrite", VSH_OT_BOOL, 0, N_("build the pool without overwriting " + "the existed pool data")}, + {"build-no-overwrite", VSH_OT_BOOL, 0, N_("build the pool with overwriting anything")},
Same problems as before.
@@ -257,11 +303,28 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) if (!buildPoolXML(cmd, &name, &xml)) return false;
+ build = vshCommandOptBool(cmd, "build"); + build_overwrite = vshCommandOptBool(cmd, "build-overwrite"); + build_no_overwrite = vshCommandOptBool(cmd, "build-no-overwrite"); + + if (build + build_overwrite + build_no_overwrite > 1) { + vshError(ctl, _("build, build-overwrite, and build-no-overwrite must " + "be sepcified exclusively")); + return false; + }
Same question about where the mutual exclusive check should live.
@@ -1244,6 +1307,10 @@ static const vshCmdInfo info_pool_start[] = {
static const vshCmdOptDef opts_pool_start[] = { {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name or uuid of the inactive pool")}, + {"build", VSH_OT_BOOL, 0, N_("build the pool as normal")}, + {"build-overwrite", VSH_OT_BOOL, 0, N_("build the pool without overwriting the " + "existed pool data")}, + {"build-no-overwrite", VSH_OT_BOOL, 0, N_("build the pool with overwriting anything")},
And again.
@@ -1260,7 +1331,24 @@ cmdPoolStart(vshControl *ctl, const vshCmd *cmd) if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) return false;
- if (virStoragePoolCreate(pool, 0) == 0) { + build = vshCommandOptBool(cmd, "build"); + build_overwrite = vshCommandOptBool(cmd, "build-overwrite"); + build_no_overwrite = vshCommandOptBool(cmd, "build-no-overwrite"); + + if (build + build_overwrite + build_no_overwrite > 1) { + vshError(ctl, _("build, build-overwrite, and build-no-overwrite must " + "be sepcified exclusively")); + return false; + }
And again.
+ + if (build) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD; + if (build_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE; + if (build_no_overwrite) + flags |= VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE; + + if (virStoragePoolCreate(pool, flags) == 0) {
Same question about providing fallback code if flags wasn't recognized.
+++ b/tools/virsh.pod @@ -2097,19 +2097,33 @@ if exists, or using mkfs to format the target device if not; If I<--overwrite> is specified, mkfs is always executed, any existed data on the target device is overwritten unconditionally.
-=item B<pool-create> I<file> +=item B<pool-create> I<file> [[I<--build>] | [I<--build-overwrite>] | +[I<--build-no-overwrite>]]
A bit of bike-shedding - would the virsh interface be better as: --build={normal,overwrite,no-overwrite} that is, --build takes a string argument, which has to be one of the three known modes, rather than having three bool arguments that we don't allow to be used at the same time? But it's not worth the redesign, I can live with the approach you've coded. I do think it's worth a v4 before pushing this patch, though. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Osier Yang