ia64/xen-unstable

changeset 6619:8a228cbb69fe

Add support in libxenstore for using the xenbus_dev store connection.
Also add simple read/write/rm clients for command line access to the
store (using the xenbus_dev store connection).
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Sat Sep 03 16:54:38 2005 +0000 (2005-09-03)
parents 87ea297c1d3a
children 5aae0c8158b9
files .hgignore tools/xenstore/Makefile tools/xenstore/xenstore_client.c tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_lib.c tools/xenstore/xs_lib.h
line diff
     1.1 --- a/.hgignore	Sat Sep 03 16:52:12 2005 +0000
     1.2 +++ b/.hgignore	Sat Sep 03 16:54:38 2005 +0000
     1.3 @@ -153,8 +153,12 @@
     1.4  ^tools/xenstat/xentop/xentop$
     1.5  ^tools/xenstore/testsuite/tmp/.*$
     1.6  ^tools/xenstore/xen$
     1.7 +^tools/xenstore/xenbus_dev.h$
     1.8  ^tools/xenstore/xenstored$
     1.9  ^tools/xenstore/xenstored_test$
    1.10 +^tools/xenstore/xenstore-read$
    1.11 +^tools/xenstore/xenstore-rm$
    1.12 +^tools/xenstore/xenstore-write$
    1.13  ^tools/xenstore/xs_dom0_test$
    1.14  ^tools/xenstore/xs_random$
    1.15  ^tools/xenstore/xs_stress$
     2.1 --- a/tools/xenstore/Makefile	Sat Sep 03 16:52:12 2005 +0000
     2.2 +++ b/tools/xenstore/Makefile	Sat Sep 03 16:54:38 2005 +0000
     2.3 @@ -24,16 +24,28 @@ TESTDIR  = `pwd`/testsuite/tmp
     2.4  TESTFLAGS= -DTESTING
     2.5  TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
     2.6  
     2.7 -all: xen xenstored libxenstore.so
     2.8 +CLIENTS := xenstore-read xenstore-rm xenstore-write
     2.9 +CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
    2.10 +
    2.11 +all: xen xenbus_dev.h libxenstore.so xenstored $(CLIENTS)
    2.12  
    2.13  testcode: xen xs_test xenstored_test xs_random xs_dom0_test
    2.14  
    2.15  xen:
    2.16  	ln -sf $(XEN_ROOT)/xen/include/public $@
    2.17  
    2.18 +xenbus_dev.h:
    2.19 +	ln -sf $(XEN_ROOT)/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h $@
    2.20 +
    2.21  xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o
    2.22  	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
    2.23  
    2.24 +$(CLIENTS): xenstore-%: xenstore_%.o
    2.25 +	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
    2.26 +
    2.27 +$(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
    2.28 +	$(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
    2.29 +
    2.30  xenstored_test: xenstored_core_test.o xenstored_watch_test.o xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o fake_libxc.o utils.o
    2.31  	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
    2.32  
    2.33 @@ -111,12 +123,13 @@ TAGS:
    2.34  tarball: clean
    2.35  	cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/
    2.36  
    2.37 -install: xenstored libxenstore.so
    2.38 +install: libxenstore.so xenstored $(CLIENTS)
    2.39  	$(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
    2.40  	$(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
    2.41  	$(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
    2.42  	$(INSTALL_DIR) -p $(DESTDIR)/usr/include
    2.43  	$(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
    2.44 +	$(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin
    2.45  	$(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
    2.46  	$(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR)
    2.47  	$(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/xenstore/xenstore_client.c	Sat Sep 03 16:54:38 2005 +0000
     3.3 @@ -0,0 +1,130 @@
     3.4 +/*
     3.5 + * This file is subject to the terms and conditions of the GNU General
     3.6 + * Public License.  See the file "COPYING" in the main directory of
     3.7 + * this archive for more details.
     3.8 + *
     3.9 + * Copyright (C) 2005 by Christian Limpach
    3.10 + *
    3.11 + */
    3.12 +
    3.13 +#include <err.h>
    3.14 +#include <fcntl.h>
    3.15 +#include <getopt.h>
    3.16 +#include <stdio.h>
    3.17 +#include <stdlib.h>
    3.18 +#include <string.h>
    3.19 +#include <xs.h>
    3.20 +
    3.21 +static void
    3.22 +usage(const char *progname)
    3.23 +{
    3.24 +#if defined(CLIENT_read)
    3.25 +    errx(1, "Usage: %s [-h] [-p] key [...]", progname);
    3.26 +#elif defined(CLIENT_write)
    3.27 +    errx(1, "Usage: %s [-h] key value [...]", progname);
    3.28 +#elif defined(CLIENT_rm)
    3.29 +    errx(1, "Usage: %s [-h] key [...]", progname);
    3.30 +#endif
    3.31 +}
    3.32 +
    3.33 +int
    3.34 +main(int argc, char **argv)
    3.35 +{
    3.36 +    struct xs_handle *xsh;
    3.37 +    bool success;
    3.38 +    int ret = 0;
    3.39 +#if defined(CLIENT_read)
    3.40 +    char *val;
    3.41 +    int prefix = 0;
    3.42 +#endif
    3.43 +
    3.44 +    xsh = xs_domain_open();
    3.45 +    if (xsh == NULL)
    3.46 +	err(1, "xs_domain_open");
    3.47 +
    3.48 +    while (1) {
    3.49 +	int c, index = 0;
    3.50 +	static struct option long_options[] = {
    3.51 +	    {"help", 0, 0, 'h'},
    3.52 +#if defined(CLIENT_read)
    3.53 +	    {"prefix", 0, 0, 'p'},
    3.54 +#endif
    3.55 +	    {0, 0, 0, 0}
    3.56 +	};
    3.57 +
    3.58 +	c = getopt_long(argc, argv, "h"
    3.59 +#if defined(CLIENT_read)
    3.60 +			"p"
    3.61 +#endif
    3.62 +			, long_options, &index);
    3.63 +	if (c == -1)
    3.64 +	    break;
    3.65 +
    3.66 +	switch (c) {
    3.67 +	case 'h':
    3.68 +	    usage(argv[0]);
    3.69 +	    /* NOTREACHED */
    3.70 +#if defined(CLIENT_read)
    3.71 +	case 'p':
    3.72 +	    prefix = 1;
    3.73 +	    break;
    3.74 +#endif
    3.75 +	}
    3.76 +    }
    3.77 +
    3.78 +    if (optind == argc) {
    3.79 +	usage(argv[0]);
    3.80 +	/* NOTREACHED */
    3.81 +    }
    3.82 +#if defined(CLIENT_write)
    3.83 +    if ((argc - optind) % 1) {
    3.84 +	usage(argv[0]);
    3.85 +	/* NOTREACHED */
    3.86 +    }
    3.87 +#endif
    3.88 +
    3.89 +    /* XXX maybe find longest common prefix */
    3.90 +    success = xs_transaction_start(xsh, "/");
    3.91 +    if (!success)
    3.92 +	errx(1, "couldn't start transaction");
    3.93 +
    3.94 +    while (optind < argc) {
    3.95 +#if defined(CLIENT_read)
    3.96 +	val = xs_read(xsh, argv[optind], NULL);
    3.97 +	if (val == NULL) {
    3.98 +	    warnx("couldn't read path %s", argv[optind]);
    3.99 +	    ret = 1;
   3.100 +	    goto out;
   3.101 +	}
   3.102 +	if (prefix)
   3.103 +	    printf("%s: ", argv[optind]);
   3.104 +	printf("%s\n", val);
   3.105 +	free(val);
   3.106 +	optind++;
   3.107 +#elif defined(CLIENT_write)
   3.108 +	success = xs_write(xsh, argv[optind], argv[optind + 1],
   3.109 +			   strlen(argv[optind + 1]), O_CREAT);
   3.110 +	if (!success) {
   3.111 +	    warnx("could not write path %s", argv[optind]);
   3.112 +	    ret = 1;
   3.113 +	    goto out;
   3.114 +	}
   3.115 +	optind += 2;
   3.116 +#elif defined(CLIENT_rm)
   3.117 +	success = xs_rm(xsh, argv[optind]);
   3.118 +	if (!success) {
   3.119 +	    warnx("could not remove path %s", argv[optind]);
   3.120 +	    ret = 1;
   3.121 +	    goto out;
   3.122 +	}
   3.123 +	optind++;
   3.124 +#endif
   3.125 +    }
   3.126 +
   3.127 + out:
   3.128 +    success = xs_transaction_end(xsh, ret ? true : false);
   3.129 +    if (!success)
   3.130 +	errx(1, "couldn't end transaction");
   3.131 +
   3.132 +    return ret;
   3.133 +}
     4.1 --- a/tools/xenstore/xs.c	Sat Sep 03 16:52:12 2005 +0000
     4.2 +++ b/tools/xenstore/xs.c	Sat Sep 03 16:54:38 2005 +0000
     4.3 @@ -31,14 +31,17 @@
     4.4  #include <signal.h>
     4.5  #include <stdint.h>
     4.6  #include <errno.h>
     4.7 +#include <sys/ioctl.h>
     4.8  #include "xs.h"
     4.9  #include "xenstored.h"
    4.10  #include "xs_lib.h"
    4.11  #include "utils.h"
    4.12 +#include "xenbus_dev.h"
    4.13  
    4.14  struct xs_handle
    4.15  {
    4.16  	int fd;
    4.17 +	enum { SOCK, DEV } type;
    4.18  };
    4.19  
    4.20  /* Get the socket from the store daemon handle.
    4.21 @@ -65,13 +68,35 @@ static struct xs_handle *get_socket(cons
    4.22  		h = malloc(sizeof(*h));
    4.23  		if (h) {
    4.24  			h->fd = sock;
    4.25 +			h->type = SOCK;
    4.26  			return h;
    4.27  		}
    4.28  	}
    4.29  
    4.30  	saved_errno = errno;
    4.31  	close(sock);
    4.32 -	free(h);
    4.33 +	errno = saved_errno;
    4.34 +	return NULL;
    4.35 +}
    4.36 +
    4.37 +static struct xs_handle *get_dev(const char *connect_to)
    4.38 +{
    4.39 +	int fd, saved_errno;
    4.40 +	struct xs_handle *h = NULL;
    4.41 +
    4.42 +	fd = open(connect_to, O_RDONLY);
    4.43 +	if (fd < 0)
    4.44 +		return NULL;
    4.45 +
    4.46 +	h = malloc(sizeof(*h));
    4.47 +	if (h) {
    4.48 +		h->fd = fd;
    4.49 +		h->type = DEV;
    4.50 +		return h;
    4.51 +	}
    4.52 +
    4.53 +	saved_errno = errno;
    4.54 +	close(fd);
    4.55  	errno = saved_errno;
    4.56  	return NULL;
    4.57  }
    4.58 @@ -86,6 +111,11 @@ struct xs_handle *xs_daemon_open_readonl
    4.59  	return get_socket(xs_daemon_socket_ro());
    4.60  }
    4.61  
    4.62 +struct xs_handle *xs_domain_open(void)
    4.63 +{
    4.64 +	return get_dev(xs_domain_dev());
    4.65 +}
    4.66 +
    4.67  void xs_daemon_close(struct xs_handle *h)
    4.68  {
    4.69  	if (h->fd >= 0)
    4.70 @@ -160,9 +190,9 @@ static void *read_reply(int fd, enum xsd
    4.71  }
    4.72  
    4.73  /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
    4.74 -static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
    4.75 -		      const struct iovec *iovec, unsigned int num_vecs,
    4.76 -		      unsigned int *len)
    4.77 +static void *xs_talkv_sock(struct xs_handle *h, enum xsd_sockmsg_type type,
    4.78 +			   const struct iovec *iovec, unsigned int num_vecs,
    4.79 +			   unsigned int *len)
    4.80  {
    4.81  	struct xsd_sockmsg msg;
    4.82  	void *ret = NULL;
    4.83 @@ -223,6 +253,54 @@ close_fd:
    4.84  	return NULL;
    4.85  }
    4.86  
    4.87 +/* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
    4.88 +static void *xs_talkv_dev(struct xs_handle *h, enum xsd_sockmsg_type type,
    4.89 +			  const struct iovec *iovec, unsigned int num_vecs,
    4.90 +			  unsigned int *len)
    4.91 +{
    4.92 +	struct xenbus_dev_talkv dt;
    4.93 +	char *buf;
    4.94 +	int err, buflen = 1024;
    4.95 +
    4.96 + again:
    4.97 +	buf = malloc(buflen);
    4.98 +	if (buf == NULL) {
    4.99 +		errno = ENOMEM;
   4.100 +		return NULL;
   4.101 +	}
   4.102 +	dt.type = type;
   4.103 +	dt.iovec = (struct kvec *)iovec;
   4.104 +	dt.num_vecs = num_vecs;
   4.105 +	dt.buf = buf;
   4.106 +	dt.len = buflen;
   4.107 +	err = ioctl(h->fd, IOCTL_XENBUS_DEV_TALKV, &dt);
   4.108 +	if (err < 0) {
   4.109 +		free(buf);
   4.110 +		errno = err;
   4.111 +		return NULL;
   4.112 +	}
   4.113 +	if (err > buflen) {
   4.114 +		free(buf);
   4.115 +		buflen = err;
   4.116 +		goto again;
   4.117 +	}
   4.118 +	if (len)
   4.119 +		*len = err;
   4.120 +	return buf;
   4.121 +}
   4.122 +
   4.123 +/* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
   4.124 +static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
   4.125 +		      const struct iovec *iovec, unsigned int num_vecs,
   4.126 +		      unsigned int *len)
   4.127 +{
   4.128 +	if (h->type == SOCK)
   4.129 +		return xs_talkv_sock(h, type, iovec, num_vecs, len);
   4.130 +	if (h->type == DEV)
   4.131 +		return xs_talkv_dev(h, type, iovec, num_vecs, len);
   4.132 +	return NULL;
   4.133 +}
   4.134 +
   4.135  /* free(), but don't change errno. */
   4.136  static void free_no_errno(void *p)
   4.137  {
     5.1 --- a/tools/xenstore/xs.h	Sat Sep 03 16:52:12 2005 +0000
     5.2 +++ b/tools/xenstore/xs.h	Sat Sep 03 16:54:38 2005 +0000
     5.3 @@ -30,6 +30,7 @@ struct xs_handle;
     5.4   * Returns a handle or NULL.
     5.5   */
     5.6  struct xs_handle *xs_daemon_open(void);
     5.7 +struct xs_handle *xs_domain_open(void);
     5.8  
     5.9  /* Connect to the xs daemon (readonly for non-root clients).
    5.10   * Returns a handle or NULL.
     6.1 --- a/tools/xenstore/xs_lib.c	Sat Sep 03 16:52:12 2005 +0000
     6.2 +++ b/tools/xenstore/xs_lib.c	Sat Sep 03 16:54:38 2005 +0000
     6.3 @@ -66,6 +66,12 @@ const char *xs_daemon_transactions(void)
     6.4  	return buf;
     6.5  }
     6.6  
     6.7 +const char *xs_domain_dev(void)
     6.8 +{
     6.9 +	char *s = getenv("XENSTORED_DOMAIN_DEV");
    6.10 +	return (s ? s : "/proc/xen/xenbus");
    6.11 +}
    6.12 +
    6.13  /* Simple routines for writing to sockets, etc. */
    6.14  bool xs_write_all(int fd, const void *data, unsigned int len)
    6.15  {
     7.1 --- a/tools/xenstore/xs_lib.h	Sat Sep 03 16:52:12 2005 +0000
     7.2 +++ b/tools/xenstore/xs_lib.h	Sat Sep 03 16:54:38 2005 +0000
     7.3 @@ -48,6 +48,7 @@ const char *xs_daemon_socket(void);
     7.4  const char *xs_daemon_socket_ro(void);
     7.5  const char *xs_daemon_store(void);
     7.6  const char *xs_daemon_transactions(void);
     7.7 +const char *xs_domain_dev(void);
     7.8  
     7.9  /* Simple write function: loops for you. */
    7.10  bool xs_write_all(int fd, const void *data, unsigned int len);