45
45
#include "xs_internal.h" /* To extract VNC port & Serial console TTY */
46
46
#include "memory.h"
47
47
#include "count-one-bits.h"
49
50
/* required for cpumap_t */
50
51
#include <xen/dom0_ops.h>
52
53
#define VIR_FROM_THIS VIR_FROM_XEND
57
56
* The number of Xen scheduler parameters
59
# define XEN_SCHED_SEDF_NPARAM 6
60
# define XEN_SCHED_CRED_NPARAM 2
58
#define XEN_SCHED_SEDF_NPARAM 6
59
#define XEN_SCHED_CRED_NPARAM 2
64
61
#ifdef WITH_RHEL5_API
65
62
# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 0
1245
1227
if (STRPREFIX(prefix, "telnet")) {
1246
def->type = VIR_DOMAIN_CHR_TYPE_TCP;
1247
def->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
1228
def->source.type = VIR_DOMAIN_CHR_TYPE_TCP;
1229
def->source.data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
1249
if ((def->type = virDomainChrTypeFromString(prefix)) < 0) {
1231
if ((def->source.type = virDomainChrTypeFromString(prefix)) < 0) {
1250
1232
virXendError(VIR_ERR_INTERNAL_ERROR,
1251
1233
_("unknown chr device type '%s'"), prefix);
1257
1239
/* Compat with legacy <console tty='/dev/pts/5'/> syntax */
1258
switch (def->type) {
1240
switch (def->source.type) {
1259
1241
case VIR_DOMAIN_CHR_TYPE_PTY:
1260
1242
if (tty != NULL &&
1261
!(def->data.file.path = strdup(tty)))
1243
!(def->source.data.file.path = strdup(tty)))
1262
1244
goto no_memory;
1265
1247
case VIR_DOMAIN_CHR_TYPE_FILE:
1266
1248
case VIR_DOMAIN_CHR_TYPE_PIPE:
1267
if (!(def->data.file.path = strdup(value)))
1249
if (!(def->source.data.file.path = strdup(value)))
1268
1250
goto no_memory;
1282
1264
if (offset != value &&
1283
(def->data.tcp.host = strndup(value, offset - value)) == NULL)
1265
(def->source.data.tcp.host = strndup(value,
1266
offset - value)) == NULL)
1284
1267
goto no_memory;
1286
1269
offset2 = strchr(offset, ',');
1287
1270
if (offset2 == NULL)
1288
def->data.tcp.service = strdup(offset+1);
1271
def->source.data.tcp.service = strdup(offset+1);
1290
def->data.tcp.service = strndup(offset+1, offset2-(offset+1));
1291
if (def->data.tcp.service == NULL)
1273
def->source.data.tcp.service = strndup(offset+1,
1274
offset2-(offset+1));
1275
if (def->source.data.tcp.service == NULL)
1292
1276
goto no_memory;
1294
1278
if (offset2 && strstr(offset2, ",server"))
1295
def->data.tcp.listen = 1;
1279
def->source.data.tcp.listen = true;
1310
1294
if (offset != value &&
1311
(def->data.udp.connectHost = strndup(value, offset - value)) == NULL)
1295
(def->source.data.udp.connectHost
1296
= strndup(value, offset - value)) == NULL)
1312
1297
goto no_memory;
1314
1299
offset2 = strchr(offset, '@');
1315
1300
if (offset2 != NULL) {
1316
if ((def->data.udp.connectService = strndup(offset + 1, offset2-(offset+1))) == NULL)
1301
if ((def->source.data.udp.connectService
1302
= strndup(offset + 1, offset2-(offset+1))) == NULL)
1317
1303
goto no_memory;
1319
1305
offset3 = strchr(offset2, ':');
1326
1312
if (offset3 > (offset2 + 1) &&
1327
(def->data.udp.bindHost = strndup(offset2 + 1, offset3 - (offset2+1))) == NULL)
1313
(def->source.data.udp.bindHost
1314
= strndup(offset2 + 1, offset3 - (offset2+1))) == NULL)
1328
1315
goto no_memory;
1330
if ((def->data.udp.bindService = strdup(offset3 + 1)) == NULL)
1317
if ((def->source.data.udp.bindService
1318
= strdup(offset3 + 1)) == NULL)
1331
1319
goto no_memory;
1333
if ((def->data.udp.connectService = strdup(offset + 1)) == NULL)
1321
if ((def->source.data.udp.connectService
1322
= strdup(offset + 1)) == NULL)
1334
1323
goto no_memory;
1341
1330
const char *offset = strchr(value, ',');
1343
def->data.nix.path = strndup(value, (offset - value));
1332
def->source.data.nix.path = strndup(value, (offset - value));
1345
def->data.nix.path = strdup(value);
1346
if (def->data.nix.path == NULL)
1334
def->source.data.nix.path = strdup(value);
1335
if (def->source.data.nix.path == NULL)
1347
1336
goto no_memory;
1349
1338
if (offset != NULL &&
1350
1339
strstr(offset, ",server") != NULL)
1351
def->data.nix.listen = 1;
1340
def->source.data.nix.listen = true;
2521
2506
if (procs == 0) /* Sanity check in case of Xen bugs in futures..*/
2523
2508
info->sockets = nr_cpus / procs;
2524
/* Should already be fine, but for further sanity make
2525
* sure we have at least one socket
2527
if (info->sockets == 0)
2511
/* On systems where NUMA nodes are not composed of whole sockets either Xen
2512
* provided us wrong number of sockets per node or we computed the wrong
2513
* number in the compatibility code above. In such case, we compute the
2514
* correct number of sockets on the host, lie about the number of NUMA
2515
* nodes, and force apps to check capabilities XML for the actual NUMA
2518
if (info->nodes * info->sockets * info->cores * info->threads
2521
info->sockets = info->cpus / (info->cores * info->threads);
3119
3111
if (domain->id < 0 && priv->xendConfigVersion < 3)
3122
snprintf(buf, sizeof(buf), "%lu", memory >> 10);
3114
snprintf(buf, sizeof(buf), "%lu", VIR_DIV_UP(memory, 1024));
3123
3115
return xend_op(domain->conn, domain->name, "op", "maxmem_set", "memory",
3156
3148
if (domain->id < 0 && priv->xendConfigVersion < 3)
3159
snprintf(buf, sizeof(buf), "%lu", memory >> 10);
3151
snprintf(buf, sizeof(buf), "%lu", VIR_DIV_UP(memory, 1024));
3160
3152
return xend_op(domain->conn, domain->name, "op", "mem_target_set",
3161
3153
"target", buf, NULL);
3164
#endif /* ! PROXY */
3166
3157
virDomainDefPtr
3167
3158
xenDaemonDomainFetch(virConnectPtr conn,
4057
4062
if (xenDaemonFormatSxprOnePCI(dev->data.hostdev,
4066
virDomainDevicePCIAddress PCIAddr;
4068
PCIAddr = dev->data.hostdev->source.subsys.u.pci;
4069
virAsprintf(&target, "PCI device: %.4x:%.2x:%.2x", PCIAddr.domain,
4070
PCIAddr.bus, PCIAddr.slot);
4072
if (target == NULL) {
4073
virReportOOMError();
4061
4077
virXendError(VIR_ERR_NO_SUPPORT, "%s",
4062
4078
_("unsupported device type"));
4076
4092
/* device doesn't exist, define it */
4077
4093
ret = xend_op(domain->conn, domain->name, "op", "device_create",
4078
4094
"config", sexpr, NULL);
4081
/* device exists, attempt to modify it */
4082
ret = xend_op(domain->conn, domain->name, "op", "device_configure",
4083
"config", sexpr, "dev", ref, NULL);
4096
if (dev->data.disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
4097
virXendError(VIR_ERR_OPERATION_INVALID,
4098
_("target '%s' already exists"), target);
4100
/* device exists, attempt to modify it */
4101
ret = xend_op(domain->conn, domain->name, "op", "device_configure",
4102
"config", sexpr, "dev", ref, NULL);
4087
4107
VIR_FREE(sexpr);
4088
4108
virDomainDefFree(def);
4089
4109
virDomainDeviceDefFree(dev);
5252
5271
if (def->data.vnc.listenAddr)
5253
5272
virBufferVSprintf(buf, "(vnclisten '%s')", def->data.vnc.listenAddr);
5254
if (def->data.vnc.passwd)
5255
virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.passwd);
5273
if (def->data.vnc.auth.passwd)
5274
virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd);
5256
5275
if (def->data.vnc.keymap)
5257
5276
virBufferVSprintf(buf, "(keymap '%s')", def->data.vnc.keymap);
5295
5314
if (def->data.vnc.listenAddr)
5296
5315
virBufferVSprintf(buf, "(vnclisten '%s')", def->data.vnc.listenAddr);
5297
if (def->data.vnc.passwd)
5298
virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.passwd);
5316
if (def->data.vnc.auth.passwd)
5317
virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd);
5299
5318
if (def->data.vnc.keymap)
5300
5319
virBufferVSprintf(buf, "(keymap '%s')", def->data.vnc.keymap);
5328
5347
case VIR_DOMAIN_CHR_TYPE_FILE:
5329
5348
case VIR_DOMAIN_CHR_TYPE_PIPE:
5330
virBufferVSprintf(buf, "%s:%s", type, def->data.file.path);
5349
virBufferVSprintf(buf, "%s:", type);
5350
virBufferEscapeSexpr(buf, "%s", def->source.data.file.path);
5333
5353
case VIR_DOMAIN_CHR_TYPE_DEV:
5334
virBufferVSprintf(buf, "%s", def->data.file.path);
5354
virBufferEscapeSexpr(buf, "%s", def->source.data.file.path);
5337
5357
case VIR_DOMAIN_CHR_TYPE_TCP:
5338
5358
virBufferVSprintf(buf, "%s:%s:%s%s",
5339
(def->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW ?
5359
(def->source.data.tcp.protocol
5360
== VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW ?
5340
5361
"tcp" : "telnet"),
5341
(def->data.tcp.host ? def->data.tcp.host : ""),
5342
(def->data.tcp.service ? def->data.tcp.service : ""),
5343
(def->data.tcp.listen ? ",server,nowait" : ""));
5362
(def->source.data.tcp.host ?
5363
def->source.data.tcp.host : ""),
5364
(def->source.data.tcp.service ?
5365
def->source.data.tcp.service : ""),
5366
(def->source.data.tcp.listen ?
5367
",server,nowait" : ""));
5346
5370
case VIR_DOMAIN_CHR_TYPE_UDP:
5347
5371
virBufferVSprintf(buf, "%s:%s:%s@%s:%s", type,
5348
(def->data.udp.connectHost ? def->data.udp.connectHost : ""),
5349
(def->data.udp.connectService ? def->data.udp.connectService : ""),
5350
(def->data.udp.bindHost ? def->data.udp.bindHost : ""),
5351
(def->data.udp.bindService ? def->data.udp.bindService : ""));
5372
(def->source.data.udp.connectHost ?
5373
def->source.data.udp.connectHost : ""),
5374
(def->source.data.udp.connectService ?
5375
def->source.data.udp.connectService : ""),
5376
(def->source.data.udp.bindHost ?
5377
def->source.data.udp.bindHost : ""),
5378
(def->source.data.udp.bindService ?
5379
def->source.data.udp.bindService : ""));
5354
5382
case VIR_DOMAIN_CHR_TYPE_UNIX:
5355
virBufferVSprintf(buf, "%s:%s%s", type,
5357
def->data.nix.listen ? ",server,nowait" : "");
5383
virBufferVSprintf(buf, "%s:", type);
5384
virBufferEscapeSexpr(buf, "%s", def->source.data.nix.path);
5385
if (def->source.data.nix.listen)
5386
virBufferAddLit(buf, ",server,nowait");
5432
5461
/* Xend <= 3.0.2 wants a ioemu: prefix on devices for HVM */
5433
if (xendConfigVersion == 1)
5434
virBufferVSprintf(buf, "(dev 'ioemu:%s')", def->dst);
5435
else /* But newer does not */
5436
virBufferVSprintf(buf, "(dev '%s:%s')", def->dst,
5462
if (xendConfigVersion == 1) {
5463
virBufferEscapeSexpr(buf, "(dev 'ioemu:%s')", def->dst);
5465
/* But newer does not */
5466
virBufferEscapeSexpr(buf, "(dev '%s:", def->dst);
5467
virBufferVSprintf(buf, "%s')",
5437
5468
def->device == VIR_DOMAIN_DISK_DEVICE_CDROM ?
5438
5469
"cdrom" : "disk");
5439
5471
} else if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
5440
virBufferVSprintf(buf, "(dev '%s:cdrom')", def->dst);
5472
virBufferEscapeSexpr(buf, "(dev '%s:cdrom')", def->dst);
5442
virBufferVSprintf(buf, "(dev '%s')", def->dst);
5474
virBufferEscapeSexpr(buf, "(dev '%s')", def->dst);
5445
5477
if (def->src) {
5446
5478
if (def->driverName) {
5447
5479
if (STREQ(def->driverName, "tap") ||
5448
5480
STREQ(def->driverName, "tap2")) {
5449
virBufferVSprintf(buf, "(uname '%s:%s:%s')",
5451
def->driverType ? def->driverType : "aio",
5481
virBufferEscapeSexpr(buf, "(uname '%s:", def->driverName);
5482
virBufferEscapeSexpr(buf, "%s:",
5483
def->driverType ? def->driverType : "aio");
5484
virBufferEscapeSexpr(buf, "%s')", def->src);
5454
virBufferVSprintf(buf, "(uname '%s:%s')",
5486
virBufferEscapeSexpr(buf, "(uname '%s:", def->driverName);
5487
virBufferEscapeSexpr(buf, "%s')", def->src);
5459
5490
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
5460
virBufferVSprintf(buf, "(uname 'file:%s')", def->src);
5491
virBufferEscapeSexpr(buf, "(uname 'file:%s')", def->src);
5461
5492
} else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
5462
5493
if (def->src[0] == '/')
5463
virBufferVSprintf(buf, "(uname 'phy:%s')", def->src);
5494
virBufferEscapeSexpr(buf, "(uname 'phy:%s')", def->src);
5465
virBufferVSprintf(buf, "(uname 'phy:/dev/%s')", def->src);
5496
virBufferEscapeSexpr(buf, "(uname 'phy:/dev/%s')",
5467
5499
virXendError(VIR_ERR_CONFIG_UNSUPPORTED,
5468
5500
_("unsupported disk type %s"),
5532
5564
switch (def->type) {
5533
5565
case VIR_DOMAIN_NET_TYPE_BRIDGE:
5534
virBufferVSprintf(buf, "(bridge '%s')", def->data.bridge.brname);
5566
virBufferEscapeSexpr(buf, "(bridge '%s')", def->data.bridge.brname);
5535
5567
if (def->data.bridge.script)
5536
5568
script = def->data.bridge.script;
5538
virBufferVSprintf(buf, "(script '%s')", script);
5570
virBufferEscapeSexpr(buf, "(script '%s')", script);
5539
5571
if (def->data.bridge.ipaddr != NULL)
5540
virBufferVSprintf(buf, "(ip '%s')", def->data.bridge.ipaddr);
5572
virBufferEscapeSexpr(buf, "(ip '%s')", def->data.bridge.ipaddr);
5543
5575
case VIR_DOMAIN_NET_TYPE_NETWORK:
5560
5592
def->data.network.name);
5563
virBufferVSprintf(buf, "(bridge '%s')", bridge);
5564
virBufferVSprintf(buf, "(script '%s')", script);
5595
virBufferEscapeSexpr(buf, "(bridge '%s')", bridge);
5596
virBufferEscapeSexpr(buf, "(script '%s')", script);
5565
5597
VIR_FREE(bridge);
5569
5601
case VIR_DOMAIN_NET_TYPE_ETHERNET:
5570
5602
if (def->data.ethernet.script)
5571
virBufferVSprintf(buf, "(script '%s')", def->data.ethernet.script);
5603
virBufferEscapeSexpr(buf, "(script '%s')",
5604
def->data.ethernet.script);
5572
5605
if (def->data.ethernet.ipaddr != NULL)
5573
virBufferVSprintf(buf, "(ip '%s')", def->data.ethernet.ipaddr);
5606
virBufferEscapeSexpr(buf, "(ip '%s')", def->data.ethernet.ipaddr);
5576
5609
case VIR_DOMAIN_NET_TYPE_USER:
5586
5619
if (def->ifname != NULL &&
5587
5620
!STRPREFIX(def->ifname, "vif"))
5588
virBufferVSprintf(buf, "(vifname '%s')", def->ifname);
5621
virBufferEscapeSexpr(buf, "(vifname '%s')", def->ifname);
5591
5624
if (def->model != NULL)
5592
virBufferVSprintf(buf, "(model '%s')", def->model);
5625
virBufferEscapeSexpr(buf, "(model '%s')", def->model);
5594
5627
else if (def->model == NULL) {
5763
5802
virBuffer buf = VIR_BUFFER_INITIALIZER;
5764
5803
char uuidstr[VIR_UUID_STRING_BUFLEN];
5765
5804
const char *tmp;
5766
5806
int hvm = 0, i;
5808
DEBUG0("Formatting domain sexpr");
5768
5810
virBufferAddLit(&buf, "(vm ");
5769
virBufferVSprintf(&buf, "(name '%s')", def->name);
5811
virBufferEscapeSexpr(&buf, "(name '%s')", def->name);
5770
5812
virBufferVSprintf(&buf, "(memory %lu)(maxmem %lu)",
5771
def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
5813
VIR_DIV_UP(def->mem.cur_balloon, 1024),
5814
VIR_DIV_UP(def->mem.max_balloon, 1024));
5772
5815
virBufferVSprintf(&buf, "(vcpus %u)", def->maxvcpus);
5773
/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is 32. */
5816
/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
5817
either 32, or 64 on a platform where long is big enough. */
5774
5818
if (def->vcpus < def->maxvcpus)
5775
virBufferVSprintf(&buf, "(vcpu_avail %u)", (1U << def->vcpus) - 1);
5819
virBufferVSprintf(&buf, "(vcpu_avail %lu)", (1UL << def->vcpus) - 1);
5777
5821
if (def->cpumask) {
5778
5822
char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
5779
5823
if (ranges == NULL)
5781
virBufferVSprintf(&buf, "(cpus '%s')", ranges);
5825
virBufferEscapeSexpr(&buf, "(cpus '%s')", ranges);
5782
5826
VIR_FREE(ranges);
5786
5830
virBufferVSprintf(&buf, "(uuid '%s')", uuidstr);
5788
5832
if (def->description)
5789
virBufferVSprintf(&buf, "(description '%s')", def->description);
5833
virBufferEscapeSexpr(&buf, "(description '%s')", def->description);
5791
5835
if (def->os.bootloader) {
5792
5836
if (def->os.bootloader[0])
5793
virBufferVSprintf(&buf, "(bootloader '%s')", def->os.bootloader);
5837
virBufferEscapeSexpr(&buf, "(bootloader '%s')", def->os.bootloader);
5795
5839
virBufferAddLit(&buf, "(bootloader)");
5797
5841
if (def->os.bootloaderArgs)
5798
virBufferVSprintf(&buf, "(bootloader_args '%s')", def->os.bootloaderArgs);
5842
virBufferEscapeSexpr(&buf, "(bootloader_args '%s')", def->os.bootloaderArgs);
5801
5845
if (!(tmp = virDomainLifecycleTypeToString(def->onPoweroff))) {
5854
5898
if (def->os.kernel)
5855
virBufferVSprintf(&buf, "(kernel '%s')", def->os.kernel);
5899
virBufferEscapeSexpr(&buf, "(kernel '%s')", def->os.kernel);
5856
5900
if (def->os.initrd)
5857
virBufferVSprintf(&buf, "(ramdisk '%s')", def->os.initrd);
5901
virBufferEscapeSexpr(&buf, "(ramdisk '%s')", def->os.initrd);
5858
5902
if (def->os.root)
5859
virBufferVSprintf(&buf, "(root '%s')", def->os.root);
5903
virBufferEscapeSexpr(&buf, "(root '%s')", def->os.root);
5860
5904
if (def->os.cmdline)
5861
virBufferVSprintf(&buf, "(args '%s')", def->os.cmdline);
5905
virBufferEscapeSexpr(&buf, "(args '%s')", def->os.cmdline);
5864
5908
char bootorder[VIR_DOMAIN_BOOT_LAST+1];
5865
5909
if (def->os.kernel)
5866
virBufferVSprintf(&buf, "(loader '%s')", def->os.loader);
5910
virBufferEscapeSexpr(&buf, "(loader '%s')", def->os.loader);
5868
virBufferVSprintf(&buf, "(kernel '%s')", def->os.loader);
5912
virBufferEscapeSexpr(&buf, "(kernel '%s')", def->os.loader);
5870
5914
virBufferVSprintf(&buf, "(vcpus %u)", def->maxvcpus);
5871
5915
if (def->vcpus < def->maxvcpus)
5872
virBufferVSprintf(&buf, "(vcpu_avail %u)",
5873
(1U << def->vcpus) - 1);
5916
virBufferVSprintf(&buf, "(vcpu_avail %lu)",
5917
(1UL << def->vcpus) - 1);
5875
5919
for (i = 0 ; i < def->os.nBootDevs ; i++) {
5876
5920
switch (def->os.bootDevs[i]) {
5908
5952
def->disks[i]->src == NULL)
5911
virBufferVSprintf(&buf, "(cdrom '%s')",
5912
def->disks[i]->src);
5955
virBufferEscapeSexpr(&buf, "(cdrom '%s')",
5956
def->disks[i]->src);
5915
5959
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
5916
5960
/* all xend versions define floppies here */
5917
virBufferVSprintf(&buf, "(%s '%s')", def->disks[i]->dst,
5918
def->disks[i]->src);
5961
virBufferEscapeSexpr(&buf, "(%s ", def->disks[i]->dst);
5962
virBufferEscapeSexpr(&buf, "'%s')", def->disks[i]->src);