1342
* "managedsave" command
1344
static const vshCmdInfo info_managedsave[] = {
1345
{"help", N_("managed save of a domain state")},
1346
{"desc", N_("Save and stop a running domain, so libvirt can restart it from the same state")},
1350
static const vshCmdOptDef opts_managedsave[] = {
1351
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
1356
cmdManagedSave(vshControl *ctl, const vshCmd *cmd)
1362
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
1365
if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
1368
if (virDomainManagedSave(dom, 0) == 0) {
1369
vshPrint(ctl, _("Domain %s state saved by libvirt\n"), name);
1371
vshError(ctl, _("Failed to save domain %s state"), name);
1271
1380
* "schedinfo" command
1273
1382
static const vshCmdInfo info_schedinfo[] = {
1274
{"help", gettext_noop("show/set scheduler parameters")},
1275
{"desc", gettext_noop("Show/Set scheduler parameters.")},
1383
{"help", N_("show/set scheduler parameters")},
1384
{"desc", N_("Show/Set scheduler parameters.")},
1279
1388
static const vshCmdOptDef opts_schedinfo[] = {
1280
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
1281
{"set", VSH_OT_STRING, VSH_OFLAG_NONE, gettext_noop("parameter=value")},
1282
{"weight", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("weight for XEN_CREDIT")},
1283
{"cap", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("cap for XEN_CREDIT")},
1389
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
1390
{"set", VSH_OT_STRING, VSH_OFLAG_NONE, N_("parameter=value")},
1391
{"weight", VSH_OT_INT, VSH_OFLAG_NONE, N_("weight for XEN_CREDIT")},
1392
{"cap", VSH_OT_INT, VSH_OFLAG_NONE, N_("cap for XEN_CREDIT")},
1284
1393
{NULL, 0, 0, NULL}
2684
2791
* "migrate" command
2686
2793
static const vshCmdInfo info_migrate[] = {
2687
{"help", gettext_noop("migrate domain to another host")},
2688
{"desc", gettext_noop("Migrate domain to another host. Add --live for live migration.")},
2794
{"help", N_("migrate domain to another host")},
2795
{"desc", N_("Migrate domain to another host. Add --live for live migration.")},
2692
2799
static const vshCmdOptDef opts_migrate[] = {
2693
{"live", VSH_OT_BOOL, 0, gettext_noop("live migration")},
2694
{"p2p", VSH_OT_BOOL, 0, gettext_noop("peer-2-peer migration")},
2695
{"direct", VSH_OT_BOOL, 0, gettext_noop("direct migration")},
2696
{"tunnelled", VSH_OT_BOOL, 0, gettext_noop("tunnelled migration")},
2697
{"persistent", VSH_OT_BOOL, 0, gettext_noop("persist VM on destination")},
2698
{"undefinesource", VSH_OT_BOOL, 0, gettext_noop("undefine VM on source")},
2699
{"suspend", VSH_OT_BOOL, 0, gettext_noop("do not restart the domain on the destination host")},
2700
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
2701
{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("connection URI of the destination host")},
2702
{"migrateuri", VSH_OT_DATA, 0, gettext_noop("migration URI, usually can be omitted")},
2703
{"dname", VSH_OT_DATA, 0, gettext_noop("rename to new name during migration (if supported)")},
2800
{"live", VSH_OT_BOOL, 0, N_("live migration")},
2801
{"p2p", VSH_OT_BOOL, 0, N_("peer-2-peer migration")},
2802
{"direct", VSH_OT_BOOL, 0, N_("direct migration")},
2803
{"tunnelled", VSH_OT_BOOL, 0, N_("tunnelled migration")},
2804
{"persistent", VSH_OT_BOOL, 0, N_("persist VM on destination")},
2805
{"undefinesource", VSH_OT_BOOL, 0, N_("undefine VM on source")},
2806
{"suspend", VSH_OT_BOOL, 0, N_("do not restart the domain on the destination host")},
2807
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
2808
{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the destination host")},
2809
{"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be omitted")},
2810
{"dname", VSH_OT_DATA, 0, N_("rename to new name during migration (if supported)")},
2704
2811
{NULL, 0, 0, NULL}
2888
* "migrate-setmaxdowntime" command
2890
static const vshCmdInfo info_migrate_setmaxdowntime[] = {
2891
{"help", N_("set maximum tolerable downtime")},
2892
{"desc", N_("Set maximum tolerable downtime of a domain which is being live-migrated to another host.")},
2896
static const vshCmdOptDef opts_migrate_setmaxdowntime[] = {
2897
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
2898
{"downtime", VSH_OT_DATA, VSH_OFLAG_REQ, N_("maximum tolerable downtime (in milliseconds) for migration")},
2903
cmdMigrateSetMaxDowntime(vshControl *ctl, const vshCmd *cmd)
2905
virDomainPtr dom = NULL;
2910
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
2913
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
2916
downtime = vshCommandOptLongLong(cmd, "downtime", &found);
2917
if (!found || downtime < 1) {
2918
vshError(ctl, "%s", _("migrate: Invalid downtime"));
2922
if (virDomainMigrateSetMaxDowntime(dom, downtime, 0))
2781
2933
* "net-autostart" command
2783
2935
static const vshCmdInfo info_network_autostart[] = {
2784
{"help", gettext_noop("autostart a network")},
2936
{"help", N_("autostart a network")},
2786
gettext_noop("Configure a network to be automatically started at boot.")},
2938
N_("Configure a network to be automatically started at boot.")},
2790
2942
static const vshCmdOptDef opts_network_autostart[] = {
2791
{"network", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("network name or uuid")},
2792
{"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
2943
{"network", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network name or uuid")},
2944
{"disable", VSH_OT_BOOL, 0, N_("disable autostarting")},
2793
2945
{NULL, 0, 0, NULL}
3910
* "nwfilter-define" command
3912
static const vshCmdInfo info_nwfilter_define[] = {
3913
{"help", N_("define or update a network filter from an XML file")},
3914
{"desc", N_("Define a new network filter or update an existing one.")},
3918
static const vshCmdOptDef opts_nwfilter_define[] = {
3919
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("file containing an XML network filter description")},
3924
cmdNWFilterDefine(vshControl *ctl, const vshCmd *cmd)
3926
virNWFilterPtr nwfilter;
3932
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
3935
from = vshCommandOptString(cmd, "file", &found);
3939
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0)
3942
nwfilter = virNWFilterDefineXML(ctl->conn, buffer);
3945
if (nwfilter != NULL) {
3946
vshPrint(ctl, _("Network filter %s defined from %s\n"),
3947
virNWFilterGetName(nwfilter), from);
3948
virNWFilterFree(nwfilter);
3950
vshError(ctl, _("Failed to define network filter from %s"), from);
3958
* "nwfilter-undefine" command
3960
static const vshCmdInfo info_nwfilter_undefine[] = {
3961
{"help", N_("undefine a network filter")},
3962
{"desc", N_("Undefine a given network filter.")},
3966
static const vshCmdOptDef opts_nwfilter_undefine[] = {
3967
{"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")},
3972
cmdNWFilterUndefine(vshControl *ctl, const vshCmd *cmd)
3974
virNWFilterPtr nwfilter;
3978
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
3981
if (!(nwfilter = vshCommandOptNWFilter(ctl, cmd, &name)))
3984
if (virNWFilterUndefine(nwfilter) == 0) {
3985
vshPrint(ctl, _("Network filter %s undefined\n"), name);
3987
vshError(ctl, _("Failed to undefine network filter %s"), name);
3991
virNWFilterFree(nwfilter);
3997
* "nwfilter-dumpxml" command
3999
static const vshCmdInfo info_nwfilter_dumpxml[] = {
4000
{"help", N_("network filter information in XML")},
4001
{"desc", N_("Output the network filter information as an XML dump to stdout.")},
4005
static const vshCmdOptDef opts_nwfilter_dumpxml[] = {
4006
{"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")},
4011
cmdNWFilterDumpXML(vshControl *ctl, const vshCmd *cmd)
4013
virNWFilterPtr nwfilter;
4017
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
4020
if (!(nwfilter = vshCommandOptNWFilter(ctl, cmd, NULL)))
4023
dump = virNWFilterGetXMLDesc(nwfilter, 0);
4031
virNWFilterFree(nwfilter);
4036
* "nwfilter-list" command
4038
static const vshCmdInfo info_nwfilter_list[] = {
4039
{"help", N_("list network filters")},
4040
{"desc", N_("Returns list of network filters.")},
4044
static const vshCmdOptDef opts_nwfilter_list[] = {
4049
cmdNWFilterList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
4053
char uuid[VIR_UUID_STRING_BUFLEN];
4055
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
4058
numfilters = virConnectNumOfNWFilters(ctl->conn);
4059
if (numfilters < 0) {
4060
vshError(ctl, "%s", _("Failed to list network filters"));
4064
names = vshMalloc(ctl, sizeof(char *) * numfilters);
4066
if ((numfilters = virConnectListNWFilters(ctl->conn, names,
4068
vshError(ctl, "%s", _("Failed to list network filters"));
4073
qsort(&names[0], numfilters, sizeof(char *), namesorter);
4075
vshPrintExtra(ctl, "%-36s %-20s \n", _("UUID"), _("Name"));
4077
"----------------------------------------------------------------\n");
4079
for (i = 0; i < numfilters; i++) {
4080
virNWFilterPtr nwfilter =
4081
virNWFilterLookupByName(ctl->conn, names[i]);
4083
/* this kind of work with networks is not atomic operation */
4089
virNWFilterGetUUIDString(nwfilter, uuid);
4090
vshPrint(ctl, "%-36s %-20s\n",
4092
virNWFilterGetName(nwfilter));
4093
virNWFilterFree(nwfilter);
4103
* "nwfilter-edit" command
4105
static const vshCmdInfo info_nwfilter_edit[] = {
4106
{"help", N_("edit XML configuration for a network filter")},
4107
{"desc", N_("Edit the XML configuration for a network filter.")},
4111
static const vshCmdOptDef opts_nwfilter_edit[] = {
4112
{"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")},
4117
cmdNWFilterEdit (vshControl *ctl, const vshCmd *cmd)
4120
virNWFilterPtr nwfilter = NULL;
4123
char *doc_edited = NULL;
4124
char *doc_reread = NULL;
4126
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
4129
nwfilter = vshCommandOptNWFilter (ctl, cmd, NULL);
4130
if (nwfilter == NULL)
4133
/* Get the XML configuration of the interface. */
4134
doc = virNWFilterGetXMLDesc (nwfilter, 0);
4138
/* Create and open the temporary file. */
4139
tmp = editWriteToTempFile (ctl, doc);
4140
if (!tmp) goto cleanup;
4142
/* Start the editor. */
4143
if (editFile (ctl, tmp) == -1) goto cleanup;
4145
/* Read back the edited file. */
4146
doc_edited = editReadBackFile (ctl, tmp);
4147
if (!doc_edited) goto cleanup;
4152
/* Compare original XML with edited. Has it changed at all? */
4153
if (STREQ (doc, doc_edited)) {
4154
vshPrint (ctl, _("Network filter %s XML configuration not changed.\n"),
4155
virNWFilterGetName (nwfilter));
4160
/* Now re-read the network filter XML. Did someone else change it while
4161
* it was being edited? This also catches problems such as us
4162
* losing a connection or the interface going away.
4164
doc_reread = virNWFilterGetXMLDesc (nwfilter, 0);
4168
if (STRNEQ (doc, doc_reread)) {
4170
_("ERROR: the XML configuration was changed by another user"));
4174
/* Everything checks out, so redefine the interface. */
4175
virNWFilterFree (nwfilter);
4176
nwfilter = virNWFilterDefineXML (ctl->conn, doc_edited);
4180
vshPrint (ctl, _("Network filter %s XML configuration edited.\n"),
4181
virNWFilterGetName(nwfilter));
4187
virNWFilterFree (nwfilter);
4190
VIR_FREE(doc_edited);
4191
VIR_FREE(doc_reread);
3756
4202
/**************************************************************************/
3758
4204
* "pool-autostart" command
3760
4206
static const vshCmdInfo info_pool_autostart[] = {
3761
{"help", gettext_noop("autostart a pool")},
4207
{"help", N_("autostart a pool")},
3763
gettext_noop("Configure a pool to be automatically started at boot.")},
4209
N_("Configure a pool to be automatically started at boot.")},
3767
4213
static const vshCmdOptDef opts_pool_autostart[] = {
3768
{"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name or uuid")},
3769
{"disable", VSH_OT_BOOL, 0, gettext_noop("disable autostarting")},
4214
{"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")},
4215
{"disable", VSH_OT_BOOL, 0, N_("disable autostarting")},
3770
4216
{NULL, 0, 0, NULL}
3958
4403
* XML Building helper for pool-define-as and pool-create-as
3960
4405
static const vshCmdOptDef opts_pool_X_as[] = {
3961
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the pool")},
3962
{"print-xml", VSH_OT_BOOL, 0, gettext_noop("print XML document, but don't define/create")},
3963
{"type", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("type of the pool")},
3964
{"source-host", VSH_OT_DATA, 0, gettext_noop("source-host for underlying storage")},
3965
{"source-path", VSH_OT_DATA, 0, gettext_noop("source path for underlying storage")},
3966
{"source-dev", VSH_OT_DATA, 0, gettext_noop("source device for underlying storage")},
3967
{"source-name", VSH_OT_DATA, 0, gettext_noop("source name for underlying storage")},
3968
{"target", VSH_OT_DATA, 0, gettext_noop("target for underlying storage")},
4406
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name of the pool")},
4407
{"print-xml", VSH_OT_BOOL, 0, N_("print XML document, but don't define/create")},
4408
{"type", VSH_OT_DATA, VSH_OFLAG_REQ, N_("type of the pool")},
4409
{"source-host", VSH_OT_DATA, 0, N_("source-host for underlying storage")},
4410
{"source-path", VSH_OT_DATA, 0, N_("source path for underlying storage")},
4411
{"source-dev", VSH_OT_DATA, 0, N_("source device for underlying storage")},
4412
{"source-name", VSH_OT_DATA, 0, N_("source name for underlying storage")},
4413
{"target", VSH_OT_DATA, 0, N_("target for underlying storage")},
3969
4414
{NULL, 0, 0, NULL}
4753
5198
* "vol-create-as" command
4755
5200
static const vshCmdInfo info_vol_create_as[] = {
4756
{"help", gettext_noop("create a volume from a set of args")},
4757
{"desc", gettext_noop("Create a vol.")},
5201
{"help", N_("create a volume from a set of args")},
5202
{"desc", N_("Create a vol.")},
4761
5206
static const vshCmdOptDef opts_vol_create_as[] = {
4762
{"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name")},
4763
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the volume")},
4764
{"capacity", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("size of the vol with optional k,M,G,T suffix")},
4765
{"allocation", VSH_OT_STRING, 0, gettext_noop("initial allocation size with optional k,M,G,T suffix")},
4766
{"format", VSH_OT_STRING, 0, gettext_noop("file format type raw,bochs,qcow,qcow2,vmdk")},
5207
{"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name")},
5208
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name of the volume")},
5209
{"capacity", VSH_OT_DATA, VSH_OFLAG_REQ, N_("size of the vol with optional k,M,G,T suffix")},
5210
{"allocation", VSH_OT_STRING, 0, N_("initial allocation size with optional k,M,G,T suffix")},
5211
{"format", VSH_OT_STRING, 0, N_("file format type raw,bochs,qcow,qcow2,vmdk")},
4767
5212
{NULL, 0, 0, NULL}
5671
* "vol-wipe" command
5673
static const vshCmdInfo info_vol_wipe[] = {
5674
{"help", N_("wipe a vol")},
5675
{"desc", N_("Ensure data previously on a volume is not accessible to future reads")},
5679
static const vshCmdOptDef opts_vol_wipe[] = {
5680
{"pool", VSH_OT_STRING, 0, N_("pool name or uuid")},
5681
{"vol", VSH_OT_DATA, VSH_OFLAG_REQ, N_("vol name, key or path")},
5686
cmdVolWipe(vshControl *ctl, const vshCmd *cmd)
5688
virStorageVolPtr vol;
5692
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
5695
if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) {
5699
if (virStorageVolWipe(vol, 0) == 0) {
5700
vshPrint(ctl, _("Vol %s wiped\n"), name);
5702
vshError(ctl, _("Failed to wipe vol %s"), name);
5706
virStorageVolFree(vol);
5224
5712
* "vol-info" command
5226
5714
static const vshCmdInfo info_vol_info[] = {
5227
{"help", gettext_noop("storage vol information")},
5228
{"desc", gettext_noop("Returns basic information about the storage vol.")},
5715
{"help", N_("storage vol information")},
5716
{"desc", N_("Returns basic information about the storage vol.")},
5232
5720
static const vshCmdOptDef opts_vol_info[] = {
5233
{"pool", VSH_OT_STRING, 0, gettext_noop("pool name or uuid")},
5234
{"vol", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("vol name, key or path")},
5721
{"pool", VSH_OT_STRING, 0, N_("pool name or uuid")},
5722
{"vol", VSH_OT_DATA, VSH_OFLAG_REQ, N_("vol name, key or path")},
5235
5723
{NULL, 0, 0, NULL}
7032
* "update-device" command
7034
static const vshCmdInfo info_update_device[] = {
7035
{"help", N_("update device from an XML file")},
7036
{"desc", N_("Update device from an XML <file>.")},
7040
static const vshCmdOptDef opts_update_device[] = {
7041
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
7042
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("XML file")},
7043
{"persistent", VSH_OT_BOOL, 0, N_("persist device update")},
7048
cmdUpdateDevice(vshControl *ctl, const vshCmd *cmd)
7057
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
7060
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
7063
from = vshCommandOptString(cmd, "file", &found);
7065
vshError(ctl, "%s", _("update-device: Missing <file> option"));
7070
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
7071
virshReportError(ctl);
7076
if (vshCommandOptBool(cmd, "persistent")) {
7077
flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
7078
if (virDomainIsActive(dom) == 1)
7079
flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE;
7081
flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE;
7083
ret = virDomainUpdateDeviceFlags(dom, buffer, flags);
7087
vshError(ctl, _("Failed to update device from %s"), from);
7091
vshPrint(ctl, "%s", _("Device updated successfully\n"));
6542
7100
* "attach-interface" command
6544
7102
static const vshCmdInfo info_attach_interface[] = {
6545
{"help", gettext_noop("attach network interface")},
6546
{"desc", gettext_noop("Attach new network interface.")},
7103
{"help", N_("attach network interface")},
7104
{"desc", N_("Attach new network interface.")},
6550
7108
static const vshCmdOptDef opts_attach_interface[] = {
6551
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
6552
{"type", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("network interface type")},
6553
{"source", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("source of network interface")},
6554
{"target", VSH_OT_DATA, 0, gettext_noop("target network name")},
6555
{"mac", VSH_OT_DATA, 0, gettext_noop("MAC address")},
6556
{"script", VSH_OT_DATA, 0, gettext_noop("script used to bridge network interface")},
6557
{"persistent", VSH_OT_BOOL, 0, gettext_noop("persist interface attachment")},
7109
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
7110
{"type", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network interface type")},
7111
{"source", VSH_OT_DATA, VSH_OFLAG_REQ, N_("source of network interface")},
7112
{"target", VSH_OT_DATA, 0, N_("target network name")},
7113
{"mac", VSH_OT_DATA, 0, N_("MAC address")},
7114
{"script", VSH_OT_DATA, 0, N_("script used to bridge network interface")},
7115
{"persistent", VSH_OT_BOOL, 0, N_("persist interface attachment")},
6558
7116
{NULL, 0, 0, NULL}
6802
7360
* "attach-disk" command
6804
7362
static const vshCmdInfo info_attach_disk[] = {
6805
{"help", gettext_noop("attach disk device")},
6806
{"desc", gettext_noop("Attach new disk device.")},
7363
{"help", N_("attach disk device")},
7364
{"desc", N_("Attach new disk device.")},
6810
7368
static const vshCmdOptDef opts_attach_disk[] = {
6811
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
6812
{"source", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("source of disk device")},
6813
{"target", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("target of disk device")},
6814
{"driver", VSH_OT_STRING, 0, gettext_noop("driver of disk device")},
6815
{"subdriver", VSH_OT_STRING, 0, gettext_noop("subdriver of disk device")},
6816
{"type", VSH_OT_STRING, 0, gettext_noop("target device type")},
6817
{"mode", VSH_OT_STRING, 0, gettext_noop("mode of device reading and writing")},
6818
{"persistent", VSH_OT_BOOL, 0, gettext_noop("persist disk attachment")},
7369
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
7370
{"source", VSH_OT_DATA, VSH_OFLAG_REQ, N_("source of disk device")},
7371
{"target", VSH_OT_DATA, VSH_OFLAG_REQ, N_("target of disk device")},
7372
{"driver", VSH_OT_STRING, 0, N_("driver of disk device")},
7373
{"subdriver", VSH_OT_STRING, 0, N_("subdriver of disk device")},
7374
{"type", VSH_OT_STRING, 0, N_("target device type")},
7375
{"mode", VSH_OT_STRING, 0, N_("mode of device reading and writing")},
7376
{"persistent", VSH_OT_BOOL, 0, N_("persist disk attachment")},
6819
7377
{NULL, 0, 0, NULL}
8187
* "snapshot-create" command
8189
static const vshCmdInfo info_snapshot_create[] = {
8190
{"help", N_("Create a snapshot")},
8191
{"desc", N_("Snapshot create")},
8195
static const vshCmdOptDef opts_snapshot_create[] = {
8196
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
8197
{"xmlfile", VSH_OT_DATA, 0, N_("domain snapshot XML")},
8202
cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd)
8204
virDomainPtr dom = NULL;
8207
char *buffer = NULL;
8208
virDomainSnapshotPtr snapshot = NULL;
8209
xmlDocPtr xml = NULL;
8210
xmlXPathContextPtr ctxt = NULL;
8214
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
8217
dom = vshCommandOptDomain(ctl, cmd, NULL);
8221
from = vshCommandOptString(cmd, "xmlfile", NULL);
8223
buffer = strdup("<domainsnapshot/>");
8225
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
8226
/* we have to report the error here because during cleanup
8227
* we'll run through virDomainFree(), which loses the
8230
virshReportError(ctl);
8234
if (buffer == NULL) {
8235
vshError(ctl, "%s", _("Out of memory"));
8239
snapshot = virDomainSnapshotCreateXML(dom, buffer, 0);
8240
if (snapshot == NULL)
8243
doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
8247
xml = xmlReadDoc((const xmlChar *) doc, "domainsnapshot.xml", NULL,
8248
XML_PARSE_NOENT | XML_PARSE_NONET |
8249
XML_PARSE_NOWARNING);
8252
ctxt = xmlXPathNewContext(xml);
8256
name = virXPathString("string(/domainsnapshot/name)", ctxt);
8259
_("Could not find 'name' element in domain snapshot XML"));
8263
vshPrint(ctl, _("Domain snapshot %s created"), name);
8265
vshPrint(ctl, _(" from '%s'"), from);
8266
vshPrint(ctl, "\n");
8272
xmlXPathFreeContext(ctxt);
8276
virDomainSnapshotFree(snapshot);
8286
* "snapshot-current" command
8288
static const vshCmdInfo info_snapshot_current[] = {
8289
{"help", N_("Get the current snapshot")},
8290
{"desc", N_("Get the current snapshot")},
8294
static const vshCmdOptDef opts_snapshot_current[] = {
8295
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
8300
cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
8302
virDomainPtr dom = NULL;
8305
virDomainSnapshotPtr snapshot = NULL;
8307
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
8310
dom = vshCommandOptDomain(ctl, cmd, NULL);
8314
current = virDomainHasCurrentSnapshot(dom, 0);
8320
if (!(snapshot = virDomainSnapshotCurrent(dom, 0)))
8323
xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
8327
vshPrint(ctl, "%s", xml);
8335
virDomainSnapshotFree(snapshot);
8343
* "snapshot-list" command
8345
static const vshCmdInfo info_snapshot_list[] = {
8346
{"help", N_("List snapshots for a domain")},
8347
{"desc", N_("Snapshot List")},
8351
static const vshCmdOptDef opts_snapshot_list[] = {
8352
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
8357
cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
8359
virDomainPtr dom = NULL;
8362
char **names = NULL;
8365
xmlDocPtr xml = NULL;
8366
xmlXPathContextPtr ctxt = NULL;
8368
virDomainSnapshotPtr snapshot = NULL;
8372
struct tm time_info;
8374
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
8377
dom = vshCommandOptDomain(ctl, cmd, NULL);
8381
numsnaps = virDomainSnapshotNum(dom, 0);
8386
vshPrint(ctl, " %-20s %-25s %s\n", _("Name"), _("Creation Time"), _("State"));
8387
vshPrint(ctl, "---------------------------------------------------\n");
8390
if (VIR_ALLOC_N(names, numsnaps) < 0)
8393
actual = virDomainSnapshotListNames(dom, names, numsnaps, 0);
8397
qsort(&names[0], actual, sizeof(char*), namesorter);
8399
for (i = 0; i < actual; i++) {
8400
/* free up memory from previous iterations of the loop */
8403
virDomainSnapshotFree(snapshot);
8404
xmlXPathFreeContext(ctxt);
8409
snapshot = virDomainSnapshotLookupByName(dom, names[i], 0);
8410
if (snapshot == NULL)
8413
doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
8417
xml = xmlReadDoc((const xmlChar *) doc, "domainsnapshot.xml", NULL,
8418
XML_PARSE_NOENT | XML_PARSE_NONET |
8419
XML_PARSE_NOWARNING);
8422
ctxt = xmlXPathNewContext(xml);
8426
state = virXPathString("string(/domainsnapshot/state)", ctxt);
8429
if (virXPathLong("string(/domainsnapshot/creationTime)", ctxt,
8432
localtime_r(&creation, &time_info);
8433
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z", &time_info);
8435
vshPrint(ctl, " %-20s %-25s %s\n", names[i], timestr, state);
8442
/* this frees up memory from the last iteration of the loop */
8445
virDomainSnapshotFree(snapshot);
8446
xmlXPathFreeContext(ctxt);
8458
* "snapshot-dumpxml" command
8460
static const vshCmdInfo info_snapshot_dumpxml[] = {
8461
{"help", N_("Dump XML for a domain snapshot")},
8462
{"desc", N_("Snapshot Dump XML")},
8466
static const vshCmdOptDef opts_snapshot_dumpxml[] = {
8467
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
8468
{"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
8473
cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd)
8475
virDomainPtr dom = NULL;
8478
virDomainSnapshotPtr snapshot = NULL;
8481
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
8484
dom = vshCommandOptDomain(ctl, cmd, NULL);
8488
name = vshCommandOptString(cmd, "snapshotname", NULL);
8490
vshError(ctl, "%s", _("missing snapshotname"));
8494
snapshot = virDomainSnapshotLookupByName(dom, name, 0);
8495
if (snapshot == NULL)
8498
xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
8509
virDomainSnapshotFree(snapshot);
8517
* "snapshot-revert" command
8519
static const vshCmdInfo info_snapshot_revert[] = {
8520
{"help", N_("Revert a domain to a snapshot")},
8521
{"desc", N_("Revert domain to snapshot")},
8525
static const vshCmdOptDef opts_snapshot_revert[] = {
8526
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
8527
{"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
8532
cmdDomainSnapshotRevert(vshControl *ctl, const vshCmd *cmd)
8534
virDomainPtr dom = NULL;
8537
virDomainSnapshotPtr snapshot = NULL;
8539
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
8542
dom = vshCommandOptDomain(ctl, cmd, NULL);
8546
name = vshCommandOptString(cmd, "snapshotname", NULL);
8548
vshError(ctl, "%s", _("missing snapshotname"));
8552
snapshot = virDomainSnapshotLookupByName(dom, name, 0);
8553
if (snapshot == NULL)
8556
if (virDomainRevertToSnapshot(snapshot, 0) < 0)
8563
virDomainSnapshotFree(snapshot);
8571
* "snapshot-delete" command
8573
static const vshCmdInfo info_snapshot_delete[] = {
8574
{"help", N_("Delete a domain snapshot")},
8575
{"desc", N_("Snapshot Delete")},
8579
static const vshCmdOptDef opts_snapshot_delete[] = {
8580
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
8581
{"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
8582
{"children", VSH_OT_BOOL, 0, N_("delete snapshot and all children")},
8587
cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd)
8589
virDomainPtr dom = NULL;
8592
virDomainSnapshotPtr snapshot = NULL;
8593
unsigned int flags = 0;
8595
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
8598
dom = vshCommandOptDomain(ctl, cmd, NULL);
8602
name = vshCommandOptString(cmd, "snapshotname", NULL);
8604
vshError(ctl, "%s", _("missing snapshotname"));
8608
if (vshCommandOptBool(cmd, "children"))
8609
flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN;
8611
snapshot = virDomainSnapshotLookupByName(dom, name, 0);
8612
if (snapshot == NULL)
8615
if (virDomainSnapshotDelete(snapshot, flags) < 0)
8622
virDomainSnapshotFree(snapshot);
7633
8632
static const vshCmdDef commands[] = {