diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 1cb729a2cd..d7c025616e 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn, corrupt(conn, "Can't find child '%s' in %s", childname, node->name); } -static int delete_node(struct connection *conn, struct node *parent, - struct node *node) +static int delete_node(struct connection *conn, const void *ctx, + struct node *parent, struct node *node) { char *name; @@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent, node->children); child = name ? read_node(conn, node, name) : NULL; if (child) { - if (delete_node(conn, node, child)) + if (delete_node(conn, ctx, node, child)) return errno; } else { trace("delete_node: Error deleting child '%s/%s'!\n", @@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent, talloc_free(name); } + fire_watches(conn, ctx, node->name, true); delete_node_single(conn, node); delete_child(conn, parent, basename(node->name)); talloc_free(node); @@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node, * This fine as we are single threaded and the next possible read will * be handled only after the node has been really removed. */ - fire_watches(conn, ctx, name, true); - return delete_node(conn, parent, node); + fire_watches(conn, ctx, name, false); + return delete_node(conn, ctx, parent, node); } diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index f0bbfe7a6d..3836675459 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -122,7 +122,7 @@ static void add_event(struct connection *conn, * Temporary memory allocations are done with ctx. */ void fire_watches(struct connection *conn, const void *ctx, const char *name, - bool recurse) + bool exact) { struct connection *i; struct watch *watch; @@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name, /* Create an event for each watch. */ list_for_each_entry(i, &connections, list) { list_for_each_entry(watch, &i->watches, list) { - if (is_child(name, watch->node)) - add_event(i, ctx, watch, name); - else if (recurse && is_child(watch->node, name)) - add_event(i, ctx, watch, watch->node); + if (exact) { + if (streq(name, watch->node)) + add_event(i, ctx, watch, name); + } else { + if (is_child(name, watch->node)) + add_event(i, ctx, watch, name); + } } } } diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h index 54d4ea7e0d..1b3c80d3dd 100644 --- a/tools/xenstore/xenstored_watch.h +++ b/tools/xenstore/xenstored_watch.h @@ -24,9 +24,9 @@ int do_watch(struct connection *conn, struct buffered_data *in); int do_unwatch(struct connection *conn, struct buffered_data *in); -/* Fire all watches: recurse means all the children are affected (ie. rm). */ +/* Fire all watches: !exact means all the children are affected (ie. rm). */ void fire_watches(struct connection *conn, const void *tmp, const char *name, - bool recurse); + bool exact); void conn_delete_all_watches(struct connection *conn);