[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xenstore: Remove broken and unmaintained test code.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1183474319 -3600
# Node ID eb71f258e8551858ff11d2331f008539cf399a55
# Parent  0528bc25c4042188bf25f5f0c365f7849d63a684
xenstore: Remove broken and unmaintained test code.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/xenstore/fake_libxc.c                     |  143 --
 tools/xenstore/speedtest.c                      |  130 -
 tools/xenstore/testsuite/01simple.test          |    4 
 tools/xenstore/testsuite/02directory.test       |   45 
 tools/xenstore/testsuite/03write.test           |   28 
 tools/xenstore/testsuite/04rm.test              |   20 
 tools/xenstore/testsuite/05filepermissions.test |   81 -
 tools/xenstore/testsuite/06dirpermissions.test  |  119 -
 tools/xenstore/testsuite/07watch.test           |  176 --
 tools/xenstore/testsuite/08transaction.slowtest |   43 
 tools/xenstore/testsuite/08transaction.test     |   92 -
 tools/xenstore/testsuite/09domain.test          |   19 
 tools/xenstore/testsuite/10domain-homedir.test  |   18 
 tools/xenstore/testsuite/11domain-watch.test    |   50 
 tools/xenstore/testsuite/12readonly.test        |   38 
 tools/xenstore/testsuite/13watch-ack.test       |   21 
 tools/xenstore/testsuite/14complexperms.test    |   68 -
 tools/xenstore/testsuite/test.sh                |   64 
 tools/xenstore/testsuite/vg-suppressions        |    9 
 tools/xenstore/xenstored_test.h                 |   37 
 tools/xenstore/xs_crashme.c                     |  393 -----
 tools/xenstore/xs_random.c                      | 1590 ------------------------
 tools/xenstore/xs_stress.c                      |  207 ---
 tools/xenstore/xs_test.c                        |  812 ------------
 tools/xenstore/Makefile                         |   94 -
 tools/xenstore/xenstored_core.c                 |  105 -
 tools/xenstore/xenstored_domain.c               |    4 
 tools/xenstore/xenstored_transaction.c          |    1 
 tools/xenstore/xenstored_watch.c                |   12 
 29 files changed, 5 insertions(+), 4418 deletions(-)

diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Tue Jul 03 15:49:16 2007 +0100
+++ b/tools/xenstore/Makefile   Tue Jul 03 15:51:59 2007 +0100
@@ -11,15 +11,11 @@ BASECFLAGS += -Wp,-MD,.$(@F).d
 BASECFLAGS += -Wp,-MD,.$(@F).d
 PROG_DEP = .*.d
 BASECFLAGS+= $(PROFILE)
-#BASECFLAGS+= -I$(XEN_ROOT)/tools
 BASECFLAGS+= -I$(XEN_ROOT)/tools/libxc
 BASECFLAGS+= -I.
 
 CFLAGS  += $(BASECFLAGS)
 LDFLAGS += $(PROFILE) -L$(XEN_LIBXC)
-TESTDIR  = testsuite/tmp
-TESTFLAGS= -DTESTING
-TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
 
 CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm 
xenstore-chmod
 CLIENTS += xenstore-write
@@ -34,12 +30,6 @@ XENSTORED_OBJS += $(XENSTORED_OBJS_y)
 
 .PHONY: all
 all: libxenstore.so libxenstore.a xenstored $(CLIENTS) xs_tdb_dump 
xenstore-control xenstore-ls
-
-test_interleaved_transactions: test_interleaved_transactions.o
-       $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -L. -lxenstore -o 
$@
-
-.PHONY: testcode
-testcode: xs_test xenstored_test xs_random
 
 xenstored: $(XENSTORED_OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl 
$(SOCKET_LIBS) -o $@
@@ -56,34 +46,8 @@ xenstore-ls: xsls.o libxenstore.so
 xenstore-ls: xsls.o libxenstore.so
        $(CC) $(CFLAGS) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -L. -lxenstore 
$(SOCKET_LIBS) -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 tdb.o
-       $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
-
 xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o
        $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
-
-xs_test xs_random xs_stress xs_crashme: LDFLAGS+=-lpthread
-xs_test: xs_test.o xs_lib.o utils.o
-xs_random: xs_random.o xs_test_lib.o xs_lib.o talloc.o utils.o
-xs_stress: xs_stress.o xs_test_lib.o xs_lib.o talloc.o utils.o
-xs_crashme: xs_crashme.o xs_lib.o talloc.o utils.o
-
-speedtest: speedtest.o xs.o xs_lib.o utils.o talloc.o
-
-.PHONY: check-speed
-check-speed: speedtest xenstored_test $(TESTDIR)
-       $(TESTENV) time ./speedtest 100
-
-xs_test.o xs_stress.o xenstored_core_test.o xenstored_watch_test.o 
xenstored_transaction_test.o xenstored_domain_test.o xs_random.o xs_test_lib.o 
talloc_test.o fake_libxc.o xs_crashme.o: CFLAGS=$(BASECFLAGS) $(TESTFLAGS)
-
-xenstored_%_test.o: xenstored_%.c
-       $(COMPILE.c) -o $@ $<
-
-xs_test_lib.o: xs.c
-       $(COMPILE.c) -o $@ $<
-
-talloc_test.o: talloc.c
-       $(COMPILE.c) -o $@ $<
 
 libxenstore.so: libxenstore.so.$(MAJOR)
        ln -sf $< $@
@@ -97,66 +61,12 @@ libxenstore.a: xs.o xs_lib.o
        $(AR) rcs libxenstore.a $^
 
 .PHONY: clean
-clean: testsuite-clean
+clean:
        rm -f *.a *.o *.opic *.so*
        rm -f xenstored xs_random xs_stress xs_crashme
-       rm -f xs_test xenstored_test xs_tdb_dump xenstore-control xenstore-ls
+       rm -f xs_tdb_dump xenstore-control xenstore-ls
        rm -f $(CLIENTS)
        $(RM) $(PROG_DEP)
-
-.PHONY: print-dir
-print-dir:
-       @echo -n tools/xenstore: 
-
-.PHONY: print-end
-print-end:
-       @echo
-
-.PHONY: check
-check: print-dir testsuite-fast randomcheck-fast print-end
-
-.PHONY: fullcheck
-fullcheck: testsuite-run randomcheck stresstest
-
-$(TESTDIR):
-       mkdir $@
-
-.PHONY: testsuite-run
-testsuite-run: xenstored_test xs_test $(TESTDIR)
-       $(TESTENV) testsuite/test.sh && echo
-
-.PHONY: testsuite-fast
-testsuite-fast: xenstored_test xs_test $(TESTDIR)
-       @$(TESTENV) testsuite/test.sh --fast
-
-.PHONY: testsuite-clean
-testsuite-clean:
-       rm -rf $(TESTDIR)
-
-# Make this visible so they can see repeat tests without --fast if they
-# fail.
-RANDSEED=$(shell date +%s)
-.PHONY: randomcheck
-randomcheck: xs_random xenstored_test $(TESTDIR)
-       $(TESTENV) ./xs_random --simple --fast /tmp/xs_random 200000 
$(RANDSEED) && echo
-       $(TESTENV) ./xs_random --fast /tmp/xs_random 100000 $(RANDSEED) && echo
-#      $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
-
-.PHONY: crashme
-crashme:  xs_crashme xenstored_test $(TESTDIR)
-       rm -rf $(TESTDIR)/store $(TESTDIR)/transactions /tmp/xs_crashme.vglog* 
/tmp/trace
-       export $(TESTENV); ./xs_crashme 5000 $(RANDSEED) 2>/dev/null
-       if [ -n "`cat /tmp/xs_crashme.vglog*`" ]; then echo Valgrind 
complained; cat /tmp/xs_crashme.vglog*; exit 1; fi
-       rm -rf $(TESTDIR)/store $(TESTDIR)/transactions /tmp/xs_crashme.vglog* 
/tmp/trace
-
-.PHONY: randomcheck-fast
-randomcheck-fast: xs_random xenstored_test $(TESTDIR)
-       @$(TESTENV) ./xs_random --fast /tmp/xs_random 2000 $(RANDSEED)
-
-.PHONY: stresstest
-stresstest: xs_stress xenstored_test $(TESTDIR)
-       rm -rf $(TESTDIR)/store $(TESTDIR)/transactions
-       export $(TESTENV); PID=`./xenstored_test --output-pid 
--trace-file=/tmp/trace`; ./xs_stress 5000; ret=$$?; kill $$PID; exit $$ret
 
 .PHONY: TAGS
 TAGS:
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/fake_libxc.c
--- a/tools/xenstore/fake_libxc.c       Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/* 
-    Fake libxc which doesn't require hypervisor but talks to xs_test.
-    Copyright (C) 2005 Rusty Russell IBM Corporation
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <assert.h>
-#include <signal.h>
-#include "utils.h"
-#include "xenstored_core.h"
-#include "xenstored_domain.h"
-#include "xenstored_test.h"
-#include <xenctrl.h>
-
-static int sigfd;
-static int xs_test_pid;
-static evtchn_port_t port;
-
-/* The event channel maps to a signal, shared page to an mmapped file. */
-void xc_evtchn_notify(int xce_handle, int local_port)
-{
-       assert(local_port == port);
-       if (kill(xs_test_pid, SIGUSR2) != 0)
-               barf_perror("fake event channel failed");
-}
-
-void *xc_map_foreign_range(int xc_handle, uint32_t dom __attribute__((unused)),
-                          int size, int prot,
-                          unsigned long mfn __attribute__((unused)))
-{
-       void *ret;
-
-       ret = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
-       if (ret == MAP_FAILED)
-               return NULL;
-
-       /* xs_test tells us pid and port by putting it in buffer, we reply. */
-       xs_test_pid = *(int *)(ret + 32);
-       port = *(int *)(ret + 36);
-       *(int *)(ret + 32) = getpid();
-       return ret;
-}
-
-int xc_interface_open(void)
-{
-       int fd;
-       char page[getpagesize()];
-
-       fd = open("/tmp/xcmap", O_RDWR|O_CREAT|O_TRUNC, 0600);
-       if (fd < 0)
-               return fd;
-
-       memset(page, 0, sizeof(page));
-       if (!xs_write_all(fd, page, sizeof(page)))
-               barf_perror("Failed to write /tmp/xcmap page");
-       
-       return fd;
-}
-
-int xc_interface_close(int xc_handle)
-{
-       close(xc_handle);
-       return 0;
-}
-
-int xc_domain_getinfo(int xc_handle __attribute__((unused)),
-                     uint32_t first_domid, unsigned int max_doms,
-                      xc_dominfo_t *info)
-{
-       assert(max_doms == 1);
-        info->domid = first_domid;
-
-        info->dying    = 0;
-        info->shutdown = 0;
-        info->paused   = 0;
-        info->blocked  = 0;
-        info->running  = 1;
-
-        info->shutdown_reason = 0;
-
-        if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
-        {
-            info->shutdown = 0;
-            info->crashed  = 1;
-        }
-
-       return 1;
-}
-
-static void send_to_fd(int signo __attribute__((unused)))
-{
-       int saved_errno = errno;
-       write(sigfd, &port, sizeof(port));
-       errno = saved_errno;
-}
-
-void fake_block_events(void)
-{
-       signal(SIGUSR2, SIG_IGN);
-}
-
-void fake_ack_event(void)
-{
-       signal(SIGUSR2, send_to_fd);
-}
-
-int xc_evtchn_open(void)
-{
-       int fds[2];
-
-       if (pipe(fds) != 0)
-               return -1;
-
-       if (signal(SIGUSR2, send_to_fd) == SIG_ERR) {
-               int saved_errno = errno;
-               close(fds[0]);
-               close(fds[1]);
-               errno = saved_errno;
-               return -1;
-       }
-       sigfd = fds[1];
-       return fds[0];
-}
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/speedtest.c
--- a/tools/xenstore/speedtest.c        Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/* 
-    Xen Store Daemon Speed test
-    Copyright (C) 2005 Rusty Russell IBM Corporation
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "utils.h"
-#include "xs.h"
-#include "list.h"
-#include "talloc.h"
-
-static void do_command(const char *cmd)
-{
-       int ret;
-
-       ret = system(cmd);
-       if (ret == -1 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
-               barf_perror("Failed '%s': %i", cmd, ret);
-}
-
-static int start_daemon(void)
-{
-       int fds[2], pid;
-
-       do_command(talloc_asprintf(NULL, "rm -rf testsuite/tmp/*"));
-
-       /* Start daemon. */
-       pipe(fds);
-       if ((pid = fork())) {
-               /* Child writes PID when its ready: we wait for that. */
-               char buffer[20];
-               close(fds[1]);
-               if (read(fds[0], buffer, sizeof(buffer)) < 0)
-                       barf("Failed to summon daemon");
-               close(fds[0]);
-       } else {
-               dup2(fds[1], STDOUT_FILENO);
-               close(fds[0]);
-#if 0
-               execlp("valgrind", "valgrind", "-q", 
"--suppressions=testsuite/vg-suppressions", "xenstored_test", "--output-pid",
-                      "--no-fork", "--trace-file=/tmp/trace", NULL);
-#else
-               execlp("./xenstored_test", "xenstored_test", "--output-pid", 
"--no-fork", NULL);
-//             execlp("strace", "strace", "-o", "/tmp/out", 
"./xenstored_test", "--output-pid", "--no-fork", NULL);
-#endif
-               exit(1);
-       }
-       return pid;
-}
-
-static void kill_daemon(int pid)
-{
-       int saved_errno = errno;
-       kill(pid, SIGTERM);
-       errno = saved_errno;
-}
-
-#define NUM_ENTRIES 50
-
-/* We create the given number of trees, each with NUM_ENTRIES, using
- * transactions. */
-int main(int argc, char *argv[])
-{
-       int i, j, pid, print;
-       struct xs_handle *h;
-
-       if (argc != 2)
-               barf("Usage: speedtest <numdomains>");
-
-       pid = start_daemon();
-       h = xs_daemon_open();
-       print = atoi(argv[1]) / 76;
-       if (!print)
-               print = 1;
-       for (i = 0; i < atoi(argv[1]); i ++) {
-               char name[64];
-
-               if (i % print == 0)
-                       write(1, ".", 1);
-               if (!xs_transaction_start(h)) {
-                       kill_daemon(pid);
-                       barf_perror("Starting transaction");
-               }
-               sprintf(name, "/%i", i);
-               if (!xs_mkdir(h, name)) {
-                       kill_daemon(pid);
-                       barf_perror("Making directory %s", name);
-               }
-
-               for (j = 0; j < NUM_ENTRIES; j++) {
-                       sprintf(name, "/%i/%i", i, j);
-                       if (!xs_write(h, name, name, strlen(name))) {
-                               kill_daemon(pid);
-                               barf_perror("Making directory %s", name);
-                       }
-               }
-               if (!xs_transaction_end(h, false)) {
-                       kill_daemon(pid);
-                       barf_perror("Ending transaction");
-               }
-       }
-       write(1, "\n", 1);
-
-       kill_daemon(pid);
-       wait(NULL);
-       return 0;
-}
-       
-       
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/01simple.test
--- a/tools/xenstore/testsuite/01simple.test    Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-# Create an entry, read it.
-write /test contents
-expect contents
-read /test
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/02directory.test
--- a/tools/xenstore/testsuite/02directory.test Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-# Root directory has only tool dir in it.
-expect tool
-dir /
-
-# Create a file.
-write /test contents
-
-# Directory shows it.
-expect test
-expect tool
-dir /
-
-# Make a new directory, check it's there
-mkdir /dir
-expect dir
-expect test
-expect tool
-dir /
-
-# Check it's empty.
-dir /dir
-
-# Create a file, check it exists.
-write /dir/test2 contents2
-expect test2
-dir /dir
-expect contents2
-read /dir/test2
-
-# Creating dir over the top should succeed.
-mkdir /dir
-mkdir /dir/test2
-
-# Mkdir implicitly creates directories.
-mkdir /dir/1/2/3/4
-expect test2
-expect 1
-dir /dir
-expect 2
-dir /dir/1
-expect 3
-dir /dir/1/2
-expect 4
-dir /dir/1/2/3
-dir /dir/1/2/3/4
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/03write.test
--- a/tools/xenstore/testsuite/03write.test     Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-# Write succeeds
-write /test contents
-expect contents
-read /test
-
-# Overwrite succeeds.
-write /test contents2
-expect contents2
-read /test
-
-# Write should implicitly create directories
-write /dir/test contents
-expect test
-dir /dir
-expect contents
-read /dir/test
-write /dir/1/2/3/4 contents4
-expect test
-expect 1
-dir /dir
-expect 2
-dir /dir/1
-expect 3
-dir /dir/1/2
-expect 4
-dir /dir/1/2/3
-expect contents4
-read /dir/1/2/3/4
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/04rm.test
--- a/tools/xenstore/testsuite/04rm.test        Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-# Remove non-existant is OK, as long as parent exists
-rm /test
-expect rm failed: No such file or directory
-rm /dir/test
-
-# Create file and remove it
-write /test contents
-rm /test
-expect tool
-dir /
-
-# Create directory and remove it.
-mkdir /dir
-rm /dir
-
-# Create directory, create file, remove all.
-mkdir /dir
-write /dir/test contents
-rm /dir
-
diff -r 0528bc25c404 -r eb71f258e855 
tools/xenstore/testsuite/05filepermissions.test
--- a/tools/xenstore/testsuite/05filepermissions.test   Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-# Fail to get perms on non-existent file.
-expect getperm failed: No such file or directory
-getperm /test
-expect getperm failed: No such file or directory
-getperm /dir/test
-
-# Create file: inherits from root (0 READ)
-write /test contents
-expect 0 READ
-getperm /test
-setid 1
-expect 0 READ
-getperm /test
-expect contents
-read /test
-expect write failed: Permission denied
-write /test contents
-
-# Take away read access to file.
-setid 0
-setperm /test 0 NONE
-setid 1
-expect getperm failed: Permission denied
-getperm /test
-expect read failed: Permission denied
-read /test
-expect write failed: Permission denied
-write /test contents
-
-# Grant everyone write access to file.
-setid 0
-setperm /test 0 WRITE
-setid 1
-expect getperm failed: Permission denied
-getperm /test
-expect read failed: Permission denied
-read /test
-write /test contents2
-setid 0
-expect contents2
-read /test
-
-# Grant everyone both read and write access.
-setperm /test 0 READ/WRITE
-setid 1
-expect 0 READ/WRITE
-getperm /test
-expect contents2
-read /test
-write /test contents3
-expect contents3
-read /test
-
-# Change so that user 1 owns it, noone else can do anything.
-setid 0
-setperm /test 1 NONE
-setid 1
-expect 1 NONE
-getperm /test
-expect contents3
-read /test
-write /test contents4
-
-# User 2 can do nothing.
-setid 2
-expect setperm failed: Permission denied
-setperm /test 2 NONE
-expect getperm failed: Permission denied
-getperm /test
-expect read failed: Permission denied
-read /test
-expect write failed: Permission denied
-write /test contents4
-
-# Tools can always access things.
-setid 0
-expect 1 NONE
-getperm /test
-expect contents4
-read /test
-write /test contents5
diff -r 0528bc25c404 -r eb71f258e855 
tools/xenstore/testsuite/06dirpermissions.test
--- a/tools/xenstore/testsuite/06dirpermissions.test    Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-# Root directory: owned by tool, everyone has read access.
-expect 0 READ
-getperm /
-
-# Create directory: inherits from root.
-mkdir /dir
-expect 0 READ
-getperm /dir
-setid 1
-expect 0 READ
-getperm /dir
-dir /dir
-expect write failed: Permission denied
-write /dir/test contents2
-
-# Remove everyone's read access to directoy.
-setid 0
-setperm /dir 0 NONE
-setid 1
-expect dir failed: Permission denied
-dir /dir
-expect read failed: Permission denied
-read /dir/test create contents2
-expect write failed: Permission denied
-write /dir/test contents2
-
-# Grant everyone write access to directory.
-setid 0
-setperm /dir 0 WRITE
-setid 1
-expect getperm failed: Permission denied
-getperm /dir
-expect dir failed: Permission denied
-dir /dir
-write /dir/test contents
-setid 0
-expect 1 WRITE
-getperm /dir/test
-setperm /dir/test 0 NONE
-expect contents
-read /dir/test
-
-# Grant everyone both read and write access.
-setperm /dir 0 READ/WRITE
-setid 1
-expect 0 READ/WRITE
-getperm /dir
-expect test
-dir /dir
-write /dir/test2 contents
-expect contents
-read /dir/test2
-setperm /dir/test2 1 NONE
-
-# Change so that user 1 owns it, noone else can do anything.
-setid 0
-setperm /dir 1 NONE
-expect 1 NONE
-getperm /dir
-expect test
-expect test2
-dir /dir
-write /dir/test3 contents
-
-# User 2 can do nothing.  Can't even tell if file exists.
-setid 2
-expect setperm failed: Permission denied
-setperm /dir 2 NONE
-expect getperm failed: Permission denied
-getperm /dir
-expect dir failed: Permission denied
-dir /dir
-expect read failed: Permission denied
-read /dir/test
-expect read failed: Permission denied
-read /dir/test2
-expect read failed: Permission denied
-read /dir/test3
-expect read failed: Permission denied
-read /dir/test4
-expect write failed: Permission denied
-write /dir/test contents
-expect write failed: Permission denied
-write /dir/test4 contents
-
-# Tools can always access things.
-setid 0
-expect 1 NONE
-getperm /dir
-expect test
-expect test2
-expect test3
-dir /dir
-write /dir/test4 contents
-
-# Inherited by child.
-mkdir /dir/subdir
-expect 1 NONE
-getperm /dir/subdir
-write /dir/subfile contents
-expect 1 NONE
-getperm /dir/subfile
-
-# But for domains, they own it.
-setperm /dir/subdir 2 READ/WRITE
-expect 2 READ/WRITE
-getperm /dir/subdir
-setid 3
-write /dir/subdir/subfile contents
-expect 3 READ/WRITE
-getperm /dir/subdir/subfile
-
-# Inheritence works through multiple directories, too.
-write /dir/subdir/1/2/3/4 contents
-expect 3 READ/WRITE
-getperm /dir/subdir/1/2/3/4
-mkdir /dir/subdir/a/b/c/d
-expect 3 READ/WRITE
-getperm /dir/subdir/a/b/c/d
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/07watch.test
--- a/tools/xenstore/testsuite/07watch.test     Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-# Watch something, write to it, check watch has fired.
-write /test contents
-
-1 watch /test token
-2 write /test contents2
-expect 1:/test:token
-1 waitwatch
-1 close
-
-# Check that reads don't set it off.
-1 watch /test token
-expect 2:contents2
-2 read /test
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
-1 close
-
-# mkdir, setperm and rm should (also tests watching dirs)
-mkdir /dir
-1 watch /dir token
-2 mkdir /dir/newdir
-expect 1:/dir/newdir:token
-1 waitwatch
-2 setperm /dir/newdir 0 READ
-expect 1:/dir/newdir:token
-1 waitwatch
-2 rm /dir/newdir
-expect 1:/dir/newdir:token
-1 waitwatch
-1 close
-2 close
-
-# Changed in b594bb976a743d509f1ffabb5bc698874ab90d8f
-## We don't get a watch from our own commands.
-#watch /dir token
-#mkdir /dir/newdir
-#expect waitwatch failed: Connection timed out
-#waitwatch
-#close
-
-# ignore watches while doing commands, should work.
-watch /dir token
-1 write /dir/test contents
-expect contents
-read /dir/test
-expect /dir/test:token
-waitwatch
-close
-
-# watch priority test: all simultaneous
-1 watch /dir token1
-3 watch /dir token3
-2 watch /dir token2
-write /dir/test contents
-expect 3:/dir/test:token3
-3 waitwatch
-expect 2:/dir/test:token2
-2 waitwatch
-expect 1:/dir/test:token1
-1 waitwatch
-1 close
-2 close
-3 close
-
-# If one dies (without acking), the other should still get ack.
-1 watch /dir token1
-2 watch /dir token2
-write /dir/test contents
-expect 2:/dir/test:token2
-2 waitwatch
-2 close
-expect 1:/dir/test:token1
-1 waitwatch
-1 close
-
-# If one dies (without reading at all), the other should still get ack.
-1 watch /dir token1
-2 watch /dir token2
-write /dir/test contents
-2 close
-expect 1:/dir/test:token1
-1 waitwatch
-1 close
-2 close
-
-# unwatch
-1 watch /dir token1
-1 unwatch /dir token1
-1 watch /dir token2
-2 write /dir/test2 contents
-expect 1:/dir/test2:token2
-1 waitwatch
-1 unwatch /dir token2
-1 close
-2 close
-
-# unwatch while watch pending.  Other watcher still gets the event.
-1 watch /dir token1
-2 watch /dir token2
-write /dir/test contents
-2 unwatch /dir token2
-expect 1:/dir/test:token1
-1 waitwatch
-1 close
-2 close
-
-# unwatch while watch pending.  Should clear this so we get next event.
-1 watch /dir token1
-write /dir/test contents
-1 unwatch /dir token1
-1 watch /dir/test token2
-write /dir/test contents2
-expect 1:/dir/test:token2
-1 waitwatch
-
-# check we only get notified once.
-1 watch /test token
-2 write /test contents2
-expect 1:/test:token
-1 waitwatch
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
-1 close
-
-# watches are queued in order.
-1 watch / token
-2 write /test1 contents
-2 write /test2 contents
-2 write /test3 contents
-expect 1:/test1:token
-1 waitwatch
-expect 1:/test2:token
-1 waitwatch
-expect 1:/test3:token
-1 waitwatch
-1 close
-
-# Creation of subpaths should be covered correctly.
-1 watch / token
-2 write /test/subnode contents2
-2 write /test/subnode/subnode contents2
-expect 1:/test/subnode:token
-1 waitwatch
-expect 1:/test/subnode/subnode:token
-1 waitwatch
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
-1 close
-
-# Watch event must have happened before we registered interest.
-1 watch / token
-2 write /test/subnode contents2
-1 watchnoack / token2 0
-expect 1:/test/subnode:token
-1 waitwatch
-expect 1:/:token2
-1 waitwatch
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
-1 close
-
-# Rm fires notification on child.
-1 watch /test/subnode token
-2 rm /test
-expect 1:/test/subnode:token
-1 waitwatch
-
-# Watch should not double-send after we ack, even if we did something in 
between.
-1 watch /test2 token
-2 write /test2/foo contents2
-expect 1:/test2/foo:token
-1 waitwatch
-expect 1:contents2
-1 read /test2/foo
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
diff -r 0528bc25c404 -r eb71f258e855 
tools/xenstore/testsuite/08transaction.slowtest
--- a/tools/xenstore/testsuite/08transaction.slowtest   Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-# Test transaction clashes.
-
-mkdir /test
-write /test/entry1 contents
-
-# Start transaction, do read-only op, transaction succeeds
-1 start
-1 write /test/entry1 contents2
-expect contents
-read /test/entry1
-1 commit
-expect contents2
-read /test/entry1
-
-# Start transaction, abort other transaction, transaction succeeds.
-1 start
-1 write /test/entry1 contents3
-start
-write /test/entry1 contents
-abort
-1 commit
-expect contents3
-read /test/entry1
-
-# Start transaction, do write op, transaction fails
-1 start
-1 write /test/entry1 contents4
-write /test/entry1 contents
-expect 1: commit failed: Resource temporarily unavailable
-1 commit
-expect contents
-read /test/entry1
-
-# Start transaction, do other transaction, transaction fails
-1 start
-1 write /test/entry1 contents4
-start
-write /test/entry1 contents5
-commit
-expect 1: commit failed: Resource temporarily unavailable
-1 commit
-expect contents5
-read /test/entry1
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/08transaction.test
--- a/tools/xenstore/testsuite/08transaction.test       Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-# Test transactions.
-
-mkdir /test
-
-# Simple transaction: create a file inside transaction.
-1 start
-1 write /test/entry1 contents
-2 dir /test
-expect 1:entry1
-1 dir /test
-1 commit
-expect 2:contents
-2 read /test/entry1
-
-rm /test/entry1
-
-# Create a file and abort transaction.
-1 start
-1 write /test/entry1 contents
-2 dir /test
-expect 1:entry1
-1 dir /test
-1 abort
-2 dir /test
-
-write /test/entry1 contents
-# Delete in transaction, commit
-1 start
-1 rm /test/entry1
-expect 2:entry1
-2 dir /test
-1 dir /test
-1 commit
-2 dir /test
-
-# Delete in transaction, abort.
-write /test/entry1 contents
-1 start
-1 rm /test/entry1
-expect 2:entry1
-2 dir /test
-1 dir /test
-1 abort
-expect 2:entry1
-2 dir /test
-
-# Events inside transactions don't trigger watches until (successful) commit.
-mkdir /test/dir
-1 watch /test token
-2 start
-2 mkdir /test/dir/sub
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
-2 close
-1 close
-
-1 watch /test token
-2 start
-2 mkdir /test/dir/sub
-2 abort
-expect 1: waitwatch failed: Connection timed out
-1 waitwatch
-1 close
-
-1 watch /test token
-2 start
-2 mkdir /test/dir/sub
-2 commit
-expect 1:/test/dir/sub:token
-1 waitwatch
-1 close
-
-# Rm inside transaction works like rm outside: children get notified.
-1 watch /test/dir/sub token
-2 start
-2 rm /test/dir
-2 commit
-expect 1:/test/dir/sub:token
-1 waitwatch
-1 close
-
-# Multiple events from single transaction don't trigger assert
-1 watch /test token
-2 start
-2 write /test/1 contents
-2 write /test/2 contents
-2 commit
-expect 1:/test/1:token
-1 waitwatch
-expect 1:/test/2:token
-1 waitwatch
-1 close
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/09domain.test
--- a/tools/xenstore/testsuite/09domain.test    Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-# Test domain communication.
-
-# Create a domain, write an entry.
-expect handle is 1
-introduce 1 100 7 /my/home
-1 write /entry1 contents
-expect entry1
-expect tool
-dir /
-close
-
-# Release that domain.
-release 1
-close
-
-# Introduce and release by same connection.
-expect handle is 2
-introduce 1 100 7 /my/home
-release 1
diff -r 0528bc25c404 -r eb71f258e855 
tools/xenstore/testsuite/10domain-homedir.test
--- a/tools/xenstore/testsuite/10domain-homedir.test    Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-# Test domain "implicit" paths.
-
-# Create a domain, write an entry using implicit path, read using implicit
-mkdir /home
-expect handle is 1
-introduce 1 100 7 /home
-1 write entry1 contents
-expect contents
-read /home/entry1
-expect entry1
-dir /home
-
-# Place a watch using a relative path: expect relative answer.
-1 mkdir foo
-1 watch foo token
-write /home/foo/bar contents
-expect 1:foo/bar:token
-1 waitwatch
diff -r 0528bc25c404 -r eb71f258e855 
tools/xenstore/testsuite/11domain-watch.test
--- a/tools/xenstore/testsuite/11domain-watch.test      Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-# Test watching from a domain.
-
-# Watch something, write to it, check watch has fired.
-write /test contents
-mkdir /dir
-
-expect handle is 1
-introduce 1 100 7 /my/home
-1 watch /test token
-write /test contents2
-expect 1:/test:token
-1 waitwatch
-1 unwatch /test token
-release 1
-1 close
-
-# ignore watches while doing commands, should work.
-expect handle is 1
-introduce 1 100 7 /my/home
-1 watch /dir token
-write /dir/test contents
-1 write /dir/test2 contents2
-1 write /dir/test3 contents3
-1 write /dir/test4 contents4
-expect 1:/dir/test:token
-1 waitwatch
-release 1
-1 close
-
-# unwatch
-expect handle is 1
-introduce 1 100 7 /my/home
-1 watch /dir token1
-1 unwatch /dir token1
-1 watch /dir token2
-write /dir/test2 contents
-expect 1:/dir/test2:token2
-1 waitwatch
-1 unwatch /dir token2
-release 1
-1 close
-
-# unwatch while watch pending.
-expect handle is 1
-introduce 1 100 7 /my/home
-1 watch /dir token1
-write /dir/test2 contents
-1 unwatch /dir token1
-release 1
-1 close
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/12readonly.test
--- a/tools/xenstore/testsuite/12readonly.test  Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-# Test that read only connection can't alter store.
-
-write /test contents
-
-readonly
-expect test
-expect tool
-dir /
-
-expect contents
-read /test
-expect 0 READ
-getperm /test
-watch /test token
-unwatch /test token 
-start
-commit
-start
-abort
-
-# These don't work
-expect write failed: Permission denied
-write /test2 contents
-expect write failed: Permission denied
-write /test contents
-expect setperm failed: Permission denied
-setperm /test 100 NONE
-expect setperm failed: Permission denied
-setperm /test 100 NONE
-expect introduce failed: Permission denied
-introduce 1 100 7 /home
-
-# Check that watches work like normal.
-watch / token
-1 readwrite
-1 write /test contents
-expect /test:token
-waitwatch
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/13watch-ack.test
--- a/tools/xenstore/testsuite/13watch-ack.test Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# This demonstrates a bug where an xs_acknowledge_watch returns
-# EINVAL, because the daemon doesn't track what watch event it sent
-# and relies on it being the "first" watch which has an event.
-# Watches firing after the first event is sent out will change this.
-
-# Create three things to watch.
-mkdir /test
-mkdir /test/1
-mkdir /test/2
-mkdir /test/3
-
-# Watch all three, fire event on 2, read watch, fire event on 1 and 3, ack 2.
-1 watch /test/1 token1
-1 watch /test/2 token2
-1 watch /test/3 token3
-2 write /test/2 contents2
-expect 1:/test/2:token2
-1 waitwatch
-3 write /test/1 contents1
-4 write /test/3 contents3
-1 close
diff -r 0528bc25c404 -r eb71f258e855 
tools/xenstore/testsuite/14complexperms.test
--- a/tools/xenstore/testsuite/14complexperms.test      Tue Jul 03 15:49:16 
2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-# We should not be able to tell the difference between a node which
-# doesn't exist, and a node we don't have permission on, if we don't
-# have permission on it directory.
-
-mkdir /dir
-setperm /dir 0 NONE
-
-# First when it doesn't exist
-setid 1
-expect *Permission denied
-dir /dir/file
-expect *Permission denied
-read /dir/file 
-expect *Permission denied
-write /dir/file value 
-expect *Permission denied
-mkdir /dir/file 
-expect *Permission denied
-rm /dir/file 
-expect *Permission denied
-rm /dir 
-expect *Permission denied
-getperm /dir/file 
-expect *Permission denied
-setperm /dir/file 0 NONE 
-# We get no watch event when there's no permission.  It's a corner case.
-watchnoack /dir/file token 
-1 write /dir/file contents
-1 rm /dir/file
-expect waitwatch failed: Connection timed out
-waitwatch
-unwatch /dir/file token 
-expect *No such file or directory
-unwatch /dir/file token 
-expect *Permission denied
-introduce 2 100 7 /dir/file
-
-# Now it exists
-setid 0
-write /dir/file contents
-
-setid 1
-expect *Permission denied
-dir /dir/file
-expect *Permission denied
-read /dir/file 
-expect *Permission denied
-write /dir/file value 
-expect *Permission denied
-mkdir /dir/file 
-expect *Permission denied
-rm /dir/file 
-expect *Permission denied
-rm /dir 
-expect *Permission denied
-getperm /dir/file 
-expect *Permission denied
-setperm /dir/file 0 NONE 
-watchnoack /dir/file token 
-1 write /dir/file contents
-1 rm /dir/file
-expect waitwatch failed: Connection timed out
-waitwatch
-unwatch /dir/file token 
-expect *No such file or directory
-unwatch /dir/file token 
-expect *Permission denied
-introduce 2 100 7 /dir/file
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/test.sh
--- a/tools/xenstore/testsuite/test.sh  Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#! /bin/sh
-
-set -e
-set -m
-
-run_test()
-{
-    rm -rf $XENSTORED_ROOTDIR
-    mkdir $XENSTORED_ROOTDIR
-    if [ $VALGRIND -eq 1 ]; then
-       valgrind --suppressions=testsuite/vg-suppressions -q ./xenstored_test 
--output-pid --trace-file=testsuite/tmp/trace --no-fork > /tmp/pid 2> 
testsuite/tmp/xenstored_errors &
-       while [ ! -s /tmp/pid ]; do sleep 0; done
-       PID=`cat /tmp/pid`
-       rm /tmp/pid
-    else
-       # We don't get error messages from this, though. 
-       PID=`./xenstored_test --output-pid --trace-file=testsuite/tmp/trace`
-    fi
-    if ./xs_test $2 $1; then
-       if [ -s testsuite/tmp/xenstored_errors ]; then
-           kill $PID
-           echo Errors:
-           cat testsuite/tmp/xenstored_errors
-           return 1
-       fi
-       kill $PID
-       sleep 1
-       return 0
-    else
-       # In case daemon is wedged.
-       kill $PID
-       sleep 1
-       return 1
-    fi
-}
-
-if [ x$1 = x--fast ]; then
-    VALGRIND=0
-    SLOWTESTS=""
-    shift
-else
-    if type valgrind >/dev/null 2>&1; then
-       VALGRIND=1
-    else
-       echo "WARNING: valgrind not available" >&2
-       VALGRIND=0
-    fi
-    SLOWTESTS=testsuite/[0-9]*.slowtest
-fi
-
-MATCH=${1:-"*"}
-for f in testsuite/[0-9]*.test $SLOWTESTS; do
-    case `basename $f` in $MATCH) RUN=1;; esac
-    [ -n "$RUN" ] || continue
-
-    if run_test $f -x >/tmp/out; then
-       echo -n .
-    else
-       cat /tmp/out
-       # That will have filled the screen, repeat message.
-       echo Test $f failed
-       exit 1
-    fi
-done
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/testsuite/vg-suppressions
--- a/tools/xenstore/testsuite/vg-suppressions  Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-{
-   Glibc goes boom from _start (Debian glibc 2.3.5-3)
-   Memcheck:Cond
-   obj:/lib/ld-2.3.5.so
-   obj:/lib/ld-2.3.5.so
-   obj:/lib/ld-2.3.5.so
-   obj:/lib/ld-2.3.5.so
-   obj:/lib/ld-2.3.5.so
-}
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Tue Jul 03 15:49:16 2007 +0100
+++ b/tools/xenstore/xenstored_core.c   Tue Jul 03 15:51:59 2007 +0100
@@ -39,7 +39,6 @@
 #include <assert.h>
 #include <setjmp.h>
 
-//#define DEBUG
 #include "utils.h"
 #include "list.h"
 #include "talloc.h"
@@ -53,7 +52,6 @@
 
 #include "hashtable.h"
 
-
 extern int xce_handle; /* in xenstored_domain.c */
 
 static bool verbose = false;
@@ -81,50 +79,6 @@ int quota_nb_watch_per_domain = 128;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
-
-#ifdef TESTING
-static bool failtest = false;
-
-/* We override talloc's malloc. */
-void *test_malloc(size_t size)
-{
-       /* 1 in 20 means only about 50% of connections establish. */
-       if (failtest && (random() % 32) == 0)
-               return NULL;
-       return malloc(size);
-}
-
-static void stop_failtest(int signum __attribute__((unused)))
-{
-       failtest = false;
-}
-
-/* Need these before we #define away write_all/mkdir in testing.h */
-bool test_write_all(int fd, void *contents, unsigned int len);
-bool test_write_all(int fd, void *contents, unsigned int len)
-{
-       if (failtest && (random() % 8) == 0) {
-               if (len)
-                       len = random() % len;
-               write(fd, contents, len);
-               errno = ENOSPC;
-               return false;
-       }
-       return xs_write_all(fd, contents, len);
-}
-
-int test_mkdir(const char *dir, int perms);
-int test_mkdir(const char *dir, int perms)
-{
-       if (failtest && (random() % 8) == 0) {
-               errno = ENOSPC;
-               return -1;
-       }
-       return mkdir(dir, perms);
-}
-#endif /* TESTING */
-
-#include "xenstored_test.h"
 
 TDB_CONTEXT *tdb_context(struct connection *conn)
 {
@@ -1163,12 +1117,10 @@ static void do_debug(struct connection *
 {
        int num;
 
-#ifndef TESTING
        if (conn->id != 0) {
                send_error(conn, EACCES);
                return;
        }
-#endif
 
        num = xs_count_strings(in->buffer, in->used);
 
@@ -1179,18 +1131,10 @@ static void do_debug(struct connection *
                }
                xprintf("debug: %s", in->buffer + get_string(in, 0));
        }
+
        if (streq(in->buffer, "check"))
                check_store();
-#ifdef TESTING
-       /* For testing, we allow them to set id. */
-       if (streq(in->buffer, "setid")) {
-               conn->id = atoi(in->buffer + get_string(in, 0));
-       } else if (streq(in->buffer, "failtest")) {
-               if (get_string(in, 0) < in->used)
-                       srandom(atoi(in->buffer + get_string(in, 0)));
-               failtest = true;
-       }
-#endif /* TESTING */
+
        send_ack(conn, XS_DEBUG);
 }
 
@@ -1319,10 +1263,8 @@ static void handle_input(struct connecti
                        return;
 
                if (in->hdr.msg.len > PATH_MAX) {
-#ifndef TESTING
                        syslog(LOG_ERR, "Client tried to feed us %i",
                               in->hdr.msg.len);
-#endif
                        goto bad_client;
                }
 
@@ -1414,39 +1356,7 @@ static void accept_connection(int sock, 
                close(fd);
 }
 
-#ifdef TESTING
-/* Valgrind can check our writes better if we don't use mmap */
-#define TDB_FLAGS TDB_NOMMAP
-/* Useful for running under debugger. */
-void dump_connection(void)
-{
-       struct connection *i;
-
-       list_for_each_entry(i, &connections, list) {
-               printf("Connection %p:\n", i);
-               printf("    state = %s\n",
-                      list_empty(&i->out_list) ? "OK" : "BUSY");
-               if (i->id)
-                       printf("    id = %i\n", i->id);
-               if (!i->in->inhdr || i->in->used)
-                       printf("    got %i bytes of %s\n",
-                              i->in->used, i->in->inhdr ? "header" : "data");
-#if 0
-               if (i->out)
-                       printf("    sending message %s (%s) out\n",
-                              sockmsg_string(i->out->hdr.msg.type),
-                              i->out->buffer);
-               if (i->transaction)
-                       dump_transaction(i);
-               if (i->domain)
-                       dump_domain(i);
-#endif
-               dump_watches(i);
-       }
-}
-#else
 #define TDB_FLAGS 0
-#endif
 
 /* We create initial nodes manually. */
 static void manual_node(const char *name, const char *child)
@@ -1693,10 +1603,6 @@ static void corrupt(struct connection *c
        log("corruption detected by connection %i: err %s: %s",
            conn ? (int)conn->id : -1, strerror(saved_errno), str);
 
-#ifdef TESTING
-       /* Allow them to attach debugger. */
-       sleep(30);
-#endif
        check_store();
 }
 
@@ -1740,11 +1646,10 @@ static void daemonize(void)
        if (pid != 0)
                exit(0);
 
-#ifndef TESTING        /* Relative paths for socket names */
        /* Move off any mount points we might be in. */
        if (chdir("/") == -1)
                barf_perror("Failed to chdir");
-#endif
+
        /* Discard our parent's old-fashioned umask prejudices. */
        umask(0);
 }
@@ -1941,10 +1846,6 @@ int main(int argc, char *argv[])
 
        signal(SIGHUP, trigger_reopen_log);
 
-#ifdef TESTING
-       signal(SIGUSR1, stop_failtest);
-#endif
-
        if (xce_handle != -1)
                evtchn_fd = xc_evtchn_fd(xce_handle);
 
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Tue Jul 03 15:49:16 2007 +0100
+++ b/tools/xenstore/xenstored_domain.c Tue Jul 03 15:51:59 2007 +0100
@@ -23,14 +23,12 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
-//#define DEBUG
 #include "utils.h"
 #include "talloc.h"
 #include "xenstored_core.h"
 #include "xenstored_domain.h"
 #include "xenstored_transaction.h"
 #include "xenstored_watch.h"
-#include "xenstored_test.h"
 
 #include <xenctrl.h>
 
@@ -217,10 +215,8 @@ void handle_event(void)
        if (port == virq_port)
                domain_cleanup();
 
-#ifndef TESTING
        if (xc_evtchn_unmask(xce_handle, port) == -1)
                barf_perror("Failed to write to event fd");
-#endif
 }
 
 bool domain_can_read(struct connection *conn)
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xenstored_test.h
--- a/tools/xenstore/xenstored_test.h   Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/* 
-    Testing replcements for Xen Store Daemon.
-    Copyright (C) 2005 Rusty Russell IBM Corporation
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#ifndef _XENSTORED_TEST_H
-#define _XENSTORED_TEST_H
-
-#ifdef TESTING
-bool test_write_all(int fd, void *contents, unsigned int len);
-#define xs_write_all test_write_all
-
-int test_mkdir(const char *dir, int perms);
-#define mkdir test_mkdir
-
-int fake_open_eventchn(void);
-void fake_block_events(void);
-void fake_ack_event(void);
-
-#define ioctl(a,b,c) 0
-
-#endif
-
-#endif /* _XENSTORED_INTERNAL_H */
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xenstored_transaction.c
--- a/tools/xenstore/xenstored_transaction.c    Tue Jul 03 15:49:16 2007 +0100
+++ b/tools/xenstore/xenstored_transaction.c    Tue Jul 03 15:51:59 2007 +0100
@@ -35,7 +35,6 @@
 #include "xenstored_domain.h"
 #include "xs_lib.h"
 #include "utils.h"
-#include "xenstored_test.h"
 
 struct changed_node
 {
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xenstored_watch.c
--- a/tools/xenstore/xenstored_watch.c  Tue Jul 03 15:49:16 2007 +0100
+++ b/tools/xenstore/xenstored_watch.c  Tue Jul 03 15:51:59 2007 +0100
@@ -29,7 +29,6 @@
 #include "xenstored_watch.h"
 #include "xs_lib.h"
 #include "utils.h"
-#include "xenstored_test.h"
 #include "xenstored_domain.h"
 
 extern int quota_nb_watch_per_domain;
@@ -195,17 +194,6 @@ void conn_delete_all_watches(struct conn
                domain_watch_dec(conn);
        }
 }
-
-#ifdef TESTING
-void dump_watches(struct connection *conn)
-{
-       struct watch *watch;
-
-       list_for_each_entry(watch, &conn->watches, list)
-               printf("    watch on %s token %s\n",
-                      watch->node, watch->token);
-}
-#endif
 
 /*
  * Local variables:
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xs_crashme.c
--- a/tools/xenstore/xs_crashme.c       Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,393 +0,0 @@
-/* Code which randomly corrupts bits going to the daemon.
-    Copyright (C) 2005 Rusty Russell IBM Corporation
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#include <stdbool.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/time.h>
-#include "xs.h"
-#include "talloc.h"
-#include <errno.h>
-
-#define XSTEST
-#define RAND_FREQ 128          /* One char in 32 is corrupted. */
-
-/* jhash.h: Jenkins hash support.
- *
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@xxxxxxxxxxxxxxxx)
- *
- * http://burtleburtle.net/bob/hash/
- *
- * These are the credits from Bob's sources:
- *
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose.  It has no warranty.
- *
- * Copyright (C) 2003 David S. Miller (davem@xxxxxxxxxx)
- *
- * I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault.  -DaveM
- */
-
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<<8); \
-  c -= a; c -= b; c ^= (b>>13); \
-  a -= b; a -= c; a ^= (c>>12);  \
-  b -= c; b -= a; b ^= (a<<16); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>3);  \
-  b -= c; b -= a; b ^= (a<<10); \
-  c -= a; c -= b; c ^= (b>>15); \
-}
-
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO     0x9e3779b9
-
-/* The most generic version, hashes an arbitrary sequence
- * of bytes.  No alignment or length assumptions are made about
- * the input key.
- */
-static inline uint32_t jhash(const void *key, uint32_t length, uint32_t 
initval)
-{
-       uint32_t a, b, c, len;
-       const uint8_t *k = key;
-
-       len = length;
-       a = b = JHASH_GOLDEN_RATIO;
-       c = initval;
-
-       while (len >= 12) {
-               a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) 
+((uint32_t)k[3]<<24));
-               b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) 
+((uint32_t)k[7]<<24));
-               c += (k[8] +((uint32_t)k[9]<<8) 
+((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24));
-
-               __jhash_mix(a,b,c);
-
-               k += 12;
-               len -= 12;
-       }
-
-       c += length;
-       switch (len) {
-       case 11: c += ((uint32_t)k[10]<<24);
-       case 10: c += ((uint32_t)k[9]<<16);
-       case 9 : c += ((uint32_t)k[8]<<8);
-       case 8 : b += ((uint32_t)k[7]<<24);
-       case 7 : b += ((uint32_t)k[6]<<16);
-       case 6 : b += ((uint32_t)k[5]<<8);
-       case 5 : b += k[4];
-       case 4 : a += ((uint32_t)k[3]<<24);
-       case 3 : a += ((uint32_t)k[2]<<16);
-       case 2 : a += ((uint32_t)k[1]<<8);
-       case 1 : a += k[0];
-       };
-
-       __jhash_mix(a,b,c);
-
-       return c;
-}
-
-/* A special optimized version that handles 1 or more of uint32_ts.
- * The length parameter here is the number of uint32_ts in the key.
- */
-static inline uint32_t jhash2(uint32_t *k, uint32_t length, uint32_t initval)
-{
-       uint32_t a, b, c, len;
-
-       a = b = JHASH_GOLDEN_RATIO;
-       c = initval;
-       len = length;
-
-       while (len >= 3) {
-               a += k[0];
-               b += k[1];
-               c += k[2];
-               __jhash_mix(a, b, c);
-               k += 3; len -= 3;
-       }
-
-       c += length * 4;
-
-       switch (len) {
-       case 2 : b += k[1];
-       case 1 : a += k[0];
-       };
-
-       __jhash_mix(a,b,c);
-
-       return c;
-}
-
-
-/* A special ultra-optimized versions that knows they are hashing exactly
- * 3, 2 or 1 word(s).
- *
- * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
- *       done at the end is not done here.
- */
-static inline uint32_t jhash_3words(uint32_t a, uint32_t b, uint32_t c, 
uint32_t initval)
-{
-       a += JHASH_GOLDEN_RATIO;
-       b += JHASH_GOLDEN_RATIO;
-       c += initval;
-
-       __jhash_mix(a, b, c);
-
-       return c;
-}
-
-static inline uint32_t jhash_2words(uint32_t a, uint32_t b, uint32_t initval)
-{
-       return jhash_3words(a, b, 0, initval);
-}
-
-static inline uint32_t jhash_1word(uint32_t a, uint32_t initval)
-{
-       return jhash_3words(a, 0, 0, initval);
-}
-
-static unsigned int get_randomness(int *state)
-{
-       return jhash_1word((*state)++, *state * 1103515243);
-}
-
-static int state;
-
-/* Lengthening headers is pointless: other end will just wait for more
- * data and timeout.  We merely shorten the length. */
-static void corrupt_header(char *output, const struct xsd_sockmsg *msg,
-                          unsigned int *next_bit)
-{
-       struct xsd_sockmsg newmsg = *msg;
-
-       while (*next_bit < sizeof(*msg)) {
-               if (newmsg.len)
-                       newmsg.len = get_randomness(&state) % newmsg.len;
-               *next_bit += get_randomness(&state) % RAND_FREQ;
-       }
-       memcpy(output, &newmsg, sizeof(newmsg));
-}
-
-#define read_all_choice read_all
-static bool write_all_choice(int fd, const void *data, unsigned int len)
-{
-       char corrupt_data[len];
-       bool ret;
-       static unsigned int next_bit;
-
-       if (len == sizeof(struct xsd_sockmsg)
-           && ((unsigned long)data % __alignof__(struct xsd_sockmsg)) == 0)
-               corrupt_header(corrupt_data, data, &next_bit);
-       else {
-               memcpy(corrupt_data, data, len);
-               while (next_bit < len * CHAR_BIT) {
-                       corrupt_data[next_bit/CHAR_BIT]
-                               ^= (1 << (next_bit%CHAR_BIT));
-                       next_bit += get_randomness(&state) % RAND_FREQ;
-               }
-       }
-
-       ret = xs_write_all(fd, corrupt_data, len);
-       next_bit -= len * CHAR_BIT;
-       return ret;
-}
-
-#include "xs.c"
-
-static char *random_path(void)
-{
-       unsigned int i;
-       char *ret = NULL;
-
-       if (get_randomness(&state) % 20 == 0)
-               return talloc_strdup(NULL, "/");
-
-       for (i = 0; i < 1 || (get_randomness(&state) % 2); i++) {
-               ret = talloc_asprintf_append(ret, "/%i", 
-                                            get_randomness(&state) % 15);
-       }
-       return ret;
-}
-
-/* Do the next operation, return the results. */
-static void do_next_op(struct xs_handle *h, bool verbose)
-{
-       char *name;
-       unsigned int num;
-
-       if (verbose)
-               printf("State %i: ", state);
-
-       name = random_path();
-       switch (get_randomness(&state) % 9) {
-       case 0:
-               if (verbose)
-                       printf("DIR %s\n", name);
-               free(xs_directory(h, name, &num));
-               break;
-       case 1:
-               if (verbose)
-                       printf("READ %s\n", name);
-               free(xs_read(h, name, &num));
-               break;
-       case 2: {
-               char *contents = talloc_asprintf(NULL, "%i",
-                                                get_randomness(&state));
-               unsigned int len = get_randomness(&state)%(strlen(contents)+1);
-               if (verbose)
-                       printf("WRITE %s %.*s\n", name, len, contents);
-               xs_write(h, name, contents, len);
-               break;
-       }
-       case 3:
-               if (verbose)
-                       printf("MKDIR %s\n", name);
-               xs_mkdir(h, name);
-               break;
-       case 4:
-               if (verbose)
-                       printf("RM %s\n", name);
-               xs_rm(h, name);
-               break;
-       case 5:
-               if (verbose)
-                       printf("GETPERMS %s\n", name);
-               free(xs_get_permissions(h, name, &num));
-               break;
-       case 6: {
-               unsigned int i, num = get_randomness(&state)%8;
-               struct xs_permissions perms[num];
-
-               if (verbose)
-                       printf("SETPERMS %s: ", name);
-               for (i = 0; i < num; i++) {
-                       perms[i].id = get_randomness(&state)%8;
-                       perms[i].perms = get_randomness(&state)%4;
-                       if (verbose)
-                               printf("%i%c ", perms[i].id,
-                                      perms[i].perms == XS_PERM_WRITE ? 'W'
-                                      : perms[i].perms == XS_PERM_READ ? 'R'
-                                      : perms[i].perms == 
-                                      (XS_PERM_READ|XS_PERM_WRITE) ? 'B'
-                                      : 'N');
-               }
-               if (verbose)
-                       printf("\n");
-               xs_set_permissions(h, name, perms, num);
-               break;
-       }
-       case 7: {
-               if (verbose)
-                       printf("START %s\n", name);
-               xs_transaction_start(h);
-               break;
-       }
-       case 8: {
-               bool abort = (get_randomness(&state) % 2);
-
-               if (verbose)
-                       printf("STOP %s\n", abort ? "ABORT" : "COMMIT");
-               xs_transaction_end(h, abort);
-               break;
-       }
-       default:
-               barf("Impossible randomness");
-       }
-}
-
-static struct xs_handle *h;
-static void alarmed(int sig __attribute__((unused)))
-{
-       /* We force close on timeout. */
-       close(h->fd);
-}
-
-static int start_daemon(void)
-{
-       int fds[2];
-       int daemon_pid;
-
-       /* Start daemon. */
-       pipe(fds);
-       if ((daemon_pid = fork())) {
-               /* Child writes PID when its ready: we wait for that. */
-               char buffer[20];
-               close(fds[1]);
-               if (read(fds[0], buffer, sizeof(buffer)) < 0)
-                       barf("Failed to summon daemon");
-               close(fds[0]);
-               return daemon_pid;
-       } else {
-               dup2(fds[1], STDOUT_FILENO);
-               close(fds[0]);
-#if 1
-               execlp("valgrind", "valgrind", 
"--log-file=/tmp/xs_crashme.vglog", "-q", "./xenstored_test", "--output-pid",
-                      "--no-fork", "--trace-file=/tmp/trace", NULL);
-#else
-               execlp("./xenstored_test", "xenstored_test", "--output-pid",
-                      "--no-fork", NULL);
-#endif
-               exit(1);
-       }
-}
-
-
-int main(int argc, char **argv)
-{
-       unsigned int i;
-       int pid;
-
-       if (argc != 3 && argc != 4)
-               barf("Usage: xs_crashme <iterations> <seed> [pid]");
-
-       if (argc == 3)
-               pid = start_daemon();
-       else
-               pid = atoi(argv[3]);
-
-       state = atoi(argv[2]);
-       h = xs_daemon_open();
-       if (!h)
-               barf_perror("Opening connection to daemon");
-       signal(SIGALRM, alarmed);
-       for (i = 0; i < (unsigned)atoi(argv[1]); i++) {
-               alarm(1);
-               do_next_op(h, false);
-               if (i % (atoi(argv[1]) / 72 ?: 1) == 0) {
-                       printf(".");
-                       fflush(stdout);
-               }
-               if (kill(pid, 0) != 0)
-                       barf_perror("Pinging daemon on iteration %i", i);
-               if (h->fd < 0) {
-                       xs_daemon_close(h);
-                       h = xs_daemon_open();
-                       if (!h)
-                               barf_perror("Connecting on iteration %i", i);
-               }
-       }
-       kill(pid, SIGTERM);
-       return 0;
-}
-
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xs_random.c
--- a/tools/xenstore/xs_random.c        Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1590 +0,0 @@
-/* Random tests.
-
-   We check that the results from a real filesystem are the same.
-*/
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include "xs.h"
-#include "talloc.h"
-#include "utils.h"
-
-struct ops
-{
-       char *name;
-
-       char **(*dir)(void *h, const char *path, unsigned int *num);
-
-       void *(*read)(void *h, const char *path, unsigned int *len);
-
-       bool (*write)(void *h, const char *path, const void *data,
-                     unsigned int len);
-
-       bool (*mkdir)(void *h, const char *path);
-
-       bool (*rm)(void *h, const char *path);
-
-       struct xs_permissions *(*get_perms)(void *h,
-                                           const char *path,
-                                           unsigned int *num);
-
-       bool (*set_perms)(void *h,
-                         const char *path,
-                         struct xs_permissions *perms,
-                         unsigned int num);
-
-       bool (*transaction_start)(void *h);
-       bool (*transaction_end)(void *h, bool abort);
-
-       /* Create and destroy a new handle. */
-       void *(*handle)(const char *path);
-       void (*close)(void *);
-};
-
-struct file_ops_info
-{
-       const char *base;
-       char *transact_base;
-};
-
-static void convert_to_dir(const char *dirname)
-{
-       char *tmpname = talloc_asprintf(dirname, "%s.tmp", dirname);
-       if (rename(dirname, tmpname) != 0)
-               barf_perror("Failed to rename %s to %s", dirname, tmpname);
-       if (mkdir(dirname, 0700) != 0) 
-               barf_perror("Failed to mkdir %s", dirname);
-       if (rename(tmpname,talloc_asprintf(dirname, "%s/.DATA", dirname)) != 0)
-               barf_perror("Failed to rename into %s", dirname);
-       /* If perms exists, move it in. */
-       rename(talloc_asprintf(dirname, "%s.perms", dirname),
-              talloc_asprintf(dirname, "%s/.perms", dirname));
-}
-
-/* Files can be used as dirs, too.  Convert them when they are. */
-static void maybe_convert_to_directory(const char *filename)
-{
-       struct stat st;
-       char *dirname = talloc_asprintf(
-               filename, "%.*s",
-               (int)(strrchr(filename, '/') - filename), filename);
-       if (lstat(dirname, &st) == 0 && S_ISREG(st.st_mode))
-               convert_to_dir(dirname);
-}
-
-static char *get_name(struct file_ops_info *info, const char *path)
-{
-       if (info->transact_base)
-               return talloc_asprintf(path, "%s%s", info->transact_base,
-                                      path);
-       return talloc_asprintf(path, "%s%s", info->base, path);
-}
-
-static char *path_to_name(struct file_ops_info *info, const char *path)
-{
-       char *filename = get_name(info, path);
-       maybe_convert_to_directory(filename);
-       return filename;
-}
-
-static char **file_directory(struct file_ops_info *info,
-                            const char *path, unsigned int *num)
-{
-       char **ret;
-       DIR *dir;
-       struct dirent *dirent;
-       char *p, *dirname = path_to_name(info, path);
-       unsigned int i, len = 0;
-       struct stat st;
-
-       /* If it exists, but isn't a directory, we convert it. */
-       if (lstat(dirname, &st) == 0 && !S_ISDIR(st.st_mode))
-               convert_to_dir(dirname);
-
-       *num = 0;
-       dir = opendir(dirname);
-       if (!dir)
-               return NULL;;
-
-       /* Once to count them. */
-       while ((dirent = readdir(dir)) != NULL) {
-               if (strchr(dirent->d_name, '.'))
-                       continue;
-               len += strlen(dirent->d_name) + 1;
-               (*num)++;
-       }
-       rewinddir(dir);
-
-       /* Now allocate and fill in. */
-       ret = malloc(sizeof(char *) * *num + len);
-       p = (char *)&ret[*num];
-       i = 0;
-       while ((dirent = readdir(dir)) != NULL) {
-               if (strchr(dirent->d_name, '.'))
-                       continue;
-               ret[i] = p;
-               strcpy(p, dirent->d_name);
-               p += strlen(p) + 1;
-               i++;
-       }
-       closedir(dir);
-
-       return ret;
-}
-
-static char *filename_to_data(const char *filename)
-{
-       struct stat st;
-
-       if (lstat(filename, &st) == 0 && S_ISDIR(st.st_mode))
-               return talloc_asprintf(filename, "%s/.DATA", filename);
-       return (char *)filename;
-}
-
-static void *file_read(struct file_ops_info *info,
-                      const char *path, unsigned int *len)
-{
-       void *ret;
-       char *filename = filename_to_data(path_to_name(info, path));
-       unsigned long size;
-
-       ret = grab_file(filename, &size);
-       /* Directory exists, .DATA doesn't. */
-       if (!ret && errno == ENOENT && strends(filename, ".DATA")) {
-               ret = strdup("");
-               size = 0;
-       }
-       *len = size;
-       return ret;
-}
-
-static struct xs_permissions *file_get_perms(struct file_ops_info *info,
-                                            const char *path,
-                                            unsigned int *num)
-{
-       void *perms;
-       struct xs_permissions *ret;
-       char *filename = path_to_name(info, path);
-       char *permfile;
-       unsigned long size;
-       struct stat st;
-
-       if (lstat(filename, &st) != 0)
-               return NULL;
-
-       if (S_ISDIR(st.st_mode)) 
-               permfile = talloc_asprintf(path, "%s/.perms", filename);
-       else
-               permfile = talloc_asprintf(path, "%s.perms", filename);
-
-       perms = grab_file(permfile, &size);
-       if (!perms)
-               barf("Grabbing permissions for %s", permfile);
-       *num = xs_count_strings(perms, size);
-
-       ret = new_array(struct xs_permissions, *num);
-       if (!xs_strings_to_perms(ret, *num, perms))
-               barf("Reading permissions from %s", permfile);
-       release_file(perms, size);
-       return ret;
-}
-
-static void do_command(const char *cmd)
-{
-       int ret;
-
-       ret = system(cmd);
-       if (ret == -1 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
-               barf_perror("Failed '%s': %i", cmd, ret);
-}
-
-static void init_perms(const char *filename)
-{
-       struct stat st;
-       char *permfile, *command;
-
-       if (lstat(filename, &st) != 0)
-               barf_perror("Failed to stat %s", filename);
-
-       if (S_ISDIR(st.st_mode)) 
-               permfile = talloc_asprintf(filename, "%s/.perms", filename);
-       else
-               permfile = talloc_asprintf(filename, "%s.perms", filename);
-
-       /* Leave permfile if it already exists. */
-       if (lstat(permfile, &st) == 0)
-               return;
-
-       /* Copy permissions from parent */
-       command = talloc_asprintf(filename, "cp %.*s/.perms %s",
-                                 (int)(strrchr(filename, '/') - filename),
-                                 filename, permfile);
-       do_command(command);
-}      
-
-static bool file_set_perms(struct file_ops_info *info,
-                          const char *path,
-                          struct xs_permissions *perms,
-                          unsigned int num)
-{
-       unsigned int i;
-       char *filename = path_to_name(info, path);
-       char *permfile;
-       int fd;
-       struct stat st;
-
-       if (num < 1) {
-               errno = EINVAL;
-               return false;
-       }
-
-       /* Check non-perm file exists/ */
-       if (lstat(filename, &st) != 0)
-               return false;
-
-       if (S_ISDIR(st.st_mode)) 
-               permfile = talloc_asprintf(path, "%s/.perms", filename);
-       else
-               permfile = talloc_asprintf(path, "%s.perms", filename);
-
-       fd = open(permfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
-       if (fd < 0)
-               return false;
-
-       for (i = 0; i < num; i++) {
-               char buffer[100];
-
-               if (!xs_perm_to_string(&perms[i], buffer)) {
-                       int saved_errno = errno;
-                       close(fd);
-                       errno = saved_errno;
-                       return false;
-               }
-               if (write(fd, buffer, strlen(buffer) + 1)
-                   != (int)strlen(buffer) + 1)
-                       barf_perror("Failed to write perm");
-       }
-       close(fd);
-       return true;
-}
-
-static char *parent_filename(const char *name)
-{
-       char *slash = strrchr(name + 1, '/');
-       if (!slash)
-               return talloc_strdup(name, "/");
-       return talloc_asprintf(name, "%.*s", (int)(slash-name), name);
-}
-
-static void make_dirs(const char *filename)
-{
-       struct stat st;
-
-       if (lstat(filename, &st) == 0 && S_ISREG(st.st_mode))
-               convert_to_dir(filename);
-
-       if (mkdir(filename, 0700) == 0) {
-               init_perms(filename);
-               return;
-       }
-       if (errno == EEXIST)
-               return;
-
-       make_dirs(parent_filename(filename));
-       if (mkdir(filename, 0700) != 0)
-               barf_perror("Failed to mkdir %s", filename);
-       init_perms(filename);
-}
-
-static bool file_write(struct file_ops_info *info,
-                      const char *path, const void *data,
-                      unsigned int len)
-{
-       char *filename = filename_to_data(path_to_name(info, path));
-       int fd;
-
-       make_dirs(parent_filename(filename));
-       fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0600);
-       if (fd < 0)
-               return false;
-
-       if (write(fd, data, len) != (int)len)
-               barf_perror("Bad write to %s", filename);
-
-       init_perms(filename);
-       close(fd);
-       return true;
-}
-
-static bool file_mkdir(struct file_ops_info *info, const char *path)
-{
-       char *dirname = path_to_name(info, path);
-
-       make_dirs(parent_filename(dirname));
-       if (mkdir(dirname, 0700) != 0)
-               return (errno == EEXIST);
-
-       init_perms(dirname);
-       return true;
-}
-
-static bool file_rm(struct file_ops_info *info, const char *path)
-{
-       char *filename = path_to_name(info, path);
-       struct stat st;
-
-       if (lstat(filename, &st) != 0) {
-               if (lstat(parent_filename(filename), &st) != 0)
-                       return false;
-               return true;
-       }
-
-       if (streq(path, "/")) {
-               errno = EINVAL;
-               return false;
-       }
-
-       do_command(talloc_asprintf(path, "rm -f %s.perms; rm -r %s", 
-                                  filename, filename));
-       return true;
-}
-
-static bool file_transaction_start(struct file_ops_info *info)
-{
-       char *cmd;
-
-       if (info->transact_base) {
-               errno = EBUSY;
-               return false;
-       }
-
-       info->transact_base = talloc_asprintf(NULL, "%s.transact", info->base);
-       cmd = talloc_asprintf(NULL, "cp -r %s %s",
-                             info->base, info->transact_base);
-       do_command(cmd);
-       talloc_free(cmd);
-       return true;
-}
-
-static bool file_transaction_end(struct file_ops_info *info, bool abort)
-{
-       char *old, *cmd;
-
-       if (!info->transact_base) {
-               errno = ENOENT;
-               return false;
-       }
-
-       if (abort) {
-               cmd = talloc_asprintf(NULL, "rm -rf %s", info->transact_base);
-               do_command(cmd);
-               goto success;
-       }
-
-       old = talloc_asprintf(NULL, "rm -rf %s", info->base);
-       do_command(old);
-       talloc_free(old);
-
-       cmd = talloc_asprintf(NULL, "mv %s %s",
-                             info->transact_base, info->base);
-       do_command(cmd);
-
-success:
-       talloc_free(cmd);
-       talloc_free(info->transact_base);
-       info->transact_base = NULL;
-       return true;
-}
-
-static struct file_ops_info *file_handle(const char *dir)
-{
-       struct file_ops_info *info = talloc(NULL, struct file_ops_info);
-
-       info->base = dir;
-       info->transact_base = NULL;
-       return info;
-}
-
-static void file_close(struct file_ops_info *handle)
-{
-       talloc_free(handle);
-}
-
-static struct xs_handle *xs_handle(const char *dir __attribute__((unused)))
-{
-       struct xs_handle *h;
-
-       h = xs_daemon_open();
-       if (!h)
-               barf_perror("Connecting to xs daemon");
-       return h;
-}
-
-static void xs_close(struct xs_handle *handle)
-{
-       xs_daemon_close(handle);
-}
-
-struct ops file_ops = {
-       .name = "FILE",
-       .dir = (void *)file_directory,
-       .read = (void *)file_read,
-       .write = (void *)file_write,
-       .mkdir = (void *)file_mkdir,
-       .rm = (void *)file_rm,
-       .get_perms = (void *)file_get_perms,
-       .set_perms = (void *)file_set_perms,
-       .transaction_start = (void *)file_transaction_start,
-       .transaction_end = (void *)file_transaction_end,
-       .handle = (void *)file_handle,
-       .close = (void *)file_close,
-};
-
-struct ops xs_ops = {
-       .name = "XS",
-       .dir = (void *)xs_directory,
-       .read = (void *)xs_read,
-       .write = (void *)xs_write,
-       .mkdir = (void *)xs_mkdir,
-       .rm = (void *)xs_rm,
-       .get_perms = (void *)xs_get_permissions,
-       .set_perms = (void *)xs_set_permissions,
-       .transaction_start = (void *)xs_transaction_start,
-       .transaction_end = (void *)xs_transaction_end,
-       .handle = (void *)xs_handle,
-       .close = (void *)xs_close,
-};
-
-static int strptrcmp(const void *a, const void *b)
-{
-       return strcmp(*(char **)a, *(char **)b);
-}
-
-static void sort_dir(char **dir, unsigned int num)
-{
-       qsort(dir, num, sizeof(char *), strptrcmp);
-}
-
-static char *dump_dir(struct ops *ops,
-                     void *h,
-                     const char *node,
-                     char **dir,
-                     unsigned int numdirs,
-                     unsigned int depth)
-{
-       char *ret = talloc_strdup(node, "");
-       unsigned int i;
-       char spacing[depth+1];
-
-       memset(spacing, ' ', depth);
-       spacing[depth] = '\0';
-
-       sort_dir(dir, numdirs);
-
-       for (i = 0; i < numdirs; i++) {
-               struct xs_permissions *perms;
-               unsigned int j, numperms;
-               unsigned int len;
-               char *contents;
-               unsigned int subnum;
-               char **subdirs;
-               char *subret;
-               char *subnode = talloc_asprintf(node, "%s/%s", node, dir[i]);
-
-               perms = ops->get_perms(h, subnode, &numperms);
-               if (!perms)
-                       return NULL;
-               ret = talloc_asprintf_append(ret, "%s%s: ", spacing, dir[i]);
-               for (j = 0; j < numperms; j++) {
-                       char buffer[100];
-                       if (!xs_perm_to_string(&perms[j], buffer))
-                               barf("perm to string");
-                       ret = talloc_asprintf_append(ret, "%s ", buffer);
-               }
-               free(perms);
-               ret = talloc_asprintf_append(ret, "\n");
-
-               /* Even directories can have contents. */
-               contents = ops->read(h, subnode, &len);
-               if (!contents) {
-                       if (errno != EISDIR)
-                               return NULL;
-               } else {
-                       ret = talloc_asprintf_append(ret, " %s(%.*s)\n",
-                                                    spacing, len, contents);
-                       free(contents);
-               }                       
-
-               /* Every node is a directory. */
-               subdirs = ops->dir(h, subnode, &subnum);
-               if (!subdirs)
-                       return NULL;
-               subret = dump_dir(ops, h, subnode, subdirs, subnum, depth+1);
-               if (!subret)
-                       return NULL;
-               ret = talloc_asprintf_append(ret, "%s", subret);
-               free(subdirs);
-       }
-       return ret;
-}
-
-static char *dump(struct ops *ops, void *h)
-{
-       char **subdirs;
-       unsigned int subnum;
-       char *ret = NULL, *root = talloc_strdup(NULL, "/");
-
-       subdirs = ops->dir(h, root, &subnum);
-       if (subdirs) {
-               ret = dump_dir(ops, h, talloc_strdup(root, ""), subdirs,
-                              subnum, 0);
-               free(subdirs);
-               if (ret)
-                       talloc_steal(NULL, ret);
-       }
-       talloc_free(root);
-       return ret;
-}
-
-/* jhash.h: Jenkins hash support.
- *
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@xxxxxxxxxxxxxxxx)
- *
- * http://burtleburtle.net/bob/hash/
- *
- * These are the credits from Bob's sources:
- *
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose.  It has no warranty.
- *
- * Copyright (C) 2003 David S. Miller (davem@xxxxxxxxxx)
- *
- * I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault.  -DaveM
- */
-
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<<8); \
-  c -= a; c -= b; c ^= (b>>13); \
-  a -= b; a -= c; a ^= (c>>12);  \
-  b -= c; b -= a; b ^= (a<<16); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>3);  \
-  b -= c; b -= a; b ^= (a<<10); \
-  c -= a; c -= b; c ^= (b>>15); \
-}
-
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO     0x9e3779b9
-
-/* The most generic version, hashes an arbitrary sequence
- * of bytes.  No alignment or length assumptions are made about
- * the input key.
- */
-static inline uint32_t jhash(const void *key, uint32_t length, uint32_t 
initval)
-{
-       uint32_t a, b, c, len;
-       const uint8_t *k = key;
-
-       len = length;
-       a = b = JHASH_GOLDEN_RATIO;
-       c = initval;
-
-       while (len >= 12) {
-               a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) 
+((uint32_t)k[3]<<24));
-               b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) 
+((uint32_t)k[7]<<24));
-               c += (k[8] +((uint32_t)k[9]<<8) 
+((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24));
-
-               __jhash_mix(a,b,c);
-
-               k += 12;
-               len -= 12;
-       }
-
-       c += length;
-       switch (len) {
-       case 11: c += ((uint32_t)k[10]<<24);
-       case 10: c += ((uint32_t)k[9]<<16);
-       case 9 : c += ((uint32_t)k[8]<<8);
-       case 8 : b += ((uint32_t)k[7]<<24);
-       case 7 : b += ((uint32_t)k[6]<<16);
-       case 6 : b += ((uint32_t)k[5]<<8);
-       case 5 : b += k[4];
-       case 4 : a += ((uint32_t)k[3]<<24);
-       case 3 : a += ((uint32_t)k[2]<<16);
-       case 2 : a += ((uint32_t)k[1]<<8);
-       case 1 : a += k[0];
-       };
-
-       __jhash_mix(a,b,c);
-
-       return c;
-}
-
-/* A special optimized version that handles 1 or more of uint32_ts.
- * The length parameter here is the number of uint32_ts in the key.
- */
-static inline uint32_t jhash2(uint32_t *k, uint32_t length, uint32_t initval)
-{
-       uint32_t a, b, c, len;
-
-       a = b = JHASH_GOLDEN_RATIO;
-       c = initval;
-       len = length;
-
-       while (len >= 3) {
-               a += k[0];
-               b += k[1];
-               c += k[2];
-               __jhash_mix(a, b, c);
-               k += 3; len -= 3;
-       }
-
-       c += length * 4;
-
-       switch (len) {
-       case 2 : b += k[1];
-       case 1 : a += k[0];
-       };
-
-       __jhash_mix(a,b,c);
-
-       return c;
-}
-
-
-/* A special ultra-optimized versions that knows they are hashing exactly
- * 3, 2 or 1 word(s).
- *
- * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
- *       done at the end is not done here.
- */
-static inline uint32_t jhash_3words(uint32_t a, uint32_t b, uint32_t c, 
uint32_t initval)
-{
-       a += JHASH_GOLDEN_RATIO;
-       b += JHASH_GOLDEN_RATIO;
-       c += initval;
-
-       __jhash_mix(a, b, c);
-
-       return c;
-}
-
-static inline uint32_t jhash_2words(uint32_t a, uint32_t b, uint32_t initval)
-{
-       return jhash_3words(a, b, 0, initval);
-}
-
-static inline uint32_t jhash_1word(uint32_t a, uint32_t initval)
-{
-       return jhash_3words(a, 0, 0, initval);
-}
-
-static unsigned int get_randomness(int *state)
-{
-       return jhash_1word((*state)++, *state * 1103515243);
-}
-
-static char *random_path(int *state)
-{
-       unsigned int i;
-       char *ret = NULL;
-
-       if (get_randomness(state) % 20 == 0)
-               return talloc_strdup(NULL, "/");
-
-       for (i = 0; i < 1 || (get_randomness(state) % 2); i++) {
-               ret = talloc_asprintf_append(ret, "/%i", 
-                                            get_randomness(state) % 15);
-       }
-       return ret;
-}
-
-static char *bool_to_errstring(bool result)
-{
-       if (result)
-               return talloc_strdup(NULL, "OK");
-
-       /* Real daemon can never return this. */
-       if (errno == ENOTDIR)
-               errno = ENOENT;
-       return talloc_asprintf(NULL, "FAILED:%s", strerror(errno));
-}
-
-static char *linearize_dir(char **dir, unsigned int *num)
-{
-       char *result = NULL;
-       unsigned int i;
-
-       if (!dir)
-               return bool_to_errstring(false);
-
-       if (!*num) {
-               free(dir);
-               return talloc_strdup(NULL, "");
-       }
-
-       sort_dir(dir, *num);
-       for (i = 0; i < *num; i++)
-               result = talloc_asprintf_append(result, "%s\n", dir[i]);
-       free(dir);
-       return result;
-}
-
-static char *linearize_read(char *read, unsigned int *size)
-{
-       char *ret;
-
-       if (!read)
-               return bool_to_errstring(false);
-
-       ret = talloc_asprintf(NULL, "%i:%.*s", *size, *size, read);
-       free(read);
-       return ret;
-}
-
-static char *linearize_perms(struct xs_permissions *perms, unsigned int *size)
-{
-       char *ret = NULL;
-       unsigned int i;
-
-       if (!perms)
-               return bool_to_errstring(false);
-
-       for (i = 0; i < *size; i++)
-               ret = talloc_asprintf_append(ret, "(%u %u)",
-                                            perms[i].id, perms[i].perms);
-
-       free(perms);
-       return ret;
-}
-
-/* Do the next operation, return the results. */
-static char *do_next_op(struct ops *ops, void *h, int state, bool verbose)
-{
-       char *name;
-       unsigned int num;
-       char *ret;
-
-       if (verbose)
-               printf("State %i: ", state);
-
-       name = random_path(&state);
-       switch (get_randomness(&state) % 9) {
-       case 0:
-               if (verbose)
-                       printf("DIR %s\n", name);
-               ret = linearize_dir(ops->dir(h, name, &num), &num);
-               break;
-       case 1:
-               if (verbose)
-                       printf("READ %s\n", name);
-               ret = linearize_read(ops->read(h, name, &num), &num);
-               break;
-       case 2: {
-               char *contents = talloc_asprintf(NULL, "%i",
-                                                get_randomness(&state));
-               unsigned int len = get_randomness(&state)%(strlen(contents)+1);
-               if (verbose)
-                       printf("WRITE %s %.*s\n", name, len, contents);
-               ret = bool_to_errstring(ops->write(h, name, contents, len));
-               talloc_steal(ret, contents);
-               break;
-       }
-       case 3:
-               if (verbose)
-                       printf("MKDIR %s\n", name);
-               ret = bool_to_errstring(ops->mkdir(h, name));
-               break;
-       case 4:
-               if (verbose)
-                       printf("RM %s\n", name);
-               ret = bool_to_errstring(ops->rm(h, name));
-               break;
-       case 5:
-               if (verbose)
-                       printf("GETPERMS %s\n", name);
-               ret = linearize_perms(ops->get_perms(h, name, &num),
-                                     &num);
-               break;
-       case 6: {
-               unsigned int i, num = get_randomness(&state)%8;
-               struct xs_permissions perms[num];
-
-               if (verbose)
-                       printf("SETPERMS %s: ", name);
-               for (i = 0; i < num; i++) {
-                       perms[i].id = get_randomness(&state)%8;
-                       perms[i].perms = get_randomness(&state)%4;
-                       if (verbose)
-                               printf("%i%c ", perms[i].id,
-                                      perms[i].perms == XS_PERM_WRITE ? 'W'
-                                      : perms[i].perms == XS_PERM_READ ? 'R'
-                                      : perms[i].perms == 
-                                      (XS_PERM_READ|XS_PERM_WRITE) ? 'B'
-                                      : 'N');
-               }
-               if (verbose)
-                       printf("\n");
-               ret = bool_to_errstring(ops->set_perms(h, name, perms,
-                                                      num));
-               break;
-       }
-       case 7: {
-               if (verbose)
-                       printf("START %s\n", name);
-               ret = bool_to_errstring(ops->transaction_start(h));
-               if (streq(ret, "OK")) {
-                       talloc_free(ret);
-                       ret = talloc_asprintf(NULL, "OK:START-TRANSACT");
-               }
-
-               break;
-       }
-       case 8: {
-               bool abort = (get_randomness(&state) % 2);
-
-               if (verbose)
-                       printf("STOP %s\n", abort ? "ABORT" : "COMMIT");
-               ret = bool_to_errstring(ops->transaction_end(h, abort));
-               if (streq(ret, "OK")) {
-                       talloc_free(ret);
-                       ret = talloc_strdup(NULL, "OK:STOP-TRANSACT");
-               }
-               break;
-       }
-       default:
-               barf("Impossible randomness");
-       }
-
-       talloc_steal(ret, name);
-       return ret;
-}
-
-static int daemon_pid;
-
-static void cleanup_xs_ops(void)
-{
-       char *cmd;
-
-       if (daemon_pid) {
-               kill(daemon_pid, SIGTERM);
-               waitpid(daemon_pid, NULL, 0);
-               daemon_pid = 0;
-       }
-       
-       cmd = talloc_asprintf(NULL, "rm -rf testsuite/tmp/*");
-       do_command(cmd);
-       talloc_free(cmd);
-}
-
-static void cleanup_file_ops(const char *dir)
-{
-       char *cmd;
-
-       cmd = talloc_asprintf(NULL, "rm -rf %s %s.transact", dir, dir);
-       do_command(cmd);
-       talloc_free(cmd);
-}
-
-static void cleanup(const char *dir)
-{
-       cleanup_xs_ops();
-       cleanup_file_ops(dir);
-}
-
-static void setup_file_ops(const char *dir)
-{
-       struct xs_permissions perm = { .id = 0, .perms = XS_PERM_READ };
-       struct file_ops_info *h = file_handle(dir);
-       if (mkdir(dir, 0700) != 0)
-               barf_perror("Creating directory %s", dir);
-       if (mkdir(talloc_asprintf(h, "%s/tool", dir), 0700) != 0)
-               barf_perror("Creating directory %s/tool", dir);
-       if (!file_set_perms(h, talloc_strdup(h, "/"), &perm, 1))
-               barf_perror("Setting root perms in %s", dir);
-       if (!file_set_perms(h, talloc_strdup(h, "/tool"), &perm, 1))
-               barf_perror("Setting root perms in %s/tool", dir);
-       file_close(h);
-}
-
-static void setup_xs_ops(void)
-{
-       int fds[2];
-
-       /* Start daemon. */
-       pipe(fds);
-       if ((daemon_pid = fork())) {
-               /* Child writes PID when its ready: we wait for that. */
-               char buffer[20];
-               close(fds[1]);
-               if (read(fds[0], buffer, sizeof(buffer)) < 0)
-                       barf("Failed to summon daemon");
-               close(fds[0]);
-       } else {
-               dup2(fds[1], STDOUT_FILENO);
-               close(fds[0]);
-#if 1
-               execlp("valgrind", "valgrind", "-q", 
"--suppressions=testsuite/vg-suppressions", "xenstored_test", "--output-pid",
-                      "--no-fork", NULL);
-#else
-               execlp("./xenstored_test", "xenstored_test", "--output-pid",
-                      "--no-fork", NULL);
-#endif
-               exit(1);
-       }
-}
-
-static void setup(const char *dir)
-{
-       setup_file_ops(dir);
-       setup_xs_ops();
-};
-
-struct simple_data
-{
-       unsigned int seed;
-       bool print_progress;
-       bool fast;
-       struct ops *ops;
-       const char *dir;
-};
-
-/* Just a random test.  Don't care about results, just that it doesn't
- * go boom. */
-static unsigned int try_simple(const bool *trymap,
-                              unsigned int number,
-                              bool verbose,
-                              void *_data)
-{
-       unsigned int i, print;
-       void *h;
-       char *snapshot = NULL;
-       struct simple_data *data = _data;
-
-       if (data->ops == &xs_ops) {
-               cleanup_xs_ops();
-               setup_xs_ops();
-       } else {
-               cleanup_file_ops(data->dir);
-               setup_file_ops(data->dir);
-       }
-       h = data->ops->handle(data->dir);
-
-       print = number / 76;
-       if (!print)
-               print = 1;
-
-       for (i = 0; i < number; i++) {
-               char *ret;
-
-               if (data->print_progress) {
-                       if (i % print == 0) {
-                               printf(".");
-                               fflush(stdout);
-                       }
-               }
-
-               if (trymap && !trymap[i])
-                       continue;
-
-               ret = do_next_op(data->ops, h, i + data->seed, verbose);
-               if (verbose)
-                       printf("-> %.*s\n",
-                              (int)(strchr(ret, '\n') - ret), ret);
-               if (streq(ret, "FAILED:Bad file descriptor"))
-                       goto out;
-               if (kill(daemon_pid, 0) != 0)
-                       goto out;
-
-               if (!data->fast) {
-                       if (streq(ret, "OK:START-TRANSACT")) {
-                               void *pre = data->ops->handle(data->dir);
-
-                               snapshot = dump(data->ops, pre);
-                               if (!snapshot)
-                                       goto out;
-                               data->ops->close(pre);
-                       } else if (streq(ret, "OK:STOP-TRANSACT")) {
-                               talloc_free(snapshot);
-                               snapshot = NULL;
-                       }
-               }
-
-               talloc_free(ret);
-
-               if (snapshot) {
-                       void *pre = data->ops->handle(data->dir);
-                       char *contents;
-
-                       contents = dump(data->ops, pre);
-                       if (!contents)
-                               goto out;
-
-                       if (!streq(contents, snapshot))
-                               goto out;
-
-                       talloc_free(contents);
-                       data->ops->close(pre);
-               }
-       }
-out:
-       data->ops->close(h);    
-       return i;
-}
-
-/* Binary elimination: try eliminating all of them, then reduce. */
-static void reduce(bool *map,
-                  unsigned int number,
-                  unsigned int try_start, unsigned int try_num,
-                  unsigned int (*try)(const bool *map,
-                                      unsigned int number,
-                                      bool verbose,
-                                      void *),
-                  void *data)
-{
-       bool newmap[number];
-
-       if (try_num == 0)
-               return;
-
-       /* Try skipping everything between start and end.  */
-       memcpy(newmap, map, sizeof(newmap));
-       memset(newmap + try_start, 0, try_num * sizeof(bool));
-
-       /* We want the *same* failure: must fail at "number-1". */
-       if (try(newmap, number, false, data) == number - 1) {
-               memset(map + try_start, 0, try_num * sizeof(bool));
-               return;
-       }
-
-       if (try_num == 1)
-               return;
-
-       /* Try each half... */
-       reduce(map, number, try_start, try_num/2, try, data);
-       reduce(map, number, try_start + try_num/2, try_num - try_num/2,
-              try, data);
-}
-
-static void reduce_problem(unsigned int failed,
-                          unsigned int (*try)(const bool *map,
-                                              unsigned int number,
-                                              bool verbose,
-                                              void *data),
-                          void *data)
-{
-       bool map[failed];
-
-       memset(map, 1, sizeof(map));
-       reduce(map, failed, 0, failed-1, try, data);
-
-       printf("Cut down:\n");
-       if (try(map, failed, true, data) != failed - 1) {
-               printf("Except, that didn't actually fail.  Bugger!");
-               exit(2);
-       }
-       exit(1);
-}
-
-/* Just a random test.  Don't care about results, just that it doesn't
- * go boom. */
-static void simple_test(const char *dir,
-                       unsigned int iters, unsigned int seed,
-                       bool fast, bool verbose)
-{
-       struct simple_data data;
-       unsigned int try;
-
-       data.seed = seed;
-       data.print_progress = !verbose;
-       data.fast = fast;
-       data.ops = &xs_ops;
-       data.dir = dir;
-
-       try = try_simple(NULL, iters, verbose, &data);
-       if (try == iters) {
-               cleanup_xs_ops();
-               exit(0);
-       }
-       printf("Failed on iteration %u of seed %u\n", try + 1, seed);
-       data.print_progress = false;
-       reduce_problem(try + 1, try_simple, &data);
-}
-
-static bool ops_equal(struct ops *a, void *ah,
-                     struct ops *b, void *bh,
-                     const char *node,
-                     struct ops **fail)
-{
-       char **dira = NULL, **dirb = NULL;
-       char *dataa = NULL, *datab = NULL;
-       unsigned int i, numa, numb, lena, lenb;
-       struct xs_permissions *permsa = NULL, *permsb = NULL;
-       unsigned int numpermsa, numpermsb;
-       char *nodename;
-       bool ret = false;
-
-       /* Ignore tool/ dir. */
-       if (streq(node, "/tool"))
-               return true;
-
-       /* FILE backend expects talloc'ed pointer. */
-       nodename = talloc_strdup(NULL, node);
-       permsa = a->get_perms(ah, nodename, &numpermsa);
-       if (!permsa) {
-               *fail = a;
-               goto out;
-       }
-       permsb = b->get_perms(bh, nodename, &numpermsb);
-       if (!permsb) {
-               *fail = b;
-               goto out;
-       }
-       if (numpermsa != numpermsb)
-               goto out;
-       for (i = 0; i < numpermsa; i++) {
-               if (permsa[i].perms != permsb[i].perms)
-                       goto out;
-               if (permsa[i].id != permsb[i].id)
-                       goto out;
-       }
-
-       /* Non-pure-directory nodes contain data. */
-       dataa = a->read(ah, nodename, &lena);
-       if (!dataa && errno != EISDIR) {
-               *fail = a;
-               goto out;
-       }
-       datab = b->read(bh, nodename, &lenb);
-       if (!datab && errno != EISDIR) {
-               *fail = b;
-               goto out;
-       }
-
-       if (dataa) {
-               if (!datab)
-                       goto out;
-               if (lena != lenb)
-                       goto out;
-
-               if (memcmp(dataa, datab, lena) != 0)
-                       goto out;
-       } else
-               if (datab)
-                       goto out;
-
-       /* Everything is a directory. */
-       dira = a->dir(ah, nodename, &numa);
-       if (!dira) {
-               *fail = a;
-               goto out;
-       }
-       dirb = b->dir(bh, nodename, &numb);
-       if (!dirb) {
-               *fail = b;
-               goto out;
-       }
-       if (numa != numb)
-               goto out;
-       sort_dir(dira, numa);
-       sort_dir(dirb, numb);
-       for (i = 0; i < numa; i++) {
-               char subnode[strlen(node) + 1 + strlen(dira[i]) + 1];
-
-               if (!streq(dira[i], dirb[i]))
-                       goto out;
-
-               strcpy(subnode, node);
-               if (!streq(node, "/"))
-                       strcat(subnode, "/");
-               strcat(subnode, dira[i]);
-               if (!ops_equal(a, ah, b, bh, subnode, fail))
-                       goto out;
-       }
-
-       ret = true;
-out:
-       free(permsa);
-       free(permsb);
-       free(dataa);
-       free(datab);
-       free(dira);
-       free(dirb);
-       talloc_free(nodename);
-       return ret;
-}
-
-struct diff_data
-{
-       unsigned int seed;
-       bool print_progress;
-       bool fast;
-       const char *dir;
-};
-
-/* Differential: try both file and xs backend, watch for differences. */
-static unsigned int try_diff(const bool *trymap,
-                            unsigned int number,
-                            bool verbose,
-                            void *_data)
-{
-       void *fileh, *xsh;
-       bool transact = false;
-       struct ops *fail;
-       struct diff_data *data = _data;
-       unsigned int i, print;
-
-       cleanup(data->dir);
-       setup(data->dir);
-
-       fileh = file_handle(data->dir);
-       xsh = xs_handle(data->dir);
-
-       print = number / 76;
-       if (!print)
-               print = 1;
-
-       for (i = 0; i < number; i++) {
-               char *file, *xs;
-
-               if (data->print_progress) {
-                       if (i % print == 0) {
-                               printf(".");
-                               fflush(stdout);
-                       }
-               }
-               if (trymap && !trymap[i])
-                       continue;
-
-               if (verbose)
-                       printf("FILE: ");
-
-               file = do_next_op(&file_ops, fileh, i+data->seed, verbose);
-               if (verbose)
-                       printf("-> %.*s\n",
-                              (int)(strchr(file, '/') - file), file);
-               
-               if (verbose)
-                       printf("XS: ");
-               xs = do_next_op(&xs_ops, xsh, i+data->seed, verbose);
-               if (verbose)
-                       printf("-> %.*s\n", (int)(strchr(xs, '/') - xs), xs);
-
-               if (!streq(file, xs))
-                       goto out;
-
-               if (strstarts(file, "OK:START-TRANSACT:"))
-                       transact = true;
-               else if (streq(file, "OK:STOP-TRANSACT"))
-                       transact = false;
-
-               talloc_free(file);
-               talloc_free(xs);
-
-               if (data->fast)
-                       continue;
-
-               fail = NULL;
-               if (!ops_equal(&xs_ops, xsh, &file_ops, fileh, "/", &fail)) {
-                       if (fail)
-                               barf("%s failed during test\n", fail->name);
-                       if (verbose)
-                               printf("Trees differ:\nXS:%s\nFILE%s\n",
-                                      dump(&xs_ops, xsh),
-                                      dump(&file_ops, fileh));
-                       goto out;
-               }
-
-               if (transact) {
-                       void *fileh_pre = file_handle(data->dir);
-                       void *xsh_pre = xs_handle(data->dir);
-
-                       fail = NULL;
-                       if (!ops_equal(&xs_ops, xsh_pre, &file_ops, fileh_pre,
-                                      "/", &fail)) {
-                               if (fail)
-                                       barf("%s failed during transact\n",
-                                            fail->name);
-
-                               xs_daemon_close(xsh_pre);
-                               talloc_free(fileh_pre);
-                               goto out;
-                       }
-                       xs_daemon_close(xsh_pre);
-                       talloc_free(fileh_pre);
-               }
-       }
-
-       fail = NULL;
-       if (data->fast)
-               if (!ops_equal(&xs_ops, xsh, &file_ops, fileh, "/", &fail))
-                       barf("Final result not the same: try without --fast");
-out:
-       file_ops.close(fileh);  
-       xs_ops.close(xsh);      
-       return i;
-}
-
-/* Differential random test: compare results against file backend. */
-static void diff_test(const char *dir,
-                     unsigned int iters, unsigned int seed, bool fast, 
-                     bool verbose)
-{
-       struct diff_data data;
-       unsigned int try;
-
-       data.seed = seed;
-       data.print_progress = !verbose;
-       data.fast = fast;
-       data.dir = dir;
-
-       try = try_diff(NULL, iters, verbose, &data);
-       if (try == iters) {
-               cleanup_xs_ops();
-               exit(0);
-       }
-       printf("Failed on iteration %u of seed %u\n", try + 1, seed);
-       data.print_progress = false;
-       reduce_problem(try + 1, try_diff, &data);
-}
-
-struct fail_data
-{
-       unsigned int seed;
-       bool print_progress;
-       const char *dir;
-};
-
-/* Try xs with inserted failures: every op should either succeed or fail. */
-static unsigned int try_fail(const bool *trymap,
-                             unsigned int number,
-                             bool verbose,
-                             void *_data)
-{
-       unsigned int i, print, tried = 0, aborted = 0;
-       struct fail_data *data = _data;
-       struct xs_handle *tmpxsh;
-       struct file_ops_info *tmpfileh;
-       void *fileh, *xsh;
-       struct ops *fail;
-       char seed[20];
-
-       /* Make sure failures off to shut down. */
-       if (daemon_pid)
-               kill(daemon_pid, SIGUSR1);
-       cleanup(data->dir);
-       setup(data->dir);
-
-       fileh = file_handle(data->dir);
-       xsh = xs_handle(data->dir);
-
-       print = number / 76;
-       if (!print)
-               print = 1;
-
-       for (i = 0; i < number; i++) {
-               unsigned int limit, failed;
-               char *ret;
-
-               /* A few times we fail due to other end OOM. */
-               limit = 0;
-               while (!xsh) {
-                       xsh = xs_handle(data->dir);
-                       if (!xsh && errno == ECONNREFUSED) {
-                               if (verbose)
-                                       printf("Daemon refused connection\n");
-                               goto out;
-                       }
-                       if (!xsh && limit++ == 5) {
-                               printf("Daemon failed conn 5 times\n");
-                               goto out;
-                       }
-               }
-
-               if (data->print_progress) {
-                       if (i % print == 0) {
-                               printf(".");
-                               fflush(stdout);
-                       }
-               }
-               if (trymap && !trymap[i])
-                       continue;
-
-               /* Turn on failure. */
-               sprintf(seed, "%i", data->seed + i);
-               free(xs_debug_command(xsh, "failtest",seed,strlen(seed)+1));
-
-               if (verbose)
-                       printf("(%i) seed %s ", i, seed);
-               ret = do_next_op(&xs_ops, xsh, i + data->seed, verbose);
-               if (streq(ret, "FAILED:Connection reset by peer")
-                   || streq(ret, "FAILED:Bad file descriptor")
-                   || streq(ret, "FAILED:Broken pipe")) {
-                       xs_close(xsh);
-                       xsh = NULL;
-                       failed = 2;
-               } else if (strstarts(ret, "OK"))
-                       failed = 0;
-               else
-                       failed = 1;
-
-               tried++;
-               if (xsh)
-                       aborted++;
-
-               if (verbose)
-                       printf("-> %.*s\n",
-                              (int)(strchr(ret, '\n') - ret), ret);
-
-               talloc_free(ret);
-
-               /* Turn off failures using signal. */
-               if (kill(daemon_pid, SIGUSR1) != 0) {
-                       if (verbose)
-                               printf("Failed to signal daemon\n");
-                       goto out;
-               }
-
-               if (failed == 0) {
-                       /* Succeeded?  Do same thing to file backend
-                        * to compare */
-               try_applying:
-                       ret = do_next_op(&file_ops, fileh, i + data->seed,
-                                        false);
-                       if (!strstarts(ret, "OK")) {
-                               if (!verbose)
-                                       printf("File op failed on %i\n",
-                                              i + data->seed);
-                               talloc_free(ret);
-                               goto out;
-                       }
-                       talloc_free(ret);
-               }
-
-               tmpxsh = xs_handle(data->dir);
-               if (!tmpxsh) {
-                       if (verbose)
-                               printf("Failed to open signalled daemon");
-                       goto out;
-               }
-               tmpfileh = file_handle(data->dir);
-
-               fail = NULL;
-               if (!ops_equal(&xs_ops, tmpxsh, &file_ops, tmpfileh, "/",
-                              &fail)) {
-                       if (fail) {
-                               if (verbose)
-                                       printf("%s failed\n", fail->name);
-                               goto out;
-                       }
-                       /* Maybe op succeeded: try comparing after local op? */
-                       if (failed == 2) {
-                               failed = 0;
-                               if (verbose)
-                                       printf("(Looks like it succeeded)\n");
-                               xs_close(tmpxsh);
-                               file_close(tmpfileh);
-                               goto try_applying;
-                       }
-                       if (verbose)
-                               printf("Trees differ:\nXS:%s\nFILE:%s\n",
-                                      dump(&xs_ops, tmpxsh),
-                                      dump(&file_ops, tmpfileh));
-                       xs_close(tmpxsh);
-                       file_close(tmpfileh);
-                       goto out;
-               }
-
-               /* If we lost the xs handle, that ended the transaction */
-               if (!xsh)
-                       file_transaction_end(fileh, true);
-
-               xs_close(tmpxsh);
-               file_close(tmpfileh);
-       }
-out:
-       if (xsh)
-               xs_close(xsh);
-       return i;
-}
-
-static void fail_test(const char *dir,
-                     unsigned int iters, unsigned int seed,
-                     bool fast __attribute__((unused)), bool verbose)
-{
-       struct fail_data data;
-       unsigned int try;
-
-       data.seed = seed;
-       data.print_progress = !verbose;
-       data.dir = dir;
-
-       try = try_fail(NULL, iters, verbose, &data);
-       if (try == iters) {
-               cleanup_xs_ops();
-               exit(0);
-       }
-       printf("Failed on iteration %u of seed %u\n", try + 1, seed);
-       fflush(stdout);
-       data.print_progress = false;
-       reduce_problem(try + 1, try_fail, &data);
-}
-
-int main(int argc, char *argv[])
-{
-       bool verbose = false;
-       bool simple = false;
-       bool fast = false;
-       bool fail = false;
-
-       if (argv[1] && streq(argv[1], "--fail")) {
-               fail = true;
-               argv++;
-               argc--;
-       }
-
-       if (argv[1] && streq(argv[1], "--simple")) {
-               simple = true;
-               argv++;
-               argc--;
-       }
-
-       if (argv[1] && streq(argv[1], "--fast")) {
-               fast = true;
-               argv++;
-               argc--;
-       }
-
-       if (argv[1] && streq(argv[1], "--verbose")) {
-               verbose = true;
-               argv++;
-               argc--;
-       }
-
-       if (argc != 4)
-               barf("Usage: xs_random [--fail|--simple] [--fast] [--verbose] 
<directory> <iterations> <seed>");
-
-       talloc_enable_null_tracking();
-
-       if (fail)
-               fail_test(argv[1], atoi(argv[2]), atoi(argv[3]), fast, verbose);
-       else if (simple)
-               simple_test(argv[1], atoi(argv[2]), atoi(argv[3]), fast, 
verbose);
-       else
-               diff_test(argv[1],  atoi(argv[2]), atoi(argv[3]), fast, 
verbose);
-       exit(2);
-}
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xs_stress.c
--- a/tools/xenstore/xs_stress.c        Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/* Stress test for Xen Store: multiple people hammering transactions */
-#include "xs.h"
-#include "utils.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#define NUM_HANDLES 2
-#define DIR_FANOUT 3
-#define DIR_DEPTH 3
-
-/* How often to print progress */
-static int print;
-
-/* Layout looks like /<num>/<num>/count. */
-static void work(unsigned int cycles, unsigned int childnum)
-{
-       unsigned int i;
-       struct xs_handle *handles[NUM_HANDLES];
-       char id;
-
-       if (childnum < 10)
-               id = '0' + childnum;
-       else
-               id = 'A' + childnum - 10;
-
-       for (i = 0; i < NUM_HANDLES; i++) {
-               handles[i] = xs_daemon_open();
-               if (!handles[i])
-                       barf_perror("Opening handle %i", i);
-       }
-
-       srandom(childnum);
-       for (i = 0; i < cycles; i++) {
-               unsigned int j, len;
-               char file[100] = "";
-               char *contents, tmp[100];
-               struct xs_handle *h = handles[random() % NUM_HANDLES];
-
-               for (j = 0; j < DIR_DEPTH; j++)
-                       sprintf(file + strlen(file), "/%li",
-                               random()%DIR_FANOUT);
-
-               if (!xs_transaction_start(h))
-                       barf_perror("%i: starting transaction %i",
-                                   childnum, i);
-
-               sprintf(file + strlen(file), "/count");
-               contents = xs_read(h, file, &len);
-               if (!contents)
-                       barf_perror("%i: can't read %s iter %i",
-                                   childnum, file, i);
-               sprintf(tmp, "%i", atoi(contents) + 1);
-               if (!xs_write(h, file, tmp, strlen(tmp)+1))
-                       barf_perror("%i: can't write %s iter %i",
-                                   childnum, file, i);
-
-               /* Abandon 1 in 10 */
-               if (random() % 10 == 0) {
-                       if (!xs_transaction_end(h, true))
-                               barf_perror("%i: can't abort transact",
-                                           childnum);
-                       i--;
-               } else {
-                       if (!xs_transaction_end(h, false)) {
-                               if (errno == EAGAIN) {
-                                       write(STDOUT_FILENO, "!", 1);
-                                       i--;
-                               } else
-                                       barf_perror("%i: can't commit trans",
-                                                   childnum);
-                       } else {
-                               /* Offset when we print . so kids don't all
-                                * print at once. */
-                               if ((i + print/(childnum+1)) % print == 0)
-                                       write(STDOUT_FILENO, &id, 1);
-                       }
-               }
-       }
-}
-
-static void create_dirs(struct xs_handle *h, const char *base, int togo)
-{
-       unsigned int i;
-       char filename[100];
-
-       if (togo == 0) {
-               sprintf(filename, "%s/count", base);
-               if (!xs_write(h, filename, "0", 1))
-                       barf_perror("Writing to %s", filename);
-               return;
-       }
-
-       for (i = 0; i < DIR_FANOUT; i++) {
-               sprintf(filename, "%s/%i", base, i);
-               if (!xs_mkdir(h, filename))
-                       barf_perror("xs_mkdir %s", filename);
-               create_dirs(h, filename, togo-1);
-       }
-}
-
-static unsigned int add_count(struct xs_handle *h, const char *base, int togo)
-{
-       unsigned int i, count;
-       char filename[100];
-
-       if (togo == 0) {
-               char *answer;
-               unsigned int len;
-
-               sprintf(filename, "%s/count", base);
-               answer = xs_read(h, filename, &len);
-               if (!answer)
-                       barf_perror("Reading %s", filename);
-               count = atoi(answer);
-               free(answer);
-               return count;
-       }
-
-       count = 0;
-       for (i = 0; i < DIR_FANOUT; i++) {
-               sprintf(filename, "%s/%i", base, i);
-               count += add_count(h, filename, togo-1);
-       }
-       return count;
-}
-
-static void setup(void)
-{
-       struct xs_handle *h;
-
-       /* Do setup. */
-       h = xs_daemon_open();
-       if (!h)
-               barf_perror("Contacting daemon");
-       create_dirs(h, "", DIR_DEPTH);
-       xs_daemon_close(h);
-}
-
-static unsigned int tally_counts(void)
-{
-       struct xs_handle *h;
-       unsigned int ret;
-       
-       h = xs_daemon_open();
-       if (!h)
-               barf_perror("Contacting daemon");
-
-       ret = add_count(h, "", DIR_DEPTH);
-       xs_daemon_close(h);
-       return ret;
-}      
-
-int main(int argc, char *argv[])
-{
-       unsigned int i;
-       bool failed = false;
-       int kids[10];
-
-       if (argc != 2)
-               barf("Usage: xs_stress <iterations>");
-
-       printf("Setting up directories...\n");
-       setup();
-
-       print = atoi(argv[1]) / 76;
-       if (!print)
-               print = 1;
-
-       printf("Running %i children...\n", ARRAY_SIZE(kids));
-       for (i = 0; i < ARRAY_SIZE(kids); i++) {
-               kids[i] = fork();
-               if (kids[i] == -1)
-                       barf_perror("fork");
-               if (kids[i] == 0) {
-                       work(atoi(argv[1]) / ARRAY_SIZE(kids), i);
-                       exit(0);
-               }
-       }
-
-       for (i = 0; i < ARRAY_SIZE(kids); i++) {
-               int status;
-               if (waitpid(kids[i], &status, 0) == -1)
-                       barf_perror("waitpid");
-               if (!WIFEXITED(status))
-                       barf("Kid %i died via signal %i\n",
-                            i, WTERMSIG(status));
-               if (WEXITSTATUS(status) != 0) {
-                       printf("Child %i exited %i\n", i, WEXITSTATUS(status));
-                       failed = true;
-               }
-       }
-       if (failed)
-               exit(1);
-
-       printf("\nCounting results...\n");
-       i = tally_counts();
-       if (i != (unsigned)atoi(argv[1]))
-               barf("Total counts %i not %s", i, argv[1]);
-       printf("Success!\n");
-       exit(0);
-}
diff -r 0528bc25c404 -r eb71f258e855 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c  Tue Jul 03 15:49:16 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,812 +0,0 @@
-/* 
-    Xen Store Daemon Test tool
-    Copyright (C) 2005 Rusty Russell IBM Corporation
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <fnmatch.h>
-#include <stdarg.h>
-#include <string.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <sys/time.h>
-#include "utils.h"
-#include "xs_lib.h"
-#include "xs.h"
-#include "list.h"
-
-#define XSTEST
-
-static struct xs_handle *handles[10] = { NULL };
-static xs_transaction_t txh[10] = { XBT_NULL };
-
-static unsigned int timeout_ms = 500;
-static bool timeout_suppressed = true;
-static bool readonly = false;
-static bool print_input = false;
-static unsigned int linenum = 0;
-
-static int daemon_pid;
-static struct xenstore_domain_interface *interface;
-
-/* FIXME: Mark connection as broken (close it?) when this happens. */
-static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-{
-       return ((prod - cons) <= XENSTORE_RING_SIZE);
-}
-
-static void *get_output_chunk(XENSTORE_RING_IDX cons,
-                             XENSTORE_RING_IDX prod,
-                             char *buf, uint32_t *len)
-{
-       *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
-       if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
-               *len = XENSTORE_RING_SIZE - (prod - cons);
-       return buf + MASK_XENSTORE_IDX(prod);
-}
-
-static const void *get_input_chunk(XENSTORE_RING_IDX cons,
-                                  XENSTORE_RING_IDX prod,
-                                  const char *buf, uint32_t *len)
-{
-       *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
-       if ((prod - cons) < *len)
-               *len = prod - cons;
-       return buf + MASK_XENSTORE_IDX(cons);
-}
-
-/* FIXME: We spin, and we're sloppy. */
-static bool read_all_shmem(int fd __attribute__((unused)),
-                          void *data, unsigned int len)
-{
-       unsigned int avail;
-       struct xenstore_domain_interface *intf = interface;
-       XENSTORE_RING_IDX cons, prod;
-       const void *src;
-
-       while (len) {
-               cons = intf->rsp_cons;
-               prod = intf->rsp_prod;
-               if (!check_indexes(cons, prod))
-                       barf("Corrupt buffer");
-
-               src = get_input_chunk(cons, prod, intf->rsp, &avail);
-               if (avail > len)
-                       avail = len;
-               memcpy(data, src, avail);
-               data += avail;
-               len -= avail;
-               intf->rsp_cons += avail;
-       }
-
-       /* Tell other end we read something. */
-       kill(daemon_pid, SIGUSR2);
-
-       return true;
-}
-
-static bool write_all_shmem(int fd __attribute__((unused)),
-                           const void *data, unsigned int len)
-{
-       uint32_t avail;
-       struct xenstore_domain_interface *intf = interface;
-       XENSTORE_RING_IDX cons, prod;
-       void *dst;
-
-       while (len) {
-               cons = intf->req_cons;
-               prod = intf->req_prod;
-               if (!check_indexes(cons, prod))
-                       barf("Corrupt buffer");
-
-               dst = get_output_chunk(cons, prod, intf->req, &avail);
-               if (avail > len)
-                       avail = len;
-               memcpy(dst, data, avail);
-               data += avail;
-               len -= avail;
-               intf->req_prod += avail;
-       }
-
-       /* Tell other end we wrote something. */
-       kill(daemon_pid, SIGUSR2);
-
-       return true;
-}
-
-static bool read_all(int fd, void *data, unsigned int len);
-static bool read_all_choice(int fd, void *data, unsigned int len)
-{
-       if (fd == -2)
-               return read_all_shmem(fd, data, len);
-       return read_all(fd, data, len);
-}
-
-static bool write_all_choice(int fd, const void *data, unsigned int len)
-{
-       if (fd == -2)
-               return write_all_shmem(fd, data, len);
-       return xs_write_all(fd, data, len);
-}
-
-/* We want access to internal functions. */
-#include "xs.c"
-
-static void __attribute__((noreturn)) usage(void)
-{
-       barf("Usage:\n"
-            "       xs_test [--readonly] [--no-timeout] [-x]\n"
-            "Reads commands from stdin, one per line:"
-            "  dir <path>\n"
-            "  read <path>\n"
-            "  write <path> <value>...\n"
-            "  setid <id>\n"
-            "  mkdir <path>\n"
-            "  rm <path>\n"
-            "  getperm <path>\n"
-            "  setperm <path> <id> <flags> ...\n"
-            "  watch <path> <token>\n"
-            "  watchnoack <path> <token>\n"
-            "  waitwatch\n"
-            "  unwatch <path> <token>\n"
-            "  close\n"
-            "  start <node>\n"
-            "  abort\n"
-            "  introduce <domid> <mfn> <eventchn> <path>\n"
-            "  commit\n"
-            "  sleep <milliseconds>\n"
-            "  expect <pattern>\n"
-            "  notimeout\n"
-            "  readonly\n"
-            "  readwrite\n"
-            "  dump\n");
-}
-
-static int argpos(const char *line, unsigned int num)
-{
-       unsigned int i, len = 0, off = 0;
-
-       for (i = 0; i <= num; i++) {
-               off += len;
-               off += strspn(line + off, " \t\n");
-               len = strcspn(line + off, " \t\n");
-               if (!len)
-                       return off;
-       }
-       return off;
-}
-
-static char *arg(const char *line, unsigned int num)
-{
-       static char *args[10];
-       unsigned int off, len;
-
-       off = argpos(line, num);
-       len = strcspn(line + off, " \t\n");
-
-       if (!len)
-               barf("Can't get arg %u", num);
-
-       free(args[num]);
-       args[num] = malloc(len + 1);
-       memcpy(args[num], line+off, len);
-       args[num][len] = '\0';
-       return args[num];
-}
-
-struct expect
-{
-       struct list_head list;
-       char *pattern;
-};
-static LIST_HEAD(expects);
-
-static char *command;
-
-/* Trim leading and trailing whitespace */
-static void trim(char *str)
-{
-       while (isspace(str[0]))
-               memmove(str, str+1, strlen(str));
-
-       while (strlen(str) && isspace(str[strlen(str)-1]))
-               str[strlen(str)-1] = '\0';
-}
-
-static void output(const char *fmt, ...)
-{
-       char *str;
-       struct expect *i;
-       va_list arglist;
-
-       va_start(arglist, fmt);
-       vasprintf(&str, fmt, arglist);
-       va_end(arglist);
-
-       printf("%s", str);
-       fflush(stdout);
-       trim(str);
-       list_for_each_entry(i, &expects, list) {
-               if (fnmatch(i->pattern, str, 0) == 0) {
-                       list_del(&i->list);
-                       free(i);
-                       return;
-               }
-       }
-       barf("Unexpected output %s\n", str);
-}
-
-static void failed(int handle)
-{
-       if (handle)
-               output("%i: %s failed: %s\n",
-                      handle, command, strerror(errno));
-       else
-               output("%s failed: %s\n", command, strerror(errno));
-}
-
-static void expect(const char *line)
-{
-       struct expect *e = malloc(sizeof(*e));
-
-       e->pattern = strdup(line + argpos(line, 1));
-       trim(e->pattern);
-       list_add(&e->list, &expects);
-}
-
-static void do_dir(unsigned int handle, char *path)
-{
-       char **entries;
-       unsigned int i, num;
-
-       entries = xs_directory(handles[handle], txh[handle], path, &num);
-       if (!entries) {
-               failed(handle);
-               return;
-       }
-
-       for (i = 0; i < num; i++)
-               if (handle)
-                       output("%i:%s\n", handle, entries[i]);
-               else
-                       output("%s\n", entries[i]);
-       free(entries);
-}
-
-static void do_read(unsigned int handle, char *path)
-{
-       char *value;
-       unsigned int len;
-
-       value = xs_read(handles[handle], txh[handle], path, &len);
-       if (!value) {
-               failed(handle);
-               return;
-       }
-
-       /* It's supposed to nul terminate for us. */
-       assert(value[len] == '\0');
-       if (handle)
-               output("%i:%.*s\n", handle, len, value);
-       else
-               output("%.*s\n", len, value);
-}
-
-static void do_write(unsigned int handle, char *path, char *data)
-{
-       if (!xs_write(handles[handle], txh[handle], path, data, strlen(data)))
-               failed(handle);
-}
-
-static void do_setid(unsigned int handle, char *id)
-{
-       if (!xs_bool(xs_debug_command(handles[handle], "setid", id,
-                                     strlen(id)+1)))
-               failed(handle);
-}
-
-static void do_mkdir(unsigned int handle, char *path)
-{
-       if (!xs_mkdir(handles[handle], txh[handle], path))
-               failed(handle);
-}
-
-static void do_rm(unsigned int handle, char *path)
-{
-       if (!xs_rm(handles[handle], txh[handle], path))
-               failed(handle);
-}
-
-static void do_getperm(unsigned int handle, char *path)
-{
-       unsigned int i, num;
-       struct xs_permissions *perms;
-
-       perms = xs_get_permissions(handles[handle], txh[handle], path, &num);
-       if (!perms) {
-               failed(handle);
-               return;
-       }
-
-       for (i = 0; i < num; i++) {
-               char *permstring;
-
-               switch (perms[i].perms) {
-               case XS_PERM_NONE:
-                       permstring = "NONE";
-                       break;
-               case XS_PERM_WRITE:
-                       permstring = "WRITE";
-                       break;
-               case XS_PERM_READ:
-                       permstring = "READ";
-                       break;
-               case XS_PERM_READ|XS_PERM_WRITE:
-                       permstring = "READ/WRITE";
-                       break;
-               default:
-                       barf("bad perm value %i", perms[i].perms);
-               }
-
-               if (handle)
-                       output("%i:%i %s\n", handle, perms[i].id, permstring);
-               else
-                       output("%i %s\n", perms[i].id, permstring);
-       }
-       free(perms);
-}
-
-static void do_setperm(unsigned int handle, char *path, char *line)
-{
-       unsigned int i;
-       struct xs_permissions perms[100];
-
-       strtok(line, " \t\n");
-       strtok(NULL, " \t\n");
-       for (i = 0; ; i++) {
-               char *arg = strtok(NULL, " \t\n");
-               if (!arg)
-                       break;
-               perms[i].id = atoi(arg);
-               arg = strtok(NULL, " \t\n");
-               if (!arg)
-                       break;
-               if (streq(arg, "WRITE"))
-                       perms[i].perms = XS_PERM_WRITE;
-               else if (streq(arg, "READ"))
-                       perms[i].perms = XS_PERM_READ;
-               else if (streq(arg, "READ/WRITE"))
-                       perms[i].perms = XS_PERM_READ|XS_PERM_WRITE;
-               else if (streq(arg, "NONE"))
-                       perms[i].perms = XS_PERM_NONE;
-               else
-                       barf("bad flags %s\n", arg);
-       }
-
-       if (!xs_set_permissions(handles[handle], txh[handle], path, perms, i))
-               failed(handle);
-}
-
-static void do_watch(unsigned int handle, const char *node, const char *token,
-                    bool swallow_event)
-{
-       if (!xs_watch(handles[handle], node, token))
-               failed(handle);
-
-       /* Convenient for testing... */
-       if (swallow_event) {
-               unsigned int num;
-               char **vec = xs_read_watch(handles[handle], &num);
-               if (!vec ||
-                   !streq(vec[XS_WATCH_PATH], node) ||
-                   !streq(vec[XS_WATCH_TOKEN], token))
-                       failed(handle);
-       }
-}
-
-static void set_timeout(void)
-{
-       struct itimerval timeout;
-
-       timeout.it_value.tv_sec = timeout_ms / 1000;
-       timeout.it_value.tv_usec = (timeout_ms * 1000) % 1000000;
-       timeout.it_interval.tv_sec = timeout.it_interval.tv_usec = 0;
-       setitimer(ITIMER_REAL, &timeout, NULL);
-}
-
-static void disarm_timeout(void)
-{
-       struct itimerval timeout;
-
-       timeout.it_value.tv_sec = 0;
-       timeout.it_value.tv_usec = 0;
-       setitimer(ITIMER_REAL, &timeout, NULL);
-}
-
-static void do_waitwatch(unsigned int handle)
-{
-       char **vec;
-       struct timeval tv = {.tv_sec = timeout_ms/1000,
-                            .tv_usec = (timeout_ms*1000)%1000000 };
-       fd_set set;
-       unsigned int num;
-
-       if (xs_fileno(handles[handle]) != -2) {
-               /* Manually select here so we can time out gracefully. */
-               FD_ZERO(&set);
-               FD_SET(xs_fileno(handles[handle]), &set);
-               disarm_timeout();
-               if (select(xs_fileno(handles[handle])+1, &set,
-                          NULL, NULL, &tv) == 0) {
-                       errno = ETIMEDOUT;
-                       failed(handle);
-                       return;
-               }
-               set_timeout();
-       }
-
-       vec = xs_read_watch(handles[handle], &num);
-       if (!vec) {
-               failed(handle);
-               return;
-       }
-
-       if (handle)
-               output("%i:%s:%s\n", handle,
-                      vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
-       else
-               output("%s:%s\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]);
-       free(vec);
-}
-
-static void do_unwatch(unsigned int handle, const char *node, const char 
*token)
-{
-       if (!xs_unwatch(handles[handle], node, token))
-               failed(handle);
-}
-
-static void do_start(unsigned int handle)
-{
-       txh[handle] = xs_transaction_start(handles[handle]);
-       if (txh[handle] == XBT_NULL)
-               failed(handle);
-}
-
-static void do_end(unsigned int handle, bool abort)
-{
-       if (!xs_transaction_end(handles[handle], txh[handle], abort))
-               failed(handle);
-       txh[handle] = XBT_NULL;
-}
-
-static void do_introduce(unsigned int handle,
-                        const char *domid,
-                        const char *mfn,
-                        const char *eventchn,
-                        const char *path)
-{
-       unsigned int i;
-       int fd;
-
-       /* This mechanism is v. slow w. valgrind running. */
-       timeout_ms = 5000;
-
-       /* We poll, so ignore signal */
-       signal(SIGUSR2, SIG_IGN);
-       for (i = 0; i < ARRAY_SIZE(handles); i++)
-               if (!handles[i])
-                       break;
-
-       fd = open("/tmp/xcmap", O_RDWR);
-       /* Set shared comms page. */
-       interface = mmap(NULL, getpagesize(), PROT_WRITE|PROT_READ,
-                        MAP_SHARED,fd,0);
-       if (interface == MAP_FAILED)
-               barf_perror("Failed to map /tmp/xcmap page");
-       close(fd);
-
-       /* Tell them the event channel and our PID. */
-       *(int *)((void *)interface + 32) = getpid();
-       *(uint16_t *)((void *)interface + 36) = atoi(eventchn);
-
-       if (!xs_introduce_domain(handles[handle], atoi(domid),
-                                atol(mfn), atoi(eventchn))) {
-               failed(handle);
-               munmap(interface, getpagesize());
-               return;
-       }
-       output("handle is %i\n", i);
-
-       /* Create new handle. */
-       handles[i] = new(struct xs_handle);
-       handles[i]->fd = -2;
-
-       /* Read in daemon pid. */
-       daemon_pid = *(int *)((void *)interface + 32);
-}
-
-static void do_release(unsigned int handle, const char *domid)
-{
-       if (!xs_release_domain(handles[handle], atoi(domid)))
-               failed(handle);
-}
-
-static int strptrcmp(const void *a, const void *b)
-{
-       return strcmp(*(char **)a, *(char **)b);
-}
-
-static void sort_dir(char **dir, unsigned int num)
-{
-       qsort(dir, num, sizeof(char *), strptrcmp);
-}
-
-static void dump_dir(unsigned int handle,
-                    const char *node,
-                    char **dir,
-                    unsigned int numdirs,
-                    unsigned int depth)
-{
-       unsigned int i;
-       char spacing[depth+1];
-
-       memset(spacing, ' ', depth);
-       spacing[depth] = '\0';
-
-       sort_dir(dir, numdirs);
-
-       for (i = 0; i < numdirs; i++) {
-               struct xs_permissions *perms;
-               unsigned int j, numperms;
-               unsigned int len;
-               char *contents;
-               unsigned int subnum;
-               char **subdirs;
-               char subnode[strlen(node) + 1 + strlen(dir[i]) + 1];
-
-               sprintf(subnode, "%s/%s", node, dir[i]);
-
-               perms = xs_get_permissions(handles[handle], txh[handle],
-                                          subnode,&numperms);
-               if (!perms) {
-                       failed(handle);
-                       return;
-               }
-
-               output("%s%s: ", spacing, dir[i]);
-               for (j = 0; j < numperms; j++) {
-                       char buffer[100];
-                       if (!xs_perm_to_string(&perms[j], buffer))
-                               barf("perm to string");
-                       output("%s ", buffer);
-               }
-               free(perms);
-               output("\n");
-
-               /* Even directories can have contents. */
-               contents = xs_read(handles[handle], txh[handle], 
-                                  subnode, &len);
-               if (!contents) {
-                       if (errno != EISDIR)
-                               failed(handle);
-               } else {
-                       output(" %s(%.*s)\n", spacing, len, contents);
-                       free(contents);
-               }                       
-
-               /* Every node is a directory. */
-               subdirs = xs_directory(handles[handle], txh[handle], 
-                                      subnode, &subnum);
-               if (!subdirs) {
-                       failed(handle);
-                       return;
-               }
-               dump_dir(handle, subnode, subdirs, subnum, depth+1);
-               free(subdirs);
-       }
-}
-
-static void dump(int handle)
-{
-       char **subdirs;
-       unsigned int subnum;
-
-       subdirs = xs_directory(handles[handle], txh[handle], "/", &subnum);
-       if (!subdirs) {
-               failed(handle);
-               return;
-       }
-
-       dump_dir(handle, "", subdirs, subnum, 0);
-       free(subdirs);
-}
-
-static int handle;
-
-static void alarmed(int sig __attribute__((unused)))
-{
-       if (handle) {
-               char handlename[10];
-               sprintf(handlename, "%u:", handle);
-               write(STDOUT_FILENO, handlename, strlen(handlename));
-       }
-       write(STDOUT_FILENO, command, strlen(command));
-       write(STDOUT_FILENO, " timeout\n", strlen(" timeout\n"));
-       exit(1);
-}
-
-static void do_command(unsigned int default_handle, char *line)
-{
-       char *endp;
-
-       if (print_input)
-               printf("%i> %s", ++linenum, line);
-
-       if (strspn(line, " \n") == strlen(line))
-               return;
-       if (strstarts(line, "#"))
-               return;
-
-       handle = strtoul(line, &endp, 10);
-       if (endp != line)
-               memmove(line, endp+1, strlen(endp));
-       else
-               handle = default_handle;
-
-       command = arg(line, 0);
-       if (!handles[handle]) {
-               if (readonly)
-                       handles[handle] = xs_daemon_open_readonly();
-               else
-                       handles[handle] = xs_daemon_open();
-               if (!handles[handle])
-                       barf_perror("Opening connection to daemon");
-       }
-
-       if (!timeout_suppressed)
-               set_timeout();
-       timeout_suppressed = false;
-
-       if (streq(command, "dir"))
-               do_dir(handle, arg(line, 1));
-       else if (streq(command, "read"))
-               do_read(handle, arg(line, 1));
-       else if (streq(command, "write"))
-               do_write(handle, arg(line, 1), arg(line, 2));
-       else if (streq(command, "setid"))
-               do_setid(handle, arg(line, 1));
-       else if (streq(command, "mkdir"))
-               do_mkdir(handle, arg(line, 1));
-       else if (streq(command, "rm"))
-               do_rm(handle, arg(line, 1));
-       else if (streq(command, "getperm"))
-               do_getperm(handle, arg(line, 1));
-       else if (streq(command, "setperm"))
-               do_setperm(handle, arg(line, 1), line);
-       else if (streq(command, "watch"))
-               do_watch(handle, arg(line, 1), arg(line, 2), true);
-       else if (streq(command, "watchnoack"))
-               do_watch(handle, arg(line, 1), arg(line, 2), false);
-       else if (streq(command, "waitwatch"))
-               do_waitwatch(handle);
-       else if (streq(command, "unwatch"))
-               do_unwatch(handle, arg(line, 1), arg(line, 2));
-       else if (streq(command, "close")) {
-               xs_daemon_close(handles[handle]);
-               handles[handle] = NULL;
-               txh[handle] = XBT_NULL;
-       } else if (streq(command, "start"))
-               do_start(handle);
-       else if (streq(command, "commit"))
-               do_end(handle, false);
-       else if (streq(command, "abort"))
-               do_end(handle, true);
-       else if (streq(command, "introduce"))
-               do_introduce(handle, arg(line, 1), arg(line, 2),
-                            arg(line, 3), arg(line, 4));
-       else if (streq(command, "release"))
-               do_release(handle, arg(line, 1));
-       else if (streq(command, "dump"))
-               dump(handle);
-       else if (streq(command, "sleep")) {
-               disarm_timeout();
-               usleep(atoi(arg(line, 1)) * 1000);
-       } else if (streq(command, "expect"))
-               expect(line);
-       else if (streq(command, "notimeout"))
-               timeout_suppressed = true;
-       else if (streq(command, "readonly")) {
-               readonly = true;
-               xs_daemon_close(handles[handle]);
-               handles[handle] = NULL;
-       } else if (streq(command, "readwrite")) {
-               readonly = false;
-               xs_daemon_close(handles[handle]);
-               handles[handle] = NULL;
-       } else
-               barf("Unknown command %s", command);
-       fflush(stdout);
-       disarm_timeout();
-
-       /* Check expectations. */
-       if (!streq(command, "expect")) {
-               struct expect *i = list_top(&expects, struct expect, list);
-
-               if (i)
-                       barf("Expected '%s', didn't happen\n", i->pattern);
-       }
-}
-
-static struct option options[] = { { "readonly", 0, NULL, 'r' },
-                                  { "no-timeout", 0, NULL, 't' },
-                                  { NULL, 0, NULL, 0 } };
-
-int main(int argc, char *argv[])
-{
-       int opt;
-       char line[1024];
-
-       while ((opt = getopt_long(argc, argv, "xrt", options, NULL)) != -1) {
-               switch (opt) {
-               case 'r':
-                       readonly = true;
-                       break;
-               case 't':
-                       timeout_ms = 0;
-                       break;
-               case 'x':
-                       print_input = true;
-                       break;
-               }
-       }
-
-       if (optind + 1 == argc) {
-               int fd = open(argv[optind], O_RDONLY);
-               if (!fd)
-                       barf_perror("Opening %s", argv[optind]);
-               dup2(fd, STDIN_FILENO);
-       } else if (optind != argc)
-               usage();
-       
-
-       signal(SIGALRM, alarmed);
-       while (fgets(line, sizeof(line), stdin))
-               do_command(0, line);
-
-       return 0;
-}
-
-/*
- * Local variables:
- *  c-file-style: "linux"
- *  indent-tabs-mode: t
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.