Signed-off-by: Claudio Fontana <cfontana(a)suse.de>
---
docs/manpages/virsh.rst | 23 ++++++++++++++-----
tools/virsh-domain.c | 49 +++++++++++++++++++++++++++++++++--------
2 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index e73e590754..e9012b85d1 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -3803,15 +3803,18 @@ save
::
save domain state-file [--bypass-cache] [--xml file]
+ [--parallel] [--parallel-connections connections]
[{--running | --paused}] [--verbose]
-Saves a running domain (RAM, but not disk state) to a state file so that
-it can be restored
-later. Once saved, the domain will no longer be running on the
-system, thus the memory allocated for the domain will be free for
-other domains to use. ``virsh restore`` restores from this state file.
+Saves a paused or running domain (RAM, but not disk state) to one or more
+state files, so that it can be restored later.
+Once saved, the domain will no longer be running on the system,
+thus the memory allocated for the domain will be free for
+other domains to use. ``virsh restore`` restores from state file/s.
+
If *--bypass-cache* is specified, the save will avoid the file system
-cache, although this may slow down the operation.
+cache; depending on the specific scenario this may slow down or speed up
+the operation.
The progress may be monitored using ``domjobinfo`` virsh command and canceled
with ``domjobabort`` command (sent by another virsh instance). Another option
@@ -3833,6 +3836,14 @@ based on the state the domain was in when the save was done;
passing
either the *--running* or *--paused* flag will allow overriding which
state the ``restore`` should use.
+*--parallel* option will cause the save data to be sent over multiple
+parallel connections to multiple files. The main save file is specified
+with ``state-file``, and a number of additional connections can be
+set using *--parallel-connections*, which will save to files named
+``state-file``.1 , ``state-file``.2 ... up to ``connections``.
+
+Parallel connections may help in speeding up the save operation.
+
Domain saved state files assume that disk images will be unchanged
between the creation and restore point. For a more complete system
restore point, where the disk state is saved alongside the memory
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index ba492e807e..4e39834118 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -4174,6 +4174,14 @@ static const vshCmdOptDef opts_save[] = {
.type = VSH_OT_BOOL,
.help = N_("avoid file system cache when saving")
},
+ {.name = "parallel",
+ .type = VSH_OT_BOOL,
+ .help = N_("enable parallel save to files")
+ },
+ {.name = "parallel-connections",
+ .type = VSH_OT_INT,
+ .help = N_("number of connections/files for parallel save")
+ },
{.name = "xml",
.type = VSH_OT_STRING,
.completer = virshCompletePathLocalExisting,
@@ -4203,6 +4211,11 @@ doSave(void *opaque)
g_autoptr(virshDomain) dom = NULL;
const char *name = NULL;
const char *to = NULL;
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+ int maxparams = 0;
+ int intOpt = 0;
+ int rv = -1;
unsigned int flags = 0;
const char *xmlfile = NULL;
g_autofree char *xml = NULL;
@@ -4216,29 +4229,46 @@ doSave(void *opaque)
goto out_sig;
#endif /* !WIN32 */
- if (vshCommandOptStringReq(ctl, cmd, "file", &to) < 0)
+ if ((rv = vshCommandOptStringReq(ctl, cmd, "file", &to)) < 0) {
goto out;
-
+ } else {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_SAVE_PARAM_FILE, to) < 0)
+ goto out;
+ }
if (vshCommandOptBool(cmd, "bypass-cache"))
flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
+ if (vshCommandOptBool(cmd, "parallel"))
+ flags |= VIR_DOMAIN_SAVE_PARALLEL;
+ if ((rv = vshCommandOptInt(ctl, cmd, "parallel-connections", &intOpt))
< 0) {
+ goto out;
+ } else if (rv > 0) {
+ if (virTypedParamsAddInt(¶ms, &nparams, &maxparams,
+ VIR_SAVE_PARAM_PARALLEL_CONNECTIONS, intOpt) < 0)
+ goto out;
+ }
if (vshCommandOptBool(cmd, "running"))
flags |= VIR_DOMAIN_SAVE_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_SAVE_PAUSED;
- if (vshCommandOptStringReq(ctl, cmd, "xml", &xmlfile) < 0)
+ if ((rv = vshCommandOptStringReq(ctl, cmd, "xml", &xmlfile)) < 0)
goto out;
if (!(dom = virshCommandOptDomain(ctl, cmd, &name)))
goto out;
- if (xmlfile &&
- virFileReadAll(xmlfile, VSH_MAX_XML_FILE, &xml) < 0) {
- vshReportError(ctl);
- goto out;
+ if (xmlfile) {
+ if (virFileReadAll(xmlfile, VSH_MAX_XML_FILE, &xml) < 0) {
+ vshReportError(ctl);
+ goto out;
+ } else if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_SAVE_PARAM_DXML, xml) < 0)
+ goto out;
}
-
- if (flags || xml) {
+ if (flags & VIR_DOMAIN_SAVE_PARALLEL) {
+ rc = virDomainSaveParams(dom, params, nparams, flags);
+ } else if (flags || xml) {
rc = virDomainSaveFlags(dom, to, xml, flags);
} else {
rc = virDomainSave(dom, to);
@@ -4252,6 +4282,7 @@ doSave(void *opaque)
data->ret = 0;
out:
+ virTypedParamsFree(params, nparams);
#ifndef WIN32
pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
out_sig:
--
2.34.1