tools/xenstored: Limit the number of requests a connection can delay
authorJulien Grall <jgrall@amazon.com>
Thu, 24 Jun 2021 08:07:30 +0000 (09:07 +0100)
committerJulien Grall <jgrall@amazon.com>
Thu, 24 Jun 2021 08:07:30 +0000 (09:07 +0100)
Currently, only liveupdate request can be delayed. The request can only
be performed by a privileged connection (e.g. dom0). So it is fine to
have no limits.

In a follow-up patch we will want to delay request for unprivileged
connection as well. So it is best to apply a limit.

For now and for simplicity, only a single request can be delayed
for a given unprivileged connection.

Take the opportunity to tweak the prototype and provide a way to
bypass the quota check. This would be useful when the function
is called from the restore code.

Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
tools/xenstore/xenstored_control.c
tools/xenstore/xenstored_core.c
tools/xenstore/xenstored_core.h

index 7acc2d134f9f9f4f052850bda8e9336789cca56e..1c24d4869eabb92cd13cfa887b520102a1dce0bb 100644 (file)
@@ -737,7 +737,7 @@ static const char *lu_start(const void *ctx, struct connection *conn,
        lu_status->timeout = to;
        lu_status->started_at = time(NULL);
 
-       errno = delay_request(conn, conn->in, do_lu_start, NULL);
+       errno = delay_request(conn, conn->in, do_lu_start, NULL, false);
 
        return NULL;
 }
index 4b6509b90de93299365a1605fc7442cb93b1ffc9..268b0187e6baeafdf34a492bd30ed170f63a9766 100644 (file)
@@ -279,10 +279,19 @@ static void call_delayed(struct delayed_request *req)
 }
 
 int delay_request(struct connection *conn, struct buffered_data *in,
-                 bool (*func)(struct delayed_request *), void *data)
+                 bool (*func)(struct delayed_request *), void *data,
+                 bool no_quota_check)
 {
        struct delayed_request *req;
 
+       /*
+        * Only allow one request can be delayed for an unprivileged
+        * connection.
+        */
+       if (!no_quota_check && domain_is_unprivileged(conn) &&
+           !list_empty(&conn->delayed))
+               return ENOSPC;
+
        req = talloc(in, struct delayed_request);
        if (!req)
                return ENOMEM;
index 89ce155e755b059ecdadb8e4391814f34262be45..34839b34f6e96544201c152239c07628278d2f84 100644 (file)
@@ -213,7 +213,8 @@ char *get_parent(const void *ctx, const char *node);
 
 /* Delay a request. */
 int delay_request(struct connection *conn, struct buffered_data *in,
-                 bool (*func)(struct delayed_request *), void *data);
+                 bool (*func)(struct delayed_request *), void *data,
+                 bool no_quota_check);
 
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);