From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>, Ian Jackson <iwj@xenproject.org>,
Wei Liu <wl@xen.org>, Julien Grall <jgrall@amazon.com>
Subject: [PATCH v12 23/27] tools/xenstore: add read connection state for live update
Date: Fri, 15 Jan 2021 09:29:56 +0100 [thread overview]
Message-ID: <20210115083000.14186-24-jgross@suse.com> (raw)
In-Reply-To: <20210115083000.14186-1-jgross@suse.com>
Add the needed functions for reading connection state for live update.
As the connection is identified by a unique connection id in the state
records we need to add this to struct connection. Add a new function
to return the connection based on a connection id.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
---
V2:
- fixed condition in introduce_domain() (Julien Grall)
V4:
- set pending data msg type to XS_INVALID (Julien Grall)
- add buffered read data (Julien Grall)
V5:
- really read buffered read data (Julien Grall)
- drop conn parameter from introduce_domain() (Paul Durrant)
- split pending write data into individual buffers
V6:
- rename "first" to "partial" (Paul Durrant)
V7:
- use local port from connection data
V8:
- remove dom0 special handling
---
tools/xenstore/xenstored_control.c | 1 +
tools/xenstore/xenstored_core.c | 102 ++++++++++++++++++++++++++++-
tools/xenstore/xenstored_core.h | 10 +++
tools/xenstore/xenstored_domain.c | 60 +++++++++++++----
tools/xenstore/xenstored_domain.h | 2 +
5 files changed, 162 insertions(+), 13 deletions(-)
diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c
index d94b558e99..7428b836a5 100644
--- a/tools/xenstore/xenstored_control.c
+++ b/tools/xenstore/xenstored_control.c
@@ -539,6 +539,7 @@ void lu_read_state(void)
read_state_global(ctx, head + 1);
break;
case XS_STATE_TYPE_CONN:
+ read_state_connection(ctx, head + 1);
break;
case XS_STATE_TYPE_WATCH:
break;
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 60e98104ad..b2c544b165 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1582,12 +1582,35 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
return new;
}
+struct connection *get_connection_by_id(unsigned int conn_id)
+{
+ struct connection *conn;
+
+ list_for_each_entry(conn, &connections, list)
+ if (conn->conn_id == conn_id)
+ return conn;
+
+ return NULL;
+}
+
#ifdef NO_SOCKETS
static void accept_connection(int sock)
{
}
+
+int writefd(struct connection *conn, const void *data, unsigned int len)
+{
+ errno = EBADF;
+ return -1;
+}
+
+int readfd(struct connection *conn, void *data, unsigned int len)
+{
+ errno = EBADF;
+ return -1;
+}
#else
-static int writefd(struct connection *conn, const void *data, unsigned int len)
+int writefd(struct connection *conn, const void *data, unsigned int len)
{
int rc;
@@ -1603,7 +1626,7 @@ static int writefd(struct connection *conn, const void *data, unsigned int len)
return rc;
}
-static int readfd(struct connection *conn, void *data, unsigned int len)
+int readfd(struct connection *conn, void *data, unsigned int len)
{
int rc;
@@ -2521,6 +2544,81 @@ void read_state_global(const void *ctx, const void *state)
domain_init(glb->evtchn_fd);
}
+static void add_buffered_data(struct buffered_data *bdata,
+ struct connection *conn, const uint8_t *data,
+ unsigned int len)
+{
+ bdata->hdr.msg.len = len;
+ if (len <= DEFAULT_BUFFER_SIZE)
+ bdata->buffer = bdata->default_buffer;
+ else
+ bdata->buffer = talloc_array(bdata, char, len);
+ if (!bdata->buffer)
+ barf("error restoring buffered data");
+
+ memcpy(bdata->buffer, data, len);
+
+ /* Queue for later transmission. */
+ list_add_tail(&bdata->list, &conn->out_list);
+}
+
+void read_state_buffered_data(const void *ctx, struct connection *conn,
+ const struct xs_state_connection *sc)
+{
+ struct buffered_data *bdata;
+ const uint8_t *data;
+ unsigned int len;
+ bool partial = sc->data_resp_len;
+
+ if (sc->data_in_len) {
+ bdata = new_buffer(conn);
+ if (!bdata)
+ barf("error restoring read data");
+ if (sc->data_in_len < sizeof(bdata->hdr)) {
+ bdata->inhdr = true;
+ memcpy(&bdata->hdr, sc->data, sc->data_in_len);
+ bdata->used = sc->data_in_len;
+ } else {
+ bdata->inhdr = false;
+ memcpy(&bdata->hdr, sc->data, sizeof(bdata->hdr));
+ if (bdata->hdr.msg.len <= DEFAULT_BUFFER_SIZE)
+ bdata->buffer = bdata->default_buffer;
+ else
+ bdata->buffer = talloc_array(bdata, char,
+ bdata->hdr.msg.len);
+ if (!bdata->buffer)
+ barf("Error allocating in buffer");
+ bdata->used = sc->data_in_len - sizeof(bdata->hdr);
+ memcpy(bdata->buffer, sc->data + sizeof(bdata->hdr),
+ bdata->used);
+ }
+
+ conn->in = bdata;
+ }
+
+ for (data = sc->data + sc->data_in_len;
+ data < sc->data + sc->data_in_len + sc->data_out_len;
+ data += len) {
+ bdata = new_buffer(conn);
+ if (!bdata)
+ barf("error restoring buffered data");
+ if (partial) {
+ bdata->inhdr = false;
+ /* Make trace look nice. */
+ bdata->hdr.msg.type = XS_INVALID;
+ len = sc->data_resp_len;
+ add_buffered_data(bdata, conn, data, len);
+ partial = false;
+ continue;
+ }
+
+ memcpy(&bdata->hdr, data, sizeof(bdata->hdr));
+ data += sizeof(bdata->hdr);
+ len = bdata->hdr.msg.len;
+ add_buffered_data(bdata, conn, data, len);
+ }
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ac9fe1559e..dcb3ad3e4b 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -135,6 +135,9 @@ struct connection
/* Methods for communicating over this connection: write can be NULL */
connwritefn_t *write;
connreadfn_t *read;
+
+ /* Support for live update: connection id. */
+ unsigned int conn_id;
};
extern struct list_head connections;
@@ -195,6 +198,7 @@ struct node *read_node(struct connection *conn, const void *ctx,
const char *name);
struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
+struct connection *get_connection_by_id(unsigned int conn_id);
void check_store(void);
void corrupt(struct connection *conn, const char *fmt, ...);
enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -250,6 +254,10 @@ void finish_daemonize(void);
/* Open a pipe for signal handling */
void init_pipe(int reopen_log_pipe[2]);
+int writefd(struct connection *conn, const void *data, unsigned int len);
+int readfd(struct connection *conn, void *data, unsigned int len);
+
+extern struct interface_funcs socket_funcs;
extern xengnttab_handle **xgt_handle;
int remember_string(struct hashtable *hash, const char *str);
@@ -266,6 +274,8 @@ const char *dump_state_node_perms(FILE *fp, struct xs_state_node *sn,
unsigned int n_perms);
void read_state_global(const void *ctx, const void *state);
+void read_state_buffered_data(const void *ctx, struct connection *conn,
+ const struct xs_state_connection *sc);
#endif /* _XENSTORED_CORE_H */
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 775546757b..6934f1bc89 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -355,7 +355,7 @@ static struct domain *find_or_alloc_domain(const void *ctx, unsigned int domid)
return domain ? : alloc_domain(ctx, domid);
}
-static int new_domain(struct domain *domain, int port)
+static int new_domain(struct domain *domain, int port, bool restore)
{
int rc;
@@ -369,11 +369,16 @@ static int new_domain(struct domain *domain, int port)
wrl_domain_new(domain);
- /* Tell kernel we're interested in this event. */
- rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
- if (rc == -1)
- return errno;
- domain->port = rc;
+ if (restore)
+ domain->port = port;
+ else {
+ /* Tell kernel we're interested in this event. */
+ rc = xenevtchn_bind_interdomain(xce_handle, domain->domid,
+ port);
+ if (rc == -1)
+ return errno;
+ domain->port = rc;
+ }
domain->introduced = true;
@@ -423,7 +428,7 @@ static void domain_conn_reset(struct domain *domain)
static struct domain *introduce_domain(const void *ctx,
unsigned int domid,
- evtchn_port_t port)
+ evtchn_port_t port, bool restore)
{
struct domain *domain;
int rc;
@@ -439,7 +444,7 @@ static struct domain *introduce_domain(const void *ctx,
: map_interface(domid);
if (!interface)
return NULL;
- if (new_domain(domain, port)) {
+ if (new_domain(domain, port, restore)) {
rc = errno;
if (is_master_domain)
unmap_xenbus(interface);
@@ -453,7 +458,7 @@ static struct domain *introduce_domain(const void *ctx,
/* Now domain belongs to its connection. */
talloc_steal(domain->conn, domain);
- if (!is_master_domain)
+ if (!is_master_domain && !restore)
fire_watches(NULL, ctx, "@introduceDomain", NULL,
false, NULL);
} else {
@@ -486,7 +491,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
if (port <= 0)
return EINVAL;
- domain = introduce_domain(in, domid, port);
+ domain = introduce_domain(in, domid, port, false);
if (!domain)
return errno;
@@ -715,7 +720,7 @@ void dom0_init(void)
if (port == -1)
barf_perror("Failed to initialize dom0 port");
- dom0 = introduce_domain(NULL, xenbus_master_domid(), port);
+ dom0 = introduce_domain(NULL, xenbus_master_domid(), port, false);
if (!dom0)
barf_perror("Failed to initialize dom0");
@@ -1261,6 +1266,39 @@ const char *dump_state_special_nodes(FILE *fp)
return ret;
}
+void read_state_connection(const void *ctx, const void *state)
+{
+ const struct xs_state_connection *sc = state;
+ struct connection *conn;
+ struct domain *domain, *tdomain;
+
+ if (sc->conn_type == XS_STATE_CONN_TYPE_SOCKET) {
+ conn = new_connection(writefd, readfd);
+ if (!conn)
+ barf("error restoring connection");
+ conn->fd = sc->spec.socket_fd;
+ } else {
+ domain = introduce_domain(ctx, sc->spec.ring.domid,
+ sc->spec.ring.evtchn, true);
+ if (!domain)
+ barf("domain allocation error");
+
+ if (sc->spec.ring.tdomid != DOMID_INVALID) {
+ tdomain = find_or_alloc_domain(ctx,
+ sc->spec.ring.tdomid);
+ if (!tdomain)
+ barf("target domain allocation error");
+ talloc_reference(domain->conn, tdomain->conn);
+ domain->conn->target = tdomain->conn;
+ }
+ conn = domain->conn;
+ }
+
+ conn->conn_id = sc->conn_id;
+
+ read_state_buffered_data(ctx, conn, sc);
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index b20269b038..8f3b4e0f8b 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -101,4 +101,6 @@ void wrl_apply_debit_trans_commit(struct connection *conn);
const char *dump_state_connections(FILE *fp, struct connection *conn);
const char *dump_state_special_nodes(FILE *fp);
+void read_state_connection(const void *ctx, const void *state);
+
#endif /* _XENSTORED_DOMAIN_H */
--
2.26.2
next prev parent reply other threads:[~2021-01-15 8:40 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-15 8:29 [PATCH v12 00/27] tools/xenstore: support live update for xenstored Juergen Gross
2021-01-15 8:29 ` [PATCH v12 01/27] tools/libxenevtchn: switch to standard xen coding style Juergen Gross
2021-01-15 8:29 ` [PATCH v12 02/27] tools/libxenevtchn: rename open_flags to flags Juergen Gross
2021-01-15 8:29 ` [PATCH v12 03/27] tools/libxenevtchn: check xenevtchn_open() flags for not supported bits Juergen Gross
2021-01-15 8:29 ` [PATCH v12 04/27] tools/libxenevtchn: propagate xenevtchn_open() flags parameter Juergen Gross
2021-01-15 8:29 ` [PATCH v12 05/27] tools/libxenevtchn: add possibility to not close file descriptor on exec Juergen Gross
2021-01-15 8:29 ` [PATCH v12 06/27] tools/xenstore: refactor XS_CONTROL handling Juergen Gross
2021-01-15 8:29 ` [PATCH v12 07/27] tools/xenstore: add live update command to xenstore-control Juergen Gross
2021-01-15 8:29 ` [PATCH v12 08/27] tools/xenstore: add basic live-update command parsing Juergen Gross
2021-01-15 8:29 ` [PATCH v12 09/27] tools/xenstore: introduce live update status block Juergen Gross
2021-01-15 8:29 ` [PATCH v12 10/27] tools/xenstore: save new binary for live update Juergen Gross
2021-01-15 8:29 ` [PATCH v12 11/27] tools/xenstore: add command line handling " Juergen Gross
2021-01-15 8:29 ` [PATCH v12 12/27] tools/xenstore: add support for delaying execution of a xenstore request Juergen Gross
2021-01-15 8:29 ` [PATCH v12 13/27] tools/xenstore: add the basic framework for doing the live update Juergen Gross
2021-01-15 8:29 ` [PATCH v12 14/27] tools/xenstore: allow live update only with no transaction active Juergen Gross
2021-01-15 8:29 ` [PATCH v12 15/27] docs: update the xenstore migration stream documentation Juergen Gross
2021-01-15 8:29 ` [PATCH v12 16/27] tools/xenstore: add include file for state structure definitions Juergen Gross
2021-01-15 8:29 ` [PATCH v12 17/27] tools/xenstore: dump the xenstore state for live update Juergen Gross
2021-01-15 8:29 ` [PATCH v12 18/27] tools/xenstore: handle CLOEXEC flag for local files and pipes Juergen Gross
2021-01-15 8:29 ` [PATCH v12 19/27] tools/xenstore: split off domain introduction from do_introduce() Juergen Gross
2021-01-15 8:29 ` [PATCH v12 20/27] tools/xenstore: evaluate the live update flag when starting Juergen Gross
2021-01-15 8:29 ` [PATCH v12 21/27] tools/xenstore: read internal state when doing live upgrade Juergen Gross
2021-01-15 8:29 ` [PATCH v12 22/27] tools/xenstore: add reading global state for live update Juergen Gross
2021-01-15 8:29 ` Juergen Gross [this message]
2021-01-15 8:29 ` [PATCH v12 24/27] tools/xenstore: add read node " Juergen Gross
2021-01-15 8:29 ` [PATCH v12 25/27] tools/xenstore: add read watch " Juergen Gross
2021-01-15 8:29 ` [PATCH v12 26/27] tools/xenstore: handle dying domains in " Juergen Gross
2021-01-15 8:30 ` [PATCH v12 27/27] tools/xenstore: activate new binary for " Juergen Gross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210115083000.14186-24-jgross@suse.com \
--to=jgross@suse.com \
--cc=iwj@xenproject.org \
--cc=jgrall@amazon.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).