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

Patch 1/3 is just about the indention fix. 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 (3): Fix the indentions of libvirt.h.in 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 | 109 +++++++++++++++++++++++------------------ src/libvirt.c | 4 +- src/storage/storage_driver.c | 38 ++++++++++++++- tools/virsh.c | 100 ++++++++++++++++++++++++++++++++++++-- tools/virsh.pod | 27 +++++++++- 5 files changed, 217 insertions(+), 61 deletions(-) Regards, Osier -- 1.7.7.3

Substitute 2 spaces with 4 spaces instead. --- include/libvirt/libvirt.h.in | 96 +++++++++++++++++++++--------------------- 1 files changed, 48 insertions(+), 48 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 6e8d5dd..e1c9789 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -736,11 +736,11 @@ int virDomainSetSchedulerParametersFlags (virDomainPtr domain, typedef struct _virDomainBlockStats virDomainBlockStatsStruct; struct _virDomainBlockStats { - long long rd_req; /* number of read requests */ - long long rd_bytes; /* number of read bytes */ - long long wr_req; /* number of write requests */ - long long wr_bytes; /* number of written bytes */ - long long errs; /* In Xen this returns the mysterious 'oo_req'. */ + long long rd_req; /* number of read requests */ + long long rd_bytes; /* number of read bytes */ + long long wr_req; /* number of write requests */ + long long wr_bytes; /* number of written bytes */ + long long errs; /* In Xen this returns the mysterious 'oo_req'. */ }; /** @@ -843,14 +843,14 @@ typedef virDomainBlockStatsStruct *virDomainBlockStatsPtr; typedef struct _virDomainInterfaceStats virDomainInterfaceStatsStruct; struct _virDomainInterfaceStats { - long long rx_bytes; - long long rx_packets; - long long rx_errs; - long long rx_drop; - long long tx_bytes; - long long tx_packets; - long long tx_errs; - long long tx_drop; + long long rx_bytes; + long long rx_packets; + long long rx_errs; + long long rx_drop; + long long tx_bytes; + long long tx_packets; + long long tx_errs; + long long tx_drop; }; /** @@ -1728,8 +1728,8 @@ int virDomainMemoryStats (virDomainPtr dom, /* Memory peeking flags. */ typedef enum { - VIR_MEMORY_VIRTUAL = 1 << 0, /* addresses are virtual addresses */ - VIR_MEMORY_PHYSICAL = 1 << 1, /* addresses are physical addresses */ + VIR_MEMORY_VIRTUAL = 1 << 0, /* addresses are virtual addresses */ + VIR_MEMORY_PHYSICAL = 1 << 1, /* addresses are physical addresses */ } virDomainMemoryFlags; int virDomainMemoryPeek (virDomainPtr dom, @@ -2358,17 +2358,17 @@ typedef enum { } virStoragePoolBuildFlags; typedef enum { - VIR_STORAGE_POOL_DELETE_NORMAL = 0, /* Delete metadata only (fast) */ - VIR_STORAGE_POOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ + VIR_STORAGE_POOL_DELETE_NORMAL = 0, /* Delete metadata only (fast) */ + VIR_STORAGE_POOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ } virStoragePoolDeleteFlags; typedef struct _virStoragePoolInfo virStoragePoolInfo; struct _virStoragePoolInfo { - int state; /* virStoragePoolState flags */ - unsigned long long capacity; /* Logical size bytes */ - unsigned long long allocation; /* Current allocation bytes */ - unsigned long long available; /* Remaining free space bytes */ + int state; /* virStoragePoolState flags */ + unsigned long long capacity; /* Logical size bytes */ + unsigned long long allocation; /* Current allocation bytes */ + unsigned long long available; /* Remaining free space bytes */ }; typedef virStoragePoolInfo *virStoragePoolInfoPtr; @@ -2391,10 +2391,10 @@ typedef virStorageVol *virStorageVolPtr; typedef enum { - VIR_STORAGE_VOL_FILE = 0, /* Regular file based volumes */ - VIR_STORAGE_VOL_BLOCK = 1, /* Block based volumes */ - VIR_STORAGE_VOL_DIR = 2, /* Directory-passthrough based volume */ - VIR_STORAGE_VOL_NETWORK = 3, /* Network volumes like RBD (RADOS Block Device) */ + VIR_STORAGE_VOL_FILE = 0, /* Regular file based volumes */ + VIR_STORAGE_VOL_BLOCK = 1, /* Block based volumes */ + VIR_STORAGE_VOL_DIR = 2, /* Directory-passthrough based volume */ + VIR_STORAGE_VOL_NETWORK = 3, /* Network volumes like RBD (RADOS Block Device) */ #ifdef VIR_ENUM_SENTINELS VIR_STORAGE_VOL_LAST @@ -2402,45 +2402,45 @@ typedef enum { } virStorageVolType; typedef enum { - VIR_STORAGE_VOL_DELETE_NORMAL = 0, /* Delete metadata only (fast) */ - VIR_STORAGE_VOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ + VIR_STORAGE_VOL_DELETE_NORMAL = 0, /* Delete metadata only (fast) */ + VIR_STORAGE_VOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */ } virStorageVolDeleteFlags; typedef enum { - VIR_STORAGE_VOL_WIPE_ALG_ZERO = 0, /* 1-pass, all zeroes */ - VIR_STORAGE_VOL_WIPE_ALG_NNSA = 1, /* 4-pass NNSA Policy Letter + VIR_STORAGE_VOL_WIPE_ALG_ZERO = 0, /* 1-pass, all zeroes */ + VIR_STORAGE_VOL_WIPE_ALG_NNSA = 1, /* 4-pass NNSA Policy Letter NAP-14.1-C (XVI-8) */ - VIR_STORAGE_VOL_WIPE_ALG_DOD = 2, /* 4-pass DoD 5220.22-M section + VIR_STORAGE_VOL_WIPE_ALG_DOD = 2, /* 4-pass DoD 5220.22-M section 8-306 procedure */ - VIR_STORAGE_VOL_WIPE_ALG_BSI = 3, /* 9-pass method recommended by the + VIR_STORAGE_VOL_WIPE_ALG_BSI = 3, /* 9-pass method recommended by the German Center of Security in Information Technologies */ - VIR_STORAGE_VOL_WIPE_ALG_GUTMANN = 4, /* The canonical 35-pass sequence */ - VIR_STORAGE_VOL_WIPE_ALG_SCHNEIER = 5, /* 7-pass method described by + VIR_STORAGE_VOL_WIPE_ALG_GUTMANN = 4, /* The canonical 35-pass sequence */ + VIR_STORAGE_VOL_WIPE_ALG_SCHNEIER = 5, /* 7-pass method described by Bruce Schneier in "Applied Cryptography" (1996) */ - VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7 = 6, /* 7-pass random */ + VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7 = 6, /* 7-pass random */ - VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33 = 7, /* 33-pass random */ + VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33 = 7, /* 33-pass random */ - VIR_STORAGE_VOL_WIPE_ALG_RANDOM = 8, /* 1-pass random */ + VIR_STORAGE_VOL_WIPE_ALG_RANDOM = 8, /* 1-pass random */ #ifdef VIR_ENUM_SENTINELS - /* - * NB: this enum value will increase over time as new algorithms are - * added to the libvirt API. It reflects the last algorithm supported - * by this version of the libvirt API. - */ - VIR_STORAGE_VOL_WIPE_ALG_LAST + /* + * NB: this enum value will increase over time as new algorithms are + * added to the libvirt API. It reflects the last algorithm supported + * by this version of the libvirt API. + */ + VIR_STORAGE_VOL_WIPE_ALG_LAST #endif } virStorageVolWipeAlgorithm; typedef struct _virStorageVolInfo virStorageVolInfo; struct _virStorageVolInfo { - int type; /* virStorageVolType flags */ - unsigned long long capacity; /* Logical size bytes */ - unsigned long long allocation; /* Current allocation bytes */ + int type; /* virStorageVolType flags */ + unsigned long long capacity; /* Logical size bytes */ + unsigned long long allocation; /* Current allocation bytes */ }; typedef virStorageVolInfo *virStorageVolInfoPtr; @@ -2590,9 +2590,9 @@ char * virStorageVolGetXMLDesc (virStorageVolPtr pool, char * virStorageVolGetPath (virStorageVolPtr vol); typedef enum { - VIR_STORAGE_VOL_RESIZE_ALLOCATE = 1 << 0, /* force allocation of new size */ - VIR_STORAGE_VOL_RESIZE_DELTA = 1 << 1, /* size is relative to current */ - VIR_STORAGE_VOL_RESIZE_SHRINK = 1 << 2, /* allow decrease in capacity */ + VIR_STORAGE_VOL_RESIZE_ALLOCATE = 1 << 0, /* force allocation of new size */ + VIR_STORAGE_VOL_RESIZE_DELTA = 1 << 1, /* size is relative to current */ + VIR_STORAGE_VOL_RESIZE_SHRINK = 1 << 2, /* allow decrease in capacity */ } virStorageVolResizeFlags; int virStorageVolResize (virStorageVolPtr vol, -- 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 e1c9789..3646e78 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2362,6 +2362,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 db6ba15..0cd6110 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -11595,7 +11595,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 @@ -11779,7 +11779,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 fbc630d..0835850 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 07/11/12 16:27, 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(-)
This patch does not longer apply cleanly. Could you please repost a rebased version? Thanks. Peter

On 2012年07月24日 17:53, Peter Krempa wrote:
On 07/11/12 16:27, 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(-)
This patch does not longer apply cleanly. Could you please repost a rebased version?
Sure, my fault. v2 is posted. Regards, Osier

On 2012年07月24日 17:53, Peter Krempa wrote:
On 07/11/12 16:27, 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(-)
This patch does not longer apply cleanly. Could you please repost a rebased version?
BTW. 3/3 is fine to apply.

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 fcef461..4fb7bef 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2364,6 +2364,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 8315b4f..12bb998 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -11599,7 +11599,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 @@ -11783,7 +11783,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 4ad9155..f2f8dcd 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

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.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 27 +++++++++++++-- 2 files changed, 118 insertions(+), 9 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 01e7ce0..7e4fc6f 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -10295,6 +10295,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} }; @@ -10305,6 +10309,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; @@ -10312,10 +10320,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) { @@ -10428,7 +10453,7 @@ cmdNodeDeviceDestroy(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")}, @@ -10510,6 +10535,23 @@ static const vshCmdInfo info_pool_create_as[] = { {NULL, NULL} }; +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 bool cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) { @@ -10517,6 +10559,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; @@ -10524,11 +10570,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) { @@ -11522,6 +11585,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} }; @@ -11531,6 +11598,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; @@ -11538,7 +11609,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); @@ -18259,9 +18347,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 ae00622..621a5b9 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2087,19 +2087,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>. @@ -2167,10 +2181,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

Ping.
Patch 1/3 is just about the indention fix.
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 (3): Fix the indentions of libvirt.h.in 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 | 109 +++++++++++++++++++++++------------------ src/libvirt.c | 4 +- src/storage/storage_driver.c | 38 ++++++++++++++- tools/virsh.c | 100 ++++++++++++++++++++++++++++++++++++-- tools/virsh.pod | 27 +++++++++- 5 files changed, 217 insertions(+), 61 deletions(-)
Regards, Osier

ping again. On 2012年07月24日 17:32, Osier Yang wrote:
Ping.
Patch 1/3 is just about the indention fix.
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 (3): Fix the indentions of libvirt.h.in 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 | 109 +++++++++++++++++++++++------------------ src/libvirt.c | 4 +- src/storage/storage_driver.c | 38 ++++++++++++++- tools/virsh.c | 100 ++++++++++++++++++++++++++++++++++++-- tools/virsh.pod | 27 +++++++++- 5 files changed, 217 insertions(+), 61 deletions(-)
Regards, Osier
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (2)
-
Osier Yang
-
Peter Krempa