diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c index 454fe9d5ab..3585d7c695 100644 --- a/tools/xenstore/xenstored_control.c +++ b/tools/xenstore/xenstored_control.c @@ -30,11 +30,11 @@ struct cmd_s { char *cmd; - int (*func)(void *, struct connection *, char **, int); + int (*func)(const void *, struct connection *, char **, int); char *pars; }; -static int do_control_check(void *ctx, struct connection *conn, +static int do_control_check(const void *ctx, struct connection *conn, char **vec, int num) { if (num) @@ -46,7 +46,7 @@ static int do_control_check(void *ctx, struct connection *conn, return 0; } -static int do_control_log(void *ctx, struct connection *conn, +static int do_control_log(const void *ctx, struct connection *conn, char **vec, int num) { if (num != 1) @@ -63,7 +63,7 @@ static int do_control_log(void *ctx, struct connection *conn, return 0; } -static int do_control_logfile(void *ctx, struct connection *conn, +static int do_control_logfile(const void *ctx, struct connection *conn, char **vec, int num) { if (num != 1) @@ -162,7 +162,7 @@ static int quota_get(const void *ctx, struct connection *conn, return domain_get_quota(ctx, conn, atoi(vec[0])); } -static int do_control_quota(void *ctx, struct connection *conn, +static int do_control_quota(const void *ctx, struct connection *conn, char **vec, int num) { if (num == 0) @@ -174,7 +174,7 @@ static int do_control_quota(void *ctx, struct connection *conn, return quota_get(ctx, conn, vec, num); } -static int do_control_quota_s(void *ctx, struct connection *conn, +static int do_control_quota_s(const void *ctx, struct connection *conn, char **vec, int num) { if (num == 0) @@ -186,7 +186,7 @@ static int do_control_quota_s(void *ctx, struct connection *conn, return EINVAL; } -static int do_control_memreport(void *ctx, struct connection *conn, +static int do_control_memreport(const void *ctx, struct connection *conn, char **vec, int num) { FILE *fp; @@ -225,7 +225,7 @@ static int do_control_memreport(void *ctx, struct connection *conn, return 0; } -static int do_control_print(void *ctx, struct connection *conn, +static int do_control_print(const void *ctx, struct connection *conn, char **vec, int num) { if (num != 1) @@ -237,7 +237,7 @@ static int do_control_print(void *ctx, struct connection *conn, return 0; } -static int do_control_help(void *, struct connection *, char **, int); +static int do_control_help(const void *, struct connection *, char **, int); static struct cmd_s cmds[] = { { "check", do_control_check, "" }, @@ -250,7 +250,7 @@ static struct cmd_s cmds[] = { { "help", do_control_help, "" }, }; -static int do_control_help(void *ctx, struct connection *conn, +static int do_control_help(const void *ctx, struct connection *conn, char **vec, int num) { int cmd, len = 0; @@ -286,7 +286,8 @@ static int do_control_help(void *ctx, struct connection *conn, return 0; } -int do_control(struct connection *conn, struct buffered_data *in) +int do_control(const void *ctx, struct connection *conn, + struct buffered_data *in) { int num; int cmd; @@ -298,7 +299,7 @@ int do_control(struct connection *conn, struct buffered_data *in) num = xs_count_strings(in->buffer, in->used); if (num < 1) return EINVAL; - vec = talloc_array(in, char *, num); + vec = talloc_array(ctx, char *, num); if (!vec) return ENOMEM; if (get_strings(in, vec, num) != num) @@ -306,7 +307,7 @@ int do_control(struct connection *conn, struct buffered_data *in) for (cmd = 0; cmd < ARRAY_SIZE(cmds); cmd++) if (streq(vec[0], cmds[cmd].cmd)) - return cmds[cmd].func(in, conn, vec + 1, num - 1); + return cmds[cmd].func(ctx, conn, vec + 1, num - 1); return EINVAL; } diff --git a/tools/xenstore/xenstored_control.h b/tools/xenstore/xenstored_control.h index 207e0a6fa3..faa955968d 100644 --- a/tools/xenstore/xenstored_control.h +++ b/tools/xenstore/xenstored_control.h @@ -16,4 +16,5 @@ along with this program; If not, see . */ -int do_control(struct connection *conn, struct buffered_data *in); +int do_control(const void *ctx, struct connection *conn, + struct buffered_data *in); diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 2c0f8fd99b..d6bbb532fb 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1145,11 +1145,13 @@ static struct node *get_node_canonicalized(struct connection *conn, return get_node(conn, ctx, *canonical_name, perm); } -static int send_directory(struct connection *conn, struct buffered_data *in) +static int send_directory(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct node *node; - node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ); + node = get_node_canonicalized(conn, ctx, onearg(in), NULL, + XS_PERM_READ); if (!node) return errno; @@ -1158,7 +1160,7 @@ static int send_directory(struct connection *conn, struct buffered_data *in) return 0; } -static int send_directory_part(struct connection *conn, +static int send_directory_part(const void *ctx, struct connection *conn, struct buffered_data *in) { unsigned int off, len, maxlen, genlen; @@ -1170,7 +1172,8 @@ static int send_directory_part(struct connection *conn, return EINVAL; /* First arg is node name. */ - node = get_node_canonicalized(conn, in, in->buffer, NULL, XS_PERM_READ); + node = get_node_canonicalized(conn, ctx, in->buffer, NULL, + XS_PERM_READ); if (!node) return errno; @@ -1197,7 +1200,7 @@ static int send_directory_part(struct connection *conn, break; } - data = talloc_array(in, char, genlen + len + 1); + data = talloc_array(ctx, char, genlen + len + 1); if (!data) return ENOMEM; @@ -1213,11 +1216,13 @@ static int send_directory_part(struct connection *conn, return 0; } -static int do_read(struct connection *conn, struct buffered_data *in) +static int do_read(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct node *node; - node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ); + node = get_node_canonicalized(conn, ctx, onearg(in), NULL, + XS_PERM_READ); if (!node) return errno; @@ -1397,7 +1402,8 @@ err: } /* path, data... */ -static int do_write(struct connection *conn, struct buffered_data *in) +static int do_write(const void *ctx, struct connection *conn, + struct buffered_data *in) { unsigned int offset, datalen; struct node *node; @@ -1411,12 +1417,12 @@ static int do_write(struct connection *conn, struct buffered_data *in) offset = strlen(vec[0]) + 1; datalen = in->used - offset; - node = get_node_canonicalized(conn, in, vec[0], &name, XS_PERM_WRITE); + node = get_node_canonicalized(conn, ctx, vec[0], &name, XS_PERM_WRITE); if (!node) { /* No permissions, invalid input? */ if (errno != ENOENT) return errno; - node = create_node(conn, in, name, in->buffer + offset, + node = create_node(conn, ctx, name, in->buffer + offset, datalen); if (!node) return errno; @@ -1427,18 +1433,19 @@ static int do_write(struct connection *conn, struct buffered_data *in) return errno; } - fire_watches(conn, in, name, node, false, NULL); + fire_watches(conn, ctx, name, node, false, NULL); send_ack(conn, XS_WRITE); return 0; } -static int do_mkdir(struct connection *conn, struct buffered_data *in) +static int do_mkdir(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct node *node; char *name; - node = get_node_canonicalized(conn, in, onearg(in), &name, + node = get_node_canonicalized(conn, ctx, onearg(in), &name, XS_PERM_WRITE); /* If it already exists, fine. */ @@ -1446,10 +1453,10 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in) /* No permissions? */ if (errno != ENOENT) return errno; - node = create_node(conn, in, name, NULL, 0); + node = create_node(conn, ctx, name, NULL, 0); if (!node) return errno; - fire_watches(conn, in, name, node, false, NULL); + fire_watches(conn, ctx, name, node, false, NULL); } send_ack(conn, XS_MKDIR); @@ -1547,22 +1554,23 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node, } -static int do_rm(struct connection *conn, struct buffered_data *in) +static int do_rm(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct node *node; int ret; char *name; char *parentname; - node = get_node_canonicalized(conn, in, onearg(in), &name, + node = get_node_canonicalized(conn, ctx, onearg(in), &name, XS_PERM_WRITE); if (!node) { /* Didn't exist already? Fine, if parent exists. */ if (errno == ENOENT) { - parentname = get_parent(in, name); + parentname = get_parent(ctx, name); if (!parentname) return errno; - node = read_node(conn, in, parentname); + node = read_node(conn, ctx, parentname); if (node) { send_ack(conn, XS_RM); return 0; @@ -1577,7 +1585,7 @@ static int do_rm(struct connection *conn, struct buffered_data *in) if (streq(name, "/")) return EINVAL; - ret = _rm(conn, in, node, name); + ret = _rm(conn, ctx, node, name); if (ret) return ret; @@ -1587,13 +1595,15 @@ static int do_rm(struct connection *conn, struct buffered_data *in) } -static int do_get_perms(struct connection *conn, struct buffered_data *in) +static int do_get_perms(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct node *node; char *strings; unsigned int len; - node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ); + node = get_node_canonicalized(conn, ctx, onearg(in), NULL, + XS_PERM_READ); if (!node) return errno; @@ -1606,7 +1616,8 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in) return 0; } -static int do_set_perms(struct connection *conn, struct buffered_data *in) +static int do_set_perms(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct node_perms perms, old_perms; char *name, *permstr; @@ -1623,7 +1634,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in) permstr = in->buffer + strlen(in->buffer) + 1; - perms.p = talloc_array(in, struct xs_permissions, perms.num); + perms.p = talloc_array(ctx, struct xs_permissions, perms.num); if (!perms.p) return ENOMEM; if (!xs_strings_to_perms(perms.p, perms.num, permstr)) @@ -1638,7 +1649,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in) } /* We must own node to do this (tools can do this too). */ - node = get_node_canonicalized(conn, in, in->buffer, &name, + node = get_node_canonicalized(conn, ctx, in->buffer, &name, XS_PERM_WRITE | XS_PERM_OWNER); if (!node) return errno; @@ -1673,7 +1684,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in) return errno; } - fire_watches(conn, in, name, node, false, &old_perms); + fire_watches(conn, ctx, name, node, false, &old_perms); send_ack(conn, XS_SET_PERMS); return 0; @@ -1681,7 +1692,8 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in) static struct { const char *str; - int (*func)(struct connection *conn, struct buffered_data *in); + int (*func)(const void *ctx, struct connection *conn, + struct buffered_data *in); unsigned int flags; #define XS_FLAG_NOTID (1U << 0) /* Ignore transaction id. */ #define XS_FLAG_PRIV (1U << 1) /* Privileged domain only. */ @@ -1754,6 +1766,7 @@ static void process_message(struct connection *conn, struct buffered_data *in) struct transaction *trans; enum xsd_sockmsg_type type = in->hdr.msg.type; int ret; + void *ctx; if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) { eprintf("Client unknown operation %i", type); @@ -1774,10 +1787,17 @@ static void process_message(struct connection *conn, struct buffered_data *in) return; } + ctx = talloc_new(NULL); + if (!ctx) { + send_error(conn, ENOMEM); + return; + } + assert(conn->transaction == NULL); conn->transaction = trans; - ret = wire_funcs[type].func(conn, in); + ret = wire_funcs[type].func(ctx, conn, in); + talloc_free(ctx); if (ret) send_error(conn, ret); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 4b2da302c2..3e2f49985a 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -337,7 +337,7 @@ bool domain_can_write(struct connection *conn) return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE); } -static char *talloc_domain_path(void *context, unsigned int domid) +static char *talloc_domain_path(const void *context, unsigned int domid) { return talloc_asprintf(context, "/local/domain/%u", domid); } @@ -479,7 +479,8 @@ static void domain_conn_reset(struct domain *domain) } /* domid, mfn, evtchn, path */ -int do_introduce(struct connection *conn, struct buffered_data *in) +int do_introduce(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct domain *domain; char *vec[3]; @@ -558,7 +559,8 @@ static struct domain *find_connected_domain(unsigned int domid) return domain; } -int do_set_target(struct connection *conn, struct buffered_data *in) +int do_set_target(const void *ctx, struct connection *conn, + struct buffered_data *in) { char *vec[2]; unsigned int domid, tdomid; @@ -605,7 +607,8 @@ static struct domain *onearg_domain(struct connection *conn, } /* domid */ -int do_release(struct connection *conn, struct buffered_data *in) +int do_release(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct domain *domain; @@ -620,7 +623,8 @@ int do_release(struct connection *conn, struct buffered_data *in) return 0; } -int do_resume(struct connection *conn, struct buffered_data *in) +int do_resume(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct domain *domain; @@ -635,7 +639,8 @@ int do_resume(struct connection *conn, struct buffered_data *in) return 0; } -int do_get_domain_path(struct connection *conn, struct buffered_data *in) +int do_get_domain_path(const void *ctx, struct connection *conn, + struct buffered_data *in) { char *path; const char *domid_str = onearg(in); @@ -643,18 +648,17 @@ int do_get_domain_path(struct connection *conn, struct buffered_data *in) if (!domid_str) return EINVAL; - path = talloc_domain_path(conn, atoi(domid_str)); + path = talloc_domain_path(ctx, atoi(domid_str)); if (!path) return errno; send_reply(conn, XS_GET_DOMAIN_PATH, path, strlen(path) + 1); - talloc_free(path); - return 0; } -int do_is_domain_introduced(struct connection *conn, struct buffered_data *in) +int do_is_domain_introduced(const void *ctx, struct connection *conn, + struct buffered_data *in) { int result; unsigned int domid; @@ -675,7 +679,8 @@ int do_is_domain_introduced(struct connection *conn, struct buffered_data *in) } /* Allow guest to reset all watches */ -int do_reset_watches(struct connection *conn, struct buffered_data *in) +int do_reset_watches(const void *ctx, struct connection *conn, + struct buffered_data *in) { conn_delete_all_watches(conn); conn_delete_all_transactions(conn); diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index e013a9991c..732eb8fa75 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -22,25 +22,32 @@ void handle_event(void); /* domid, mfn, eventchn, path */ -int do_introduce(struct connection *conn, struct buffered_data *in); +int do_introduce(const void *ctx, struct connection *conn, + struct buffered_data *in); /* domid */ -int do_is_domain_introduced(struct connection *conn, struct buffered_data *in); +int do_is_domain_introduced(const void *ctx, struct connection *conn, + struct buffered_data *in); /* domid */ -int do_release(struct connection *conn, struct buffered_data *in); +int do_release(const void *ctx, struct connection *conn, + struct buffered_data *in); /* domid */ -int do_resume(struct connection *conn, struct buffered_data *in); +int do_resume(const void *ctx, struct connection *conn, + struct buffered_data *in); /* domid, target */ -int do_set_target(struct connection *conn, struct buffered_data *in); +int do_set_target(const void *ctx, struct connection *conn, + struct buffered_data *in); /* domid */ -int do_get_domain_path(struct connection *conn, struct buffered_data *in); +int do_get_domain_path(const void *ctx, struct connection *conn, + struct buffered_data *in); /* Allow guest to reset all watches */ -int do_reset_watches(struct connection *conn, struct buffered_data *in); +int do_reset_watches(const void *ctx, struct connection *conn, + struct buffered_data *in); void domain_init(void); diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index 6e29118c80..cd592845e7 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -487,7 +487,8 @@ struct transaction *transaction_lookup(struct connection *conn, uint32_t id) return ERR_PTR(-ENOENT); } -int do_transaction_start(struct connection *conn, struct buffered_data *in) +int do_transaction_start(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct transaction *trans, *exists; char id_str[20]; @@ -500,8 +501,8 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in) conn->transaction_started > quota_max_transaction) return ENOSPC; - /* Attach transaction to input for autofree until it's complete */ - trans = talloc_zero(in, struct transaction); + /* Attach transaction to ctx for autofree until it's complete */ + trans = talloc_zero(ctx, struct transaction); if (!trans) return ENOMEM; @@ -548,7 +549,8 @@ static int transaction_fix_domains(struct transaction *trans, bool update) return 0; } -int do_transaction_end(struct connection *conn, struct buffered_data *in) +int do_transaction_end(const void *ctx, struct connection *conn, + struct buffered_data *in) { const char *arg = onearg(in); struct transaction *trans; @@ -564,8 +566,8 @@ int do_transaction_end(struct connection *conn, struct buffered_data *in) list_del(&trans->list); conn->transaction_started--; - /* Attach transaction to in for auto-cleanup */ - talloc_steal(in, trans); + /* Attach transaction to ctx for auto-cleanup */ + talloc_steal(ctx, trans); if (streq(arg, "T")) { if (trans->fail) diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h index e3cbd6b230..39d7f81c51 100644 --- a/tools/xenstore/xenstored_transaction.h +++ b/tools/xenstore/xenstored_transaction.h @@ -29,8 +29,10 @@ struct transaction; extern uint64_t generation; -int do_transaction_start(struct connection *conn, struct buffered_data *node); -int do_transaction_end(struct connection *conn, struct buffered_data *in); +int do_transaction_start(const void *ctx, struct connection *conn, + struct buffered_data *node); +int do_transaction_end(const void *ctx, struct connection *conn, + struct buffered_data *in); struct transaction *transaction_lookup(struct connection *conn, uint32_t id); diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 19d0fb01b1..13627ce972 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -184,7 +184,7 @@ static int destroy_watch(void *_watch) return 0; } -int do_watch(struct connection *conn, struct buffered_data *in) +int do_watch(const void *ctx, struct connection *conn, struct buffered_data *in) { struct watch *watch; char *vec[2]; @@ -200,7 +200,7 @@ int do_watch(struct connection *conn, struct buffered_data *in) /* check if valid event */ } else { relative = !strstarts(vec[0], "/"); - vec[0] = canonicalize(conn, in, vec[0]); + vec[0] = canonicalize(conn, ctx, vec[0]); if (!vec[0]) return ENOMEM; if (!is_valid_nodename(vec[0])) @@ -250,7 +250,8 @@ int do_watch(struct connection *conn, struct buffered_data *in) return 0; } -int do_unwatch(struct connection *conn, struct buffered_data *in) +int do_unwatch(const void *ctx, struct connection *conn, + struct buffered_data *in) { struct watch *watch; char *node, *vec[2]; @@ -258,7 +259,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in) if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) return EINVAL; - node = canonicalize(conn, in, vec[0]); + node = canonicalize(conn, ctx, vec[0]); if (!node) return ENOMEM; list_for_each_entry(watch, &conn->watches, list) { diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h index 03094374f3..40455dff5d 100644 --- a/tools/xenstore/xenstored_watch.h +++ b/tools/xenstore/xenstored_watch.h @@ -21,8 +21,10 @@ #include "xenstored_core.h" -int do_watch(struct connection *conn, struct buffered_data *in); -int do_unwatch(struct connection *conn, struct buffered_data *in); +int do_watch(const void *ctx, struct connection *conn, + struct buffered_data *in); +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). */ void fire_watches(struct connection *conn, const void *tmp, const char *name,