Rusty Russell
2005-Aug-04 12:31 UTC
[Xen-devel] [PATCH 2/11] Start of code to persistent store connections when xenstored restarts:
# HG changeset patch # User Rusty Russell <rusty@rustcorp.com.au> # 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@rustcorp.com.au> 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@lists.xensource.com http://lists.xensource.com/xen-devel