ia64/xen-unstable

changeset 17407:32e3c81ada56

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.

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 <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Apr 09 13:27:33 2008 +0100 (2008-04-09)
parents 9b635405ef90
children 7259de99f7fd
files tools/xenstore/Makefile tools/xenstore/xs.c
line diff
     1.1 --- a/tools/xenstore/Makefile	Wed Apr 09 11:30:32 2008 +0100
     1.2 +++ b/tools/xenstore/Makefile	Wed Apr 09 13:27:33 2008 +0100
     1.3 @@ -24,8 +24,18 @@ XENSTORED_OBJS_$(CONFIG_NetBSD) = xensto
     1.4  
     1.5  XENSTORED_OBJS += $(XENSTORED_OBJS_y)
     1.6  
     1.7 +ifneq ($(XENSTORE_STATIC_CLIENTS),y)
     1.8 +LIBXENSTORE := libxenstore.so
     1.9 +else
    1.10 +LIBXENSTORE := libxenstore.a
    1.11 +$(CLIENTS) xenstore-control xenstore-ls: CFLAGS += -static
    1.12 +endif
    1.13 +
    1.14  .PHONY: all
    1.15 -all: libxenstore.so libxenstore.a xenstored $(CLIENTS) xs_tdb_dump xenstore-control xenstore-ls
    1.16 +all: libxenstore.so libxenstore.a xenstored clients xs_tdb_dump 
    1.17 +
    1.18 +.PHONY: clients
    1.19 +clients: $(CLIENTS) xenstore-control xenstore-ls
    1.20  
    1.21  ifeq ($(CONFIG_SunOS),y)
    1.22  xenstored_probes.h: xenstored_probes.d
    1.23 @@ -42,16 +52,16 @@ endif
    1.24  xenstored: $(XENSTORED_OBJS)
    1.25  	$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDFLAGS_libxenctrl) $(SOCKET_LIBS) -o $@
    1.26  
    1.27 -$(CLIENTS): xenstore-%: xenstore_%.o libxenstore.so
    1.28 +$(CLIENTS): xenstore-%: xenstore_%.o $(LIBXENSTORE)
    1.29  	$(CC) $(CFLAGS) $(LDFLAGS) $< -L. -lxenstore $(SOCKET_LIBS) -o $@
    1.30  
    1.31  $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
    1.32  	$(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
    1.33  
    1.34 -xenstore-control: xenstore_control.o libxenstore.so
    1.35 +xenstore-control: xenstore_control.o $(LIBXENSTORE)
    1.36  	$(CC) $(CFLAGS) $(LDFLAGS) $< -L. -lxenstore $(SOCKET_LIBS) -o $@
    1.37  
    1.38 -xenstore-ls: xsls.o libxenstore.so
    1.39 +xenstore-ls: xsls.o $(LIBXENSTORE)
    1.40  	$(CC) $(CFLAGS) $(LDFLAGS) $< -L. -lxenstore $(SOCKET_LIBS) -o $@
    1.41  
    1.42  xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o
    1.43 @@ -62,6 +72,8 @@ libxenstore.so: libxenstore.so.$(MAJOR)
    1.44  libxenstore.so.$(MAJOR): libxenstore.so.$(MAJOR).$(MINOR)
    1.45  	ln -sf $< $@
    1.46  
    1.47 +xs.opic: CFLAGS += -DUSE_PTHREAD
    1.48 +
    1.49  libxenstore.so.$(MAJOR).$(MINOR): xs.opic xs_lib.opic
    1.50  	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenstore.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ $(SOCKET_LIBS) -lpthread
    1.51  
     2.1 --- a/tools/xenstore/xs.c	Wed Apr 09 11:30:32 2008 +0100
     2.2 +++ b/tools/xenstore/xs.c	Wed Apr 09 13:27:33 2008 +0100
     2.3 @@ -32,7 +32,6 @@
     2.4  #include <signal.h>
     2.5  #include <stdint.h>
     2.6  #include <errno.h>
     2.7 -#include <pthread.h>
     2.8  #include "xs.h"
     2.9  #include "list.h"
    2.10  #include "utils.h"
    2.11 @@ -43,6 +42,10 @@ struct xs_stored_msg {
    2.12  	char *body;
    2.13  };
    2.14  
    2.15 +#ifdef USE_PTHREAD
    2.16 +
    2.17 +#include <pthread.h>
    2.18 +
    2.19  struct xs_handle {
    2.20  	/* Communications channel to xenstore daemon. */
    2.21  	int fd;
    2.22 @@ -78,14 +81,37 @@ struct xs_handle {
    2.23  	pthread_mutex_t request_mutex;
    2.24  };
    2.25  
    2.26 +#define mutex_lock(m)		pthread_mutex_lock(m)
    2.27 +#define mutex_unlock(m)		pthread_mutex_unlock(m)
    2.28 +#define condvar_signal(c)	pthread_cond_signal(c)
    2.29 +#define condvar_wait(c,m,hnd)	pthread_cond_wait(c,m)
    2.30 +
    2.31 +static void *read_thread(void *arg);
    2.32 +
    2.33 +#else /* !defined(USE_PTHREAD) */
    2.34 +
    2.35 +struct xs_handle {
    2.36 +	int fd;
    2.37 +	struct list_head reply_list;
    2.38 +	struct list_head watch_list;
    2.39 +	/* Clients can select() on this pipe to wait for a watch to fire. */
    2.40 +	int watch_pipe[2];
    2.41 +};
    2.42 +
    2.43 +#define mutex_lock(m)		((void)0)
    2.44 +#define mutex_unlock(m)		((void)0)
    2.45 +#define condvar_signal(c)	((void)0)
    2.46 +#define condvar_wait(c,m,hnd)	read_message(hnd)
    2.47 +
    2.48 +#endif
    2.49 +
    2.50  static int read_message(struct xs_handle *h);
    2.51 -static void *read_thread(void *arg);
    2.52  
    2.53  int xs_fileno(struct xs_handle *h)
    2.54  {
    2.55  	char c = 0;
    2.56  
    2.57 -	pthread_mutex_lock(&h->watch_mutex);
    2.58 +	mutex_lock(&h->watch_mutex);
    2.59  
    2.60  	if ((h->watch_pipe[0] == -1) && (pipe(h->watch_pipe) != -1)) {
    2.61  		/* Kick things off if the watch list is already non-empty. */
    2.62 @@ -94,7 +120,7 @@ int xs_fileno(struct xs_handle *h)
    2.63  				continue;
    2.64  	}
    2.65  
    2.66 -	pthread_mutex_unlock(&h->watch_mutex);
    2.67 +	mutex_unlock(&h->watch_mutex);
    2.68  
    2.69  	return h->watch_pipe[0];
    2.70  }
    2.71 @@ -163,18 +189,21 @@ static struct xs_handle *get_handle(cons
    2.72  
    2.73  	h->fd = fd;
    2.74  
    2.75 +	INIT_LIST_HEAD(&h->reply_list);
    2.76 +	INIT_LIST_HEAD(&h->watch_list);
    2.77 +
    2.78  	/* Watch pipe is allocated on demand in xs_fileno(). */
    2.79  	h->watch_pipe[0] = h->watch_pipe[1] = -1;
    2.80  
    2.81 -	INIT_LIST_HEAD(&h->watch_list);
    2.82 +#ifdef USE_PTHREAD
    2.83  	pthread_mutex_init(&h->watch_mutex, NULL);
    2.84  	pthread_cond_init(&h->watch_condvar, NULL);
    2.85  
    2.86 -	INIT_LIST_HEAD(&h->reply_list);
    2.87  	pthread_mutex_init(&h->reply_mutex, NULL);
    2.88  	pthread_cond_init(&h->reply_condvar, NULL);
    2.89  
    2.90  	pthread_mutex_init(&h->request_mutex, NULL);
    2.91 +#endif
    2.92  
    2.93  	return h;
    2.94  }
    2.95 @@ -198,15 +227,17 @@ void xs_daemon_close(struct xs_handle *h
    2.96  {
    2.97  	struct xs_stored_msg *msg, *tmsg;
    2.98  
    2.99 -	pthread_mutex_lock(&h->request_mutex);
   2.100 -	pthread_mutex_lock(&h->reply_mutex);
   2.101 -	pthread_mutex_lock(&h->watch_mutex);
   2.102 +	mutex_lock(&h->request_mutex);
   2.103 +	mutex_lock(&h->reply_mutex);
   2.104 +	mutex_lock(&h->watch_mutex);
   2.105  
   2.106 +#ifdef USE_PTHREAD
   2.107  	if (h->read_thr_exists) {
   2.108  		/* XXX FIXME: May leak an unpublished message buffer. */
   2.109  		pthread_cancel(h->read_thr);
   2.110  		pthread_join(h->read_thr, NULL);
   2.111  	}
   2.112 +#endif
   2.113  
   2.114  	list_for_each_entry_safe(msg, tmsg, &h->reply_list, list) {
   2.115  		free(msg->body);
   2.116 @@ -218,9 +249,9 @@ void xs_daemon_close(struct xs_handle *h
   2.117  		free(msg);
   2.118  	}
   2.119  
   2.120 -	pthread_mutex_unlock(&h->request_mutex);
   2.121 -	pthread_mutex_unlock(&h->reply_mutex);
   2.122 -	pthread_mutex_unlock(&h->watch_mutex);
   2.123 +	mutex_unlock(&h->request_mutex);
   2.124 +	mutex_unlock(&h->reply_mutex);
   2.125 +	mutex_unlock(&h->watch_mutex);
   2.126  
   2.127  	if (h->watch_pipe[0] != -1) {
   2.128  		close(h->watch_pipe[0]);
   2.129 @@ -277,17 +308,19 @@ static void *read_reply(
   2.130  	struct xs_stored_msg *msg;
   2.131  	char *body;
   2.132  
   2.133 +#ifdef USE_PTHREAD
   2.134  	/* Read from comms channel ourselves if there is no reader thread. */
   2.135  	if (!h->read_thr_exists && (read_message(h) == -1))
   2.136  		return NULL;
   2.137 +#endif
   2.138  
   2.139 -	pthread_mutex_lock(&h->reply_mutex);
   2.140 +	mutex_lock(&h->reply_mutex);
   2.141  	while (list_empty(&h->reply_list))
   2.142 -		pthread_cond_wait(&h->reply_condvar, &h->reply_mutex);
   2.143 +		condvar_wait(&h->reply_condvar, &h->reply_mutex, h);
   2.144  	msg = list_top(&h->reply_list, struct xs_stored_msg, list);
   2.145  	list_del(&msg->list);
   2.146  	assert(list_empty(&h->reply_list));
   2.147 -	pthread_mutex_unlock(&h->reply_mutex);
   2.148 +	mutex_unlock(&h->reply_mutex);
   2.149  
   2.150  	*type = msg->hdr.type;
   2.151  	if (len)
   2.152 @@ -329,7 +362,7 @@ static void *xs_talkv(struct xs_handle *
   2.153  	ignorepipe.sa_flags = 0;
   2.154  	sigaction(SIGPIPE, &ignorepipe, &oldact);
   2.155  
   2.156 -	pthread_mutex_lock(&h->request_mutex);
   2.157 +	mutex_lock(&h->request_mutex);
   2.158  
   2.159  	if (!xs_write_all(h->fd, &msg, sizeof(msg)))
   2.160  		goto fail;
   2.161 @@ -342,7 +375,7 @@ static void *xs_talkv(struct xs_handle *
   2.162  	if (!ret)
   2.163  		goto fail;
   2.164  
   2.165 -	pthread_mutex_unlock(&h->request_mutex);
   2.166 +	mutex_unlock(&h->request_mutex);
   2.167  
   2.168  	sigaction(SIGPIPE, &oldact, NULL);
   2.169  	if (msg.type == XS_ERROR) {
   2.170 @@ -362,7 +395,7 @@ static void *xs_talkv(struct xs_handle *
   2.171  fail:
   2.172  	/* We're in a bad state, so close fd. */
   2.173  	saved_errno = errno;
   2.174 -	pthread_mutex_unlock(&h->request_mutex);
   2.175 +	mutex_unlock(&h->request_mutex);
   2.176  	sigaction(SIGPIPE, &oldact, NULL);
   2.177  close_fd:
   2.178  	close(h->fd);
   2.179 @@ -556,16 +589,18 @@ bool xs_watch(struct xs_handle *h, const
   2.180  {
   2.181  	struct iovec iov[2];
   2.182  
   2.183 +#ifdef USE_PTHREAD
   2.184  	/* We dynamically create a reader thread on demand. */
   2.185 -	pthread_mutex_lock(&h->request_mutex);
   2.186 +	mutex_lock(&h->request_mutex);
   2.187  	if (!h->read_thr_exists) {
   2.188  		if (pthread_create(&h->read_thr, NULL, read_thread, h) != 0) {
   2.189 -			pthread_mutex_unlock(&h->request_mutex);
   2.190 +			mutex_unlock(&h->request_mutex);
   2.191  			return false;
   2.192  		}
   2.193  		h->read_thr_exists = 1;
   2.194  	}
   2.195 -	pthread_mutex_unlock(&h->request_mutex);
   2.196 +	mutex_unlock(&h->request_mutex);
   2.197 +#endif
   2.198  
   2.199  	iov[0].iov_base = (void *)path;
   2.200  	iov[0].iov_len = strlen(path) + 1;
   2.201 @@ -586,11 +621,11 @@ char **xs_read_watch(struct xs_handle *h
   2.202  	char **ret, *strings, c = 0;
   2.203  	unsigned int num_strings, i;
   2.204  
   2.205 -	pthread_mutex_lock(&h->watch_mutex);
   2.206 +	mutex_lock(&h->watch_mutex);
   2.207  
   2.208  	/* Wait on the condition variable for a watch to fire. */
   2.209  	while (list_empty(&h->watch_list))
   2.210 -		pthread_cond_wait(&h->watch_condvar, &h->watch_mutex);
   2.211 +		condvar_wait(&h->watch_condvar, &h->watch_mutex, h);
   2.212  	msg = list_top(&h->watch_list, struct xs_stored_msg, list);
   2.213  	list_del(&msg->list);
   2.214  
   2.215 @@ -599,7 +634,7 @@ char **xs_read_watch(struct xs_handle *h
   2.216  		while (read(h->watch_pipe[0], &c, 1) != 1)
   2.217  			continue;
   2.218  
   2.219 -	pthread_mutex_unlock(&h->watch_mutex);
   2.220 +	mutex_unlock(&h->watch_mutex);
   2.221  
   2.222  	assert(msg->hdr.type == XS_WATCH_EVENT);
   2.223  
   2.224 @@ -801,7 +836,7 @@ static int read_message(struct xs_handle
   2.225  	body[msg->hdr.len] = '\0';
   2.226  
   2.227  	if (msg->hdr.type == XS_WATCH_EVENT) {
   2.228 -		pthread_mutex_lock(&h->watch_mutex);
   2.229 +		mutex_lock(&h->watch_mutex);
   2.230  
   2.231  		/* Kick users out of their select() loop. */
   2.232  		if (list_empty(&h->watch_list) &&
   2.233 @@ -810,22 +845,23 @@ static int read_message(struct xs_handle
   2.234  				continue;
   2.235  
   2.236  		list_add_tail(&msg->list, &h->watch_list);
   2.237 -		pthread_cond_signal(&h->watch_condvar);
   2.238  
   2.239 -		pthread_mutex_unlock(&h->watch_mutex);
   2.240 +		condvar_signal(&h->watch_condvar);
   2.241 +
   2.242 +		mutex_unlock(&h->watch_mutex);
   2.243  	} else {
   2.244 -		pthread_mutex_lock(&h->reply_mutex);
   2.245 +		mutex_lock(&h->reply_mutex);
   2.246  
   2.247  		/* There should only ever be one response pending! */
   2.248  		if (!list_empty(&h->reply_list)) {
   2.249 -			pthread_mutex_unlock(&h->reply_mutex);
   2.250 +			mutex_unlock(&h->reply_mutex);
   2.251  			goto error;
   2.252  		}
   2.253  
   2.254  		list_add_tail(&msg->list, &h->reply_list);
   2.255 -		pthread_cond_signal(&h->reply_condvar);
   2.256 +		condvar_signal(&h->reply_condvar);
   2.257  
   2.258 -		pthread_mutex_unlock(&h->reply_mutex);
   2.259 +		mutex_unlock(&h->reply_mutex);
   2.260  	}
   2.261  
   2.262  	return 0;
   2.263 @@ -838,6 +874,7 @@ static int read_message(struct xs_handle
   2.264  	return -1;
   2.265  }
   2.266  
   2.267 +#ifdef USE_PTHREAD
   2.268  static void *read_thread(void *arg)
   2.269  {
   2.270  	struct xs_handle *h = arg;
   2.271 @@ -847,6 +884,7 @@ static void *read_thread(void *arg)
   2.272  
   2.273  	return NULL;
   2.274  }
   2.275 +#endif
   2.276  
   2.277  /*
   2.278   * Local variables: