613
!strcmp((const char *)device, "floppy") &&
614
strcmp((const char *)target, "fda") &&
615
strcmp((const char *)target, "fdb")) {
726
STREQ((const char *)device, "floppy") &&
727
STRNEQ((const char *)target, "fda") &&
728
STRNEQ((const char *)target, "fdb")) {
616
729
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
617
730
_("Invalid floppy device name: %s"), target);
622
!strcmp((const char *)device, "cdrom") &&
623
strcmp((const char *)target, "hdc")) {
735
STREQ((const char *)device, "cdrom") &&
736
STRNEQ((const char *)target, "hdc")) {
624
737
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
625
738
_("Invalid cdrom device name: %s"), target);
630
!strcmp((const char *)device, "cdrom"))
743
STREQ((const char *)device, "cdrom"))
631
744
disk->readonly = 1;
633
if ((!device || !strcmp((const char *)device, "disk")) &&
634
strcmp((const char *)target, "hda") &&
635
strcmp((const char *)target, "hdb") &&
636
strcmp((const char *)target, "hdc") &&
637
strcmp((const char *)target, "hdd")) {
746
if ((!device || STREQ((const char *)device, "disk")) &&
747
!STRPREFIX((const char *)target, "hd") &&
748
!STRPREFIX((const char *)target, "sd") &&
749
!STRPREFIX((const char *)target, "vd") &&
750
!STRPREFIX((const char *)target, "xvd")) {
638
751
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
639
752
_("Invalid harddisk device name: %s"), target);
926
1078
xmlFree(address);
1081
/* NIC model (see -net nic,model=?). We only check that it looks
1082
* reasonable, not that it is a supported NIC type. FWIW kvm
1083
* supports these types as of April 2008:
1084
* i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio
1086
if (model != NULL) {
1089
len = xmlStrlen (model);
1090
if (len >= QEMUD_MODEL_MAX_LEN) {
1091
qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG,
1092
_("Model name '%s' is too long"), model);
1095
for (i = 0; i < len; ++i) {
1096
int char_ok = c_isalnum(model[i]) || model[i] == '_';
1098
qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG, "%s",
1099
_("Model name contains invalid characters"));
1103
strncpy (net->model, (const char*) model, len);
1104
net->model[len] = '\0';
1109
net->model[0] = '\0';
1125
/* Parse the XML definition for a character device
1126
* @param net pre-allocated & zero'd net record
1127
* @param node XML nodeset to parse for net definition
1128
* @return 0 on success, -1 on failure
1130
* The XML we're dealing with looks like
1132
* <serial type="pty">
1133
* <source path="/dev/pts/3"/>
1134
* <target port="1"/>
1137
* <serial type="dev">
1138
* <source path="/dev/ttyS0"/>
1139
* <target port="1"/>
1142
* <serial type="tcp">
1143
* <source mode="connect" host="0.0.0.0" service="2445"/>
1144
* <target port="1"/>
1147
* <serial type="tcp">
1148
* <source mode="bind" host="0.0.0.0" service="2445"/>
1149
* <target port="1"/>
1152
* <serial type="udp">
1153
* <source mode="bind" host="0.0.0.0" service="2445"/>
1154
* <source mode="connect" host="0.0.0.0" service="2445"/>
1155
* <target port="1"/>
1158
* <serial type="unix">
1159
* <source mode="bind" path="/tmp/foo"/>
1160
* <target port="1"/>
1164
static int qemudParseCharXML(virConnectPtr conn,
1165
struct qemud_vm_chr_def *chr,
1169
xmlChar *type = NULL;
1170
xmlChar *bindHost = NULL;
1171
xmlChar *bindService = NULL;
1172
xmlChar *connectHost = NULL;
1173
xmlChar *connectService = NULL;
1174
xmlChar *path = NULL;
1175
xmlChar *mode = NULL;
1176
xmlChar *protocol = NULL;
1179
chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
1180
type = xmlGetProp(node, BAD_CAST "type");
1182
if (xmlStrEqual(type, BAD_CAST "null"))
1183
chr->srcType = QEMUD_CHR_SRC_TYPE_NULL;
1184
else if (xmlStrEqual(type, BAD_CAST "vc"))
1185
chr->srcType = QEMUD_CHR_SRC_TYPE_VC;
1186
else if (xmlStrEqual(type, BAD_CAST "pty"))
1187
chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
1188
else if (xmlStrEqual(type, BAD_CAST "dev"))
1189
chr->srcType = QEMUD_CHR_SRC_TYPE_DEV;
1190
else if (xmlStrEqual(type, BAD_CAST "file"))
1191
chr->srcType = QEMUD_CHR_SRC_TYPE_FILE;
1192
else if (xmlStrEqual(type, BAD_CAST "pipe"))
1193
chr->srcType = QEMUD_CHR_SRC_TYPE_PIPE;
1194
else if (xmlStrEqual(type, BAD_CAST "stdio"))
1195
chr->srcType = QEMUD_CHR_SRC_TYPE_STDIO;
1196
else if (xmlStrEqual(type, BAD_CAST "udp"))
1197
chr->srcType = QEMUD_CHR_SRC_TYPE_UDP;
1198
else if (xmlStrEqual(type, BAD_CAST "tcp"))
1199
chr->srcType = QEMUD_CHR_SRC_TYPE_TCP;
1200
else if (xmlStrEqual(type, BAD_CAST "unix"))
1201
chr->srcType = QEMUD_CHR_SRC_TYPE_UNIX;
1203
chr->srcType = QEMUD_CHR_SRC_TYPE_NULL;
1206
cur = node->children;
1207
while (cur != NULL) {
1208
if (cur->type == XML_ELEMENT_NODE) {
1209
if (xmlStrEqual(cur->name, BAD_CAST "source")) {
1211
mode = xmlGetProp(cur, BAD_CAST "mode");
1213
switch (chr->srcType) {
1214
case QEMUD_CHR_SRC_TYPE_PTY:
1215
case QEMUD_CHR_SRC_TYPE_DEV:
1216
case QEMUD_CHR_SRC_TYPE_FILE:
1217
case QEMUD_CHR_SRC_TYPE_PIPE:
1218
case QEMUD_CHR_SRC_TYPE_UNIX:
1220
path = xmlGetProp(cur, BAD_CAST "path");
1224
case QEMUD_CHR_SRC_TYPE_UDP:
1225
case QEMUD_CHR_SRC_TYPE_TCP:
1227
STREQ((const char *)mode, "connect")) {
1229
if (connectHost == NULL)
1230
connectHost = xmlGetProp(cur, BAD_CAST "host");
1231
if (connectService == NULL)
1232
connectService = xmlGetProp(cur, BAD_CAST "service");
1234
if (bindHost == NULL)
1235
bindHost = xmlGetProp(cur, BAD_CAST "host");
1236
if (bindService == NULL)
1237
bindService = xmlGetProp(cur, BAD_CAST "service");
1240
if (chr->srcType == QEMUD_CHR_SRC_TYPE_UDP) {
1245
} else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) {
1246
if (protocol == NULL)
1247
protocol = xmlGetProp(cur, BAD_CAST "type");
1254
chr->dstPort = portNum;
1256
switch (chr->srcType) {
1257
case QEMUD_CHR_SRC_TYPE_NULL:
1261
case QEMUD_CHR_SRC_TYPE_VC:
1264
case QEMUD_CHR_SRC_TYPE_PTY:
1265
/* @path attribute is an output only property - pty is auto-allocted */
1268
case QEMUD_CHR_SRC_TYPE_DEV:
1269
case QEMUD_CHR_SRC_TYPE_FILE:
1270
case QEMUD_CHR_SRC_TYPE_PIPE:
1272
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1273
"%s", _("Missing source path attribute for char device"));
1277
strncpy(chr->srcData.file.path, (const char *)path,
1278
sizeof(chr->srcData.file.path));
1279
NUL_TERMINATE(chr->srcData.file.path);
1282
case QEMUD_CHR_SRC_TYPE_STDIO:
1286
case QEMUD_CHR_SRC_TYPE_TCP:
1288
STREQ((const char *)mode, "connect")) {
1289
if (connectHost == NULL) {
1290
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1291
"%s", _("Missing source host attribute for char device"));
1294
if (connectService == NULL) {
1295
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1296
"%s", _("Missing source service attribute for char device"));
1300
strncpy(chr->srcData.tcp.host, (const char *)connectHost,
1301
sizeof(chr->srcData.tcp.host));
1302
NUL_TERMINATE(chr->srcData.tcp.host);
1303
strncpy(chr->srcData.tcp.service, (const char *)connectService,
1304
sizeof(chr->srcData.tcp.service));
1305
NUL_TERMINATE(chr->srcData.tcp.service);
1307
chr->srcData.tcp.listen = 0;
1309
if (bindHost == NULL) {
1310
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1311
"%s", _("Missing source host attribute for char device"));
1314
if (bindService == NULL) {
1315
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1316
"%s", _("Missing source service attribute for char device"));
1320
strncpy(chr->srcData.tcp.host, (const char *)bindHost,
1321
sizeof(chr->srcData.tcp.host));
1322
NUL_TERMINATE(chr->srcData.tcp.host);
1323
strncpy(chr->srcData.tcp.service, (const char *)bindService,
1324
sizeof(chr->srcData.tcp.service));
1325
NUL_TERMINATE(chr->srcData.tcp.service);
1327
chr->srcData.tcp.listen = 1;
1329
if (protocol != NULL &&
1330
STREQ((const char *)protocol, "telnet"))
1331
chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET;
1333
chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_RAW;
1336
case QEMUD_CHR_SRC_TYPE_UDP:
1337
if (connectService == NULL) {
1338
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1339
"%s", _("Missing source service attribute for char device"));
1343
if (connectHost != NULL) {
1344
strncpy(chr->srcData.udp.connectHost, (const char *)connectHost,
1345
sizeof(chr->srcData.udp.connectHost));
1346
NUL_TERMINATE(chr->srcData.udp.connectHost);
1348
strncpy(chr->srcData.udp.connectService, (const char *)connectService,
1349
sizeof(chr->srcData.udp.connectService));
1350
NUL_TERMINATE(chr->srcData.udp.connectService);
1352
if (bindHost != NULL) {
1353
strncpy(chr->srcData.udp.bindHost, (const char *)bindHost,
1354
sizeof(chr->srcData.udp.bindHost));
1355
NUL_TERMINATE(chr->srcData.udp.bindHost);
1357
if (bindService != NULL) {
1358
strncpy(chr->srcData.udp.bindService, (const char *)bindService,
1359
sizeof(chr->srcData.udp.bindService));
1360
NUL_TERMINATE(chr->srcData.udp.bindService);
1364
case QEMUD_CHR_SRC_TYPE_UNIX:
1366
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1367
"%s", _("Missing source path attribute for char device"));
1372
STRNEQ((const char *)mode, "connect"))
1373
chr->srcData.nix.listen = 1;
1375
chr->srcData.nix.listen = 0;
1377
strncpy(chr->srcData.nix.path, (const char *)path,
1378
sizeof(chr->srcData.nix.path));
1379
NUL_TERMINATE(chr->srcData.nix.path);
1390
xmlFree(bindService);
1391
xmlFree(connectHost);
1392
xmlFree(connectService);
1399
static int qemudParseCharXMLDevices(virConnectPtr conn,
1400
xmlXPathContextPtr ctxt,
1402
unsigned int *ndevs,
1403
struct qemud_vm_chr_def **devs)
1405
xmlXPathObjectPtr obj;
1408
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
1409
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
1410
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
1411
struct qemud_vm_chr_def *prev = *devs;
1412
if (ndevs == NULL &&
1413
obj->nodesetval->nodeNr > 1) {
1414
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1415
"%s", _("too many character devices"));
1419
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
1420
struct qemud_vm_chr_def *chr;
1421
if (VIR_ALLOC(chr) < 0) {
1422
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1424
_("failed to allocate space for char device"));
1428
if (qemudParseCharXML(conn, chr, i, obj->nodesetval->nodeTab[i]) < 0) {
1447
xmlXPathFreeObject(obj);
948
1452
/* Parse the XML definition for a network interface */
949
1453
static int qemudParseInputXML(virConnectPtr conn,
1454
const struct qemud_vm_def *vm,
950
1455
struct qemud_vm_input_def *input,
951
1456
xmlNodePtr node) {
952
1457
xmlChar *type = NULL;
976
if (!strcmp((const char*)bus, "ps2")) { /* Only allow mouse */
977
if (input->type == QEMU_INPUT_TYPE_TABLET) {
1481
if (STREQ(vm->os.type, "hvm")) {
1482
if (STREQ((const char*)bus, "ps2")) { /* Only allow mouse */
1483
if (input->type != QEMU_INPUT_TYPE_MOUSE) {
1484
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1485
_("ps2 bus does not support %s input device"),
1489
input->bus = QEMU_INPUT_BUS_PS2;
1490
} else if (STREQ((const char *)bus, "usb")) { /* Allow mouse & tablet */
1491
input->bus = QEMU_INPUT_BUS_USB;
978
1493
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
979
_("ps2 bus does not support %s input device"),
1494
_("unsupported input bus %s"), (const char*)bus);
983
input->bus = QEMU_INPUT_BUS_PS2;
984
} else if (!strcmp((const char *)bus, "usb")) { /* Allow mouse & keyboard */
985
input->bus = QEMU_INPUT_BUS_USB;
987
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
988
_("unsupported input bus %s"), (const char*)bus);
1498
if (STREQ((const char *)bus, "xen")) { /* Allow mouse only */
1499
input->bus = QEMU_INPUT_BUS_XEN;
1500
if (input->type != QEMU_INPUT_TYPE_MOUSE) {
1501
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1502
_("xen bus does not support %s input device"),
1507
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1508
_("unsupported input bus %s"), (const char*)bus);
992
if (input->type == QEMU_INPUT_TYPE_MOUSE)
993
input->bus = QEMU_INPUT_BUS_PS2;
995
input->bus = QEMU_INPUT_BUS_USB;
1513
if (STREQ(vm->os.type, "hvm")) {
1514
if (input->type == QEMU_INPUT_TYPE_MOUSE)
1515
input->bus = QEMU_INPUT_BUS_PS2;
1517
input->bus = QEMU_INPUT_BUS_USB;
1519
input->bus = QEMU_INPUT_BUS_XEN;
1535
static int qemudDiskCompare(const void *aptr, const void *bptr) {
1536
struct qemud_vm_disk_def *a = (struct qemud_vm_disk_def *) aptr;
1537
struct qemud_vm_disk_def *b = (struct qemud_vm_disk_def *) bptr;
1538
if (a->bus == b->bus)
1539
return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst);
1541
return a->bus - b->bus;
1544
static const char *qemudBusIdToName(int busId, int qemuIF) {
1545
const char *busnames[] = { "ide",
1546
(qemuIF ? "floppy" : "fdc"),
1550
verify_true(ARRAY_CARDINALITY(busnames) == QEMUD_DISK_BUS_LAST);
1552
return busnames[busId];
1555
/* Sound device helper functions */
1556
static int qemudSoundModelFromString(const char *model) {
1557
if (STREQ(model, "sb16")) {
1558
return QEMU_SOUND_SB16;
1559
} else if (STREQ(model, "es1370")) {
1560
return QEMU_SOUND_ES1370;
1561
} else if (STREQ(model, "pcspk")) {
1562
return QEMU_SOUND_PCSPK;
1568
static const char *qemudSoundModelToString(const int model) {
1570
if (model == QEMU_SOUND_SB16) {
1572
} else if (model == QEMU_SOUND_ES1370) {
1574
} else if (model == QEMU_SOUND_PCSPK) {
1582
static int qemudParseSoundXML(virConnectPtr conn,
1583
struct qemud_vm_sound_def *sound,
1584
const xmlNodePtr node) {
1587
xmlChar *model = NULL;
1588
model = xmlGetProp(node, BAD_CAST "model");
1591
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1592
"%s", _("missing sound model"));
1595
if ((sound->model = qemudSoundModelFromString((char *) model)) < 0) {
1596
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1597
_("invalid sound model '%s'"), (char *) model);
1016
1608
* Parses a libvirt XML definition of a guest, and populates the
1264
1890
xmlXPathFreeObject(obj);
1267
obj = xmlXPathEval(BAD_CAST "string(/domain/os/kernel[1])", ctxt);
1268
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
1269
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
1270
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
1271
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1272
"%s", _("kernel path too long"));
1275
strcpy(def->os.kernel, (const char *)obj->stringval);
1277
xmlXPathFreeObject(obj);
1280
obj = xmlXPathEval(BAD_CAST "string(/domain/os/initrd[1])", ctxt);
1281
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
1282
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
1283
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
1284
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1285
"%s", _("initrd path too long"));
1288
strcpy(def->os.initrd, (const char *)obj->stringval);
1290
xmlXPathFreeObject(obj);
1293
obj = xmlXPathEval(BAD_CAST "string(/domain/os/cmdline[1])", ctxt);
1294
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
1295
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
1296
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
1297
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1298
"%s", _("cmdline arguments too long"));
1301
strcpy(def->os.cmdline, (const char *)obj->stringval);
1303
xmlXPathFreeObject(obj);
1306
/* analysis of the disk devices */
1307
obj = xmlXPathEval(BAD_CAST "/domain/os/boot", ctxt);
1308
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
1309
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
1310
for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
1311
if (!(prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev")))
1313
if (!strcmp((char *)prop, "hd")) {
1314
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
1315
} else if (!strcmp((char *)prop, "fd")) {
1316
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
1317
} else if (!strcmp((char *)prop, "cdrom")) {
1318
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
1319
} else if (!strcmp((char *)prop, "network")) {
1320
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
1322
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1323
_("unknown boot device \'%s\'"), (char*)prop);
1330
xmlXPathFreeObject(obj);
1331
if (def->os.nBootDevs == 0) {
1332
def->os.nBootDevs = 1;
1333
def->os.bootDevs[0] = QEMUD_BOOT_DISK;
1893
if (!def->os.bootloader[0]) {
1894
obj = xmlXPathEval(BAD_CAST "string(/domain/os/kernel[1])", ctxt);
1895
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
1896
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
1897
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
1898
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1899
"%s", _("kernel path too long"));
1902
strcpy(def->os.kernel, (const char *)obj->stringval);
1904
xmlXPathFreeObject(obj);
1907
obj = xmlXPathEval(BAD_CAST "string(/domain/os/initrd[1])", ctxt);
1908
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
1909
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
1910
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
1911
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1912
"%s", _("initrd path too long"));
1915
strcpy(def->os.initrd, (const char *)obj->stringval);
1917
xmlXPathFreeObject(obj);
1920
obj = xmlXPathEval(BAD_CAST "string(/domain/os/cmdline[1])", ctxt);
1921
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
1922
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
1923
if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
1924
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1925
"%s", _("cmdline arguments too long"));
1928
strcpy(def->os.cmdline, (const char *)obj->stringval);
1930
xmlXPathFreeObject(obj);
1933
/* analysis of the disk devices */
1934
obj = xmlXPathEval(BAD_CAST "/domain/os/boot", ctxt);
1935
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
1936
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
1937
for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
1938
if (!(prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev")))
1940
if (STREQ((char *)prop, "hd")) {
1941
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
1942
} else if (STREQ((char *)prop, "fd")) {
1943
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
1944
} else if (STREQ((char *)prop, "cdrom")) {
1945
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
1946
} else if (STREQ((char *)prop, "network")) {
1947
def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
1949
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1950
_("unknown boot device \'%s\'"), (char*)prop);
1957
xmlXPathFreeObject(obj);
1958
if (def->os.nBootDevs == 0) {
1959
def->os.nBootDevs = 1;
1960
def->os.bootDevs[0] = QEMUD_BOOT_DISK;
1337
1964
obj = xmlXPathEval(BAD_CAST "string(/domain/devices/emulator[1])", ctxt);
1338
1965
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
1339
1966
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
1340
const char *type = (def->virtType == QEMUD_VIRT_QEMU ? "qemu" :
1341
def->virtType == QEMUD_VIRT_KQEMU ? "kqemu":
1967
const char *type = qemudVirtTypeToString(def->virtType);
1969
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1970
"%s", _("unknown virt type"));
1343
1973
const char *emulator = virCapabilitiesDefaultGuestEmulator(driver->caps,
1400
2030
obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
1401
2031
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
1402
2032
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
1403
struct qemud_vm_disk_def *prev = NULL;
1404
2033
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
1405
struct qemud_vm_disk_def *disk = calloc(1, sizeof(*disk));
2034
struct qemud_vm_disk_def *disk;
2035
if (VIR_ALLOC(disk) < 0) {
1407
2036
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1408
2037
"%s", _("failed to allocate space for disk string"));
1411
2040
if (qemudParseDiskXML(conn, disk, obj->nodesetval->nodeTab[i]) < 0) {
1418
2047
def->disks = disk;
2049
struct qemud_vm_disk_def *ptr = def->disks;
2051
if (!ptr->next || qemudDiskCompare(disk, ptr->next) < 0) {
2052
disk->next = ptr->next;
1425
2061
xmlXPathFreeObject(obj);
2064
/* analysis of the character devices */
2065
if (qemudParseCharXMLDevices(conn, ctxt,
2066
"/domain/devices/parallel",
2068
&def->parallels) < 0)
2070
if (qemudParseCharXMLDevices(conn, ctxt,
2071
"/domain/devices/serial",
2077
* If no serial devices were listed, then look for console
2078
* devices which is the legacy syntax for the same thing
2080
if (def->nserials == 0) {
2081
obj = xmlXPathEval(BAD_CAST "/domain/devices/console", ctxt);
2082
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
2083
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
2084
struct qemud_vm_chr_def *chr;
2085
if (VIR_ALLOC(chr) < 0) {
2086
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
2088
_("failed to allocate space for char device"));
2092
if (qemudParseCharXML(conn, chr, 0, obj->nodesetval->nodeTab[0]) < 0) {
2099
xmlXPathFreeObject(obj);
1428
2103
/* analysis of the network devices */
1611
2329
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1612
2330
"%s", _("failed to allocate space for tapfds string"));
1615
2333
if (tapfd != -1)
2338
static int qemudBuildCommandLineChrDevStr(struct qemud_vm_chr_def *dev,
2342
switch (dev->srcType) {
2343
case QEMUD_CHR_SRC_TYPE_NULL:
2344
strncpy(buf, "null", buflen);
2345
buf[buflen-1] = '\0';
2348
case QEMUD_CHR_SRC_TYPE_VC:
2349
strncpy(buf, "vc", buflen);
2350
buf[buflen-1] = '\0';
2353
case QEMUD_CHR_SRC_TYPE_PTY:
2354
strncpy(buf, "pty", buflen);
2355
buf[buflen-1] = '\0';
2358
case QEMUD_CHR_SRC_TYPE_DEV:
2359
if (snprintf(buf, buflen, "%s",
2360
dev->srcData.file.path) >= buflen)
2364
case QEMUD_CHR_SRC_TYPE_FILE:
2365
if (snprintf(buf, buflen, "file:%s",
2366
dev->srcData.file.path) >= buflen)
2370
case QEMUD_CHR_SRC_TYPE_PIPE:
2371
if (snprintf(buf, buflen, "pipe:%s",
2372
dev->srcData.file.path) >= buflen)
2376
case QEMUD_CHR_SRC_TYPE_STDIO:
2377
strncpy(buf, "stdio", buflen);
2378
buf[buflen-1] = '\0';
2381
case QEMUD_CHR_SRC_TYPE_UDP:
2382
if (snprintf(buf, buflen, "udp:%s:%s@%s:%s",
2383
dev->srcData.udp.connectHost,
2384
dev->srcData.udp.connectService,
2385
dev->srcData.udp.bindHost,
2386
dev->srcData.udp.bindService) >= buflen)
2390
case QEMUD_CHR_SRC_TYPE_TCP:
2391
if (snprintf(buf, buflen, "%s:%s:%s%s",
2392
dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET ? "telnet" : "tcp",
2393
dev->srcData.tcp.host,
2394
dev->srcData.tcp.service,
2395
dev->srcData.tcp.listen ? ",listen" : "") >= buflen)
2399
case QEMUD_CHR_SRC_TYPE_UNIX:
2400
if (snprintf(buf, buflen, "unix:%s%s",
2401
dev->srcData.nix.path,
2402
dev->srcData.nix.listen ? ",listen" : "") >= buflen)
1621
2411
* Constructs a argv suitable for launching qemu with config defined
1622
2412
* for a given virtual machine.
1670
2452
* 3. The qemu binary has the -no-kqemu flag
1672
2454
if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
1673
!strcmp(ut.machine, vm->def->os.arch) &&
2455
STREQ(ut.machine, vm->def->os.arch) &&
1674
2456
vm->def->virtType == QEMUD_VIRT_QEMU)
1675
2457
disableKQEMU = 1;
1677
len = 1 + /* qemu */
1678
2 + /* machine type */
1679
disableKQEMU + /* Disable kqemu */
1680
2 * vm->def->ndisks + /* disks*/
1681
(vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */
1683
2 * vm->def->ninputs + /* input devices */
1686
2 + /* boot device */
1688
(vm->def->localtime ? 1 : 0) + /* localtime */
1689
(vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
1690
vm->def->noReboot ? 1 : 0) + /* no-reboot */
1691
(vm->def->features & QEMUD_FEATURE_ACPI ? 0 : 1) + /* acpi */
1692
(vm->def->os.kernel[0] ? 2 : 0) + /* kernel */
1693
(vm->def->os.initrd[0] ? 2 : 0) + /* initrd */
1694
(vm->def->os.cmdline[0] ? 2 : 0) + /* cmdline */
1695
(vm->def->graphicsType == QEMUD_GRAPHICS_VNC ? 2 :
1696
(vm->def->graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)) + /* graphics */
1697
(vm->migrateFrom[0] ? 3 : 0); /* migrateFrom */
2459
#define ADD_ARG_SPACE \
2461
if (qargc == qarga) { \
2463
if (VIR_REALLOC_N(qargv, qarga) < 0) \
2468
#define ADD_ARG(thisarg) \
2471
qargv[qargc++] = thisarg; \
2474
#define ADD_ARG_LIT(thisarg) \
2477
if ((qargv[qargc++] = strdup(thisarg)) == NULL) \
1699
2481
snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
1700
2482
snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus);
1702
if (!(*argv = malloc(sizeof(**argv) * (len+1))))
1704
if (!((*argv)[++n] = strdup(vm->def->os.binary)))
1706
if (!((*argv)[++n] = strdup("-M")))
1708
if (!((*argv)[++n] = strdup(vm->def->os.machine)))
1711
if (!((*argv)[++n] = strdup("-no-kqemu")))
2485
ADD_ARG_LIT(vm->def->os.binary);
2488
ADD_ARG_LIT(vm->def->os.machine);
2490
ADD_ARG_LIT("-no-kqemu");
2492
ADD_ARG_LIT(memory);
2493
ADD_ARG_LIT("-smp");
2496
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
2497
ADD_ARG_LIT("-name");
2498
ADD_ARG_LIT(vm->def->name);
1714
if (!((*argv)[++n] = strdup("-m")))
1716
if (!((*argv)[++n] = strdup(memory)))
1718
if (!((*argv)[++n] = strdup("-smp")))
1720
if (!((*argv)[++n] = strdup(vcpus)))
1724
2501
* NB, -nographic *MUST* come before any serial, or monitor
1725
2502
* or parallel port flags due to QEMU craziness, where it
1727
2504
* if you ask for nographic. So we have to make sure we override
1728
2505
* these defaults ourselves...
1730
if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
1731
if (!((*argv)[++n] = strdup("-nographic")))
1735
if (!((*argv)[++n] = strdup("-monitor")))
1737
if (!((*argv)[++n] = strdup("pty")))
1740
if (vm->def->localtime) {
1741
if (!((*argv)[++n] = strdup("-localtime")))
1745
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
1746
vm->def->noReboot) {
1747
if (!((*argv)[++n] = strdup("-no-reboot")))
1751
if (!(vm->def->features & QEMUD_FEATURE_ACPI)) {
1752
if (!((*argv)[++n] = strdup("-no-acpi")))
1756
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
1757
switch (vm->def->os.bootDevs[i]) {
1758
case QEMUD_BOOT_CDROM:
1761
case QEMUD_BOOT_FLOPPY:
1764
case QEMUD_BOOT_DISK:
1767
case QEMUD_BOOT_NET:
1775
boot[vm->def->os.nBootDevs] = '\0';
1776
if (!((*argv)[++n] = strdup("-boot")))
1778
if (!((*argv)[++n] = strdup(boot)))
1781
if (vm->def->os.kernel[0]) {
1782
if (!((*argv)[++n] = strdup("-kernel")))
1784
if (!((*argv)[++n] = strdup(vm->def->os.kernel)))
1787
if (vm->def->os.initrd[0]) {
1788
if (!((*argv)[++n] = strdup("-initrd")))
1790
if (!((*argv)[++n] = strdup(vm->def->os.initrd)))
1793
if (vm->def->os.cmdline[0]) {
1794
if (!((*argv)[++n] = strdup("-append")))
1796
if (!((*argv)[++n] = strdup(vm->def->os.cmdline)))
1802
char file[PATH_MAX];
1803
if (!strcmp(disk->dst, "hdc") &&
1804
disk->device == QEMUD_DISK_CDROM) {
1806
snprintf(dev, NAME_MAX, "-%s", "cdrom");
1808
/* Don't put anything on the cmdline for an empty cdrom*/
1813
snprintf(dev, NAME_MAX, "-%s", disk->dst);
1814
snprintf(file, PATH_MAX, "%s", disk->src);
1816
if (!((*argv)[++n] = strdup(dev)))
1818
if (!((*argv)[++n] = strdup(file)))
2507
if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE)
2508
ADD_ARG_LIT("-nographic");
2510
ADD_ARG_LIT("-monitor");
2513
if (vm->def->localtime)
2514
ADD_ARG_LIT("-localtime");
2516
if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
2518
ADD_ARG_LIT("-no-reboot");
2520
if (!(vm->def->features & QEMUD_FEATURE_ACPI))
2521
ADD_ARG_LIT("-no-acpi");
2523
if (!vm->def->os.bootloader[0]) {
2524
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
2525
switch (vm->def->os.bootDevs[i]) {
2526
case QEMUD_BOOT_CDROM:
2529
case QEMUD_BOOT_FLOPPY:
2532
case QEMUD_BOOT_DISK:
2535
case QEMUD_BOOT_NET:
2543
boot[vm->def->os.nBootDevs] = '\0';
2544
ADD_ARG_LIT("-boot");
2547
if (vm->def->os.kernel[0]) {
2548
ADD_ARG_LIT("-kernel");
2549
ADD_ARG_LIT(vm->def->os.kernel);
2551
if (vm->def->os.initrd[0]) {
2552
ADD_ARG_LIT("-initrd");
2553
ADD_ARG_LIT(vm->def->os.initrd);
2555
if (vm->def->os.cmdline[0]) {
2556
ADD_ARG_LIT("-append");
2557
ADD_ARG_LIT(vm->def->os.cmdline);
2560
ADD_ARG_LIT("-bootloader");
2561
ADD_ARG_LIT(vm->def->os.bootloader);
2564
/* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
2565
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) {
2566
int bootCD = 0, bootFloppy = 0, bootDisk = 0;
2568
/* If QEMU supports boot=on for -drive param... */
2569
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_BOOT) {
2570
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
2571
switch (vm->def->os.bootDevs[i]) {
2572
case QEMUD_BOOT_CDROM:
2575
case QEMUD_BOOT_FLOPPY:
2578
case QEMUD_BOOT_DISK:
2587
const char *media = NULL;
2589
int idx = virDiskNameToIndex(disk->dst);
2592
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
2593
_("unsupported disk type '%s'"), disk->dst);
2597
if (disk->device == QEMUD_DISK_CDROM)
2598
media = "media=cdrom,";
2600
switch (disk->device) {
2601
case QEMUD_DISK_CDROM:
2605
case QEMUD_DISK_FLOPPY:
2606
bootable = bootFloppy;
2609
case QEMUD_DISK_DISK:
2610
bootable = bootDisk;
2615
snprintf(opt, PATH_MAX, "file=%s,if=%s,%sindex=%d%s",
2616
disk->src, qemudBusIdToName(disk->bus, 1),
2619
bootable ? ",boot=on" : "");
2621
ADD_ARG_LIT("-drive");
2628
char file[PATH_MAX];
2630
if (STREQ(disk->dst, "hdc") &&
2631
disk->device == QEMUD_DISK_CDROM) {
2633
snprintf(dev, NAME_MAX, "-%s", "cdrom");
2639
if (STRPREFIX(disk->dst, "hd") ||
2640
STRPREFIX(disk->dst, "fd")) {
2641
snprintf(dev, NAME_MAX, "-%s", disk->dst);
2643
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
2644
_("unsupported disk type '%s'"), disk->dst);
2649
snprintf(file, PATH_MAX, "%s", disk->src);
1825
if (!((*argv)[++n] = strdup("-net")))
1827
if (!((*argv)[++n] = strdup("none")))
2659
ADD_ARG_LIT("-net");
2660
ADD_ARG_LIT("none");
1834
if (snprintf(nic, sizeof(nic), "nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d",
2666
if (snprintf(nic, sizeof(nic),
2667
"nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s",
1835
2668
net->mac[0], net->mac[1],
1836
2669
net->mac[2], net->mac[3],
1837
2670
net->mac[4], net->mac[5],
1838
vlan) >= sizeof(nic))
2672
(net->model[0] ? ",model=" : ""), net->model) >= sizeof(nic))
1841
if (!((*argv)[++n] = strdup("-net")))
1843
if (!((*argv)[++n] = strdup(nic)))
1846
if (!((*argv)[++n] = strdup("-net")))
2675
ADD_ARG_LIT("-net");
2677
ADD_ARG_LIT("-net");
1849
2679
switch (net->type) {
1850
2680
case QEMUD_NET_NETWORK:
1851
2681
case QEMUD_NET_BRIDGE:
1852
if (!((*argv)[++n] = qemudNetworkIfaceConnect(conn, driver, vm, net, vlan)))
2683
char *tap = qemudNetworkIfaceConnect(conn, driver, vm, net, vlan);
1856
2690
case QEMUD_NET_ETHERNET:
3731
static int qemudGenerateXMLChar(virBufferPtr buf,
3732
const struct qemud_vm_chr_def *dev,
3735
const char *const types[] = {
3747
verify_true(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);
3749
/* Compat with legacy <console tty='/dev/pts/5'/> syntax */
3750
if (STREQ(type, "console") &&
3751
dev->srcType == QEMUD_CHR_SRC_TYPE_PTY &&
3752
dev->srcData.file.path[0] != '\0') {
3753
virBufferVSprintf(buf, " <%s type='%s' tty='%s'>\n",
3754
type, types[dev->srcType],
3755
dev->srcData.file.path);
3757
virBufferVSprintf(buf, " <%s type='%s'>\n",
3758
type, types[dev->srcType]);
3761
switch (dev->srcType) {
3762
case QEMUD_CHR_SRC_TYPE_NULL:
3763
case QEMUD_CHR_SRC_TYPE_VC:
3764
case QEMUD_CHR_SRC_TYPE_STDIO:
3768
case QEMUD_CHR_SRC_TYPE_PTY:
3769
case QEMUD_CHR_SRC_TYPE_DEV:
3770
case QEMUD_CHR_SRC_TYPE_FILE:
3771
case QEMUD_CHR_SRC_TYPE_PIPE:
3772
if (dev->srcType != QEMUD_CHR_SRC_TYPE_PTY ||
3773
dev->srcData.file.path[0]) {
3774
virBufferVSprintf(buf, " <source path='%s'/>\n",
3775
dev->srcData.file.path);
3779
case QEMUD_CHR_SRC_TYPE_UDP:
3780
if (dev->srcData.udp.bindService[0] != '\0' &&
3781
dev->srcData.udp.bindHost[0] != '\0') {
3782
virBufferVSprintf(buf, " <source mode='bind' host='%s' service='%s'/>\n",
3783
dev->srcData.udp.bindHost,
3784
dev->srcData.udp.bindService);
3785
} else if (dev->srcData.udp.bindHost[0] !='\0') {
3786
virBufferVSprintf(buf, " <source mode='bind' host='%s'/>\n",
3787
dev->srcData.udp.bindHost);
3788
} else if (dev->srcData.udp.bindService[0] != '\0') {
3789
virBufferVSprintf(buf, " <source mode='bind' service='%s'/>\n",
3790
dev->srcData.udp.bindService);
3793
if (dev->srcData.udp.connectService[0] != '\0' &&
3794
dev->srcData.udp.connectHost[0] != '\0') {
3795
virBufferVSprintf(buf, " <source mode='connect' host='%s' service='%s'/>\n",
3796
dev->srcData.udp.connectHost,
3797
dev->srcData.udp.connectService);
3798
} else if (dev->srcData.udp.connectHost[0] != '\0') {
3799
virBufferVSprintf(buf, " <source mode='connect' host='%s'/>\n",
3800
dev->srcData.udp.connectHost);
3801
} else if (dev->srcData.udp.connectService[0] != '\0') {
3802
virBufferVSprintf(buf, " <source mode='connect' service='%s'/>\n",
3803
dev->srcData.udp.connectService);
3807
case QEMUD_CHR_SRC_TYPE_TCP:
3808
virBufferVSprintf(buf, " <source mode='%s' host='%s' service='%s'/>\n",
3809
dev->srcData.tcp.listen ? "bind" : "connect",
3810
dev->srcData.tcp.host,
3811
dev->srcData.tcp.service);
3812
virBufferVSprintf(buf, " <protocol type='%s'/>\n",
3813
dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET
3814
? "telnet" : "raw");
3817
case QEMUD_CHR_SRC_TYPE_UNIX:
3818
virBufferVSprintf(buf, " <source mode='%s' path='%s'/>\n",
3819
dev->srcData.nix.listen ? "bind" : "connect",
3820
dev->srcData.nix.path);
3824
virBufferVSprintf(buf, " <target port='%d'/>\n",
3827
virBufferVSprintf(buf, " </%s>\n",
2841
3834
/* Generate an XML document describing the guest's configuration */
2842
3835
char *qemudGenerateXML(virConnectPtr conn,
2843
3836
struct qemud_driver *driver ATTRIBUTE_UNUSED,
2844
3837
struct qemud_vm *vm,
2845
3838
struct qemud_vm_def *def,
2847
virBufferPtr buf = 0;
3840
virBuffer buf = VIR_BUFFER_INITIALIZER;
2848
3841
unsigned char *uuid;
2849
3842
char uuidstr[VIR_UUID_STRING_BUFLEN];
2850
struct qemud_vm_disk_def *disk;
2851
struct qemud_vm_net_def *net;
2852
struct qemud_vm_input_def *input;
2853
const char *type = NULL;
2856
buf = virBufferNew (QEMUD_MAX_XML_LEN);
2860
switch (def->virtType) {
2861
case QEMUD_VIRT_QEMU:
2864
case QEMUD_VIRT_KQEMU:
2867
case QEMUD_VIRT_KVM:
3843
const struct qemud_vm_disk_def *disk;
3844
const struct qemud_vm_net_def *net;
3845
const struct qemud_vm_input_def *input;
3846
const struct qemud_vm_sound_def *sound;
3847
const struct qemud_vm_chr_def *chr;
3848
const char *type = NULL, *tmp;
3851
if (!(type = qemudVirtTypeToString(def->virtType))) {
2872
3852
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
2873
3853
_("unexpected domain type %d"), def->virtType);
2877
if (qemudIsActiveVM(vm) && live) {
2878
if (virBufferVSprintf(buf, "<domain type='%s' id='%d'>\n", type, vm->id) < 0)
2881
if (virBufferVSprintf(buf, "<domain type='%s'>\n", type) < 0)
3857
if (qemudIsActiveVM(vm) && live)
3858
virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id);
3860
virBufferVSprintf(&buf, "<domain type='%s'>\n", type);
2885
if (virBufferVSprintf(buf, " <name>%s</name>\n", def->name) < 0)
3862
virBufferVSprintf(&buf, " <name>%s</name>\n", def->name);
2888
3864
uuid = def->uuid;
2889
3865
virUUIDFormat(uuid, uuidstr);
2890
if (virBufferVSprintf(buf, " <uuid>%s</uuid>\n", uuidstr) < 0)
2892
if (virBufferVSprintf(buf, " <memory>%lu</memory>\n", def->maxmem) < 0)
2894
if (virBufferVSprintf(buf, " <currentMemory>%lu</currentMemory>\n", def->memory) < 0)
2896
if (virBufferVSprintf(buf, " <vcpu>%d</vcpu>\n", def->vcpus) < 0)
2899
if (virBufferAddLit(buf, " <os>\n") < 0)
2902
if (def->virtType == QEMUD_VIRT_QEMU) {
2903
if (virBufferVSprintf(buf, " <type arch='%s' machine='%s'>%s</type>\n",
2904
def->os.arch, def->os.machine, def->os.type) < 0)
3866
virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
3868
virBufferVSprintf(&buf, " <memory>%lu</memory>\n", def->maxmem);
3869
virBufferVSprintf(&buf, " <currentMemory>%lu</currentMemory>\n", def->memory);
3871
for (n = 0 ; n < QEMUD_CPUMASK_LEN ; n++)
3872
if (def->cpumask[n] != 1)
3876
virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n", def->vcpus);
2907
if (virBufferVSprintf(buf, " <type>%s</type>\n", def->os.type) < 0)
2911
if (def->os.kernel[0])
2912
if (virBufferVSprintf(buf, " <kernel>%s</kernel>\n", def->os.kernel) < 0)
2914
if (def->os.initrd[0])
2915
if (virBufferVSprintf(buf, " <initrd>%s</initrd>\n", def->os.initrd) < 0)
2917
if (def->os.cmdline[0])
2918
if (virBufferVSprintf(buf, " <cmdline>%s</cmdline>\n", def->os.cmdline) < 0)
2921
for (n = 0 ; n < def->os.nBootDevs ; n++) {
2922
const char *boottype = "hd";
2923
switch (def->os.bootDevs[n]) {
2924
case QEMUD_BOOT_FLOPPY:
2927
case QEMUD_BOOT_DISK:
2930
case QEMUD_BOOT_CDROM:
2933
case QEMUD_BOOT_NET:
2934
boottype = "network";
2937
if (virBufferVSprintf(buf, " <boot dev='%s'/>\n", boottype) < 0)
2941
if (virBufferAddLit(buf, " </os>\n") < 0)
3878
char *cpumask = NULL;
3879
if ((cpumask = virSaveCpuSet(conn, def->cpumask, QEMUD_CPUMASK_LEN)) == NULL) {
3880
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
3881
"%s", _("allocating cpu mask"));
3884
virBufferVSprintf(&buf, " <vcpu cpuset='%s'>%d</vcpu>\n", cpumask, def->vcpus);
3888
if (def->os.bootloader[0])
3889
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", def->os.bootloader);
3890
virBufferAddLit(&buf, " <os>\n");
3892
if (def->virtType == QEMUD_VIRT_QEMU)
3893
virBufferVSprintf(&buf, " <type arch='%s' machine='%s'>%s</type>\n",
3894
def->os.arch, def->os.machine, def->os.type);
3896
virBufferVSprintf(&buf, " <type>%s</type>\n", def->os.type);
3898
if (!def->os.bootloader[0]) {
3899
if (def->os.kernel[0])
3900
virBufferVSprintf(&buf, " <kernel>%s</kernel>\n", def->os.kernel);
3901
if (def->os.initrd[0])
3902
virBufferVSprintf(&buf, " <initrd>%s</initrd>\n", def->os.initrd);
3903
if (def->os.cmdline[0])
3904
virBufferVSprintf(&buf, " <cmdline>%s</cmdline>\n", def->os.cmdline);
3906
for (n = 0 ; n < def->os.nBootDevs ; n++) {
3907
const char *boottype = "hd";
3908
switch (def->os.bootDevs[n]) {
3909
case QEMUD_BOOT_FLOPPY:
3912
case QEMUD_BOOT_DISK:
3915
case QEMUD_BOOT_CDROM:
3918
case QEMUD_BOOT_NET:
3919
boottype = "network";
3922
virBufferVSprintf(&buf, " <boot dev='%s'/>\n", boottype);
3926
virBufferAddLit(&buf, " </os>\n");
2944
3928
if (def->features & QEMUD_FEATURE_ACPI) {
2945
if (virBufferAddLit(buf, " <features>\n") < 0)
2947
if (virBufferAddLit(buf, " <acpi/>\n") < 0)
2949
if (virBufferAddLit(buf, " </features>\n") < 0)
2953
virBufferVSprintf(buf, " <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
2955
if (virBufferAddLit(buf, " <on_poweroff>destroy</on_poweroff>\n") < 0)
2957
if (def->noReboot) {
2958
if (virBufferAddLit(buf, " <on_reboot>destroy</on_reboot>\n") < 0)
2961
if (virBufferAddLit(buf, " <on_reboot>restart</on_reboot>\n") < 0)
2964
if (virBufferAddLit(buf, " <on_crash>destroy</on_crash>\n") < 0)
2967
if (virBufferAddLit(buf, " <devices>\n") < 0)
2970
if (virBufferVSprintf(buf, " <emulator>%s</emulator>\n", def->os.binary) < 0)
3929
virBufferAddLit(&buf, " <features>\n");
3930
virBufferAddLit(&buf, " <acpi/>\n");
3931
virBufferAddLit(&buf, " </features>\n");
3934
virBufferVSprintf(&buf, " <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
3936
virBufferAddLit(&buf, " <on_poweroff>destroy</on_poweroff>\n");
3938
virBufferAddLit(&buf, " <on_reboot>destroy</on_reboot>\n");
3940
virBufferAddLit(&buf, " <on_reboot>restart</on_reboot>\n");
3942
virBufferAddLit(&buf, " <on_crash>destroy</on_crash>\n");
3943
virBufferAddLit(&buf, " <devices>\n");
3945
virBufferVSprintf(&buf, " <emulator>%s</emulator>\n", def->os.binary);
2973
3947
disk = def->disks;
3021
if (virBufferVSprintf(buf, " <interface type='%s'>\n",
3022
types[net->type]) < 0)
3991
virBufferVSprintf(&buf, " <interface type='%s'>\n",
3025
if (virBufferVSprintf(buf, " <mac address='%02x:%02x:%02x:%02x:%02x:%02x'/>\n",
3026
net->mac[0], net->mac[1], net->mac[2],
3027
net->mac[3], net->mac[4], net->mac[5]) < 0)
3994
virBufferVSprintf(&buf, " <mac address='%02x:%02x:%02x:%02x:%02x:%02x'/>\n",
3995
net->mac[0], net->mac[1], net->mac[2],
3996
net->mac[3], net->mac[4], net->mac[5]);
3030
3998
switch (net->type) {
3031
3999
case QEMUD_NET_NETWORK:
3032
if (virBufferVSprintf(buf, " <source network='%s'/>\n", net->dst.network.name) < 0)
4000
virBufferVSprintf(&buf, " <source network='%s'/>\n", net->dst.network.name);
3035
if (net->dst.network.ifname[0] != '\0') {
3036
if (virBufferVSprintf(buf, " <target dev='%s'/>\n", net->dst.network.ifname) < 0)
4002
if (net->dst.network.ifname[0] != '\0')
4003
virBufferVSprintf(&buf, " <target dev='%s'/>\n", net->dst.network.ifname);
3041
4006
case QEMUD_NET_ETHERNET:
3042
if (net->dst.ethernet.ifname[0] != '\0') {
3043
if (virBufferVSprintf(buf, " <target dev='%s'/>\n", net->dst.ethernet.ifname) < 0)
3046
if (net->dst.ethernet.script[0] != '\0') {
3047
if (virBufferVSprintf(buf, " <script path='%s'/>\n", net->dst.ethernet.script) < 0)
4007
if (net->dst.ethernet.ifname[0] != '\0')
4008
virBufferVSprintf(&buf, " <target dev='%s'/>\n", net->dst.ethernet.ifname);
4009
if (net->dst.ethernet.script[0] != '\0')
4010
virBufferVSprintf(&buf, " <script path='%s'/>\n", net->dst.ethernet.script);
3052
4013
case QEMUD_NET_BRIDGE:
3053
if (virBufferVSprintf(buf, " <source bridge='%s'/>\n", net->dst.bridge.brname) < 0)
3055
if (net->dst.bridge.ifname[0] != '\0') {
3056
if (virBufferVSprintf(buf, " <target dev='%s'/>\n", net->dst.bridge.ifname) < 0)
4014
virBufferVSprintf(&buf, " <source bridge='%s'/>\n", net->dst.bridge.brname);
4015
if (net->dst.bridge.ifname[0] != '\0')
4016
virBufferVSprintf(&buf, " <target dev='%s'/>\n", net->dst.bridge.ifname);
3061
4019
case QEMUD_NET_SERVER:
3062
4020
case QEMUD_NET_CLIENT:
3063
4021
case QEMUD_NET_MCAST:
3064
if (net->dst.socket.address[0] != '\0') {
3065
if (virBufferVSprintf(buf, " <source address='%s' port='%d'/>\n",
3066
net->dst.socket.address, net->dst.socket.port) < 0)
3069
if (virBufferVSprintf(buf, " <source port='%d'/>\n",
3070
net->dst.socket.port) < 0)
3075
if (virBufferAddLit(buf, " </interface>\n") < 0)
4022
if (net->dst.socket.address[0] != '\0')
4023
virBufferVSprintf(&buf, " <source address='%s' port='%d'/>\n",
4024
net->dst.socket.address, net->dst.socket.port);
4026
virBufferVSprintf(&buf, " <source port='%d'/>\n",
4027
net->dst.socket.port);
4030
if (net->model && net->model[0] != '\0') {
4031
virBufferVSprintf(&buf, " <model type='%s'/>\n",
4035
virBufferAddLit(&buf, " </interface>\n");
3078
4037
net = net->next;
4042
if (qemudGenerateXMLChar(&buf, chr, "serial") < 0)
4048
chr = def->parallels;
4050
if (qemudGenerateXMLChar(&buf, chr, "parallel") < 0)
4056
/* First serial device is the primary console */
4057
if (def->nserials > 0 &&
4058
qemudGenerateXMLChar(&buf, def->serials, "console") < 0)
3081
4061
input = def->inputs;
3082
4062
while (input) {
3083
if (input->bus != QEMU_INPUT_BUS_PS2 &&
3084
virBufferVSprintf(buf, " <input type='%s' bus='usb'/>\n",
3085
input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet") < 0)
4063
if (input->bus == QEMU_INPUT_BUS_USB)
4064
virBufferVSprintf(&buf, " <input type='%s' bus='usb'/>\n",
4065
input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
3087
4066
input = input->next;
3089
4068
/* If graphics is enable, add implicit mouse */
3090
4069
if (def->graphicsType != QEMUD_GRAPHICS_NONE)
3091
if (virBufferAddLit(buf, " <input type='mouse' bus='ps2'/>\n") < 0)
4070
virBufferVSprintf(&buf, " <input type='mouse' bus='%s'/>\n",
4071
STREQ(def->os.type, "hvm") ? "ps2" : "xen");
3094
4073
switch (def->graphicsType) {
3095
4074
case QEMUD_GRAPHICS_VNC:
3096
if (virBufferAddLit(buf, " <graphics type='vnc'") < 0)
3100
virBufferVSprintf(buf, " port='%d'",
3101
qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort) < 0)
3104
if (def->vncListen[0] &&
3105
virBufferVSprintf(buf, " listen='%s'",
3106
def->vncListen) < 0)
3110
virBufferVSprintf(buf, " keymap='%s'",
3114
if (virBufferAddLit(buf, "/>\n") < 0)
4075
virBufferAddLit(&buf, " <graphics type='vnc'");
4078
virBufferVSprintf(&buf, " port='%d'",
4079
qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort);
4081
if (def->vncListen[0])
4082
virBufferVSprintf(&buf, " listen='%s'",
4086
virBufferVSprintf(&buf, " keymap='%s'",
4089
virBufferAddLit(&buf, "/>\n");
3118
4092
case QEMUD_GRAPHICS_SDL:
3119
if (virBufferAddLit(buf, " <graphics type='sdl'/>\n") < 0)
4093
virBufferAddLit(&buf, " <graphics type='sdl'/>\n");
3123
4096
case QEMUD_GRAPHICS_NONE:
3150
4132
struct qemud_driver *driver ATTRIBUTE_UNUSED,
3151
4133
struct qemud_network *network,
3152
4134
struct qemud_network_def *def) {
3153
virBufferPtr buf = 0;
4135
virBuffer buf = VIR_BUFFER_INITIALIZER;
3154
4136
unsigned char *uuid;
3155
4138
char uuidstr[VIR_UUID_STRING_BUFLEN];
3157
buf = virBufferNew (QEMUD_MAX_XML_LEN);
3161
if (virBufferAddLit(buf, "<network>\n") < 0)
3164
if (virBufferVSprintf(buf, " <name>%s</name>\n", def->name) < 0)
4140
virBufferAddLit(&buf, "<network>\n");
4142
virBufferVSprintf(&buf, " <name>%s</name>\n", def->name);
3167
4144
uuid = def->uuid;
3168
4145
virUUIDFormat(uuid, uuidstr);
3169
if (virBufferVSprintf(buf, " <uuid>%s</uuid>\n", uuidstr) < 0)
4146
virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
3172
4148
if (def->forward) {
3173
4149
if (def->forwardDev[0]) {
3174
virBufferVSprintf(buf, " <forward dev='%s' mode='%s'/>\n",
4150
virBufferVSprintf(&buf, " <forward dev='%s' mode='%s'/>\n",
3175
4151
def->forwardDev, (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
3177
virBufferVSprintf(buf, " <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
4153
virBufferVSprintf(&buf, " <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
3181
virBufferAddLit(buf, " <bridge");
4157
virBufferAddLit(&buf, " <bridge");
3182
4158
if (qemudIsActiveNetwork(network)) {
3183
if (virBufferVSprintf(buf, " name='%s'", network->bridge) < 0)
4159
virBufferVSprintf(&buf, " name='%s'", network->bridge);
3185
4160
} else if (def->bridge[0]) {
3186
if (virBufferVSprintf(buf, " name='%s'", def->bridge) < 0)
4161
virBufferVSprintf(&buf, " name='%s'", def->bridge);
3189
if (virBufferVSprintf(buf, " stp='%s' forwardDelay='%d' />\n",
3190
def->disableSTP ? "off" : "on",
3191
def->forwardDelay) < 0)
4163
virBufferVSprintf(&buf, " stp='%s' forwardDelay='%d' />\n",
4164
def->disableSTP ? "off" : "on",
3194
4167
if (def->ipAddress[0] || def->netmask[0]) {
3195
if (virBufferAddLit(buf, " <ip") < 0)
3198
if (def->ipAddress[0] &&
3199
virBufferVSprintf(buf, " address='%s'", def->ipAddress) < 0)
3202
if (def->netmask[0] &&
3203
virBufferVSprintf(buf, " netmask='%s'", def->netmask) < 0)
3206
if (virBufferAddLit(buf, ">\n") < 0)
4168
virBufferAddLit(&buf, " <ip");
4170
if (def->ipAddress[0])
4171
virBufferVSprintf(&buf, " address='%s'", def->ipAddress);
4173
if (def->netmask[0])
4174
virBufferVSprintf(&buf, " netmask='%s'", def->netmask);
4176
virBufferAddLit(&buf, ">\n");
3209
4178
if (def->ranges) {
3210
4179
struct qemud_dhcp_range_def *range = def->ranges;
3211
if (virBufferAddLit(buf, " <dhcp>\n") < 0)
4180
virBufferAddLit(&buf, " <dhcp>\n");
3213
4181
while (range) {
3214
if (virBufferVSprintf(buf, " <range start='%s' end='%s' />\n",
3215
range->start, range->end) < 0)
4182
virBufferVSprintf(&buf, " <range start='%s' end='%s' />\n",
4183
range->start, range->end);
3217
4184
range = range->next;
3219
if (virBufferAddLit(buf, " </dhcp>\n") < 0)
4186
virBufferAddLit(&buf, " </dhcp>\n");
3223
if (virBufferAddLit(buf, " </ip>\n") < 0)
4189
virBufferAddLit(&buf, " </ip>\n");
3227
if (virBufferAddLit(buf, "</network>\n") < 0)
4192
virBufferAddLit(&buf, "</network>\n");
4194
if (virBufferError(&buf))
3228
4195
goto no_memory;
3230
return virBufferContentAndFree (buf);
4197
return virBufferContentAndReset(&buf);
3233
4200
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
3234
4201
"%s", _("failed to generate XML: out of memory"));
3235
if (buf) virBufferFree (buf);
4202
tmp = virBufferContentAndReset(&buf);