[Libvir] [QEMU 2/3] add commands for inactive domains to virsh
Daniel P. Berrange
berrange at redhat.com
Sun Aug 27 23:16:43 UTC 2006
The attached patch adds new commands to virsh, and modifies the list
command.
* 'list' is given two additional parameters '--inactive' to tell it to
list inactive instances, instead of active instances, and --all to
tell it to list both active & instance domains. NB inactive domains
will show with an ID of -1 and state 'shut off'.
* 'define' defines an inactive domain - instructing the backend to
save the XML definition in some persist location. The domain is
not started.
* 'undefine' removes an inactive domain - the persist config file
managed by the backend is deleted. The domain must not be running
when this is run.
* 'start' starts up an inactive domain which was previously defined
via the 'define' command.
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
-------------- next part --------------
diff --exclude docs --exclude .deps --exclude CVS -ruN libvirt-orig/src/virsh.c libvirt-new/src/virsh.c
--- libvirt-orig/src/virsh.c 2006-08-25 18:40:33.000000000 -0400
+++ libvirt-new/src/virsh.c 2006-08-27 17:27:12.000000000 -0400
@@ -314,28 +314,63 @@
{NULL, NULL}
};
+static vshCmdOptDef opts_list[] = {
+ {"inactive", VSH_OT_BOOL, 0, "list inactive domains"},
+ {"all", VSH_OT_BOOL, 0, "list inactive & active domains"},
+ {NULL, 0, 0, NULL}
+};
+
static int
cmdList(vshControl * ctl, vshCmd * cmd ATTRIBUTE_UNUSED)
{
- int *ids = NULL, maxid, i;
+ int inactive = vshCommandOptBool(cmd, "inactive");
+ int all = vshCommandOptBool(cmd, "all");
+ int active = !inactive || all ? 1 : 0;
+ int *ids = NULL, maxid = 0, i;
+ const char **names = NULL;
+ int maxname = 0;
+ inactive |= all;
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE;
-
- maxid = virConnectNumOfDomains(ctl->conn);
- if (maxid < 0) {
+
+ if (active) {
+ maxid = virConnectNumOfDomains(ctl->conn);
+ if (maxid < 0) {
vshError(ctl, FALSE, "failed to list active domains.");
return FALSE;
- }
- if (maxid) {
+ }
+ if (maxid) {
ids = vshMalloc(ctl, sizeof(int) * maxid);
-
+
if (virConnectListDomains(ctl->conn, &ids[0], maxid) < 0) {
- vshError(ctl, FALSE, "failed to list active domains.");
- return FALSE;
+ vshError(ctl, FALSE, "failed to list active domains.");
+ free(ids);
+ return FALSE;
+ }
+ }
+ }
+ if (inactive) {
+ maxname = virConnectNumOfDefinedDomains(ctl->conn);
+ if (maxname < 0) {
+ vshError(ctl, FALSE, "failed to list inactive domains.");
+ if (ids)
+ free(ids);
+ return FALSE;
+ }
+ if (maxname) {
+ names = vshMalloc(ctl, sizeof(int) * maxname);
+
+ if (virConnectListDefinedDomains(ctl->conn, names, maxname) < 0) {
+ vshError(ctl, FALSE, "failed to list inactive domains.");
+ if (ids)
+ free(ids);
+ free(names);
+ return FALSE;
}
+ }
}
vshPrintExtra(ctl, "%3s %-20s %s\n", "Id", "Name", "State");
vshPrintExtra(ctl, "----------------------------------\n");
@@ -357,8 +392,27 @@
0 ? "no state" : vshDomainStateToString(info.state));
virDomainFree(dom);
}
+ for (i = 0; i < maxname; i++) {
+ int ret;
+ virDomainInfo info;
+ virDomainPtr dom = virDomainLookupByName(ctl->conn, names[i]);
+
+ /* this kind of work with domains is not atomic operation */
+ if (!dom)
+ continue;
+ ret = virDomainGetInfo(dom, &info);
+
+ vshPrint(ctl, "%3d %-20s %s\n",
+ virDomainGetID(dom),
+ names[i],
+ ret <
+ 0 ? "no state" : vshDomainStateToString(info.state));
+ virDomainFree(dom);
+ }
if (ids)
free(ids);
+ if (names)
+ free(names);
return TRUE;
}
@@ -495,6 +549,149 @@
}
/*
+ * "define" command
+ */
+static vshCmdInfo info_define[] = {
+ {"syntax", "define a domain from an XML <file>"},
+ {"help", "define a domain (but don't start) from an XML file"},
+ {"desc", "Define a domain."},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_define[] = {
+ {"file", VSH_OT_DATA, VSH_OFLAG_REQ, "file conatining an XML domain description"},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdDefine(vshControl * ctl, vshCmd * cmd)
+{
+ virDomainPtr dom;
+ char *from;
+ int found;
+ int ret = TRUE;
+ char buffer[4096];
+ int fd, l;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ from = vshCommandOptString(cmd, "file", &found);
+ if (!found)
+ return FALSE;
+
+ fd = open(from, O_RDONLY);
+ if (fd < 0) {
+ vshError(ctl, FALSE, "Failed to read description file %s\n", from);
+ return(FALSE);
+ }
+ l = read(fd, &buffer[0], sizeof(buffer));
+ if ((l <= 0) || (l >= (int) sizeof(buffer))) {
+ vshError(ctl, FALSE, "Failed to read description file %s\n", from);
+ close(fd);
+ return(FALSE);
+ }
+ buffer[l] = 0;
+ dom = virDomainDefineXML(ctl->conn, &buffer[0]);
+ if (dom != NULL) {
+ vshPrint(ctl, "Domain %s defined from %s\n",
+ virDomainGetName(dom), from);
+ } else {
+ vshError(ctl, FALSE, "Failed to define domain\n");
+ ret = FALSE;
+ }
+ return ret;
+}
+
+/*
+ * "undefine" command
+ */
+static vshCmdInfo info_undefine[] = {
+ {"syntax", "undefine <domain>"},
+ {"help", "Undefine an inactive domain"},
+ {"desc", "Undefine the configuration for an inactive domain"},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_undefine[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name, or uuid"},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdUndefine(vshControl * ctl, vshCmd * cmd)
+{
+ virDomainPtr dom;
+ int ret = TRUE;
+ char *name;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &name)))
+ return FALSE;
+
+ if (virDomainUndefine(dom) == 0) {
+ vshPrint(ctl, "Domain %s has been undefined\n", name);
+ } else {
+ vshError(ctl, FALSE, "Failed to undefine domain\n");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+
+/*
+ * "start" command
+ */
+static vshCmdInfo info_start[] = {
+ {"syntax", "start a domain from an XML <file>"},
+ {"help", "start a domain from an XML file"},
+ {"desc", "Start a domain."},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_start[] = {
+ {"name", VSH_OT_DATA, VSH_OFLAG_REQ, "name of the inactive domain" },
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdStart(vshControl * ctl, vshCmd * cmd)
+{
+ virDomainPtr dom;
+ char *name;
+ int found;
+ int ret = TRUE;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ name = vshCommandOptString(cmd, "name", &found);
+ if (!found)
+ return FALSE;
+
+ dom = virDomainLookupByName(ctl->conn, name);
+ if (!dom)
+ return FALSE;
+
+ if (virDomainGetID(dom) != (unsigned int)-1) {
+ vshError(ctl, FALSE, "Domain is already active\n");
+ return FALSE;
+ }
+
+ if (virDomainCreate(dom) == 0) {
+ vshPrint(ctl, "Domain %s started\n",
+ name);
+ } else {
+ vshError(ctl, FALSE, "Failed to start domain\n");
+ ret = FALSE;
+ }
+ return ret;
+}
+
+/*
* "save" command
*/
static vshCmdInfo info_save[] = {
@@ -1367,7 +1564,9 @@
static vshCmdDef commands[] = {
{"connect", cmdConnect, opts_connect, info_connect},
{"create", cmdCreate, opts_create, info_create},
+ {"start", cmdStart, opts_start, info_start},
{"destroy", cmdDestroy, opts_destroy, info_destroy},
+ {"define", cmdDefine, opts_define, info_define},
{"domid", cmdDomid, opts_domid, info_domid},
{"domuuid", cmdDomuuid, opts_domuuid, info_domuuid},
{"dominfo", cmdDominfo, opts_dominfo, info_dominfo},
@@ -1375,7 +1574,7 @@
{"domstate", cmdDomstate, opts_domstate, info_domstate},
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
{"help", cmdHelp, opts_help, info_help},
- {"list", cmdList, NULL, info_list},
+ {"list", cmdList, opts_list, info_list},
{"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo},
{"quit", cmdQuit, NULL, info_quit},
{"reboot", cmdReboot, opts_reboot, info_reboot},
@@ -1387,6 +1586,7 @@
{"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem},
{"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus},
{"suspend", cmdSuspend, opts_suspend, info_suspend},
+ {"undefine", cmdUndefine, opts_undefine, info_undefine},
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
{"version", cmdVersion, NULL, info_version},
@@ -2084,7 +2284,8 @@
/* basic connection to hypervisor, for Xen connections unless
we're root open a read only connections. Allow 'test' HV
to be RW all the time though */
- if (ctl->uid == 0 || (ctl->name && !strncmp(ctl->name, "test", 4)))
+ if (ctl->uid == 0 || (ctl->name && (!strncmp(ctl->name, "test", 4) ||
+ !strncmp(ctl->name, "qemu", 4))))
ctl->conn = virConnectOpen(ctl->name);
else
ctl->conn = virConnectOpenReadOnly(ctl->name);
More information about the libvir-list
mailing list