direct-io.hg

annotate tools/ioemu/xenstore.c @ 15481:538c3d8aa4b1

Revert 15471:7ac7f147241405af83e7a9d748cf7b01279734fc

Block-device specifiers in ioemu can contain colons, so skipping
always past the first colon is not a good idea. Better solutions are
in the pipeline to solve the blktap issues.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Jul 06 15:01:20 2007 +0100 (2007-07-06)
parents 7ac7f1472414
children
rev   line source
chris@10921 1 /*
chris@10921 2 * This file is subject to the terms and conditions of the GNU General
chris@10921 3 * Public License. See the file "COPYING" in the main directory of
chris@10921 4 * this archive for more details.
chris@10921 5 *
chris@10921 6 * Copyright (C) 2006 Christian Limpach
chris@10921 7 * Copyright (C) 2006 XenSource Ltd.
chris@10921 8 *
chris@10921 9 */
chris@10921 10
chris@10921 11 #include "vl.h"
chris@10921 12 #include "block_int.h"
wim@13827 13 #include <unistd.h>
Tim@14405 14 #include <sys/ipc.h>
Tim@14405 15 #include <sys/shm.h>
Tim@14405 16 #include <sys/types.h>
Tim@14405 17 #include <sys/stat.h>
Tim@14405 18 #include <fcntl.h>
chris@10921 19
chris@10921 20 static struct xs_handle *xsh = NULL;
Christian@14814 21 static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS];
chris@10921 22 static QEMUTimer *insert_timer = NULL;
chris@10921 23
wim@14177 24 #define UWAIT_MAX (30*1000000) /* thirty seconds */
wim@14177 25 #define UWAIT (100000) /* 1/10th second */
wim@14177 26
chris@10921 27 static int pasprintf(char **buf, const char *fmt, ...)
chris@10921 28 {
chris@10921 29 va_list ap;
chris@10921 30 int ret = 0;
chris@10921 31
chris@10921 32 if (*buf)
kfraser@14803 33 free(*buf);
chris@10921 34 va_start(ap, fmt);
chris@10921 35 if (vasprintf(buf, fmt, ap) == -1) {
kfraser@14803 36 buf = NULL;
kfraser@14803 37 ret = -1;
chris@10921 38 }
chris@10921 39 va_end(ap);
chris@10921 40 return ret;
chris@10921 41 }
chris@10921 42
chris@10921 43 static void insert_media(void *opaque)
chris@10921 44 {
chris@10921 45 int i;
chris@10921 46
Christian@14814 47 for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) {
kfraser@14803 48 if (media_filename[i] && bs_table[i]) {
kfraser@14803 49 do_change(bs_table[i]->device_name, media_filename[i]);
kfraser@14803 50 free(media_filename[i]);
kfraser@14803 51 media_filename[i] = NULL;
kfraser@14803 52 }
chris@10921 53 }
chris@10921 54 }
chris@10921 55
chris@10921 56 void xenstore_check_new_media_present(int timeout)
chris@10921 57 {
chris@10921 58
chris@10921 59 if (insert_timer == NULL)
kfraser@14803 60 insert_timer = qemu_new_timer(rt_clock, insert_media, NULL);
chris@10921 61 qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
chris@10921 62 }
chris@10921 63
wim@14177 64 static void waitForDevice(char *fn)
wim@13827 65 {
wim@14177 66 struct stat sbuf;
wim@14177 67 int status;
wim@14177 68 int uwait = UWAIT_MAX;
wim@13827 69
wim@14177 70 do {
wim@14177 71 status = stat(fn, &sbuf);
wim@14177 72 if (!status) break;
wim@14177 73 usleep(UWAIT);
wim@14177 74 uwait -= UWAIT;
wim@14177 75 } while (uwait > 0);
wim@13827 76
wim@14177 77 return;
wim@13827 78 }
wim@13827 79
chris@10921 80 void xenstore_parse_domain_config(int domid)
chris@10921 81 {
chris@10921 82 char **e = NULL;
chris@10921 83 char *buf = NULL, *path;
wim@13827 84 char *fpath = NULL, *bpath = NULL,
kfraser@14803 85 *dev = NULL, *params = NULL, *type = NULL;
kfraser@14803 86 int i, is_scsi;
chris@10921 87 unsigned int len, num, hd_index;
chris@10921 88
Christian@14814 89 for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
Christian@14434 90 media_filename[i] = NULL;
chris@10921 91
chris@10921 92 xsh = xs_daemon_open();
chris@10921 93 if (xsh == NULL) {
kfraser@14803 94 fprintf(logfile, "Could not contact xenstore for domain config\n");
kfraser@14803 95 return;
chris@10921 96 }
chris@10921 97
chris@10921 98 path = xs_get_domain_path(xsh, domid);
chris@10921 99 if (path == NULL) {
chris@10921 100 fprintf(logfile, "xs_get_domain_path() error\n");
chris@10921 101 goto out;
chris@10921 102 }
chris@10921 103
chris@10921 104 if (pasprintf(&buf, "%s/device/vbd", path) == -1)
kfraser@14803 105 goto out;
chris@10921 106
chris@10921 107 e = xs_directory(xsh, XBT_NULL, buf, &num);
chris@10921 108 if (e == NULL)
kfraser@14803 109 goto out;
chris@10921 110
chris@10921 111 for (i = 0; i < num; i++) {
kfraser@14803 112 /* read the backend path */
kfraser@14803 113 if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
kfraser@14803 114 continue;
kfraser@14803 115 free(bpath);
chris@10921 116 bpath = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@14803 117 if (bpath == NULL)
kfraser@14803 118 continue;
kfraser@14803 119 /* read the name of the device */
kfraser@14803 120 if (pasprintf(&buf, "%s/dev", bpath) == -1)
kfraser@14803 121 continue;
kfraser@14803 122 free(dev);
kfraser@14803 123 dev = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@14803 124 if (dev == NULL)
kfraser@14803 125 continue;
kfraser@14803 126 is_scsi = !strncmp(dev, "sd", 2);
kfraser@14803 127 if ((strncmp(dev, "hd", 2) && !is_scsi) || strlen(dev) != 3 )
kfraser@14803 128 continue;
kfraser@14803 129 hd_index = dev[2] - 'a';
kfraser@14803 130 if (hd_index >= (is_scsi ? MAX_SCSI_DISKS : MAX_DISKS))
kfraser@14803 131 continue;
kfraser@14803 132 /* read the type of the device */
kfraser@14803 133 if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
kfraser@14803 134 continue;
kfraser@14803 135 free(type);
kfraser@14803 136 type = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@14803 137 if (pasprintf(&buf, "%s/params", bpath) == -1)
kfraser@14803 138 continue;
kfraser@14803 139 free(params);
kfraser@14803 140 params = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@14803 141 if (params == NULL)
kfraser@14803 142 continue;
wim@13827 143 /*
wim@13827 144 * check if device has a phantom vbd; the phantom is hooked
wim@13827 145 * to the frontend device (for ease of cleanup), so lookup
wim@13827 146 * the frontend device, and see if there is a phantom_vbd
wim@13827 147 * if there is, we will use resolution as the filename
wim@13827 148 */
kfraser@14803 149 if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
kfraser@14803 150 continue;
kfraser@14803 151 free(fpath);
wim@13827 152 fpath = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@14803 153 if (fpath) {
kfraser@14803 154 if (pasprintf(&buf, "%s/dev", fpath) == -1)
kfraser@14803 155 continue;
kfraser@14803 156 free(params);
wim@13827 157 params = xs_read(xsh, XBT_NULL, buf , &len);
kfraser@14803 158 if (params) {
wim@14177 159 /*
wim@14177 160 * wait for device, on timeout silently fail because we will
wim@14177 161 * fail to open below
wim@14177 162 */
Christian@14434 163 waitForDevice(params);
wim@13827 164 }
wim@13827 165 }
Christian@14434 166
kfraser@14803 167 bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev);
kfraser@14803 168 /* check if it is a cdrom */
kfraser@14803 169 if (type && !strcmp(type, "cdrom")) {
kfraser@14803 170 bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
kfraser@14803 171 if (pasprintf(&buf, "%s/params", bpath) != -1)
kfraser@14803 172 xs_watch(xsh, buf, dev);
kfraser@14803 173 }
kfraser@14803 174 /* open device now if media present */
kfraser@14803 175 if (params[0]) {
kfraser@14803 176 if (bdrv_open(bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)],
kfraser@15481 177 params, 0 /* snapshot */) < 0)
chris@10921 178 fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
kfraser@15481 179 params);
kfraser@14803 180 }
chris@10921 181 }
chris@10921 182
Tim@14405 183 /* Set a watch for log-dirty requests from the migration tools */
Tim@14405 184 if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) {
Tim@14405 185 xs_watch(xsh, buf, "logdirty");
Tim@14405 186 fprintf(logfile, "Watching %s\n", buf);
Tim@14405 187 }
Tim@14405 188
Tim@14405 189
chris@10921 190 out:
chris@10921 191 free(type);
chris@10921 192 free(params);
chris@10921 193 free(dev);
chris@10921 194 free(bpath);
chris@10921 195 free(buf);
chris@10921 196 free(path);
chris@10921 197 free(e);
chris@10921 198 return;
chris@10921 199 }
chris@10921 200
chris@10921 201 int xenstore_fd(void)
chris@10921 202 {
chris@10921 203 if (xsh)
kfraser@14803 204 return xs_fileno(xsh);
chris@10921 205 return -1;
chris@10921 206 }
chris@10921 207
Tim@14405 208 unsigned long *logdirty_bitmap = NULL;
Tim@14405 209 unsigned long logdirty_bitmap_size;
Tim@14405 210 extern int vga_ram_size, bios_size;
Tim@14405 211
Tim@14405 212 void xenstore_process_logdirty_event(void)
Tim@14405 213 {
Tim@14405 214 char *act;
Tim@14405 215 static char *active_path = NULL;
Tim@14405 216 static char *next_active_path = NULL;
Tim@14405 217 static char *seg = NULL;
Tim@14405 218 unsigned int len;
Tim@14405 219 int i;
Tim@14405 220
Tim@14405 221 fprintf(logfile, "Triggered log-dirty buffer switch\n");
Tim@14405 222
Tim@14405 223 if (!seg) {
Tim@14412 224 char *path, *p, *key_ascii, key_terminated[17] = {0,};
Tim@14405 225 key_t key;
Tim@14405 226 int shmid;
Tim@14405 227
Tim@14405 228 /* Find and map the shared memory segment for log-dirty bitmaps */
Tim@14405 229 if (!(path = xs_get_domain_path(xsh, domid))) {
Tim@14405 230 fprintf(logfile, "Log-dirty: can't get domain path in store\n");
Tim@14405 231 exit(1);
Tim@14405 232 }
Tim@14405 233 if (!(path = realloc(path, strlen(path)
Tim@14405 234 + strlen("/logdirty/next-active") + 1))) {
Tim@14405 235 fprintf(logfile, "Log-dirty: out of memory\n");
Tim@14405 236 exit(1);
Tim@14405 237 }
Tim@14405 238 strcat(path, "/logdirty/");
Tim@14405 239 p = path + strlen(path);
Tim@14405 240 strcpy(p, "key");
Tim@14405 241
Tim@14405 242 key_ascii = xs_read(xsh, XBT_NULL, path, &len);
Tim@14405 243 if (!key_ascii) {
Tim@14405 244 /* No key yet: wait for the next watch */
Tim@14405 245 free(path);
Tim@14405 246 return;
Tim@14405 247 }
Tim@14405 248 strncpy(key_terminated, key_ascii, 16);
Tim@14405 249 free(key_ascii);
Tim@14405 250 key = (key_t) strtoull(key_terminated, NULL, 16);
Tim@14405 251
Tim@14405 252 /* Figure out how bit the log-dirty bitmaps are */
Tim@14751 253 logdirty_bitmap_size = xc_memory_op(xc_handle,
Tim@14751 254 XENMEM_maximum_gpfn, &domid) + 1;
Tim@14405 255 logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
Tim@14405 256 / HOST_LONG_BITS); /* longs */
Tim@14405 257 logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
Tim@14405 258
Tim@14405 259 /* Map the shared-memory segment */
Tim@14405 260 if ((shmid = shmget(key,
Tim@14405 261 2 * logdirty_bitmap_size,
Tim@14405 262 S_IRUSR|S_IWUSR)) == -1
Tim@14405 263 || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
Tim@14405 264 fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
Tim@14405 265 (unsigned long long) key, strerror(errno));
Tim@14405 266 exit(1);
Tim@14405 267 }
Tim@14405 268
Tim@14405 269 fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
Tim@14405 270
Tim@14405 271 /* Double-check that the bitmaps are the size we expect */
Tim@14405 272 if (logdirty_bitmap_size != *(uint32_t *)seg) {
kfraser@14718 273 fprintf(logfile, "Log-dirty: got %u, calc %lu\n",
Tim@14405 274 *(uint32_t *)seg, logdirty_bitmap_size);
Tim@14405 275 return;
Tim@14405 276 }
Tim@14405 277
Tim@14405 278 /* Remember the paths for the next-active and active entries */
Tim@14405 279 strcpy(p, "active");
Tim@14405 280 if (!(active_path = strdup(path))) {
Tim@14405 281 fprintf(logfile, "Log-dirty: out of memory\n");
Tim@14405 282 exit(1);
Tim@14405 283 }
Tim@14405 284 strcpy(p, "next-active");
Tim@14405 285 if (!(next_active_path = strdup(path))) {
Tim@14405 286 fprintf(logfile, "Log-dirty: out of memory\n");
Tim@14405 287 exit(1);
Tim@14405 288 }
Tim@14405 289 free(path);
Tim@14405 290 }
Tim@14405 291
Tim@14405 292 /* Read the required active buffer from the store */
Tim@14405 293 act = xs_read(xsh, XBT_NULL, next_active_path, &len);
Tim@14405 294 if (!act) {
Tim@14405 295 fprintf(logfile, "Log-dirty: can't read next-active\n");
Tim@14405 296 exit(1);
Tim@14405 297 }
Tim@14405 298
Tim@14405 299 /* Switch buffers */
Tim@14405 300 i = act[0] - '0';
Tim@14405 301 if (i != 0 && i != 1) {
Tim@14405 302 fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
Tim@14405 303 exit(1);
Tim@14405 304 }
kfraser@14718 305 logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);
Tim@14405 306
Tim@14405 307 /* Ack that we've switched */
Tim@14405 308 xs_write(xsh, XBT_NULL, active_path, act, len);
Tim@14405 309 free(act);
Tim@14405 310 }
Tim@14405 311
Tim@14405 312
Tim@14405 313
chris@10921 314 void xenstore_process_event(void *opaque)
chris@10921 315 {
chris@10921 316 char **vec, *image = NULL;
chris@10921 317 unsigned int len, num, hd_index;
chris@10921 318
chris@10921 319 vec = xs_read_watch(xsh, &num);
chris@10921 320 if (!vec)
kfraser@14803 321 return;
chris@10921 322
Tim@14405 323 if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
Tim@14405 324 xenstore_process_logdirty_event();
Tim@14405 325 goto out;
Tim@14405 326 }
Tim@14405 327
chris@10921 328 if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
kfraser@14803 329 strlen(vec[XS_WATCH_TOKEN]) != 3)
kfraser@14803 330 goto out;
chris@10921 331 hd_index = vec[XS_WATCH_TOKEN][2] - 'a';
chris@10921 332 image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
chris@10921 333 if (image == NULL || !strcmp(image, bs_table[hd_index]->filename))
kfraser@14803 334 goto out; /* gone or identical */
chris@10921 335
chris@10921 336 do_eject(0, vec[XS_WATCH_TOKEN]);
chris@10921 337 bs_table[hd_index]->filename[0] = 0;
Christian@14434 338 if (media_filename[hd_index]) {
kfraser@14803 339 free(media_filename[hd_index]);
kfraser@14803 340 media_filename[hd_index] = NULL;
chris@10921 341 }
chris@10921 342
chris@10921 343 if (image[0]) {
kfraser@14803 344 media_filename[hd_index] = strdup(image);
kfraser@14803 345 xenstore_check_new_media_present(5000);
chris@10921 346 }
chris@10921 347
chris@10921 348 out:
chris@10921 349 free(image);
chris@10921 350 free(vec);
chris@10921 351 }
chris@10923 352
chris@10923 353 void xenstore_write_vncport(int display)
chris@10923 354 {
chris@10923 355 char *buf = NULL, *path;
chris@10923 356 char *portstr = NULL;
chris@10923 357
chris@10923 358 if (xsh == NULL)
kfraser@14803 359 return;
chris@10923 360
chris@10923 361 path = xs_get_domain_path(xsh, domid);
chris@10923 362 if (path == NULL) {
chris@10923 363 fprintf(logfile, "xs_get_domain_path() error\n");
chris@10923 364 goto out;
chris@10923 365 }
chris@10923 366
chris@10923 367 if (pasprintf(&buf, "%s/console/vnc-port", path) == -1)
kfraser@14803 368 goto out;
chris@10923 369
kfraser@15229 370 if (pasprintf(&portstr, "%d", display) == -1)
kfraser@14803 371 goto out;
chris@10923 372
chris@10923 373 if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0)
chris@10923 374 fprintf(logfile, "xs_write() vncport failed\n");
chris@10923 375
chris@10923 376 out:
chris@10923 377 free(portstr);
chris@10923 378 free(buf);
chris@10923 379 }
kfraser@11840 380
kfraser@11840 381 int xenstore_read_vncpasswd(int domid)
kfraser@11840 382 {
kfraser@11840 383 extern char vncpasswd[64];
kfraser@11840 384 char *buf = NULL, *path, *uuid = NULL, *passwd = NULL;
kfraser@11840 385 unsigned int i, len, rc = 0;
kfraser@11840 386
kfraser@11840 387 if (xsh == NULL) {
kfraser@14803 388 return -1;
kfraser@11840 389 }
kfraser@11840 390
kfraser@11840 391 path = xs_get_domain_path(xsh, domid);
kfraser@11840 392 if (path == NULL) {
kfraser@14803 393 fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid);
kfraser@14803 394 return -1;
kfraser@11840 395 }
kfraser@11840 396
kfraser@11840 397 pasprintf(&buf, "%s/vm", path);
kfraser@11840 398 uuid = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@11840 399 if (uuid == NULL) {
kfraser@14803 400 fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf);
kfraser@14803 401 free(path);
kfraser@14803 402 return -1;
kfraser@11840 403 }
kfraser@11840 404
kfraser@11840 405 pasprintf(&buf, "%s/vncpasswd", uuid);
kfraser@11840 406 passwd = xs_read(xsh, XBT_NULL, buf, &len);
kfraser@11840 407 if (passwd == NULL) {
kfraser@14803 408 fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf);
kfraser@14803 409 free(uuid);
kfraser@14803 410 free(path);
kfraser@14803 411 return rc;
kfraser@11840 412 }
kfraser@11840 413
kfraser@11840 414 for (i=0; i<len && i<63; i++) {
kfraser@14803 415 vncpasswd[i] = passwd[i];
kfraser@14803 416 passwd[i] = '\0';
kfraser@11840 417 }
kfraser@11840 418 vncpasswd[len] = '\0';
kfraser@11840 419 pasprintf(&buf, "%s/vncpasswd", uuid);
kfraser@11840 420 if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) {
kfraser@14803 421 fprintf(logfile, "xs_write() vncpasswd failed.\n");
kfraser@14803 422 rc = -1;
kfraser@11840 423 }
kfraser@11840 424
kfraser@11840 425 free(passwd);
kfraser@11840 426 free(uuid);
kfraser@11840 427 free(path);
kfraser@11840 428
kfraser@11840 429 return rc;
kfraser@11840 430 }
kaf24@12022 431
kaf24@12022 432
kaf24@12022 433 /*
kaf24@12022 434 * get all device instances of a certain type
kaf24@12022 435 */
kaf24@12022 436 char **xenstore_domain_get_devices(struct xs_handle *handle,
kaf24@12022 437 const char *devtype, unsigned int *num)
kaf24@12022 438 {
kaf24@12022 439 char *path;
kaf24@12022 440 char *buf = NULL;
kaf24@12022 441 char **e = NULL;
kaf24@12022 442
kaf24@12022 443 path = xs_get_domain_path(handle, domid);
kaf24@12022 444 if (path == NULL)
kaf24@12022 445 goto out;
kaf24@12022 446
kaf24@12022 447 if (pasprintf(&buf, "%s/device/%s", path,devtype) == -1)
kfraser@14803 448 goto out;
kaf24@12022 449
kaf24@12022 450 e = xs_directory(handle, XBT_NULL, buf, num);
kaf24@12022 451
kaf24@12022 452 out:
kaf24@12022 453 free(path);
kaf24@12022 454 free(buf);
kaf24@12022 455 return e;
kaf24@12022 456 }
kaf24@12022 457
kaf24@12022 458 /*
kaf24@12022 459 * Check whether a domain has devices of the given type
kaf24@12022 460 */
kaf24@12022 461 int xenstore_domain_has_devtype(struct xs_handle *handle, const char *devtype)
kaf24@12022 462 {
kaf24@12022 463 int rc = 0;
kaf24@12022 464 unsigned int num;
kaf24@12022 465 char **e = xenstore_domain_get_devices(handle, devtype, &num);
kaf24@12022 466 if (e)
kaf24@12022 467 rc = 1;
kaf24@12022 468 free(e);
kaf24@12022 469 return rc;
kaf24@12022 470 }
kaf24@12022 471
kaf24@12022 472 /*
kaf24@12022 473 * Function that creates a path to a variable of an instance of a
kaf24@12022 474 * certain device
kaf24@12022 475 */
kaf24@12022 476 static char *get_device_variable_path(const char *devtype, const char *inst,
kaf24@12022 477 const char *var)
kaf24@12022 478 {
kaf24@12022 479 char *buf = NULL;
kaf24@12022 480 if (pasprintf(&buf, "/local/domain/0/backend/%s/%d/%s/%s",
kaf24@12022 481 devtype,
kaf24@12022 482 domid,
kaf24@12022 483 inst,
kaf24@12022 484 var) == -1) {
kaf24@12022 485 free(buf);
kaf24@12022 486 buf = NULL;
kaf24@12022 487 }
kaf24@12022 488 return buf;
kaf24@12022 489 }
kaf24@12022 490
kaf24@12022 491 char *xenstore_backend_read_variable(struct xs_handle *handle,
kaf24@12022 492 const char *devtype, const char *inst,
kaf24@12022 493 const char *var)
kaf24@12022 494 {
kaf24@12022 495 char *value = NULL;
kaf24@12022 496 char *buf = NULL;
kaf24@12022 497 unsigned int len;
kaf24@12022 498
kaf24@12022 499 buf = get_device_variable_path(devtype, inst, var);
kaf24@12022 500 if (NULL == buf)
kfraser@14803 501 goto out;
kaf24@12022 502
kaf24@12022 503 value = xs_read(handle, XBT_NULL, buf, &len);
kaf24@12022 504
kaf24@12022 505 free(buf);
kaf24@12022 506
kfraser@14803 507 out:
kaf24@12022 508 return value;
kaf24@12022 509 }
kaf24@12022 510
kaf24@12022 511 /*
kaf24@12022 512 Read the hotplug status variable from the backend given the type
kaf24@12022 513 of device and its instance.
kaf24@12022 514 */
kaf24@12022 515 char *xenstore_read_hotplug_status(struct xs_handle *handle,
kaf24@12022 516 const char *devtype, const char *inst)
kaf24@12022 517 {
kaf24@12022 518 return xenstore_backend_read_variable(handle, devtype, inst,
kaf24@12022 519 "hotplug-status");
kaf24@12022 520 }
kaf24@12022 521
kaf24@12022 522 /*
kaf24@12022 523 Subscribe to the hotplug status of a device given the type of device and
kaf24@12022 524 its instance.
kaf24@12022 525 In case an error occurrs, a negative number is returned.
kaf24@12022 526 */
kaf24@12022 527 int xenstore_subscribe_to_hotplug_status(struct xs_handle *handle,
kaf24@12022 528 const char *devtype,
kaf24@12022 529 const char *inst,
kaf24@12022 530 const char *token)
kaf24@12022 531 {
kaf24@12022 532 int rc = 0;
kaf24@12022 533 char *path = get_device_variable_path(devtype, inst, "hotplug-status");
kaf24@12022 534
kaf24@12022 535 if (path == NULL)
kaf24@12022 536 return -1;
kaf24@12022 537
kaf24@12022 538 if (0 == xs_watch(handle, path, token))
kaf24@12022 539 rc = -2;
kaf24@12022 540
kaf24@12022 541 free(path);
kaf24@12022 542
kaf24@12022 543 return rc;
kaf24@12022 544 }
kaf24@12022 545
kaf24@12022 546 /*
kaf24@12022 547 * Unsubscribe from a subscription to the status of a hotplug variable of
kaf24@12022 548 * a device.
kaf24@12022 549 */
kaf24@12022 550 int xenstore_unsubscribe_from_hotplug_status(struct xs_handle *handle,
kaf24@12022 551 const char *devtype,
kaf24@12022 552 const char *inst,
kaf24@12022 553 const char *token)
kaf24@12022 554 {
kaf24@12022 555 int rc = 0;
kaf24@12022 556 char *path;
kaf24@12022 557 path = get_device_variable_path(devtype, inst, "hotplug-status");
kaf24@12022 558 if (path == NULL)
kaf24@12022 559 return -1;
kaf24@12022 560
kaf24@12022 561 if (0 == xs_unwatch(handle, path, token))
kaf24@12022 562 rc = -2;
kaf24@12022 563
kaf24@12022 564 free(path);
kaf24@12022 565
kaf24@12022 566 return rc;
kaf24@12022 567 }
Christian@14703 568
Christian@14703 569 char *xenstore_vm_read(int domid, char *key, int *len)
Christian@14703 570 {
Christian@14703 571 char *buf = NULL, *path = NULL, *value = NULL;
Christian@14703 572
Christian@14703 573 if (xsh == NULL)
kfraser@14803 574 goto out;
Christian@14703 575
Christian@14703 576 path = xs_get_domain_path(xsh, domid);
Christian@14703 577 if (path == NULL) {
kfraser@14803 578 fprintf(logfile, "xs_get_domain_path(%d): error\n", domid);
kfraser@14803 579 goto out;
Christian@14703 580 }
Christian@14703 581
Christian@14703 582 pasprintf(&buf, "%s/vm", path);
Christian@14703 583 free(path);
Christian@14703 584 path = xs_read(xsh, XBT_NULL, buf, NULL);
Christian@14703 585 if (path == NULL) {
kfraser@14803 586 fprintf(logfile, "xs_read(%s): read error\n", buf);
kfraser@14803 587 goto out;
Christian@14703 588 }
Christian@14703 589
Christian@14703 590 pasprintf(&buf, "%s/%s", path, key);
Christian@14703 591 value = xs_read(xsh, XBT_NULL, buf, len);
Christian@14703 592 if (value == NULL) {
kfraser@14803 593 fprintf(logfile, "xs_read(%s): read error\n", buf);
kfraser@14803 594 goto out;
Christian@14703 595 }
Christian@14703 596
Christian@14703 597 out:
Christian@14703 598 free(path);
Christian@14703 599 free(buf);
Christian@14703 600 return value;
Christian@14703 601 }
Christian@14703 602
Christian@14703 603 int xenstore_vm_write(int domid, char *key, char *value)
Christian@14703 604 {
Christian@14703 605 char *buf = NULL, *path = NULL;
Christian@14703 606 int rc = -1;
Christian@14703 607
Christian@14703 608 if (xsh == NULL)
kfraser@14803 609 goto out;
Christian@14703 610
Christian@14703 611 path = xs_get_domain_path(xsh, domid);
Christian@14703 612 if (path == NULL) {
kfraser@14803 613 fprintf(logfile, "xs_get_domain_path: error\n");
kfraser@14803 614 goto out;
Christian@14703 615 }
Christian@14703 616
Christian@14703 617 pasprintf(&buf, "%s/vm", path);
Christian@14703 618 free(path);
Christian@14703 619 path = xs_read(xsh, XBT_NULL, buf, NULL);
Christian@14703 620 if (path == NULL) {
kfraser@14803 621 fprintf(logfile, "xs_read(%s): read error\n", buf);
kfraser@14803 622 goto out;
Christian@14703 623 }
Christian@14703 624
Christian@14703 625 pasprintf(&buf, "%s/%s", path, key);
Christian@14703 626 rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value));
Christian@14703 627 if (rc) {
kfraser@14803 628 fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key);
kfraser@14803 629 goto out;
Christian@14703 630 }
Christian@14703 631
Christian@14703 632 out:
Christian@14703 633 free(path);
Christian@14703 634 free(buf);
Christian@14703 635 return rc;
Christian@14703 636 }