# 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
|