debuggers.hg

view tools/ioemu/xenstore.c @ 10959:4c2fab8f8c34

[qemu] Use xenstore to configure ioemu block devices.
- read ioemu block device config from xenstore
- don't require the ioemu: prefix on block devices any longer
- allow change of media associated with cdrom drives
- replace cdrom= option by :cdrom suffix on regular block device config:
'file:/root/mytest.iso,hdc:cdrom,r'
- don't create default cdrom drive anymore - to create default empty
cdrom drive use: ',hdc:cdrom,r'

Signed-off-by: Christian Limpach <Christian.Limpach@xensource.com>
author chris@kneesaa.uk.xensource.com
date Thu Aug 03 18:28:29 2006 +0100 (2006-08-03)
parents
children 155385a02d0b
line source
1 /*
2 * This file is subject to the terms and conditions of the GNU General
3 * Public License. See the file "COPYING" in the main directory of
4 * this archive for more details.
5 *
6 * Copyright (C) 2006 Christian Limpach
7 * Copyright (C) 2006 XenSource Ltd.
8 *
9 */
11 #include "vl.h"
12 #include "block_int.h"
14 static struct xs_handle *xsh = NULL;
15 static char *hd_filename[MAX_DISKS];
16 static QEMUTimer *insert_timer = NULL;
18 static int pasprintf(char **buf, const char *fmt, ...)
19 {
20 va_list ap;
21 int ret = 0;
23 if (*buf)
24 free(*buf);
25 va_start(ap, fmt);
26 if (vasprintf(buf, fmt, ap) == -1) {
27 buf = NULL;
28 ret = -1;
29 }
30 va_end(ap);
31 return ret;
32 }
34 static void insert_media(void *opaque)
35 {
36 int i;
38 for (i = 0; i < MAX_DISKS; i++) {
39 if (hd_filename[i]) {
40 do_change(bs_table[i]->device_name, hd_filename[i]);
41 free(hd_filename[i]);
42 hd_filename[i] = NULL;
43 }
44 }
45 }
47 void xenstore_check_new_media_present(int timeout)
48 {
50 if (insert_timer == NULL)
51 insert_timer = qemu_new_timer(rt_clock, insert_media, NULL);
52 qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
53 }
55 void xenstore_parse_domain_config(int domid)
56 {
57 char **e = NULL;
58 char *buf = NULL, *path;
59 char *bpath = NULL, *dev = NULL, *params = NULL, *type = NULL;
60 int i;
61 unsigned int len, num, hd_index;
63 for(i = 0; i < MAX_DISKS; i++)
64 hd_filename[i] = NULL;
66 xsh = xs_daemon_open();
67 if (xsh == NULL) {
68 fprintf(logfile, "Could not contact xenstore for domain config\n");
69 return;
70 }
72 path = xs_get_domain_path(xsh, domid);
73 if (path == NULL) {
74 fprintf(logfile, "xs_get_domain_path() error\n");
75 goto out;
76 }
78 if (pasprintf(&buf, "%s/device/vbd", path) == -1)
79 goto out;
81 e = xs_directory(xsh, XBT_NULL, buf, &num);
82 if (e == NULL)
83 goto out;
85 for (i = 0; i < num; i++) {
86 /* read the backend path */
87 if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
88 continue;
89 free(bpath);
90 bpath = xs_read(xsh, XBT_NULL, buf, &len);
91 if (bpath == NULL)
92 continue;
93 /* read the name of the device */
94 if (pasprintf(&buf, "%s/dev", bpath) == -1)
95 continue;
96 free(dev);
97 dev = xs_read(xsh, XBT_NULL, buf, &len);
98 if (dev == NULL)
99 continue;
100 if (strncmp(dev, "hd", 2) || strlen(dev) != 3)
101 continue;
102 hd_index = dev[2] - 'a';
103 if (hd_index > MAX_DISKS)
104 continue;
105 /* read the type of the device */
106 if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
107 continue;
108 free(type);
109 type = xs_read(xsh, XBT_NULL, buf, &len);
110 /* read params to get the patch of the image -- read it last
111 * so that we have its path in buf when setting up the
112 * watch */
113 if (pasprintf(&buf, "%s/params", bpath) == -1)
114 continue;
115 free(params);
116 params = xs_read(xsh, XBT_NULL, buf, &len);
117 if (params == NULL)
118 continue;
119 if (params[0]) {
120 hd_filename[hd_index] = params; /* strdup() */
121 params = NULL; /* don't free params on re-use */
122 }
123 bs_table[hd_index] = bdrv_new(dev);
124 /* check if it is a cdrom */
125 if (type && !strcmp(type, "cdrom")) {
126 bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
127 xs_watch(xsh, buf, dev);
128 }
129 if (hd_filename[hd_index]) {
130 if (bdrv_open(bs_table[hd_index], hd_filename[hd_index],
131 0 /* snapshot */) < 0)
132 fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
133 hd_filename[hd_index]);
134 }
135 }
137 out:
138 free(type);
139 free(params);
140 free(dev);
141 free(bpath);
142 free(buf);
143 free(path);
144 free(e);
145 return;
146 }
148 int xenstore_fd(void)
149 {
150 if (xsh)
151 return xs_fileno(xsh);
152 return -1;
153 }
155 void xenstore_process_event(void *opaque)
156 {
157 char **vec, *image = NULL;
158 unsigned int len, num, hd_index;
160 vec = xs_read_watch(xsh, &num);
161 if (!vec)
162 return;
164 if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
165 strlen(vec[XS_WATCH_TOKEN]) != 3)
166 goto out;
167 hd_index = vec[XS_WATCH_TOKEN][2] - 'a';
168 image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
169 if (image == NULL || !strcmp(image, bs_table[hd_index]->filename))
170 goto out; /* gone or identical */
172 do_eject(0, vec[XS_WATCH_TOKEN]);
173 bs_table[hd_index]->filename[0] = 0;
174 if (hd_filename[hd_index]) {
175 free(hd_filename[hd_index]);
176 hd_filename[hd_index] = NULL;
177 }
179 if (image[0]) {
180 hd_filename[hd_index] = strdup(image);
181 xenstore_check_new_media_present(5000);
182 }
184 out:
185 free(image);
186 free(vec);
187 }