From b2ad519a8a1fc6509d262b64882c964d000488d4 Mon Sep 17 00:00:00 2001 From: Jean Guyader Date: Thu, 29 Jan 2009 22:47:42 +0000 Subject: [PATCH] Change the way we do the keyboard switching. - Creation of a proxy node under the private tree of a domain. - /local/domain//dom0_input/command The command are: - take to ask for the keyboard - release to give the keyboard back to the natif domain. - Move dom0_input to dom0_input/pos - Add some a xenstore fonction to chmod the node from qemu. The dom0_input/command node needs to be writable by the domain. --- dom0_driver.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------ qemu-xen.h | 2 ++ xenstore.c | 48 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/dom0_driver.c b/dom0_driver.c index 386b2949..91c763f5 100644 --- a/dom0_driver.c +++ b/dom0_driver.c @@ -98,7 +98,7 @@ static int dom0_driver_xs_read_dom0(const char *key) if (!(str = xenstore_read_dom0_driver(key))) { - fprintf(stderr, "dom0_driver: fatal the node %s don't exits\n", key); + fprintf(stderr, "dom0_driver: the node %s don't exits\n", key); exit(2); } return strtol(str, NULL, 10); @@ -337,7 +337,7 @@ static void dom0_get_positions(int *positions) for (int i = 0; i < num; i++) if (domids[i]) { - if (!(tmp = xenstore_dom_read(domids[i], "dom0_input", &len))) + if (!(tmp = xenstore_dom_read(domids[i], "dom0_input/pos", &len))) continue; pos = strtol(tmp, NULL, 10); free(tmp); @@ -639,6 +639,42 @@ static void dom0_driver_dev_init(void) assert(driver.mouse_fds[0] != -1); } +static void dom0_driver_dom_command(char *path, void *opaque) +{ + unsigned int len; + char *str; + char buff[256]; + int positions[NB_SLOTS]; + int natif_domid; + int i; + + if (!(str = xenstore_read(path)) || !*str) + return; + + DEBUG("Received private command %s\n", path); + dom0_get_positions(positions); + natif_domid = dom0_driver_xs_read_dom0("natif"); + + for (i = 0; i < NB_SLOTS; ++i) + { + if (!strcmp("take", str) && positions[i] == domid) + break; + if (!strcmp("release", str) && positions[i] == natif_domid) + break; + } + if (i == NB_SLOTS) + { + DEBUG("Try to %s on a bad slot\n", str); + free(str); + return; + } + + sprintf(buff, "keyboard %d", i); + DEBUG("Write \"%s\" into xenstore\n", buff); + xenstore_write_dom0_driver("command", buff); + free(str); +} + static void dom0_driver_event_init(const char *str_arg) { int positions[NB_SLOTS]; @@ -658,22 +694,33 @@ static void dom0_driver_event_init(const char *str_arg) else { snprintf(str, 9, "%d", pos); - xenstore_dom_write(domid, "dom0_input", str); + xenstore_dom_write(domid, "dom0_input/pos", str); } if (vga_passthrough) { - char str[20]; - sprintf(str, "%d", domid); xenstore_write_dom0_driver("natif", str); } + else + { + xenstore_dom_write(domid, "dom0_input/command", ""); + sprintf(str, "w%d", domid); + xenstore_dom_chmod(domid, "dom0_input/command", str); + } xenstore_watch_dom0_driver("mouse/state", dom0_driver_state_change, NULL); xenstore_watch_dom0_driver("keyboard/state", dom0_driver_state_change, NULL); - xenstore_watch_dom0_driver("blank", dom0_driver_state_change, NULL); + if (vga_passthrough) + { + xenstore_write_dom0_driver("blank", "0"); xenstore_watch_dom0_driver("command", dom0_driver_command, NULL); + } + else + xenstore_dom_watch(domid, "dom0_input/command", dom0_driver_dom_command, NULL); + + xenstore_watch_dom0_driver("blank", dom0_driver_state_change, NULL); /* Register the failover switch */ driver.xs_timer = qemu_new_timer(rt_clock, dom0_driver_failover_switch, NULL); diff --git a/qemu-xen.h b/qemu-xen.h index 99b9cd52..93d9e645 100644 --- a/qemu-xen.h +++ b/qemu-xen.h @@ -86,6 +86,8 @@ int xenstore_watch_dom0_driver(const char *key, xenstore_callback fptr, void *op char *xenstore_dom_read(int domid, char *key, unsigned int *len); int xenstore_dom_write(int domid, char *key, char *value); +void xenstore_dom_watch(int domid, const char *key, xenstore_callback ftp, void *opaque); +void xenstore_dom_chmod(int domid, const char *key, const char *perms); int *xenstore_get_domids(int *len); char *xenstore_read(const char *path); diff --git a/xenstore.c b/xenstore.c index a5ac7abe..ac5a73da 100644 --- a/xenstore.c +++ b/xenstore.c @@ -1469,6 +1469,54 @@ char *xenstore_dom_read(int domid, char *key, unsigned int *len) return value; } +void xenstore_dom_watch(int domid, const char *key, xenstore_callback fptr, void *opaque) +{ + char *buf = NULL, *path = NULL; + int rc = -1; + + if (xsh == NULL) + goto out; + + path = xs_get_domain_path(xsh, domid); + if (path == NULL) { + fprintf(logfile, "xs_get_domain_path: error\n"); + goto out; + } + + pasprintf(&buf, "%s/%s", path, key); + xenstore_watch_new_callback(buf, fptr, opaque); + + out: + free(path); + free(buf); +} + +void xenstore_dom_chmod(int domid, const char *key, const char *perms) +{ + char *buf = NULL, *path = NULL; + int rc = -1; + struct xs_permissions p; + + if (xsh == NULL) + goto out; + + path = xs_get_domain_path(xsh, domid); + if (path == NULL) { + fprintf(logfile, "xs_get_domain_path: error\n"); + goto out; + } + + pasprintf(&buf, "%s/%s", path, key); + + xs_strings_to_perms(&p, 1, perms); + xs_set_permissions(xsh, XBT_NULL, buf, &p, 1); + + out: + free(path); + free(buf); +} + + int xenstore_dom_write(int domid, char *key, char *value) { char *buf = NULL, *path = NULL; -- 2.39.5