int pcifront_physical_to_virtual (struct pcifront_dev *dev, unsigned int *dom, unsigned int *bus, unsigned int *slot, unsigned long *fun) { /* FIXME: the buffer sizing is a little lazy here. 10 extra bytes should be enough to hold the paths we need to construct, even if the number of devices is large */ char path[strlen(dev->backend) + strlen("/num_devs") + 10 + 1]; int i, n; char *s, *msg = NULL; unsigned int dom1, bus1, slot1, fun1; if (!dev) dev = pcidev; snprintf(path, sizeof(path), "%s/num_devs", dev->backend); n = xenbus_read_integer(path); for (i = 0; i < n; i++) { snprintf(path, sizeof(path), "%s/dev-%d", dev->backend, i); msg = xenbus_read(XBT_NIL, path, &s); if (msg) { printk("Error %s when reading the PCI root name at %s\n", msg, path); free(msg); continue; } if (sscanf(s, "%x:%x:%x.%x", &dom1, &bus1, &slot1, &fun1) != 4) { printk("\"%s\" does not look like a PCI device address\n", s); free(s); continue; } free(s); if (dom1 == *dom && bus1 == *bus && slot1 == *slot && fun1 == *fun) { snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i); msg = xenbus_read(XBT_NIL, path, &s); if (msg) { printk("Error %s when reading the PCI root name at %s\n", msg, path); continue; } if (sscanf(s, "%x:%x:%x.%x", dom, bus, slot, fun) != 4) { printk("\"%s\" does not look like a PCI device address\n", s); free(s); continue; } free(s); return 0; } } return -1; }
static void xen_net_read_rate(struct xenbus_device *dev, unsigned long *bytes, unsigned long *usec) { char *s, *e; unsigned long b, u; char *ratestr; /* Default to unlimited bandwidth. */ *bytes = ~0UL; *usec = 0; ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL); if (IS_ERR(ratestr)) return; s = ratestr; b = simple_strtoul(s, &e, 10); if ((s == e) || (*e != ',')) goto fail; s = e + 1; u = simple_strtoul(s, &e, 10); if ((s == e) || (*e != '\0')) goto fail; *bytes = b; *usec = u; kfree(ratestr); return; fail: pr_warn("Failed to parse network rate limit. Traffic unlimited.\n"); kfree(ratestr); }
/* Write a grant ref and ec port to xenstore in a transaction for whatever * your pThing is. Also some non-transaction read/write stuff. */ static NTSTATUS GrantAndEventChannelInATransaction(CHAR *pFrontendPath, struct THING *pThing) { NTSTATUS Status; CHAR *pMyData; xenbus_transaction_t Xbt; do { xenbus_transaction_start(&Xbt); xenbus_write_grant_ref(Xbt, pFrontendPath, "ring-ref", pThing->RingGrantRef); xenbus_write_evtchn_port(Xbt, pFrontendPath, "event-channel", pThing->EvtchnPort); Status = xenbus_transaction_end(Xbt, 0); } while (Status == STATUS_RETRY); if (Status != STATUS_SUCCESS) { DbgPrint("Failed to end transaction, 0x%08x.\n", Status); /* Handle failure */ } /* A write and read w/o a transaction */ xenbus_write(XBT_NIL, "drivers/mydriver", "1.2.3.4"); Status = xenbus_read(XBT_NIL, "drivers/mydriver/mydata", &pMyData); if (NT_SUCCESS(Status)) { DbgPrint("Read MyData: %s\n", pMyData); XmFreeMemory(pMyData); } /* ... */ }
static void shutdown_thread(void *p) { const char *path = "control/shutdown"; const char *token = path; xenbus_event_queue events = NULL; char *shutdown = NULL, *err; unsigned int shutdown_reason; xenbus_watch_path_token(XBT_NIL, path, token, &events); while ((err = xenbus_read(XBT_NIL, path, &shutdown)) != NULL || !strcmp(shutdown, "")) { free(err); free(shutdown); shutdown = NULL; xenbus_wait_for_watch(&events); } err = xenbus_unwatch_path_token(XBT_NIL, path, token); free(err); err = xenbus_write(XBT_NIL, path, ""); free(err); printk("Shutting down (%s)\n", shutdown); if (!strcmp(shutdown, "poweroff")) shutdown_reason = SHUTDOWN_poweroff; else if (!strcmp(shutdown, "reboot")) shutdown_reason = SHUTDOWN_reboot; else /* Unknown */ shutdown_reason = SHUTDOWN_crash; app_shutdown(shutdown_reason); free(shutdown); }
int fork_xenbus(void) { char path[50]; char *flag = "fork", *err; xenbus_event_queue events = NULL; sprintf(path,"fork/requests"); xenbus_watch_path_token(XBT_NIL, path, path, &events); xenbus_write(XBT_NIL, path, "fork"); while(1){ xenbus_wait_for_watch(&events); if ((err = xenbus_read(XBT_NIL, path, &flag))) { free(err); continue; } if (!strcmp(flag, "") || !strcmp(flag, "fork")) { free(flag); flag = NULL; continue; }else if (!strcmp(flag, "0")) return 0; else if (!strcmp(flag, "1")) return 1; err = xenbus_write(XBT_NIL, path, ""); free(err); free(flag); flag = NULL; } return -1; }
/** * Handle the creation of the hotplug script environment. We add the script * and vif variables to the environment, for the benefit of the vif-* hotplug * scripts. */ static int netback_uevent(struct xenbus_device *xdev, struct kobj_uevent_env *env) { struct backend_info *be = dev_get_drvdata(&xdev->dev); char *val; DPRINTK("netback_uevent"); val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); if (IS_ERR(val)) { int err = PTR_ERR(val); xenbus_dev_fatal(xdev, err, "reading script"); return err; } else { if (add_uevent_var(env, "script=%s", val)) { kfree(val); return -ENOMEM; } kfree(val); } if (be && be->netif && add_uevent_var(env, "vif=%s", be->netif->dev->name)) return -ENOMEM; return 0; }
/** * Handle the creation of the hotplug script environment. We add the script * and vif variables to the environment, for the benefit of the vif-* hotplug * scripts. */ static int netback_uevent(struct xenbus_device *xdev, char **envp, int num_envp, char *buffer, int buffer_size) { struct backend_info *be = xdev->dev.driver_data; netif_t *netif = be->netif; int i = 0, length = 0; char *val; DPRINTK("netback_uevent"); val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); if (IS_ERR(val)) { int err = PTR_ERR(val); xenbus_dev_fatal(xdev, err, "reading script"); return err; } else { add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "script=%s", val); kfree(val); } add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "vif=%s", netif->dev->name); envp[i] = NULL; return 0; }
void pcifront_scan(struct pcifront_dev *dev, void (*func)(unsigned int domain, unsigned int bus, unsigned slot, unsigned int fun)) { char path[strlen(dev->backend) + 1 + 5 + 10 + 1]; int i, n; char *s, *msg; unsigned int domain, bus, slot, fun; snprintf(path, sizeof(path), "%s/num_devs", dev->backend); n = xenbus_read_integer(path); for (i = 0; i < n; i++) { snprintf(path, sizeof(path), "%s/vdev-%d", dev->backend, i); msg = xenbus_read(XBT_NIL, path, &s); if (msg) { printk("Error %s when reading the PCI root name at %s\n", path); continue; } if (sscanf(s, "%x:%x:%x.%x", &domain, &bus, &slot, &fun) != 4) { printk("\"%s\" does not look like a PCI device address\n", s); free(s); continue; } free(s); func(domain, bus, slot, fun); } }
static PCHAR XenLowerReadXenstoreValue( PCHAR Path, PCHAR Value) { ULONG plen, vlen; PCHAR path; PCHAR res = NULL; NTSTATUS status; plen = (ULONG)strlen(Path); vlen = (ULONG)strlen(Value); path = (PCHAR)XmAllocateMemory(plen + vlen + 2); if (path == NULL) { return NULL; } memcpy(path, Path, plen); path[plen] = '/'; memcpy(path + plen + 1, Value, vlen + 1); status = xenbus_read(XBT_NIL, path, &res); XmFreeMemory(path); if (!NT_SUCCESS(status)) { return NULL; } return res; }
int xenbus_read_uuid(const char* path, unsigned char uuid[16]) { char * res, *buf; res = xenbus_read(XBT_NIL, path, &buf); if(res) { printk("Failed to read %s.\n", path); free(res); return 0; } if(strlen(buf) != ((2*16)+4) /* 16 hex bytes and 4 hyphens */ || sscanf(buf, "%2hhx%2hhx%2hhx%2hhx-" "%2hhx%2hhx-" "%2hhx%2hhx-" "%2hhx%2hhx-" "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", uuid, uuid + 1, uuid + 2, uuid + 3, uuid + 4, uuid + 5, uuid + 6, uuid + 7, uuid + 8, uuid + 9, uuid + 10, uuid + 11, uuid + 12, uuid + 13, uuid + 14, uuid + 15) != 16) { printk("Xenbus path %s value %s is not a uuid!\n", path, buf); free(buf); return 0; } free(buf); return 1; }
/*ARGSUSED*/ static void xen_shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *str; xenbus_transaction_t xbt; int err, shutdown_code = SHUTDOWN_INVALID; unsigned int slen; again: err = xenbus_transaction_start(&xbt); if (err) return; if (xenbus_read(xbt, "control", "shutdown", (void *)&str, &slen)) { (void) xenbus_transaction_end(xbt, 1); return; } SUSPEND_DEBUG("%d: xen_shutdown_handler: \"%s\"\n", CPU->cpu_id, str); /* * If this is a watch fired from our write below, check out early to * avoid an infinite loop. */ if (strcmp(str, "") == 0) { (void) xenbus_transaction_end(xbt, 0); kmem_free(str, slen); return; } else if (strcmp(str, "poweroff") == 0) { shutdown_code = SHUTDOWN_POWEROFF; } else if (strcmp(str, "reboot") == 0) { shutdown_code = SHUTDOWN_REBOOT; } else if (strcmp(str, "suspend") == 0) { shutdown_code = SHUTDOWN_SUSPEND; } else if (strcmp(str, "halt") == 0) { shutdown_code = SHUTDOWN_HALT; } else { printf("Ignoring shutdown request: %s\n", str); } /* * XXPV Should we check the value of xenbus_write() too, or are all * errors automatically folded into xenbus_transaction_end() ?? */ (void) xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == EAGAIN) { SUSPEND_DEBUG("%d: trying again\n", CPU->cpu_id); kmem_free(str, slen); goto again; } kmem_free(str, slen); if (shutdown_code != SHUTDOWN_INVALID) { (void) taskq_dispatch(xen_shutdown_tq, xen_shutdown, (void *)(intptr_t)shutdown_code, 0); } }
static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *str; struct xenbus_transaction xbt; int err; static struct shutdown_handler handlers[] = { { "poweroff", do_poweroff }, { "halt", do_poweroff }, { "reboot", do_reboot }, #ifdef CONFIG_HIBERNATE_CALLBACKS { "suspend", do_suspend }, #endif {NULL, NULL}, }; static struct shutdown_handler *handler; if (shutting_down != SHUTDOWN_INVALID) return; again: err = xenbus_transaction_start(&xbt); if (err) return; str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); /* Ignore read errors and empty reads. */ if (XENBUS_IS_ERR_READ(str)) { xenbus_transaction_end(xbt, 1); return; } for (handler = &handlers[0]; handler->command; handler++) { if (strcmp(str, handler->command) == 0) break; } /* Only acknowledge commands which we are prepared to handle. */ if (handler->cb) xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { kfree(str); goto again; } if (handler->cb) { handler->cb(); } else { pr_info("Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; } kfree(str); }
domid_t xenbus_get_self_id(void) { char *dom_id; domid_t ret; BUG_ON(xenbus_read(XBT_NIL, "domid", &dom_id)); sscanf(dom_id, "%u", (unsigned int*)&ret); return ret; }
static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer) { char *vm, *val; int ret; if (!is_xenstored_ready()) return -EBUSY; vm = xenbus_read(XBT_NIL, "vm", "", NULL); if (IS_ERR(vm)) return PTR_ERR(vm); val = xenbus_read(XBT_NIL, vm, "uuid", NULL); kfree(vm); if (IS_ERR(val)) return PTR_ERR(val); ret = sprintf(buffer, "%s\n", val); kfree(val); return ret; }
static int read_nicname(struct xenbus_device *dev, struct netback_accel *bend) { int len; /* nic name used to select interface used for acceleration */ bend->nicname = xenbus_read(XBT_NIL, dev->nodename, "accel", &len); if (IS_ERR(bend->nicname)) return PTR_ERR(bend->nicname); return 0; }
int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) { struct xenbus_device *dev = be->dev; struct xen_blkif *blkif = be->blkif; char *type; int err; int state = 0; type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL); if (!IS_ERR(type)) { if (strncmp(type, "file", 4) == 0) { state = 1; blkif->blk_backend_type = BLKIF_BACKEND_FILE; } if (strncmp(type, "phy", 3) == 0) { struct block_device *bdev = be->blkif->vbd.bdev; struct request_queue *q = bdev_get_queue(bdev); if (blk_queue_discard(q)) { err = xenbus_printf(xbt, dev->nodename, "discard-granularity", "%u", q->limits.discard_granularity); if (err) { xenbus_dev_fatal(dev, err, "writing discard-granularity"); goto kfree; } err = xenbus_printf(xbt, dev->nodename, "discard-alignment", "%u", q->limits.discard_alignment); if (err) { xenbus_dev_fatal(dev, err, "writing discard-alignment"); goto kfree; } state = 1; blkif->blk_backend_type = BLKIF_BACKEND_PHY; } } } else { err = PTR_ERR(type); xenbus_dev_fatal(dev, err, "reading type"); goto out; } err = xenbus_printf(xbt, dev->nodename, "feature-discard", "%d", state); if (err) xenbus_dev_fatal(dev, err, "writing feature-discard"); kfree: kfree(type); out: return err; }
static void do_read_test(const char *path) { char *res, *msg; printk("Read %s...\n", path); msg = xenbus_read(XBT_NIL, path, &res); if (msg) { printk("Error in xenbus read: %s\n", msg); free(msg); return; } printk("Read %s -> %s.\n", path, res); free(res); }
static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { extern void ctrl_alt_del(void); char *str; struct xenbus_transaction xbt; int err, new_state = SHUTDOWN_INVALID; if ((shutting_down != SHUTDOWN_INVALID) && (shutting_down != SHUTDOWN_RESUMING)) return; again: err = xenbus_transaction_start(&xbt); if (err) return; str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); /* Ignore read errors and empty reads. */ if (XENBUS_IS_ERR_READ(str)) { xenbus_transaction_end(xbt, 1); return; } /*将其清空后,如果热迁移时suspend失败则会导致迁移挂死,去掉后suspend失败后则会迁移超时*/ //xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { kfree(str); goto again; } printk(KERN_WARNING "%s(%d): receive shutdown request %s\n", __FUNCTION__, __LINE__, str); if (strcmp(str, "poweroff") == 0) new_state = SHUTDOWN_POWEROFF; else if (strcmp(str, "reboot") == 0) ctrl_alt_del(); else if (strcmp(str, "suspend") == 0) new_state = SHUTDOWN_SUSPEND; else if (strcmp(str, "halt") == 0) new_state = SHUTDOWN_HALT; else printk("Ignoring shutdown request: %s\n", str); switch_shutdown_state(new_state); kfree(str); }
/* mlr-begin : changed, add para unsigned long *initial */ static void xen_net_read_rate(struct xenbus_device *dev, unsigned long *bytes, unsigned long *usec, unsigned long *initial) /* mlr-end */ { char *s, *e; unsigned long b, u; char *ratestr; /* Default to unlimited bandwidth. */ *bytes = ~0UL; *usec = 0; ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL); if (IS_ERR(ratestr)) return; s = ratestr; b = simple_strtoul(s, &e, 10); if ((s == e) || (*e != ',')) goto fail; s = e + 1; u = simple_strtoul(s, &e, 10); if ((s == e) || (*e != '\0')) goto fail; /* mlr-begin : check for average */ /** if (xen_net_read_average) { int dn = domain_number(); xen_read_bandwidth(dev); *bytes = (long) total_credit/dn; } else */ *bytes = b; *initial = *bytes; /* mlr-end */ /* original: *bytes = b; */ *usec = u; kfree(ratestr); return; fail: pr_warn("Failed to parse network rate limit. Traffic unlimited.\n"); kfree(ratestr); }
int xenbus_read_integer(const char *path) { char *res, *buf; int t; res = xenbus_read(XBT_NIL, path, &buf); if (res) { vPortFree(res); return -1; } sscanf(buf, "%d", &t); vPortFree(buf); return t; }
domid_t xenbus_get_self_id(void) { char *dom_id, *msg; domid_t ret; msg = xenbus_read(XBT_NIL, "domid", &dom_id); if (msg) { printk("BUG: xenbus_read of domid failed with '%s'\n", msg); BUG(); } sscanf(dom_id, "%u", (unsigned int *) &ret); return ret; }
int xenbus_read_integer(const 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; }
static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { extern void ctrl_alt_del(void); char *str; struct xenbus_transaction xbt; int err; if (shutting_down != SHUTDOWN_INVALID) return; again: err = xenbus_transaction_start(&xbt); if (err) return; str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); /* Ignore read errors and empty reads. */ if (XENBUS_IS_ERR_READ(str)) { xenbus_transaction_end(xbt, 1); return; } xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { kfree(str); goto again; } if (strcmp(str, "poweroff") == 0) shutting_down = SHUTDOWN_POWEROFF; else if (strcmp(str, "reboot") == 0) ctrl_alt_del(); else if (strcmp(str, "suspend") == 0) shutting_down = SHUTDOWN_SUSPEND; else if (strcmp(str, "halt") == 0) shutting_down = SHUTDOWN_HALT; else { printk("Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; } if (shutting_down != SHUTDOWN_INVALID) schedule_work(&shutdown_work); kfree(str); }
static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *str; struct xenbus_transaction xbt; int err; if (shutting_down != SHUTDOWN_INVALID) return; again: err = xenbus_transaction_start(&xbt); if (err) return; str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); /* Ignore read errors and empty reads. */ if (XENBUS_IS_ERR_READ(str)) { xenbus_transaction_end(xbt, 1); return; } xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { kfree(str); goto again; } if (strcmp(str, "poweroff") == 0 || strcmp(str, "halt") == 0) { shutting_down = SHUTDOWN_POWEROFF; orderly_poweroff(false); } else if (strcmp(str, "reboot") == 0) { shutting_down = SHUTDOWN_POWEROFF; /* ? */ ctrl_alt_del(); #ifdef CONFIG_PM_SLEEP } else if (strcmp(str, "suspend") == 0) { do_suspend(); #endif } else { printk(KERN_INFO "Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; } kfree(str); }
static void shutdown_handler(struct xenbus_watch *watch, const char *path, const char *token) { char *str; struct xenbus_transaction xbt; int err; int idx; if (shutting_down != SHUTDOWN_INVALID) return; again: err = xenbus_transaction_start(&xbt); if (err) return; str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); /* Ignore read errors and empty reads. */ if (XENBUS_IS_ERR_READ(str)) { xenbus_transaction_end(xbt, 1); return; } for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) { if (strcmp(str, shutdown_handlers[idx].command) == 0) break; } /* Only acknowledge commands which we are prepared to handle. */ if (idx < ARRAY_SIZE(shutdown_handlers)) xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { kfree(str); goto again; } if (idx < ARRAY_SIZE(shutdown_handlers)) { shutdown_handlers[idx].cb(); } else { pr_info("Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; } kfree(str); }
static char * get_config(char *cmdline) { xenbus_transaction_t txn; char *cfg; int retry; cfg = rumprun_config_path(cmdline); if (cfg != NULL) return cfg; if (xenbus_transaction_start(&txn)) return jsonordie(); if (xenbus_read(txn, "rumprun/cfg", &cfg) != NULL) cfg = jsonordie(); xenbus_transaction_end(txn, 0, &retry); return cfg; }
char* xenbus_wait_for_value(const char* path, const char* value, xenbus_event_queue *queue) { if (!queue) queue = &xenbus_events; for(;;) { char *res, *msg; int r; msg = xenbus_read(XBT_NIL, path, &res); if(msg) return msg; r = strcmp(value,res); free(res); if(r==0) break; else xenbus_wait_for_watch(queue); } return NULL; }
static void hotplug_status_changed(struct xenbus_watch *watch, const char **vec, unsigned int vec_size) { struct backend_info *be = container_of(watch, struct backend_info, hotplug_status_watch); char *str; unsigned int len; str = xenbus_read(XBT_NIL, be->dev->nodename, "hotplug-status", &len); if (IS_ERR(str)) return; if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) { xenbus_switch_state(be->dev, XenbusStateConnected); /* Not interested in this watch anymore. */ unregister_hotplug_status_watch(be); } kfree(str); }
static int blkback_name(struct xen_blkif *blkif, char *buf) { char *devpath, *devname; struct xenbus_device *dev = blkif->be->dev; devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL); if (IS_ERR(devpath)) return PTR_ERR(devpath); devname = strstr(devpath, "/dev/"); if (devname != NULL) devname += strlen("/dev/"); else devname = devpath; snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname); kfree(devpath); return 0; }
char* xenbus_wait_for_value(const char* path, const char* value, struct xenbus_event_queue *queue) { if (!queue) queue = &xenbus_default_watch_queue; for(;;) { char *res, *msg; int r; msg = xenbus_read(XBT_NIL, path, &res); if(msg) return msg; r = bmk_strcmp(value,res); bmk_memfree(res, BMK_MEMWHO_WIREDBMK); if(r==0) break; else xenbus_wait_for_watch(queue); } return NULL; }