[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v8 8/9] tools/xenstored: use unique_id to identify new domain with same domid
Use the new unique_id of a domain in order to detect that a domain has been replaced with another one reusing the doamin-id of the old domain. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- V8: - new patch --- tools/xenstored/domain.c | 53 +++++++++++++++++++++++++++----- tools/xenstored/xenstore_state.h | 2 +- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index a6506a5bb2..63df24030e 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -110,6 +110,7 @@ struct domain { /* The id of this domain */ unsigned int domid; + uint64_t unique_id; /* Event channel port */ evtchn_port_t port; @@ -627,9 +628,17 @@ static int check_domain(const void *k, void *v, void *arg) int dom_invalid; struct domain *domain = v; bool *notify = arg; + uint64_t unique_id; dom_invalid = xenmanage_get_domain_info(xm_handle, domain->domid, - &state, NULL); + &state, &unique_id); + if (!dom_invalid) { + if (!domain->unique_id) + domain->unique_id = unique_id; + else if (domain->unique_id != unique_id) + dom_invalid = 1; + } + if (!domain->introduced) { if (dom_invalid) talloc_free(domain); @@ -747,7 +756,8 @@ int domain_max_global_acc(const void *ctx, struct connection *conn) return 0; } -static struct domain *alloc_domain(const void *context, unsigned int domid) +static struct domain *alloc_domain(const void *context, unsigned int domid, + uint64_t unique_id) { struct domain *domain; @@ -758,6 +768,7 @@ static struct domain *alloc_domain(const void *context, unsigned int domid) } domain->domid = domid; + domain->unique_id = unique_id; domain->generation = generation; domain->introduced = false; @@ -777,16 +788,27 @@ static struct domain *find_or_alloc_domain(const void *ctx, unsigned int domid) struct domain *domain; domain = find_domain_struct(domid); - return domain ? : alloc_domain(ctx, domid); + /* If domain not already known, use unique_id = 0 meaning "unknown". */ + return domain ? : alloc_domain(ctx, domid, 0); } static struct domain *find_or_alloc_existing_domain(unsigned int domid) { struct domain *domain; + uint64_t unique_id = 0; + int dom_invalid = 0; domain = find_domain_struct(domid); - if (!domain && !xenmanage_get_domain_info(xm_handle, domid, NULL, NULL)) - domain = alloc_domain(NULL, domid); + if (!domain || !domain->unique_id) + dom_invalid = xenmanage_get_domain_info(xm_handle, domid, + NULL, &unique_id); + + if (!dom_invalid) { + if (!domain) + domain = alloc_domain(NULL, domid, unique_id); + else if (unique_id) + domain->unique_id = unique_id; + } return domain; } @@ -1321,15 +1343,16 @@ int domain_alloc_permrefs(struct node_perms *perms) { unsigned int i, domid; struct domain *d; + uint64_t unique_id; for (i = 0; i < perms->num; i++) { domid = perms->p[i].id; d = find_domain_struct(domid); if (!d) { if (xenmanage_get_domain_info(xm_handle, domid, - NULL, NULL)) + NULL, &unique_id)) perms->p[i].perms |= XS_PERM_IGNORE; - else if (!alloc_domain(NULL, domid)) + else if (!alloc_domain(NULL, domid, unique_id)) return ENOMEM; } } @@ -1697,12 +1720,14 @@ const char *dump_state_connections(FILE *fp) struct xs_state_record_header head; struct connection *c; + BUILD_BUG_ON(sizeof(c->domain->unique_id) != sizeof(uint64_t)); + list_for_each_entry(c, &connections, list) { head.type = XS_STATE_TYPE_CONN; head.length = sizeof(sc); sc.conn_id = conn_id++; - sc.pad = 0; + sc.uniq_id_off = 0; memset(&sc.spec, 0, sizeof(sc.spec)); if (c->domain) { sc.conn_type = XS_STATE_CONN_TYPE_RING; @@ -1720,6 +1745,10 @@ const char *dump_state_connections(FILE *fp) return ret; head.length += sc.data_in_len + sc.data_out_len; head.length = ROUNDUP(head.length, 3); + if (c->domain) { + sc.uniq_id_off = head.length; + head.length += sizeof(uint64_t); + } if (fwrite(&head, sizeof(head), 1, fp) != 1) return "Dump connection state error"; if (fwrite(&sc, offsetof(struct xs_state_connection, data), @@ -1731,6 +1760,9 @@ const char *dump_state_connections(FILE *fp) ret = dump_state_align(fp); if (ret) return ret; + if (c->domain && + fwrite(&c->domain->unique_id, sizeof(uint64_t), 1, fp) != 1) + return "Dump connection state error"; ret = dump_state_watches(fp, c, sc.conn_id); if (ret) @@ -1748,6 +1780,7 @@ void read_state_connection(const void *ctx, const void *state) if (sc->conn_type == XS_STATE_CONN_TYPE_SOCKET) { conn = add_socket_connection(sc->spec.socket_fd); + domain = NULL; } else { domain = introduce_domain(ctx, sc->spec.ring.domid, sc->spec.ring.evtchn, true); @@ -1778,6 +1811,10 @@ void read_state_connection(const void *ctx, const void *state) conn->conn_id = sc->conn_id; read_state_buffered_data(ctx, conn, sc); + + /* Validity of unique_id will be tested by check_domains() later. */ + if (sc->uniq_id_off && domain) + domain->unique_id = *(uint64_t *)(state + sc->uniq_id_off); } struct domain_acc { diff --git a/tools/xenstored/xenstore_state.h b/tools/xenstored/xenstore_state.h index ae0d053c8f..4c785e3774 100644 --- a/tools/xenstored/xenstore_state.h +++ b/tools/xenstored/xenstore_state.h @@ -74,7 +74,7 @@ struct xs_state_connection { uint16_t conn_type; #define XS_STATE_CONN_TYPE_RING 0 #define XS_STATE_CONN_TYPE_SOCKET 1 - uint16_t pad; + uint16_t uniq_id_off; union { struct { uint16_t domid; /* Domain-Id. */ -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |