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

[Xen-devel] [PATCH 2/11] Start of code to persistent store connections when xenstored restarts:



# HG changeset patch
# User Rusty Russell <rusty@xxxxxxxxxxxxxxx>
# Node ID e158ae50d2613b3e01d41c395b8dbc34c9766f73
# Parent  bdc6aabe3e1a6f83e7119c68212c2c33a4cb851f
Start of code to persistent store connections when xenstored restarts:
Create tool/xenstored directory during initialization.

Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>

diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/Makefile   Thu Aug  4 09:18:42 2005
@@ -87,9 +87,9 @@
        $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
 
 stresstest: xs_stress xs_watch_stress xenstored_test
-       rm -rf $(TESTDIR)/store
+       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
-       rm -rf $(TESTDIR)/store
+       rm -rf $(TESTDIR)/store $(TESTDIR)/transactions
        export $(TESTENV); PID=`./xenstored_test --output-pid`; 
./xs_watch_stress; ret=$$?; kill $$PID; exit $$ret
 
 xs_dom0_test: xs_dom0_test.o utils.o
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/testsuite/02directory.sh
--- a/tools/xenstore/testsuite/02directory.sh   Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/testsuite/02directory.sh   Thu Aug  4 09:18:42 2005
@@ -1,22 +1,23 @@
 #! /bin/sh
 
-# Root directory has nothing in it.
-[ "`echo -e 'dir /' | ./xs_test 2>&1`" = "" ]
+# Root directory has only tool dir in it.
+[ "`echo -e 'dir /' | ./xs_test 2>&1`" = "tool" ]
 
 # Create a file.
 [ "`echo -e 'write /test create contents' | ./xs_test 2>&1`" = "" ]
 
 # Directory shows it.
-[ "`echo -e 'dir /' | ./xs_test 2>&1`" = "test" ]
+[ "`echo -e 'dir /' | ./xs_test 2>&1 | sort`" = "test
+tool" ]
 
 # Make a new directory.
 [ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
 
 # Check it's there.
-DIR="`echo -e 'dir /' | ./xs_test 2>&1`"
-[ "$DIR" = "test
-dir" ] || [ "$DIR" = "dir
-test" ]
+DIR="`echo -e 'dir /' | ./xs_test 2>&1 | sort`"
+[ "$DIR" = "dir
+test
+tool" ]
 
 # Check it's empty.
 [ "`echo -e 'dir /dir' | ./xs_test 2>&1`" = "" ]
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/testsuite/08transaction.sh
--- a/tools/xenstore/testsuite/08transaction.sh Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/testsuite/08transaction.sh Thu Aug  4 09:18:42 2005
@@ -1,79 +1,81 @@
 #! /bin/sh
 # Test transactions.
 
+echo mkdir /test | ./xs_test
+
 # Simple transaction: create a file inside transaction.
-[ "`echo -e '1 start /
-1 write /entry1 create contents
-2 dir /
-1 dir /
+[ "`echo -e '1 start /test
+1 write /test/entry1 create contents
+2 dir /test
+1 dir /test
 1 commit
-2 read /entry1' | ./xs_test`" = "1:entry1
+2 read /test/entry1' | ./xs_test`" = "1:entry1
 2:contents" ]
-echo rm /entry1 | ./xs_test
+echo rm /test/entry1 | ./xs_test
 
 # Create a file and abort transaction.
-[ "`echo -e '1 start /
-1 write /entry1 create contents
-2 dir /
-1 dir /
+[ "`echo -e '1 start /test
+1 write /test/entry1 create contents
+2 dir /test
+1 dir /test
 1 abort
-2 dir /' | ./xs_test`" = "1:entry1" ]
+2 dir /test' | ./xs_test`" = "1:entry1" ]
 
-echo write /entry1 create contents | ./xs_test
+echo write /test/entry1 create contents | ./xs_test
 # Delete in transaction, commit
-[ "`echo -e '1 start /
-1 rm /entry1
-2 dir /
-1 dir /
+[ "`echo -e '1 start /test
+1 rm /test/entry1
+2 dir /test
+1 dir /test
 1 commit
-2 dir /' | ./xs_test`" = "2:entry1" ]
+2 dir /test' | ./xs_test`" = "2:entry1" ]
 
 # Delete in transaction, abort.
-echo write /entry1 create contents | ./xs_test
-[ "`echo -e '1 start /
-1 rm /entry1
-2 dir /
-1 dir /
+echo write /test/entry1 create contents | ./xs_test
+[ "`echo -e '1 start /test
+1 rm /test/entry1
+2 dir /test
+1 dir /test
 1 abort
-2 dir /' | ./xs_test`" = "2:entry1
+2 dir /test' | ./xs_test`" = "2:entry1
 2:entry1" ]
 
 # Transactions can take as long as the want...
-[ "`echo -e 'start /
+[ "`echo -e 'start /test
 sleep 1
-rm /entry1
+rm /test/entry1
 commit
-dir /' | ./xs_test`" = "" ]
+dir /test' | ./xs_test`" = "" ]
 
 # ... as long as noone is waiting.
-[ "`echo -e '1 start /
-2 mkdir /dir
-1 mkdir /dir
-1 dir /
+[ "`echo -e '1 start /test
+2 mkdir /test/dir
+1 mkdir /test/dir
+1 dir /test
 1 commit' | ./xs_test 2>&1`" = "1:dir
 FATAL: 1: commit: Connection timed out" ]
 
 # Events inside transactions don't trigger watches until (successful) commit.
-[ "`echo -e '1 watch / token 100
-2 start /
-2 mkdir /dir/sub
+[ "`echo -e '1 watch /test token 100
+2 start /test
+2 mkdir /test/dir/sub
 1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
-[ "`echo -e '1 watch / token 100
-2 start /
-2 mkdir /dir/sub
+[ "`echo -e '1 watch /test token 100
+2 start /test
+2 mkdir /test/dir/sub
 2 abort
 1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
-[ "`echo -e '1 watch / token 100
-2 start /
-2 mkdir /dir/sub
+[ "`echo -e '1 watch /test token 100
+2 start /test
+2 mkdir /test/dir/sub
 2 commit
 1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/dir/sub:token" ]
+1 ackwatch token' | ./xs_test 2>&1`" = "1:/test/dir/sub:token" ]
 
 # Rm inside transaction works like rm outside: children get notified.
-[ "`echo -e '1 watch /dir/sub token 100
-2 start /
-2 rm /dir
+[ "`echo -e '1 watch /test/dir/sub token 100
+2 start /test
+2 rm /test/dir
 2 commit
 1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/dir/sub:token" ]
+1 ackwatch token' | ./xs_test 2>&1`" = "1:/test/dir/sub:token" ]
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/testsuite/09domain.sh
--- a/tools/xenstore/testsuite/09domain.sh      Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/testsuite/09domain.sh      Thu Aug  4 09:18:42 2005
@@ -4,8 +4,9 @@
 # Create a domain, write an entry.
 [ "`echo -e 'introduce 1 100 7 /my/home
 1 write /entry1 create contents
-dir /' | ./xs_test 2>&1`" = "handle is 1
-entry1" ]
+dir /' | ./xs_test 2>&1 | sort`" = "entry1
+handle is 1
+tool" ]
 
 # Release that domain.
 [ "`echo -e 'release 1' | ./xs_test`" = "" ]
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/testsuite/12readonly.sh
--- a/tools/xenstore/testsuite/12readonly.sh    Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/testsuite/12readonly.sh    Thu Aug  4 09:18:42 2005
@@ -4,16 +4,17 @@
 [ "`echo 'write /test create contents' | ./xs_test 2>&1`" = "" ]
 
 # These are all valid.
-[ "`echo 'dir /
-read /test
+[ "`echo dir / | ./xs_test --readonly 2>&1 | sort`" = "test
+tool" ]
+
+[ "`echo 'read /test
 getperm /test
 watch /test token 0
 unwatch /test token 
 start /
 commit
 start /
-abort' | ./xs_test --readonly 2>&1`" = "test
-contents
+abort' | ./xs_test --readonly 2>&1`" = "contents
 0 READ" ]
 
 # These don't work
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/xenstored_core.c   Thu Aug  4 09:18:42 2005
@@ -1382,6 +1382,45 @@
 }
 #endif
 
+static void setup_structure(void)
+{
+       struct xs_permissions perms = { .id = 0, .perms = XS_PERM_READ };
+       char *root, *dir, *permfile;
+
+       /* Create root directory, with permissions. */
+       if (mkdir(xs_daemon_store(), 0750) != 0) {
+               if (errno != EEXIST)
+                       barf_perror("Could not create root %s",
+                                   xs_daemon_store());
+               return;
+       }
+       root = talloc_strdup(talloc_autofree_context(), "/");
+       if (!set_perms(NULL, root, &perms, 1))
+               barf_perror("Could not create permissions in root");
+
+       /* Create tool directory, with xenstored subdir. */
+       dir = talloc_asprintf(root, "%s/%s", xs_daemon_store(), "tool");
+       if (mkdir(dir, 0750) != 0)
+               barf_perror("Making dir %s", dir);
+       
+       permfile = talloc_strdup(root, "/tool");
+       if (!set_perms(NULL, permfile, &perms, 1))
+               barf_perror("Could not create permissions on %s", permfile);
+
+       dir = talloc_asprintf(root, "%s/%s", dir, "xenstored");
+       if (mkdir(dir, 0750) != 0)
+               barf_perror("Making dir %s", dir);
+       
+       permfile = talloc_strdup(root, "/tool/xenstored");
+       if (!set_perms(NULL, permfile, &perms, 1))
+               barf_perror("Could not create permissions on %s", permfile);
+
+       talloc_free(root);
+       if (mkdir(xs_daemon_transactions(), 0750) != 0)
+               barf_perror("Could not create transaction dir %s",
+                           xs_daemon_transactions());
+}
+
 static struct option options[] = { { "no-fork", 0, NULL, 'N' },
                                   { "verbose", 0, NULL, 'V' },
                                   { "output-pid", 0, NULL, 'P' },
@@ -1457,21 +1496,13 @@
                barf_perror("Could not listen on sockets");
 
        /* If we're the first, create .perms file for root. */
-       if (mkdir(xs_daemon_store(), 0750) == 0) {
-               struct xs_permissions perms;
-               char *root = talloc_strdup(talloc_autofree_context(), "/");
-
-               perms.id = 0;
-               perms.perms = XS_PERM_READ;
-               if (!set_perms(NULL, root, &perms, 1))
-                       barf_perror("Could not create permissions in root");
-               talloc_free(root);
-               mkdir(xs_daemon_transactions(), 0750);
-       } else if (errno != EEXIST)
-               barf_perror("Could not create root %s", xs_daemon_store());
+       setup_structure();
 
        /* Listen to hypervisor. */
        event_fd = domain_init();
+
+       /* Restore existing connections. */
+       restore_existing_connections();
 
        /* Debugging: daemonize() closes standard fds, so dup here. */
        tmpout = dup(STDOUT_FILENO);
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/xenstored_domain.c Thu Aug  4 09:18:42 2005
@@ -254,34 +254,21 @@
 #endif
 }
 
-/* domid, mfn, evtchn, path */
-bool do_introduce(struct connection *conn, struct buffered_data *in)
+static struct domain *new_domain(void *context, domid_t domid,
+                                unsigned long mfn, int port,
+                                const char *path)
 {
        struct domain *domain;
-       char *vec[4];
-
-       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
-               return send_error(conn, EINVAL);
-
-       if (conn->id != 0)
-               return send_error(conn, EACCES);
-
-       if (!conn->can_write)
-               return send_error(conn, EROFS);
-
-       /* Hang domain off "in" until we're finished. */
-       domain = talloc(in, struct domain);
-       domain->domid = atoi(vec[0]);
-       domain->port = atoi(vec[2]);
-       if ((domain->port <= 0) || !is_valid_nodename(vec[3]))
-               return send_error(conn, EINVAL);
-       domain->path = talloc_strdup(domain, vec[3]);
+       domain = talloc(context, struct domain);
+       domain->domid = domid;
+       domain->port = port;
+       domain->path = talloc_strdup(domain, path);
        domain->page = xc_map_foreign_range(*xc_handle, domain->domid,
                                            getpagesize(),
                                            PROT_READ|PROT_WRITE,
-                                           atol(vec[1]));
+                                           mfn);
        if (!domain->page)
-               return send_error(conn, errno);
+               return NULL;
 
        list_add(&domain->list, &domains);
        talloc_set_destructor(domain, destroy_domain);
@@ -292,11 +279,38 @@
 
        /* Tell kernel we're interested in this event. */
        if (ioctl(eventchn_fd, EVENTCHN_BIND, domain->port) != 0)
-               return send_error(conn, errno);
+               return NULL;
 
        domain->conn = new_connection(writechn, readchn);
        domain->conn->domain = domain;
-
+       return domain;
+}
+
+/* domid, mfn, evtchn, path */
+bool do_introduce(struct connection *conn, struct buffered_data *in)
+{
+       struct domain *domain;
+       char *vec[4];
+
+       if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
+               return send_error(conn, EINVAL);
+
+       if (conn->id != 0)
+               return send_error(conn, EACCES);
+
+       if (!conn->can_write)
+               return send_error(conn, EROFS);
+
+       /* Sanity check args. */
+       if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3]))
+               return send_error(conn, EINVAL);
+       /* Hang domain off "in" until we're finished. */
+       domain = new_domain(in, atoi(vec[0]), atol(vec[1]), atol(vec[2]),
+                           vec[3]);
+       if (!domain)
+               return send_error(conn, errno);
+
+       /* Now domain belongs to its connection. */
        talloc_steal(domain->conn, domain);
 
        return send_ack(conn, XS_INTRODUCE);
@@ -373,6 +387,11 @@
        if (!conn->domain)
                return NULL;
        return conn->domain->path;
+}
+
+/* Restore existing connections. */
+void restore_existing_connections(void)
+{
 }
 
 /* Returns the event channel handle. */
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/xenstored_domain.h Thu Aug  4 09:18:42 2005
@@ -35,4 +35,7 @@
 
 /* Returns the implicit path of a connection (only domains have this) */
 const char *get_implicit_path(const struct connection *conn);
+
+/* Read existing connection information from store. */
+void restore_existing_connections(void);
 #endif /* _XENSTORED_DOMAIN_H */
diff -r bdc6aabe3e1a -r e158ae50d261 tools/xenstore/xs_random.c
--- a/tools/xenstore/xs_random.c        Thu Aug  4 08:58:03 2005
+++ b/tools/xenstore/xs_random.c        Thu Aug  4 09:18:42 2005
@@ -987,6 +987,8 @@
        char *cmd = talloc_asprintf(NULL, "echo -n r0 > %s/.perms", dir);
        if (mkdir(dir, 0700) != 0)
                barf_perror("Creating directory %s", dir);
+       if (mkdir(talloc_asprintf(cmd, "%s/tool", dir), 0700) != 0)
+               barf_perror("Creating directory %s/tool", dir);
        do_command(cmd);
        talloc_free(cmd);
 }
@@ -1211,6 +1213,10 @@
        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);
-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman


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


 


Rackspace

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