~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages

« back to all changes in this revision

Viewing changes to .pc/ubuntu/xen-vif-ioemu-deprecated.patch/src/xenxs/xen_xm.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-13 15:44:12 UTC
  • mfrom: (1.2.13)
  • Revision ID: package-import@ubuntu.com-20120513154412-fgmn5sxqdzgnzlx3
Tags: 0.9.12-0ubuntu1
* New upstream version:
  * Synchronize with debian packaging:
    - debian/control: Update build depends.
    - debian/libvirt-bin.postrm: Cleanup /var/log/libvirt
      on purge.
    - Bump standards verson (no changes).
    - debian/patches/Don-t-fail-if-we-can-t-setup-avahi.patch: Added
  * Dropped patches:
    - debian/patches/Debianize-libvirt-guests.patch
    - debian/patches/rewrite-lxc-controller-eof-handling-yet-again
    - debian/patches/ubuntu/libnl13.patch
    - debian/patches/ubuntu/fix-lxc-startup-error.patch
    - debian/patches/ubuntu/fix-bridge-fd.patch
    - debian/patches/ubuntu/skip-labelling-network-disks.patch
    - debian/patches/ubuntu/xen-xend-shutdown-detection.patch
    - debian/patches/ubuntu/xen-config-no-vfb-for-hvm.patch
    - debian/patches/debian/Disable-daemon-start-test.patch
    - debian/patches/debian/Disable-gnulib-s-test-nonplocking-pipe.sh.patch
    - debian/patches/ubuntu/9006-default-config-test-case.patch
    - debian/patches/fix-block-migration.patch
    - debian/patches/ubuntu/9022-qemu-unescape-HMP-commands-before-converting-them-to.patch
    - debian/patches/ubuntu/9023-qemu-change-rbd-auth_supported-separation-character-.patch
    - debian/patches/ubuntu/9024-qemu-allow-snapshotting-of-sheepdog-and-rbd-disks.patch
    - debian/patches/9025-qemu-change-rbd-auth_supported-separation-character-.patch
    - debian/patches/ubuntu/arm-gcc-workaround.patch
  * Rediffed:
    - debian/patches/Allow-libvirt-group-to-access-the-socket.patch
    - debian/patches/Disable-failing-virnetsockettest.patch
    - debian/patches/dnsmasq-as-priv-user
    - debian/patches/9002-better_default_uri_virsh.patch
  * debian/control: Add libnl-route-3-dev ass a build depends.
  * debian/patches/libnl3-build-fix.patch: Fix build with libnl3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * xen_xm.c: Xen XM parsing functions
3
 
 *
4
 
 * Copyright (C) 2011 Univention GmbH
5
 
 * Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
6
 
 * Copyright (C) 2006 Daniel P. Berrange
7
 
 *
8
 
 * This library is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Lesser General Public
10
 
 * License as published by the Free Software Foundation; either
11
 
 * version 2.1 of the License, or (at your option) any later version.
12
 
 *
13
 
 * This library is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * Lesser General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with this library; if not, write to the Free Software
20
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
21
 
 *
22
 
 * Author: Daniel P. Berrange <berrange@redhat.com>
23
 
 * Author: Markus Groß <gross@univention.de>
24
 
 */
25
 
 
26
 
#include <config.h>
27
 
 
28
 
#include "internal.h"
29
 
#include "virterror_internal.h"
30
 
#include "conf.h"
31
 
#include "memory.h"
32
 
#include "verify.h"
33
 
#include "uuid.h"
34
 
#include "sexpr.h"
35
 
#include "count-one-bits.h"
36
 
#include "xenxs_private.h"
37
 
#include "xen_xm.h"
38
 
#include "xen_sxpr.h"
39
 
#include "domain_conf.h"
40
 
 
41
 
/* Convenience method to grab a int from the config file object */
42
 
static int xenXMConfigGetBool(virConfPtr conf,
43
 
                              const char *name,
44
 
                              int *value,
45
 
                              int def) {
46
 
    virConfValuePtr val;
47
 
 
48
 
    *value = 0;
49
 
    if (!(val = virConfGetValue(conf, name))) {
50
 
        *value = def;
51
 
        return 0;
52
 
    }
53
 
 
54
 
    if (val->type == VIR_CONF_LONG) {
55
 
        *value = val->l ? 1 : 0;
56
 
    } else if (val->type == VIR_CONF_STRING) {
57
 
        *value = STREQ(val->str, "1") ? 1 : 0;
58
 
    } else {
59
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
60
 
                   _("config value %s was malformed"), name);
61
 
        return -1;
62
 
    }
63
 
    return 0;
64
 
}
65
 
 
66
 
 
67
 
/* Convenience method to grab a int from the config file object */
68
 
static int xenXMConfigGetULong(virConfPtr conf,
69
 
                               const char *name,
70
 
                               unsigned long *value,
71
 
                               int def) {
72
 
    virConfValuePtr val;
73
 
 
74
 
    *value = 0;
75
 
    if (!(val = virConfGetValue(conf, name))) {
76
 
        *value = def;
77
 
        return 0;
78
 
    }
79
 
 
80
 
    if (val->type == VIR_CONF_LONG) {
81
 
        *value = val->l;
82
 
    } else if (val->type == VIR_CONF_STRING) {
83
 
        char *ret;
84
 
        *value = strtol(val->str, &ret, 10);
85
 
        if (ret == val->str) {
86
 
            XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
87
 
                       _("config value %s was malformed"), name);
88
 
            return -1;
89
 
        }
90
 
    } else {
91
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
92
 
                   _("config value %s was malformed"), name);
93
 
        return -1;
94
 
    }
95
 
    return 0;
96
 
}
97
 
 
98
 
 
99
 
/* Convenience method to grab a string from the config file object */
100
 
static int xenXMConfigGetString(virConfPtr conf,
101
 
                                const char *name,
102
 
                                const char **value,
103
 
                                const char *def) {
104
 
    virConfValuePtr val;
105
 
 
106
 
    *value = NULL;
107
 
    if (!(val = virConfGetValue(conf, name))) {
108
 
        *value = def;
109
 
        return 0;
110
 
    }
111
 
 
112
 
    if (val->type != VIR_CONF_STRING) {
113
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
114
 
                   _("config value %s was malformed"), name);
115
 
        return -1;
116
 
    }
117
 
    if (!val->str)
118
 
        *value = def;
119
 
    else
120
 
        *value = val->str;
121
 
    return 0;
122
 
}
123
 
 
124
 
static int xenXMConfigCopyStringInternal(virConfPtr conf,
125
 
                                         const char *name,
126
 
                                         char **value,
127
 
                                         int allowMissing) {
128
 
    virConfValuePtr val;
129
 
 
130
 
    *value = NULL;
131
 
    if (!(val = virConfGetValue(conf, name))) {
132
 
        if (allowMissing)
133
 
            return 0;
134
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
135
 
                   _("config value %s was missing"), name);
136
 
        return -1;
137
 
    }
138
 
 
139
 
    if (val->type != VIR_CONF_STRING) {
140
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
141
 
                   _("config value %s was not a string"), name);
142
 
        return -1;
143
 
    }
144
 
    if (!val->str) {
145
 
        if (allowMissing)
146
 
            return 0;
147
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
148
 
                   _("config value %s was missing"), name);
149
 
        return -1;
150
 
    }
151
 
 
152
 
    if (!(*value = strdup(val->str))) {
153
 
        virReportOOMError();
154
 
        return -1;
155
 
    }
156
 
 
157
 
    return 0;
158
 
}
159
 
 
160
 
 
161
 
static int xenXMConfigCopyString(virConfPtr conf,
162
 
                                 const char *name,
163
 
                                 char **value) {
164
 
    return xenXMConfigCopyStringInternal(conf, name, value, 0);
165
 
}
166
 
 
167
 
static int xenXMConfigCopyStringOpt(virConfPtr conf,
168
 
                                    const char *name,
169
 
                                    char **value) {
170
 
    return xenXMConfigCopyStringInternal(conf, name, value, 1);
171
 
}
172
 
 
173
 
 
174
 
/* Convenience method to grab a string UUID from the config file object */
175
 
static int xenXMConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid) {
176
 
    virConfValuePtr val;
177
 
 
178
 
    if (!uuid || !name || !conf) {
179
 
        XENXS_ERROR(VIR_ERR_INVALID_ARG,
180
 
                   _("Arguments must be non null"));
181
 
        return -1;
182
 
    }
183
 
 
184
 
    if (!(val = virConfGetValue(conf, name))) {
185
 
        XENXS_ERROR(VIR_ERR_CONF_SYNTAX,
186
 
                   _("config value %s was missing"), name);
187
 
        return -1;
188
 
    }
189
 
 
190
 
    if (val->type != VIR_CONF_STRING) {
191
 
        XENXS_ERROR(VIR_ERR_CONF_SYNTAX,
192
 
                   _("config value %s not a string"), name);
193
 
        return -1;
194
 
    }
195
 
 
196
 
    if (!val->str) {
197
 
        XENXS_ERROR(VIR_ERR_CONF_SYNTAX,
198
 
                   _("%s can't be empty"), name);
199
 
        return -1;
200
 
    }
201
 
 
202
 
    if (virUUIDParse(val->str, uuid) < 0) {
203
 
        XENXS_ERROR(VIR_ERR_CONF_SYNTAX,
204
 
                   _("%s not parseable"), val->str);
205
 
        return -1;
206
 
    }
207
 
 
208
 
    return 0;
209
 
}
210
 
 
211
 
#define MAX_VFB 1024
212
 
/*
213
 
 * Turn a config record into a lump of XML describing the
214
 
 * domain, suitable for later feeding for virDomainCreateXML
215
 
 */
216
 
virDomainDefPtr
217
 
xenParseXM(virConfPtr conf, int xendConfigVersion,
218
 
                       virCapsPtr caps) {
219
 
    const char *str;
220
 
    int hvm = 0;
221
 
    int val;
222
 
    virConfValuePtr list;
223
 
    virDomainDefPtr def = NULL;
224
 
    virDomainDiskDefPtr disk = NULL;
225
 
    virDomainNetDefPtr net = NULL;
226
 
    virDomainGraphicsDefPtr graphics = NULL;
227
 
    virDomainHostdevDefPtr hostdev = NULL;
228
 
    int i;
229
 
    const char *defaultArch, *defaultMachine;
230
 
    int vmlocaltime = 0;
231
 
    unsigned long count;
232
 
    char *script = NULL;
233
 
    char *listenAddr = NULL;
234
 
 
235
 
    if (VIR_ALLOC(def) < 0) {
236
 
        virReportOOMError();
237
 
        return NULL;
238
 
    }
239
 
 
240
 
    def->virtType = VIR_DOMAIN_VIRT_XEN;
241
 
    def->id = -1;
242
 
 
243
 
    if (xenXMConfigCopyString(conf, "name", &def->name) < 0)
244
 
        goto cleanup;
245
 
    if (xenXMConfigGetUUID(conf, "uuid", def->uuid) < 0)
246
 
        goto cleanup;
247
 
 
248
 
 
249
 
    if ((xenXMConfigGetString(conf, "builder", &str, "linux") == 0) &&
250
 
        STREQ(str, "hvm"))
251
 
        hvm = 1;
252
 
 
253
 
    if (!(def->os.type = strdup(hvm ? "hvm" : "xen")))
254
 
        goto no_memory;
255
 
 
256
 
    defaultArch = virCapabilitiesDefaultGuestArch(caps, def->os.type, virDomainVirtTypeToString(def->virtType));
257
 
    if (defaultArch == NULL) {
258
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
259
 
                   _("no supported architecture for os type '%s'"),
260
 
                   def->os.type);
261
 
        goto cleanup;
262
 
    }
263
 
    if (!(def->os.arch = strdup(defaultArch)))
264
 
        goto no_memory;
265
 
 
266
 
    defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
267
 
                                                        def->os.type,
268
 
                                                        def->os.arch,
269
 
                                                        virDomainVirtTypeToString(def->virtType));
270
 
    if (defaultMachine != NULL) {
271
 
        if (!(def->os.machine = strdup(defaultMachine)))
272
 
            goto no_memory;
273
 
    }
274
 
 
275
 
    if (hvm) {
276
 
        const char *boot;
277
 
        if (xenXMConfigCopyString(conf, "kernel", &def->os.loader) < 0)
278
 
            goto cleanup;
279
 
 
280
 
        if (xenXMConfigGetString(conf, "boot", &boot, "c") < 0)
281
 
            goto cleanup;
282
 
 
283
 
        for (i = 0 ; i < VIR_DOMAIN_BOOT_LAST && boot[i] ; i++) {
284
 
            switch (*boot) {
285
 
            case 'a':
286
 
                def->os.bootDevs[i] = VIR_DOMAIN_BOOT_FLOPPY;
287
 
                break;
288
 
            case 'd':
289
 
                def->os.bootDevs[i] = VIR_DOMAIN_BOOT_CDROM;
290
 
                break;
291
 
            case 'n':
292
 
                def->os.bootDevs[i] = VIR_DOMAIN_BOOT_NET;
293
 
                break;
294
 
            case 'c':
295
 
            default:
296
 
                def->os.bootDevs[i] = VIR_DOMAIN_BOOT_DISK;
297
 
                break;
298
 
            }
299
 
            def->os.nBootDevs++;
300
 
        }
301
 
    } else {
302
 
        if (xenXMConfigCopyStringOpt(conf, "bootloader", &def->os.bootloader) < 0)
303
 
            goto cleanup;
304
 
        if (xenXMConfigCopyStringOpt(conf, "bootargs", &def->os.bootloaderArgs) < 0)
305
 
            goto cleanup;
306
 
 
307
 
        if (xenXMConfigCopyStringOpt(conf, "kernel", &def->os.kernel) < 0)
308
 
            goto cleanup;
309
 
        if (xenXMConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
310
 
            goto cleanup;
311
 
        if (xenXMConfigCopyStringOpt(conf, "extra", &def->os.cmdline) < 0)
312
 
            goto cleanup;
313
 
    }
314
 
 
315
 
    if (xenXMConfigGetULong(conf, "memory", &def->mem.cur_balloon,
316
 
                            MIN_XEN_GUEST_SIZE * 2) < 0)
317
 
        goto cleanup;
318
 
 
319
 
    if (xenXMConfigGetULong(conf, "maxmem", &def->mem.max_balloon,
320
 
                            def->mem.cur_balloon) < 0)
321
 
        goto cleanup;
322
 
 
323
 
    def->mem.cur_balloon *= 1024;
324
 
    def->mem.max_balloon *= 1024;
325
 
 
326
 
    if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
327
 
        MAX_VIRT_CPUS < count)
328
 
        goto cleanup;
329
 
    def->maxvcpus = count;
330
 
    if (xenXMConfigGetULong(conf, "vcpu_avail", &count, -1) < 0)
331
 
        goto cleanup;
332
 
    def->vcpus = MIN(count_one_bits_l(count), def->maxvcpus);
333
 
 
334
 
    if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
335
 
        goto cleanup;
336
 
    if (str) {
337
 
        def->cpumasklen = 4096;
338
 
        if (VIR_ALLOC_N(def->cpumask, def->cpumasklen) < 0)
339
 
            goto no_memory;
340
 
 
341
 
        if (virDomainCpuSetParse(str, 0,
342
 
                                 def->cpumask, def->cpumasklen) < 0)
343
 
            goto cleanup;
344
 
    }
345
 
 
346
 
 
347
 
    if (xenXMConfigGetString(conf, "on_poweroff", &str, "destroy") < 0)
348
 
        goto cleanup;
349
 
    if ((def->onPoweroff = virDomainLifecycleTypeFromString(str)) < 0) {
350
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
351
 
                   _("unexpected value %s for on_poweroff"), str);
352
 
        goto cleanup;
353
 
    }
354
 
 
355
 
    if (xenXMConfigGetString(conf, "on_reboot", &str, "restart") < 0)
356
 
        goto cleanup;
357
 
    if ((def->onReboot = virDomainLifecycleTypeFromString(str)) < 0) {
358
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
359
 
                   _("unexpected value %s for on_reboot"), str);
360
 
        goto cleanup;
361
 
    }
362
 
 
363
 
    if (xenXMConfigGetString(conf, "on_crash", &str, "restart") < 0)
364
 
        goto cleanup;
365
 
    if ((def->onCrash = virDomainLifecycleCrashTypeFromString(str)) < 0) {
366
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
367
 
                   _("unexpected value %s for on_crash"), str);
368
 
        goto cleanup;
369
 
    }
370
 
 
371
 
 
372
 
 
373
 
    if (hvm) {
374
 
        if (xenXMConfigGetBool(conf, "pae", &val, 0) < 0)
375
 
            goto cleanup;
376
 
        else if (val)
377
 
            def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
378
 
        if (xenXMConfigGetBool(conf, "acpi", &val, 0) < 0)
379
 
            goto cleanup;
380
 
        else if (val)
381
 
            def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI);
382
 
        if (xenXMConfigGetBool(conf, "apic", &val, 0) < 0)
383
 
            goto cleanup;
384
 
        else if (val)
385
 
            def->features |= (1 << VIR_DOMAIN_FEATURE_APIC);
386
 
        if (xenXMConfigGetBool(conf, "hap", &val, 0) < 0)
387
 
            goto cleanup;
388
 
        else if (val)
389
 
            def->features |= (1 << VIR_DOMAIN_FEATURE_HAP);
390
 
        if (xenXMConfigGetBool(conf, "viridian", &val, 0) < 0)
391
 
            goto cleanup;
392
 
        else if (val)
393
 
            def->features |= (1 << VIR_DOMAIN_FEATURE_VIRIDIAN);
394
 
 
395
 
        if (xenXMConfigGetBool(conf, "hpet", &val, -1) < 0)
396
 
            goto cleanup;
397
 
        else if (val != -1) {
398
 
            virDomainTimerDefPtr timer;
399
 
 
400
 
            if (VIR_ALLOC_N(def->clock.timers, 1) < 0 ||
401
 
                VIR_ALLOC(timer) < 0) {
402
 
                virReportOOMError();
403
 
                goto cleanup;
404
 
            }
405
 
 
406
 
            timer->name = VIR_DOMAIN_TIMER_NAME_HPET;
407
 
            timer->present = val;
408
 
            timer->tickpolicy = -1;
409
 
 
410
 
            def->clock.ntimers = 1;
411
 
            def->clock.timers[0] = timer;
412
 
        }
413
 
    }
414
 
    if (xenXMConfigGetBool(conf, "localtime", &vmlocaltime, 0) < 0)
415
 
        goto cleanup;
416
 
 
417
 
    def->clock.offset = vmlocaltime ?
418
 
        VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME :
419
 
        VIR_DOMAIN_CLOCK_OFFSET_UTC;
420
 
 
421
 
    if (xenXMConfigCopyStringOpt(conf, "device_model", &def->emulator) < 0)
422
 
        goto cleanup;
423
 
 
424
 
    list = virConfGetValue(conf, "disk");
425
 
    if (list && list->type == VIR_CONF_LIST) {
426
 
        list = list->list;
427
 
        while (list) {
428
 
            char *head;
429
 
            char *offset;
430
 
            char *tmp;
431
 
 
432
 
            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
433
 
                goto skipdisk;
434
 
            head = list->str;
435
 
 
436
 
            if (VIR_ALLOC(disk) < 0)
437
 
                goto no_memory;
438
 
 
439
 
            /*
440
 
             * Disks have 3 components, SOURCE,DEST-DEVICE,MODE
441
 
             * eg, phy:/dev/HostVG/XenGuest1,xvda,w
442
 
             * The SOURCE is usually prefixed with a driver type,
443
 
             * and optionally driver sub-type
444
 
             * The DEST-DEVICE is optionally post-fixed with disk type
445
 
             */
446
 
 
447
 
            /* Extract the source file path*/
448
 
            if (!(offset = strchr(head, ',')))
449
 
                goto skipdisk;
450
 
            if ((offset - head) >= (PATH_MAX-1))
451
 
                goto skipdisk;
452
 
 
453
 
            if (offset == head) {
454
 
                disk->src = NULL; /* No source file given, eg CDROM with no media */
455
 
            } else {
456
 
                if (VIR_ALLOC_N(disk->src, (offset - head) + 1) < 0)
457
 
                    goto no_memory;
458
 
                if (virStrncpy(disk->src, head, offset - head,
459
 
                               (offset - head) + 1) == NULL) {
460
 
                    XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
461
 
                               _("Source file %s too big for destination"),
462
 
                               head);
463
 
                    goto cleanup;
464
 
                }
465
 
            }
466
 
            head = offset + 1;
467
 
 
468
 
            /* Remove legacy ioemu: junk */
469
 
            if (STRPREFIX(head, "ioemu:"))
470
 
                head = head + 6;
471
 
 
472
 
            /* Extract the dest device name */
473
 
            if (!(offset = strchr(head, ',')))
474
 
                goto skipdisk;
475
 
            if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
476
 
                goto no_memory;
477
 
            if (virStrncpy(disk->dst, head, offset - head,
478
 
                           (offset - head) + 1) == NULL) {
479
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
480
 
                           _("Dest file %s too big for destination"), head);
481
 
                goto cleanup;
482
 
            }
483
 
            head = offset + 1;
484
 
 
485
 
 
486
 
            /* Extract source driver type */
487
 
            if (disk->src) {
488
 
                /* The main type  phy:, file:, tap: ... */
489
 
                if ((tmp = strchr(disk->src, ':')) != NULL) {
490
 
                    if (VIR_ALLOC_N(disk->driverName, (tmp - disk->src) + 1) < 0)
491
 
                        goto no_memory;
492
 
                    if (virStrncpy(disk->driverName, disk->src,
493
 
                                   (tmp - disk->src),
494
 
                                   (tmp - disk->src) + 1) == NULL) {
495
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
496
 
                                   _("Driver name %s too big for destination"),
497
 
                                   disk->src);
498
 
                        goto cleanup;
499
 
                    }
500
 
 
501
 
                    /* Strip the prefix we found off the source file name */
502
 
                    memmove(disk->src, disk->src+(tmp-disk->src)+1,
503
 
                            strlen(disk->src)-(tmp-disk->src));
504
 
                }
505
 
 
506
 
                /* And the sub-type for tap:XXX: type */
507
 
                if (disk->driverName &&
508
 
                    STREQ(disk->driverName, "tap")) {
509
 
                    if (!(tmp = strchr(disk->src, ':')))
510
 
                        goto skipdisk;
511
 
                    if (VIR_ALLOC_N(disk->driverType, (tmp - disk->src) + 1) < 0)
512
 
                        goto no_memory;
513
 
                    if (virStrncpy(disk->driverType, disk->src,
514
 
                                   (tmp - disk->src),
515
 
                                   (tmp - disk->src) + 1) == NULL) {
516
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
517
 
                                   _("Driver type %s too big for destination"),
518
 
                                   disk->src);
519
 
                        goto cleanup;
520
 
                    }
521
 
 
522
 
                    /* Strip the prefix we found off the source file name */
523
 
                    memmove(disk->src, disk->src+(tmp-disk->src)+1,
524
 
                            strlen(disk->src)-(tmp-disk->src));
525
 
                }
526
 
            }
527
 
 
528
 
            /* No source, or driver name, so fix to phy: */
529
 
            if (!disk->driverName &&
530
 
                !(disk->driverName = strdup("phy")))
531
 
                goto no_memory;
532
 
 
533
 
 
534
 
            /* phy: type indicates a block device */
535
 
            disk->type = STREQ(disk->driverName, "phy") ?
536
 
                VIR_DOMAIN_DISK_TYPE_BLOCK : VIR_DOMAIN_DISK_TYPE_FILE;
537
 
 
538
 
            /* Check for a :cdrom/:disk postfix */
539
 
            disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
540
 
            if ((tmp = strchr(disk->dst, ':')) != NULL) {
541
 
                if (STREQ(tmp, ":cdrom"))
542
 
                    disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
543
 
                tmp[0] = '\0';
544
 
            }
545
 
 
546
 
            if (STRPREFIX(disk->dst, "xvd") || !hvm) {
547
 
                disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
548
 
            } else if (STRPREFIX(disk->dst, "sd")) {
549
 
                disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
550
 
            } else {
551
 
                disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
552
 
            }
553
 
 
554
 
            if (STREQ(head, "r") ||
555
 
                STREQ(head, "ro"))
556
 
                disk->readonly = 1;
557
 
            else if ((STREQ(head, "w!")) ||
558
 
                     (STREQ(head, "!")))
559
 
                disk->shared = 1;
560
 
 
561
 
            /* Maintain list in sorted order according to target device name */
562
 
            if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
563
 
                goto no_memory;
564
 
            def->disks[def->ndisks++] = disk;
565
 
            disk = NULL;
566
 
 
567
 
            skipdisk:
568
 
            list = list->next;
569
 
            virDomainDiskDefFree(disk);
570
 
        }
571
 
    }
572
 
 
573
 
    if (hvm && xendConfigVersion == 1) {
574
 
        if (xenXMConfigGetString(conf, "cdrom", &str, NULL) < 0)
575
 
            goto cleanup;
576
 
        if (str) {
577
 
            if (VIR_ALLOC(disk) < 0)
578
 
                goto no_memory;
579
 
 
580
 
            disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
581
 
            disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
582
 
            if (!(disk->driverName = strdup("file")))
583
 
                goto no_memory;
584
 
            if (!(disk->src = strdup(str)))
585
 
                goto no_memory;
586
 
            if (!(disk->dst = strdup("hdc")))
587
 
                goto no_memory;
588
 
            disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
589
 
            disk->readonly = 1;
590
 
 
591
 
            if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
592
 
                goto no_memory;
593
 
            def->disks[def->ndisks++] = disk;
594
 
            disk = NULL;
595
 
        }
596
 
    }
597
 
 
598
 
    list = virConfGetValue(conf, "vif");
599
 
    if (list && list->type == VIR_CONF_LIST) {
600
 
        list = list->list;
601
 
        while (list) {
602
 
            char model[10];
603
 
            char type[10];
604
 
            char ip[16];
605
 
            char mac[18];
606
 
            char bridge[50];
607
 
            char vifname[50];
608
 
            char *key;
609
 
 
610
 
            bridge[0] = '\0';
611
 
            mac[0] = '\0';
612
 
            ip[0] = '\0';
613
 
            model[0] = '\0';
614
 
            type[0] = '\0';
615
 
            vifname[0] = '\0';
616
 
 
617
 
            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
618
 
                goto skipnic;
619
 
 
620
 
            key = list->str;
621
 
            while (key) {
622
 
                char *data;
623
 
                char *nextkey = strchr(key, ',');
624
 
 
625
 
                if (!(data = strchr(key, '=')))
626
 
                    goto skipnic;
627
 
                data++;
628
 
 
629
 
                if (STRPREFIX(key, "mac=")) {
630
 
                    int len = nextkey ? (nextkey - data) : sizeof(mac) - 1;
631
 
                    if (virStrncpy(mac, data, len, sizeof(mac)) == NULL) {
632
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
633
 
                                   _("MAC address %s too big for destination"),
634
 
                                   data);
635
 
                        goto skipnic;
636
 
                    }
637
 
                } else if (STRPREFIX(key, "bridge=")) {
638
 
                    int len = nextkey ? (nextkey - data) : sizeof(bridge) - 1;
639
 
                    if (virStrncpy(bridge, data, len, sizeof(bridge)) == NULL) {
640
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
641
 
                                   _("Bridge %s too big for destination"),
642
 
                                   data);
643
 
                        goto skipnic;
644
 
                    }
645
 
                } else if (STRPREFIX(key, "script=")) {
646
 
                    int len = nextkey ? (nextkey - data) : strlen(data);
647
 
                    VIR_FREE(script);
648
 
                    if (!(script = strndup(data, len))) {
649
 
                        goto no_memory;
650
 
                    }
651
 
                } else if (STRPREFIX(key, "model=")) {
652
 
                    int len = nextkey ? (nextkey - data) : sizeof(model) - 1;
653
 
                    if (virStrncpy(model, data, len, sizeof(model)) == NULL) {
654
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
655
 
                                   _("Model %s too big for destination"), data);
656
 
                        goto skipnic;
657
 
                    }
658
 
                } else if (STRPREFIX(key, "type=")) {
659
 
                    int len = nextkey ? (nextkey - data) : sizeof(type) - 1;
660
 
                    if (virStrncpy(type, data, len, sizeof(type)) == NULL) {
661
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
662
 
                                   _("Type %s too big for destination"), data);
663
 
                        goto skipnic;
664
 
                    }
665
 
                } else if (STRPREFIX(key, "vifname=")) {
666
 
                    int len = nextkey ? (nextkey - data) : sizeof(vifname) - 1;
667
 
                    if (virStrncpy(vifname, data, len, sizeof(vifname)) == NULL) {
668
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
669
 
                                   _("Vifname %s too big for destination"),
670
 
                                   data);
671
 
                        goto skipnic;
672
 
                    }
673
 
                } else if (STRPREFIX(key, "ip=")) {
674
 
                    int len = nextkey ? (nextkey - data) : sizeof(ip) - 1;
675
 
                    if (virStrncpy(ip, data, len, sizeof(ip)) == NULL) {
676
 
                        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
677
 
                                   _("IP %s too big for destination"), data);
678
 
                        goto skipnic;
679
 
                    }
680
 
                }
681
 
 
682
 
                while (nextkey && (nextkey[0] == ',' ||
683
 
                                   nextkey[0] == ' ' ||
684
 
                                   nextkey[0] == '\t'))
685
 
                    nextkey++;
686
 
                key = nextkey;
687
 
            }
688
 
 
689
 
            if (VIR_ALLOC(net) < 0)
690
 
                goto no_memory;
691
 
 
692
 
            if (mac[0]) {
693
 
                if (virParseMacAddr(mac, net->mac) < 0) {
694
 
                    XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
695
 
                               _("malformed mac address '%s'"), mac);
696
 
                    goto cleanup;
697
 
                }
698
 
            }
699
 
 
700
 
            if (bridge[0] || STREQ_NULLABLE(script, "vif-bridge") ||
701
 
                STREQ_NULLABLE(script, "vif-vnic")) {
702
 
                net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
703
 
            } else {
704
 
                net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
705
 
            }
706
 
 
707
 
            if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
708
 
                if (bridge[0] &&
709
 
                    !(net->data.bridge.brname = strdup(bridge)))
710
 
                    goto no_memory;
711
 
                if (script[0] &&
712
 
                    !(net->data.bridge.script = strdup(script)))
713
 
                    goto no_memory;
714
 
                if (ip[0] &&
715
 
                    !(net->data.bridge.ipaddr = strdup(ip)))
716
 
                    goto no_memory;
717
 
            } else {
718
 
                if (script && script[0] &&
719
 
                    !(net->data.ethernet.script = strdup(script)))
720
 
                    goto no_memory;
721
 
                if (ip[0] &&
722
 
                    !(net->data.ethernet.ipaddr = strdup(ip)))
723
 
                    goto no_memory;
724
 
            }
725
 
 
726
 
            if (model[0] &&
727
 
                !(net->model = strdup(model)))
728
 
                goto no_memory;
729
 
 
730
 
            if (!model[0] && type[0] &&
731
 
                STREQ(type, "netfront") &&
732
 
                !(net->model = strdup("netfront")))
733
 
                goto no_memory;
734
 
 
735
 
            if (vifname[0] &&
736
 
                !(net->ifname = strdup(vifname)))
737
 
                goto no_memory;
738
 
 
739
 
            if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0)
740
 
                goto no_memory;
741
 
            def->nets[def->nnets++] = net;
742
 
            net = NULL;
743
 
 
744
 
        skipnic:
745
 
            list = list->next;
746
 
            virDomainNetDefFree(net);
747
 
        }
748
 
    }
749
 
 
750
 
    list = virConfGetValue(conf, "pci");
751
 
    if (list && list->type == VIR_CONF_LIST) {
752
 
        list = list->list;
753
 
        while (list) {
754
 
            char domain[5];
755
 
            char bus[3];
756
 
            char slot[3];
757
 
            char func[2];
758
 
            char *key, *nextkey;
759
 
            int domainID;
760
 
            int busID;
761
 
            int slotID;
762
 
            int funcID;
763
 
 
764
 
            domain[0] = bus[0] = slot[0] = func[0] = '\0';
765
 
 
766
 
            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
767
 
                goto skippci;
768
 
 
769
 
            /* pci=['0000:00:1b.0','0000:00:13.0'] */
770
 
            if (!(key = list->str))
771
 
                goto skippci;
772
 
            if (!(nextkey = strchr(key, ':')))
773
 
                goto skippci;
774
 
 
775
 
            if (virStrncpy(domain, key, (nextkey - key), sizeof(domain)) == NULL) {
776
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
777
 
                           _("Domain %s too big for destination"), key);
778
 
                goto skippci;
779
 
            }
780
 
 
781
 
            key = nextkey + 1;
782
 
            if (!(nextkey = strchr(key, ':')))
783
 
                goto skippci;
784
 
 
785
 
            if (virStrncpy(bus, key, (nextkey - key), sizeof(bus)) == NULL) {
786
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
787
 
                           _("Bus %s too big for destination"), key);
788
 
                goto skippci;
789
 
            }
790
 
 
791
 
            key = nextkey + 1;
792
 
            if (!(nextkey = strchr(key, '.')))
793
 
                goto skippci;
794
 
 
795
 
            if (virStrncpy(slot, key, (nextkey - key), sizeof(slot)) == NULL) {
796
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
797
 
                           _("Slot %s too big for destination"), key);
798
 
                goto skippci;
799
 
            }
800
 
 
801
 
            key = nextkey + 1;
802
 
            if (strlen(key) != 1)
803
 
                goto skippci;
804
 
 
805
 
            if (virStrncpy(func, key, 1, sizeof(func)) == NULL) {
806
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
807
 
                           _("Function %s too big for destination"), key);
808
 
                goto skippci;
809
 
            }
810
 
 
811
 
            if (virStrToLong_i(domain, NULL, 16, &domainID) < 0)
812
 
                goto skippci;
813
 
            if (virStrToLong_i(bus, NULL, 16, &busID) < 0)
814
 
                goto skippci;
815
 
            if (virStrToLong_i(slot, NULL, 16, &slotID) < 0)
816
 
                goto skippci;
817
 
            if (virStrToLong_i(func, NULL, 16, &funcID) < 0)
818
 
                goto skippci;
819
 
 
820
 
            if (VIR_ALLOC(hostdev) < 0)
821
 
                goto no_memory;
822
 
 
823
 
            hostdev->managed = 0;
824
 
            hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
825
 
            hostdev->source.subsys.u.pci.domain = domainID;
826
 
            hostdev->source.subsys.u.pci.bus = busID;
827
 
            hostdev->source.subsys.u.pci.slot = slotID;
828
 
            hostdev->source.subsys.u.pci.function = funcID;
829
 
 
830
 
            if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0)
831
 
                goto no_memory;
832
 
            def->hostdevs[def->nhostdevs++] = hostdev;
833
 
            hostdev = NULL;
834
 
 
835
 
        skippci:
836
 
            list = list->next;
837
 
        }
838
 
    }
839
 
 
840
 
    if (hvm) {
841
 
        if (xenXMConfigGetString(conf, "usbdevice", &str, NULL) < 0)
842
 
            goto cleanup;
843
 
        if (str &&
844
 
            (STREQ(str, "tablet") ||
845
 
             STREQ(str, "mouse"))) {
846
 
            virDomainInputDefPtr input;
847
 
            if (VIR_ALLOC(input) < 0)
848
 
                goto no_memory;
849
 
            input->bus = VIR_DOMAIN_INPUT_BUS_USB;
850
 
            input->type = STREQ(str, "tablet") ?
851
 
                VIR_DOMAIN_INPUT_TYPE_TABLET :
852
 
                VIR_DOMAIN_INPUT_TYPE_MOUSE;
853
 
            if (VIR_ALLOC_N(def->inputs, 1) < 0) {
854
 
                virDomainInputDefFree(input);
855
 
                goto no_memory;
856
 
            }
857
 
            def->inputs[0] = input;
858
 
            def->ninputs = 1;
859
 
        }
860
 
    }
861
 
 
862
 
    /* HVM guests, or old PV guests use this config format */
863
 
    if (hvm || xendConfigVersion < 3) {
864
 
        if (xenXMConfigGetBool(conf, "vnc", &val, 0) < 0)
865
 
            goto cleanup;
866
 
 
867
 
        if (val) {
868
 
            if (VIR_ALLOC(graphics) < 0)
869
 
                goto no_memory;
870
 
            graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
871
 
            if (xenXMConfigGetBool(conf, "vncunused", &val, 1) < 0)
872
 
                goto cleanup;
873
 
            graphics->data.vnc.autoport = val ? 1 : 0;
874
 
 
875
 
            if (!graphics->data.vnc.autoport) {
876
 
                unsigned long vncdisplay;
877
 
                if (xenXMConfigGetULong(conf, "vncdisplay", &vncdisplay, 0) < 0)
878
 
                    goto cleanup;
879
 
                graphics->data.vnc.port = (int)vncdisplay + 5900;
880
 
            }
881
 
 
882
 
            if (xenXMConfigCopyStringOpt(conf, "vnclisten", &listenAddr) < 0)
883
 
                goto cleanup;
884
 
            if (listenAddr &&
885
 
                virDomainGraphicsListenSetAddress(graphics, 0, listenAddr,
886
 
                                                  -1, true) < 0) {
887
 
               goto cleanup;
888
 
            }
889
 
            VIR_FREE(listenAddr);
890
 
 
891
 
            if (xenXMConfigCopyStringOpt(conf, "vncpasswd", &graphics->data.vnc.auth.passwd) < 0)
892
 
                goto cleanup;
893
 
            if (xenXMConfigCopyStringOpt(conf, "keymap", &graphics->data.vnc.keymap) < 0)
894
 
                goto cleanup;
895
 
 
896
 
            if (VIR_ALLOC_N(def->graphics, 1) < 0)
897
 
                goto no_memory;
898
 
            def->graphics[0] = graphics;
899
 
            def->ngraphics = 1;
900
 
            graphics = NULL;
901
 
        } else {
902
 
            if (xenXMConfigGetBool(conf, "sdl", &val, 0) < 0)
903
 
                goto cleanup;
904
 
            if (val) {
905
 
                if (VIR_ALLOC(graphics) < 0)
906
 
                    goto no_memory;
907
 
                graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
908
 
                if (xenXMConfigCopyStringOpt(conf, "display", &graphics->data.sdl.display) < 0)
909
 
                    goto cleanup;
910
 
                if (xenXMConfigCopyStringOpt(conf, "xauthority", &graphics->data.sdl.xauth) < 0)
911
 
                    goto cleanup;
912
 
                if (VIR_ALLOC_N(def->graphics, 1) < 0)
913
 
                    goto no_memory;
914
 
                def->graphics[0] = graphics;
915
 
                def->ngraphics = 1;
916
 
                graphics = NULL;
917
 
            }
918
 
        }
919
 
    }
920
 
 
921
 
    if (!hvm && def->graphics == NULL) { /* New PV guests use this format */
922
 
        list = virConfGetValue(conf, "vfb");
923
 
        if (list && list->type == VIR_CONF_LIST &&
924
 
            list->list && list->list->type == VIR_CONF_STRING &&
925
 
            list->list->str) {
926
 
            char vfb[MAX_VFB];
927
 
            char *key = vfb;
928
 
 
929
 
            if (virStrcpyStatic(vfb, list->list->str) == NULL) {
930
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
931
 
                           _("VFB %s too big for destination"),
932
 
                           list->list->str);
933
 
                goto cleanup;
934
 
            }
935
 
 
936
 
            if (VIR_ALLOC(graphics) < 0)
937
 
                goto no_memory;
938
 
 
939
 
            if (strstr(key, "type=sdl"))
940
 
                graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
941
 
            else
942
 
                graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
943
 
 
944
 
            while (key) {
945
 
                char *nextkey = strchr(key, ',');
946
 
                char *end = nextkey;
947
 
                if (nextkey) {
948
 
                    *end = '\0';
949
 
                    nextkey++;
950
 
                }
951
 
 
952
 
                if (!strchr(key, '='))
953
 
                    break;
954
 
 
955
 
                if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
956
 
                    if (STRPREFIX(key, "vncunused=")) {
957
 
                        if (STREQ(key + 10, "1"))
958
 
                            graphics->data.vnc.autoport = 1;
959
 
                    } else if (STRPREFIX(key, "vnclisten=")) {
960
 
                        if (virDomainGraphicsListenSetAddress(graphics, 0, key+10,
961
 
                                                              -1, true) < 0)
962
 
                            goto cleanup;
963
 
                    } else if (STRPREFIX(key, "vncpasswd=")) {
964
 
                        if (!(graphics->data.vnc.auth.passwd = strdup(key + 10)))
965
 
                            goto no_memory;
966
 
                    } else if (STRPREFIX(key, "keymap=")) {
967
 
                        if (!(graphics->data.vnc.keymap = strdup(key + 7)))
968
 
                            goto no_memory;
969
 
                    } else if (STRPREFIX(key, "vncdisplay=")) {
970
 
                        graphics->data.vnc.port = strtol(key+11, NULL, 10) + 5900;
971
 
                    }
972
 
                } else {
973
 
                    if (STRPREFIX(key, "display=")) {
974
 
                        if (!(graphics->data.sdl.display = strdup(key + 8)))
975
 
                            goto no_memory;
976
 
                    } else if (STRPREFIX(key, "xauthority=")) {
977
 
                        if (!(graphics->data.sdl.xauth = strdup(key + 11)))
978
 
                            goto no_memory;
979
 
                    }
980
 
                }
981
 
 
982
 
                while (nextkey && (nextkey[0] == ',' ||
983
 
                                   nextkey[0] == ' ' ||
984
 
                                   nextkey[0] == '\t'))
985
 
                    nextkey++;
986
 
                key = nextkey;
987
 
            }
988
 
            if (VIR_ALLOC_N(def->graphics, 1) < 0)
989
 
                goto no_memory;
990
 
            def->graphics[0] = graphics;
991
 
            def->ngraphics = 1;
992
 
            graphics = NULL;
993
 
        }
994
 
    }
995
 
 
996
 
    if (hvm) {
997
 
        virDomainChrDefPtr chr = NULL;
998
 
 
999
 
        if (xenXMConfigGetString(conf, "parallel", &str, NULL) < 0)
1000
 
            goto cleanup;
1001
 
        if (str && STRNEQ(str, "none") &&
1002
 
            !(chr = xenParseSxprChar(str, NULL)))
1003
 
            goto cleanup;
1004
 
 
1005
 
        if (chr) {
1006
 
            if (VIR_ALLOC_N(def->parallels, 1) < 0) {
1007
 
                virDomainChrDefFree(chr);
1008
 
                goto no_memory;
1009
 
            }
1010
 
            chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
1011
 
            chr->target.port = 0;
1012
 
            def->parallels[0] = chr;
1013
 
            def->nparallels++;
1014
 
            chr = NULL;
1015
 
        }
1016
 
 
1017
 
        /* Try to get the list of values to support multiple serial ports */
1018
 
        list = virConfGetValue(conf, "serial");
1019
 
        if (list && list->type == VIR_CONF_LIST) {
1020
 
            int portnum = -1;
1021
 
 
1022
 
            list = list->list;
1023
 
            while (list) {
1024
 
                char *port = NULL;
1025
 
 
1026
 
                if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
1027
 
                    goto cleanup;
1028
 
 
1029
 
                port = list->str;
1030
 
                portnum++;
1031
 
                if (STREQ(port, "none")) {
1032
 
                    list = list->next;
1033
 
                    continue;
1034
 
                }
1035
 
 
1036
 
                if (!(chr = xenParseSxprChar(port, NULL)))
1037
 
                    goto cleanup;
1038
 
 
1039
 
                if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0)
1040
 
                    goto no_memory;
1041
 
 
1042
 
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
1043
 
                chr->target.port = portnum;
1044
 
 
1045
 
                def->serials[def->nserials++] = chr;
1046
 
                chr = NULL;
1047
 
 
1048
 
                list = list->next;
1049
 
            }
1050
 
        } else {
1051
 
            /* If domain is not using multiple serial ports we parse data old way */
1052
 
            if (xenXMConfigGetString(conf, "serial", &str, NULL) < 0)
1053
 
                goto cleanup;
1054
 
            if (str && STRNEQ(str, "none") &&
1055
 
                !(chr = xenParseSxprChar(str, NULL)))
1056
 
                goto cleanup;
1057
 
            if (chr) {
1058
 
                if (VIR_ALLOC_N(def->serials, 1) < 0) {
1059
 
                    virDomainChrDefFree(chr);
1060
 
                    goto no_memory;
1061
 
                }
1062
 
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
1063
 
                chr->target.port = 0;
1064
 
                def->serials[0] = chr;
1065
 
                def->nserials++;
1066
 
            }
1067
 
        }
1068
 
    } else {
1069
 
        def->nconsoles = 1;
1070
 
        if (VIR_ALLOC_N(def->consoles, 1) < 0)
1071
 
            goto no_memory;
1072
 
        if (!(def->consoles[0] = xenParseSxprChar("pty", NULL)))
1073
 
            goto cleanup;
1074
 
        def->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
1075
 
        def->consoles[0]->target.port = 0;
1076
 
        def->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
1077
 
    }
1078
 
 
1079
 
    if (hvm) {
1080
 
        if (xenXMConfigGetString(conf, "soundhw", &str, NULL) < 0)
1081
 
            goto cleanup;
1082
 
 
1083
 
        if (str &&
1084
 
            xenParseSxprSound(def, str) < 0)
1085
 
            goto cleanup;
1086
 
    }
1087
 
 
1088
 
    VIR_FREE(script);
1089
 
    return def;
1090
 
 
1091
 
no_memory:
1092
 
    virReportOOMError();
1093
 
    /* fallthrough */
1094
 
cleanup:
1095
 
    virDomainGraphicsDefFree(graphics);
1096
 
    virDomainNetDefFree(net);
1097
 
    virDomainDiskDefFree(disk);
1098
 
    virDomainDefFree(def);
1099
 
    VIR_FREE(script);
1100
 
    VIR_FREE(listenAddr);
1101
 
    return NULL;
1102
 
}
1103
 
 
1104
 
 
1105
 
static
1106
 
int xenXMConfigSetInt(virConfPtr conf, const char *setting, long l) {
1107
 
    virConfValuePtr value = NULL;
1108
 
 
1109
 
    if (VIR_ALLOC(value) < 0) {
1110
 
        virReportOOMError();
1111
 
        return -1;
1112
 
    }
1113
 
 
1114
 
    value->type = VIR_CONF_LONG;
1115
 
    value->next = NULL;
1116
 
    value->l = l;
1117
 
 
1118
 
    return virConfSetValue(conf, setting, value);
1119
 
}
1120
 
 
1121
 
 
1122
 
static
1123
 
int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str) {
1124
 
    virConfValuePtr value = NULL;
1125
 
 
1126
 
    if (VIR_ALLOC(value) < 0) {
1127
 
        virReportOOMError();
1128
 
        return -1;
1129
 
    }
1130
 
 
1131
 
    value->type = VIR_CONF_STRING;
1132
 
    value->next = NULL;
1133
 
    if (!(value->str = strdup(str))) {
1134
 
        VIR_FREE(value);
1135
 
        virReportOOMError();
1136
 
        return -1;
1137
 
    }
1138
 
 
1139
 
    return virConfSetValue(conf, setting, value);
1140
 
}
1141
 
 
1142
 
 
1143
 
static int xenFormatXMDisk(virConfValuePtr list,
1144
 
                                       virDomainDiskDefPtr disk,
1145
 
                                       int hvm,
1146
 
                                       int xendConfigVersion)
1147
 
{
1148
 
    virBuffer buf = VIR_BUFFER_INITIALIZER;
1149
 
    virConfValuePtr val, tmp;
1150
 
 
1151
 
    if(disk->src) {
1152
 
        if (disk->driverName) {
1153
 
            virBufferAsprintf(&buf, "%s:", disk->driverName);
1154
 
            if (STREQ(disk->driverName, "tap"))
1155
 
                virBufferAsprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
1156
 
        } else {
1157
 
            switch (disk->type) {
1158
 
            case VIR_DOMAIN_DISK_TYPE_FILE:
1159
 
                virBufferAddLit(&buf, "file:");
1160
 
                break;
1161
 
            case VIR_DOMAIN_DISK_TYPE_BLOCK:
1162
 
                virBufferAddLit(&buf, "phy:");
1163
 
                break;
1164
 
            default:
1165
 
                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
1166
 
                           _("unsupported disk type %s"),
1167
 
                           virDomainDiskTypeToString(disk->type));
1168
 
                goto cleanup;
1169
 
            }
1170
 
        }
1171
 
        virBufferAdd(&buf, disk->src, -1);
1172
 
    }
1173
 
    virBufferAddLit(&buf, ",");
1174
 
    if (hvm && xendConfigVersion == 1)
1175
 
        virBufferAddLit(&buf, "ioemu:");
1176
 
 
1177
 
    virBufferAdd(&buf, disk->dst, -1);
1178
 
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
1179
 
        virBufferAddLit(&buf, ":cdrom");
1180
 
 
1181
 
    if (disk->readonly)
1182
 
        virBufferAddLit(&buf, ",r");
1183
 
    else if (disk->shared)
1184
 
        virBufferAddLit(&buf, ",!");
1185
 
    else
1186
 
        virBufferAddLit(&buf, ",w");
1187
 
    if (disk->transient) {
1188
 
        XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
1189
 
                    _("transient disks not supported yet"));
1190
 
        return -1;
1191
 
    }
1192
 
 
1193
 
    if (virBufferError(&buf)) {
1194
 
        virReportOOMError();
1195
 
        goto cleanup;
1196
 
    }
1197
 
 
1198
 
    if (VIR_ALLOC(val) < 0) {
1199
 
        virReportOOMError();
1200
 
        goto cleanup;
1201
 
    }
1202
 
 
1203
 
    val->type = VIR_CONF_STRING;
1204
 
    val->str = virBufferContentAndReset(&buf);
1205
 
    tmp = list->list;
1206
 
    while (tmp && tmp->next)
1207
 
        tmp = tmp->next;
1208
 
    if (tmp)
1209
 
        tmp->next = val;
1210
 
    else
1211
 
        list->list = val;
1212
 
 
1213
 
    return 0;
1214
 
 
1215
 
cleanup:
1216
 
    virBufferFreeAndReset(&buf);
1217
 
    return -1;
1218
 
}
1219
 
 
1220
 
static int xenFormatXMSerial(virConfValuePtr list,
1221
 
                             virDomainChrDefPtr serial)
1222
 
{
1223
 
    virBuffer buf = VIR_BUFFER_INITIALIZER;
1224
 
    virConfValuePtr val, tmp;
1225
 
    int ret;
1226
 
 
1227
 
    if (serial) {
1228
 
        ret = xenFormatSxprChr(serial, &buf);
1229
 
        if (ret < 0) {
1230
 
            virReportOOMError();
1231
 
            goto cleanup;
1232
 
        }
1233
 
    } else {
1234
 
        virBufferAddLit(&buf, "none");
1235
 
    }
1236
 
    if (virBufferError(&buf)) {
1237
 
        virReportOOMError();
1238
 
        goto cleanup;
1239
 
    }
1240
 
 
1241
 
    if (VIR_ALLOC(val) < 0) {
1242
 
        virReportOOMError();
1243
 
        goto cleanup;
1244
 
    }
1245
 
 
1246
 
    val->type = VIR_CONF_STRING;
1247
 
    val->str = virBufferContentAndReset(&buf);
1248
 
    tmp = list->list;
1249
 
    while (tmp && tmp->next)
1250
 
        tmp = tmp->next;
1251
 
    if (tmp)
1252
 
        tmp->next = val;
1253
 
    else
1254
 
        list->list = val;
1255
 
 
1256
 
    return 0;
1257
 
 
1258
 
cleanup:
1259
 
    virBufferFreeAndReset(&buf);
1260
 
    return -1;
1261
 
}
1262
 
 
1263
 
static int xenFormatXMNet(virConnectPtr conn,
1264
 
                                      virConfValuePtr list,
1265
 
                                      virDomainNetDefPtr net,
1266
 
                                      int hvm, int xendConfigVersion)
1267
 
{
1268
 
    virBuffer buf = VIR_BUFFER_INITIALIZER;
1269
 
    virConfValuePtr val, tmp;
1270
 
 
1271
 
    virBufferAsprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
1272
 
                      net->mac[0], net->mac[1],
1273
 
                      net->mac[2], net->mac[3],
1274
 
                      net->mac[4], net->mac[5]);
1275
 
 
1276
 
    switch (net->type) {
1277
 
    case VIR_DOMAIN_NET_TYPE_BRIDGE:
1278
 
        virBufferAsprintf(&buf, ",bridge=%s", net->data.bridge.brname);
1279
 
        if (net->data.bridge.ipaddr)
1280
 
            virBufferAsprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
1281
 
        virBufferAsprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
1282
 
        break;
1283
 
 
1284
 
    case VIR_DOMAIN_NET_TYPE_ETHERNET:
1285
 
        if (net->data.ethernet.script)
1286
 
            virBufferAsprintf(&buf, ",script=%s", net->data.ethernet.script);
1287
 
        if (net->data.ethernet.ipaddr)
1288
 
            virBufferAsprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
1289
 
        break;
1290
 
 
1291
 
    case VIR_DOMAIN_NET_TYPE_NETWORK:
1292
 
    {
1293
 
        virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
1294
 
        char *bridge;
1295
 
        if (!network) {
1296
 
            XENXS_ERROR(VIR_ERR_NO_NETWORK, "%s",
1297
 
                       net->data.network.name);
1298
 
            return -1;
1299
 
        }
1300
 
        bridge = virNetworkGetBridgeName(network);
1301
 
        virNetworkFree(network);
1302
 
        if (!bridge) {
1303
 
            XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
1304
 
                       _("network %s is not active"),
1305
 
                       net->data.network.name);
1306
 
            return -1;
1307
 
        }
1308
 
 
1309
 
        virBufferAsprintf(&buf, ",bridge=%s", bridge);
1310
 
        virBufferAsprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
1311
 
    }
1312
 
    break;
1313
 
 
1314
 
    default:
1315
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
1316
 
                   _("unsupported network type %d"),
1317
 
                   net->type);
1318
 
        goto cleanup;
1319
 
    }
1320
 
 
1321
 
    if (!hvm) {
1322
 
        if (net->model != NULL)
1323
 
            virBufferAsprintf(&buf, ",model=%s", net->model);
1324
 
    }
1325
 
    else if (net->model == NULL) {
1326
 
        /*
1327
 
         * apparently type ioemu breaks paravirt drivers on HVM so skip this
1328
 
         * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
1329
 
         */
1330
 
        if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
1331
 
            virBufferAddLit(&buf, ",type=ioemu");
1332
 
    }
1333
 
    else if (STREQ(net->model, "netfront")) {
1334
 
        virBufferAddLit(&buf, ",type=netfront");
1335
 
    }
1336
 
    else {
1337
 
        virBufferAsprintf(&buf, ",model=%s", net->model);
1338
 
        virBufferAddLit(&buf, ",type=ioemu");
1339
 
    }
1340
 
 
1341
 
    if (net->ifname)
1342
 
        virBufferAsprintf(&buf, ",vifname=%s",
1343
 
                          net->ifname);
1344
 
 
1345
 
    if (virBufferError(&buf)) {
1346
 
        virReportOOMError();
1347
 
        goto cleanup;
1348
 
    }
1349
 
 
1350
 
    if (VIR_ALLOC(val) < 0) {
1351
 
        virReportOOMError();
1352
 
        goto cleanup;
1353
 
    }
1354
 
 
1355
 
    val->type = VIR_CONF_STRING;
1356
 
    val->str = virBufferContentAndReset(&buf);
1357
 
    tmp = list->list;
1358
 
    while (tmp && tmp->next)
1359
 
        tmp = tmp->next;
1360
 
    if (tmp)
1361
 
        tmp->next = val;
1362
 
    else
1363
 
        list->list = val;
1364
 
 
1365
 
    return 0;
1366
 
 
1367
 
cleanup:
1368
 
    virBufferFreeAndReset(&buf);
1369
 
    return -1;
1370
 
}
1371
 
 
1372
 
 
1373
 
 
1374
 
static int
1375
 
xenFormatXMPCI(virConfPtr conf,
1376
 
                           virDomainDefPtr def)
1377
 
{
1378
 
 
1379
 
    virConfValuePtr pciVal = NULL;
1380
 
    int hasPCI = 0;
1381
 
    int i;
1382
 
 
1383
 
    for (i = 0 ; i < def->nhostdevs ; i++)
1384
 
        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
1385
 
            def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
1386
 
            hasPCI = 1;
1387
 
 
1388
 
    if (!hasPCI)
1389
 
        return 0;
1390
 
 
1391
 
    if (VIR_ALLOC(pciVal) < 0) {
1392
 
        virReportOOMError();
1393
 
        return -1;
1394
 
    }
1395
 
 
1396
 
    pciVal->type = VIR_CONF_LIST;
1397
 
    pciVal->list = NULL;
1398
 
 
1399
 
    for (i = 0 ; i < def->nhostdevs ; i++) {
1400
 
        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
1401
 
            def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
1402
 
            virConfValuePtr val, tmp;
1403
 
            char *buf;
1404
 
 
1405
 
            if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
1406
 
                            def->hostdevs[i]->source.subsys.u.pci.domain,
1407
 
                            def->hostdevs[i]->source.subsys.u.pci.bus,
1408
 
                            def->hostdevs[i]->source.subsys.u.pci.slot,
1409
 
                            def->hostdevs[i]->source.subsys.u.pci.function) < 0) {
1410
 
                virReportOOMError();
1411
 
                goto error;
1412
 
            }
1413
 
 
1414
 
            if (VIR_ALLOC(val) < 0) {
1415
 
                VIR_FREE(buf);
1416
 
                virReportOOMError();
1417
 
                goto error;
1418
 
            }
1419
 
            val->type = VIR_CONF_STRING;
1420
 
            val->str = buf;
1421
 
            tmp = pciVal->list;
1422
 
            while (tmp && tmp->next)
1423
 
                tmp = tmp->next;
1424
 
            if (tmp)
1425
 
                tmp->next = val;
1426
 
            else
1427
 
                pciVal->list = val;
1428
 
        }
1429
 
    }
1430
 
 
1431
 
    if (pciVal->list != NULL) {
1432
 
        int ret = virConfSetValue(conf, "pci", pciVal);
1433
 
        pciVal = NULL;
1434
 
        if (ret < 0)
1435
 
            return -1;
1436
 
    }
1437
 
    VIR_FREE(pciVal);
1438
 
 
1439
 
    return 0;
1440
 
 
1441
 
error:
1442
 
    virConfFreeValue(pciVal);
1443
 
    return -1;
1444
 
}
1445
 
 
1446
 
 
1447
 
/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
1448
 
   either 32, or 64 on a platform where long is big enough.  */
1449
 
verify(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
1450
 
 
1451
 
virConfPtr xenFormatXM(virConnectPtr conn,
1452
 
                                   virDomainDefPtr def,
1453
 
                                   int xendConfigVersion) {
1454
 
    virConfPtr conf = NULL;
1455
 
    int hvm = 0, i;
1456
 
    char *cpus = NULL;
1457
 
    const char *lifecycle;
1458
 
    char uuid[VIR_UUID_STRING_BUFLEN];
1459
 
    virConfValuePtr diskVal = NULL;
1460
 
    virConfValuePtr netVal = NULL;
1461
 
 
1462
 
    if (!(conf = virConfNew()))
1463
 
        goto cleanup;
1464
 
 
1465
 
 
1466
 
    if (xenXMConfigSetString(conf, "name", def->name) < 0)
1467
 
        goto no_memory;
1468
 
 
1469
 
    virUUIDFormat(def->uuid, uuid);
1470
 
    if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
1471
 
        goto no_memory;
1472
 
 
1473
 
    if (xenXMConfigSetInt(conf, "maxmem", VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
1474
 
        goto no_memory;
1475
 
 
1476
 
    if (xenXMConfigSetInt(conf, "memory", VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
1477
 
        goto no_memory;
1478
 
 
1479
 
    if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
1480
 
        goto no_memory;
1481
 
    /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
1482
 
       either 32, or 64 on a platform where long is big enough.  */
1483
 
    if (def->vcpus < def->maxvcpus &&
1484
 
        xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
1485
 
        goto no_memory;
1486
 
 
1487
 
    if ((def->cpumask != NULL) &&
1488
 
        ((cpus = virDomainCpuSetFormat(def->cpumask,
1489
 
                                       def->cpumasklen)) == NULL))
1490
 
        goto cleanup;
1491
 
 
1492
 
    if (cpus &&
1493
 
        xenXMConfigSetString(conf, "cpus", cpus) < 0)
1494
 
        goto no_memory;
1495
 
    VIR_FREE(cpus);
1496
 
 
1497
 
    hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
1498
 
 
1499
 
    if (hvm) {
1500
 
        char boot[VIR_DOMAIN_BOOT_LAST+1];
1501
 
        if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
1502
 
            goto no_memory;
1503
 
 
1504
 
        if (def->os.loader &&
1505
 
            xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
1506
 
            goto no_memory;
1507
 
 
1508
 
        for (i = 0 ; i < def->os.nBootDevs ; i++) {
1509
 
            switch (def->os.bootDevs[i]) {
1510
 
            case VIR_DOMAIN_BOOT_FLOPPY:
1511
 
                boot[i] = 'a';
1512
 
                break;
1513
 
            case VIR_DOMAIN_BOOT_CDROM:
1514
 
                boot[i] = 'd';
1515
 
                break;
1516
 
            case VIR_DOMAIN_BOOT_NET:
1517
 
                boot[i] = 'n';
1518
 
                break;
1519
 
            case VIR_DOMAIN_BOOT_DISK:
1520
 
            default:
1521
 
                boot[i] = 'c';
1522
 
                break;
1523
 
            }
1524
 
        }
1525
 
        if (!def->os.nBootDevs) {
1526
 
            boot[0] = 'c';
1527
 
            boot[1] = '\0';
1528
 
        } else {
1529
 
            boot[def->os.nBootDevs] = '\0';
1530
 
        }
1531
 
 
1532
 
        if (xenXMConfigSetString(conf, "boot", boot) < 0)
1533
 
            goto no_memory;
1534
 
 
1535
 
        if (xenXMConfigSetInt(conf, "pae",
1536
 
                              (def->features &
1537
 
                               (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
1538
 
            goto no_memory;
1539
 
 
1540
 
        if (xenXMConfigSetInt(conf, "acpi",
1541
 
                              (def->features &
1542
 
                               (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
1543
 
            goto no_memory;
1544
 
 
1545
 
        if (xenXMConfigSetInt(conf, "apic",
1546
 
                              (def->features &
1547
 
                               (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
1548
 
            goto no_memory;
1549
 
 
1550
 
        if (xendConfigVersion >= 3) {
1551
 
            if (xenXMConfigSetInt(conf, "hap",
1552
 
                                  (def->features &
1553
 
                                   (1 << VIR_DOMAIN_FEATURE_HAP)) ? 1 : 0) < 0)
1554
 
                goto no_memory;
1555
 
 
1556
 
            if (xenXMConfigSetInt(conf, "viridian",
1557
 
                                  (def->features &
1558
 
                                   (1 << VIR_DOMAIN_FEATURE_VIRIDIAN)) ? 1 : 0) < 0)
1559
 
                goto no_memory;
1560
 
        }
1561
 
 
1562
 
        if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
1563
 
            if (def->clock.data.timezone) {
1564
 
                XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
1565
 
                           "%s", _("configurable timezones are not supported"));
1566
 
                goto cleanup;
1567
 
            }
1568
 
 
1569
 
            if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
1570
 
                goto no_memory;
1571
 
        } else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
1572
 
            if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
1573
 
                goto no_memory;
1574
 
        } else {
1575
 
            /* XXX We could support Xen's rtc clock offset */
1576
 
            XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
1577
 
                       _("unsupported clock offset '%s'"),
1578
 
                       virDomainClockOffsetTypeToString(def->clock.offset));
1579
 
            goto cleanup;
1580
 
        }
1581
 
 
1582
 
        for (i = 0; i < def->clock.ntimers; i++) {
1583
 
            if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET &&
1584
 
                def->clock.timers[i]->present != -1 &&
1585
 
                xenXMConfigSetInt(conf, "hpet", def->clock.timers[i]->present) < 0)
1586
 
                    break;
1587
 
        }
1588
 
 
1589
 
        if (xendConfigVersion == 1) {
1590
 
            for (i = 0 ; i < def->ndisks ; i++) {
1591
 
                if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
1592
 
                    def->disks[i]->dst &&
1593
 
                    STREQ(def->disks[i]->dst, "hdc") &&
1594
 
                    def->disks[i]->src) {
1595
 
                    if (xenXMConfigSetString(conf, "cdrom",
1596
 
                                             def->disks[i]->src) < 0)
1597
 
                        goto no_memory;
1598
 
                    break;
1599
 
                }
1600
 
            }
1601
 
        }
1602
 
 
1603
 
        /* XXX floppy disks */
1604
 
    } else {
1605
 
        if (def->os.bootloader &&
1606
 
            xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
1607
 
            goto no_memory;
1608
 
        if (def->os.bootloaderArgs &&
1609
 
            xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
1610
 
            goto no_memory;
1611
 
        if (def->os.kernel &&
1612
 
            xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
1613
 
            goto no_memory;
1614
 
        if (def->os.initrd &&
1615
 
            xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
1616
 
            goto no_memory;
1617
 
        if (def->os.cmdline &&
1618
 
            xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
1619
 
            goto no_memory;
1620
 
 
1621
 
    }
1622
 
 
1623
 
    if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
1624
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
1625
 
                   _("unexpected lifecycle action %d"), def->onPoweroff);
1626
 
        goto cleanup;
1627
 
    }
1628
 
    if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
1629
 
        goto no_memory;
1630
 
 
1631
 
 
1632
 
    if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
1633
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
1634
 
                   _("unexpected lifecycle action %d"), def->onReboot);
1635
 
        goto cleanup;
1636
 
    }
1637
 
    if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
1638
 
        goto no_memory;
1639
 
 
1640
 
 
1641
 
    if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
1642
 
        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
1643
 
                   _("unexpected lifecycle action %d"), def->onCrash);
1644
 
        goto cleanup;
1645
 
    }
1646
 
    if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
1647
 
        goto no_memory;
1648
 
 
1649
 
 
1650
 
 
1651
 
    if (hvm) {
1652
 
        if (def->emulator &&
1653
 
            xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
1654
 
            goto no_memory;
1655
 
 
1656
 
        for (i = 0 ; i < def->ninputs ; i++) {
1657
 
            if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
1658
 
                if (xenXMConfigSetInt(conf, "usb", 1) < 0)
1659
 
                    goto no_memory;
1660
 
                if (xenXMConfigSetString(conf, "usbdevice",
1661
 
                                         def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
1662
 
                                         "mouse" : "tablet") < 0)
1663
 
                    goto no_memory;
1664
 
                break;
1665
 
            }
1666
 
        }
1667
 
    }
1668
 
 
1669
 
    if (def->ngraphics == 1) {
1670
 
        if (xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
1671
 
            if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
1672
 
                if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
1673
 
                    goto no_memory;
1674
 
                if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
1675
 
                    goto no_memory;
1676
 
                if (def->graphics[0]->data.sdl.display &&
1677
 
                    xenXMConfigSetString(conf, "display",
1678
 
                                     def->graphics[0]->data.sdl.display) < 0)
1679
 
                    goto no_memory;
1680
 
                if (def->graphics[0]->data.sdl.xauth &&
1681
 
                    xenXMConfigSetString(conf, "xauthority",
1682
 
                                         def->graphics[0]->data.sdl.xauth) < 0)
1683
 
                    goto no_memory;
1684
 
            } else {
1685
 
                const char *listenAddr;
1686
 
 
1687
 
                if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
1688
 
                    goto no_memory;
1689
 
                if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
1690
 
                    goto no_memory;
1691
 
                if (xenXMConfigSetInt(conf, "vncunused",
1692
 
                              def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
1693
 
                    goto no_memory;
1694
 
                if (!def->graphics[0]->data.vnc.autoport &&
1695
 
                    xenXMConfigSetInt(conf, "vncdisplay",
1696
 
                                  def->graphics[0]->data.vnc.port - 5900) < 0)
1697
 
                    goto no_memory;
1698
 
                listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
1699
 
                if (listenAddr &&
1700
 
                    xenXMConfigSetString(conf, "vnclisten", listenAddr) < 0)
1701
 
                    goto no_memory;
1702
 
                if (def->graphics[0]->data.vnc.auth.passwd &&
1703
 
                    xenXMConfigSetString(conf, "vncpasswd",
1704
 
                                        def->graphics[0]->data.vnc.auth.passwd) < 0)
1705
 
                    goto no_memory;
1706
 
                if (def->graphics[0]->data.vnc.keymap &&
1707
 
                    xenXMConfigSetString(conf, "keymap",
1708
 
                                        def->graphics[0]->data.vnc.keymap) < 0)
1709
 
                    goto no_memory;
1710
 
            }
1711
 
        } else {
1712
 
            virConfValuePtr vfb, disp;
1713
 
            char *vfbstr = NULL;
1714
 
            virBuffer buf = VIR_BUFFER_INITIALIZER;
1715
 
            if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
1716
 
                virBufferAddLit(&buf, "type=sdl");
1717
 
                if (def->graphics[0]->data.sdl.display)
1718
 
                    virBufferAsprintf(&buf, ",display=%s",
1719
 
                                      def->graphics[0]->data.sdl.display);
1720
 
                if (def->graphics[0]->data.sdl.xauth)
1721
 
                    virBufferAsprintf(&buf, ",xauthority=%s",
1722
 
                                      def->graphics[0]->data.sdl.xauth);
1723
 
            } else {
1724
 
                const char *listenAddr
1725
 
                    = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
1726
 
 
1727
 
                virBufferAddLit(&buf, "type=vnc");
1728
 
                virBufferAsprintf(&buf, ",vncunused=%d",
1729
 
                                  def->graphics[0]->data.vnc.autoport ? 1 : 0);
1730
 
                if (!def->graphics[0]->data.vnc.autoport)
1731
 
                    virBufferAsprintf(&buf, ",vncdisplay=%d",
1732
 
                                      def->graphics[0]->data.vnc.port - 5900);
1733
 
                if (listenAddr)
1734
 
                    virBufferAsprintf(&buf, ",vnclisten=%s", listenAddr);
1735
 
                if (def->graphics[0]->data.vnc.auth.passwd)
1736
 
                    virBufferAsprintf(&buf, ",vncpasswd=%s",
1737
 
                                      def->graphics[0]->data.vnc.auth.passwd);
1738
 
                if (def->graphics[0]->data.vnc.keymap)
1739
 
                    virBufferAsprintf(&buf, ",keymap=%s",
1740
 
                                      def->graphics[0]->data.vnc.keymap);
1741
 
            }
1742
 
            if (virBufferError(&buf)) {
1743
 
                virBufferFreeAndReset(&buf);
1744
 
                goto no_memory;
1745
 
            }
1746
 
 
1747
 
            vfbstr = virBufferContentAndReset(&buf);
1748
 
 
1749
 
            if (VIR_ALLOC(vfb) < 0) {
1750
 
                VIR_FREE(vfbstr);
1751
 
                goto no_memory;
1752
 
            }
1753
 
 
1754
 
            if (VIR_ALLOC(disp) < 0) {
1755
 
                VIR_FREE(vfb);
1756
 
                VIR_FREE(vfbstr);
1757
 
                goto no_memory;
1758
 
            }
1759
 
 
1760
 
            vfb->type = VIR_CONF_LIST;
1761
 
            vfb->list = disp;
1762
 
            disp->type = VIR_CONF_STRING;
1763
 
            disp->str = vfbstr;
1764
 
 
1765
 
            if (virConfSetValue(conf, "vfb", vfb) < 0)
1766
 
                goto no_memory;
1767
 
        }
1768
 
    }
1769
 
 
1770
 
    /* analyze of the devices */
1771
 
    if (VIR_ALLOC(diskVal) < 0)
1772
 
        goto no_memory;
1773
 
    diskVal->type = VIR_CONF_LIST;
1774
 
    diskVal->list = NULL;
1775
 
 
1776
 
    for (i = 0 ; i < def->ndisks ; i++) {
1777
 
        if (xendConfigVersion == 1 &&
1778
 
            def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
1779
 
            def->disks[i]->dst &&
1780
 
            STREQ(def->disks[i]->dst, "hdc")) {
1781
 
            continue;
1782
 
        }
1783
 
        if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
1784
 
            continue;
1785
 
 
1786
 
        if (xenFormatXMDisk(diskVal, def->disks[i],
1787
 
                            hvm, xendConfigVersion) < 0)
1788
 
            goto cleanup;
1789
 
    }
1790
 
    if (diskVal->list != NULL) {
1791
 
        int ret = virConfSetValue(conf, "disk", diskVal);
1792
 
        diskVal = NULL;
1793
 
        if (ret < 0)
1794
 
            goto no_memory;
1795
 
    }
1796
 
    VIR_FREE(diskVal);
1797
 
 
1798
 
    if (VIR_ALLOC(netVal) < 0)
1799
 
        goto no_memory;
1800
 
    netVal->type = VIR_CONF_LIST;
1801
 
    netVal->list = NULL;
1802
 
 
1803
 
    for (i = 0 ; i < def->nnets ; i++) {
1804
 
        if (xenFormatXMNet(conn, netVal,def->nets[i],
1805
 
                           hvm, xendConfigVersion) < 0)
1806
 
            goto cleanup;
1807
 
    }
1808
 
    if (netVal->list != NULL) {
1809
 
        int ret = virConfSetValue(conf, "vif", netVal);
1810
 
        netVal = NULL;
1811
 
        if (ret < 0)
1812
 
            goto no_memory;
1813
 
    }
1814
 
    VIR_FREE(netVal);
1815
 
 
1816
 
    if (xenFormatXMPCI(conf, def) < 0)
1817
 
        goto cleanup;
1818
 
 
1819
 
    if (hvm) {
1820
 
        if (def->nparallels) {
1821
 
            virBuffer buf = VIR_BUFFER_INITIALIZER;
1822
 
            char *str;
1823
 
            int ret;
1824
 
 
1825
 
            ret = xenFormatSxprChr(def->parallels[0], &buf);
1826
 
            str = virBufferContentAndReset(&buf);
1827
 
            if (ret == 0)
1828
 
                ret = xenXMConfigSetString(conf, "parallel", str);
1829
 
            VIR_FREE(str);
1830
 
            if (ret < 0)
1831
 
                goto no_memory;
1832
 
        } else {
1833
 
            if (xenXMConfigSetString(conf, "parallel", "none") < 0)
1834
 
                goto no_memory;
1835
 
        }
1836
 
 
1837
 
        if (def->nserials) {
1838
 
            if ((def->nserials == 1) && (def->serials[0]->target.port == 0)) {
1839
 
                virBuffer buf = VIR_BUFFER_INITIALIZER;
1840
 
                char *str;
1841
 
                int ret;
1842
 
 
1843
 
                ret = xenFormatSxprChr(def->serials[0], &buf);
1844
 
                str = virBufferContentAndReset(&buf);
1845
 
                if (ret == 0)
1846
 
                    ret = xenXMConfigSetString(conf, "serial", str);
1847
 
                VIR_FREE(str);
1848
 
                if (ret < 0)
1849
 
                    goto no_memory;
1850
 
            } else {
1851
 
                int j = 0;
1852
 
                int maxport = -1;
1853
 
                virConfValuePtr serialVal = NULL;
1854
 
 
1855
 
                if (VIR_ALLOC(serialVal) < 0)
1856
 
                    goto no_memory;
1857
 
                serialVal->type = VIR_CONF_LIST;
1858
 
                serialVal->list = NULL;
1859
 
 
1860
 
                for (i = 0; i < def->nserials; i++)
1861
 
                    if (def->serials[i]->target.port > maxport)
1862
 
                        maxport = def->serials[i]->target.port;
1863
 
 
1864
 
                for (i = 0; i <= maxport; i++) {
1865
 
                    virDomainChrDefPtr chr = NULL;
1866
 
                    for (j = 0; j < def->nserials; j++) {
1867
 
                        if (def->serials[j]->target.port == i) {
1868
 
                            chr = def->serials[j];
1869
 
                            break;
1870
 
                        }
1871
 
                    }
1872
 
                    if (xenFormatXMSerial(serialVal, chr) < 0)
1873
 
                        goto cleanup;
1874
 
                }
1875
 
 
1876
 
                if (serialVal->list != NULL) {
1877
 
                    int ret = virConfSetValue(conf, "serial", serialVal);
1878
 
                    serialVal = NULL;
1879
 
                    if (ret < 0)
1880
 
                        goto no_memory;
1881
 
                }
1882
 
                VIR_FREE(serialVal);
1883
 
            }
1884
 
        } else {
1885
 
            if (xenXMConfigSetString(conf, "serial", "none") < 0)
1886
 
                goto no_memory;
1887
 
        }
1888
 
 
1889
 
 
1890
 
        if (def->sounds) {
1891
 
            virBuffer buf = VIR_BUFFER_INITIALIZER;
1892
 
            char *str = NULL;
1893
 
            int ret = xenFormatSxprSound(def, &buf);
1894
 
            str = virBufferContentAndReset(&buf);
1895
 
            if (ret == 0)
1896
 
                ret = xenXMConfigSetString(conf, "soundhw", str);
1897
 
 
1898
 
            VIR_FREE(str);
1899
 
            if (ret < 0)
1900
 
                goto no_memory;
1901
 
        }
1902
 
    }
1903
 
 
1904
 
    return conf;
1905
 
 
1906
 
no_memory:
1907
 
    virReportOOMError();
1908
 
 
1909
 
cleanup:
1910
 
    virConfFreeValue(diskVal);
1911
 
    virConfFreeValue(netVal);
1912
 
    VIR_FREE(cpus);
1913
 
    if (conf)
1914
 
        virConfFree(conf);
1915
 
    return (NULL);
1916
 
}