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

[Xen-tools] Re: [PATCH 1/3] Recover transaction on restart, give transac

To: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Subject: [Xen-tools] Re: [PATCH 1/3] Recover transaction on restart, give transactions IDs
From: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
Date: Mon, 26 Sep 2005 19:57:33 +0100
Cc: Xen Tools <xen-tools@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Delivery-date: Mon, 26 Sep 2005 18:55:01 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1127734218.26244.1.camel@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-tools-request@lists.xensource.com?subject=help>
List-id: Xen control tools developers <xen-tools.lists.xensource.com>
List-post: <mailto:xen-tools@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-tools>, <mailto:xen-tools-request@lists.xensource.com?subject=unsubscribe>
References: <1127734218.26244.1.camel@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-tools-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.1i
Rusty,

I don't agree with this approach since it relies on the fact that
we won't suspend/resume within a transaction.

I'd still like to get the recover watches code from the 3rd patch.
Any chance of sending that seperately?  Otherwise Ewan can probably
pick it out.

    christian

On Mon, Sep 26, 2005 at 09:30:18PM +1000, Rusty Russell wrote:
> # HG changeset patch
> # User Rusty Russell <rusty@xxxxxxxxxxxxxxx>
> # Node ID 6d2f8b0a18c4713286a16d22fd2a11d7ab4525b4
> # Parent  5ea81e6405097b7ac25901ecdcd5fb19475508d8
> Recover transactions on restart.
> Give an ID to each transaction, and return that to client (they can use this 
> to get it back).
> 
> Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
> 
> diff -r 5ea81e640509 -r 6d2f8b0a18c4 tools/xenstore/xenstored_core.c
> --- a/tools/xenstore/xenstored_core.c Sun Sep 25 10:47:22 2005
> +++ b/tools/xenstore/xenstored_core.c Mon Sep 26 04:30:14 2005
> @@ -1409,9 +1409,10 @@
>               manual_node("/", "tool");
>               manual_node("/tool", "xenstored");
>               manual_node("/tool/xenstored", NULL);
> -     }
> -
> -     /* FIXME: Fsck */
> +     } else {
> +             /* FIXME: Fsck */
> +             recover_transactions();
> +     }
>  }
>  
>  static void write_pidfile(const char *pidfile)
> diff -r 5ea81e640509 -r 6d2f8b0a18c4 tools/xenstore/xenstored_transaction.c
> --- a/tools/xenstore/xenstored_transaction.c  Sun Sep 25 10:47:22 2005
> +++ b/tools/xenstore/xenstored_transaction.c  Mon Sep 26 04:30:14 2005
> @@ -55,10 +55,11 @@
>       /* Generation when transaction started. */
>       unsigned int generation;
>  
> -     /* My owner (conn->transaction == me). */
> +     /* My owner (conn->transaction == me).  NULL if unclaimed. */
>       struct connection *conn;
>  
>       /* TDB to work on, and filename */
> +     int id;
>       TDB_CONTEXT *tdb;
>       char *tdb_name;
>  
> @@ -108,35 +109,90 @@
>       return 0;
>  }
>  
> +/* Very dumb algorithm to get unique transaction id */
> +static int get_transaction_id(void)
> +{
> +     int i = 0;
> +     struct transaction *trans;
> +
> +again:
> +     list_for_each_entry(trans, &transactions, list) {
> +             if (trans->id == i) {
> +                     i++;
> +                     goto again;
> +             }
> +     }
> +     return i;
> +}
> +
> +static struct transaction *get_trans_by_id(int id)
> +{
> +     struct transaction *trans;
> +
> +     list_for_each_entry(trans, &transactions, list)
> +             if (trans->id == id)
> +                     return trans;
> +     return NULL;
> +}
> +
> +/* Caller fills in ->conn and ->tdb. */
> +static struct transaction *new_trans(void *ctx, unsigned int gen, int id)
> +{
> +     struct transaction *trans;
> +
> +     trans = talloc(ctx, struct transaction);
> +     INIT_LIST_HEAD(&trans->changes);
> +     trans->generation = gen;
> +     trans->id = id;
> +     trans->tdb_name = talloc_asprintf(trans, "%s.%i", xs_daemon_tdb(), id);
> +     list_add_tail(&trans->list, &transactions);
> +     talloc_set_destructor(trans, destroy_transaction);
> +     return trans;
> +}
> +
>  void do_transaction_start(struct connection *conn, struct buffered_data *in)
>  {
>       struct transaction *trans;
> +     char *vec[1];
> +     char id[MAX_STRLEN(trans->id)];
> +
> +     if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) {
> +             send_error(conn, EINVAL);
> +             return;
> +     }
>  
>       if (conn->transaction) {
>               send_error(conn, EBUSY);
>               return;
>       }
>  
> -     /* Attach transaction to input for autofree until it's complete */
> -     trans = talloc(in, struct transaction);
> -     INIT_LIST_HEAD(&trans->changes);
> +     /* If given a name, they want transaction back. */
> +     if (!streq(vec[0], "")) {
> +             trans = get_trans_by_id(atoi(vec[0]));
> +             if (!trans || trans->conn) {
> +                     send_error(conn, ENOENT);
> +                     return;
> +             }
> +     } else {
> +             /* Attach transaction to input for autofree until complete */
> +             trans = new_trans(in, generation, get_transaction_id());
> +
> +             trans->tdb = tdb_copy(tdb_context(conn), trans->tdb_name);
> +             if (!trans->tdb) {
> +                     send_error(conn, errno);
> +                     return;
> +             }
> +             /* TDB lifetime is that of transaction */
> +             talloc_steal(trans, trans->tdb);
> +     }
> +
> +     /* Now we own it. */
>       trans->conn = conn;
> -     trans->generation = generation;
> -     trans->tdb_name = talloc_asprintf(trans, "%s.%p",
> -                                       xs_daemon_tdb(), trans);
> -     trans->tdb = tdb_copy(tdb_context(conn), trans->tdb_name);
> -     if (!trans->tdb) {
> -             send_error(conn, errno);
> -             return;
> -     }
> -     /* Make it close if we go away. */
> -     talloc_steal(trans, trans->tdb);
> -
> -     /* Now we own it. */
>       conn->transaction = talloc_steal(conn, trans);
> -     list_add_tail(&trans->list, &transactions);
> -     talloc_set_destructor(trans, destroy_transaction);
> -     send_ack(conn, XS_TRANSACTION_START);
> +
> +     /* We return the transaction id as a string. */
> +     sprintf(id, "%i", trans->id);
> +     send_reply(conn, XS_TRANSACTION_START, id, strlen(id));
>  }
>  
>  void do_transaction_end(struct connection *conn, const char *arg)
> @@ -181,3 +237,37 @@
>       send_ack(conn, XS_TRANSACTION_END);
>  }
>  
> +/* Transactions sit in files: recover them. */
> +void recover_transactions(void)
> +{
> +     DIR *dir;
> +     struct dirent *dirent;
> +     int id;
> +     struct transaction *trans;
> +     char *transdir;
> +
> +     transdir = talloc_strdup(talloc_autofree_context(), xs_daemon_tdb());
> +     if (strrchr(transdir, '/'))
> +             *strchr(transdir, '/') = '\0';
> +     else
> +             transdir = talloc_strdup(transdir, ".");
> +
> +     dir = opendir(transdir);
> +     if (!dir)
> +             barf_perror("Could not open %s", transdir);
> +
> +     while ((dirent = readdir(dir)) != NULL) {
> +             if (!strstarts(dirent->d_name, "tdb."))
> +                     continue;
> +
> +             id = atoi(dirent->d_name + strlen("tdb."));
> +             trans = new_trans(transdir, -1, id);
> +             trans->conn = NULL;
> +             trans->tdb = tdb_open(trans->tdb_name, 0, 0, O_RDWR, 0);
> +             if (!trans->tdb) {
> +                     eprintf("Could not reopen transaction %i: corrupt?",
> +                             id);
> +                     talloc_free(trans);
> +             }
> +     }
> +}
> diff -r 5ea81e640509 -r 6d2f8b0a18c4 tools/xenstore/xenstored_transaction.h
> --- a/tools/xenstore/xenstored_transaction.h  Sun Sep 25 10:47:22 2005
> +++ b/tools/xenstore/xenstored_transaction.h  Mon Sep 26 04:30:14 2005
> @@ -32,4 +32,6 @@
>  
>  /* Return tdb context to use for this connection. */
>  TDB_CONTEXT *tdb_transaction_context(struct transaction *trans);
> +
> +void recover_transactions(void);
>  #endif /* _XENSTORED_TRANSACTION_H */
> 
> -- 
> A bad analogy is like a leaky screwdriver -- Richard Braakman
> 
> 

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