]> git.proxmox.com Git - qemu.git/blob - hw/xen_backend.c
xen: Replace some tab-indents with spaces (clean-up).
[qemu.git] / hw / xen_backend.c
1 /*
2 * xen backend driver infrastructure
3 * (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; under version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * TODO: add some xenbus / xenstore concepts overview here.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <inttypes.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/mman.h>
32 #include <sys/signal.h>
33
34 #include <xs.h>
35 #include <xenctrl.h>
36 #include <xen/grant_table.h>
37
38 #include "hw.h"
39 #include "qemu-char.h"
40 #include "qemu-log.h"
41 #include "xen_backend.h"
42
43 /* ------------------------------------------------------------- */
44
45 /* public */
46 int xen_xc;
47 struct xs_handle *xenstore = NULL;
48 const char *xen_protocol;
49
50 /* private */
51 static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
52 static int debug = 0;
53
54 /* ------------------------------------------------------------- */
55
56 int xenstore_write_str(const char *base, const char *node, const char *val)
57 {
58 char abspath[XEN_BUFSIZE];
59
60 snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
61 if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
62 return -1;
63 }
64 return 0;
65 }
66
67 char *xenstore_read_str(const char *base, const char *node)
68 {
69 char abspath[XEN_BUFSIZE];
70 unsigned int len;
71 char *str, *ret = NULL;
72
73 snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
74 str = xs_read(xenstore, 0, abspath, &len);
75 if (str != NULL) {
76 /* move to qemu-allocated memory to make sure
77 * callers can savely qemu_free() stuff. */
78 ret = qemu_strdup(str);
79 free(str);
80 }
81 return ret;
82 }
83
84 int xenstore_write_int(const char *base, const char *node, int ival)
85 {
86 char val[32];
87
88 snprintf(val, sizeof(val), "%d", ival);
89 return xenstore_write_str(base, node, val);
90 }
91
92 int xenstore_read_int(const char *base, const char *node, int *ival)
93 {
94 char *val;
95 int rc = -1;
96
97 val = xenstore_read_str(base, node);
98 if (val && 1 == sscanf(val, "%d", ival)) {
99 rc = 0;
100 }
101 qemu_free(val);
102 return rc;
103 }
104
105 int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
106 {
107 return xenstore_write_str(xendev->be, node, val);
108 }
109
110 int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
111 {
112 return xenstore_write_int(xendev->be, node, ival);
113 }
114
115 char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
116 {
117 return xenstore_read_str(xendev->be, node);
118 }
119
120 int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival)
121 {
122 return xenstore_read_int(xendev->be, node, ival);
123 }
124
125 char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node)
126 {
127 return xenstore_read_str(xendev->fe, node);
128 }
129
130 int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
131 {
132 return xenstore_read_int(xendev->fe, node, ival);
133 }
134
135 /* ------------------------------------------------------------- */
136
137 const char *xenbus_strstate(enum xenbus_state state)
138 {
139 static const char *const name[] = {
140 [ XenbusStateUnknown ] = "Unknown",
141 [ XenbusStateInitialising ] = "Initialising",
142 [ XenbusStateInitWait ] = "InitWait",
143 [ XenbusStateInitialised ] = "Initialised",
144 [ XenbusStateConnected ] = "Connected",
145 [ XenbusStateClosing ] = "Closing",
146 [ XenbusStateClosed ] = "Closed",
147 };
148 return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
149 }
150
151 int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
152 {
153 int rc;
154
155 rc = xenstore_write_be_int(xendev, "state", state);
156 if (rc < 0) {
157 return rc;
158 }
159 xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
160 xenbus_strstate(xendev->be_state), xenbus_strstate(state));
161 xendev->be_state = state;
162 return 0;
163 }
164
165 /* ------------------------------------------------------------- */
166
167 struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
168 {
169 struct XenDevice *xendev;
170
171 QTAILQ_FOREACH(xendev, &xendevs, next) {
172 if (xendev->dom != dom) {
173 continue;
174 }
175 if (xendev->dev != dev) {
176 continue;
177 }
178 if (strcmp(xendev->type, type) != 0) {
179 continue;
180 }
181 return xendev;
182 }
183 return NULL;
184 }
185
186 /*
187 * get xen backend device, allocate a new one if it doesn't exist.
188 */
189 static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
190 struct XenDevOps *ops)
191 {
192 struct XenDevice *xendev;
193 char *dom0;
194
195 xendev = xen_be_find_xendev(type, dom, dev);
196 if (xendev) {
197 return xendev;
198 }
199
200 /* init new xendev */
201 xendev = qemu_mallocz(ops->size);
202 xendev->type = type;
203 xendev->dom = dom;
204 xendev->dev = dev;
205 xendev->ops = ops;
206
207 dom0 = xs_get_domain_path(xenstore, 0);
208 snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
209 dom0, xendev->type, xendev->dom, xendev->dev);
210 snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
211 xendev->type, xendev->dev);
212 free(dom0);
213
214 xendev->debug = debug;
215 xendev->local_port = -1;
216
217 xendev->evtchndev = xc_evtchn_open();
218 if (xendev->evtchndev < 0) {
219 xen_be_printf(NULL, 0, "can't open evtchn device\n");
220 qemu_free(xendev);
221 return NULL;
222 }
223 fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
224
225 if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
226 xendev->gnttabdev = xc_gnttab_open();
227 if (xendev->gnttabdev < 0) {
228 xen_be_printf(NULL, 0, "can't open gnttab device\n");
229 xc_evtchn_close(xendev->evtchndev);
230 qemu_free(xendev);
231 return NULL;
232 }
233 } else {
234 xendev->gnttabdev = -1;
235 }
236
237 QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
238
239 if (xendev->ops->alloc) {
240 xendev->ops->alloc(xendev);
241 }
242
243 return xendev;
244 }
245
246 /*
247 * release xen backend device.
248 */
249 static struct XenDevice *xen_be_del_xendev(int dom, int dev)
250 {
251 struct XenDevice *xendev, *xnext;
252
253 /*
254 * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but
255 * we save the next pointer in xnext because we might free xendev.
256 */
257 xnext = xendevs.tqh_first;
258 while (xnext) {
259 xendev = xnext;
260 xnext = xendev->next.tqe_next;
261
262 if (xendev->dom != dom) {
263 continue;
264 }
265 if (xendev->dev != dev && dev != -1) {
266 continue;
267 }
268
269 if (xendev->ops->free) {
270 xendev->ops->free(xendev);
271 }
272
273 if (xendev->fe) {
274 char token[XEN_BUFSIZE];
275 snprintf(token, sizeof(token), "fe:%p", xendev);
276 xs_unwatch(xenstore, xendev->fe, token);
277 qemu_free(xendev->fe);
278 }
279
280 if (xendev->evtchndev >= 0) {
281 xc_evtchn_close(xendev->evtchndev);
282 }
283 if (xendev->gnttabdev >= 0) {
284 xc_gnttab_close(xendev->gnttabdev);
285 }
286
287 QTAILQ_REMOVE(&xendevs, xendev, next);
288 qemu_free(xendev);
289 }
290 return NULL;
291 }
292
293 /*
294 * Sync internal data structures on xenstore updates.
295 * Node specifies the changed field. node = NULL means
296 * update all fields (used for initialization).
297 */
298 static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
299 {
300 if (node == NULL || strcmp(node, "online") == 0) {
301 if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) {
302 xendev->online = 0;
303 }
304 }
305
306 if (node) {
307 xen_be_printf(xendev, 2, "backend update: %s\n", node);
308 if (xendev->ops->backend_changed) {
309 xendev->ops->backend_changed(xendev, node);
310 }
311 }
312 }
313
314 static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
315 {
316 int fe_state;
317
318 if (node == NULL || strcmp(node, "state") == 0) {
319 if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) {
320 fe_state = XenbusStateUnknown;
321 }
322 if (xendev->fe_state != fe_state) {
323 xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
324 xenbus_strstate(xendev->fe_state),
325 xenbus_strstate(fe_state));
326 }
327 xendev->fe_state = fe_state;
328 }
329 if (node == NULL || strcmp(node, "protocol") == 0) {
330 qemu_free(xendev->protocol);
331 xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
332 if (xendev->protocol) {
333 xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
334 }
335 }
336
337 if (node) {
338 xen_be_printf(xendev, 2, "frontend update: %s\n", node);
339 if (xendev->ops->frontend_changed) {
340 xendev->ops->frontend_changed(xendev, node);
341 }
342 }
343 }
344
345 /* ------------------------------------------------------------- */
346 /* Check for possible state transitions and perform them. */
347
348 /*
349 * Initial xendev setup. Read frontend path, register watch for it.
350 * Should succeed once xend finished setting up the backend device.
351 *
352 * Also sets initial state (-> Initializing) when done. Which
353 * only affects the xendev->be_state variable as xenbus should
354 * already be put into that state by xend.
355 */
356 static int xen_be_try_setup(struct XenDevice *xendev)
357 {
358 char token[XEN_BUFSIZE];
359 int be_state;
360
361 if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
362 xen_be_printf(xendev, 0, "reading backend state failed\n");
363 return -1;
364 }
365
366 if (be_state != XenbusStateInitialising) {
367 xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
368 xenbus_strstate(be_state));
369 return -1;
370 }
371
372 xendev->fe = xenstore_read_be_str(xendev, "frontend");
373 if (xendev->fe == NULL) {
374 xen_be_printf(xendev, 0, "reading frontend path failed\n");
375 return -1;
376 }
377
378 /* setup frontend watch */
379 snprintf(token, sizeof(token), "fe:%p", xendev);
380 if (!xs_watch(xenstore, xendev->fe, token)) {
381 xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
382 xendev->fe);
383 return -1;
384 }
385 xen_be_set_state(xendev, XenbusStateInitialising);
386
387 xen_be_backend_changed(xendev, NULL);
388 xen_be_frontend_changed(xendev, NULL);
389 return 0;
390 }
391
392 /*
393 * Try initialize xendev. Prepare everything the backend can do
394 * without synchronizing with the frontend. Fakes hotplug-status. No
395 * hotplug involved here because this is about userspace drivers, thus
396 * there are kernel backend devices which could invoke hotplug.
397 *
398 * Goes to InitWait on success.
399 */
400 static int xen_be_try_init(struct XenDevice *xendev)
401 {
402 int rc = 0;
403
404 if (!xendev->online) {
405 xen_be_printf(xendev, 1, "not online\n");
406 return -1;
407 }
408
409 if (xendev->ops->init) {
410 rc = xendev->ops->init(xendev);
411 }
412 if (rc != 0) {
413 xen_be_printf(xendev, 1, "init() failed\n");
414 return rc;
415 }
416
417 xenstore_write_be_str(xendev, "hotplug-status", "connected");
418 xen_be_set_state(xendev, XenbusStateInitWait);
419 return 0;
420 }
421
422 /*
423 * Try to connect xendev. Depends on the frontend being ready
424 * for it (shared ring and evtchn info in xenstore, state being
425 * Initialised or Connected).
426 *
427 * Goes to Connected on success.
428 */
429 static int xen_be_try_connect(struct XenDevice *xendev)
430 {
431 int rc = 0;
432
433 if (xendev->fe_state != XenbusStateInitialised &&
434 xendev->fe_state != XenbusStateConnected) {
435 if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
436 xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
437 } else {
438 xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
439 return -1;
440 }
441 }
442
443 if (xendev->ops->connect) {
444 rc = xendev->ops->connect(xendev);
445 }
446 if (rc != 0) {
447 xen_be_printf(xendev, 0, "connect() failed\n");
448 return rc;
449 }
450
451 xen_be_set_state(xendev, XenbusStateConnected);
452 return 0;
453 }
454
455 /*
456 * Teardown connection.
457 *
458 * Goes to Closed when done.
459 */
460 static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
461 {
462 if (xendev->be_state != XenbusStateClosing &&
463 xendev->be_state != XenbusStateClosed &&
464 xendev->ops->disconnect) {
465 xendev->ops->disconnect(xendev);
466 }
467 if (xendev->be_state != state) {
468 xen_be_set_state(xendev, state);
469 }
470 }
471
472 /*
473 * Try to reset xendev, for reconnection by another frontend instance.
474 */
475 static int xen_be_try_reset(struct XenDevice *xendev)
476 {
477 if (xendev->fe_state != XenbusStateInitialising) {
478 return -1;
479 }
480
481 xen_be_printf(xendev, 1, "device reset (for re-connect)\n");
482 xen_be_set_state(xendev, XenbusStateInitialising);
483 return 0;
484 }
485
486 /*
487 * state change dispatcher function
488 */
489 void xen_be_check_state(struct XenDevice *xendev)
490 {
491 int rc = 0;
492
493 /* frontend may request shutdown from almost anywhere */
494 if (xendev->fe_state == XenbusStateClosing ||
495 xendev->fe_state == XenbusStateClosed) {
496 xen_be_disconnect(xendev, xendev->fe_state);
497 return;
498 }
499
500 /* check for possible backend state transitions */
501 for (;;) {
502 switch (xendev->be_state) {
503 case XenbusStateUnknown:
504 rc = xen_be_try_setup(xendev);
505 break;
506 case XenbusStateInitialising:
507 rc = xen_be_try_init(xendev);
508 break;
509 case XenbusStateInitWait:
510 rc = xen_be_try_connect(xendev);
511 break;
512 case XenbusStateClosed:
513 rc = xen_be_try_reset(xendev);
514 break;
515 default:
516 rc = -1;
517 }
518 if (rc != 0) {
519 break;
520 }
521 }
522 }
523
524 /* ------------------------------------------------------------- */
525
526 static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
527 {
528 struct XenDevice *xendev;
529 char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
530 char **dev = NULL, *dom0;
531 unsigned int cdev, j;
532
533 /* setup watch */
534 dom0 = xs_get_domain_path(xenstore, 0);
535 snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
536 snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
537 free(dom0);
538 if (!xs_watch(xenstore, path, token)) {
539 xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
540 return -1;
541 }
542
543 /* look for backends */
544 dev = xs_directory(xenstore, 0, path, &cdev);
545 if (!dev) {
546 return 0;
547 }
548 for (j = 0; j < cdev; j++) {
549 xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
550 if (xendev == NULL) {
551 continue;
552 }
553 xen_be_check_state(xendev);
554 }
555 free(dev);
556 return 0;
557 }
558
559 static void xenstore_update_be(char *watch, char *type, int dom,
560 struct XenDevOps *ops)
561 {
562 struct XenDevice *xendev;
563 char path[XEN_BUFSIZE], *dom0;
564 unsigned int len, dev;
565
566 dom0 = xs_get_domain_path(xenstore, 0);
567 len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
568 free(dom0);
569 if (strncmp(path, watch, len) != 0) {
570 return;
571 }
572 if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) {
573 strcpy(path, "");
574 if (sscanf(watch+len, "/%u", &dev) != 1) {
575 dev = -1;
576 }
577 }
578 if (dev == -1) {
579 return;
580 }
581
582 if (0) {
583 /* FIXME: detect devices being deleted from xenstore ... */
584 xen_be_del_xendev(dom, dev);
585 }
586
587 xendev = xen_be_get_xendev(type, dom, dev, ops);
588 if (xendev != NULL) {
589 xen_be_backend_changed(xendev, path);
590 xen_be_check_state(xendev);
591 }
592 }
593
594 static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
595 {
596 char *node;
597 unsigned int len;
598
599 len = strlen(xendev->fe);
600 if (strncmp(xendev->fe, watch, len) != 0) {
601 return;
602 }
603 if (watch[len] != '/') {
604 return;
605 }
606 node = watch + len + 1;
607
608 xen_be_frontend_changed(xendev, node);
609 xen_be_check_state(xendev);
610 }
611
612 static void xenstore_update(void *unused)
613 {
614 char **vec = NULL;
615 intptr_t type, ops, ptr;
616 unsigned int dom, count;
617
618 vec = xs_read_watch(xenstore, &count);
619 if (vec == NULL) {
620 goto cleanup;
621 }
622
623 if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
624 &type, &dom, &ops) == 3) {
625 xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
626 }
627 if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
628 xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
629 }
630
631 cleanup:
632 free(vec);
633 }
634
635 static void xen_be_evtchn_event(void *opaque)
636 {
637 struct XenDevice *xendev = opaque;
638 evtchn_port_t port;
639
640 port = xc_evtchn_pending(xendev->evtchndev);
641 if (port != xendev->local_port) {
642 xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
643 port, xendev->local_port);
644 return;
645 }
646 xc_evtchn_unmask(xendev->evtchndev, port);
647
648 if (xendev->ops->event) {
649 xendev->ops->event(xendev);
650 }
651 }
652
653 /* -------------------------------------------------------------------- */
654
655 int xen_be_init(void)
656 {
657 xenstore = xs_daemon_open();
658 if (!xenstore) {
659 xen_be_printf(NULL, 0, "can't connect to xenstored\n");
660 return -1;
661 }
662
663 if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) {
664 goto err;
665 }
666
667 xen_xc = xc_interface_open();
668 if (xen_xc == -1) {
669 xen_be_printf(NULL, 0, "can't open xen interface\n");
670 goto err;
671 }
672 return 0;
673
674 err:
675 qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
676 xs_daemon_close(xenstore);
677 xenstore = NULL;
678
679 return -1;
680 }
681
682 int xen_be_register(const char *type, struct XenDevOps *ops)
683 {
684 return xenstore_scan(type, xen_domid, ops);
685 }
686
687 int xen_be_bind_evtchn(struct XenDevice *xendev)
688 {
689 if (xendev->local_port != -1) {
690 return 0;
691 }
692 xendev->local_port = xc_evtchn_bind_interdomain
693 (xendev->evtchndev, xendev->dom, xendev->remote_port);
694 if (xendev->local_port == -1) {
695 xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n");
696 return -1;
697 }
698 xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
699 qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev),
700 xen_be_evtchn_event, NULL, xendev);
701 return 0;
702 }
703
704 void xen_be_unbind_evtchn(struct XenDevice *xendev)
705 {
706 if (xendev->local_port == -1) {
707 return;
708 }
709 qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
710 xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
711 xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
712 xendev->local_port = -1;
713 }
714
715 int xen_be_send_notify(struct XenDevice *xendev)
716 {
717 return xc_evtchn_notify(xendev->evtchndev, xendev->local_port);
718 }
719
720 /*
721 * msg_level:
722 * 0 == errors (stderr + logfile).
723 * 1 == informative debug messages (logfile only).
724 * 2 == noisy debug messages (logfile only).
725 * 3 == will flood your log (logfile only).
726 */
727 void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
728 {
729 va_list args;
730
731 if (xendev) {
732 if (msg_level > xendev->debug) {
733 return;
734 }
735 qemu_log("xen be: %s: ", xendev->name);
736 if (msg_level == 0) {
737 fprintf(stderr, "xen be: %s: ", xendev->name);
738 }
739 } else {
740 if (msg_level > debug) {
741 return;
742 }
743 qemu_log("xen be core: ");
744 if (msg_level == 0) {
745 fprintf(stderr, "xen be core: ");
746 }
747 }
748 va_start(args, fmt);
749 qemu_log_vprintf(fmt, args);
750 va_end(args);
751 if (msg_level == 0) {
752 va_start(args, fmt);
753 vfprintf(stderr, fmt, args);
754 va_end(args);
755 }
756 qemu_log_flush();
757 }