提交 7ca81e6f 编写于 作者: L Liu Dayu 提交者: Peter Krempa

virsh: support block device storage type in virshParseSnapshotDiskspec

virsh snapshot-create-as supports 'file' storage type in --diskspec by default.
But it doesn't support 'block' storage type in the virshParseSnapshotDiskspec().
So if a snapshot on a block device (e.g. LV) was created, the type of
current running storage source in dumpxml is inconsistent with the actual
backend storage source. It will check file-system type mismatch failed
and return an error message of 'Migration without shared storage is unsafe'
when VM performs a live migration after this snapshot.

Considering virsh has to be able to work remotely that recognizing a block device
by prefix /dev/ or by stat() may be not suitable, so adding a "stype" field
for the --diskspec string which will be either "file" or "block".
e.g. --diskspec vda,snapshot=external,driver=qcow2,stype=block,file=/dev/xxx.
Signed-off-by: NLiu Dayu <liu.dayu@zte.com.cn>
Signed-off-by: NPeter Krempa <pkrempa@redhat.com>
上级 dd94cc2e
...@@ -251,10 +251,12 @@ virshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str) ...@@ -251,10 +251,12 @@ virshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str)
const char *name = NULL; const char *name = NULL;
const char *snapshot = NULL; const char *snapshot = NULL;
const char *driver = NULL; const char *driver = NULL;
const char *stype = NULL;
const char *file = NULL; const char *file = NULL;
char **array = NULL; char **array = NULL;
int narray; int narray;
size_t i; size_t i;
bool isFile = true;
narray = vshStringToArray(str, &array); narray = vshStringToArray(str, &array);
if (narray <= 0) if (narray <= 0)
...@@ -266,6 +268,8 @@ virshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str) ...@@ -266,6 +268,8 @@ virshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str)
snapshot = array[i] + strlen("snapshot="); snapshot = array[i] + strlen("snapshot=");
else if (!driver && STRPREFIX(array[i], "driver=")) else if (!driver && STRPREFIX(array[i], "driver="))
driver = array[i] + strlen("driver="); driver = array[i] + strlen("driver=");
else if (!stype && STRPREFIX(array[i], "stype="))
stype = array[i] + strlen("stype=");
else if (!file && STRPREFIX(array[i], "file=")) else if (!file && STRPREFIX(array[i], "file="))
file = array[i] + strlen("file="); file = array[i] + strlen("file=");
else else
...@@ -275,13 +279,26 @@ virshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str) ...@@ -275,13 +279,26 @@ virshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str)
virBufferEscapeString(buf, "<disk name='%s'", name); virBufferEscapeString(buf, "<disk name='%s'", name);
if (snapshot) if (snapshot)
virBufferAsprintf(buf, " snapshot='%s'", snapshot); virBufferAsprintf(buf, " snapshot='%s'", snapshot);
if (stype) {
if (STREQ(stype, "block")) {
isFile = false;
} else if (STRNEQ(stype, "file")) {
vshError(ctl, _("Unknown storage type: '%s'"), stype);
goto cleanup;
}
virBufferAsprintf(buf, " type='%s'", stype);
}
if (driver || file) { if (driver || file) {
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
if (driver) if (driver)
virBufferAsprintf(buf, "<driver type='%s'/>\n", driver); virBufferAsprintf(buf, "<driver type='%s'/>\n", driver);
if (file) if (file) {
virBufferEscapeString(buf, "<source file='%s'/>\n", file); if (isFile)
virBufferEscapeString(buf, "<source file='%s'/>\n", file);
else
virBufferEscapeString(buf, "<source dev='%s'/>\n", file);
}
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</disk>\n"); virBufferAddLit(buf, "</disk>\n");
} else { } else {
...@@ -351,7 +368,7 @@ static const vshCmdOptDef opts_snapshot_create_as[] = { ...@@ -351,7 +368,7 @@ static const vshCmdOptDef opts_snapshot_create_as[] = {
}, },
{.name = "diskspec", {.name = "diskspec",
.type = VSH_OT_ARGV, .type = VSH_OT_ARGV,
.help = N_("disk attributes: disk[,snapshot=type][,driver=type][,file=name]") .help = N_("disk attributes: disk[,snapshot=type][,driver=type][,stype=type][,file=name]")
}, },
{.name = NULL} {.name = NULL}
}; };
......
...@@ -4676,11 +4676,14 @@ The I<--diskspec> option can be used to control how I<--disk-only> and ...@@ -4676,11 +4676,14 @@ The I<--diskspec> option can be used to control how I<--disk-only> and
external full system snapshots create external files. This option can occur external full system snapshots create external files. This option can occur
multiple times, according to the number of <disk> elements in the domain multiple times, according to the number of <disk> elements in the domain
xml. Each <diskspec> is in the xml. Each <diskspec> is in the
form B<disk[,snapshot=type][,driver=type][,file=name]>. A I<diskspec> form B<disk[,snapshot=type][,driver=type][,stype=type][,file=name]>.
must be provided for disks backed by block devices as libvirt doesn't A I<diskspec> must be provided for disks backed by block devices as libvirt
auto-generate file names for those. To include a doesn't auto-generate file names for those. The optional B<stype> parameter
literal comma in B<disk> or in B<file=name>, escape it with a second allows to control the type of the source file. Supported values are 'file'
comma. A literal I<--diskspec> must precede each B<diskspec> unless (default) and 'block'.
To include a literal comma in B<disk> or in B<file=name>, escape it with a
second comma. A literal I<--diskspec> must precede each B<diskspec> unless
all three of I<domain>, I<name>, and I<description> are also present. all three of I<domain>, I<name>, and I<description> are also present.
For example, a diskspec of "vda,snapshot=external,file=/path/to,,new" For example, a diskspec of "vda,snapshot=external,file=/path/to,,new"
results in the following XML: results in the following XML:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册