From: kaf24@firebug.cl.cam.ac.uk Date: Wed, 9 Mar 2005 16:45:29 +0000 (+0000) Subject: bitkeeper revision 1.1236.12.25 (422f282953v_J4bTBy1CN1Z9x3rhog) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~17857^2~57^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=fffb91d4d8a6f91ce230e4f9443ff133edc387b9;p=xen.git bitkeeper revision 1.1236.12.25 (422f282953v_J4bTBy1CN1Z9x3rhog) .del-util.c~fb55f547242f9869: Delete: tools/x2d2/util.c .del-minixend.h~9bba8a3fbfa4153: Delete: tools/x2d2/minixend.h .del-minixend.c~ef5576bb71152607: Delete: tools/x2d2/minixend.c .del-cntrl_con.c~9df6acbfc777c229: Delete: tools/x2d2/cntrl_con.c .del-Makefile~7ab0b94e34972cb0: Delete: tools/x2d2/Makefile --- diff --git a/.rootkeys b/.rootkeys index 779e74a063..2986ce0696 100644 --- a/.rootkeys +++ b/.rootkeys @@ -850,11 +850,6 @@ 41a2188ar6_vOO3_tEJQjmFVU3409A tools/vnet/vnetd/vcache.h 41a2188aETrGU60X9WtGhYVfU7z0Pw tools/vnet/vnetd/vnetd.c 41a2188ahYjemudGyB7078AWMFR-0w tools/vnet/vnetd/vnetd.h -4194e861IgTabTt8HOuh143QIJFD1Q tools/x2d2/Makefile -4194e861M2gcBz4i94cQYpqzi8n6UA tools/x2d2/cntrl_con.c -4194e8612TrrMvC8ZlA4h2ZYCPWz4g tools/x2d2/minixend.c -4194e861x2eqNCD61RYPCUEBVdMYuw tools/x2d2/minixend.h -4194e861A4V9VbD_FYmgXpYEj5YwVg tools/x2d2/util.c 41d58ba63w1WfBmd6Cr_18nhLNv7PA tools/xcs/Makefile 41d58ba6NxgkfzD_rmsGjgd_zJ3H_w tools/xcs/bindings.c 41d58ba6I2umi60mShq4Pl0RDg7lzQ tools/xcs/connection.c diff --git a/tools/x2d2/Makefile b/tools/x2d2/Makefile deleted file mode 100644 index 43f6964cae..0000000000 --- a/tools/x2d2/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -XEN_ROOT=../.. -include $(XEN_ROOT)/tools/Rules.mk - -CC = gcc -CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing - -CFLAGS += -I $(XEN_XC) -CFLAGS += -I $(XEN_LIBXC) -CFLAGS += -I $(XEN_LIBXUTIL) - -HDRS = $(wildcard *.h) -OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) - -BIN = minixend - -all: $(BIN) - -clean: - $(RM) *.a *.so *.o *.rpm $(BIN) - -$(BIN): $(OBJS) - $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -lxc -lxutil -lpthread diff --git a/tools/x2d2/cntrl_con.c b/tools/x2d2/cntrl_con.c deleted file mode 100644 index 46084dbdee..0000000000 --- a/tools/x2d2/cntrl_con.c +++ /dev/null @@ -1,457 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "minixend.h" - -struct command { - const char *name; - void (*func)(struct open_connection *oc, const struct command *c, - const char *, const char *); -}; - -static void -domain_created(const char *name, int mem_kb, int domid) -{ - struct domain *d; - d = xmalloc(sizeof(*d)); - d->domid = domid; - d->name = xstrdup(name); - d->mem_kb = mem_kb; - d->state = DOM_STATE_CREATED; - d->control_evtchn = -1; /* Not connected yet. */ - - memcpy(d->netif_mac, "\xaa\x00\x00\x02\x00\x00", 6); - d->netif_mac[5] = d->domid; - - pthread_mutex_init(&d->mux, NULL); - pthread_cond_init(&d->cond, NULL); - pthread_create(&d->thread, NULL, domain_thread_func, d); - - list_insert_after(&d->domain_list, &head_domain); -} - -static struct domain * -find_domain(int domain_id) -{ - struct domain *d; - - foreach_domain(d) { - if (d->domid == domain_id) - return d; - } - return NULL; -} - -static int -free_event_port(struct domain *d, int port) -{ - if (d == NULL) - return xc_evtchn_close(xc_handle, DOMID_SELF, port); - else - return xc_evtchn_close(xc_handle, d->domid, port); -} - -static char * -readline(struct open_connection *oc) -{ - char *end; - char *res; - int line_length; - - if (oc->state == OC_STATE_ERROR) - return NULL; - - end = memchr(oc->buf, '\r', oc->buf_used); - assert(end != NULL); - line_length = end - oc->buf; - - res = xmalloc(line_length + 1); - memcpy(res, oc->buf, line_length); - res[line_length] = 0; - memmove(oc->buf, oc->buf + line_length + 2, - oc->buf_used - line_length - 2); - - oc->buf_used -= line_length + 2; - - if (memchr(oc->buf, '\n', oc->buf_used)) - oc->state = OC_STATE_COMMAND_PENDING; - else - oc->state = OC_STATE_CONNECTED; - - return res; -} - -static unsigned long -find_domain_shared_info_mfn(struct domain *d) -{ - xc_dominfo_t info; - - xc_domain_getinfo(xc_handle, d->domid, 1, &info); - return info.shared_info_frame; -} - -static void -send_message(struct open_connection *oc, const char *fmt, ...) -{ - char *buf; - va_list ap; - int size; - int off; - ssize_t r; - - if (oc->state == OC_STATE_ERROR) - return; - - va_start(ap, fmt); - size = vasprintf(&buf, fmt, ap); - va_end(ap); - if (size < 0) - err(1, "preparing response to a query"); - assert(buf[0] == 'E' || buf[0] == 'N'); - assert(isdigit(buf[1])); - assert(isdigit(buf[2])); - assert(buf[3] == ' ' || buf[3] == '\n'); - - off = 0; - while (off < size) { - r = write(oc->fd, buf + off, size - off); - if (r < 0) { - warn("sending response to remote"); - oc->state = OC_STATE_ERROR; - free(buf); - return; - } - off += r; - } - free(buf); -} - -static void -default_command_handler(struct open_connection *oc, const struct command *ign, - const char *buf, const char *args) -{ - warnx("bad command %s", buf); - send_message(oc, "E00 unknown command %s\n", buf); -} - -static void -create_command_handler(struct open_connection *oc, const struct command *ign, - const char *buf, const char *args) -{ - char *name; - unsigned mem_kb; - int r; - u32 domid = -1; - - r = sscanf(args, "%d %a[^\n]", &mem_kb, &name); - if (r != 2) { - send_message(oc, "E01 failed to parse %s\n", args); - return; - } - r = xc_domain_create(xc_handle, mem_kb, -1, 0, &domid); - if (r < 0) { - send_message(oc, "E02 creating domain (%s)\n", - strerror(errno)); - free(name); - return; - } - - domain_created(name, mem_kb, domid); - - send_message(oc, "N00 %d\n", domid); - free(name); -} - -static void -build_command_handler(struct open_connection *oc, const struct command *ign, - const char *buf, const char *args) -{ - struct domain *d; - int domain_id; - char *image, *cmdline; - int event_ports[2]; - int r; - - r = sscanf(args, "%d %a[^\t] %a[^\n]", &domain_id, - &image, &cmdline); - if (r != 3) { - send_message(oc, "E03 failed to parse %s\n", args); - return; - } - d = find_domain(domain_id); - if (d == NULL) { - send_message(oc, "E04 unknown domain %d\n", domain_id); - goto out; - } - if (d->state != DOM_STATE_CREATED) { - send_message(oc, "E05 domain %d in bad state\n", domain_id); - goto out; - } - - r = allocate_event_channel(d, event_ports); - if (r < 0) { - send_message(oc, "E06 allocating control event channel: %s\n", - strerror(errno)); - goto out; - } - - r = xc_linux_build(xc_handle, domain_id, image, NULL, cmdline, - event_ports[1], 0); - if (r < 0) { - send_message(oc, "E07 building domain: %s\n", - strerror(errno)); - free_event_port(NULL, event_ports[0]); - free_event_port(d, event_ports[1]); - goto out; - } - - if (ioctl(evtchn_fd, EVTCHN_BIND, event_ports[0]) < 0) - err(1, "binding to event control event channel"); - - d->shared_info_mfn = find_domain_shared_info_mfn(d); - d->shared_info = map_domain_mem(d, d->shared_info_mfn); - if (d->shared_info == NULL) - err(1, "maping domain shared info page at %lx.\n", - d->shared_info_mfn); - d->ctrl_if = (control_if_t *)((unsigned)d->shared_info + 2048); - - d->control_evtchn = event_ports[0]; - d->state = DOM_STATE_PAUSED; - - send_message(oc, "N00\n"); - - out: - free(image); - free(cmdline); - return; -} - -static void -unpause_command_handler(struct open_connection *oc, - const struct command *ign, - const char *buf, - const char *args) -{ - int domain_id; - int r; - struct domain *d; - - r = sscanf(args, "%d", &domain_id); - if (r != 1) { - send_message(oc, "E08 cannot parse %s\n", args); - return; - } - d = find_domain(domain_id); - if (d == NULL) { - send_message(oc, "E09 cannot find domain %d\n", domain_id); - return; - } - if (d->state != DOM_STATE_PAUSED) { - send_message(oc, "E10 domain not paused\n"); - return; - } - - r = xc_domain_unpause(xc_handle, d->domid); - if (r < 0) { - send_message(oc, "E11 unpausing domain: %s\n", - strerror(errno)); - return; - } - - d->state = DOM_STATE_RUNNING; - send_message(oc, "N00\n"); -} - -static void -console_command_handler(struct open_connection *oc, - const struct command *ign, - const char *buf, - const char *args) -{ - int domain_id; - struct domain *d; - int r; - struct sockaddr_in name; - socklen_t namelen; - - r = sscanf(args, "%d", &domain_id); - if (r != 1) { - send_message(oc, "E12 cannot parse %s\n", args); - return; - } - d = find_domain(domain_id); - if (d == NULL) { - send_message(oc, "E13 cannot find domain %d\n", domain_id); - return; - } - if (d->cc != NULL) { - send_message(oc, "E14 console already exists\n"); - return; - } - - d->cc = xmalloc(sizeof(*d->cc)); - d->cc->fd = socket(PF_INET, SOCK_STREAM, 0); - if (d->cc->fd < 0) - err(1, "creating console socket"); - d->cc->dom = d; - d->cc->state = CC_STATE_PENDING; - d->cc->buf_used = 0; - d->cc->buf_allocated = 0; - d->cc->buf = NULL; - - r = listen(d->cc->fd, 1); - if (r < 0) - err(1, "listening on console socket"); - namelen = sizeof(name); - r = getsockname(d->cc->fd, (struct sockaddr *)&name, &namelen); - if (r < 0) - err(1, "getting name of console socket"); - assert(name.sin_family == AF_INET); - assert(namelen == sizeof(name)); - list_insert_after(&d->cc->list, &head_console); - send_message(oc, "N00 %d\n", ntohs(name.sin_port)); -} - -static void -plug_command_handler(struct open_connection *oc, - const struct command *ign, - const char *buf, - const char *args) -{ - unsigned domid; - int r; - struct domain *d; - - r = sscanf(args, "%d", &domid); - if (r != 1) { - send_message(oc, "E15 cannot parse %s\n", args); - return; - } - d = find_domain(domid); - if (d == NULL) { - send_message(oc, "E16 cannot find domain %d\n", domid); - return; - } - - d->plugged = 1; - send_message(oc, "N00\n"); - PRINTF(1, "set domain %d plug state to %d\n", d->domid, d->plugged); -} - -static void -destroy_command_handler(struct open_connection *oc, - const struct command *ign, - const char *buf, - const char *args) -{ - unsigned domid; - int r; - struct domain *d; - - r = sscanf(args, "%d", &domid); - if (r != 1) { - send_message(oc, "E17 cannot parse %s\n", args); - return; - } - d = find_domain(domid); - if (d == NULL) { - send_message(oc, "E18 cannot find domain %d\n", domid); - return; - } - - r = xc_domain_destroy(xc_handle, domid); - if (r < 0) { - send_message( oc, "E19 error destroying domain %d: %s\n", - domid, strerror(errno) ); - return; - } - d->state = DOM_STATE_DEAD; - - send_message(oc, "N00\n"); -} - -static void -list_command_handler(struct open_connection *oc, - const struct command *ign, - const char *buf, - const char *args) -{ - struct domain *d; - static const char *const state_strings[] = { - [DOM_STATE_CREATED] = "created", - [DOM_STATE_PAUSED] = "paused", - [DOM_STATE_RUNNING] = "running", - [DOM_STATE_DEAD] = "dead" - }; - - foreach_domain(d) { - send_message(oc, "N01 %d %s %d %s\n", - d->domid, - d->name, - d->mem_kb, - state_strings[d->state]); - } - send_message(oc, "N00\n"); -} - -static struct command -default_command = { NULL, default_command_handler }; - -static struct command -commands[] = { - { "build", build_command_handler }, - { "console", console_command_handler }, - { "create", create_command_handler }, - { "destroy", destroy_command_handler }, - { "plug", plug_command_handler }, - { "list", list_command_handler }, - { "unpause", unpause_command_handler } -}; - -void -process_command(struct open_connection *oc) -{ - char *buf, *b; - int command_len; - int x; - struct command *cmd; - - buf = readline(oc); - if (buf == NULL) - return; - b = strchr(buf, ' '); - if (b == NULL) - command_len = strlen(buf); - else - command_len = b - buf; - b = buf + command_len; - while (b[0] && b[0] == ' ') - b++; - - cmd = &default_command; - for (x = 0; x < sizeof(commands) / sizeof(commands[0]); x++) { - if (strlen(commands[x].name) == command_len && - memcmp(commands[x].name, buf, command_len) == 0) { - cmd = &commands[x]; - break; - } - } - cmd->func(oc, cmd, buf, b); - free(buf); - return; -} diff --git a/tools/x2d2/minixend.c b/tools/x2d2/minixend.c deleted file mode 100644 index 64fe27195a..0000000000 --- a/tools/x2d2/minixend.c +++ /dev/null @@ -1,939 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "minixend.h" - -#define NETWORK_SCRIPT "/etc/xen/scripts/network" -#define VIFBRIDGE_SCRIPT "/etc/xen/scripts/vif-bridge" - -#define MINIXEND_PORT 5123 - -#define mb() asm volatile ("" ::: "memory") - -static void send_control_message(int type, int subtype, int id, - int size, void *payload, - struct domain *target); - -struct list_head -head_domain = LIST_HEAD(&head_domain); - -static struct list_head -head_connection = LIST_HEAD(&head_connection); - -struct list_head -head_console = LIST_HEAD(&head_console); - -#define foreach_open_connection(d) \ -foreach_item(d, &head_connection, struct open_connection, connection_list) - -/* Not modified after initial start up */ -static struct domain *dom0; -unsigned xc_handle; -static int listen_fd; -int evtchn_fd; - -static struct list_head -head_event_receiver = LIST_HEAD(&head_event_receiver); - -struct event_receiver { - struct list_head list; - int id; - pthread_cond_t cond; -}; - -/* We're protected by the dom0 mutex in here */ -static struct event_receiver * -allocate_event_receiver(struct domain *d) -{ - static int next_message_id; - struct event_receiver *work; - - assert(d == dom0); - work = xmalloc(sizeof(*work)); - work->id = next_message_id++; - pthread_cond_init(&work->cond, NULL); - - list_insert_after(&work->list, &head_event_receiver); - - return work; -} - -static struct event_receiver * -find_event_receiver(int id) -{ - struct event_receiver *work; - foreach_item(work, &head_event_receiver, struct event_receiver, list) - if (work->id == id) - return work; - return NULL; -} - -static void -release_event_receiver(struct event_receiver *w) -{ - list_remove(&w->list); - pthread_cond_destroy(&w->cond); - free(w); -} - -/* Send a message to dom0, and then block awaiting a reply. */ -/* Make sure we don't hold any domain mutexs */ -static void -send_dom0_message_block(control_msg_t *msg) -{ - CONTROL_RING_IDX c; - struct event_receiver *er; - control_msg_t buf; - - PRINTF(0, "sending message to dom0 and blocking for reply.\n"); - pthread_mutex_lock(&dom0->mux); - PRINTF(0, "got dom0 lock.\n"); - er = allocate_event_receiver(dom0); - PRINTF(0, "allocated evetn receiver.\n"); - msg->id = er->id; - PRINTF(1, "sending message with id %d\n", msg->id); - send_control_message(msg->type, msg->subtype, - msg->id, msg->length, msg->msg, dom0); - xc_evtchn_send(xc_handle, dom0->control_evtchn); - - PRINTF(0, "waiting for reply\n"); - pthread_cond_wait(&er->cond, &dom0->mux); - PRINTF(0, "got reply\n"); - - c = dom0->rx_resp_cons % CONTROL_RING_SIZE; - memcpy(&buf, &dom0->ctrl_if->rx_ring[c], sizeof(buf)); - assert(msg->id == buf.id); - assert(msg->type == buf.type); - assert(msg->subtype == buf.subtype); - memcpy(msg, &buf, sizeof(*msg)); - dom0->rx_resp_cons++; - - release_event_receiver(er); - - pthread_mutex_unlock(&dom0->mux); - - PRINTF(1, "got reply to message with id %d\n", msg->id); -} - -/* Allocate an interdomain event channel. event_ports[0] is the - local event port number, event_ports[1] the remote */ -int -allocate_event_channel(struct domain *d, int event_ports[2]) -{ - return xc_evtchn_bind_interdomain(xc_handle, DOMID_SELF, - d->domid, event_ports, - event_ports+1); -} - -static void -accept_new_connection(void) -{ - int fd; - struct open_connection *oc; - - fd = accept(listen_fd, NULL, NULL); - if (fd < 0) - return; - oc = xmalloc(sizeof(*oc)); - oc->fd = fd; - oc->state = OC_STATE_CONNECTED; - oc->buf_used = 0; - oc->buf_allocated = 16; - oc->buf = xmalloc(oc->buf_allocated); - list_insert_after(&oc->connection_list, &head_connection); -} - -static void -closedown_connection(struct open_connection *oc) -{ - close(oc->fd); - assert(oc->buf); - free(oc->buf); - free(oc); -} - -#if 0 -/* Hackl for the benefit of domain replay */ -static unsigned -report_work(u32 *ptr, u32 val, unsigned dom, int do_direct) -{ - if (!do_direct) { - int rc; - asm("int $0x80" : "=a" (rc) - : "0" (264), "b" (ptr), "c" (val), "d" (dom)); - if (rc < 0) { - errno = -rc; - rc = -1; - } - return rc; - } else { - *ptr = val; - return 0; - } -} -#else -static unsigned -report_work(u32 *ptr, u32 val, unsigned dom, int do_direct) -{ - *ptr = val; - return 0; -} -#endif - -static void -send_control_reply(const control_msg_t *msg, struct domain *d) -{ - CONTROL_RING_IDX c; - - PRINTF(3,"Control reply, type %d:%d, length %d.\n", - msg->type, msg->subtype, msg->length); - c = d->ctrl_if->tx_resp_prod % CONTROL_RING_SIZE; - memcpy(&d->ctrl_if->tx_ring[c], msg, sizeof(*msg)); - report_work(&d->ctrl_if->tx_resp_prod, - d->ctrl_if->tx_resp_prod + 1, - d->domid, - 0); - PRINTF(4,"tx_resp_prod %ld.\n", d->ctrl_if->tx_resp_prod); - assert(!d->plugged); -} - -static void -send_trivial_control_reply(const control_msg_t *msg, struct domain *d) -{ - control_msg_t rep; - - memset(&rep, 0, sizeof(rep)); - rep.type = msg->type; - rep.subtype = msg->subtype; - rep.id = msg->id; - send_control_reply(&rep, d); -} - -static void -process_console_control_message(control_msg_t *m, struct domain *d) -{ - int off; - int r; - - if (m->subtype != CMSG_CONSOLE_DATA) { - warnx("unknown console message subtype %d", - m->subtype); - return; - } - - if (m->length > 60) { - warnx("truncating message from domain %d (was length %d)", - d->domid, m->length); - m->length = 60; - } - PRINTF(1, "DOM%d: %.*s\n", d->domid, m->length, m->msg); - send_trivial_control_reply(m, d); - - if (d->cc) { - PRINTF(5, "Have a console connection.\n"); - if (d->cc->state == CC_STATE_CONNECTED) { - PRINTF(5, "Console is connected, sending directly.\n"); - for (off = 0; off < m->length; off += r) { - r = write(d->cc->fd, m->msg + off, - m->length - off); - if (r <= 0) { - d->cc->state = CC_STATE_ERROR; - break; - } - } - } else { - PRINTF(5, "Console not connected, buffering.\n"); - if (d->cc->buf_allocated == 0) { - d->cc->buf_allocated = 60; - d->cc->buf = xmalloc(d->cc->buf_allocated); - d->cc->buf_used = 0; - } else if (d->cc->buf_allocated < - d->cc->buf_used + m->length) { - d->cc->buf_allocated += 60; - d->cc->buf = xrealloc(d->cc->buf, - d->cc->buf_allocated); - } - assert(d->cc->buf_allocated >= - d->cc->buf_used + m->length); - memcpy(d->cc->buf + d->cc->buf_used, - m->msg, - m->length); - d->cc->buf_used += m->length; - } - } -} - -static void -process_blkif_fe_message(control_msg_t *m, struct domain *d) -{ - switch (m->subtype) { - default: - warnx("unknown blkif front end message subtype %d", - m->subtype); - } -} - -static void -send_control_message(int type, int subtype, int id, - int size, void *payload, struct domain *target) -{ - control_msg_t msg; - CONTROL_RING_IDX c; - - msg.type = type; - msg.subtype = subtype; - msg.id = id; - msg.length = size; - memcpy(msg.msg, payload, size); - - c = target->ctrl_if->rx_req_prod % CONTROL_RING_SIZE; - memcpy(&target->ctrl_if->rx_ring[c], &msg, sizeof(msg)); - report_work(&target->ctrl_if->rx_req_prod, - target->ctrl_if->rx_req_prod + 1, - target->domid, - 0); - assert(!target->plugged); -} - -/* Procedure for bringing a new netif front end up: - - -- Front end sends us NETIF_FE_DRIVER_STATUS_CHANGED - -- We send back end NETIF_BE_CREATE, wait for a reply - -- Back end creates a new netif for us, replies - -- We send front end a NETIF_FE_DRIVER_STATUS_CHANGED message saying - how many interfaces we've created for it - -- We send front end a NETIF_FE_INTERFACE_STATUS_CHANGED for each - netif created - -- Front end sends us a NETIF_FE_INTERFACE_CONNECT for each netif -*/ -static void -handle_netif_fe_driver_status(control_msg_t *m, - netif_fe_driver_status_t *sh, - struct domain *d) -{ - netif_fe_interface_status_t if_s; - control_msg_t be_msg; - netif_be_create_t *be = (void *)be_msg.msg; - int r; - - switch (sh->status) { - case NETIF_DRIVER_STATUS_UP: - /* Tell the back end about the new interface coming - * up. */ - if (d->created_netif_backend) { - send_control_reply(m, d); - send_control_message(CMSG_NETIF_FE, - CMSG_NETIF_FE_DRIVER_STATUS, - 1, - sizeof(*sh), - sh, - d); - return; - } - be_msg.type = CMSG_NETIF_BE; - be_msg.subtype = CMSG_NETIF_BE_CREATE; - be_msg.id = d->domid; - be_msg.length = sizeof(*be); - be->domid = d->domid; - be->netif_handle = 0; - memcpy(be->mac, d->netif_mac, 6); - - PRINTF(2,"Telling back end about new front end.\n"); - pthread_mutex_unlock(&d->mux); - send_dom0_message_block(&be_msg); - pthread_mutex_lock(&d->mux); - PRINTF(3,"Done.\n"); - - if (be->status != NETIF_BE_STATUS_OKAY) { - /* Uh oh... can't bring back end - * up. */ - send_control_reply(m, d); - send_control_message(CMSG_NETIF_FE, - CMSG_NETIF_FE_DRIVER_STATUS, - 1, - sizeof(*sh), - sh, - d); - return; - } - d->created_netif_backend = 1; - - r = our_system(VIFBRIDGE_SCRIPT " up domain=%s mac=%.02x:%.02x:%.02x:%.02x:%.02x:%.02x vif=vif%d.0 bridge=xen-br0", - d->name, - d->netif_mac[0], - d->netif_mac[1], - d->netif_mac[2], - d->netif_mac[3], - d->netif_mac[4], - d->netif_mac[5], - d->domid); - if (r != 0) - warn("error %d running " VIFBRIDGE_SCRIPT, r); - - /* Tell domain how many interfaces it has to deal - * with. */ - send_control_reply(m, d); - send_control_message(CMSG_NETIF_FE, - CMSG_NETIF_FE_DRIVER_STATUS, - 1, - sizeof(*sh), - sh, - d); - - PRINTF(2,"Telling front end about its interfaces.\n"); - if_s.handle = 0; - if_s.status = NETIF_INTERFACE_STATUS_DISCONNECTED; - send_control_message(CMSG_NETIF_FE, - CMSG_NETIF_FE_INTERFACE_STATUS, - 1, - sizeof(if_s), - &if_s, - d); - PRINTF(3,"Done.\n"); - - break; - default: - warnx("unknown netif status %ld", sh->status); - break; - } -} - -static void -handle_netif_fe_interface_connect(control_msg_t *m, - netif_fe_interface_connect_t *ic, - struct domain *d) -{ - control_msg_t be_msg; - netif_be_connect_t *bmsg = (void *)be_msg.msg; - netif_fe_interface_status_t fmsg = {0}; - int evtchn_ports[2]; - int r; - - PRINTF(4, "front end sent us an interface connect message.\n"); - send_trivial_control_reply(m, d); - - r = xc_evtchn_bind_interdomain(xc_handle, - dom0->domid, - d->domid, - &evtchn_ports[0], - &evtchn_ports[1]); - if (r < 0) - err(1, "allocating network event channel"); - - be_msg.type = CMSG_NETIF_BE; - be_msg.subtype = CMSG_NETIF_BE_CONNECT; - be_msg.id = 0; - be_msg.length = sizeof(*bmsg); - bmsg->domid = d->domid; - bmsg->netif_handle = ic->handle; - bmsg->tx_shmem_frame = ic->tx_shmem_frame; - bmsg->rx_shmem_frame = ic->rx_shmem_frame; - bmsg->evtchn = evtchn_ports[0]; - - pthread_mutex_unlock(&d->mux); - send_dom0_message_block(&be_msg); - pthread_mutex_lock(&d->mux); - - if (bmsg->status != NETIF_BE_STATUS_OKAY) { - PRINTF(2, "error connected backend netif: %ld\n", - bmsg->status); - abort(); /* Need to handle this */ - } else { - PRINTF(3, "connect backend netif\n"); - - /* Tell the domain that we've connected it up. */ - fmsg.handle = ic->handle; - fmsg.status = NETIF_INTERFACE_STATUS_CONNECTED; - fmsg.evtchn = evtchn_ports[1]; - memcpy(fmsg.mac, d->netif_mac, 6); - - send_control_message(CMSG_NETIF_FE, - CMSG_NETIF_FE_INTERFACE_STATUS, - 0, - sizeof(fmsg), - &fmsg, - d); - } -} - -static void -process_netif_fe_message(control_msg_t *m, struct domain *d) -{ - switch (m->subtype) { - case CMSG_NETIF_FE_DRIVER_STATUS: - { - netif_fe_driver_status_t *sh = - (netif_fe_driver_status_t *)m->msg; - handle_netif_fe_driver_status(m, sh, d); - break; - } - case CMSG_NETIF_FE_INTERFACE_CONNECT: - { - netif_fe_interface_connect_t *ic = - (netif_fe_interface_connect_t *)m->msg; - handle_netif_fe_interface_connect(m, ic, d); - break; - } - default: - warnx("unknown netif front end message subtype %d", - m->subtype); - } -} - -static void -process_control_message(control_msg_t *msg, struct domain *d) -{ - control_msg_t m; - - /* Don't want a malicous domain messing us about, so copy the - control mesasge into a local buffer. */ - memcpy(&m, msg, sizeof(m)); - switch (m.type) { - case CMSG_CONSOLE: - process_console_control_message(&m, d); - break; - case CMSG_BLKIF_FE: - process_blkif_fe_message(&m, d); - break; - case CMSG_NETIF_FE: - process_netif_fe_message(&m, d); - break; - default: - warnx("unknown control message type %d", m.type); - } -} - -static void -domain_did_control_event(struct domain *d) -{ - CONTROL_RING_IDX c; - - /* Pick up and process control ring messages. */ - while (d->tx_req_cons != d->ctrl_if->tx_req_prod) { - c = d->tx_req_cons % CONTROL_RING_SIZE; - process_control_message(&d->ctrl_if->tx_ring[c], d); - d->tx_req_cons++; - assert(d->tx_req_cons <= d->ctrl_if->tx_req_prod); - PRINTF(5, "req_cons %ld, req_prod %ld.\n", - d->tx_req_cons, d->ctrl_if->tx_req_prod); - } - - /* Take any replies off, and discard them. */ - if (d->rx_resp_cons != d->ctrl_if->rx_resp_prod) - PRINTF(1, "discard %ld events\n", - d->ctrl_if->rx_resp_prod - - d->rx_resp_cons); - d->rx_resp_cons = d->ctrl_if->rx_resp_prod; -} - -/* This is the main function for domain control threads */ -void * -domain_thread_func(void *D) -{ - struct domain *d = D; - int r; - CONTROL_RING_IDX old_resp_prod, old_req_prod; - - pthread_mutex_lock(&d->mux); - for (;;) { - pthread_cond_wait(&d->cond, &d->mux); - - old_resp_prod = d->ctrl_if->tx_resp_prod; - old_req_prod = d->ctrl_if->rx_req_prod; - - domain_did_control_event(d); - if (d->cc && d->cc->in_buf_used != 0 && d->plugged == 0) { - r = d->cc->in_buf_used; - if (r > 60) - r = 60; - PRINTF(1, "Sending to domain: %.*s\n", - r, d->cc->in_buf); - send_control_message(CMSG_CONSOLE, - CMSG_CONSOLE_DATA, - 0, - r, - d->cc->in_buf, - d); - memmove(d->cc->in_buf, d->cc->in_buf + r, - d->cc->in_buf_used - r); - d->cc->in_buf_used -= r; - } - - if (d->ctrl_if->tx_resp_prod != old_resp_prod || - d->ctrl_if->rx_req_prod != old_req_prod) - xc_evtchn_send(xc_handle, d->control_evtchn); - } -} - -/* This is the only thing you can do with a domain structure if you're - not in the thread which controls that domain. Domain 0 is - special. */ -void -signal_domain(struct domain *d) -{ - CONTROL_RING_IDX c; - int id; - struct event_receiver *evt; - - pthread_mutex_lock(&d->mux); - if (d == dom0) { - /* Take events off of dom0's control ring, and send - them to the event receivers. */ - while (d->tx_req_cons != d->ctrl_if->tx_req_prod) { - c = d->tx_req_cons % CONTROL_RING_SIZE; - id = d->ctrl_if->tx_ring[c].id; - evt = find_event_receiver(id); - if (evt != NULL) { - PRINTF(1, "delivering event id %d\n", evt->id); - pthread_cond_broadcast(&evt->cond); - pthread_mutex_unlock(&d->mux); - sched_yield(); - pthread_mutex_lock(&d->mux); - } else { - warnx("unexpected message id %d discarded", - id); - d->tx_req_cons++; - } - } - while (d->rx_resp_cons != d->ctrl_if->rx_resp_prod) { - c = d->rx_resp_cons % CONTROL_RING_SIZE; - id = d->ctrl_if->rx_ring[c].id; - evt = find_event_receiver(id); - if (evt != NULL) { - PRINTF(1, "delivering event rep id %d\n", evt->id); - pthread_cond_broadcast(&evt->cond); - pthread_mutex_unlock(&d->mux); - sched_yield(); - pthread_mutex_lock(&d->mux); - } else { - warnx("unexpected message reply id %d discarded", - id); - d->rx_resp_cons++; - } - } - } else { - if (d->plugged) { - d->event_pending = 1; - } else { - pthread_cond_broadcast(&d->cond); - } - } - pthread_mutex_unlock(&d->mux); -} - -static void -handle_evtchn_event(void) -{ - short port; - struct domain *d; - - read(evtchn_fd, &port, sizeof(short)); - write(evtchn_fd, &port, sizeof(short)); - foreach_domain (d) { - if (d->control_evtchn == port) { - signal_domain(d); - return; - } - } - warnx("got an event on an unknown port %d", port); -} - -void * -map_domain_mem(struct domain *d, unsigned long mfn) -{ - return xc_map_foreign_range(xc_handle, d->domid, - PAGE_SIZE, PROT_READ | PROT_WRITE, - mfn); -} - -static void -handle_console_event(struct console_connection *cc) -{ - int r; - int fd; - - switch (cc->state) { - case CC_STATE_ERROR: - /* Errors shouldn't get here. */ - abort(); - case CC_STATE_PENDING: - fd = accept(cc->fd, NULL, NULL); - if (fd >= 0) { - PRINTF(3, "Accepted console connection for domain %d", - cc->dom->domid); - close(cc->fd); - cc->fd = fd; - cc->state = CC_STATE_CONNECTED; - while (cc->buf_used != 0) { - r = write(cc->fd, - cc->buf, - cc->buf_used); - if (r <= 0) { - cc->state = CC_STATE_ERROR; - break; - } - memmove(cc->buf, - cc->buf + r, - cc->buf_used - r); - cc->buf_used -= r; - } - free(cc->buf); - cc->buf = NULL; - cc->buf_allocated = 0; - } else { - PRINTF(1, "error %s accepting console", strerror(errno)); - } - pthread_mutex_unlock(&cc->dom->mux); - break; - case CC_STATE_CONNECTED: - if (cc->in_buf_allocated == 0) { - assert(cc->in_buf_used == 0); - cc->in_buf_allocated = 128; - cc->in_buf = xmalloc(cc->in_buf_allocated); - } - if (cc->in_buf_used == cc->in_buf_allocated) { - cc->in_buf_allocated *= 2; - cc->in_buf = xrealloc(cc->in_buf, cc->in_buf_allocated); - } - r = read(cc->fd, cc->in_buf + cc->in_buf_used, - cc->in_buf_allocated - cc->in_buf_used); - if (r <= 0) { - cc->state = CC_STATE_ERROR; - } else { - cc->in_buf_used += r; - } - pthread_mutex_unlock(&cc->dom->mux); - signal_domain(cc->dom); - break; - } -} - -static void -handle_connection_event(struct open_connection *oc) -{ - int r; - - /* We know that some amount of data is ready and waiting for - us. Slurp it in. */ - if (oc->buf_used == oc->buf_allocated) { - oc->buf_allocated *= 2; - oc->buf = xrealloc(oc->buf, oc->buf_allocated); - } - r = read(oc->fd, oc->buf + oc->buf_used, - oc->buf_allocated - oc->buf_used); - if (r < 0) { - warn("reading command from remote"); - oc->state = OC_STATE_ERROR; - } else if (r == 0) { - warnx("reading command from remote"); - oc->state = OC_STATE_ERROR; - } else { - oc->buf_used += r; - if (strchr(oc->buf, '\n')) - oc->state = OC_STATE_COMMAND_PENDING; - } -} - -static void -get_and_process_event(void) -{ - fd_set read_fds, except_fds; - struct open_connection *oc; - struct console_connection *cc; - int max_fd = listen_fd; - int r; - struct list_head *li, *temp_li; - - FD_ZERO(&read_fds); - FD_ZERO(&except_fds); - FD_SET(listen_fd, &read_fds); - FD_SET(evtchn_fd, &read_fds); - if (evtchn_fd > max_fd) - max_fd = evtchn_fd; - foreach_open_connection(oc) { - FD_SET(oc->fd, &read_fds); - FD_SET(oc->fd, &except_fds); - if (oc->fd > max_fd) - max_fd = oc->fd; - } - foreach_console_connection(cc) { - FD_SET(cc->fd, &read_fds); - FD_SET(cc->fd, &except_fds); - if (cc->fd > max_fd) - max_fd = cc->fd; - } - - r = select(max_fd + 1, &read_fds, NULL, &except_fds, NULL); - if (r < 0) - err(1, "select"); - if (FD_ISSET(listen_fd, &read_fds)) { - accept_new_connection(); - } else if (FD_ISSET(evtchn_fd, &read_fds)) - handle_evtchn_event(); - - - foreach_open_connection(oc) { - if (FD_ISSET(oc->fd, &read_fds)) - handle_connection_event(oc); - if (FD_ISSET(oc->fd, &except_fds)) - oc->state = OC_STATE_ERROR; - } - list_foreach_safe(&head_console, li, temp_li) { - cc = list_item(li, struct console_connection, list); - if (FD_ISSET(cc->fd, &read_fds)) - handle_console_event(cc); - if (FD_ISSET(cc->fd, &except_fds) || - cc->state == CC_STATE_ERROR) { - PRINTF(1, "Cleaning up console connection"); - cc->dom->cc = NULL; - list_remove(&cc->list); - close(cc->fd); - if (cc->buf_allocated != 0) - free(cc->buf); - if (cc->in_buf_allocated != 0) - free(cc->in_buf); - free(cc); - } - } - - /* Run pending stuff on the open connections. */ - list_foreach_safe(&head_connection, li, temp_li) { - oc = list_item(li, struct open_connection, connection_list); - switch (oc->state) { - case OC_STATE_ERROR: - list_remove(&oc->connection_list); - closedown_connection(oc); - break; - case OC_STATE_COMMAND_PENDING: - process_command(oc); - break; - case OC_STATE_CONNECTED: - /* Don't need to do anything */ - break; - } - } -} - -static int -start_listening(void) -{ - int sock; - struct sockaddr_in inaddr; - - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) - err(1, "creating socket"); - memset(&inaddr, 0, sizeof(inaddr)); - inaddr.sin_family = AF_INET; - inaddr.sin_port = htons(MINIXEND_PORT); - - if (bind(sock, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0) - err(1, "binding to port %d", MINIXEND_PORT); - if (listen(sock, 5) < 0) - err(1, "listening for connections"); - - return sock; -} - -static struct domain * -find_dom0(void) -{ - int r; - xc_dominfo_t info; - struct domain *work; - - r = xc_domain_getinfo(xc_handle, 0, 1, &info); - if (r < 0) - err(1, "getting domain 0 information"); - work = xmalloc(sizeof(*work)); - work->control_evtchn = 2; - if (ioctl(evtchn_fd, EVTCHN_BIND, 2) < 0) - err(1, "binding to domain 0 control event channel"); - - work->domid = 0; - work->name = strdup("dom0"); - work->mem_kb = info.max_memkb; - work->state = DOM_STATE_RUNNING; - work->shared_info_mfn = info.shared_info_frame; - - work->shared_info = map_domain_mem(work, info.shared_info_frame); - work->ctrl_if = (control_if_t *)((unsigned)work->shared_info + 2048); - work->tx_req_cons = work->ctrl_if->tx_req_prod; - work->rx_resp_cons = work->ctrl_if->rx_resp_prod; - - pthread_mutex_init(&work->mux, NULL); - pthread_cond_init(&work->cond, NULL); - - list_insert_after(&work->domain_list, &head_domain); - - return work; -} - -int -main(int argc, char *argv[]) -{ - int r; - - r = our_system(NETWORK_SCRIPT " start antispoof=no"); - if (r < 0) - err(1, "running " NETWORK_SCRIPT); - if (!WIFEXITED(r)) { - if (WIFSIGNALED(r)) { - errx(1, NETWORK_SCRIPT " killed by signal %d", - WTERMSIG(r)); - } - errx(1, NETWORK_SCRIPT " terminated abnormally"); - } - if (WEXITSTATUS(r) != 0) - errx(1, NETWORK_SCRIPT " returned error status %d", - WEXITSTATUS(r)); - - xc_handle = xc_interface_open(); - - listen_fd = start_listening(); - - evtchn_fd = open("/dev/xen/evtchn", O_RDWR); - if (evtchn_fd < 0) - err(1, "openning /dev/xen/evtchn"); - - dom0 = find_dom0(); - - while (1) { - get_and_process_event(); - - PRINTF(5, "Dom0 ring state:\n"); - PRINTF(5, "RX: req_prod %ld, resp_prod %ld, resp_cons %ld\n", - dom0->ctrl_if->rx_req_prod, - dom0->ctrl_if->rx_resp_prod, - dom0->rx_resp_cons); - PRINTF(5, "TX: req_prod %ld, resp_prod %ld, req_cons %ld\n", - dom0->ctrl_if->tx_req_prod, - dom0->ctrl_if->tx_resp_prod, - dom0->tx_req_cons); - } - - return 0; -} - diff --git a/tools/x2d2/minixend.h b/tools/x2d2/minixend.h deleted file mode 100644 index db28d48529..0000000000 --- a/tools/x2d2/minixend.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef MINIXEND_H__ -#define MINIXEND_H__ - -#include -#include - -struct list_head { - struct list_head *next, **pprev; -}; - -struct open_connection { - struct list_head connection_list; - int fd; - enum { - OC_STATE_CONNECTED, - OC_STATE_ERROR, - OC_STATE_COMMAND_PENDING - } state; - - /* Buffer of stuff coming from the remote until we get a whole - command */ - int buf_used; - int buf_allocated; - char *buf; -}; - -struct console_connection; - -/* Only ever accessed from the domain's controlling thread, unless - it's dom0, in which case we perform a moderately complex dance to - avoid needing any sort of locking at all. */ -struct domain { - struct list_head domain_list; - int control_evtchn; /* the local port for the doain control - interface event channel. */ - int domid; - char *name; - int mem_kb; - enum { - DOM_STATE_CREATED, /* created but not built */ - DOM_STATE_PAUSED, /* built but not started or paused */ - DOM_STATE_RUNNING, /* running normally */ - DOM_STATE_DEAD /* dead; either destroyed, crashed, - or exitted. */ - } state; - - unsigned long shared_info_mfn; - shared_info_t *shared_info; - control_if_t *ctrl_if; - CONTROL_RING_IDX tx_req_cons; - CONTROL_RING_IDX rx_resp_cons; - - unsigned created_netif_backend:1; - unsigned plugged:1; - unsigned event_pending:1; /* True if an event arrived while - the domain was plugged. */ - - struct console_connection *cc; - - char netif_mac[6]; - - /* Used for two purposes: waking up domain threads when - necessary, and synchronising access to dom0, which doesn't - have a domain thread. */ - pthread_mutex_t mux; - pthread_cond_t cond; - - pthread_t thread; -}; - -struct console_connection { - struct list_head list; - int fd; - struct domain *dom; - - enum { - CC_STATE_PENDING, - CC_STATE_CONNECTED, - CC_STATE_ERROR - } state; - - unsigned buf_allocated; - unsigned buf_used; - char *buf; - - unsigned in_buf_allocated; - unsigned in_buf_used; - char *in_buf; -}; - - -void *domain_thread_func(void *d); -void process_command(struct open_connection *oc); - -void *xmalloc(size_t s); -void *xrealloc(void *x, size_t s); -char *xstrdup(const char *s); - -int allocate_event_channel(struct domain *d, int event_ports[2]); -void *map_domain_mem(struct domain *d, unsigned long mfn); -void signal_domain(struct domain *d); -int our_system(const char *fmt, ...); - -extern unsigned xc_handle; -#define EVTCHN_BIND _IO('E', 2) -extern int evtchn_fd; - -#define list_item(head, type, field) \ -((type *)((unsigned)(head) - offsetof(type, field))) - -#define foreach_item(iter, head, type, field) \ -for ((iter) = list_item((head)->next, type, field); \ - (iter) != list_item((head), type, field); \ - (iter) = list_item((iter)->field.next, type, field)) - -#define list_insert_after(what, head) \ -do { \ - (what)->next = (head)->next; \ - (what)->pprev = &(head)->next; \ - (head)->next->pprev = &(what)->next; \ - (head)->next = what; \ -} while (0) - -#define list_remove(head) \ -(head)->next->pprev = (head)->pprev; \ -*(head)->pprev = (head)->next; - -#define list_foreach_safe(head, li, temp) \ -for ((li) = (head)->next, (temp) = (li)->next; \ - (li) != (head); \ - (li) = (temp), (temp) = (li)->next) - -#define LIST_HEAD(x) { (x), &(x)->next } - - -extern struct list_head head_domain; -extern struct list_head head_console; - -#define foreach_domain(d) \ -foreach_item(d, &head_domain, struct domain, domain_list) -#define foreach_console_connection(cc) \ -foreach_item(cc, &head_console, struct console_connection, list) - - -#define CURRENT_LOG_LEVEL 0 - -#define PRINTF(level, ...) \ -do { \ - if ((level) >= CURRENT_LOG_LEVEL) \ - printf(__VA_ARGS__); \ -} while (0) - - -#endif /* MINIXEND_H__ */ diff --git a/tools/x2d2/util.c b/tools/x2d2/util.c deleted file mode 100644 index 9994c7dfb8..0000000000 --- a/tools/x2d2/util.c +++ /dev/null @@ -1,132 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void * -xmalloc(size_t s) -{ - void *x; - - x = malloc(s); - if (x == NULL) - err(1, "allocating memory"); - memset(x, 0, s); - return x; -} - -void * -xrealloc(void *x, size_t s) -{ - void *y; - y = realloc(x, s); - if (y == NULL) - err(1, "allocating more memory"); - return y; -} - -char * -xstrdup(const char *s) -{ - char *x = strdup(s); - if (x == NULL) - err(1, "duplicating %s", s); - return x; -} - -/* Slightly less stupid implementation of system(). We return - negative iff there is an error executing the shell; otherwise, we - return the wait status as reported by waitpid(). Also, we support - printf-style escapes. We don't handle setting the SIGCHLD handler - to SIGIGN, though: in that case, we have a race. */ -int -our_system(const char *fmt, ...) -{ - char *cmd = NULL; - int r; - va_list ap; - pid_t child = -1; - int pip[2] = {-1, -1}; - int e; - fd_set fds; - struct timeval to; - int res; - pid_t c; - unsigned status; - - va_start(ap, fmt); - r = vasprintf(&cmd, fmt, ap); - va_end(ap); - if (r < 0) - return r; - r = pipe(pip); - if (r < 0) { - res = r; - goto out; - } - child = fork(); - if (child < 0) { - res = child; - goto out; - } - if (child == 0) { - close(pip[0]); - fcntl(pip[1], F_SETFD, 1); - r = execl("/bin/sh", "/bin/sh", "-c", cmd, NULL); - /* Uh oh, exec failed */ - write(pip[1], &r, sizeof(r)); - _exit(1); - } - - close(pip[1]); - pip[1] = -1; - - c = waitpid(child, &status, 0); - if (c < 0) { - res = c; - goto out; - } - assert(c == child); - child = -1; - - /* Check execl result */ - FD_ZERO(&fds); - FD_SET(pip[0], &fds); - memset(&to, 0, sizeof(to)); - r = select(pip[0]+1, &fds, NULL, NULL, &to); - if (r == 0) { - res = status; - } else { - assert(FD_ISSET(pip[0], &fds)); - r = read(pip[0], &res, sizeof(res)); - if (r != sizeof(res)) - res = status; - } - close(pip[0]); - pip[0] = -1; - - out: - e = errno; - if (child >= 0) { - /* Not obvious what the correct thing to do here is. */ - /* Don't want to kill the child; that will create a - zombie. */ -// kill(child, 9); - } - if (pip[0] >= 0) - close(pip[0]); - if (pip[1] >= 0) - close(pip[1]); - free(cmd); - errno = e; - return res; -}