[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v11 25/27] tools/xenstore: add read watch state for live update
Add reading the watch state records for live update. This requires factoring out some of the add watch functionality into a dedicated function. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Reviewed-by: Paul Durrant <paul@xxxxxxx> --- V4: - add comment (Julien Grall) V6: - correct check_watch_path() (setting errno) --- tools/xenstore/xenstored_control.c | 2 + tools/xenstore/xenstored_watch.c | 114 +++++++++++++++++++++-------- tools/xenstore/xenstored_watch.h | 2 + 3 files changed, 88 insertions(+), 30 deletions(-) diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c index d73e1dca7e..ba48358c31 100644 --- a/tools/xenstore/xenstored_control.c +++ b/tools/xenstore/xenstored_control.c @@ -35,6 +35,7 @@ Interactive commands for Xen Store Daemon. #include "xenstored_core.h" #include "xenstored_control.h" #include "xenstored_domain.h" +#include "xenstored_watch.h" /* Mini-OS only knows about MAP_ANON. */ #ifndef MAP_ANONYMOUS @@ -542,6 +543,7 @@ void lu_read_state(void) read_state_connection(ctx, head + 1); break; case XS_STATE_TYPE_WATCH: + read_state_watch(ctx, head + 1); break; case XS_STATE_TYPE_TA: xprintf("live-update: ignore transaction record\n"); diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 9248f08bd9..db89e0141f 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -205,6 +205,62 @@ static int destroy_watch(void *_watch) return 0; } +static int check_watch_path(struct connection *conn, const void *ctx, + char **path, bool *relative) +{ + /* Check if valid event. */ + if (strstarts(*path, "@")) { + *relative = false; + if (strlen(*path) > XENSTORE_REL_PATH_MAX) + goto inval; + } else { + *relative = !strstarts(*path, "/"); + *path = canonicalize(conn, ctx, *path); + if (!*path) + return errno; + if (!is_valid_nodename(*path)) + goto inval; + } + + return 0; + + inval: + errno = EINVAL; + return errno; +} + +static struct watch *add_watch(struct connection *conn, char *path, char *token, + bool relative) +{ + struct watch *watch; + + watch = talloc(conn, struct watch); + if (!watch) + goto nomem; + watch->node = talloc_strdup(watch, path); + watch->token = talloc_strdup(watch, token); + if (!watch->node || !watch->token) + goto nomem; + + if (relative) + watch->relative_path = get_implicit_path(conn); + else + watch->relative_path = NULL; + + INIT_LIST_HEAD(&watch->events); + + domain_watch_inc(conn); + list_add_tail(&watch->list, &conn->watches); + talloc_set_destructor(watch, destroy_watch); + + return watch; + + nomem: + talloc_free(watch); + errno = ENOMEM; + return NULL; +} + int do_watch(struct connection *conn, struct buffered_data *in) { struct watch *watch; @@ -214,19 +270,9 @@ int do_watch(struct connection *conn, struct buffered_data *in) if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) return EINVAL; - if (strstarts(vec[0], "@")) { - relative = false; - if (strlen(vec[0]) > XENSTORE_REL_PATH_MAX) - return EINVAL; - /* check if valid event */ - } else { - relative = !strstarts(vec[0], "/"); - vec[0] = canonicalize(conn, in, vec[0]); - if (!vec[0]) - return ENOMEM; - if (!is_valid_nodename(vec[0])) - return EINVAL; - } + errno = check_watch_path(conn, in, &(vec[0]), &relative); + if (errno) + return errno; /* Check for duplicates. */ list_for_each_entry(watch, &conn->watches, list) { @@ -238,26 +284,11 @@ int do_watch(struct connection *conn, struct buffered_data *in) if (domain_watch(conn) > quota_nb_watch_per_domain) return E2BIG; - watch = talloc(conn, struct watch); + watch = add_watch(conn, vec[0], vec[1], relative); if (!watch) - return ENOMEM; - watch->node = talloc_strdup(watch, vec[0]); - watch->token = talloc_strdup(watch, vec[1]); - if (!watch->node || !watch->token) { - talloc_free(watch); - return ENOMEM; - } - if (relative) - watch->relative_path = get_implicit_path(conn); - else - watch->relative_path = NULL; + return errno; - INIT_LIST_HEAD(&watch->events); - - domain_watch_inc(conn); - list_add_tail(&watch->list, &conn->watches); trace_create(watch, "watch"); - talloc_set_destructor(watch, destroy_watch); send_ack(conn, XS_WATCH); /* We fire once up front: simplifies clients and restart. */ @@ -338,6 +369,29 @@ const char *dump_state_watches(FILE *fp, struct connection *conn, return ret; } +void read_state_watch(const void *ctx, const void *state) +{ + const struct xs_state_watch *sw = state; + struct connection *conn; + char *path, *token; + bool relative; + + conn = get_connection_by_id(sw->conn_id); + if (!conn) + barf("connection not found for read watch"); + + path = (char *)sw->data; + token = path + sw->path_length; + + /* Don't check success, we want the relative information only. */ + check_watch_path(conn, ctx, &path, &relative); + if (!path) + barf("allocation error for read watch"); + + if (!add_watch(conn, path, token, relative)) + barf("error adding watch"); +} + /* * Local variables: * mode: C diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h index 3d81645f45..0e693f0839 100644 --- a/tools/xenstore/xenstored_watch.h +++ b/tools/xenstore/xenstored_watch.h @@ -33,4 +33,6 @@ void conn_delete_all_watches(struct connection *conn); const char *dump_state_watches(FILE *fp, struct connection *conn, unsigned int conn_id); +void read_state_watch(const void *ctx, const void *state); + #endif /* _XENSTORED_WATCH_H */ -- 2.26.2
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |