---
tools/virsh.c | 52
+++++++++++++++++++++++++++++++++++++++++++++++++++-
tools/virsh.pod | 7 ++++++-
2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 1279f41..3ba549b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -5274,6 +5274,8 @@ static const vshCmdOptDef opts_vol_create_as[] = {
{"capacity", VSH_OT_DATA, VSH_OFLAG_REQ, N_("size of the vol with
optional k,M,G,T suffix")},
{"allocation", VSH_OT_STRING, 0, N_("initial allocation size with
optional k,M,G,T suffix")},
{"format", VSH_OT_STRING, 0, N_("file format type
raw,bochs,qcow,qcow2,vmdk")},
+ {"snapshot-source-vol", VSH_OT_STRING, 0, N_("the source volume if
taking a snapshot")},
+ {"snapshot-source-format", VSH_OT_STRING, 0, N_("format of the
source volume if taking a snapshot")},
{NULL, 0, 0, NULL}
};
@@ -5313,6 +5315,7 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd)
int found;
char *xml;
char *name, *capacityStr, *allocationStr, *format;
+ char *snapshotStrVol, *snapshotStrFormat;
unsigned long long capacity, allocation = 0;
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -5339,6 +5342,8 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd)
vshError(ctl, _("Malformed size %s"), allocationStr);
format = vshCommandOptString(cmd, "format", &found);
+ snapshotStrVol = vshCommandOptString(cmd, "snapshot-source-vol",
&found);
+ snapshotStrFormat = vshCommandOptString(cmd,
"snapshot-source-format", &found);
virBufferAddLit(&buf, "<volume>\n");
virBufferVSprintf(&buf, " <name>%s</name>\n", name);
@@ -5351,8 +5356,53 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd)
virBufferVSprintf(&buf, " <format
type='%s'/>\n",format);
virBufferAddLit(&buf, " </target>\n");
}
- virBufferAddLit(&buf, "</volume>\n");
+ // Convert the snapshot parameters into backingStore XML
+ if (snapshotStrVol) {
+ // Use the name of the snapshot source volume to retrieve its
device path
+ vshDebug(ctl, 5, "%s: Looking up backing store volume '%s' as
name\n", cmd->def->name, snapshotStrVol);
+ virStorageVolPtr snapVol = virStorageVolLookupByName(pool,
snapshotStrVol);
+ if (snapVol)
+ vshDebug(ctl, 5, "%s: Backing store volume found using
'%s' as name\n", cmd->def->name, snapshotStrVol);
+
+ if (snapVol == NULL) {
+ // Snapshot source volume was not found by name. Try using
the snapshot-source-vol parameter as a key
+ vshDebug(ctl, 5, "%s: Looking up backing store volume '%s'
as key\n", cmd->def->name, snapshotStrVol);
+ snapVol = virStorageVolLookupByKey(ctl->conn, snapshotStrVol);
+ if (snapVol)
+ vshDebug(ctl, 5, "%s: Backing store volume found using
'%s' as key\n", cmd->def->name, snapshotStrVol);
+ }
+ if (snapVol == NULL) {
+ // Snapshot source volume was not found by key either. Try
using the snapshot-source-vol parameter as a path
+ vshDebug(ctl, 5, "%s: Looking up backing store volume '%s'
by path\n", cmd->def->name, snapshotStrVol);
+ snapVol = virStorageVolLookupByPath(ctl->conn, snapshotStrVol);
+ if (snapVol)
+ vshDebug(ctl, 5, "%s: Backing store volume found using
'%s' as path\n", cmd->def->name, snapshotStrVol);
+ }
+ if (snapVol == NULL) {
+ vshError(ctl, _("failed to get vol '%s'"),
snapshotStrVol);
+ return FALSE;
+ }
+
+ char *snapshotStrVolPath;
+ if ((snapshotStrVolPath = virStorageVolGetPath(snapVol)) == NULL) {
+ virStorageVolFree(snapVol);
+ return FALSE;
+ }
+
+ // Create the XML for the backing store
+ virBufferAddLit(&buf, " <backingStore>\n");
+ virBufferVSprintf(&buf, "
<path>%s</path>\n",snapshotStrVolPath);
+ if (snapshotStrFormat)
+ virBufferVSprintf(&buf, " <format
type='%s'/>\n",snapshotStrFormat);
+ virBufferAddLit(&buf, " </backingStore>\n");
+
+ // Cleanup snapshot allocations
+ VIR_FREE(snapshotStrVolPath);
+ virStorageVolFree(snapVol);
+ }
+
+ virBufferAddLit(&buf, "</volume>\n");
if (virBufferError(&buf)) {
vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
diff --git a/tools/virsh.pod b/tools/virsh.pod
index cab931c..b1a8544 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -782,7 +782,8 @@ source volume is in.
I<vol-name-or-key> is the name or UUID of the source volume.
=item B<vol-create-as> I<pool-or-uuid> I<name> I<capacity>
optional
-I<--allocation> I<size> I<--format> I<string>
+I<--allocation> I<size> I<--format> I<string>
I<--snapshot-source-vol>
I<vol-name-or-key>
+I<--snapshot-source-format> I<string>
Create a volume from a set of arguments.
I<pool-or-uuid> is the name or UUID of the storage pool to create the
volume
@@ -794,6 +795,10 @@ I<--allocation> I<size> is the initial size to be
allocated in the volume, with
optional k, M, G, or T suffix.
I<--format> I<string> is used in file based storage pools to specify
the volume
file format to use; raw, bochs, qcow, qcow2, vmdk.
+I<--snapshot-source-vol> I<vol-name-or-key> is the source backing
volume to be used if
+taking a snapshot of an existing volume.
+I<--snapshot-source-format> I<string> is the format of the snapshot
backing volume;
+raw, bochs, qcow, qcow2, vmdk.
=item B<vol-clone> [optional I<--pool> I<pool-or-uuid>]
I<vol-name-or-key> I<name>
-- 1.7.0.1