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)
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)
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)
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)
}
#ifdef __MINIOS__
-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)
{
if (num)
return 0;
}
#else
-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)
return 0;
}
-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;
}
#endif
-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)
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, "" },
{ "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;
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;
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)
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;
}
along with this program; If not, see <http://www.gnu.org/licenses/>.
*/
-int do_control(struct connection *conn, struct buffered_data *in);
+int do_control(const void *ctx, struct connection *conn,
+ struct buffered_data *in);
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;
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;
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;
break;
}
- data = talloc_array(in, char, genlen + len + 1);
+ data = talloc_array(ctx, char, genlen + len + 1);
if (!data)
return ENOMEM;
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;
}
/* 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;
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;
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. */
/* 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);
}
-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;
if (streq(name, "/"))
return EINVAL;
- ret = _rm(conn, in, node, name);
+ ret = _rm(conn, ctx, node, name);
if (ret)
return ret;
}
-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;
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;
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))
}
/* 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;
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;
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. */
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);
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);
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);
}
}
/* domid, gfn, 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];
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;
}
/* 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;
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;
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);
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;
}
/* 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);
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);
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];
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;
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;
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)
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);
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];
/* 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]))
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];
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) {
#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,