+Thu Mar 30 16:04:47 EST 2006 Daniel Veillard <veillard@redhat.com>
+
+ * src/virsh.c: allocation check (Jim Meyering) and adding a
+ new create command
+ * src/xend_internal.c src/xml.c: trying to cope with the new
+ xvda domains states generated on FC5, but Dom0 bootloader
+ really break the model, so that doesn't work.
+
Thu Mar 30 12:15:46 EST 2006 Daniel Veillard <veillard@redhat.com>
* src/virsh.c: catching memory allocation error and existing, as
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
+#include <fcntl.h>
#include <readline/readline.h>
#include <readline/history.h>
return ret;
}
+/*
+ * "create" command
+ */
+static vshCmdInfo info_create[] = {
+ {"syntax", "create a domain from an XML <file>"},
+ {"help", "create a domain from an XML file"},
+ {"desc", "Create a domain."},
+ {NULL, NULL}
+};
+
+static vshCmdOptDef opts_create[] = {
+ {"file", VSH_OT_DATA, VSH_OFLAG_REQ, "file conatining an XML domain description"},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdCreate(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 = virDomainCreateLinux(ctl->conn, &buffer[0], 0);
+ if (dom != NULL) {
+ vshPrint(ctl, VSH_MESG, "Domain %s created from %s\n",
+ virDomainGetName(dom), from);
+ } else {
+ vshError(ctl, FALSE, "Failed to create domain\n");
+ ret = FALSE;
+ }
+ return ret;
+}
+
/*
* "save" command
*/
*/
static vshCmdDef commands[] = {
{"connect", cmdConnect, opts_connect, info_connect},
+ {"create", cmdCreate, opts_create, info_create},
{"dinfo", cmdDinfo, opts_dinfo, info_dinfo},
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
{"dstate", cmdDstate, opts_dstate, info_dstate},
return NULL;
cmdname = calloc((p - rl_line_buffer) + 1, 1);
+ if (cmdname == NULL) {
+ fprintf(stderr, "Failed to allocate %d bytes\n",
+ (p - rl_line_buffer) + 1);
+ exit(1);
+ }
memcpy(cmdname, rl_line_buffer, p - rl_line_buffer);
cmd = vshCmddefSearch(cmdname);
sz += strlen(argv[i]) + 1; /* +1 is for blank space between items */
cmdstr = calloc(sz + 1, 1);
+ if (cmdstr == NULL) {
+ fprintf(stderr, "Failed to allocate %d bytes\n", sz + 1);
+ exit(1);
+ }
for (i = end; i < argc; i++) {
strncat(cmdstr, argv[i], sz);
goto error;
}
virBufferVSprintf(&buf, " <name>%s</name>\n", tmp);
+ tmp = sexpr_node(root, "domain/bootloader");
+ if (tmp != NULL)
+ virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", tmp);
tmp = sexpr_node(root, "domain/image/linux/kernel");
if (tmp == NULL) {
/*
serial);
TODO}
} else if (sexpr_lookup(node, "device/vif")) {
+ const char *tmp2;
+
tmp = sexpr_node(node, "device/vif/bridge");
- if (tmp != NULL) {
+ tmp2 = sexpr_node(node, "device/vif/script");
+ if ((tmp != NULL) || (strstr(tmp2, "bridge"))) {
virBufferVSprintf(&buf, " <interface type='bridge'>\n");
- virBufferVSprintf(&buf, " <source bridge='%s'/>\n",
- tmp);
+ if (tmp != NULL)
+ virBufferVSprintf(&buf, " <source bridge='%s'/>\n",
+ tmp);
tmp = sexpr_node(node, "device/vif/vifname");
if (tmp != NULL)
virBufferVSprintf(&buf, " <target dev='%s'/>\n",
if (tmp != NULL)
virBufferVSprintf(&buf, " <ip address='%s'/>\n",
tmp);
- tmp = sexpr_node(node, "device/vif/script");
- if (tmp != NULL)
+ if (tmp2 != NULL)
virBufferVSprintf(&buf, " <script path='%s'/>\n",
- tmp);
+ tmp2);
virBufferAdd(&buf, " </interface>\n", 17);
} else {
char serial[1000];
- TODO sexpr2string(node->car, serial, 1000);
- virBufferVSprintf(&buf, "<!-- Failed to parse %s -->\n",
+ TODO sexpr2string(node, serial, 1000);
+ virBufferVSprintf(&buf, "<!-- Failed to parse vif: %s -->\n",
serial);
}
* virDomainParseXMLOSDesc:
* @xmldesc: string with the XML description
* @buf: a buffer for the result S-Expr
+ * @bootloader: indocate if a bootloader script was provided
*
* Parse the OS part of the XML description and add it to the S-Expr in buf
* This is a temporary interface as the S-Expr interface
* Returns 0 in case of success, -1 in case of error.
*/
static int
-virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf)
+virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf, int bootloader)
{
xmlNodePtr cur, txt;
const xmlChar *type = NULL;
}
virBufferAdd(buf, "(linux ", 7);
if (kernel == NULL) {
- virXMLError(VIR_ERR_NO_KERNEL, NULL, 0);
- return (-1);
+ if (bootloader == 0) {
+ virXMLError(VIR_ERR_NO_KERNEL, NULL, 0);
+ return (-1);
+ }
+ } else {
+ virBufferVSprintf(buf, "(kernel '%s')", (const char *) kernel);
}
- virBufferVSprintf(buf, "(kernel '%s')", (const char *) kernel);
if (initrd != NULL)
virBufferVSprintf(buf, "(ramdisk '%s')", (const char *) initrd);
if (root == NULL) {
xmlXPathObjectPtr obj = NULL;
xmlXPathContextPtr ctxt = NULL;
int i, res;
+ int bootloader = 0;
if (name != NULL)
*name = NULL;
}
xmlXPathFreeObject(obj);
+ obj = xmlXPathEval(BAD_CAST "string(/domain/bootloader[1])", ctxt);
+ if ((obj != NULL) && (obj->type == XPATH_STRING) &&
+ (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+ virBufferVSprintf(&buf, "(bootloader '%s')", obj->stringval);
+ bootloader = 1;
+ }
+ xmlXPathFreeObject(obj);
+
/* analyze of the os description */
virBufferAdd(&buf, "(image ", 7);
obj = xmlXPathEval(BAD_CAST "/domain/os[1]", ctxt);
virXMLError(VIR_ERR_NO_OS, nam, 0);
goto error;
}
- res = virDomainParseXMLOSDesc(obj->nodesetval->nodeTab[0], &buf);
+ res = virDomainParseXMLOSDesc(obj->nodesetval->nodeTab[0], &buf,
+ bootloader);
if (res != 0) {
goto error;
}