qemu: Support mountpoints option of guest-fsfreeze-freeze

With this patch, virDomainFSFreeze will pass the mountpoints argument
to qemu guest agent. For example,

  virDomainFSFreeze(dom, {"/mnt/vol1", "/mnt/vol2"}, 2, 0)

will issue qemu guest agent command:

  {"execute":"guest-fsfreeze-freeze",
   "arguments":{"mountpoints":["/mnt/vol1","/mnt/vol2"]}}

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com>
Acked-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Tomoki Sekiyama 2014-05-01 20:06:19 -04:00 committed by Eric Blake
parent 061c6347e4
commit 2bb520c802
4 changed files with 56 additions and 18 deletions

View File

@ -1235,6 +1235,32 @@ qemuAgentMakeCommand(const char *cmdname,
return NULL;
}
static virJSONValuePtr
qemuAgentMakeStringsArray(const char **strings, unsigned int len)
{
size_t i;
virJSONValuePtr ret = virJSONValueNewArray(), str;
if (!ret)
return NULL;
for (i = 0; i < len; i++) {
str = virJSONValueNewString(strings[i]);
if (!str)
goto error;
if (virJSONValueArrayAppend(ret, str) < 0) {
virJSONValueFree(str);
goto error;
}
}
return ret;
error:
virJSONValueFree(ret);
return NULL;
}
void qemuAgentNotifyEvent(qemuAgentPtr mon,
qemuAgentEvent event)
{
@ -1287,21 +1313,34 @@ int qemuAgentShutdown(qemuAgentPtr mon,
/*
* qemuAgentFSFreeze:
* @mon: Agent
* @mountpoints: Array of mountpoint paths to be frozen, or NULL for all
* @nmountpoints: Number of mountpoints to be frozen, or 0 for all
*
* Issue guest-fsfreeze-freeze command to guest agent,
* which freezes all mounted file systems and returns
* which freezes file systems mounted on specified mountpoints
* (or all file systems when @mountpoints is NULL), and returns
* number of frozen file systems on success.
*
* Returns: number of file system frozen on success,
* -1 on error.
*/
int qemuAgentFSFreeze(qemuAgentPtr mon)
int qemuAgentFSFreeze(qemuAgentPtr mon, const char **mountpoints,
unsigned int nmountpoints)
{
int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr cmd, arg;
virJSONValuePtr reply = NULL;
cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", NULL);
if (mountpoints && nmountpoints) {
arg = qemuAgentMakeStringsArray(mountpoints, nmountpoints);
if (!arg)
return -1;
cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze",
"a:mountpoints", arg, NULL);
} else {
cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", NULL);
}
if (!cmd)
return -1;

View File

@ -70,7 +70,8 @@ typedef enum {
int qemuAgentShutdown(qemuAgentPtr mon,
qemuAgentShutdownMode mode);
int qemuAgentFSFreeze(qemuAgentPtr mon);
int qemuAgentFSFreeze(qemuAgentPtr mon,
const char **mountpoints, unsigned int nmountpoints);
int qemuAgentFSThaw(qemuAgentPtr mon);
int qemuAgentSuspend(qemuAgentPtr mon,

View File

@ -12087,7 +12087,9 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
* returned, FSThaw should be called revert the quiesced status. */
static int
qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver,
virDomainObjPtr vm)
virDomainObjPtr vm,
const char **mountpoints,
unsigned int nmountpoints)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
virQEMUDriverConfigPtr cfg;
@ -12113,7 +12115,7 @@ qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver,
virObjectUnref(cfg);
qemuDomainObjEnterAgent(vm);
frozen = qemuAgentFSFreeze(priv->agent);
frozen = qemuAgentFSFreeze(priv->agent, mountpoints, nmountpoints);
qemuDomainObjExitAgent(vm);
return frozen < 0 ? -2 : frozen;
}
@ -13160,7 +13162,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
* The command will fail if the guest is paused or the guest agent
* is not running, or is already quiesced. */
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) {
int freeze = qemuDomainSnapshotFSFreeze(driver, vm);
int freeze = qemuDomainSnapshotFSFreeze(driver, vm, NULL, 0);
if (freeze < 0) {
/* the helper reported the error */
if (freeze == -2)
@ -16561,12 +16563,6 @@ qemuDomainFSFreeze(virDomainPtr dom,
virCheckFlags(0, -1);
if (mountpoints || nmountpoints) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("specifying mountpoints is not supported"));
return ret;
}
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
@ -16582,7 +16578,7 @@ qemuDomainFSFreeze(virDomainPtr dom,
goto endjob;
}
ret = qemuDomainSnapshotFSFreeze(driver, vm);
ret = qemuDomainSnapshotFSFreeze(driver, vm, mountpoints, nmountpoints);
if (ret == -2) {
qemuDomainSnapshotFSThaw(driver, vm, false);
ret = -1;

View File

@ -36,6 +36,7 @@ testQemuAgentFSFreeze(const void *data)
{
virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
const char *mountpoints[] = {"/fs1", "/fs2", "/fs3", "/fs4", "/fs5"};
int ret = -1;
if (!test)
@ -55,7 +56,8 @@ testQemuAgentFSFreeze(const void *data)
"{ \"return\" : 7 }") < 0)
goto cleanup;
if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test))) < 0)
if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test),
mountpoints, 5)) < 0)
goto cleanup;
if (ret != 5) {
@ -64,7 +66,7 @@ testQemuAgentFSFreeze(const void *data)
goto cleanup;
}
if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test))) < 0)
if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0)) < 0)
goto cleanup;
if (ret != 7) {
@ -547,7 +549,7 @@ testQemuAgentTimeout(const void *data)
NULL, NULL) < 0)
goto cleanup;
if (qemuAgentFSFreeze(qemuMonitorTestGetAgent(test)) != -1) {
if (qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0) != -1) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
"agent command should have failed");
goto cleanup;