These are exposed under domfsfreeze command and domfsthaw command. Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@xxxxxxx> --- tools/virsh-domain.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 23 +++++++++ 2 files changed, 153 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 73414f8..32d52ac 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -11391,6 +11391,124 @@ cmdDomFSTrim(vshControl *ctl, const vshCmd *cmd) return ret; } +static const vshCmdInfo info_domfsfreeze[] = { + {.name = "help", + .data = N_("Freeze domain's mounted filesystems.") + }, + {.name = "desc", + .data = N_("Freeze domain's mounted filesystems.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_domfsfreeze[] = { + {.name = "domain", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("domain name, id or uuid") + }, + {.name = "mountpoints", + .type = VSH_OT_DATA, + .help = N_("comma separated list of mountpoints to be frozen") + }, + {.name = NULL} +}; +static bool +cmdDomFSFreeze(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + int ret = -1; + unsigned int flags = 0; + const char *mountpoints_string = NULL; + char **list = NULL; /* tokenized mountpoints_string */ + int nmountpoints = 0; + size_t i; + + ignore_value(vshCommandOptString(cmd, "mountpoints", &mountpoints_string)); + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (mountpoints_string) { + if ((nmountpoints = vshStringToArray(mountpoints_string, &list)) < 0) + goto cleanup; + } + + ret = virDomainFSFreeze(dom, (const char **)list, nmountpoints, flags); + if (ret < 0) { + vshError(ctl, _("Unable to freeze filesystems")); + goto cleanup; + } + + vshPrint(ctl, _("Froze %d filesystem(s)\n"), ret); + + cleanup: + for (i = 0; i < nmountpoints; i++) + VIR_FREE(list[i]); + VIR_FREE(list); + virDomainFree(dom); + return ret >= 0; +} + +static const vshCmdInfo info_domfsthaw[] = { + {.name = "help", + .data = N_("Thaw domain's mounted filesystems.") + }, + {.name = "desc", + .data = N_("Thaw domain's mounted filesystems.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_domfsthaw[] = { + {.name = "domain", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("domain name, id or uuid") + }, + {.name = "mountpoints", + .type = VSH_OT_DATA, + .help = N_("comma separated list of mountpoints to be thawed") + }, + {.name = NULL} +}; +static bool +cmdDomFSThaw(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + int ret = -1; + unsigned int flags = 0; + const char *mountpoints_string = NULL; + char **list = NULL; /* tokenized mountpoints_string */ + int nmountpoints = 0; + size_t i; + + ignore_value(vshCommandOptString(cmd, "mountpoints", &mountpoints_string)); + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (mountpoints_string) { + if ((nmountpoints = vshStringToArray(mountpoints_string, &list)) < 0) + goto cleanup; + } + + ret = virDomainFSThaw(dom, (const char **)list, nmountpoints, flags); + if (ret < 0) { + vshError(ctl, _("Unable to thaw filesystems")); + goto cleanup; + } + + vshPrint(ctl, _("Thawed %d filesystem(s)\n"), ret); + + cleanup: + for (i = 0; i < nmountpoints; i++) + VIR_FREE(list[i]); + VIR_FREE(list); + virDomainFree(dom); + return ret >= 0; +} + const vshCmdDef domManagementCmds[] = { {.name = "attach-device", .handler = cmdAttachDevice, @@ -11538,6 +11656,18 @@ const vshCmdDef domManagementCmds[] = { .info = info_domdisplay, .flags = 0 }, + {.name = "domfsfreeze", + .handler = cmdDomFSFreeze, + .opts = opts_domfsfreeze, + .info = info_domfsfreeze, + .flags = 0 + }, + {.name = "domfsthaw", + .handler = cmdDomFSThaw, + .opts = opts_domfsthaw, + .info = info_domfsthaw, + .flags = 0 + }, {.name = "domfstrim", .handler = cmdDomFSTrim, .opts = opts_domfstrim, diff --git a/tools/virsh.pod b/tools/virsh.pod index abd2e93..89c58be 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -941,6 +941,29 @@ Output a URI which can be used to connect to the graphical display of the domain via VNC, SPICE or RDP. If I<--include-password> is specified, the SPICE channel password will be included in the URI. +=item B<domfsfreeze> I<domain> [I<--mountpoints> B<mountpoints>] + +Freeze mounted filesystems within a running domain to prepare for consistent +snapshots. + +The I<--mountpoints> option takes a parameter B<mountpoints>, which is a comma +separated list of mountpoint paths of filesystems to be frozen. If this is not +specified, every mounted filesystem is frozen. + +Note that B<snapshot-create> command has a I<--quiesce> option to freeze +and thaw the filesystems automatically to keep snapshots consistent. +B<domfsfreeze> command is only needed when a user wants to utilize the +native snapshot features of storage devices not supported by libvirt. + +=item B<domfsthaw> I<domain> [I<--mountpoints> B<mountpoints>] + +Thaw mounted filesystems within a running domain, which have been frozen by +domfsfreeze command. + +The I<--mountpoints> option takes a parameter B<mountpoints>, which is a comma +separated list of mountpoint paths of filesystems to be thawed. If it is not +specified, every mounted filesystem is thawed. + =item B<domfstrim> I<domain> [I<--minimum> B<bytes>] [I<--mountpoint mountPoint>] -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list