xenbus.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 762 行 · 第 1/2 页
C
762 行
static char *errmsg(struct xsd_sockmsg *rep){ char *res; if (!rep) { char msg[] = "No reply"; size_t len = strlen(msg) + 1; return memcpy(malloc(len), msg, len); } if (rep->type != XS_ERROR) return NULL; res = malloc(rep->len + 1); memcpy(res, rep + 1, rep->len); res[rep->len] = 0; free(rep); return res;} /* 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)); DEBUG("Got a reply, type %d, id %d, len %d.\n", reply->type, reply->req_id, reply->len);}/* 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_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; rep = xenbus_msg_reply(XS_READ, 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_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; rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req)); msg = errmsg(rep); if (msg) return msg; 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;}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_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;}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;}#define PERM_MAX_SIZE 32char *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_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), "%u", xbt); free(rep); 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;}int xenbus_read_integer(char *path){ char *res, *buf; int t; res = xenbus_read(XBT_NIL, path, &buf); if (res) { printk("Failed to read %s.\n", path); free(res); return -1; } sscanf(buf, "%d", &t); free(buf); return t;}char* xenbus_printf(xenbus_transaction_t xbt, char* node, char* path, char* fmt, ...){#define BUFFER_SIZE 256 char fullpath[BUFFER_SIZE]; char val[BUFFER_SIZE]; va_list args; BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE); sprintf(fullpath,"%s/%s", node, path); va_start(args, fmt); vsprintf(val, fmt, args); va_end(args); return xenbus_write(xbt,fullpath,val);}static void do_ls_test(const char *pre){ char **dirs, *msg; int x; DEBUG("ls %s...\n", pre); msg = xenbus_ls(XBT_NIL, pre, &dirs); if (msg) { DEBUG("Error in xenbus ls: %s\n", msg); free(msg); return; } for (x = 0; dirs[x]; x++) { DEBUG("ls %s[%d] -> %s\n", pre, x, dirs[x]); free(dirs[x]); } free(dirs);}static void do_read_test(const char *path){ char *res, *msg; DEBUG("Read %s...\n", path); msg = xenbus_read(XBT_NIL, path, &res); if (msg) { DEBUG("Error in xenbus read: %s\n", msg); free(msg); return; } DEBUG("Read %s -> %s.\n", path, res); free(res);}static void do_write_test(const char *path, const char *val){ char *msg; DEBUG("Write %s to %s...\n", val, path); msg = xenbus_write(XBT_NIL, path, val); if (msg) { DEBUG("Result %s\n", msg); free(msg); } else { DEBUG("Success.\n"); }}static void do_rm_test(const char *path){ char *msg; DEBUG("rm %s...\n", path); msg = xenbus_rm(XBT_NIL, path); if (msg) { DEBUG("Result %s\n", msg); free(msg); } else { DEBUG("Success.\n"); }}/* Simple testing thing */void test_xenbus(void){ DEBUG("Doing xenbus test.\n"); xenbus_debug_msg("Testing xenbus...\n"); DEBUG("Doing ls test.\n"); do_ls_test("device"); do_ls_test("device/vif"); do_ls_test("device/vif/0"); DEBUG("Doing read test.\n"); do_read_test("device/vif/0/mac"); do_read_test("device/vif/0/backend"); DEBUG("Doing write test.\n"); do_write_test("device/vif/0/flibble", "flobble"); do_read_test("device/vif/0/flibble"); do_write_test("device/vif/0/flibble", "widget"); do_read_test("device/vif/0/flibble"); DEBUG("Doing rm test.\n"); do_rm_test("device/vif/0/flibble"); do_read_test("device/vif/0/flibble"); DEBUG("(Should have said ENOENT)\n");}/* * Local variables: * mode: C * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?