|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 6/8] tools/xenstored: replace the fire_watches() exact parameter
Today fire_watches() has the boolean "exact" parameter specifying how
the matching of the modified node with registered watches is to be
handled (only the exact node name is matching or all nodes being
in the subtree beneath the watched node).
For the handling of <special-watch>/<domid> watch events 2 additional
matching possibility needs to be added, as those events should only
be delivered to clients having requested such events, either by
watching <special-watch> with the depth=1 parameter, or by directly
watching for <special-watch>/<domid>, while the traditional special
watch events should NOT delivered to those watchers.
For this purpose rename the "exact" parameter to "match" and make it
an enum with four possible values.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
tools/xenstored/core.c | 12 +++++-----
tools/xenstored/transaction.c | 14 +++++++-----
tools/xenstored/transaction.h | 4 +++-
tools/xenstored/watch.c | 42 +++++++++++++++++++++++++----------
tools/xenstored/watch.h | 9 +++++++-
5 files changed, 55 insertions(+), 26 deletions(-)
diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 09f1390f14..109e319f8c 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -1612,7 +1612,7 @@ static int do_write(const void *ctx, struct connection
*conn,
return errno;
}
- fire_watches(conn, ctx, name, node, false, NULL);
+ fire_watches(conn, ctx, name, node, MATCH_SUBTREE, NULL);
send_ack(conn, XS_WRITE);
return 0;
@@ -1636,7 +1636,7 @@ static int do_mkdir(const void *ctx, struct connection
*conn,
node = create_node(conn, ctx, name, NULL, 0);
if (!node)
return errno;
- fire_watches(conn, ctx, name, node, false, NULL);
+ fire_watches(conn, ctx, name, node, MATCH_SUBTREE, NULL);
}
send_ack(conn, XS_MKDIR);
@@ -1682,7 +1682,7 @@ static int delnode_sub(const void *ctx, struct connection
*conn,
struct node *node, void *arg)
{
const char *root = arg;
- bool watch_exact;
+ enum watch_match watch_match;
int ret;
const char *db_name;
@@ -1702,8 +1702,8 @@ static int delnode_sub(const void *ctx, struct connection
*conn,
* This fine as we are single threaded and the next possible read will
* be handled only after the node has been really removed.
*/
- watch_exact = strcmp(root, node->name);
- fire_watches(conn, ctx, node->name, node, watch_exact, NULL);
+ watch_match = strcmp(root, node->name) ? MATCH_EXACT : MATCH_SUBTREE;
+ fire_watches(conn, ctx, node->name, node, watch_match, NULL);
return WALK_TREE_RM_CHILDENTRY;
}
@@ -1857,7 +1857,7 @@ static int do_set_perms(const void *ctx, struct
connection *conn,
if (write_node(conn, node, NODE_MODIFY, false))
return errno;
- fire_watches(conn, ctx, name, node, false, &old_perms);
+ fire_watches(conn, ctx, name, node, MATCH_SUBTREE, &old_perms);
send_ack(conn, XS_SET_PERMS);
return 0;
diff --git a/tools/xenstored/transaction.c b/tools/xenstored/transaction.c
index ccf93a1132..7e15aa8a2c 100644
--- a/tools/xenstored/transaction.c
+++ b/tools/xenstored/transaction.c
@@ -134,7 +134,7 @@ struct accessed_node
/* Watch event flags. */
bool fire_watch;
- bool watch_exact;
+ enum watch_match watch_match;
};
struct transaction
@@ -327,8 +327,10 @@ err:
* A watch event should be fired for a node modified inside a transaction.
* Set the corresponding information. A non-exact event is replacing an exact
* one, but not the other way round.
+ * No special watch handling needed here, so MATCH_DEPTH is no issue.
*/
-void queue_watches(struct connection *conn, const char *name, bool watch_exact)
+void queue_watches(struct connection *conn, const char *name,
+ enum watch_match watch_match)
{
struct accessed_node *i;
@@ -340,9 +342,9 @@ void queue_watches(struct connection *conn, const char
*name, bool watch_exact)
if (!i->fire_watch) {
i->fire_watch = true;
- i->watch_exact = watch_exact;
- } else if (!watch_exact) {
- i->watch_exact = false;
+ i->watch_match = watch_match;
+ } else if (watch_match == MATCH_SUBTREE) {
+ i->watch_match = MATCH_SUBTREE;
}
}
@@ -419,7 +421,7 @@ static int finalize_transaction(struct connection *conn,
db_delete(conn, i->node, NULL);
}
if (i->fire_watch)
- fire_watches(conn, trans, i->node, NULL, i->watch_exact,
+ fire_watches(conn, trans, i->node, NULL, i->watch_match,
i->perms.p ? &i->perms : NULL);
list_del(&i->list);
diff --git a/tools/xenstored/transaction.h b/tools/xenstored/transaction.h
index 90435b4fc9..b4f5f757e2 100644
--- a/tools/xenstored/transaction.h
+++ b/tools/xenstored/transaction.h
@@ -18,6 +18,7 @@
#ifndef _XENSTORED_TRANSACTION_H
#define _XENSTORED_TRANSACTION_H
#include "core.h"
+#include "watch.h"
enum node_access_type {
NODE_ACCESS_READ,
@@ -44,7 +45,8 @@ int __must_check access_node(struct connection *conn, struct
node *node,
enum node_access_type type, const char **db_name);
/* Queue watches for a modified node. */
-void queue_watches(struct connection *conn, const char *name, bool
watch_exact);
+void queue_watches(struct connection *conn, const char *name,
+ enum watch_match watch_match);
/* Prepend the transaction to name if appropriate. */
const char *transaction_prepend(struct connection *conn, const char *name);
diff --git a/tools/xenstored/watch.c b/tools/xenstored/watch.c
index 5de386370d..342b283285 100644
--- a/tools/xenstored/watch.c
+++ b/tools/xenstored/watch.c
@@ -128,7 +128,8 @@ static bool watch_permitted(struct connection *conn, const
void *ctx,
* watch event, too.
*/
void fire_watches(struct connection *conn, const void *ctx, const char *name,
- const struct node *node, bool exact, struct node_perms *perms)
+ const struct node *node, enum watch_match match,
+ struct node_perms *perms)
{
struct connection *i;
struct buffered_data *req;
@@ -136,7 +137,7 @@ void fire_watches(struct connection *conn, const void *ctx,
const char *name,
/* During transactions, don't fire watches, but queue them. */
if (conn && conn->transaction) {
- queue_watches(conn, name, exact);
+ queue_watches(conn, name, match);
return;
}
@@ -148,17 +149,34 @@ void fire_watches(struct connection *conn, const void
*ctx, const char *name,
continue;
list_for_each_entry(watch, &i->watches, list) {
- if (exact) {
- if (streq(name, watch->node))
- send_event(req, i,
- get_watch_path(watch, name),
- watch->token);
- } else {
- if (is_child(name, watch->node, watch->depth))
- send_event(req, i,
- get_watch_path(watch, name),
- watch->token);
+ bool send = false;
+
+ switch (match) {
+ case MATCH_EXACT:
+ send = streq(name, watch->node);
+ break;
+
+ case MATCH_SUBTREE:
+ send = is_child(name, watch->node,
+ watch->depth);
+ break;
+
+ case MATCH_DEPTH:
+ send = streq(name, watch->node) ||
+ (watch->depth > 0 &&
+ is_child(name, watch->node,
+ watch->depth));
+ break;
+
+ case MATCH_NODEPTH:
+ send = streq(name, watch->node) &&
+ watch->depth < 0;
+ break;
}
+
+ if (send)
+ send_event(req, i, get_watch_path(watch, name),
+ watch->token);
}
}
}
diff --git a/tools/xenstored/watch.h b/tools/xenstored/watch.h
index afdfdc6b2f..692343389f 100644
--- a/tools/xenstored/watch.h
+++ b/tools/xenstored/watch.h
@@ -27,8 +27,15 @@ int do_unwatch(const void *ctx, struct connection *conn,
struct buffered_data *in);
/* Fire all watches: !exact means all the children are affected (ie. rm). */
+enum watch_match {
+ MATCH_EXACT,
+ MATCH_SUBTREE,
+ MATCH_DEPTH, /* watches with depth > 0, MATCH_SUBTREE semantics */
+ MATCH_NODEPTH /* watches with no depth, MATCH_EXACT semantics */
+};
+
void fire_watches(struct connection *conn, const void *tmp, const char *name,
- const struct node *node, bool exact,
+ const struct node *node, enum watch_match match,
struct node_perms *perms);
void conn_delete_all_watches(struct connection *conn);
--
2.53.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |