char* xenbus_unwatch_path_token( xenbus_transaction_t xbt, const char *path, const char *token) { struct xsd_sockmsg *rep; struct write_req req[] = { {path, strlen(path) + 1}, {token, strlen(token) + 1}, }; struct watch *watch, **prev; char *msg; rep = xenbus_msg_reply(XS_UNWATCH, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) return msg; free(rep); for (prev = &watches, watch = *prev; watch; prev = &watch->next, watch = *prev) if (!strcmp(watch->token, token)) { free(watch->token); *prev = watch->next; free(watch); break; } return NULL; }
char * xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry) { struct xsd_sockmsg *rep; struct write_req req; char *err; *retry = 0; req.data = abort ? "F" : "T"; req.len = 2; rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1); err = errmsg(rep); if (err) { if (!strcmp(err, "EAGAIN")) { *retry = 1; free(err); return NULL; } else { return err; } } free(rep); return NULL; }
char* xenbus_watch_path_token( xenbus_transaction_t xbt, const char *path, const char *token, xenbus_event_queue *events) { struct xsd_sockmsg *rep; struct write_req req[] = { {path, strlen(path) + 1}, {token, strlen(token) + 1}, }; struct watch *watch = malloc(sizeof(*watch)); char *msg; if (!events) events = &xenbus_events; watch->token = strdup(token); watch->events = events; watch->next = watches; watches = watch; rep = xenbus_msg_reply(XS_WATCH, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) return msg; free(rep); return NULL; }
/* List the contents of a directory. Returns a malloc()ed array of pointers to malloc()ed strings. The array is NULL terminated. May block. */ char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents) { struct xsd_sockmsg *reply, *repmsg; struct write_req req[] = { { pre, strlen(pre)+1 } }; int nr_elems, x, i; char **res, *msg; repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req)); msg = errmsg(repmsg); if (msg) { *contents = NULL; return msg; } reply = repmsg + 1; for (x = nr_elems = 0; x < repmsg->len; x++) nr_elems += (((char *)reply)[x] == 0); res = malloc(sizeof(res[0]) * (nr_elems + 1)); for (x = i = 0; i < nr_elems; i++) { int l = strlen((char *)reply + x); res[i] = malloc(l + 1); memcpy(res[i], (char *)reply + x, l + 1); x += l + 1; } res[i] = NULL; free(repmsg); *contents = res; return NULL; }
char *xenbus_rm(xenbus_transaction_t xbt, const char *path) { struct write_req req[] = { {path, strlen(path) + 1} }; struct xsd_sockmsg *rep; char *msg; rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) return msg; free(rep); return NULL; }
/* Send a debug message to xenbus. Can block. */ static void xenbus_debug_msg(const char *msg) { int len = strlen(msg); struct write_req req[] = { { "print", sizeof("print") }, { msg, len }, { "", 1 }}; struct xsd_sockmsg *reply; reply = xenbus_msg_reply(XS_DEBUG, 0, req, ARRAY_SIZE(req)); printk("Got a reply, type %d, id %d, len %d.\n", reply->type, reply->req_id, reply->len); }
char *xenbus_transaction_start(xenbus_transaction_t *xbt) { /* xenstored becomes angry if you send a length 0 message, so just shove a nul terminator on the end */ struct write_req req = { "", 1}; struct xsd_sockmsg *rep; char *err; rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1); err = errmsg(rep); if (err) return err; sscanf((char *)(rep + 1), "%lu", xbt); free(rep); return NULL; }
char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value) { struct write_req req[] = { {path, strlen(path) + 1}, {value, strlen(value)}, }; struct xsd_sockmsg *rep; char *msg; DEBUG("xenbus_write: called\n"); rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) return msg; vPortFree(rep); return NULL; }
char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm) { char value[PERM_MAX_SIZE]; struct write_req req[] = { {path, strlen(path) + 1}, {value, 0}, }; struct xsd_sockmsg *rep; char *msg; snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom); req[1].len = strlen(value) + 1; rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) return msg; free(rep); return NULL; }
char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value) { struct write_req req[] = { {path, strlen(path) + 1} }; struct xsd_sockmsg *rep; char *res, *msg; rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) { *value = NULL; return msg; } res = malloc(rep->len + 1); memcpy(res, rep + 1, rep->len); res[rep->len] = 0; free(rep); *value = res; return NULL; }
char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value) { struct write_req req[] = { {path, strlen(path) + 1} }; struct xsd_sockmsg *rep; char *res, *msg; DEBUG("xenbus_read: called\n"); rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) { *value = NULL; return msg; } res = pvPortMalloc(rep->len + 1); memcpy(res, rep + 1, rep->len); res[rep->len] = 0; vPortFree(rep); *value = res; return NULL; }