73
106
if (strcmp(domname, name) == 0) {
74
107
*domid = dominfo[i].domid;
81
char *libxl_poolid_to_name(struct libxl_ctx *ctx, uint32_t poolid)
118
char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid)
84
121
char path[strlen("/local/pool") + 12];
89
124
snprintf(path, sizeof(path), "/local/pool/%d/name", poolid);
90
125
s = xs_read(ctx->xsh, XBT_NULL, path, &len);
91
libxl_ptr_add(ctx, s);
95
int libxl_get_stubdom_id(struct libxl_ctx *ctx, int guest_domid)
97
char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid)));
126
if (!s && (poolid == 0))
127
return strdup("Pool-0");
131
char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid)
133
char *s = libxl_cpupoolid_to_name(libxl__gc_owner(gc), poolid);
135
libxl__ptr_add(gc, s);
139
int libxl_name_to_cpupoolid(libxl_ctx *ctx, const char *name,
144
libxl_cpupoolinfo *poolinfo;
145
int ret = ERROR_INVAL;
147
poolinfo = libxl_list_cpupool(ctx, &nb_pools);
151
for (i = 0; i < nb_pools; i++) {
152
if (ret && ((poolname = libxl_cpupoolid_to_name(ctx,
153
poolinfo[i].poolid)) != NULL)) {
154
if (strcmp(poolname, name) == 0) {
155
*poolid = poolinfo[i].poolid;
160
libxl_cpupoolinfo_destroy(poolinfo + i);
166
int libxl_name_to_schedid(libxl_ctx *ctx, const char *name)
170
for (i = 0; schedid_name[i].name != NULL; i++)
171
if (strcmp(name, schedid_name[i].name) == 0)
172
return schedid_name[i].id;
177
char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid)
181
for (i = 0; schedid_name[i].name != NULL; i++)
182
if (schedid_name[i].id == schedid)
183
return schedid_name[i].name;
188
int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid)
190
libxl__gc gc = LIBXL_INIT_GC(ctx);
194
stubdom_id_s = libxl__xs_read(&gc, XBT_NULL,
195
libxl__sprintf(&gc, "%s/image/device-model-domid",
196
libxl__xs_get_dompath(&gc, guest_domid)));
99
return atoi(stubdom_id_s);
198
ret = atoi(stubdom_id_s);
201
libxl__free_all(&gc);
104
int libxl_is_stubdom(struct libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid)
205
int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid)
207
libxl__gc gc = LIBXL_INIT_GC(ctx);
106
208
char *target, *endptr;
109
target = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid)));
212
target = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)));
112
215
value = strtol(target, &endptr, 10);
113
216
if (*endptr != '\0')
115
218
if (target_domid)
116
219
*target_domid = value;
222
libxl__free_all(&gc);
120
static int logrename(struct libxl_ctx *ctx, const char *old, const char *new) {
226
static int logrename(libxl_ctx *ctx, const char *old, const char *new) {
123
229
r = rename(old, new);
125
231
if (errno == ENOENT) return 0; /* ok */
127
XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to rotate logfile - could not"
233
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to rotate logfile - could not"
128
234
" rename %s to %s", old, new);
129
235
return ERROR_FAIL;
134
int libxl_create_logfile(struct libxl_ctx *ctx, char *name, char **full_name)
240
int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name)
242
libxl__gc gc = LIBXL_INIT_GC(ctx);
136
243
struct stat stat_buf;
137
244
char *logfile, *logfile_new;
140
logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
247
logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log", name);
141
248
if (stat(logfile, &stat_buf) == 0) {
142
249
/* file exists, rotate */
143
logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.10", name);
250
logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log.10", name);
145
252
for (i = 9; i > 0; i--) {
146
logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i);
147
logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i + 1);
253
logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log.%d", name, i);
254
logfile_new = libxl__sprintf(&gc, "/var/log/xen/%s.log.%d", name, i + 1);
148
255
rc = logrename(ctx, logfile, logfile_new);
151
logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
152
logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.1", name);
259
logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log", name);
260
logfile_new = libxl__sprintf(&gc, "/var/log/xen/%s.log.1", name);
154
262
rc = logrename(ctx, logfile, logfile_new);
157
266
if (errno != ENOENT)
158
XL_LOG_ERRNO(ctx, XL_LOG_WARNING, "problem checking existence of"
267
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_WARNING, "problem checking existence of"
159
268
" logfile %s, which might have needed to be rotated",
162
271
*full_name = strdup(logfile);
274
libxl__free_all(&gc);
166
int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, libxl_disk_phystype *phystype)
278
int libxl_string_to_backend(libxl_ctx *ctx, char *s, libxl_disk_backend *backend)
171
283
if (!strcmp(s, "phy")) {
172
*phystype = PHYSTYPE_PHY;
284
*backend = DISK_BACKEND_PHY;
173
285
} else if (!strcmp(s, "file")) {
174
*phystype = PHYSTYPE_FILE;
286
*backend = DISK_BACKEND_TAP;
175
287
} else if (!strcmp(s, "tap")) {
176
288
p = strchr(s, ':');
182
if (!strcmp(p, "aio")) {
183
*phystype = PHYSTYPE_AIO;
184
} else if (!strcmp(p, "vhd")) {
185
*phystype = PHYSTYPE_VHD;
294
if (!strcmp(p, "vhd")) {
295
*backend = DISK_BACKEND_TAP;
186
296
} else if (!strcmp(p, "qcow")) {
187
*phystype = PHYSTYPE_QCOW;
297
*backend = DISK_BACKEND_QDISK;
188
298
} else if (!strcmp(p, "qcow2")) {
189
*phystype = PHYSTYPE_QCOW2;
299
*backend = DISK_BACKEND_QDISK;
196
int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename,
306
int libxl_read_file_contents(libxl_ctx *ctx, const char *filename,
197
307
void **data_r, int *datalen_r) {
199
309
uint8_t *data = 0;
330
int libxl_pipe(struct libxl_ctx *ctx, int pipes[2])
440
int libxl_pipe(libxl_ctx *ctx, int pipes[2])
332
442
if (pipe(pipes) < 0) {
333
XL_LOG(ctx, XL_LOG_ERROR, "Failed to create a pipe");
443
LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Failed to create a pipe");
339
int libxl_mac_to_device_nic(struct libxl_ctx *ctx, uint32_t domid,
449
int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
340
450
const char *mac, libxl_device_nic *nic)
342
452
libxl_nicinfo *nics;
343
453
unsigned int nb, i;
344
455
uint8_t mac_n[6];
349
460
nics = libxl_list_nics(ctx, domid, &nb);
351
462
return ERROR_FAIL;
354
464
for (i = 0, tok = mac; *tok && (i < 6); ++i, tok += 3) {
355
465
mac_n[i] = strtol(tok, &endptr, 16);
356
if (endptr != (tok + 2)) {
466
if (endptr != (tok + 2))
357
467
return ERROR_INVAL;
360
469
memset(nic, 0, sizeof (libxl_device_nic));
361
for (; nb; --nb, ++nics) {
362
for (i = 0, a = nics->mac, b = mac_n;
471
for (i = 0; i < nb; ++i) {
472
for (i = 0, a = nics[i].mac, b = mac_n;
363
473
(b < mac_n + 6) && (*a == *b); ++a, ++b)
365
475
if ((b >= mac_n + 6) && (*a == *b)) {
366
nic->backend_domid = nics->backend_id;
367
nic->domid = nics->frontend_id;
368
nic->devid = nics->devid;
369
memcpy(nic->mac, nics->mac, sizeof (nic->mac));
370
nic->script = nics->script;
371
libxl_free(ctx, nics);
476
nic->backend_domid = nics[i].backend_id;
477
nic->domid = nics[i].frontend_id;
478
nic->devid = nics[i].devid;
479
memcpy(nic->mac, nics[i].mac, sizeof (nic->mac));
480
nic->script = strdup(nics[i].script);
376
libxl_free(ctx, nics);
487
libxl_nicinfo_destroy(&nics[i]);
380
int libxl_devid_to_device_nic(struct libxl_ctx *ctx, uint32_t domid,
492
int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid,
381
493
const char *devid, libxl_device_nic *nic)
495
libxl__gc gc = LIBXL_INIT_GC(ctx);
384
497
char *dompath, *nic_path_fe, *nic_path_be;
387
501
memset(nic, 0, sizeof (libxl_device_nic));
388
dompath = libxl_xs_get_dompath(ctx, domid);
502
dompath = libxl__xs_get_dompath(&gc, domid);
392
nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, devid);
393
nic_path_be = libxl_xs_read(ctx, XBT_NULL,
394
libxl_sprintf(ctx, "%s/backend", nic_path_fe));
395
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", nic_path_fe));
506
nic_path_fe = libxl__sprintf(&gc, "%s/device/vif/%s", dompath, devid);
507
nic_path_be = libxl__xs_read(&gc, XBT_NULL,
508
libxl__sprintf(&gc, "%s/backend", nic_path_fe));
509
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend-id", nic_path_fe));
396
513
nic->backend_domid = strtoul(val, NULL, 10);
397
514
nic->devid = strtoul(devid, NULL, 10);
398
libxl_free(ctx, val);
400
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", nic_path_fe));
516
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mac", nic_path_fe));
401
517
for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
402
518
++i, tok = strtok(NULL, ":")) {
403
519
nic->mac[i] = strtoul(tok, NULL, 16);
405
libxl_free(ctx, val);
406
nic->script = libxl_xs_read(ctx, XBT_NULL,
407
libxl_sprintf(ctx, "%s/script", nic_path_be));
408
libxl_free(ctx, nic_path_fe);
409
libxl_free(ctx, nic_path_be);
521
nic->script = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "%s/script", nic_path_be), NULL);
524
libxl__free_all(&gc);
413
int libxl_devid_to_device_disk(struct libxl_ctx *ctx, uint32_t domid,
528
int libxl_devid_to_device_disk(libxl_ctx *ctx, uint32_t domid,
414
529
const char *devid, libxl_device_disk *disk)
531
libxl__gc gc = LIBXL_INIT_GC(ctx);
416
532
char *endptr, *val;
417
533
char *dompath, *diskpath, *be_path;
418
534
unsigned int devid_n;
535
int rc = ERROR_INVAL;
420
537
devid_n = strtoul(devid, &endptr, 10);
421
538
if (devid == endptr) {
424
dompath = libxl_xs_get_dompath(ctx, domid);
425
diskpath = libxl_sprintf(ctx, "%s/device/vbd/%s", dompath, devid);
542
dompath = libxl__xs_get_dompath(&gc, domid);
543
diskpath = libxl__sprintf(&gc, "%s/device/vbd/%s", dompath, devid);
430
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", diskpath));
548
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend-id", diskpath));
431
551
disk->backend_domid = strtoul(val, NULL, 10);
432
552
disk->domid = domid;
433
be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", diskpath));
434
disk->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/params", be_path));
435
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/type", be_path));
436
libxl_string_to_phystype(ctx, val, &(disk->phystype));
437
disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", be_path));
438
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/removable", be_path));
553
be_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend", diskpath));
554
disk->pdev_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/params", be_path));
555
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/type", be_path));
556
libxl_string_to_backend(ctx, val, &(disk->backend));
557
disk->vdev = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/dev", be_path));
558
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/removable", be_path));
439
559
disk->unpluggable = !strcmp(val, "1");
440
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mode", be_path));
560
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mode", be_path));
441
561
disk->readwrite = !!strcmp(val, "w");
442
val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", diskpath));
562
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/device-type", diskpath));
443
563
disk->is_cdrom = !strcmp(val, "cdrom");
567
libxl__free_all(&gc);
571
int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
572
const char *devid, libxl_device_net2 *net2)
574
libxl__gc gc = LIBXL_INIT_GC(ctx);
575
char *tok, *endptr, *val;
576
char *dompath, *net2path, *be_path;
577
unsigned int devid_n, i;
578
int rc = ERROR_INVAL;
580
devid_n = strtoul(devid, &endptr, 10);
581
if (devid == endptr) {
585
dompath = libxl__xs_get_dompath(&gc, domid);
586
net2path = libxl__sprintf(&gc, "%s/device/vif2/%s", dompath, devid);
590
memset(net2, 0, sizeof (libxl_device_net2));
591
be_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend", net2path));
593
net2->devid = devid_n;
594
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mac", net2path));
595
for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
596
++i, tok = strtok(NULL, ":")) {
597
net2->front_mac[i] = strtoul(tok, NULL, 16);
599
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/remote-mac", net2path));
600
for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
601
++i, tok = strtok(NULL, ":")) {
602
net2->back_mac[i] = strtoul(tok, NULL, 16);
604
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend-id", net2path));
605
net2->backend_domid = strtoul(val, NULL, 10);
608
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/remote-trusted", be_path));
609
net2->trusted = strtoul(val, NULL, 10);
610
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/local-trusted", be_path));
611
net2->back_trusted = strtoul(val, NULL, 10);
612
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/filter-mac", be_path));
613
net2->filter_mac = strtoul(val, NULL, 10);
614
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/filter-mac", net2path));
615
net2->front_filter_mac = strtoul(val, NULL, 10);
616
val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/max-bypasses", be_path));
617
net2->max_bypasses = strtoul(val, NULL, 10);
621
libxl__free_all(&gc);
625
int libxl_strtomac(const char *mac_s, uint8_t *mac)
627
const char *end = mac_s + 17;
630
for (; mac_s < end; mac_s += 3, ++mac) {
631
val = strtoul(mac_s, &endptr, 16);
632
if (endptr != (mac_s + 2)) {
640
#define QEMU_VERSION_STR "QEMU emulator version "
643
int libxl_check_device_model_version(libxl_ctx *ctx, char *path)
645
libxl__gc gc = LIBXL_INIT_GC(ctx);
649
ssize_t i, count = 0;
651
char *abs_path = NULL;
654
abs_path = libxl__abs_path(&gc, path, libxl_private_bindir_path());
666
if (dup2(pipefd[1], STDOUT_FILENO) == -1)
668
execlp(abs_path, abs_path, "-h", NULL);
676
/* attempt to get the first line of `qemu -h` */
677
while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) {
680
for (int j = 0; j < i; j++) {
681
if (buf[j + count] == '\n')
688
waitpid(pid, &status, 0);
689
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
693
/* Check if we have the forked qemu-xen. */
694
/* QEMU-DM emulator version 0.10.2, ... */
695
if (strncmp("QEMU-DM ", buf, 7) == 0) {
700
/* Check if the version is above 12.0 */
701
/* The first line is : QEMU emulator version 0.12.50, ... */
702
if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) {
705
char *v = buf + strlen(QEMU_VERSION_STR);
707
major = strtol(v, &endptr, 10);
708
if (major == 0 && endptr && *endptr == '.') {
710
minor = strtol(v, &endptr, 10);
719
libxl__free_all(&gc);
723
int libxl_cpumap_alloc(libxl_ctx *ctx, libxl_cpumap *cpumap)
728
max_cpus = libxl_get_max_cpus(ctx);
732
sz = (max_cpus + 7) / 8;
733
cpumap->map = calloc(sz, sizeof(*cpumap->map));
740
void libxl_cpumap_destroy(libxl_cpumap *map)
745
int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu)
747
if (cpu >= cpumap->size * 8)
749
return (cpumap->map[cpu / 8] & (1 << (cpu & 7))) ? 1 : 0;
752
void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu)
754
if (cpu >= cpumap->size * 8)
756
cpumap->map[cpu / 8] |= 1 << (cpu & 7);
759
void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu)
761
if (cpu >= cpumap->size * 8)
763
cpumap->map[cpu / 8] &= ~(1 << (cpu & 7));
766
int libxl_cpuarray_alloc(libxl_ctx *ctx, libxl_cpuarray *cpuarray)
771
max_cpus = libxl_get_max_cpus(ctx);
775
cpuarray->array = calloc(max_cpus, sizeof(*cpuarray->array));
776
if (!cpuarray->array)
778
cpuarray->entries = max_cpus;
779
for (i = 0; i < max_cpus; i++)
780
cpuarray->array[i] = LIBXL_CPUARRAY_INVALID_ENTRY;
785
void libxl_cpuarray_destroy(libxl_cpuarray *array)
790
int libxl_get_max_cpus(libxl_ctx *ctx)
792
return xc_get_max_cpus(ctx->xch);