Only in xen-unstable/docs: man1 Only in xen-unstable/docs: man5 Only in xen-unstable/docs: pdf Only in xen-unstable/docs: ps Only in xen-unstable/extras/mini-os/console: console.o Only in xen-unstable/extras/mini-os/console: xencons_ring.o Only in xen-unstable/extras/mini-os: events.o Only in xen-unstable/extras/mini-os: hypervisor.o Only in xen-unstable/extras/mini-os/include: xen diff -ur oxen-unstable/extras/mini-os/include/xenbus.h xen-unstable/extras/mini-os/include/xenbus.h --- oxen-unstable/extras/mini-os/include/xenbus.h 2006-06-02 01:03:40.000000000 -0400 +++ xen-unstable/extras/mini-os/include/xenbus.h 2006-06-03 17:01:49.000000000 -0400 @@ -1,6 +1,41 @@ #ifndef XENBUS_H__ #define XENBUS_H__ +/* Initialize the XenBus system. Must be called before thread + scheduling and the application is initialized. */ void init_xenbus(void); +/* Register a function that is called when the XenBus thread becomes + alive. Must be called after init_xenbus, but before thread + scheduling is initialized. The handler usually awakes an + application thread waiting for XenBus. */ +void register_xenbus_awoke_handler(void (*handler)(void)); + +/* Read the value associated with a path. Returns a malloc'd error + string on failure and sets *value to NULL. On success, *value is + set to a malloc'd copy of the value. */ +char *xenbus_read(const char *path, char **value); + +/* Associates a value with a path. Returns a malloc'd error string on + failure. */ +char *xenbus_write(const char *path, const char *value); + +/* Removes the value associated with a path. Returns a malloc'd error + string on failure. */ +char *xenbus_rm(const char *path); + +/* List the contents of a directory. Returns a malloc'd error string + on failure and sets *contents to NULL. On success, *contents is + set to a malloc'd array of pointers to malloc'd strings. The array + is NULL terminated. May block. */ +char *xenbus_ls(const char *prefix, char ***contents); + +/* Reads permissions associated with a path. Returns a malloc'd error + string on failure and sets *value to NULL. On success, *value is + set to a malloc'd copy of the value. */ +char *xenbus_get_perms(const char *path, char **value); + +/* Sets the permissions associated with a path. Returns a malloc'd + error string on failure. */ +char *xenbus_set_perms(const char *path, domid_t dom, char perm); #endif /* XENBUS_H__ */ Only in xen-unstable/extras/mini-os/include: xenbus.h~ diff -ur oxen-unstable/extras/mini-os/kernel.c xen-unstable/extras/mini-os/kernel.c --- oxen-unstable/extras/mini-os/kernel.c 2006-06-02 01:03:40.000000000 -0400 +++ xen-unstable/extras/mini-os/kernel.c 2006-06-03 09:22:00.000000000 -0400 @@ -82,17 +82,6 @@ } -void test_xenbus(void); - -/* Do initialisation from a thread once the scheduler's available */ -static void init_xs(void *ign) -{ - init_xenbus(); - - test_xenbus(); -} - - u8 xen_features[XENFEAT_NR_SUBMAPS * 32]; void setup_xen_features(void) @@ -111,10 +100,13 @@ } } +void test_xenbus(void); + /* This should be overridden by the application we are linked against. */ __attribute__((weak)) int app_main(start_info_t *si) { printk("Dummy main: start_info=%p\n", si); + test_xenbus(); return 0; } @@ -183,11 +175,14 @@ /* Init scheduler. */ init_sched(); - /* Init XenBus from a separate thread */ - create_thread("init_xs", init_xs, NULL); + /* Init XenBus */ + init_xenbus(); /* Call (possibly overridden) app_main() */ - app_main(&start_info); + if (app_main(&start_info)) { + printk("Application failed to initialize\n"); + do_exit(); + } /* Everything initialised, start idle thread */ run_idle_thread(); Only in xen-unstable/extras/mini-os: kernel.o Only in xen-unstable/extras/mini-os/lib: math.o Only in xen-unstable/extras/mini-os/lib: printf.o Only in xen-unstable/extras/mini-os/lib: string.o Only in xen-unstable/extras/mini-os/lib: xmalloc.o Only in xen-unstable/extras/mini-os: libminios.a Only in xen-unstable/extras/mini-os: mini-os.elf Only in xen-unstable/extras/mini-os: mini-os.gz Only in xen-unstable/extras/mini-os: mm.o Only in xen-unstable/extras/mini-os: sched.o Only in xen-unstable/extras/mini-os: time.o Only in xen-unstable/extras/mini-os: traps.o Only in xen-unstable/extras/mini-os: x86_32.o diff -ur oxen-unstable/extras/mini-os/xenbus/xenbus.c xen-unstable/extras/mini-os/xenbus/xenbus.c --- oxen-unstable/extras/mini-os/xenbus/xenbus.c 2006-06-02 01:03:40.000000000 -0400 +++ xen-unstable/extras/mini-os/xenbus/xenbus.c 2006-06-04 11:24:12.000000000 -0400 @@ -3,11 +3,11 @@ * (C) 2006 - Cambridge University **************************************************************************** * - * File: mm.c + * File: xenbus.c * Author: Steven Smith (sos22@xxxxxxxxx) * Changes: Grzegorz Milos (gm281@xxxxxxxxx) * - * Date: Mar 2006, chages Aug 2005 + * Date: Jun 2006, chages Aug 2005 * * Environment: Xen Minimal OS * Description: Minimal implementation of xenbus @@ -71,11 +71,20 @@ memcpy(dest + c1, ring, c2); } +static void (*xenbus_awoke_handler)(void) = NULL; + +void register_xenbus_awoke_handler(void (*handler)(void)) +{ + xenbus_awoke_handler = handler; +} + static void xenbus_thread_func(void *ign) { struct xsd_sockmsg msg; unsigned prod; + if (xenbus_awoke_handler) + xenbus_awoke_handler(); for (;;) { wait_event(xb_waitq, prod != xenstore_buf->rsp_prod); @@ -167,8 +176,10 @@ void init_xenbus(void) { int err; + printk("Initialising xenbus\n"); DEBUG("init_xenbus called.\n"); xenstore_buf = mfn_to_virt(start_info.store_mfn); + xenbus_awoke_handler = NULL; create_thread("xenstore", xenbus_thread_func, NULL); DEBUG("buf at %p.\n", xenstore_buf); err = bind_evtchn(start_info.store_evtchn, @@ -262,15 +273,15 @@ /* Send a mesasge to xenbus, in the same fashion as xb_write, and block waiting for a reply. The reply is malloced and should be freed by the caller. */ -static void *xenbus_msg_reply(int type, +static struct xsd_sockmsg * +xenbus_msg_reply(int type, int trans, struct write_req *io, int nr_reqs) { int id; DEFINE_WAIT(w); - void *rep; - struct xsd_sockmsg *repmsg; + struct xsd_sockmsg *rep; id = allocate_xenbus_id(); add_waiter(w, req_info[id].waitq); @@ -281,13 +292,27 @@ wake(current); rep = req_info[id].reply; - repmsg = rep; - BUG_ON(repmsg->req_id != id); + BUG_ON(rep->req_id != id); release_xenbus_id(id); - return rep; } +static char *errmsg(struct xsd_sockmsg *rep) +{ + if (!rep) { + char msg[] = "No reply"; + size_t len = strlen(msg) + 1; + return memcpy(malloc(len), msg, len); + } + if (rep->type != XS_ERROR) + return NULL; + char *res = malloc(rep->len + 1); + memcpy(res, rep + 1, rep->len); + res[rep->len] = 0; + free(rep); + return res; +} + /* Send a debug message to xenbus. Can block. */ static void xenbus_debug_msg(const char *msg) { @@ -296,27 +321,29 @@ { "print", sizeof("print") }, { msg, len }, { "", 1 }}; - void *reply; - struct xsd_sockmsg *repmsg; + struct xsd_sockmsg *reply; - reply = xenbus_msg_reply(XS_DEBUG, 0, req, 3); - repmsg = reply; + reply = xenbus_msg_reply(XS_DEBUG, 0, req, ARRAY_SIZE(req)); DEBUG("Got a reply, type %d, id %d, len %d.\n", - repmsg->type, repmsg->req_id, repmsg->len); + reply->type, reply->req_id, reply->len); } /* List the contents of a directory. Returns a malloc()ed array of pointers to malloc()ed strings. The array is NULL terminated. May block. */ -static char **xenbus_ls(const char *pre) +char *xenbus_ls(const char *pre, char ***contents) { - void *reply; - struct xsd_sockmsg *repmsg; + struct xsd_sockmsg *reply, *repmsg; struct write_req req[] = { { pre, strlen(pre)+1 } }; int nr_elems, x, i; char **res; - repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, 1); + repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, ARRAY_SIZE(req)); + char *msg = errmsg(repmsg); + if (msg) { + *contents = NULL; + return msg; + } reply = repmsg + 1; for (x = nr_elems = 0; x < repmsg->len; x++) nr_elems += (((char *)reply)[x] == 0); @@ -329,20 +356,91 @@ } res[i] = NULL; free(repmsg); - return res; + *contents = res; + return NULL; } -static char *xenbus_read(const char *path) +char *xenbus_read(const char *path, char **value) { - struct write_req req[] = { {path, strlen(path) + 1}}; + struct write_req req[] = { {path, strlen(path) + 1} }; struct xsd_sockmsg *rep; char *res; - rep = xenbus_msg_reply(XS_READ, 0, req, 1); + rep = xenbus_msg_reply(XS_READ, 0, req, ARRAY_SIZE(req)); + char *msg = errmsg(rep); + if (msg) { + *value = NULL; + return msg; + } res = malloc(rep->len + 1); memcpy(res, rep + 1, rep->len); res[rep->len] = 0; free(rep); - return res; + *value = res; + return NULL; +} + +char *xenbus_write(const char *path, const char *value) +{ + struct write_req req[] = { + {path, strlen(path) + 1}, + {value, strlen(value) + 1}, + }; + struct xsd_sockmsg *rep; + rep = xenbus_msg_reply(XS_WRITE, 0, req, ARRAY_SIZE(req)); + char *msg = errmsg(rep); + if (msg) + return msg; + free(rep); + return NULL; +} + +char *xenbus_rm(const char *path) +{ + struct write_req req[] = { {path, strlen(path) + 1} }; + struct xsd_sockmsg *rep; + rep = xenbus_msg_reply(XS_RM, 0, req, ARRAY_SIZE(req)); + char *msg = errmsg(rep); + if (msg) + return msg; + free(rep); + return NULL; +} + +char *xenbus_get_perms(const char *path, char **value) +{ + struct write_req req[] = { {path, strlen(path) + 1} }; + struct xsd_sockmsg *rep; + char *res; + rep = xenbus_msg_reply(XS_GET_PERMS, 0, req, ARRAY_SIZE(req)); + char *msg = errmsg(rep); + if (msg) { + *value = NULL; + return msg; + } + res = malloc(rep->len + 1); + memcpy(res, rep + 1, rep->len); + res[rep->len] = 0; + free(rep); + *value = res; + return NULL; +} + +#define PERM_MAX_SIZE 32 +char *xenbus_set_perms(const char *path, domid_t dom, char perm) +{ + char value[PERM_MAX_SIZE]; + snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom); + struct write_req req[] = { + {path, strlen(path) + 1}, + {value, strlen(value) + 1}, + }; + struct xsd_sockmsg *rep; + rep = xenbus_msg_reply(XS_SET_PERMS, 0, req, ARRAY_SIZE(req)); + char *msg = errmsg(rep); + if (msg) + return msg; + free(rep); + return NULL; } static void do_ls_test(const char *pre) @@ -351,7 +449,12 @@ int x; DEBUG("ls %s...\n", pre); - dirs = xenbus_ls(pre); + char *msg = xenbus_ls(pre, &dirs); + if (msg) { + printk("Error in xenbus ls: %s\n", msg); + free(msg); + return; + } for (x = 0; dirs[x]; x++) { DEBUG("ls %s[%d] -> %s\n", pre, x, dirs[x]); @@ -364,13 +467,18 @@ { char *res; DEBUG("Read %s...\n", path); - res = xenbus_read(path); + char *msg = xenbus_read(path, &res); + if (msg) { + printk("Error in xenbus read: %s\n", msg); + free(msg); + return; + } DEBUG("Read %s -> %s.\n", path, res); free(res); } /* Simple testing thing */ -void test_xenbus(void) +static void do_xenbus_test(void *ign) { DEBUG("Doing xenbus test.\n"); xenbus_debug_msg("Testing xenbus...\n"); @@ -383,5 +491,27 @@ DEBUG("Doing read test.\n"); do_read_test("device/vif/0/mac"); do_read_test("device/vif/0/backend"); - printk("Xenbus initialised.\n"); } + +static struct thread *test_thread; + +static void xenbus_awoke(void) +{ + if (test_thread) + wake(test_thread); +} + +/* Simple testing thing */ +void test_xenbus(void) +{ + test_thread = create_thread("xenbus tester", do_xenbus_test, NULL); + block(test_thread); + register_xenbus_awoke_handler(xenbus_awoke); +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ Only in xen-unstable/extras/mini-os/xenbus: xenbus.c~ Only in xen-unstable/extras/mini-os/xenbus: xenbus.o Only in xen-unstable/patches/linux-2.6.16.13: .makedep Only in xen-unstable/xen/include/xen: banner.h.new Only in xen-unstable/xen/tools/figlet: figlet Only in xen-unstable/xen/tools: symbols