~ubuntu-branches/ubuntu/maverick/libvirt/maverick

« back to all changes in this revision

Viewing changes to src/qemu_conf.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2008-06-25 18:51:21 UTC
  • mto: (3.1.1 lenny) (1.2.1 upstream) (0.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 27.
  • Revision ID: james.westby@ubuntu.com-20080625185121-8dku38gpoluks1bx
Tags: upstream-0.4.4
ImportĀ upstreamĀ versionĀ 0.4.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
#include <libxml/xpath.h>
43
43
#include <libxml/uri.h>
44
44
 
45
 
#include "libvirt/virterror.h"
 
45
#if HAVE_NUMACTL
 
46
#include <numa.h>
 
47
#endif
46
48
 
 
49
#include "internal.h"
47
50
#include "qemu_conf.h"
48
51
#include "uuid.h"
49
52
#include "buf.h"
50
53
#include "conf.h"
51
54
#include "util.h"
 
55
#include "memory.h"
 
56
#include "verify.h"
 
57
#include "c-ctype.h"
 
58
#include "xml.h"
52
59
 
53
60
#define qemudLog(level, msg...) fprintf(stderr, msg)
54
61
 
114
121
    p = virConfGetValue (conf, "vnc_tls_x509_cert_dir");
115
122
    CHECK_TYPE ("vnc_tls_x509_cert_dir", VIR_CONF_STRING);
116
123
    if (p && p->str) {
117
 
        free(driver->vncTLSx509certdir);
 
124
        VIR_FREE(driver->vncTLSx509certdir);
118
125
        if (!(driver->vncTLSx509certdir = strdup(p->str))) {
119
126
            qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY,
120
127
                             "%s", _("failed to allocate vncTLSx509certdir"));
165
172
    struct qemud_vm *vm = driver->vms;
166
173
 
167
174
    while (vm) {
168
 
        if (!strcmp(vm->def->name, name))
 
175
        if (STREQ(vm->def->name, name))
169
176
            return vm;
170
177
        vm = vm->next;
171
178
    }
191
198
    struct qemud_network *network = driver->networks;
192
199
 
193
200
    while (network) {
194
 
        if (!strcmp(network->def->name, name))
 
201
        if (STREQ(network->def->name, name))
195
202
            return network;
196
203
        network = network->next;
197
204
    }
205
212
    struct qemud_vm_disk_def *disk = def->disks;
206
213
    struct qemud_vm_net_def *net = def->nets;
207
214
    struct qemud_vm_input_def *input = def->inputs;
 
215
    struct qemud_vm_chr_def *serial = def->serials;
 
216
    struct qemud_vm_chr_def *parallel = def->parallels;
 
217
    struct qemud_vm_sound_def *sound = def->sounds;
208
218
 
209
219
    while (disk) {
210
220
        struct qemud_vm_disk_def *prev = disk;
211
221
        disk = disk->next;
212
 
        free(prev);
 
222
        VIR_FREE(prev);
213
223
    }
214
224
    while (net) {
215
225
        struct qemud_vm_net_def *prev = net;
216
226
        net = net->next;
217
 
        free(prev);
 
227
        VIR_FREE(prev);
218
228
    }
219
229
    while (input) {
220
230
        struct qemud_vm_input_def *prev = input;
221
231
        input = input->next;
222
 
        free(prev);
 
232
        VIR_FREE(prev);
 
233
    }
 
234
    while (serial) {
 
235
        struct qemud_vm_chr_def *prev = serial;
 
236
        serial = serial->next;
 
237
        VIR_FREE(prev);
 
238
    }
 
239
    while (parallel) {
 
240
        struct qemud_vm_chr_def *prev = parallel;
 
241
        parallel = parallel->next;
 
242
        VIR_FREE(prev);
 
243
    }
 
244
    while (sound) {
 
245
        struct qemud_vm_sound_def *prev = sound;
 
246
        sound = sound->next;
 
247
        VIR_FREE(prev);
223
248
    }
224
249
    xmlFree(def->keymap);
225
 
    free(def);
 
250
    VIR_FREE(def);
226
251
}
227
252
 
228
253
void qemudFreeVM(struct qemud_vm *vm) {
229
254
    qemudFreeVMDef(vm->def);
230
255
    if (vm->newDef)
231
256
        qemudFreeVMDef(vm->newDef);
232
 
    free(vm);
 
257
    VIR_FREE(vm);
233
258
}
234
259
 
235
260
 
376
401
    return 0;
377
402
}
378
403
 
 
404
#if HAVE_NUMACTL
 
405
#define MAX_CPUS 4096
 
406
#define MAX_CPUS_MASK_SIZE (sizeof(unsigned long))
 
407
#define MAX_CPUS_MASK_LEN (MAX_CPUS / MAX_CPUS_MASK_SIZE)
 
408
#define MAX_CPUS_MASK_BYTES (MAX_CPUS / 8)
 
409
 
 
410
#define MASK_CPU_ISSET(mask, cpu) \
 
411
    (((mask)[((cpu) / MAX_CPUS_MASK_SIZE)] >> ((cpu) % MAX_CPUS_MASK_SIZE)) & 1)
 
412
 
 
413
static int
 
414
qemudCapsInitNUMA(virCapsPtr caps)
 
415
{
 
416
    int n, i;
 
417
    unsigned long *mask = NULL;
 
418
    int ncpus;
 
419
    int *cpus = NULL;
 
420
    int ret = -1;
 
421
 
 
422
    if (numa_available() < 0)
 
423
        return 0;
 
424
 
 
425
    if (VIR_ALLOC_N(mask, MAX_CPUS_MASK_LEN) < 0)
 
426
        goto cleanup;
 
427
 
 
428
    for (n = 0 ; n <= numa_max_node() ; n++) {
 
429
        if (numa_node_to_cpus(n, mask, MAX_CPUS_MASK_BYTES) < 0)
 
430
            goto cleanup;
 
431
 
 
432
        for (ncpus = 0, i = 0 ; i < MAX_CPUS ; i++)
 
433
            if (MASK_CPU_ISSET(mask, i))
 
434
                ncpus++;
 
435
 
 
436
        if (VIR_ALLOC_N(cpus, ncpus) < 0)
 
437
            goto cleanup;
 
438
 
 
439
        for (ncpus = 0, i = 0 ; i < MAX_CPUS ; i++)
 
440
            if (MASK_CPU_ISSET(mask, i))
 
441
                cpus[ncpus++] = i;
 
442
 
 
443
        if (virCapabilitiesAddHostNUMACell(caps,
 
444
                                           n,
 
445
                                           ncpus,
 
446
                                           cpus) < 0)
 
447
            goto cleanup;
 
448
 
 
449
        VIR_FREE(cpus);
 
450
    }
 
451
 
 
452
    ret = 0;
 
453
 
 
454
cleanup:
 
455
    VIR_FREE(cpus);
 
456
    VIR_FREE(mask);
 
457
    return ret;
 
458
}
 
459
#else
 
460
static int qemudCapsInitNUMA(virCapsPtr caps ATTRIBUTE_UNUSED) { return 0; }
 
461
#endif
 
462
 
379
463
virCapsPtr qemudCapsInit(void) {
380
464
    struct utsname utsname;
381
465
    virCapsPtr caps;
388
472
                                   0, 0)) == NULL)
389
473
        goto no_memory;
390
474
 
 
475
    if (qemudCapsInitNUMA(caps) < 0)
 
476
        goto no_memory;
 
477
 
391
478
    for (i = 0 ; i < (sizeof(arch_info_hvm)/sizeof(arch_info_hvm[0])) ; i++)
392
479
        if (qemudCapsInitGuest(caps,
393
480
                               utsname.machine,
434
521
    }
435
522
 
436
523
    if (child == 0) { /* Kid */
 
524
        /* Just in case QEMU is translated someday we force to C locale.. */
 
525
        const char *const qemuenv[] = { "LANG=C", NULL };
 
526
 
437
527
        if (close(STDIN_FILENO) < 0)
438
528
            goto cleanup1;
439
529
        if (close(STDERR_FILENO) < 0)
443
533
        if (dup2(newstdout[1], STDOUT_FILENO) < 0)
444
534
            goto cleanup1;
445
535
 
446
 
        /* Just in case QEMU is translated someday.. */
447
 
        setenv("LANG", "C", 1);
448
 
        execl(qemu, qemu, (char*)NULL);
 
536
        /* Passing -help, rather than relying on no-args which doesn't
 
537
           always work */
 
538
        execle(qemu, qemu, "-help", (char*)NULL, qemuenv);
449
539
 
450
540
    cleanup1:
451
541
        _exit(-1); /* Just in case */
479
569
            *flags |= QEMUD_CMD_FLAG_KQEMU;
480
570
        if (strstr(help, "-no-reboot"))
481
571
            *flags |= QEMUD_CMD_FLAG_NO_REBOOT;
 
572
        if (strstr(help, "-name"))
 
573
            *flags |= QEMUD_CMD_FLAG_NAME;
 
574
        if (strstr(help, "-drive"))
 
575
            *flags |= QEMUD_CMD_FLAG_DRIVE;
 
576
        if (strstr(help, "boot=on"))
 
577
            *flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
482
578
        if (*version >= 9000)
483
579
            *flags |= QEMUD_CMD_FLAG_VNC_COLON;
484
580
        ret = 0;
503
599
        /* Check & log unexpected exit status, but don't fail,
504
600
         * as there's really no need to throw an error if we did
505
601
         * actually read a valid version number above */
506
 
        if (WEXITSTATUS(got) != 1) {
 
602
        if (WEXITSTATUS(got) != 0) {
507
603
            qemudLog(QEMUD_WARN,
508
604
                     _("Unexpected exit status '%d', qemu probably failed"),
509
605
                     got);
542
638
    return 0;
543
639
}
544
640
 
 
641
/* Converts def->virtType to applicable string type
 
642
 * @param type integer virt type
 
643
 * @return string type on success, NULL on fail
 
644
 */
 
645
const char * qemudVirtTypeToString(int type) {
 
646
    switch (type) {
 
647
        case QEMUD_VIRT_QEMU:
 
648
            return "qemu";
 
649
        case QEMUD_VIRT_KQEMU:
 
650
            return "kqemu";
 
651
        case QEMUD_VIRT_KVM:
 
652
            return "kvm";
 
653
    }
 
654
    return NULL;
 
655
}
545
656
 
546
657
/* Parse the XML definition for a disk
547
658
 * @param disk pre-allocated & zero'd disk record
556
667
    xmlChar *source = NULL;
557
668
    xmlChar *target = NULL;
558
669
    xmlChar *type = NULL;
 
670
    xmlChar *bus = NULL;
559
671
    int typ = 0;
560
672
 
561
673
    type = xmlGetProp(node, BAD_CAST "type");
586
698
            } else if ((target == NULL) &&
587
699
                       (xmlStrEqual(cur->name, BAD_CAST "target"))) {
588
700
                target = xmlGetProp(cur, BAD_CAST "dev");
 
701
                bus = xmlGetProp(cur, BAD_CAST "bus");
589
702
            } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
590
703
                disk->readonly = 1;
591
704
            }
610
723
    }
611
724
 
612
725
    if (device &&
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);
618
731
        goto error;
619
732
    }
620
733
 
621
734
    if (device &&
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);
626
739
        goto error;
627
740
    }
628
741
 
629
742
    if (device &&
630
 
        !strcmp((const char *)device, "cdrom"))
 
743
        STREQ((const char *)device, "cdrom"))
631
744
        disk->readonly = 1;
632
745
 
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);
640
753
        goto error;
649
762
 
650
763
    if (!device)
651
764
        disk->device = QEMUD_DISK_DISK;
652
 
    else if (!strcmp((const char *)device, "disk"))
 
765
    else if (STREQ((const char *)device, "disk"))
653
766
        disk->device = QEMUD_DISK_DISK;
654
 
    else if (!strcmp((const char *)device, "cdrom"))
 
767
    else if (STREQ((const char *)device, "cdrom"))
655
768
        disk->device = QEMUD_DISK_CDROM;
656
 
    else if (!strcmp((const char *)device, "floppy"))
 
769
    else if (STREQ((const char *)device, "floppy"))
657
770
        disk->device = QEMUD_DISK_FLOPPY;
658
771
    else {
659
772
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
661
774
        goto error;
662
775
    }
663
776
 
 
777
    if (!bus) {
 
778
        if (disk->device == QEMUD_DISK_FLOPPY) {
 
779
            disk->bus = QEMUD_DISK_BUS_FDC;
 
780
        } else {
 
781
            if (STRPREFIX((const char *)target, "hd"))
 
782
                disk->bus = QEMUD_DISK_BUS_IDE;
 
783
            else if (STRPREFIX((const char *)target, "sd"))
 
784
                disk->bus = QEMUD_DISK_BUS_SCSI;
 
785
            else if (STRPREFIX((const char *)target, "vd"))
 
786
                disk->bus = QEMUD_DISK_BUS_VIRTIO;
 
787
            else if (STRPREFIX((const char *)target, "xvd"))
 
788
                disk->bus = QEMUD_DISK_BUS_XEN;
 
789
            else
 
790
                disk->bus = QEMUD_DISK_BUS_IDE;
 
791
        }
 
792
    } else if (STREQ((const char *)bus, "ide"))
 
793
        disk->bus = QEMUD_DISK_BUS_IDE;
 
794
    else if (STREQ((const char *)bus, "fdc"))
 
795
        disk->bus = QEMUD_DISK_BUS_FDC;
 
796
    else if (STREQ((const char *)bus, "scsi"))
 
797
        disk->bus = QEMUD_DISK_BUS_SCSI;
 
798
    else if (STREQ((const char *)bus, "virtio"))
 
799
        disk->bus = QEMUD_DISK_BUS_VIRTIO;
 
800
    else if (STREQ((const char *)bus, "xen"))
 
801
        disk->bus = QEMUD_DISK_BUS_XEN;
 
802
    else {
 
803
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
804
                         _("Invalid bus type: %s"), bus);
 
805
        goto error;
 
806
    }
 
807
 
 
808
    if (disk->device == QEMUD_DISK_FLOPPY &&
 
809
        disk->bus != QEMUD_DISK_BUS_FDC) {
 
810
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
811
                         _("Invalid bus type '%s' for floppy disk"), bus);
 
812
        goto error;
 
813
    }
 
814
 
664
815
    xmlFree(device);
665
816
    xmlFree(target);
666
817
    xmlFree(source);
 
818
    xmlFree(bus);
667
819
 
668
820
    return 0;
669
821
 
670
822
 error:
671
 
    if (type)
672
 
        xmlFree(type);
673
 
    if (target)
674
 
        xmlFree(target);
675
 
    if (source)
676
 
        xmlFree(source);
677
 
    if (device)
678
 
        xmlFree(device);
 
823
    xmlFree(bus);
 
824
    xmlFree(type);
 
825
    xmlFree(target);
 
826
    xmlFree(source);
 
827
    xmlFree(device);
679
828
    return -1;
680
829
}
681
830
 
706
855
    xmlChar *script = NULL;
707
856
    xmlChar *address = NULL;
708
857
    xmlChar *port = NULL;
 
858
    xmlChar *model = NULL;
709
859
 
710
860
    net->type = QEMUD_NET_USER;
711
861
 
758
908
                        (net->type == QEMUD_NET_BRIDGE)) &&
759
909
                       xmlStrEqual(cur->name, BAD_CAST "target")) {
760
910
                ifname = xmlGetProp(cur, BAD_CAST "dev");
761
 
                if (STREQLEN("vnet", (const char*)ifname, 4)) {
 
911
                if (STRPREFIX((const char*)ifname, "vnet")) {
762
912
                    /* An auto-generated target name, blank it out */
763
913
                    xmlFree(ifname);
764
914
                    ifname = NULL;
767
917
                       (net->type == QEMUD_NET_ETHERNET) &&
768
918
                       xmlStrEqual(cur->name, BAD_CAST "script")) {
769
919
                script = xmlGetProp(cur, BAD_CAST "path");
 
920
            } else if (xmlStrEqual (cur->name, BAD_CAST "model")) {
 
921
                model = xmlGetProp (cur, BAD_CAST "type");
770
922
            }
771
923
        }
772
924
        cur = cur->next;
926
1078
        xmlFree(address);
927
1079
    }
928
1080
 
 
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
 
1085
     */
 
1086
    if (model != NULL) {
 
1087
        int i, len;
 
1088
 
 
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);
 
1093
            goto error;
 
1094
        }
 
1095
        for (i = 0; i < len; ++i) {
 
1096
            int char_ok = c_isalnum(model[i]) || model[i] == '_';
 
1097
            if (!char_ok) {
 
1098
                qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG, "%s",
 
1099
                                  _("Model name contains invalid characters"));
 
1100
                goto error;
 
1101
            }
 
1102
        }
 
1103
        strncpy (net->model, (const char*) model, len);
 
1104
        net->model[len] = '\0';
 
1105
 
 
1106
        xmlFree (model);
 
1107
        model = NULL;
 
1108
    } else
 
1109
        net->model[0] = '\0';
 
1110
 
929
1111
    return 0;
930
1112
 
931
1113
 error:
932
 
    if (network)
933
 
        xmlFree(network);
934
 
    if (address)
935
 
        xmlFree(address);
936
 
    if (port)
937
 
        xmlFree(port);
938
 
    if (ifname)
939
 
        xmlFree(ifname);
940
 
    if (script)
941
 
        xmlFree(script);
942
 
    if (bridge)
943
 
        xmlFree(bridge);
 
1114
    xmlFree(network);
 
1115
    xmlFree(address);
 
1116
    xmlFree(port);
 
1117
    xmlFree(ifname);
 
1118
    xmlFree(script);
 
1119
    xmlFree(bridge);
 
1120
    xmlFree(model);
944
1121
    return -1;
945
1122
}
946
1123
 
947
1124
 
 
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
 
1129
 *
 
1130
 * The XML we're dealing with looks like
 
1131
 *
 
1132
 * <serial type="pty">
 
1133
 *   <source path="/dev/pts/3"/>
 
1134
 *   <target port="1"/>
 
1135
 * </serial>
 
1136
 *
 
1137
 * <serial type="dev">
 
1138
 *   <source path="/dev/ttyS0"/>
 
1139
 *   <target port="1"/>
 
1140
 * </serial>
 
1141
 *
 
1142
 * <serial type="tcp">
 
1143
 *   <source mode="connect" host="0.0.0.0" service="2445"/>
 
1144
 *   <target port="1"/>
 
1145
 * </serial>
 
1146
 *
 
1147
 * <serial type="tcp">
 
1148
 *   <source mode="bind" host="0.0.0.0" service="2445"/>
 
1149
 *   <target port="1"/>
 
1150
 * </serial>
 
1151
 *
 
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"/>
 
1156
 * </serial>
 
1157
 *
 
1158
 * <serial type="unix">
 
1159
 *   <source mode="bind" path="/tmp/foo"/>
 
1160
 *   <target port="1"/>
 
1161
 * </serial>
 
1162
 *
 
1163
 */
 
1164
static int qemudParseCharXML(virConnectPtr conn,
 
1165
                             struct qemud_vm_chr_def *chr,
 
1166
                             int portNum,
 
1167
                             xmlNodePtr node) {
 
1168
    xmlNodePtr cur;
 
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;
 
1177
    int ret = -1;
 
1178
 
 
1179
    chr->srcType = QEMUD_CHR_SRC_TYPE_PTY;
 
1180
    type = xmlGetProp(node, BAD_CAST "type");
 
1181
    if (type != NULL) {
 
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;
 
1202
        else
 
1203
            chr->srcType = QEMUD_CHR_SRC_TYPE_NULL;
 
1204
    }
 
1205
 
 
1206
    cur = node->children;
 
1207
    while (cur != NULL) {
 
1208
        if (cur->type == XML_ELEMENT_NODE) {
 
1209
            if (xmlStrEqual(cur->name, BAD_CAST "source")) {
 
1210
                if (mode == NULL)
 
1211
                    mode = xmlGetProp(cur, BAD_CAST "mode");
 
1212
 
 
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:
 
1219
                    if (path == NULL)
 
1220
                        path = xmlGetProp(cur, BAD_CAST "path");
 
1221
 
 
1222
                    break;
 
1223
 
 
1224
                case QEMUD_CHR_SRC_TYPE_UDP:
 
1225
                case QEMUD_CHR_SRC_TYPE_TCP:
 
1226
                    if (mode == NULL ||
 
1227
                        STREQ((const char *)mode, "connect")) {
 
1228
 
 
1229
                        if (connectHost == NULL)
 
1230
                            connectHost = xmlGetProp(cur, BAD_CAST "host");
 
1231
                        if (connectService == NULL)
 
1232
                            connectService = xmlGetProp(cur, BAD_CAST "service");
 
1233
                    } else {
 
1234
                        if (bindHost == NULL)
 
1235
                            bindHost = xmlGetProp(cur, BAD_CAST "host");
 
1236
                        if (bindService == NULL)
 
1237
                            bindService = xmlGetProp(cur, BAD_CAST "service");
 
1238
                    }
 
1239
 
 
1240
                    if (chr->srcType == QEMUD_CHR_SRC_TYPE_UDP) {
 
1241
                        xmlFree(mode);
 
1242
                        mode = NULL;
 
1243
                    }
 
1244
                }
 
1245
            } else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) {
 
1246
                if (protocol == NULL)
 
1247
                    protocol = xmlGetProp(cur, BAD_CAST "type");
 
1248
            }
 
1249
        }
 
1250
        cur = cur->next;
 
1251
    }
 
1252
 
 
1253
 
 
1254
    chr->dstPort = portNum;
 
1255
 
 
1256
    switch (chr->srcType) {
 
1257
    case QEMUD_CHR_SRC_TYPE_NULL:
 
1258
        /* Nada */
 
1259
        break;
 
1260
 
 
1261
    case QEMUD_CHR_SRC_TYPE_VC:
 
1262
        break;
 
1263
 
 
1264
    case QEMUD_CHR_SRC_TYPE_PTY:
 
1265
        /* @path attribute is an output only property - pty is auto-allocted */
 
1266
        break;
 
1267
 
 
1268
    case QEMUD_CHR_SRC_TYPE_DEV:
 
1269
    case QEMUD_CHR_SRC_TYPE_FILE:
 
1270
    case QEMUD_CHR_SRC_TYPE_PIPE:
 
1271
        if (path == NULL) {
 
1272
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1273
                             "%s", _("Missing source path attribute for char device"));
 
1274
            goto cleanup;
 
1275
        }
 
1276
 
 
1277
        strncpy(chr->srcData.file.path, (const char *)path,
 
1278
                sizeof(chr->srcData.file.path));
 
1279
        NUL_TERMINATE(chr->srcData.file.path);
 
1280
        break;
 
1281
 
 
1282
    case QEMUD_CHR_SRC_TYPE_STDIO:
 
1283
        /* Nada */
 
1284
        break;
 
1285
 
 
1286
    case QEMUD_CHR_SRC_TYPE_TCP:
 
1287
        if (mode == NULL ||
 
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"));
 
1292
                goto cleanup;
 
1293
            }
 
1294
            if (connectService == NULL) {
 
1295
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1296
                                 "%s", _("Missing source service attribute for char device"));
 
1297
                goto cleanup;
 
1298
            }
 
1299
 
 
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);
 
1306
 
 
1307
            chr->srcData.tcp.listen = 0;
 
1308
        } else {
 
1309
            if (bindHost == NULL) {
 
1310
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1311
                                 "%s", _("Missing source host attribute for char device"));
 
1312
                goto cleanup;
 
1313
            }
 
1314
            if (bindService == NULL) {
 
1315
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1316
                                 "%s", _("Missing source service attribute for char device"));
 
1317
                goto cleanup;
 
1318
            }
 
1319
 
 
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);
 
1326
 
 
1327
            chr->srcData.tcp.listen = 1;
 
1328
        }
 
1329
        if (protocol != NULL &&
 
1330
            STREQ((const char *)protocol, "telnet"))
 
1331
            chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET;
 
1332
        else
 
1333
            chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_RAW;
 
1334
        break;
 
1335
 
 
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"));
 
1340
            goto cleanup;
 
1341
        }
 
1342
 
 
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);
 
1347
        }
 
1348
        strncpy(chr->srcData.udp.connectService, (const char *)connectService,
 
1349
                sizeof(chr->srcData.udp.connectService));
 
1350
        NUL_TERMINATE(chr->srcData.udp.connectService);
 
1351
 
 
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);
 
1356
        }
 
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);
 
1361
        }
 
1362
        break;
 
1363
 
 
1364
    case QEMUD_CHR_SRC_TYPE_UNIX:
 
1365
        if (path == NULL) {
 
1366
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1367
                             "%s", _("Missing source path attribute for char device"));
 
1368
            goto cleanup;
 
1369
        }
 
1370
 
 
1371
        if (mode != NULL &&
 
1372
            STRNEQ((const char *)mode, "connect"))
 
1373
            chr->srcData.nix.listen = 1;
 
1374
        else
 
1375
            chr->srcData.nix.listen = 0;
 
1376
 
 
1377
        strncpy(chr->srcData.nix.path, (const char *)path,
 
1378
                sizeof(chr->srcData.nix.path));
 
1379
        NUL_TERMINATE(chr->srcData.nix.path);
 
1380
        break;
 
1381
    }
 
1382
 
 
1383
    ret = 0;
 
1384
 
 
1385
cleanup:
 
1386
    xmlFree(mode);
 
1387
    xmlFree(protocol);
 
1388
    xmlFree(type);
 
1389
    xmlFree(bindHost);
 
1390
    xmlFree(bindService);
 
1391
    xmlFree(connectHost);
 
1392
    xmlFree(connectService);
 
1393
    xmlFree(path);
 
1394
 
 
1395
    return ret;
 
1396
}
 
1397
 
 
1398
 
 
1399
static int qemudParseCharXMLDevices(virConnectPtr conn,
 
1400
                                    xmlXPathContextPtr ctxt,
 
1401
                                    const char *xpath,
 
1402
                                    unsigned int *ndevs,
 
1403
                                    struct qemud_vm_chr_def **devs)
 
1404
{
 
1405
    xmlXPathObjectPtr obj;
 
1406
    int i, ret = -1;
 
1407
 
 
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"));
 
1416
            goto cleanup;
 
1417
        }
 
1418
 
 
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,
 
1423
                                 "%s",
 
1424
                                 _("failed to allocate space for char device"));
 
1425
                goto cleanup;
 
1426
            }
 
1427
 
 
1428
            if (qemudParseCharXML(conn, chr, i, obj->nodesetval->nodeTab[i]) < 0) {
 
1429
                VIR_FREE(chr);
 
1430
                goto cleanup;
 
1431
            }
 
1432
            if (ndevs)
 
1433
                (*ndevs)++;
 
1434
            chr->next = NULL;
 
1435
            if (i == 0) {
 
1436
                *devs = chr;
 
1437
            } else {
 
1438
                prev->next = chr;
 
1439
            }
 
1440
            prev = chr;
 
1441
        }
 
1442
    }
 
1443
 
 
1444
    ret = 0;
 
1445
 
 
1446
cleanup:
 
1447
    xmlXPathFreeObject(obj);
 
1448
    return ret;
 
1449
}
 
1450
 
 
1451
 
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;
961
1466
        goto error;
962
1467
    }
963
1468
 
964
 
    if (!strcmp((const char *)type, "mouse")) {
 
1469
    if (STREQ((const char *)type, "mouse")) {
965
1470
        input->type = QEMU_INPUT_TYPE_MOUSE;
966
 
    } else if (!strcmp((const char *)type, "tablet")) {
 
1471
    } else if (STREQ((const char *)type, "tablet")) {
967
1472
        input->type = QEMU_INPUT_TYPE_TABLET;
968
1473
    } else {
969
1474
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
973
1478
    }
974
1479
 
975
1480
    if (bus) {
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"),
 
1486
                                     (const char*)type);
 
1487
                    goto error;
 
1488
                }
 
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;
 
1492
            } else {
978
1493
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
979
 
                                 _("ps2 bus does not support %s input device"),
980
 
                                 (const char*)type);
 
1494
                                 _("unsupported input bus %s"), (const char*)bus);
981
1495
                goto error;
982
1496
            }
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;
986
1497
        } else {
987
 
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
988
 
                             _("unsupported input bus %s"), (const char*)bus);
989
 
            goto error;
 
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"),
 
1503
                                     (const char*)type);
 
1504
                    goto error;
 
1505
                }
 
1506
            } else {
 
1507
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1508
                                 _("unsupported input bus %s"), (const char*)bus);
 
1509
                goto error;
 
1510
            }
990
1511
        }
991
1512
    } else {
992
 
        if (input->type == QEMU_INPUT_TYPE_MOUSE)
993
 
            input->bus = QEMU_INPUT_BUS_PS2;
994
 
        else
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;
 
1516
            else
 
1517
                input->bus = QEMU_INPUT_BUS_USB;
 
1518
        } else {
 
1519
            input->bus = QEMU_INPUT_BUS_XEN;
 
1520
        }
996
1521
    }
997
1522
 
998
 
    if (type)
999
 
        xmlFree(type);
1000
 
    if (bus)
1001
 
        xmlFree(bus);
 
1523
    xmlFree(type);
 
1524
    xmlFree(bus);
1002
1525
 
1003
1526
    return 0;
1004
1527
 
1005
1528
 error:
1006
 
    if (type)
1007
 
        xmlFree(type);
1008
 
    if (bus)
1009
 
        xmlFree(bus);
1010
 
 
1011
 
    return -1;
1012
 
}
1013
 
 
 
1529
    xmlFree(type);
 
1530
    xmlFree(bus);
 
1531
 
 
1532
    return -1;
 
1533
}
 
1534
 
 
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);
 
1540
    else
 
1541
        return a->bus - b->bus;
 
1542
}
 
1543
 
 
1544
static const char *qemudBusIdToName(int busId, int qemuIF) {
 
1545
    const char *busnames[] = { "ide",
 
1546
                               (qemuIF ? "floppy" : "fdc"),
 
1547
                               "scsi",
 
1548
                               "virtio",
 
1549
                               "xen"};
 
1550
    verify_true(ARRAY_CARDINALITY(busnames) == QEMUD_DISK_BUS_LAST);
 
1551
 
 
1552
    return busnames[busId];
 
1553
}
 
1554
 
 
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;
 
1563
    }
 
1564
 
 
1565
    return -1;
 
1566
}
 
1567
 
 
1568
static const char *qemudSoundModelToString(const int model) {
 
1569
 
 
1570
    if (model == QEMU_SOUND_SB16) {
 
1571
        return "sb16";
 
1572
    } else if (model == QEMU_SOUND_ES1370) {
 
1573
        return "es1370";
 
1574
    } else if (model == QEMU_SOUND_PCSPK) {
 
1575
        return "pcspk";
 
1576
    }
 
1577
 
 
1578
    return NULL;
 
1579
}
 
1580
 
 
1581
 
 
1582
static int qemudParseSoundXML(virConnectPtr conn,
 
1583
                              struct qemud_vm_sound_def *sound,
 
1584
                              const xmlNodePtr node) {
 
1585
 
 
1586
    int err = -1;
 
1587
    xmlChar *model = NULL;
 
1588
    model = xmlGetProp(node, BAD_CAST "model");
 
1589
 
 
1590
    if (!model) {
 
1591
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1592
                         "%s", _("missing sound model"));
 
1593
        goto error;
 
1594
    }
 
1595
    if ((sound->model = qemudSoundModelFromString((char *) model)) < 0) {
 
1596
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1597
                         _("invalid sound model '%s'"), (char *) model);
 
1598
        goto error;
 
1599
    }
 
1600
 
 
1601
    err = 0;
 
1602
 error:
 
1603
    xmlFree(model);
 
1604
    return err;
 
1605
}
1014
1606
 
1015
1607
/*
1016
1608
 * Parses a libvirt XML definition of a guest, and populates the
1027
1619
    int i;
1028
1620
    struct qemud_vm_def *def;
1029
1621
 
1030
 
    if (!(def = calloc(1, sizeof(*def)))) {
 
1622
    if (VIR_ALLOC(def) < 0) {
1031
1623
        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1032
1624
                         "%s", _("failed to allocate space for xmlXPathContext"));
1033
1625
        return NULL;
1056
1648
        goto error;
1057
1649
    }
1058
1650
 
1059
 
    if (!strcmp((char *)prop, "qemu"))
 
1651
    if (STREQ((char *)prop, "qemu"))
1060
1652
        def->virtType = QEMUD_VIRT_QEMU;
1061
 
    else if (!strcmp((char *)prop, "kqemu"))
 
1653
    else if (STREQ((char *)prop, "kqemu"))
1062
1654
        def->virtType = QEMUD_VIRT_KQEMU;
1063
 
    else if (!strcmp((char *)prop, "kvm"))
 
1655
    else if (STREQ((char *)prop, "kvm"))
1064
1656
        def->virtType = QEMUD_VIRT_KVM;
1065
1657
    else {
1066
1658
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1067
1659
                         "%s", _("invalid domain type attribute"));
1068
1660
        goto error;
1069
1661
    }
1070
 
    free(prop);
1071
 
    prop = NULL;
 
1662
    VIR_FREE(prop);
1072
1663
 
1073
1664
 
1074
1665
    /* Extract domain name */
1158
1749
    }
1159
1750
    xmlXPathFreeObject(obj);
1160
1751
 
 
1752
    /* Extract domain vcpu info */
 
1753
    obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1]/@cpuset)", ctxt);
 
1754
    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
 
1755
        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
 
1756
        /* Allow use on all CPUS */
 
1757
        memset(def->cpumask, 1, QEMUD_CPUMASK_LEN);
 
1758
    } else {
 
1759
        char *set = (char *)obj->stringval;
 
1760
        memset(def->cpumask, 0, QEMUD_CPUMASK_LEN);
 
1761
        if (virParseCpuSet(conn, (const char **)&set,
 
1762
                           0, def->cpumask,
 
1763
                           QEMUD_CPUMASK_LEN) < 0) {
 
1764
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1765
                             "%s", _("malformed vcpu mask information"));
 
1766
            goto error;
 
1767
        }
 
1768
    }
 
1769
    xmlXPathFreeObject(obj);
 
1770
 
1161
1771
    /* See if ACPI feature is requested */
1162
1772
    obj = xmlXPathEval(BAD_CAST "/domain/features/acpi", ctxt);
1163
1773
    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
1173
1783
        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
1174
1784
        def->noReboot = 0;
1175
1785
    } else {
1176
 
        if (!strcmp((char*)obj->stringval, "destroy"))
 
1786
        if (STREQ((char*)obj->stringval, "destroy"))
1177
1787
            def->noReboot = 1;
1178
1788
        else
1179
1789
            def->noReboot = 0;
1186
1796
        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
1187
1797
        def->localtime = 0;
1188
1798
    } else {
1189
 
        if (!strcmp((char*)obj->stringval, "localtime"))
 
1799
        if (STREQ((char*)obj->stringval, "localtime"))
1190
1800
            def->localtime = 1;
1191
1801
        else
1192
1802
            def->localtime = 0;
1194
1804
    xmlXPathFreeObject(obj);
1195
1805
 
1196
1806
 
 
1807
    /* Extract bootloader */
 
1808
    obj = xmlXPathEval(BAD_CAST "string(/domain/bootloader)", ctxt);
 
1809
    if ((obj != NULL) && (obj->type == XPATH_STRING) &&
 
1810
        (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
 
1811
        strncpy(def->os.bootloader, (const char*)obj->stringval, sizeof(def->os.bootloader));
 
1812
        NUL_TERMINATE(def->os.bootloader);
 
1813
 
 
1814
        /* Set a default OS type, since <type> is optional with bootloader */
 
1815
        strcpy(def->os.type, "xen");
 
1816
    }
 
1817
    xmlXPathFreeObject(obj);
 
1818
 
1197
1819
    /* Extract OS type info */
1198
1820
    obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1])", ctxt);
1199
1821
    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
1200
1822
        (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
1201
 
        qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
1202
 
                         "%s", _("no OS type"));
1203
 
        goto error;
1204
 
    }
1205
 
    if (!virCapabilitiesSupportsGuestOSType(driver->caps, (const char*)obj->stringval)) {
1206
 
        qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
1207
 
                         "%s", obj->stringval);
1208
 
        goto error;
1209
 
    }
1210
 
    strcpy(def->os.type, (const char *)obj->stringval);
 
1823
        if (!def->os.type[0]) {
 
1824
            qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
 
1825
                             "%s", _("no OS type"));
 
1826
            goto error;
 
1827
        }
 
1828
    } else {
 
1829
        strcpy(def->os.type, (const char *)obj->stringval);
 
1830
    }
1211
1831
    xmlXPathFreeObject(obj);
 
1832
    obj = NULL;
1212
1833
 
 
1834
    if (!virCapabilitiesSupportsGuestOSType(driver->caps, def->os.type)) {
 
1835
        qemudReportError(conn, NULL, NULL, VIR_ERR_OS_TYPE,
 
1836
                         "%s", def->os.type);
 
1837
        goto error;
 
1838
    }
1213
1839
 
1214
1840
    obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@arch)", ctxt);
1215
1841
    if ((obj == NULL) || (obj->type != XPATH_STRING) ||
1264
1890
    xmlXPathFreeObject(obj);
1265
1891
 
1266
1892
 
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"));
1273
 
            goto error;
1274
 
        }
1275
 
        strcpy(def->os.kernel, (const char *)obj->stringval);
1276
 
    }
1277
 
    xmlXPathFreeObject(obj);
1278
 
 
1279
 
 
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"));
1286
 
            goto error;
1287
 
        }
1288
 
        strcpy(def->os.initrd, (const char *)obj->stringval);
1289
 
    }
1290
 
    xmlXPathFreeObject(obj);
1291
 
 
1292
 
 
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"));
1299
 
            goto error;
1300
 
        }
1301
 
        strcpy(def->os.cmdline, (const char *)obj->stringval);
1302
 
    }
1303
 
    xmlXPathFreeObject(obj);
1304
 
 
1305
 
 
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")))
1312
 
                continue;
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;
1321
 
            } else {
1322
 
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1323
 
                             _("unknown boot device \'%s\'"), (char*)prop);
1324
 
                goto error;
1325
 
            }
1326
 
            xmlFree(prop);
1327
 
            prop = NULL;
1328
 
        }
1329
 
    }
1330
 
    xmlXPathFreeObject(obj);
1331
 
    if (def->os.nBootDevs == 0) {
1332
 
        def->os.nBootDevs = 1;
1333
 
        def->os.bootDevs[0] = QEMUD_BOOT_DISK;
1334
 
    }
1335
 
 
 
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"));
 
1900
                goto error;
 
1901
            }
 
1902
            strcpy(def->os.kernel, (const char *)obj->stringval);
 
1903
        }
 
1904
        xmlXPathFreeObject(obj);
 
1905
 
 
1906
 
 
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"));
 
1913
                goto error;
 
1914
            }
 
1915
            strcpy(def->os.initrd, (const char *)obj->stringval);
 
1916
        }
 
1917
        xmlXPathFreeObject(obj);
 
1918
 
 
1919
 
 
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"));
 
1926
                goto error;
 
1927
            }
 
1928
            strcpy(def->os.cmdline, (const char *)obj->stringval);
 
1929
        }
 
1930
        xmlXPathFreeObject(obj);
 
1931
 
 
1932
 
 
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")))
 
1939
                    continue;
 
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;
 
1948
                } else {
 
1949
                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1950
                                     _("unknown boot device \'%s\'"), (char*)prop);
 
1951
                    goto error;
 
1952
                }
 
1953
                xmlFree(prop);
 
1954
                prop = NULL;
 
1955
            }
 
1956
        }
 
1957
        xmlXPathFreeObject(obj);
 
1958
        if (def->os.nBootDevs == 0) {
 
1959
            def->os.nBootDevs = 1;
 
1960
            def->os.bootDevs[0] = QEMUD_BOOT_DISK;
 
1961
        }
 
1962
    }
1336
1963
 
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":
1342
 
                            "kvm");
 
1967
        const char *type = qemudVirtTypeToString(def->virtType);
 
1968
        if (!type) {
 
1969
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
1970
                             "%s", _("unknown virt type"));
 
1971
            goto error;
 
1972
        }
1343
1973
        const char *emulator = virCapabilitiesDefaultGuestEmulator(driver->caps,
1344
1974
                                                                   def->os.type,
1345
1975
                                                                   def->os.arch,
1365
1995
        (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) {
1366
1996
        def->graphicsType = QEMUD_GRAPHICS_NONE;
1367
1997
    } else if ((prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type"))) {
1368
 
        if (!strcmp((char *)prop, "vnc")) {
 
1998
        if (STREQ((char *)prop, "vnc")) {
1369
1999
            xmlChar *vncport, *vnclisten;
1370
2000
            def->graphicsType = QEMUD_GRAPHICS_VNC;
1371
2001
            vncport = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "port");
1384
2014
            def->keymap = (char *) xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "keymap");
1385
2015
            xmlFree(vncport);
1386
2016
            xmlFree(vnclisten);
1387
 
        } else if (!strcmp((char *)prop, "sdl")) {
 
2017
        } else if (STREQ((char *)prop, "sdl")) {
1388
2018
            def->graphicsType = QEMUD_GRAPHICS_SDL;
1389
2019
        } else {
1390
2020
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
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));
1406
 
            if (!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"));
1409
2038
                goto error;
1410
2039
            }
1411
2040
            if (qemudParseDiskXML(conn, disk, obj->nodesetval->nodeTab[i]) < 0) {
1412
 
                free(disk);
 
2041
                VIR_FREE(disk);
1413
2042
                goto error;
1414
2043
            }
1415
2044
            def->ndisks++;
1416
 
            disk->next = NULL;
1417
2045
            if (i == 0) {
 
2046
                disk->next = NULL;
1418
2047
                def->disks = disk;
1419
2048
            } else {
1420
 
                prev->next = disk;
 
2049
                struct qemud_vm_disk_def *ptr = def->disks;
 
2050
                while (ptr) {
 
2051
                    if (!ptr->next || qemudDiskCompare(disk, ptr->next) < 0) {
 
2052
                        disk->next = ptr->next;
 
2053
                        ptr->next = disk;
 
2054
                        break;
 
2055
                    }
 
2056
                    ptr = ptr->next;
 
2057
                }
1421
2058
            }
1422
 
            prev = disk;
1423
2059
        }
1424
2060
    }
1425
2061
    xmlXPathFreeObject(obj);
 
2062
    obj = NULL;
 
2063
 
 
2064
    /* analysis of the character devices */
 
2065
    if (qemudParseCharXMLDevices(conn, ctxt,
 
2066
                                 "/domain/devices/parallel",
 
2067
                                 &def->nparallels,
 
2068
                                 &def->parallels) < 0)
 
2069
        goto error;
 
2070
    if (qemudParseCharXMLDevices(conn, ctxt,
 
2071
                                 "/domain/devices/serial",
 
2072
                                 &def->nserials,
 
2073
                                 &def->serials) < 0)
 
2074
        goto error;
 
2075
 
 
2076
    /*
 
2077
     * If no serial devices were listed, then look for console
 
2078
     * devices which is the legacy syntax for the same thing
 
2079
     */
 
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,
 
2087
                                 "%s",
 
2088
                                 _("failed to allocate space for char device"));
 
2089
                goto error;
 
2090
            }
 
2091
 
 
2092
            if (qemudParseCharXML(conn, chr, 0, obj->nodesetval->nodeTab[0]) < 0) {
 
2093
                VIR_FREE(chr);
 
2094
                goto error;
 
2095
            }
 
2096
            def->nserials = 1;
 
2097
            def->serials = chr;
 
2098
        }
 
2099
        xmlXPathFreeObject(obj);
 
2100
    }
1426
2101
 
1427
2102
 
1428
2103
    /* analysis of the network devices */
1431
2106
        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
1432
2107
        struct qemud_vm_net_def *prev = NULL;
1433
2108
        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
1434
 
            struct qemud_vm_net_def *net = calloc(1, sizeof(*net));
1435
 
            if (!net) {
 
2109
            struct qemud_vm_net_def *net;
 
2110
            if (VIR_ALLOC(net) < 0) {
1436
2111
                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1437
2112
                           "%s", _("failed to allocate space for net string"));
1438
2113
                goto error;
1439
2114
            }
1440
2115
            if (qemudParseInterfaceXML(conn, net, obj->nodesetval->nodeTab[i]) < 0) {
1441
 
                free(net);
 
2116
                VIR_FREE(net);
1442
2117
                goto error;
1443
2118
            }
1444
2119
            def->nnets++;
1459
2134
        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
1460
2135
        struct qemud_vm_input_def *prev = NULL;
1461
2136
        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
1462
 
            struct qemud_vm_input_def *input = calloc(1, sizeof(*input));
1463
 
            if (!input) {
 
2137
            struct qemud_vm_input_def *input;
 
2138
            if (VIR_ALLOC(input) < 0) {
1464
2139
                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1465
2140
                         "%s", _("failed to allocate space for input string"));
1466
2141
                goto error;
1467
2142
            }
1468
 
            if (qemudParseInputXML(conn, input, obj->nodesetval->nodeTab[i]) < 0) {
1469
 
                free(input);
 
2143
            if (qemudParseInputXML(conn, def, input, obj->nodesetval->nodeTab[i]) < 0) {
 
2144
                VIR_FREE(input);
1470
2145
                goto error;
1471
2146
            }
1472
2147
            /* Mouse + PS/2 is implicit with graphics, so don't store it */
1473
2148
            if (input->bus == QEMU_INPUT_BUS_PS2 &&
1474
2149
                input->type == QEMU_INPUT_TYPE_MOUSE) {
1475
 
                free(input);
 
2150
                VIR_FREE(input);
1476
2151
                continue;
1477
2152
            }
1478
2153
            def->ninputs++;
1486
2161
        }
1487
2162
    }
1488
2163
    xmlXPathFreeObject(obj);
 
2164
 
 
2165
    /* Parse sound driver xml */
 
2166
    obj = xmlXPathEval(BAD_CAST "/domain/devices/sound", ctxt);
 
2167
    if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
 
2168
        (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
 
2169
        struct qemud_vm_sound_def *prev = NULL;
 
2170
        for (i = 0; i < obj->nodesetval->nodeNr; i++) {
 
2171
 
 
2172
            struct qemud_vm_sound_def *sound;
 
2173
            struct qemud_vm_sound_def *check = def->sounds;
 
2174
            int collision = 0;
 
2175
            if (VIR_ALLOC(sound) < 0) {
 
2176
                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
 
2177
                         "%s", _("failed to allocate space for sound dev"));
 
2178
                goto error;
 
2179
            }
 
2180
            if (qemudParseSoundXML(conn, sound,
 
2181
                                   obj->nodesetval->nodeTab[i]) < 0) {
 
2182
                VIR_FREE(sound);
 
2183
                goto error;
 
2184
            }
 
2185
 
 
2186
            // Check that model type isn't already present in sound dev list
 
2187
            while(check) {
 
2188
                if (check->model == sound->model) {
 
2189
                    collision = 1;
 
2190
                    break;
 
2191
                }
 
2192
                check = check->next;
 
2193
            }
 
2194
            if (collision) {
 
2195
                VIR_FREE(sound);
 
2196
                continue;
 
2197
            }
 
2198
 
 
2199
            def->nsounds++;
 
2200
            sound->next = NULL;
 
2201
            if (def->sounds == NULL) {
 
2202
                def->sounds = sound;
 
2203
            } else {
 
2204
                prev->next = sound;
 
2205
            }
 
2206
            prev = sound;
 
2207
        }
 
2208
    }
 
2209
    xmlXPathFreeObject(obj);
1489
2210
    obj = NULL;
1490
2211
 
1491
2212
    /* If graphics are enabled, there's an implicit PS2 mouse */
1500
2221
        }
1501
2222
 
1502
2223
        if (!hasPS2mouse) {
1503
 
            input = calloc(1, sizeof(*input));
1504
 
            if (!input) {
 
2224
            if (VIR_ALLOC(input) < 0) {
1505
2225
                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1506
2226
                         "%s", _("failed to allocate space for input string"));
1507
2227
                goto error;
1519
2239
    return def;
1520
2240
 
1521
2241
 error:
1522
 
    free(prop);
 
2242
    VIR_FREE(prop);
1523
2243
    xmlXPathFreeObject(obj);
1524
2244
    xmlXPathFreeContext(ctxt);
1525
2245
    qemudFreeVMDef(def);
1541
2261
    char *retval = NULL;
1542
2262
    int err;
1543
2263
    int tapfd = -1;
1544
 
    int *tapfds;
1545
2264
 
1546
2265
    if (net->type == QEMUD_NET_NETWORK) {
1547
2266
        if (!(network = qemudFindNetworkByName(driver, net->dst.network.name))) {
1557
2276
        }
1558
2277
        brname = network->bridge;
1559
2278
        if (net->dst.network.ifname[0] == '\0' ||
1560
 
            STREQLEN(net->dst.network.ifname, "vnet", 4) ||
 
2279
            STRPREFIX(net->dst.network.ifname, "vnet") ||
1561
2280
            strchr(net->dst.network.ifname, '%')) {
1562
2281
            strcpy(net->dst.network.ifname, "vnet%d");
1563
2282
        }
1565
2284
    } else if (net->type == QEMUD_NET_BRIDGE) {
1566
2285
        brname = net->dst.bridge.brname;
1567
2286
        if (net->dst.bridge.ifname[0] == '\0' ||
1568
 
            STREQLEN(net->dst.bridge.ifname, "vnet", 4) ||
 
2287
            STRPREFIX(net->dst.bridge.ifname, "vnet") ||
1569
2288
            strchr(net->dst.bridge.ifname, '%')) {
1570
2289
            strcpy(net->dst.bridge.ifname, "vnet%d");
1571
2290
        }
1598
2317
    if (!(retval = strdup(tapfdstr)))
1599
2318
        goto no_memory;
1600
2319
 
1601
 
    if (!(tapfds = realloc(vm->tapfds, sizeof(*tapfds) * (vm->ntapfds+2))))
 
2320
    if (VIR_REALLOC_N(vm->tapfds, vm->ntapfds+2) < 0)
1602
2321
        goto no_memory;
1603
2322
 
1604
 
    vm->tapfds = tapfds;
1605
2323
    vm->tapfds[vm->ntapfds++] = tapfd;
1606
2324
    vm->tapfds[vm->ntapfds]   = -1;
1607
2325
 
1611
2329
    qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
1612
2330
                     "%s", _("failed to allocate space for tapfds string"));
1613
2331
 error:
1614
 
    free(retval);
 
2332
    VIR_FREE(retval);
1615
2333
    if (tapfd != -1)
1616
2334
        close(tapfd);
1617
2335
    return NULL;
1618
2336
}
1619
2337
 
 
2338
static int qemudBuildCommandLineChrDevStr(struct qemud_vm_chr_def *dev,
 
2339
                                          char *buf,
 
2340
                                          int buflen)
 
2341
{
 
2342
    switch (dev->srcType) {
 
2343
    case QEMUD_CHR_SRC_TYPE_NULL:
 
2344
        strncpy(buf, "null", buflen);
 
2345
        buf[buflen-1] = '\0';
 
2346
        break;
 
2347
 
 
2348
    case QEMUD_CHR_SRC_TYPE_VC:
 
2349
        strncpy(buf, "vc", buflen);
 
2350
        buf[buflen-1] = '\0';
 
2351
        break;
 
2352
 
 
2353
    case QEMUD_CHR_SRC_TYPE_PTY:
 
2354
        strncpy(buf, "pty", buflen);
 
2355
        buf[buflen-1] = '\0';
 
2356
        break;
 
2357
 
 
2358
    case QEMUD_CHR_SRC_TYPE_DEV:
 
2359
        if (snprintf(buf, buflen, "%s",
 
2360
                     dev->srcData.file.path) >= buflen)
 
2361
            return -1;
 
2362
        break;
 
2363
 
 
2364
    case QEMUD_CHR_SRC_TYPE_FILE:
 
2365
        if (snprintf(buf, buflen, "file:%s",
 
2366
                     dev->srcData.file.path) >= buflen)
 
2367
            return -1;
 
2368
        break;
 
2369
 
 
2370
    case QEMUD_CHR_SRC_TYPE_PIPE:
 
2371
        if (snprintf(buf, buflen, "pipe:%s",
 
2372
                     dev->srcData.file.path) >= buflen)
 
2373
            return -1;
 
2374
        break;
 
2375
 
 
2376
    case QEMUD_CHR_SRC_TYPE_STDIO:
 
2377
        strncpy(buf, "stdio", buflen);
 
2378
        buf[buflen-1] = '\0';
 
2379
        break;
 
2380
 
 
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)
 
2387
            return -1;
 
2388
        break;
 
2389
 
 
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)
 
2396
            return -1;
 
2397
        break;
 
2398
 
 
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)
 
2403
            return -1;
 
2404
        break;
 
2405
    }
 
2406
 
 
2407
    return 0;
 
2408
}
 
2409
 
1620
2410
/*
1621
2411
 * Constructs a argv suitable for launching qemu with config defined
1622
2412
 * for a given virtual machine.
1624
2414
int qemudBuildCommandLine(virConnectPtr conn,
1625
2415
                          struct qemud_driver *driver,
1626
2416
                          struct qemud_vm *vm,
1627
 
                          char ***argv) {
1628
 
    int len, n = -1, i;
 
2417
                          char ***retargv) {
 
2418
    int i;
1629
2419
    char memory[50];
1630
2420
    char vcpus[50];
1631
2421
    char boot[QEMUD_MAX_BOOT_DEVS+1];
1632
 
    struct stat sb;
1633
2422
    struct qemud_vm_disk_def *disk = vm->def->disks;
1634
2423
    struct qemud_vm_net_def *net = vm->def->nets;
1635
2424
    struct qemud_vm_input_def *input = vm->def->inputs;
 
2425
    struct qemud_vm_sound_def *sound = vm->def->sounds;
 
2426
    struct qemud_vm_chr_def *serial = vm->def->serials;
 
2427
    struct qemud_vm_chr_def *parallel = vm->def->parallels;
1636
2428
    struct utsname ut;
1637
2429
    int disableKQEMU = 0;
1638
 
 
1639
 
    /* Make sure the binary we are about to try exec'ing exists.
1640
 
     * Technically we could catch the exec() failure, but that's
1641
 
     * in a sub-process so its hard to feed back a useful error
1642
 
     */
1643
 
    if (stat(vm->def->os.binary, &sb) < 0) {
1644
 
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
1645
 
                         _("Cannot find QEMU binary %s: %s"),
1646
 
                         vm->def->os.binary,
1647
 
                         strerror(errno));
1648
 
        return -1;
1649
 
    }
 
2430
    int qargc = 0, qarga = 0;
 
2431
    char **qargv = NULL;
1650
2432
 
1651
2433
    if (vm->qemuVersion == 0) {
1652
2434
        if (qemudExtractVersionInfo(vm->def->os.binary,
1670
2452
     * 3. The qemu binary has the -no-kqemu flag
1671
2453
     */
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;
1676
2458
 
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 */
1682
 
        1 + /* usb */
1683
 
        2 * vm->def->ninputs + /* input devices */
1684
 
        2 + /* memory*/
1685
 
        2 + /* cpus */
1686
 
        2 + /* boot device */
1687
 
        2 + /* monitor */
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                                                   \
 
2460
    do { \
 
2461
        if (qargc == qarga) {                                           \
 
2462
            qarga += 10;                                                \
 
2463
            if (VIR_REALLOC_N(qargv, qarga) < 0)                        \
 
2464
                goto no_memory;                                         \
 
2465
        }                                                               \
 
2466
    } while (0)
 
2467
 
 
2468
#define ADD_ARG(thisarg)                                                \
 
2469
    do {                                                                \
 
2470
        ADD_ARG_SPACE;                                                  \
 
2471
        qargv[qargc++] = thisarg;                                       \
 
2472
    } while (0)
 
2473
 
 
2474
#define ADD_ARG_LIT(thisarg)                                            \
 
2475
    do {                                                                \
 
2476
        ADD_ARG_SPACE;                                                  \
 
2477
        if ((qargv[qargc++] = strdup(thisarg)) == NULL)                 \
 
2478
            goto no_memory;                                             \
 
2479
    } while (0)
1698
2480
 
1699
2481
    snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
1700
2482
    snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus);
1701
2483
 
1702
 
    if (!(*argv = malloc(sizeof(**argv) * (len+1))))
1703
 
        goto no_memory;
1704
 
    if (!((*argv)[++n] = strdup(vm->def->os.binary)))
1705
 
        goto no_memory;
1706
 
    if (!((*argv)[++n] = strdup("-M")))
1707
 
        goto no_memory;
1708
 
    if (!((*argv)[++n] = strdup(vm->def->os.machine)))
1709
 
        goto no_memory;
1710
 
    if (disableKQEMU) {
1711
 
        if (!((*argv)[++n] = strdup("-no-kqemu")))
1712
 
            goto no_memory;
 
2484
 
 
2485
    ADD_ARG_LIT(vm->def->os.binary);
 
2486
    ADD_ARG_LIT("-S");
 
2487
    ADD_ARG_LIT("-M");
 
2488
    ADD_ARG_LIT(vm->def->os.machine);
 
2489
    if (disableKQEMU)
 
2490
        ADD_ARG_LIT("-no-kqemu");
 
2491
    ADD_ARG_LIT("-m");
 
2492
    ADD_ARG_LIT(memory);
 
2493
    ADD_ARG_LIT("-smp");
 
2494
    ADD_ARG_LIT(vcpus);
 
2495
 
 
2496
    if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
 
2497
        ADD_ARG_LIT("-name");
 
2498
        ADD_ARG_LIT(vm->def->name);
1713
2499
    }
1714
 
    if (!((*argv)[++n] = strdup("-m")))
1715
 
        goto no_memory;
1716
 
    if (!((*argv)[++n] = strdup(memory)))
1717
 
        goto no_memory;
1718
 
    if (!((*argv)[++n] = strdup("-smp")))
1719
 
        goto no_memory;
1720
 
    if (!((*argv)[++n] = strdup(vcpus)))
1721
 
        goto no_memory;
1722
 
 
1723
2500
    /*
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...
1729
2506
     */
1730
 
    if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
1731
 
        if (!((*argv)[++n] = strdup("-nographic")))
1732
 
            goto no_memory;
1733
 
    }
1734
 
 
1735
 
    if (!((*argv)[++n] = strdup("-monitor")))
1736
 
        goto no_memory;
1737
 
    if (!((*argv)[++n] = strdup("pty")))
1738
 
        goto no_memory;
1739
 
 
1740
 
    if (vm->def->localtime) {
1741
 
        if (!((*argv)[++n] = strdup("-localtime")))
1742
 
            goto no_memory;
1743
 
    }
1744
 
 
1745
 
    if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
1746
 
        vm->def->noReboot) {
1747
 
        if (!((*argv)[++n] = strdup("-no-reboot")))
1748
 
            goto no_memory;
1749
 
    }
1750
 
 
1751
 
    if (!(vm->def->features & QEMUD_FEATURE_ACPI)) {
1752
 
        if (!((*argv)[++n] = strdup("-no-acpi")))
1753
 
            goto no_memory;
1754
 
    }
1755
 
 
1756
 
    for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
1757
 
        switch (vm->def->os.bootDevs[i]) {
1758
 
        case QEMUD_BOOT_CDROM:
1759
 
            boot[i] = 'd';
1760
 
            break;
1761
 
        case QEMUD_BOOT_FLOPPY:
1762
 
            boot[i] = 'a';
1763
 
            break;
1764
 
        case QEMUD_BOOT_DISK:
1765
 
            boot[i] = 'c';
1766
 
            break;
1767
 
        case QEMUD_BOOT_NET:
1768
 
            boot[i] = 'n';
1769
 
            break;
1770
 
        default:
1771
 
            boot[i] = 'c';
1772
 
            break;
1773
 
        }
1774
 
    }
1775
 
    boot[vm->def->os.nBootDevs] = '\0';
1776
 
    if (!((*argv)[++n] = strdup("-boot")))
1777
 
        goto no_memory;
1778
 
    if (!((*argv)[++n] = strdup(boot)))
1779
 
        goto no_memory;
1780
 
 
1781
 
    if (vm->def->os.kernel[0]) {
1782
 
        if (!((*argv)[++n] = strdup("-kernel")))
1783
 
            goto no_memory;
1784
 
        if (!((*argv)[++n] = strdup(vm->def->os.kernel)))
1785
 
            goto no_memory;
1786
 
    }
1787
 
    if (vm->def->os.initrd[0]) {
1788
 
        if (!((*argv)[++n] = strdup("-initrd")))
1789
 
            goto no_memory;
1790
 
        if (!((*argv)[++n] = strdup(vm->def->os.initrd)))
1791
 
            goto no_memory;
1792
 
    }
1793
 
    if (vm->def->os.cmdline[0]) {
1794
 
        if (!((*argv)[++n] = strdup("-append")))
1795
 
            goto no_memory;
1796
 
        if (!((*argv)[++n] = strdup(vm->def->os.cmdline)))
1797
 
            goto no_memory;
1798
 
    }
1799
 
 
1800
 
    while (disk) {
1801
 
        char dev[NAME_MAX];
1802
 
        char file[PATH_MAX];
1803
 
        if (!strcmp(disk->dst, "hdc") &&
1804
 
            disk->device == QEMUD_DISK_CDROM) {
1805
 
            if (disk->src[0])
1806
 
                snprintf(dev, NAME_MAX, "-%s", "cdrom");
1807
 
            else {
1808
 
                /* Don't put anything on the cmdline for an empty cdrom*/
1809
 
                disk = disk->next;
1810
 
                continue;
1811
 
            }
1812
 
        } else
1813
 
            snprintf(dev, NAME_MAX, "-%s", disk->dst);
1814
 
        snprintf(file, PATH_MAX, "%s", disk->src);
1815
 
 
1816
 
        if (!((*argv)[++n] = strdup(dev)))
1817
 
            goto no_memory;
1818
 
        if (!((*argv)[++n] = strdup(file)))
1819
 
            goto no_memory;
1820
 
 
1821
 
        disk = disk->next;
 
2507
    if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE)
 
2508
        ADD_ARG_LIT("-nographic");
 
2509
 
 
2510
    ADD_ARG_LIT("-monitor");
 
2511
    ADD_ARG_LIT("pty");
 
2512
 
 
2513
    if (vm->def->localtime)
 
2514
        ADD_ARG_LIT("-localtime");
 
2515
 
 
2516
    if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
 
2517
        vm->def->noReboot)
 
2518
        ADD_ARG_LIT("-no-reboot");
 
2519
 
 
2520
    if (!(vm->def->features & QEMUD_FEATURE_ACPI))
 
2521
        ADD_ARG_LIT("-no-acpi");
 
2522
 
 
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:
 
2527
                boot[i] = 'd';
 
2528
                break;
 
2529
            case QEMUD_BOOT_FLOPPY:
 
2530
                boot[i] = 'a';
 
2531
                break;
 
2532
            case QEMUD_BOOT_DISK:
 
2533
                boot[i] = 'c';
 
2534
                break;
 
2535
            case QEMUD_BOOT_NET:
 
2536
                boot[i] = 'n';
 
2537
                break;
 
2538
            default:
 
2539
                boot[i] = 'c';
 
2540
                break;
 
2541
            }
 
2542
        }
 
2543
        boot[vm->def->os.nBootDevs] = '\0';
 
2544
        ADD_ARG_LIT("-boot");
 
2545
        ADD_ARG_LIT(boot);
 
2546
 
 
2547
        if (vm->def->os.kernel[0]) {
 
2548
            ADD_ARG_LIT("-kernel");
 
2549
            ADD_ARG_LIT(vm->def->os.kernel);
 
2550
        }
 
2551
        if (vm->def->os.initrd[0]) {
 
2552
            ADD_ARG_LIT("-initrd");
 
2553
            ADD_ARG_LIT(vm->def->os.initrd);
 
2554
        }
 
2555
        if (vm->def->os.cmdline[0]) {
 
2556
            ADD_ARG_LIT("-append");
 
2557
            ADD_ARG_LIT(vm->def->os.cmdline);
 
2558
        }
 
2559
    } else {
 
2560
        ADD_ARG_LIT("-bootloader");
 
2561
        ADD_ARG_LIT(vm->def->os.bootloader);
 
2562
    }
 
2563
 
 
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;
 
2567
 
 
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:
 
2573
                    bootCD = 1;
 
2574
                    break;
 
2575
                case QEMUD_BOOT_FLOPPY:
 
2576
                    bootFloppy = 1;
 
2577
                    break;
 
2578
                case QEMUD_BOOT_DISK:
 
2579
                    bootDisk = 1;
 
2580
                    break;
 
2581
                }
 
2582
            }
 
2583
        }
 
2584
 
 
2585
        while (disk) {
 
2586
            char opt[PATH_MAX];
 
2587
            const char *media = NULL;
 
2588
            int bootable = 0;
 
2589
            int idx = virDiskNameToIndex(disk->dst);
 
2590
 
 
2591
            if (idx < 0) {
 
2592
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
2593
                                 _("unsupported disk type '%s'"), disk->dst);
 
2594
                goto error;
 
2595
            }
 
2596
 
 
2597
            if (disk->device == QEMUD_DISK_CDROM)
 
2598
                media = "media=cdrom,";
 
2599
 
 
2600
            switch (disk->device) {
 
2601
            case QEMUD_DISK_CDROM:
 
2602
                bootable = bootCD;
 
2603
                bootCD = 0;
 
2604
                break;
 
2605
            case QEMUD_DISK_FLOPPY:
 
2606
                bootable = bootFloppy;
 
2607
                bootFloppy = 0;
 
2608
                break;
 
2609
            case QEMUD_DISK_DISK:
 
2610
                bootable = bootDisk;
 
2611
                bootDisk = 0;
 
2612
                break;
 
2613
            }
 
2614
 
 
2615
            snprintf(opt, PATH_MAX, "file=%s,if=%s,%sindex=%d%s",
 
2616
                     disk->src, qemudBusIdToName(disk->bus, 1),
 
2617
                     media ? media : "",
 
2618
                     idx,
 
2619
                     bootable ? ",boot=on" : "");
 
2620
 
 
2621
            ADD_ARG_LIT("-drive");
 
2622
            ADD_ARG_LIT(opt);
 
2623
            disk = disk->next;
 
2624
        }
 
2625
    } else {
 
2626
        while (disk) {
 
2627
            char dev[NAME_MAX];
 
2628
            char file[PATH_MAX];
 
2629
 
 
2630
            if (STREQ(disk->dst, "hdc") &&
 
2631
                disk->device == QEMUD_DISK_CDROM) {
 
2632
                if (disk->src[0]) {
 
2633
                    snprintf(dev, NAME_MAX, "-%s", "cdrom");
 
2634
                } else {
 
2635
                    disk = disk->next;
 
2636
                    continue;
 
2637
                }
 
2638
            } else {
 
2639
                if (STRPREFIX(disk->dst, "hd") ||
 
2640
                    STRPREFIX(disk->dst, "fd")) {
 
2641
                    snprintf(dev, NAME_MAX, "-%s", disk->dst);
 
2642
                } else {
 
2643
                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
2644
                                     _("unsupported disk type '%s'"), disk->dst);
 
2645
                    goto error;
 
2646
                }
 
2647
            }
 
2648
 
 
2649
            snprintf(file, PATH_MAX, "%s", disk->src);
 
2650
 
 
2651
            ADD_ARG_LIT(dev);
 
2652
            ADD_ARG_LIT(file);
 
2653
 
 
2654
            disk = disk->next;
 
2655
        }
1822
2656
    }
1823
2657
 
1824
2658
    if (!net) {
1825
 
        if (!((*argv)[++n] = strdup("-net")))
1826
 
            goto no_memory;
1827
 
        if (!((*argv)[++n] = strdup("none")))
1828
 
            goto no_memory;
 
2659
        ADD_ARG_LIT("-net");
 
2660
        ADD_ARG_LIT("none");
1829
2661
    } else {
1830
2662
        int vlan = 0;
1831
2663
        while (net) {
1832
2664
            char nic[100];
1833
2665
 
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))
 
2671
                         vlan,
 
2672
                         (net->model[0] ? ",model=" : ""), net->model) >= sizeof(nic))
1839
2673
                goto error;
1840
2674
 
1841
 
            if (!((*argv)[++n] = strdup("-net")))
1842
 
                goto no_memory;
1843
 
            if (!((*argv)[++n] = strdup(nic)))
1844
 
                goto no_memory;
1845
 
 
1846
 
            if (!((*argv)[++n] = strdup("-net")))
1847
 
                goto no_memory;
 
2675
            ADD_ARG_LIT("-net");
 
2676
            ADD_ARG_LIT(nic);
 
2677
            ADD_ARG_LIT("-net");
1848
2678
 
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)))
1853
 
                    goto error;
1854
 
                break;
 
2682
                {
 
2683
                    char *tap = qemudNetworkIfaceConnect(conn, driver, vm, net, vlan);
 
2684
                    if (tap == NULL)
 
2685
                        goto error;
 
2686
                    ADD_ARG(tap);
 
2687
                    break;
 
2688
                }
1855
2689
 
1856
2690
            case QEMUD_NET_ETHERNET:
1857
2691
                {
1862
2696
                                 vlan) >= (PATH_MAX-1))
1863
2697
                        goto error;
1864
2698
 
1865
 
                    if (!((*argv)[++n] = strdup(arg)))
1866
 
                        goto no_memory;
 
2699
                    ADD_ARG_LIT(arg);
1867
2700
                }
1868
2701
                break;
1869
2702
 
1891
2724
                                 vlan) >= (PATH_MAX-1))
1892
2725
                        goto error;
1893
2726
 
1894
 
                    if (!((*argv)[++n] = strdup(arg)))
1895
 
                        goto no_memory;
 
2727
                    ADD_ARG_LIT(arg);
1896
2728
                }
1897
2729
                break;
1898
2730
 
1903
2735
                    if (snprintf(arg, PATH_MAX-1, "user,vlan=%d", vlan) >= (PATH_MAX-1))
1904
2736
                        goto error;
1905
2737
 
1906
 
                    if (!((*argv)[++n] = strdup(arg)))
1907
 
                        goto no_memory;
 
2738
                    ADD_ARG_LIT(arg);
1908
2739
                }
1909
2740
            }
1910
2741
 
1913
2744
        }
1914
2745
    }
1915
2746
 
1916
 
    if (!((*argv)[++n] = strdup("-usb")))
1917
 
        goto no_memory;
 
2747
    if (!serial) {
 
2748
        ADD_ARG_LIT("-serial");
 
2749
        ADD_ARG_LIT("none");
 
2750
    } else {
 
2751
        while (serial) {
 
2752
            char buf[4096];
 
2753
 
 
2754
            if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0)
 
2755
                goto error;
 
2756
 
 
2757
            ADD_ARG_LIT("-serial");
 
2758
            ADD_ARG_LIT(buf);
 
2759
 
 
2760
            serial = serial->next;
 
2761
        }
 
2762
    }
 
2763
 
 
2764
    if (!parallel) {
 
2765
        ADD_ARG_LIT("-parallel");
 
2766
        ADD_ARG_LIT("none");
 
2767
    } else {
 
2768
        while (parallel) {
 
2769
            char buf[4096];
 
2770
 
 
2771
            if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0)
 
2772
                goto error;
 
2773
 
 
2774
            ADD_ARG_LIT("-parallel");
 
2775
            ADD_ARG_LIT(buf);
 
2776
 
 
2777
            parallel = parallel->next;
 
2778
        }
 
2779
    }
 
2780
 
 
2781
    ADD_ARG_LIT("-usb");
1918
2782
    while (input) {
1919
2783
        if (input->bus == QEMU_INPUT_BUS_USB) {
1920
 
            if (!((*argv)[++n] = strdup("-usbdevice")))
1921
 
                goto no_memory;
1922
 
            if (!((*argv)[++n] = strdup(input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet")))
1923
 
                goto no_memory;
 
2784
            ADD_ARG_LIT("-usbdevice");
 
2785
            ADD_ARG_LIT(input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
1924
2786
        }
1925
2787
 
1926
2788
        input = input->next;
1954
2816
        if (ret < 0 || ret >= (int)sizeof(vncdisplay))
1955
2817
            goto error;
1956
2818
 
1957
 
        if (!((*argv)[++n] = strdup("-vnc")))
1958
 
            goto no_memory;
1959
 
        if (!((*argv)[++n] = strdup(vncdisplay)))
1960
 
            goto no_memory;
 
2819
        ADD_ARG_LIT("-vnc");
 
2820
        ADD_ARG_LIT(vncdisplay);
1961
2821
        if (vm->def->keymap) {
1962
 
            if (!((*argv)[++n] = strdup("-k")))
1963
 
                goto no_memory;
1964
 
            if (!((*argv)[++n] = strdup(vm->def->keymap)))
1965
 
                goto no_memory;
 
2822
            ADD_ARG_LIT("-k");
 
2823
            ADD_ARG_LIT(vm->def->keymap);
1966
2824
        }
1967
2825
    } else if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
1968
2826
        /* Nada - we added -nographic earlier in this function */
1970
2828
        /* SDL is the default. no args needed */
1971
2829
    }
1972
2830
 
 
2831
    /* Add sound hardware */
 
2832
    if (sound) {
 
2833
        int size = 100;
 
2834
        char *modstr;
 
2835
        if (VIR_ALLOC_N(modstr, size+1) < 0)
 
2836
            goto no_memory;
 
2837
 
 
2838
        while(sound && size > 0) {
 
2839
            const char *model = qemudSoundModelToString(sound->model);
 
2840
            if (!model) {
 
2841
                VIR_FREE(modstr);
 
2842
                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
2843
                                 "%s", _("invalid sound model"));
 
2844
                goto error;
 
2845
            }
 
2846
            strncat(modstr, model, size);
 
2847
            size -= strlen(model);
 
2848
            sound = sound->next;
 
2849
            if (sound)
 
2850
               strncat(modstr, ",", size--);
 
2851
        }
 
2852
        ADD_ARG_LIT("-soundhw");
 
2853
        ADD_ARG(modstr);
 
2854
    }
 
2855
 
1973
2856
    if (vm->migrateFrom[0]) {
1974
 
        if (!((*argv)[++n] = strdup("-S")))
1975
 
            goto no_memory;
1976
 
        if (!((*argv)[++n] = strdup("-incoming")))
1977
 
            goto no_memory;
1978
 
        if (!((*argv)[++n] = strdup(vm->migrateFrom)))
1979
 
            goto no_memory;
 
2857
        ADD_ARG_LIT("-incoming");
 
2858
        ADD_ARG_LIT(vm->migrateFrom);
1980
2859
    }
1981
2860
 
1982
 
    (*argv)[++n] = NULL;
 
2861
    ADD_ARG(NULL);
1983
2862
 
 
2863
    *retargv = qargv;
1984
2864
    return 0;
1985
2865
 
1986
2866
 no_memory:
1990
2870
    if (vm->tapfds) {
1991
2871
        for (i = 0; vm->tapfds[i] != -1; i++)
1992
2872
            close(vm->tapfds[i]);
1993
 
        free(vm->tapfds);
 
2873
        VIR_FREE(vm->tapfds);
1994
2874
        vm->tapfds = NULL;
1995
2875
        vm->ntapfds = 0;
1996
2876
    }
1997
 
    if (argv) {
1998
 
        for (i = 0 ; i < n ; i++)
1999
 
            free((*argv)[i]);
2000
 
        free(*argv);
 
2877
    if (qargv) {
 
2878
        for (i = 0 ; i < qargc ; i++)
 
2879
            VIR_FREE((qargv)[i]);
 
2880
        VIR_FREE(qargv);
2001
2881
    }
2002
2882
    return -1;
 
2883
 
 
2884
#undef ADD_ARG
 
2885
#undef ADD_ARG_LIT
 
2886
#undef ADD_ARG_SPACE
2003
2887
}
2004
2888
 
2005
2889
 
2045
2929
    if (fd != -1)
2046
2930
        close(fd);
2047
2931
 
2048
 
    free(xml);
 
2932
    VIR_FREE(xml);
2049
2933
 
2050
2934
    return ret;
2051
2935
}
2052
2936
 
2053
2937
struct qemud_vm_device_def *
2054
2938
qemudParseVMDeviceDef(virConnectPtr conn,
2055
 
                      struct qemud_driver *driver ATTRIBUTE_UNUSED,
 
2939
                      const struct qemud_vm_def *def,
2056
2940
                      const char *xmlStr)
2057
2941
{
2058
2942
    xmlDocPtr xml;
2059
2943
    xmlNodePtr node;
2060
 
    struct qemud_vm_device_def *dev = calloc(1, sizeof(*dev));
 
2944
    struct qemud_vm_device_def *dev;
 
2945
 
 
2946
    if (VIR_ALLOC(dev) < 0) {
 
2947
        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
 
2948
        return NULL;
 
2949
    }
2061
2950
 
2062
2951
    if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "device.xml", NULL,
2063
2952
                           XML_PARSE_NOENT | XML_PARSE_NONET |
2064
2953
                           XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
2065
2954
        qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL);
2066
 
        return NULL;
 
2955
        goto error;
2067
2956
    }
2068
2957
 
2069
2958
    node = xmlDocGetRootElement(xml);
2075
2964
    if (xmlStrEqual(node->name, BAD_CAST "disk")) {
2076
2965
        dev->type = QEMUD_DEVICE_DISK;
2077
2966
        qemudParseDiskXML(conn, &(dev->data.disk), node);
2078
 
    } else if (xmlStrEqual(node->name, BAD_CAST "net")) {
 
2967
    } else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
2079
2968
        dev->type = QEMUD_DEVICE_NET;
2080
2969
        qemudParseInterfaceXML(conn, &(dev->data.net), node);
2081
2970
    } else if (xmlStrEqual(node->name, BAD_CAST "input")) {
2082
2971
        dev->type = QEMUD_DEVICE_DISK;
2083
 
        qemudParseInputXML(conn, &(dev->data.input), node);
 
2972
        qemudParseInputXML(conn, def, &(dev->data.input), node);
 
2973
    } else if (xmlStrEqual(node->name, BAD_CAST "sound")) {
 
2974
        dev->type = QEMUD_DEVICE_SOUND;
 
2975
        qemudParseSoundXML(conn, &(dev->data.sound), node);
2084
2976
    } else {
2085
2977
        qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR,
2086
2978
                         "%s", _("unknown device type"));
2093
2985
 
2094
2986
  error:
2095
2987
    if (xml) xmlFreeDoc(xml);
2096
 
    free(dev);
 
2988
    VIR_FREE(dev);
2097
2989
    return NULL;
2098
2990
}
2099
2991
 
2141
3033
        return vm;
2142
3034
    }
2143
3035
 
2144
 
    if (!(vm = calloc(1, sizeof(*vm)))) {
 
3036
    if (VIR_ALLOC(vm) < 0) {
2145
3037
        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
2146
3038
                         "%s", _("failed to allocate space for vm string"));
2147
3039
        return NULL;
2269
3161
 
2270
3162
 cleanup:
2271
3163
 
2272
 
    free(xml);
 
3164
    VIR_FREE(xml);
2273
3165
 
2274
3166
    return ret;
2275
3167
}
2278
3170
    struct qemud_dhcp_range_def *range = def->ranges;
2279
3171
    while (range) {
2280
3172
        struct qemud_dhcp_range_def *next = range->next;
2281
 
        free(range);
 
3173
        VIR_FREE(range);
2282
3174
        range = next;
2283
3175
    }
2284
 
    free(def);
 
3176
    VIR_FREE(def);
2285
3177
}
2286
3178
 
2287
3179
void qemudFreeNetwork(struct qemud_network *network) {
2288
3180
    qemudFreeNetworkDef(network->def);
2289
3181
    if (network->newDef)
2290
3182
        qemudFreeNetworkDef(network->newDef);
2291
 
    free(network);
 
3183
    VIR_FREE(network);
2292
3184
}
2293
3185
 
2294
3186
static int qemudParseBridgeXML(struct qemud_driver *driver ATTRIBUTE_UNUSED,
2341
3233
            continue;
2342
3234
        }
2343
3235
 
2344
 
        if (!(range = calloc(1, sizeof(*range)))) {
 
3236
        if (VIR_ALLOC(range) < 0) {
2345
3237
            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
2346
3238
                         "%s", _("failed to allocate space for range string"));
2347
3239
            return 0;
2361
3253
            def->ranges = range;
2362
3254
            def->nranges++;
2363
3255
        } else {
2364
 
            free(range);
 
3256
            VIR_FREE(range);
2365
3257
        }
2366
3258
 
2367
 
        if (start)
2368
 
            xmlFree(start);
2369
 
        if (end)
2370
 
            xmlFree(end);
 
3259
        xmlFree(start);
 
3260
        xmlFree(end);
2371
3261
 
2372
3262
        cur = cur->next;
2373
3263
    }
2434
3324
    xmlXPathObjectPtr obj = NULL, tmp = NULL;
2435
3325
    struct qemud_network_def *def;
2436
3326
 
2437
 
    if (!(def = calloc(1, sizeof(*def)))) {
 
3327
    if (VIR_ALLOC(def) < 0) {
2438
3328
        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
2439
3329
                   "%s", _("failed to allocate space for network_def string"));
2440
3330
        return NULL;
2608
3498
        return network;
2609
3499
    }
2610
3500
 
2611
 
    if (!(network = calloc(1, sizeof(*network)))) {
 
3501
    if (VIR_ALLOC(network) < 0) {
2612
3502
        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
2613
3503
                         "%s", _("failed to allocate space for network string"));
2614
3504
        return NULL;
2819
3709
        else
2820
3710
            qemudLoadNetworkConfig(driver, entry->d_name, path, xml, autostartLink);
2821
3711
 
2822
 
        free(xml);
 
3712
        VIR_FREE(xml);
2823
3713
    }
2824
3714
 
2825
3715
    closedir(dir);
2838
3728
    return 0;
2839
3729
}
2840
3730
 
 
3731
static int qemudGenerateXMLChar(virBufferPtr buf,
 
3732
                                const struct qemud_vm_chr_def *dev,
 
3733
                                const char *type)
 
3734
{
 
3735
    const char *const types[] = {
 
3736
        "null",
 
3737
        "vc",
 
3738
        "pty",
 
3739
        "dev",
 
3740
        "file",
 
3741
        "pipe",
 
3742
        "stdio",
 
3743
        "udp",
 
3744
        "tcp",
 
3745
        "unix"
 
3746
    };
 
3747
    verify_true(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);
 
3748
 
 
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);
 
3756
    } else {
 
3757
        virBufferVSprintf(buf, "    <%s type='%s'>\n",
 
3758
                          type, types[dev->srcType]);
 
3759
    }
 
3760
 
 
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:
 
3765
        /* nada */
 
3766
        break;
 
3767
 
 
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);
 
3776
        }
 
3777
        break;
 
3778
 
 
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);
 
3791
        }
 
3792
 
 
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);
 
3804
        }
 
3805
        break;
 
3806
 
 
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");
 
3815
        break;
 
3816
 
 
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);
 
3821
        break;
 
3822
    }
 
3823
 
 
3824
    virBufferVSprintf(buf, "      <target port='%d'/>\n",
 
3825
                      dev->dstPort);
 
3826
 
 
3827
    virBufferVSprintf(buf, "    </%s>\n",
 
3828
                      type);
 
3829
 
 
3830
    return 0;
 
3831
}
 
3832
 
 
3833
 
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,
2846
3839
                       int live) {
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;
2854
 
    int n;
2855
 
 
2856
 
    buf = virBufferNew (QEMUD_MAX_XML_LEN);
2857
 
    if (!buf)
2858
 
        goto no_memory;
2859
 
 
2860
 
    switch (def->virtType) {
2861
 
    case QEMUD_VIRT_QEMU:
2862
 
        type = "qemu";
2863
 
        break;
2864
 
    case QEMUD_VIRT_KQEMU:
2865
 
        type = "kqemu";
2866
 
        break;
2867
 
    case QEMUD_VIRT_KVM:
2868
 
        type = "kvm";
2869
 
        break;
2870
 
    }
2871
 
    if (!type) {
 
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;
 
3849
    int n, allones = 1;
 
3850
 
 
3851
    if (!(type = qemudVirtTypeToString(def->virtType))) {
2872
3852
        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
2873
3853
                         _("unexpected domain type %d"), def->virtType);
2874
3854
        goto cleanup;
2875
3855
    }
2876
3856
 
2877
 
    if (qemudIsActiveVM(vm) && live) {
2878
 
        if (virBufferVSprintf(buf, "<domain type='%s' id='%d'>\n", type, vm->id) < 0)
2879
 
            goto no_memory;
2880
 
    } else {
2881
 
        if (virBufferVSprintf(buf, "<domain type='%s'>\n", type) < 0)
2882
 
            goto no_memory;
2883
 
    }
 
3857
    if (qemudIsActiveVM(vm) && live)
 
3858
        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id);
 
3859
    else
 
3860
        virBufferVSprintf(&buf, "<domain type='%s'>\n", type);
2884
3861
 
2885
 
    if (virBufferVSprintf(buf, "  <name>%s</name>\n", def->name) < 0)
2886
 
        goto no_memory;
 
3862
    virBufferVSprintf(&buf, "  <name>%s</name>\n", def->name);
2887
3863
 
2888
3864
    uuid = def->uuid;
2889
3865
    virUUIDFormat(uuid, uuidstr);
2890
 
    if (virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr) < 0)
2891
 
        goto no_memory;
2892
 
    if (virBufferVSprintf(buf, "  <memory>%lu</memory>\n", def->maxmem) < 0)
2893
 
        goto no_memory;
2894
 
    if (virBufferVSprintf(buf, "  <currentMemory>%lu</currentMemory>\n", def->memory) < 0)
2895
 
        goto no_memory;
2896
 
    if (virBufferVSprintf(buf, "  <vcpu>%d</vcpu>\n", def->vcpus) < 0)
2897
 
        goto no_memory;
2898
 
 
2899
 
    if (virBufferAddLit(buf, "  <os>\n") < 0)
2900
 
        goto no_memory;
2901
 
 
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)
2905
 
            goto no_memory;
 
3866
    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
 
3867
 
 
3868
    virBufferVSprintf(&buf, "  <memory>%lu</memory>\n", def->maxmem);
 
3869
    virBufferVSprintf(&buf, "  <currentMemory>%lu</currentMemory>\n", def->memory);
 
3870
 
 
3871
    for (n = 0 ; n < QEMUD_CPUMASK_LEN ; n++)
 
3872
        if (def->cpumask[n] != 1)
 
3873
            allones = 0;
 
3874
 
 
3875
    if (allones) {
 
3876
        virBufferVSprintf(&buf, "  <vcpu>%d</vcpu>\n", def->vcpus);
2906
3877
    } else {
2907
 
        if (virBufferVSprintf(buf, "    <type>%s</type>\n", def->os.type) < 0)
2908
 
            goto no_memory;
2909
 
    }
2910
 
 
2911
 
    if (def->os.kernel[0])
2912
 
        if (virBufferVSprintf(buf, "    <kernel>%s</kernel>\n", def->os.kernel) < 0)
2913
 
            goto no_memory;
2914
 
    if (def->os.initrd[0])
2915
 
        if (virBufferVSprintf(buf, "    <initrd>%s</initrd>\n", def->os.initrd) < 0)
2916
 
            goto no_memory;
2917
 
    if (def->os.cmdline[0])
2918
 
        if (virBufferVSprintf(buf, "    <cmdline>%s</cmdline>\n", def->os.cmdline) < 0)
2919
 
            goto no_memory;
2920
 
 
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:
2925
 
            boottype = "fd";
2926
 
            break;
2927
 
        case QEMUD_BOOT_DISK:
2928
 
            boottype = "hd";
2929
 
            break;
2930
 
        case QEMUD_BOOT_CDROM:
2931
 
            boottype = "cdrom";
2932
 
            break;
2933
 
        case QEMUD_BOOT_NET:
2934
 
            boottype = "network";
2935
 
            break;
2936
 
        }
2937
 
        if (virBufferVSprintf(buf, "    <boot dev='%s'/>\n", boottype) < 0)
2938
 
            goto no_memory;
2939
 
    }
2940
 
 
2941
 
    if (virBufferAddLit(buf, "  </os>\n") < 0)
2942
 
        goto no_memory;
 
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"));
 
3882
            goto cleanup;
 
3883
        }
 
3884
        virBufferVSprintf(&buf, "  <vcpu cpuset='%s'>%d</vcpu>\n", cpumask, def->vcpus);
 
3885
        VIR_FREE(cpumask);
 
3886
    }
 
3887
 
 
3888
    if (def->os.bootloader[0])
 
3889
        virBufferVSprintf(&buf, "  <bootloader>%s</bootloader>\n", def->os.bootloader);
 
3890
    virBufferAddLit(&buf, "  <os>\n");
 
3891
 
 
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);
 
3895
    else
 
3896
        virBufferVSprintf(&buf, "    <type>%s</type>\n", def->os.type);
 
3897
 
 
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);
 
3905
 
 
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:
 
3910
                boottype = "fd";
 
3911
                break;
 
3912
            case QEMUD_BOOT_DISK:
 
3913
                boottype = "hd";
 
3914
                break;
 
3915
            case QEMUD_BOOT_CDROM:
 
3916
                boottype = "cdrom";
 
3917
                break;
 
3918
            case QEMUD_BOOT_NET:
 
3919
                boottype = "network";
 
3920
                break;
 
3921
            }
 
3922
            virBufferVSprintf(&buf, "    <boot dev='%s'/>\n", boottype);
 
3923
        }
 
3924
    }
 
3925
 
 
3926
    virBufferAddLit(&buf, "  </os>\n");
2943
3927
 
2944
3928
    if (def->features & QEMUD_FEATURE_ACPI) {
2945
 
        if (virBufferAddLit(buf, "  <features>\n") < 0)
2946
 
            goto no_memory;
2947
 
        if (virBufferAddLit(buf, "    <acpi/>\n") < 0)
2948
 
            goto no_memory;
2949
 
        if (virBufferAddLit(buf, "  </features>\n") < 0)
2950
 
            goto no_memory;
2951
 
    }
2952
 
 
2953
 
    virBufferVSprintf(buf, "  <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
2954
 
 
2955
 
    if (virBufferAddLit(buf, "  <on_poweroff>destroy</on_poweroff>\n") < 0)
2956
 
        goto no_memory;
2957
 
    if (def->noReboot) {
2958
 
        if (virBufferAddLit(buf, "  <on_reboot>destroy</on_reboot>\n") < 0)
2959
 
            goto no_memory;
2960
 
    } else {
2961
 
        if (virBufferAddLit(buf, "  <on_reboot>restart</on_reboot>\n") < 0)
2962
 
            goto no_memory;
2963
 
    }
2964
 
    if (virBufferAddLit(buf, "  <on_crash>destroy</on_crash>\n") < 0)
2965
 
        goto no_memory;
2966
 
 
2967
 
    if (virBufferAddLit(buf, "  <devices>\n") < 0)
2968
 
        goto no_memory;
2969
 
 
2970
 
    if (virBufferVSprintf(buf, "    <emulator>%s</emulator>\n", def->os.binary) < 0)
2971
 
        goto no_memory;
 
3929
        virBufferAddLit(&buf, "  <features>\n");
 
3930
        virBufferAddLit(&buf, "    <acpi/>\n");
 
3931
        virBufferAddLit(&buf, "  </features>\n");
 
3932
    }
 
3933
 
 
3934
    virBufferVSprintf(&buf, "  <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
 
3935
 
 
3936
    virBufferAddLit(&buf, "  <on_poweroff>destroy</on_poweroff>\n");
 
3937
    if (def->noReboot)
 
3938
        virBufferAddLit(&buf, "  <on_reboot>destroy</on_reboot>\n");
 
3939
    else
 
3940
        virBufferAddLit(&buf, "  <on_reboot>restart</on_reboot>\n");
 
3941
 
 
3942
    virBufferAddLit(&buf, "  <on_crash>destroy</on_crash>\n");
 
3943
    virBufferAddLit(&buf, "  <devices>\n");
 
3944
 
 
3945
    virBufferVSprintf(&buf, "    <emulator>%s</emulator>\n", def->os.binary);
2972
3946
 
2973
3947
    disk = def->disks;
2974
3948
    while (disk) {
2985
3959
            "cdrom",
2986
3960
            "floppy",
2987
3961
        };
2988
 
        if (virBufferVSprintf(buf, "    <disk type='%s' device='%s'>\n",
2989
 
                              types[disk->type], devices[disk->device]) < 0)
2990
 
            goto no_memory;
 
3962
        virBufferVSprintf(&buf, "    <disk type='%s' device='%s'>\n",
 
3963
                          types[disk->type], devices[disk->device]);
2991
3964
 
2992
3965
        if (disk->src[0])
2993
 
            if (virBufferVSprintf(buf, "      <source %s='%s'/>\n",
2994
 
                                  typeAttrs[disk->type], disk->src) < 0)
2995
 
                goto no_memory;
 
3966
            virBufferVSprintf(&buf, "      <source %s='%s'/>\n",
 
3967
                              typeAttrs[disk->type], disk->src);
2996
3968
 
2997
 
        if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", disk->dst) < 0)
2998
 
            goto no_memory;
 
3969
        virBufferVSprintf(&buf, "      <target dev='%s' bus='%s'/>\n",
 
3970
                          disk->dst, qemudBusIdToName(disk->bus, 0));
2999
3971
 
3000
3972
        if (disk->readonly)
3001
 
            if (virBufferAddLit(buf, "      <readonly/>\n") < 0)
3002
 
                goto no_memory;
 
3973
            virBufferAddLit(&buf, "      <readonly/>\n");
3003
3974
 
3004
 
        if (virBufferAddLit(buf, "    </disk>\n") < 0)
3005
 
            goto no_memory;
 
3975
        virBufferAddLit(&buf, "    </disk>\n");
3006
3976
 
3007
3977
        disk = disk->next;
3008
3978
    }
3018
3988
            "network",
3019
3989
            "bridge",
3020
3990
        };
3021
 
        if (virBufferVSprintf(buf, "    <interface type='%s'>\n",
3022
 
                              types[net->type]) < 0)
3023
 
            goto no_memory;
 
3991
        virBufferVSprintf(&buf, "    <interface type='%s'>\n",
 
3992
                          types[net->type]);
3024
3993
 
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)
3028
 
            goto no_memory;
 
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]);
3029
3997
 
3030
3998
        switch (net->type) {
3031
3999
        case QEMUD_NET_NETWORK:
3032
 
            if (virBufferVSprintf(buf, "      <source network='%s'/>\n", net->dst.network.name) < 0)
3033
 
                goto no_memory;
 
4000
            virBufferVSprintf(&buf, "      <source network='%s'/>\n", net->dst.network.name);
3034
4001
 
3035
 
            if (net->dst.network.ifname[0] != '\0') {
3036
 
                if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", net->dst.network.ifname) < 0)
3037
 
                    goto no_memory;
3038
 
            }
 
4002
            if (net->dst.network.ifname[0] != '\0')
 
4003
                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.network.ifname);
3039
4004
            break;
3040
4005
 
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)
3044
 
                    goto no_memory;
3045
 
            }
3046
 
            if (net->dst.ethernet.script[0] != '\0') {
3047
 
                if (virBufferVSprintf(buf, "      <script path='%s'/>\n", net->dst.ethernet.script) < 0)
3048
 
                    goto no_memory;
3049
 
            }
 
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);
3050
4011
            break;
3051
4012
 
3052
4013
        case QEMUD_NET_BRIDGE:
3053
 
            if (virBufferVSprintf(buf, "      <source bridge='%s'/>\n", net->dst.bridge.brname) < 0)
3054
 
                goto no_memory;
3055
 
            if (net->dst.bridge.ifname[0] != '\0') {
3056
 
                if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", net->dst.bridge.ifname) < 0)
3057
 
                    goto no_memory;
3058
 
            }
 
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);
3059
4017
            break;
3060
4018
 
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)
3067
 
                    goto no_memory;
3068
 
            } else {
3069
 
                if (virBufferVSprintf(buf, "      <source port='%d'/>\n",
3070
 
                                      net->dst.socket.port) < 0)
3071
 
                    goto no_memory;
3072
 
            }
3073
 
        }
3074
 
 
3075
 
        if (virBufferAddLit(buf, "    </interface>\n") < 0)
3076
 
            goto no_memory;
 
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);
 
4025
            else
 
4026
                virBufferVSprintf(&buf, "      <source port='%d'/>\n",
 
4027
                                  net->dst.socket.port);
 
4028
        }
 
4029
 
 
4030
        if (net->model && net->model[0] != '\0') {
 
4031
            virBufferVSprintf(&buf, "      <model type='%s'/>\n",
 
4032
                              net->model);
 
4033
        }
 
4034
 
 
4035
        virBufferAddLit(&buf, "    </interface>\n");
3077
4036
 
3078
4037
        net = net->next;
3079
4038
    }
3080
4039
 
 
4040
    chr = def->serials;
 
4041
    while (chr) {
 
4042
        if (qemudGenerateXMLChar(&buf, chr, "serial") < 0)
 
4043
            goto no_memory;
 
4044
 
 
4045
        chr = chr->next;
 
4046
    }
 
4047
 
 
4048
    chr = def->parallels;
 
4049
    while (chr) {
 
4050
        if (qemudGenerateXMLChar(&buf, chr, "parallel") < 0)
 
4051
            goto no_memory;
 
4052
 
 
4053
        chr = chr->next;
 
4054
    }
 
4055
 
 
4056
    /* First serial device is the primary console */
 
4057
    if (def->nserials > 0 &&
 
4058
        qemudGenerateXMLChar(&buf, def->serials, "console") < 0)
 
4059
        goto no_memory;
 
4060
 
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)
3086
 
            goto no_memory;
 
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;
3088
4067
    }
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)
3092
 
            goto no_memory;
 
4070
        virBufferVSprintf(&buf, "    <input type='mouse' bus='%s'/>\n",
 
4071
                          STREQ(def->os.type, "hvm") ? "ps2" : "xen");
3093
4072
 
3094
4073
    switch (def->graphicsType) {
3095
4074
    case QEMUD_GRAPHICS_VNC:
3096
 
        if (virBufferAddLit(buf, "    <graphics type='vnc'") < 0)
3097
 
            goto no_memory;
3098
 
 
3099
 
        if (def->vncPort &&
3100
 
            virBufferVSprintf(buf, " port='%d'",
3101
 
                              qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort) < 0)
3102
 
            goto no_memory;
3103
 
 
3104
 
        if (def->vncListen[0] &&
3105
 
            virBufferVSprintf(buf, " listen='%s'",
3106
 
                              def->vncListen) < 0)
3107
 
            goto no_memory;
3108
 
 
3109
 
        if (def->keymap &&
3110
 
            virBufferVSprintf(buf, " keymap='%s'",
3111
 
                              def->keymap) < 0)
3112
 
            goto no_memory;
3113
 
 
3114
 
        if (virBufferAddLit(buf, "/>\n") < 0)
3115
 
            goto no_memory;
 
4075
        virBufferAddLit(&buf, "    <graphics type='vnc'");
 
4076
 
 
4077
        if (def->vncPort)
 
4078
            virBufferVSprintf(&buf, " port='%d'",
 
4079
                              qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort);
 
4080
 
 
4081
        if (def->vncListen[0])
 
4082
            virBufferVSprintf(&buf, " listen='%s'",
 
4083
                              def->vncListen);
 
4084
 
 
4085
        if (def->keymap)
 
4086
            virBufferVSprintf(&buf, " keymap='%s'",
 
4087
                              def->keymap);
 
4088
 
 
4089
        virBufferAddLit(&buf, "/>\n");
3116
4090
        break;
3117
4091
 
3118
4092
    case QEMUD_GRAPHICS_SDL:
3119
 
        if (virBufferAddLit(buf, "    <graphics type='sdl'/>\n") < 0)
3120
 
            goto no_memory;
 
4093
        virBufferAddLit(&buf, "    <graphics type='sdl'/>\n");
3121
4094
        break;
3122
4095
 
3123
4096
    case QEMUD_GRAPHICS_NONE:
3125
4098
        break;
3126
4099
    }
3127
4100
 
3128
 
    if (def->graphicsType == QEMUD_GRAPHICS_VNC) {
 
4101
    sound = def->sounds;
 
4102
    while(sound) {
 
4103
        const char *model = qemudSoundModelToString(sound->model);
 
4104
        if (!model) {
 
4105
            qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
 
4106
                             "%s", _("invalid sound model"));
 
4107
            goto cleanup;
 
4108
        }
 
4109
        virBufferVSprintf(&buf, "    <sound model='%s'/>\n", model);
 
4110
        sound = sound->next;
3129
4111
    }
3130
4112
 
3131
 
    if (virBufferAddLit(buf, "  </devices>\n") < 0)
3132
 
        goto no_memory;
3133
 
 
3134
 
 
3135
 
    if (virBufferAddLit(buf, "</domain>\n") < 0)
3136
 
        goto no_memory;
3137
 
 
3138
 
    return virBufferContentAndFree (buf);
 
4113
    virBufferAddLit(&buf, "  </devices>\n");
 
4114
    virBufferAddLit(&buf, "</domain>\n");
 
4115
 
 
4116
    if (virBufferError(&buf))
 
4117
        goto no_memory;
 
4118
 
 
4119
    return virBufferContentAndReset(&buf);
3139
4120
 
3140
4121
 no_memory:
3141
4122
    qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
3142
4123
                     "%s", _("failed to generate XML: out of memory"));
3143
4124
 cleanup:
3144
 
    if (buf) virBufferFree (buf);
 
4125
    tmp = virBufferContentAndReset(&buf);
 
4126
    VIR_FREE(tmp);
3145
4127
    return NULL;
3146
4128
}
3147
4129
 
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;
 
4137
    char *tmp;
3155
4138
    char uuidstr[VIR_UUID_STRING_BUFLEN];
3156
4139
 
3157
 
    buf = virBufferNew (QEMUD_MAX_XML_LEN);
3158
 
    if (!buf)
3159
 
        goto no_memory;
3160
 
 
3161
 
    if (virBufferAddLit(buf, "<network>\n") < 0)
3162
 
        goto no_memory;
3163
 
 
3164
 
    if (virBufferVSprintf(buf, "  <name>%s</name>\n", def->name) < 0)
3165
 
        goto no_memory;
 
4140
    virBufferAddLit(&buf, "<network>\n");
 
4141
 
 
4142
    virBufferVSprintf(&buf, "  <name>%s</name>\n", def->name);
3166
4143
 
3167
4144
    uuid = def->uuid;
3168
4145
    virUUIDFormat(uuid, uuidstr);
3169
 
    if (virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr) < 0)
3170
 
        goto no_memory;
 
4146
    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
3171
4147
 
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"));
3176
4152
        } else {
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"));
3178
4154
        }
3179
4155
    }
3180
4156
 
3181
 
    virBufferAddLit(buf, "  <bridge");
 
4157
    virBufferAddLit(&buf, "  <bridge");
3182
4158
    if (qemudIsActiveNetwork(network)) {
3183
 
        if (virBufferVSprintf(buf, " name='%s'", network->bridge) < 0)
3184
 
            goto no_memory;
 
4159
        virBufferVSprintf(&buf, " name='%s'", network->bridge);
3185
4160
    } else if (def->bridge[0]) {
3186
 
        if (virBufferVSprintf(buf, " name='%s'", def->bridge) < 0)
3187
 
            goto no_memory;
 
4161
        virBufferVSprintf(&buf, " name='%s'", def->bridge);
3188
4162
    }
3189
 
    if (virBufferVSprintf(buf, " stp='%s' forwardDelay='%d' />\n",
3190
 
                       def->disableSTP ? "off" : "on",
3191
 
                       def->forwardDelay) < 0)
3192
 
        goto no_memory;
 
4163
    virBufferVSprintf(&buf, " stp='%s' forwardDelay='%d' />\n",
 
4164
                      def->disableSTP ? "off" : "on",
 
4165
                      def->forwardDelay);
3193
4166
 
3194
4167
    if (def->ipAddress[0] || def->netmask[0]) {
3195
 
        if (virBufferAddLit(buf, "  <ip") < 0)
3196
 
            goto no_memory;
3197
 
 
3198
 
        if (def->ipAddress[0] &&
3199
 
            virBufferVSprintf(buf, " address='%s'", def->ipAddress) < 0)
3200
 
            goto no_memory;
3201
 
 
3202
 
        if (def->netmask[0] &&
3203
 
            virBufferVSprintf(buf, " netmask='%s'", def->netmask) < 0)
3204
 
            goto no_memory;
3205
 
 
3206
 
        if (virBufferAddLit(buf, ">\n") < 0)
3207
 
            goto no_memory;
 
4168
        virBufferAddLit(&buf, "  <ip");
 
4169
 
 
4170
        if (def->ipAddress[0])
 
4171
            virBufferVSprintf(&buf, " address='%s'", def->ipAddress);
 
4172
 
 
4173
        if (def->netmask[0])
 
4174
            virBufferVSprintf(&buf, " netmask='%s'", def->netmask);
 
4175
 
 
4176
        virBufferAddLit(&buf, ">\n");
3208
4177
 
3209
4178
        if (def->ranges) {
3210
4179
            struct qemud_dhcp_range_def *range = def->ranges;
3211
 
            if (virBufferAddLit(buf, "    <dhcp>\n") < 0)
3212
 
                goto no_memory;
 
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)
3216
 
                    goto no_memory;
 
4182
                virBufferVSprintf(&buf, "      <range start='%s' end='%s' />\n",
 
4183
                                  range->start, range->end);
3217
4184
                range = range->next;
3218
4185
            }
3219
 
            if (virBufferAddLit(buf, "    </dhcp>\n") < 0)
3220
 
                goto no_memory;
 
4186
            virBufferAddLit(&buf, "    </dhcp>\n");
3221
4187
        }
3222
4188
 
3223
 
        if (virBufferAddLit(buf, "  </ip>\n") < 0)
3224
 
            goto no_memory;
 
4189
        virBufferAddLit(&buf, "  </ip>\n");
3225
4190
    }
3226
4191
 
3227
 
    if (virBufferAddLit(buf, "</network>\n") < 0)
 
4192
    virBufferAddLit(&buf, "</network>\n");
 
4193
 
 
4194
    if (virBufferError(&buf))
3228
4195
        goto no_memory;
3229
4196
 
3230
 
    return virBufferContentAndFree (buf);
 
4197
    return virBufferContentAndReset(&buf);
3231
4198
 
3232
4199
 no_memory:
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);
 
4203
    VIR_FREE(tmp);
3236
4204
    return NULL;
3237
4205
}
3238
4206
 
3257
4225
}
3258
4226
 
3259
4227
#endif /* WITH_QEMU */
3260
 
 
3261
 
/*
3262
 
 * Local variables:
3263
 
 *  indent-tabs-mode: nil
3264
 
 *  c-indent-level: 4
3265
 
 *  c-basic-offset: 4
3266
 
 *  tab-width: 4
3267
 
 * End:
3268
 
 */