WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] merge?

# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 29808fef91486c3d5e560c9b7524195599bcdf3e
# Parent  dbded18962a406db5cebcc191dbe255f5f562160
# Parent  f27205ea60ef4b47734e4a8b8177ca1c2b25fa5d
merge?

diff -r dbded18962a4 -r 29808fef9148 .hgignore
--- a/.hgignore Sat Sep  3 18:15:39 2005
+++ b/.hgignore Sat Sep  3 18:24:46 2005
@@ -153,8 +153,12 @@
 ^tools/xenstat/xentop/xentop$
 ^tools/xenstore/testsuite/tmp/.*$
 ^tools/xenstore/xen$
+^tools/xenstore/xenbus_dev.h$
 ^tools/xenstore/xenstored$
 ^tools/xenstore/xenstored_test$
+^tools/xenstore/xenstore-read$
+^tools/xenstore/xenstore-rm$
+^tools/xenstore/xenstore-write$
 ^tools/xenstore/xs_dom0_test$
 ^tools/xenstore/xs_random$
 ^tools/xenstore/xs_stress$
diff -r dbded18962a4 -r 29808fef9148 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Sat Sep  3 18:15:39 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Sat Sep  3 18:24:46 2005
@@ -350,6 +350,8 @@
 
     spin_unlock_irq(&port_user_lock);
 
+    kfree(u);
+
     return 0;
 }
 
diff -r dbded18962a4 -r 29808fef9148 
linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Sat Sep  3 18:15:39 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Sat Sep  3 18:24:46 2005
@@ -4,3 +4,4 @@
 xenbus-objs += xenbus_comms.o
 xenbus-objs += xenbus_xs.o
 xenbus-objs += xenbus_probe.o 
+xenbus-objs += xenbus_dev.o 
diff -r dbded18962a4 -r 29808fef9148 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Sat Sep  3 
18:15:39 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Sat Sep  3 
18:24:46 2005
@@ -212,7 +212,7 @@
                xen_start_info.store_evtchn, wake_waiting,
                0, "xenbus", &xb_waitq);
        if (err) {
-               xprintk("XENBUS request irq failed %i\n", err);
+               printk(KERN_ERR "XENBUS request irq failed %i\n", err);
                unbind_evtchn_from_irq(xen_start_info.store_evtchn);
                return err;
        }
diff -r dbded18962a4 -r 29808fef9148 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Sep  3 
18:15:39 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Sat Sep  3 
18:24:46 2005
@@ -106,10 +106,10 @@
 }
 
 /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-static void *xs_talkv(enum xsd_sockmsg_type type,
-                     const struct kvec *iovec,
-                     unsigned int num_vecs,
-                     unsigned int *len)
+void *xs_talkv(enum xsd_sockmsg_type type,
+              const struct kvec *iovec,
+              unsigned int num_vecs,
+              unsigned int *len)
 {
        struct xsd_sockmsg msg;
        void *ret = NULL;
@@ -557,7 +557,7 @@
                        BUG_ON(!w);
                        w->callback(w, node);
                        kfree(node);
-               } else
+               } else if (node)
                        printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
                               PTR_ERR(node));
                up(&xenbus_lock);
diff -r dbded18962a4 -r 29808fef9148 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Sat Sep  3 18:15:39 2005
+++ b/tools/xenstore/Makefile   Sat Sep  3 18:24:46 2005
@@ -24,15 +24,27 @@
 TESTFLAGS= -DTESTING
 TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
 
-all: xen xenstored libxenstore.so
+CLIENTS := xenstore-read xenstore-rm xenstore-write
+CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
+
+all: xen xenbus_dev.h libxenstore.so xenstored $(CLIENTS)
 
 testcode: xen xs_test xenstored_test xs_random xs_dom0_test
 
 xen:
        ln -sf $(XEN_ROOT)/xen/include/public $@
 
+xenbus_dev.h:
+       ln -sf 
$(XEN_ROOT)/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h $@
+
 xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@
+
+$(CLIENTS): xenstore-%: xenstore_%.o
+       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
+
+$(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
+       $(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
 
 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
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
@@ -111,12 +123,13 @@
 tarball: clean
        cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/
 
-install: xenstored libxenstore.so
+install: libxenstore.so xenstored $(CLIENTS)
        $(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
        $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
        $(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
        $(INSTALL_DIR) -p $(DESTDIR)/usr/include
        $(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
+       $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin
        $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
        $(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR)
        $(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
diff -r dbded18962a4 -r 29808fef9148 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Sat Sep  3 18:15:39 2005
+++ b/tools/xenstore/xs.c       Sat Sep  3 18:24:46 2005
@@ -31,14 +31,17 @@
 #include <signal.h>
 #include <stdint.h>
 #include <errno.h>
+#include <sys/ioctl.h>
 #include "xs.h"
 #include "xenstored.h"
 #include "xs_lib.h"
 #include "utils.h"
+#include "xenbus_dev.h"
 
 struct xs_handle
 {
        int fd;
+       enum { SOCK, DEV } type;
 };
 
 /* Get the socket from the store daemon handle.
@@ -65,17 +68,39 @@
                h = malloc(sizeof(*h));
                if (h) {
                        h->fd = sock;
+                       h->type = SOCK;
                        return h;
                }
        }
 
        saved_errno = errno;
        close(sock);
-       free(h);
        errno = saved_errno;
        return NULL;
 }
 
+static struct xs_handle *get_dev(const char *connect_to)
+{
+       int fd, saved_errno;
+       struct xs_handle *h = NULL;
+
+       fd = open(connect_to, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+
+       h = malloc(sizeof(*h));
+       if (h) {
+               h->fd = fd;
+               h->type = DEV;
+               return h;
+       }
+
+       saved_errno = errno;
+       close(fd);
+       errno = saved_errno;
+       return NULL;
+}
+
 struct xs_handle *xs_daemon_open(void)
 {
        return get_socket(xs_daemon_socket());
@@ -84,6 +109,11 @@
 struct xs_handle *xs_daemon_open_readonly(void)
 {
        return get_socket(xs_daemon_socket_ro());
+}
+
+struct xs_handle *xs_domain_open(void)
+{
+       return get_dev(xs_domain_dev());
 }
 
 void xs_daemon_close(struct xs_handle *h)
@@ -160,9 +190,9 @@
 }
 
 /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
-static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
-                     const struct iovec *iovec, unsigned int num_vecs,
-                     unsigned int *len)
+static void *xs_talkv_sock(struct xs_handle *h, enum xsd_sockmsg_type type,
+                          const struct iovec *iovec, unsigned int num_vecs,
+                          unsigned int *len)
 {
        struct xsd_sockmsg msg;
        void *ret = NULL;
@@ -220,6 +250,54 @@
        close(h->fd);
        h->fd = -1;
        errno = saved_errno;
+       return NULL;
+}
+
+/* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
+static void *xs_talkv_dev(struct xs_handle *h, enum xsd_sockmsg_type type,
+                         const struct iovec *iovec, unsigned int num_vecs,
+                         unsigned int *len)
+{
+       struct xenbus_dev_talkv dt;
+       char *buf;
+       int err, buflen = 1024;
+
+ again:
+       buf = malloc(buflen);
+       if (buf == NULL) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       dt.type = type;
+       dt.iovec = (struct kvec *)iovec;
+       dt.num_vecs = num_vecs;
+       dt.buf = buf;
+       dt.len = buflen;
+       err = ioctl(h->fd, IOCTL_XENBUS_DEV_TALKV, &dt);
+       if (err < 0) {
+               free(buf);
+               errno = err;
+               return NULL;
+       }
+       if (err > buflen) {
+               free(buf);
+               buflen = err;
+               goto again;
+       }
+       if (len)
+               *len = err;
+       return buf;
+}
+
+/* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
+static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
+                     const struct iovec *iovec, unsigned int num_vecs,
+                     unsigned int *len)
+{
+       if (h->type == SOCK)
+               return xs_talkv_sock(h, type, iovec, num_vecs, len);
+       if (h->type == DEV)
+               return xs_talkv_dev(h, type, iovec, num_vecs, len);
        return NULL;
 }
 
diff -r dbded18962a4 -r 29808fef9148 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Sat Sep  3 18:15:39 2005
+++ b/tools/xenstore/xs.h       Sat Sep  3 18:24:46 2005
@@ -30,6 +30,7 @@
  * Returns a handle or NULL.
  */
 struct xs_handle *xs_daemon_open(void);
+struct xs_handle *xs_domain_open(void);
 
 /* Connect to the xs daemon (readonly for non-root clients).
  * Returns a handle or NULL.
diff -r dbded18962a4 -r 29808fef9148 tools/xenstore/xs_lib.c
--- a/tools/xenstore/xs_lib.c   Sat Sep  3 18:15:39 2005
+++ b/tools/xenstore/xs_lib.c   Sat Sep  3 18:24:46 2005
@@ -64,6 +64,12 @@
        static char buf[PATH_MAX];
        sprintf(buf, "%s/transactions", xs_daemon_rootdir());
        return buf;
+}
+
+const char *xs_domain_dev(void)
+{
+       char *s = getenv("XENSTORED_DOMAIN_DEV");
+       return (s ? s : "/proc/xen/xenbus");
 }
 
 /* Simple routines for writing to sockets, etc. */
diff -r dbded18962a4 -r 29808fef9148 tools/xenstore/xs_lib.h
--- a/tools/xenstore/xs_lib.h   Sat Sep  3 18:15:39 2005
+++ b/tools/xenstore/xs_lib.h   Sat Sep  3 18:24:46 2005
@@ -48,6 +48,7 @@
 const char *xs_daemon_socket_ro(void);
 const char *xs_daemon_store(void);
 const char *xs_daemon_transactions(void);
+const char *xs_domain_dev(void);
 
 /* Simple write function: loops for you. */
 bool xs_write_all(int fd, const void *data, unsigned int len);
diff -r dbded18962a4 -r 29808fef9148 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- /dev/null   Sat Sep  3 18:15:39 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Sat Sep  3 
18:24:46 2005
@@ -0,0 +1,186 @@
+/*
+ * xenbus_dev.c
+ * 
+ * Driver giving user-space access to the kernel's xenbus connection
+ * to xenstore.
+ * 
+ * Copyright (c) 2005, Christian Limpach
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/uio.h>
+#include <linux/notifier.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+
+#include "xenstored.h"
+#include "xenbus_comms.h"
+
+#include <asm/uaccess.h>
+#include <asm-xen/xenbus.h>
+#include <asm-xen/linux-public/xenbus_dev.h>
+#include <asm-xen/xen_proc.h>
+
+struct xenbus_dev_data {
+       int in_transaction;
+};
+
+static struct proc_dir_entry *xenbus_dev_intf;
+
+void *xs_talkv(enum xsd_sockmsg_type type, const struct kvec *iovec,
+              unsigned int num_vecs, unsigned int *len);
+
+static int xenbus_dev_talkv(struct xenbus_dev_data *u, unsigned long data)
+{
+       struct xenbus_dev_talkv xt;
+       unsigned int len;
+       void *resp, *base;
+       struct kvec *iovec;
+       int ret = -EFAULT, v = 0;
+
+       if (copy_from_user(&xt, (void *)data, sizeof(xt)))
+               return -EFAULT;
+
+       iovec = kmalloc(xt.num_vecs * sizeof(struct kvec), GFP_KERNEL);
+       if (iovec == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(iovec, xt.iovec,
+                          xt.num_vecs * sizeof(struct kvec)))
+               goto out;
+
+       for (v = 0; v < xt.num_vecs; v++) {
+               base = iovec[v].iov_base;
+               iovec[v].iov_base = kmalloc(iovec[v].iov_len, GFP_KERNEL);
+               if (iovec[v].iov_base == NULL ||
+                   copy_from_user(iovec[v].iov_base, base, iovec[v].iov_len))
+               {
+                       if (iovec[v].iov_base)
+                               kfree(iovec[v].iov_base);
+                       else
+                               ret = -ENOMEM;
+                       v--;
+                       goto out;
+               }
+       }
+
+       resp = xs_talkv(xt.type, iovec, xt.num_vecs, &len);
+       if (IS_ERR(resp)) {
+               ret = PTR_ERR(resp);
+               goto out;
+       }
+
+       switch (xt.type) {
+       case XS_TRANSACTION_START:
+               u->in_transaction = 1;
+               break;
+       case XS_TRANSACTION_END:
+               u->in_transaction = 0;
+               break;
+       default:
+               break;
+       }
+
+       ret = len;
+       if (len > xt.len)
+               len = xt.len;
+
+       if (copy_to_user(xt.buf, resp, len))
+               ret = -EFAULT;
+
+       kfree(resp);
+ out:
+       while (v-- > 0)
+               kfree(iovec[v].iov_base);
+       kfree(iovec);
+       return ret;
+}
+
+static int xenbus_dev_ioctl(struct inode *inode, struct file *filp,
+                           unsigned int cmd, unsigned long data)
+{
+       struct xenbus_dev_data *u = filp->private_data;
+       int ret = -ENOSYS;
+
+       switch (cmd) {
+       case IOCTL_XENBUS_DEV_TALKV:
+               ret = xenbus_dev_talkv(u, data);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int xenbus_dev_open(struct inode *inode, struct file *filp)
+{
+       struct xenbus_dev_data *u;
+
+       u = kmalloc(sizeof(*u), GFP_KERNEL);
+       if (u == NULL)
+               return -ENOMEM;
+
+       memset(u, 0, sizeof(*u));
+
+       filp->private_data = u;
+
+       down(&xenbus_lock);
+
+       return 0;
+}
+
+static int xenbus_dev_release(struct inode *inode, struct file *filp)
+{
+       struct xenbus_dev_data *u = filp->private_data;
+
+       if (u->in_transaction)
+               xenbus_transaction_end(1);
+
+       up(&xenbus_lock);
+
+       kfree(u);
+
+       return 0;
+}
+
+static struct file_operations xenbus_dev_file_ops = {
+       ioctl: xenbus_dev_ioctl,
+       open: xenbus_dev_open,
+       release: xenbus_dev_release
+};
+
+static int __init
+xenbus_dev_init(void)
+{
+       xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400);
+       if (xenbus_dev_intf)
+               xenbus_dev_intf->proc_fops = &xenbus_dev_file_ops;
+
+       return 0;
+}
+
+__initcall(xenbus_dev_init);
diff -r dbded18962a4 -r 29808fef9148 
linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h
--- /dev/null   Sat Sep  3 18:15:39 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h    Sat Sep 
 3 18:24:46 2005
@@ -0,0 +1,47 @@
+/*
+ * xenbus_dev.h
+ * 
+ * Copyright (c) 2005, Christian Limpach
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _XENBUS_DEV_H_
+#define _XENBUS_DEV_H_
+
+struct xenbus_dev_talkv {
+       enum xsd_sockmsg_type type;
+       const struct kvec *iovec;
+       unsigned int num_vecs;
+       char *buf;
+       unsigned int len;
+};
+
+/*
+ * @cmd: IOCTL_XENBUS_DEV_TALKV
+ * @arg: struct xenbus_dev_talkv
+ * Return: 0 on success, error code on failure.
+ */
+#define        IOCTL_XENBUS_DEV_TALKV \
+       _IOC(_IOC_NONE, 'X', 0, sizeof(struct xenbus_dev_talkv))
+
+#endif /* _XENBUS_DEV_H_ */
diff -r dbded18962a4 -r 29808fef9148 tools/xenstore/xenstore_client.c
--- /dev/null   Sat Sep  3 18:15:39 2005
+++ b/tools/xenstore/xenstore_client.c  Sat Sep  3 18:24:46 2005
@@ -0,0 +1,130 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2005 by Christian Limpach
+ *
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <xs.h>
+
+static void
+usage(const char *progname)
+{
+#if defined(CLIENT_read)
+    errx(1, "Usage: %s [-h] [-p] key [...]", progname);
+#elif defined(CLIENT_write)
+    errx(1, "Usage: %s [-h] key value [...]", progname);
+#elif defined(CLIENT_rm)
+    errx(1, "Usage: %s [-h] key [...]", progname);
+#endif
+}
+
+int
+main(int argc, char **argv)
+{
+    struct xs_handle *xsh;
+    bool success;
+    int ret = 0;
+#if defined(CLIENT_read)
+    char *val;
+    int prefix = 0;
+#endif
+
+    xsh = xs_domain_open();
+    if (xsh == NULL)
+       err(1, "xs_domain_open");
+
+    while (1) {
+       int c, index = 0;
+       static struct option long_options[] = {
+           {"help", 0, 0, 'h'},
+#if defined(CLIENT_read)
+           {"prefix", 0, 0, 'p'},
+#endif
+           {0, 0, 0, 0}
+       };
+
+       c = getopt_long(argc, argv, "h"
+#if defined(CLIENT_read)
+                       "p"
+#endif
+                       , long_options, &index);
+       if (c == -1)
+           break;
+
+       switch (c) {
+       case 'h':
+           usage(argv[0]);
+           /* NOTREACHED */
+#if defined(CLIENT_read)
+       case 'p':
+           prefix = 1;
+           break;
+#endif
+       }
+    }
+
+    if (optind == argc) {
+       usage(argv[0]);
+       /* NOTREACHED */
+    }
+#if defined(CLIENT_write)
+    if ((argc - optind) % 1) {
+       usage(argv[0]);
+       /* NOTREACHED */
+    }
+#endif
+
+    /* XXX maybe find longest common prefix */
+    success = xs_transaction_start(xsh, "/");
+    if (!success)
+       errx(1, "couldn't start transaction");
+
+    while (optind < argc) {
+#if defined(CLIENT_read)
+       val = xs_read(xsh, argv[optind], NULL);
+       if (val == NULL) {
+           warnx("couldn't read path %s", argv[optind]);
+           ret = 1;
+           goto out;
+       }
+       if (prefix)
+           printf("%s: ", argv[optind]);
+       printf("%s\n", val);
+       free(val);
+       optind++;
+#elif defined(CLIENT_write)
+       success = xs_write(xsh, argv[optind], argv[optind + 1],
+                          strlen(argv[optind + 1]), O_CREAT);
+       if (!success) {
+           warnx("could not write path %s", argv[optind]);
+           ret = 1;
+           goto out;
+       }
+       optind += 2;
+#elif defined(CLIENT_rm)
+       success = xs_rm(xsh, argv[optind]);
+       if (!success) {
+           warnx("could not remove path %s", argv[optind]);
+           ret = 1;
+           goto out;
+       }
+       optind++;
+#endif
+    }
+
+ out:
+    success = xs_transaction_end(xsh, ret ? true : false);
+    if (!success)
+       errx(1, "couldn't end transaction");
+
+    return ret;
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>