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

[Xen-tools] [PATCH 2/3] Delay deletion of failed transactions slightly



# HG changeset patch
# User Rusty Russell <rusty@xxxxxxxxxxxxxxx>
# Node ID 703e0e8e7efce364f62a79b209af0d48195b6825
# Parent  6d2f8b0a18c4713286a16d22fd2a11d7ab4525b4
Delay delete of transaction file when transaction fails with EAGAIN.

Randomized testing with killing xenstored reveals a flaw: if it dies before 
client gets response from xs_transaction_end (ie. transaction commit), we can't 
tell if commit failed (EAGAIN) or succeeded.  This is the only non-repeatable 
operation.

Note that this won't happen on a clean shutdown, but delaying delete allows us 
to handle the unexpected death case: the client will reconnect, attach to 
transaction again, the second commit attempt will fail.

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

diff -r 6d2f8b0a18c4 -r 703e0e8e7efc tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Mon Sep 26 04:30:14 2005
+++ b/tools/xenstore/xenstored_core.c   Mon Sep 26 10:53:13 2005
@@ -1185,6 +1185,12 @@
        if (type != XS_WATCH_ACK)
                conn->waiting_for_ack = NULL;
 
+       /* Now we're sure they know transaction is over. */
+       if (conn->last_transaction) {
+               talloc_free(conn->last_transaction);
+               conn->last_transaction = NULL;
+       }
+
        /* Careful: process_message may free connection.  We detach
         * "in" beforehand and allocate the new buffer to avoid
         * touching conn after process_message.
@@ -1282,7 +1288,7 @@
        new->fd = -1;
        new->id = 0;
        new->domain = NULL;
-       new->transaction = NULL;
+       new->transaction = new->last_transaction = NULL;
        new->write = write;
        new->read = read;
        new->can_write = true;
diff -r 6d2f8b0a18c4 -r 703e0e8e7efc tools/xenstore/xenstored_core.h
--- a/tools/xenstore/xenstored_core.h   Mon Sep 26 04:30:14 2005
+++ b/tools/xenstore/xenstored_core.h   Mon Sep 26 10:53:13 2005
@@ -84,8 +84,8 @@
        /* If we had a watch fire outgoing when we needed to reply... */
        struct buffered_data *waiting_reply;
 
-       /* My transaction, if any. */
-       struct transaction *transaction;
+       /* My transaction, if any, and aborted one. */
+       struct transaction *transaction, *last_transaction;
 
        /* The domain I'm associated with, if any. */
        struct domain *domain;
diff -r 6d2f8b0a18c4 -r 703e0e8e7efc tools/xenstore/xenstored_transaction.c
--- a/tools/xenstore/xenstored_transaction.c    Mon Sep 26 04:30:14 2005
+++ b/tools/xenstore/xenstored_transaction.c    Mon Sep 26 10:53:13 2005
@@ -219,6 +219,8 @@
        if (streq(arg, "T")) {
                /* FIXME: Merge, rather failing on any change. */
                if (trans->generation != generation) {
+                       /* Keep transaction around: more robust if we die. */
+                       conn->last_transaction = talloc_steal(conn, trans);
                        send_error(conn, EAGAIN);
                        return;
                }
@@ -248,7 +250,7 @@
 
        transdir = talloc_strdup(talloc_autofree_context(), xs_daemon_tdb());
        if (strrchr(transdir, '/'))
-               *strchr(transdir, '/') = '\0';
+               *strrchr(transdir, '/') = '\0';
        else
                transdir = talloc_strdup(transdir, ".");
 
@@ -267,6 +269,7 @@
                if (!trans->tdb) {
                        eprintf("Could not reopen transaction %i: corrupt?",
                                id);
+                       unlink(trans->tdb_name);
                        talloc_free(trans);
                }
        }

-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman


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


 


Rackspace

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