WARNING - OLD ARCHIVES

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

xen-devel

[Xen-devel] [PATCH 2/11] Start of code to persistent store connections w

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 2/11] Start of code to persistent store connections when xenstored restarts:
From: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Date: Thu, 04 Aug 2005 22:31:18 +1000
Delivery-date: Thu, 04 Aug 2005 12:30:18 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 2/11] Start of code to persistent store connections when xenstored restarts:, Rusty Russell <=