Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
xen.26660
xsa326-01.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa326-01.patch of Package xen.26660
From 5192f13a41661b1c1b9e0889d57c0f5b41925c39 Mon Sep 17 00:00:00 2001 From: Juergen Gross <jgross@suse.com> Date: Tue, 13 Sep 2022 07:35:07 +0200 Subject: tools/xenstore: split up send_reply() Today send_reply() is used for both, normal request replies and watch events. Split it up into send_reply() and send_event(). This will be used to add some event specific handling. add_event() can be merged into send_event(), removing the need for an intermediate memory allocation. This is part of XSA-326. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Julien Grall <jgrall@amazon.com> diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index e9c9695fd16e..249ad5ec6fb1 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -767,49 +767,32 @@ static void send_error(struct connection *conn, int error) void send_reply(struct connection *conn, enum xsd_sockmsg_type type, const void *data, unsigned int len) { - struct buffered_data *bdata; + struct buffered_data *bdata = conn->in; + + assert(type != XS_WATCH_EVENT); if ( len > XENSTORE_PAYLOAD_MAX ) { send_error(conn, E2BIG); return; } - /* Replies reuse the request buffer, events need a new one. */ - if (type != XS_WATCH_EVENT) { - bdata = conn->in; - /* Drop asynchronous responses, e.g. errors for watch events. */ - if (!bdata) - return; - bdata->inhdr = true; - bdata->used = 0; - conn->in = NULL; - } else { - /* Message is a child of the connection for auto-cleanup. */ - bdata = new_buffer(conn); + if (!bdata) + return; + bdata->inhdr = true; + bdata->used = 0; - /* - * Allocation failure here is unfortunate: we have no way to - * tell anybody about it. - */ - if (!bdata) - return; - } if (len <= DEFAULT_BUFFER_SIZE) bdata->buffer = bdata->default_buffer; - else + else { bdata->buffer = talloc_array(bdata, char, len); - if (!bdata->buffer) { - if (type == XS_WATCH_EVENT) { - /* Same as above: no way to tell someone. */ - talloc_free(bdata); + if (!bdata->buffer) { + send_error(conn, ENOMEM); return; } - /* re-establish request buffer for sending ENOMEM. */ - conn->in = bdata; - send_error(conn, ENOMEM); - return; } + conn->in = NULL; + /* Update relevant header fields and fill in the message body. */ bdata->hdr.msg.type = type; bdata->hdr.msg.len = len; @@ -817,8 +800,39 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type, /* Queue for later transmission. */ list_add_tail(&bdata->list, &conn->out_list); +} - return; +/* + * Send a watch event. + * As this is not directly related to the current command, errors can't be + * reported. + */ +void send_event(struct connection *conn, const char *path, const char *token) +{ + struct buffered_data *bdata; + unsigned int len; + + len = strlen(path) + 1 + strlen(token) + 1; + /* Don't try to send over-long events. */ + if (len > XENSTORE_PAYLOAD_MAX) + return; + + bdata = new_buffer(conn); + if (!bdata) + return; + + bdata->buffer = talloc_array(bdata, char, len); + if (!bdata->buffer) { + talloc_free(bdata); + return; + } + strcpy(bdata->buffer, path); + strcpy(bdata->buffer + strlen(path) + 1, token); + bdata->hdr.msg.type = XS_WATCH_EVENT; + bdata->hdr.msg.len = len; + + /* Queue for later transmission. */ + list_add_tail(&bdata->list, &conn->out_list); } /* Some routines (write, mkdir, etc) just need a non-error return */ diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index 0004fa848c83..9af9af4390bd 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -187,6 +187,7 @@ unsigned int get_string(const struct buffered_data *data, unsigned int offset); void send_reply(struct connection *conn, enum xsd_sockmsg_type type, const void *data, unsigned int len); +void send_event(struct connection *conn, const char *path, const char *token); /* Some routines (write, mkdir, etc) just need a non-error return */ void send_ack(struct connection *conn, enum xsd_sockmsg_type type); diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index aca0a71bada1..99a2c266b28a 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -86,35 +86,6 @@ static const char *get_watch_path(const struct watch *watch, const char *name) } /* - * Send a watch event. - * Temporary memory allocations are done with ctx. - */ -static void add_event(struct connection *conn, - const void *ctx, - struct watch *watch, - const char *name) -{ - /* Data to send (node\0token\0). */ - unsigned int len; - char *data; - - name = get_watch_path(watch, name); - - len = strlen(name) + 1 + strlen(watch->token) + 1; - /* Don't try to send over-long events. */ - if (len > XENSTORE_PAYLOAD_MAX) - return; - - data = talloc_array(ctx, char, len); - if (!data) - return; - strcpy(data, name); - strcpy(data + strlen(name) + 1, watch->token); - send_reply(conn, XS_WATCH_EVENT, data, len); - talloc_free(data); -} - -/* * Check permissions of a specific watch to fire: * Either the node itself or its parent have to be readable by the connection * the watch has been setup for. In case a watch event is created due to @@ -190,10 +161,14 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name, list_for_each_entry(watch, &i->watches, list) { if (exact) { if (streq(name, watch->node)) - add_event(i, ctx, watch, name); + send_event(i, + get_watch_path(watch, name), + watch->token); } else { if (is_child(name, watch->node)) - add_event(i, ctx, watch, name); + send_event(i, + get_watch_path(watch, name), + watch->token); } } } @@ -292,7 +267,7 @@ int do_watch(struct connection *conn, struct buffered_data *in) send_ack(conn, XS_WATCH); /* We fire once up front: simplifies clients and restart. */ - add_event(conn, in, watch, watch->node); + send_event(conn, get_watch_path(watch, watch->node), watch->token); return 0; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor