# HG changeset patch # User Ian Campbell # Date 1207658376 -3600 # Node ID 40310b53f5d0a456f12302aa07b592fd27736cb5 # Parent af1d20b86b02bf463690e8af61e77ddf169c4c6c xenstore: support building the xenstore clients statically. This removes threading from libxenstore.a (but not libxenstore.so) since pthreads is incompatible with static linking and none of the command line clients require threads anyway. This also disables watch support in the static library. It is now possible to build these utilities statically with a uclibc toolchain which is useful for small userspace utility domains. Signed-off-by: Ian Campbell diff -r af1d20b86b02 -r 40310b53f5d0 tools/xenstore/Makefile --- a/tools/xenstore/Makefile Tue Apr 08 09:57:37 2008 +0100 +++ b/tools/xenstore/Makefile Tue Apr 08 13:39:36 2008 +0100 @@ -24,8 +24,18 @@ XENSTORED_OBJS_$(CONFIG_NetBSD) = xensto XENSTORED_OBJS += $(XENSTORED_OBJS_y) +ifneq ($(XENSTORE_STATIC_CLIENTS),y) +LIBXENSTORE := libxenstore.so +else +LIBXENSTORE := libxenstore.a +$(CLIENTS) xenstore-control xenstore-ls: CFLAGS += -static +endif + .PHONY: all -all: libxenstore.so libxenstore.a xenstored $(CLIENTS) xs_tdb_dump xenstore-control xenstore-ls +all: libxenstore.so libxenstore.a xenstored clients xs_tdb_dump + +.PHONY: clients +clients: $(CLIENTS) xenstore-control xenstore-ls ifeq ($(CONFIG_SunOS),y) xenstored_probes.h: xenstored_probes.d @@ -42,16 +52,16 @@ xenstored: $(XENSTORED_OBJS) xenstored: $(XENSTORED_OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDFLAGS_libxenctrl) $(SOCKET_LIBS) -o $@ -$(CLIENTS): xenstore-%: xenstore_%.o libxenstore.so +$(CLIENTS): xenstore-%: xenstore_%.o $(LIBXENSTORE) $(CC) $(CFLAGS) $(LDFLAGS) $< -L. -lxenstore $(SOCKET_LIBS) -o $@ $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c $(COMPILE.c) -DCLIENT_$(*F) -o $@ $< -xenstore-control: xenstore_control.o libxenstore.so +xenstore-control: xenstore_control.o $(LIBXENSTORE) $(CC) $(CFLAGS) $(LDFLAGS) $< -L. -lxenstore $(SOCKET_LIBS) -o $@ -xenstore-ls: xsls.o libxenstore.so +xenstore-ls: xsls.o $(LIBXENSTORE) $(CC) $(CFLAGS) $(LDFLAGS) $< -L. -lxenstore $(SOCKET_LIBS) -o $@ xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o @@ -61,6 +71,8 @@ libxenstore.so: libxenstore.so.$(MAJOR) ln -sf $< $@ libxenstore.so.$(MAJOR): libxenstore.so.$(MAJOR).$(MINOR) ln -sf $< $@ + +xs.opic: CFLAGS += -DUSE_PTHREAD libxenstore.so.$(MAJOR).$(MINOR): xs.opic xs_lib.opic $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenstore.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ $(SOCKET_LIBS) -lpthread diff -r af1d20b86b02 -r 40310b53f5d0 tools/xenstore/xs.c --- a/tools/xenstore/xs.c Tue Apr 08 09:57:37 2008 +0100 +++ b/tools/xenstore/xs.c Tue Apr 08 13:39:36 2008 +0100 @@ -32,7 +32,9 @@ #include #include #include +#ifdef USE_PTHREAD #include +#endif #include "xs.h" #include "list.h" #include "utils.h" @@ -43,6 +45,7 @@ struct xs_stored_msg { char *body; }; +#ifdef USE_PTHREAD struct xs_handle { /* Communications channel to xenstore daemon. */ int fd; @@ -78,14 +81,61 @@ struct xs_handle { pthread_mutex_t request_mutex; }; +static void watch_mutex_lock(struct xs_handle *h) +{ + pthread_mutex_lock(&h->watch_mutex); +} + +static void watch_mutex_unlock(struct xs_handle *h) +{ + pthread_mutex_unlock(&h->watch_mutex); +} + +static void request_mutex_lock(struct xs_handle *h) +{ + pthread_mutex_lock(&h->request_mutex); +} + +static void request_mutex_unlock(struct xs_handle *h) +{ + pthread_mutex_unlock(&h->request_mutex); +} + +static void reply_mutex_lock(struct xs_handle *h) +{ + pthread_mutex_lock(&h->reply_mutex); +} + +static void reply_mutex_unlock(struct xs_handle *h) +{ + pthread_mutex_unlock(&h->reply_mutex); +} + +static void *read_thread(void *arg); + +#else /*!USE_PTHREAD*/ + +struct xs_handle { + int fd; + struct list_head reply_list; +}; + +static void request_mutex_lock(struct xs_handle *h) {} +static void request_mutex_unlock(struct xs_handle *h) {} + +static void reply_mutex_lock(struct xs_handle *h) {} +static void reply_mutex_unlock(struct xs_handle *h) {} + +#endif + static int read_message(struct xs_handle *h); -static void *read_thread(void *arg); - + +#ifdef USE_PTHREAD int xs_fileno(struct xs_handle *h) { char c = 0; - pthread_mutex_lock(&h->watch_mutex); + watch_mutex_lock(h); if ((h->watch_pipe[0] == -1) && (pipe(h->watch_pipe) != -1)) { /* Kick things off if the watch list is already non-empty. */ @@ -94,10 +144,11 @@ int xs_fileno(struct xs_handle *h) continue; } - pthread_mutex_unlock(&h->watch_mutex); + watch_mutex_unlock(h); return h->watch_pipe[0]; } +#endif static int get_socket(const char *connect_to) { @@ -163,6 +214,9 @@ static struct xs_handle *get_handle(cons h->fd = fd; + INIT_LIST_HEAD(&h->reply_list); + +#ifdef USE_PTHREAD /* Watch pipe is allocated on demand in xs_fileno(). */ h->watch_pipe[0] = h->watch_pipe[1] = -1; @@ -170,11 +224,11 @@ static struct xs_handle *get_handle(cons pthread_mutex_init(&h->watch_mutex, NULL); pthread_cond_init(&h->watch_condvar, NULL); - INIT_LIST_HEAD(&h->reply_list); pthread_mutex_init(&h->reply_mutex, NULL); pthread_cond_init(&h->reply_condvar, NULL); pthread_mutex_init(&h->request_mutex, NULL); +#endif return h; } @@ -198,34 +252,38 @@ void xs_daemon_close(struct xs_handle *h { struct xs_stored_msg *msg, *tmsg; - pthread_mutex_lock(&h->request_mutex); - pthread_mutex_lock(&h->reply_mutex); - pthread_mutex_lock(&h->watch_mutex); +#ifdef USE_PTHREAD + request_mutex_lock(h); + reply_mutex_lock(h); + watch_mutex_lock(h); if (h->read_thr_exists) { /* XXX FIXME: May leak an unpublished message buffer. */ pthread_cancel(h->read_thr); pthread_join(h->read_thr, NULL); } +#endif list_for_each_entry_safe(msg, tmsg, &h->reply_list, list) { free(msg->body); free(msg); } +#ifdef USE_PTHREAD list_for_each_entry_safe(msg, tmsg, &h->watch_list, list) { free(msg->body); free(msg); } - pthread_mutex_unlock(&h->request_mutex); - pthread_mutex_unlock(&h->reply_mutex); - pthread_mutex_unlock(&h->watch_mutex); + request_mutex_unlock(h); + reply_mutex_unlock(h); + watch_mutex_unlock(h); if (h->watch_pipe[0] != -1) { close(h->watch_pipe[0]); close(h->watch_pipe[1]); } +#endif close(h->fd); @@ -277,17 +335,24 @@ static void *read_reply( struct xs_stored_msg *msg; char *body; +#ifdef USE_PTHREAD /* Read from comms channel ourselves if there is no reader thread. */ if (!h->read_thr_exists && (read_message(h) == -1)) return NULL; - - pthread_mutex_lock(&h->reply_mutex); +#endif + + reply_mutex_lock(h); +#ifdef USE_PTHREAD while (list_empty(&h->reply_list)) pthread_cond_wait(&h->reply_condvar, &h->reply_mutex); +#else + while (list_empty(&h->reply_list)) + read_message(h); +#endif msg = list_top(&h->reply_list, struct xs_stored_msg, list); list_del(&msg->list); assert(list_empty(&h->reply_list)); - pthread_mutex_unlock(&h->reply_mutex); + reply_mutex_unlock(h); *type = msg->hdr.type; if (len) @@ -329,7 +394,7 @@ static void *xs_talkv(struct xs_handle * ignorepipe.sa_flags = 0; sigaction(SIGPIPE, &ignorepipe, &oldact); - pthread_mutex_lock(&h->request_mutex); + request_mutex_lock(h); if (!xs_write_all(h->fd, &msg, sizeof(msg))) goto fail; @@ -342,7 +407,7 @@ static void *xs_talkv(struct xs_handle * if (!ret) goto fail; - pthread_mutex_unlock(&h->request_mutex); + request_mutex_unlock(h); sigaction(SIGPIPE, &oldact, NULL); if (msg.type == XS_ERROR) { @@ -362,7 +427,7 @@ fail: fail: /* We're in a bad state, so close fd. */ saved_errno = errno; - pthread_mutex_unlock(&h->request_mutex); + request_mutex_unlock(h); sigaction(SIGPIPE, &oldact, NULL); close_fd: close(h->fd); @@ -547,6 +612,7 @@ unwind: return false; } +#ifdef USE_PTHREAD /* Watch a node for changes (poll on fd to detect, or call read_watch()). * When the node (or any child) changes, fd will become readable. * Token is returned when watch is read, to allow matching. @@ -557,15 +623,15 @@ bool xs_watch(struct xs_handle *h, const struct iovec iov[2]; /* We dynamically create a reader thread on demand. */ - pthread_mutex_lock(&h->request_mutex); + request_mutex_lock(h); if (!h->read_thr_exists) { if (pthread_create(&h->read_thr, NULL, read_thread, h) != 0) { - pthread_mutex_unlock(&h->request_mutex); + request_mutex_unlock(h); return false; } h->read_thr_exists = 1; } - pthread_mutex_unlock(&h->request_mutex); + request_mutex_unlock(h); iov[0].iov_base = (void *)path; iov[0].iov_len = strlen(path) + 1; @@ -586,7 +652,7 @@ char **xs_read_watch(struct xs_handle *h char **ret, *strings, c = 0; unsigned int num_strings, i; - pthread_mutex_lock(&h->watch_mutex); + watch_mutex_lock(h); /* Wait on the condition variable for a watch to fire. */ while (list_empty(&h->watch_list)) @@ -599,7 +665,7 @@ char **xs_read_watch(struct xs_handle *h while (read(h->watch_pipe[0], &c, 1) != 1) continue; - pthread_mutex_unlock(&h->watch_mutex); + watch_mutex_unlock(h); assert(msg->hdr.type == XS_WATCH_EVENT); @@ -642,6 +708,7 @@ bool xs_unwatch(struct xs_handle *h, con return xs_bool(xs_talkv(h, XBT_NULL, XS_UNWATCH, iov, ARRAY_SIZE(iov), NULL)); } +#endif /* Start a transaction: changes by others will not be seen during this * transaction, and changes will not be visible to others until end. @@ -801,7 +868,8 @@ static int read_message(struct xs_handle body[msg->hdr.len] = '\0'; if (msg->hdr.type == XS_WATCH_EVENT) { - pthread_mutex_lock(&h->watch_mutex); +#ifdef USE_PTHREAD + watch_mutex_lock(h); /* Kick users out of their select() loop. */ if (list_empty(&h->watch_list) && @@ -812,20 +880,27 @@ static int read_message(struct xs_handle list_add_tail(&msg->list, &h->watch_list); pthread_cond_signal(&h->watch_condvar); - pthread_mutex_unlock(&h->watch_mutex); + watch_mutex_unlock(h); +#else + /* Cannot handle this event, but should never have been registered. */ + errno = -EIO; + goto error; +#endif } else { - pthread_mutex_lock(&h->reply_mutex); + reply_mutex_lock(h); /* There should only ever be one response pending! */ if (!list_empty(&h->reply_list)) { - pthread_mutex_unlock(&h->reply_mutex); + reply_mutex_unlock(h); goto error; } list_add_tail(&msg->list, &h->reply_list); +#ifdef USE_PTHREAD pthread_cond_signal(&h->reply_condvar); - - pthread_mutex_unlock(&h->reply_mutex); +#endif + + reply_mutex_unlock(h); } return 0; @@ -838,6 +913,7 @@ static int read_message(struct xs_handle return -1; } +#ifdef USE_PTHREAD static void *read_thread(void *arg) { struct xs_handle *h = arg; @@ -847,6 +923,7 @@ static void *read_thread(void *arg) return NULL; } +#endif /* * Local variables: