mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
snapshot: add 'virsh snapshot-info'
Expose the recent API additions in virsh. Borrows ideas from 'dominfo' for the general type of information to display. Output looks like: $ tools/virsh snapshot-info fedora-local tmp Name: tmp Domain: fedora-local Current: no State: disk-snapshot Parent: - Children: 1 Descendants: 2 Metadata: yes possibly with fewer lines when talking to older servers. * tools/virsh.c (cmdSnapshotInfo): New command. * tools/virsh.pod (snapshot-info): Document it.
This commit is contained in:
parent
a0ac7450d9
commit
757c47635d
125
tools/virsh.c
125
tools/virsh.c
@ -16567,6 +16567,129 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* "snapshot-info" command
|
||||
*/
|
||||
static const vshCmdInfo info_snapshot_info[] = {
|
||||
{"help", N_("snapshot information")},
|
||||
{"desc", N_("Returns basic information about a snapshot.")},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_snapshot_info[] = {
|
||||
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
|
||||
{"snapshotname", VSH_OT_DATA, 0, N_("snapshot name")},
|
||||
{"current", VSH_OT_BOOL, 0, N_("info on current snapshot")},
|
||||
{NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virDomainPtr dom;
|
||||
virDomainSnapshotPtr snapshot = NULL;
|
||||
const char *name;
|
||||
char *doc = NULL;
|
||||
char *tmp;
|
||||
char *parent = NULL;
|
||||
bool ret = false;
|
||||
int count;
|
||||
unsigned int flags;
|
||||
int current;
|
||||
int metadata;
|
||||
|
||||
if (!vshConnectionUsability(ctl, ctl->conn))
|
||||
return false;
|
||||
|
||||
dom = vshCommandOptDomain(ctl, cmd, NULL);
|
||||
if (dom == NULL)
|
||||
return false;
|
||||
|
||||
if (vshLookupSnapshot(ctl, cmd, "snapshotname", true, dom,
|
||||
&snapshot, &name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
vshPrint(ctl, "%-15s %s\n", _("Name:"), name);
|
||||
vshPrint(ctl, "%-15s %s\n", _("Domain:"), virDomainGetName(dom));
|
||||
|
||||
/* Determine if snapshot is current; this is useful enough that we
|
||||
* attempt a fallback. */
|
||||
current = virDomainSnapshotIsCurrent(snapshot, 0);
|
||||
if (current < 0) {
|
||||
virDomainSnapshotPtr other = virDomainSnapshotCurrent(dom, 0);
|
||||
|
||||
virResetLastError();
|
||||
current = 0;
|
||||
if (other) {
|
||||
if (STREQ(name, virDomainSnapshotGetName(other)))
|
||||
current = 1;
|
||||
virDomainSnapshotFree(other);
|
||||
}
|
||||
}
|
||||
vshPrint(ctl, "%-15s %s\n", _("Current:"),
|
||||
current > 0 ? _("yes") : _("no"));
|
||||
|
||||
/* Get the XML configuration of the snapshot to determine the
|
||||
* state of the machine at the time of the snapshot. */
|
||||
doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
|
||||
if (!doc)
|
||||
goto cleanup;
|
||||
|
||||
tmp = strstr(doc, "<state>");
|
||||
if (!tmp) {
|
||||
vshError(ctl, "%s",
|
||||
_("unexpected problem reading snapshot xml"));
|
||||
goto cleanup;
|
||||
}
|
||||
tmp += strlen("<state>");
|
||||
vshPrint(ctl, "%-15s %.*s\n", _("State:"),
|
||||
(int) (strchr(tmp, '<') - tmp), tmp);
|
||||
|
||||
if (vshGetSnapshotParent(ctl, snapshot, &parent) < 0)
|
||||
goto cleanup;
|
||||
vshPrint(ctl, "%-15s %s\n", _("Parent:"), parent ? parent : "-");
|
||||
|
||||
/* Children, Descendants. After this point, the fallback to
|
||||
* compute children is too expensive, so we gracefully quit if the
|
||||
* APIs don't exist. */
|
||||
if (ctl->useSnapshotOld) {
|
||||
ret = true;
|
||||
goto cleanup;
|
||||
}
|
||||
flags = 0;
|
||||
count = virDomainSnapshotNumChildren(snapshot, flags);
|
||||
if (count < 0)
|
||||
goto cleanup;
|
||||
vshPrint(ctl, "%-15s %d\n", _("Children:"), count);
|
||||
flags = VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
|
||||
count = virDomainSnapshotNumChildren(snapshot, flags);
|
||||
if (count < 0)
|
||||
goto cleanup;
|
||||
vshPrint(ctl, "%-15s %d\n", _("Descendants:"), count);
|
||||
|
||||
/* Metadata; the fallback here relies on the fact that metadata
|
||||
* used to have an all-or-nothing effect on snapshot count. */
|
||||
metadata = virDomainSnapshotHasMetadata(snapshot, 0);
|
||||
if (metadata < 0) {
|
||||
metadata = virDomainSnapshotNum(dom,
|
||||
VIR_DOMAIN_SNAPSHOT_LIST_METADATA);
|
||||
virResetLastError();
|
||||
}
|
||||
if (metadata >= 0)
|
||||
vshPrint(ctl, "%-15s %s\n", _("Metadata:"),
|
||||
metadata ? _("yes") : _("no"));
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(doc);
|
||||
VIR_FREE(parent);
|
||||
if (snapshot)
|
||||
virDomainSnapshotFree(snapshot);
|
||||
virDomainFree(dom);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* "snapshot-list" command
|
||||
*/
|
||||
@ -17661,6 +17784,8 @@ static const vshCmdDef snapshotCmds[] = {
|
||||
info_snapshot_dumpxml, 0},
|
||||
{"snapshot-edit", cmdSnapshotEdit, opts_snapshot_edit,
|
||||
info_snapshot_edit, 0},
|
||||
{"snapshot-info", cmdSnapshotInfo, opts_snapshot_info,
|
||||
info_snapshot_info, 0},
|
||||
{"snapshot-list", cmdSnapshotList, opts_snapshot_list,
|
||||
info_snapshot_list, 0},
|
||||
{"snapshot-parent", cmdSnapshotParent, opts_snapshot_parent,
|
||||
|
@ -2504,6 +2504,11 @@ a snapshot name must be done with care, since the contents of some
|
||||
snapshots, such as internal snapshots within a single qcow2 file, are
|
||||
accessible only from the original name.
|
||||
|
||||
=item B<snapshot-info> I<domain> {I<snapshot> | I<--current>}
|
||||
|
||||
Output basic information about a named <snapshot>, or the current snapshot
|
||||
with I<--current>.
|
||||
|
||||
=item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}]
|
||||
[{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]]
|
||||
[I<--metadata>] [I<--leaves>]
|
||||
|
Loading…
Reference in New Issue
Block a user