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

[xen master] tools/xenstore: add read node state for live update



commit 34ceff030e482efcd261cca7a7f9b15213345cb4
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Wed Jan 13 14:00:20 2021 +0100
Commit:     Juergen Gross <jgross@xxxxxxxx>
CommitDate: Thu Jan 21 17:31:49 2021 +0100

    tools/xenstore: add read node state for live update
    
    Add the needed functions for reading node state for live update.
    
    This requires some refactoring of current node handling in Xenstore in
    order to avoid repeating the same code patterns multiple times.
    
    Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
    Reviewed-by: Paul Durrant <paul@xxxxxxx>
    Acked-by: Julien Grall <jgrall@xxxxxxxxxx>
    Acked-by: Wei Liu <wl@xxxxxxx>
---
 tools/xenstore/xenstored_control.c |   1 +
 tools/xenstore/xenstored_core.c    | 105 +++++++++++++++++++++++++++++++++----
 tools/xenstore/xenstored_core.h    |   1 +
 3 files changed, 96 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_control.c 
b/tools/xenstore/xenstored_control.c
index 7428b836a5..287417de6b 100644
--- a/tools/xenstore/xenstored_control.c
+++ b/tools/xenstore/xenstored_control.c
@@ -547,6 +547,7 @@ void lu_read_state(void)
                        xprintf("live-update: ignore transaction record\n");
                        break;
                case XS_STATE_TYPE_NODE:
+                       read_state_node(ctx, head + 1);
                        break;
                default:
                        xprintf("live-update: unknown state record %08x\n",
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b2c544b165..a5c1a56c6c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -979,13 +979,30 @@ static char *basename(const char *name)
        return strrchr(name, '/') + 1;
 }
 
-static struct node *construct_node(struct connection *conn, const void *ctx,
-                                  const char *name)
+static int add_child(const void *ctx, struct node *parent, const char *name)
 {
        const char *base;
        unsigned int baselen;
+       char *children;
+
+       base = basename(name);
+       baselen = strlen(base) + 1;
+       children = talloc_array(ctx, char, parent->childlen + baselen);
+       if (!children)
+               return ENOMEM;
+       memcpy(children, parent->children, parent->childlen);
+       memcpy(children + parent->childlen, base, baselen);
+       parent->children = children;
+       parent->childlen += baselen;
+
+       return 0;
+}
+
+static struct node *construct_node(struct connection *conn, const void *ctx,
+                                  const char *name)
+{
        struct node *parent, *node;
-       char *children, *parentname = get_parent(ctx, name);
+       char *parentname = get_parent(ctx, name);
 
        if (!parentname)
                return NULL;
@@ -998,15 +1015,8 @@ static struct node *construct_node(struct connection 
*conn, const void *ctx,
                return NULL;
 
        /* Add child to parent. */
-       base = basename(name);
-       baselen = strlen(base) + 1;
-       children = talloc_array(ctx, char, parent->childlen + baselen);
-       if (!children)
+       if (add_child(ctx, parent, name))
                goto nomem;
-       memcpy(children, parent->children, parent->childlen);
-       memcpy(children + parent->childlen, base, baselen);
-       parent->children = children;
-       parent->childlen += baselen;
 
        /* Allocate node */
        node = talloc(ctx, struct node);
@@ -2619,6 +2629,79 @@ void read_state_buffered_data(const void *ctx, struct 
connection *conn,
        }
 }
 
+void read_state_node(const void *ctx, const void *state)
+{
+       const struct xs_state_node *sn = state;
+       struct node *node, *parent;
+       TDB_DATA key;
+       char *name, *parentname;
+       unsigned int i;
+       struct connection conn = { .id = priv_domid };
+
+       name = (char *)(sn->perms + sn->perm_n);
+       node = talloc(ctx, struct node);
+       if (!node)
+               barf("allocation error restoring node");
+
+       node->name = name;
+       node->generation = ++generation;
+       node->datalen = sn->data_len;
+       node->data = name + sn->path_len;
+       node->childlen = 0;
+       node->children = NULL;
+       node->perms.num = sn->perm_n;
+       node->perms.p = talloc_array(node, struct xs_permissions,
+                                    node->perms.num);
+       if (!node->perms.p)
+               barf("allocation error restoring node");
+       for (i = 0; i < node->perms.num; i++) {
+               switch (sn->perms[i].access) {
+               case 'r':
+                       node->perms.p[i].perms = XS_PERM_READ;
+                       break;
+               case 'w':
+                       node->perms.p[i].perms = XS_PERM_WRITE;
+                       break;
+               case 'b':
+                       node->perms.p[i].perms = XS_PERM_READ | XS_PERM_WRITE;
+                       break;
+               default:
+                       node->perms.p[i].perms = XS_PERM_NONE;
+                       break;
+               }
+               if (sn->perms[i].flags & XS_STATE_NODE_PERM_IGNORE)
+                       node->perms.p[i].perms |= XS_PERM_IGNORE;
+               node->perms.p[i].id = sn->perms[i].domid;
+       }
+
+       if (strstarts(name, "@")) {
+               set_perms_special(&conn, name, &node->perms);
+               talloc_free(node);
+               return;
+       }
+
+       parentname = get_parent(node, name);
+       if (!parentname)
+               barf("allocation error restoring node");
+       parent = read_node(NULL, node, parentname);
+       if (!parent)
+               barf("read parent error restoring node");
+
+       if (add_child(node, parent, name))
+               barf("allocation error restoring node");
+
+       set_tdb_key(parentname, &key);
+       if (write_node_raw(NULL, &key, parent, true))
+               barf("write parent error restoring node");
+
+       set_tdb_key(name, &key);
+       if (write_node_raw(NULL, &key, node, true))
+               barf("write node error restoring node");
+       domain_entry_inc(&conn, node);
+
+       talloc_free(node);
+}
+
 /*
  * Local variables:
  *  mode: C
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index dcb3ad3e4b..6ac5a6fbfa 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -276,6 +276,7 @@ const char *dump_state_node_perms(FILE *fp, struct 
xs_state_node *sn,
 void read_state_global(const void *ctx, const void *state);
 void read_state_buffered_data(const void *ctx, struct connection *conn,
                              const struct xs_state_connection *sc);
+void read_state_node(const void *ctx, const void *state);
 
 #endif /* _XENSTORED_CORE_H */
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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