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)
{
/*
* 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;
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,
* 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;
virObjectUnref(cfg);
qemuDomainObjEnterAgent(vm);
- frozen = qemuAgentFSFreeze(priv->agent);
+ frozen = qemuAgentFSFreeze(priv->agent, mountpoints, nmountpoints);
qemuDomainObjExitAgent(vm);
return frozen < 0 ? -2 : frozen;
}
* 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)
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;
goto endjob;
}
- ret = qemuDomainSnapshotFSFreeze(driver, vm);
+ ret = qemuDomainSnapshotFSFreeze(driver, vm, mountpoints, nmountpoints);
if (ret == -2) {
qemuDomainSnapshotFSThaw(driver, vm, false);
ret = -1;
{
virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
+ const char *mountpoints[] = {"/fs1", "/fs2", "/fs3", "/fs4", "/fs5"};
int ret = -1;
if (!test)
"{ \"return\" : 7 }") < 0)
goto cleanup;
- if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test))) < 0)
+ if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test),
+ mountpoints, 5)) < 0)
goto cleanup;
if (ret != 5) {
goto cleanup;
}
- if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test))) < 0)
+ if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0)) < 0)
goto cleanup;
if (ret != 7) {
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;