aboutsummaryrefslogtreecommitdiffstats
path: root/tools/blktap/lib/xenbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/blktap/lib/xenbus.c')
-rw-r--r--tools/blktap/lib/xenbus.c179
1 files changed, 113 insertions, 66 deletions
diff --git a/tools/blktap/lib/xenbus.c b/tools/blktap/lib/xenbus.c
index 91cdd00536..d50e492784 100644
--- a/tools/blktap/lib/xenbus.c
+++ b/tools/blktap/lib/xenbus.c
@@ -166,62 +166,60 @@ static void ueblktap_setup(struct xs_handle *h, char *bepath)
goto fail;
}
- deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
- if (!deverr) {
- DPRINTF("pdev set to %ld\n",pdev);
- if (be->pdev && be->pdev != pdev) {
- DPRINTF("changing physical-device not supported");
- goto fail;
- }
- be->pdev = pdev;
- }
-
- /*Check to see if device is to be opened read-only*/
- asprintf(&path, "%s/%s", bepath, "read-only");
- if (xs_exists(h, path))
- be->readonly = 1;
-
- if (be->blkif == NULL) {
-
- /* Front end dir is a number, which is used as the handle. */
- p = strrchr(be->frontpath, '/') + 1;
- handle = strtoul(p, NULL, 0);
-
- be->blkif = alloc_blkif(be->frontend_id);
-
- if (be->blkif == NULL)
- goto fail;
+ deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
+ if (!deverr) {
+ DPRINTF("pdev set to %ld\n",pdev);
+ if (be->pdev && be->pdev != pdev) {
+ DPRINTF("changing physical-device not supported");
+ goto fail;
+ }
+ be->pdev = pdev;
+ }
+
+ /* Check to see if device is to be opened read-only. */
+ asprintf(&path, "%s/%s", bepath, "read-only");
+ if (xs_exists(h, path))
+ be->readonly = 1;
+
+ if (be->blkif == NULL) {
+ /* Front end dir is a number, which is used as the handle. */
+ p = strrchr(be->frontpath, '/') + 1;
+ handle = strtoul(p, NULL, 0);
+
+ be->blkif = alloc_blkif(be->frontend_id);
+ if (be->blkif == NULL)
+ goto fail;
be->blkif->be_id = get_be_id(bepath);
- /*Insert device specific info*/
- blk = malloc(sizeof(blkif_info_t));
+ /* Insert device specific info, */
+ blk = malloc(sizeof(blkif_info_t));
if (!blk) {
DPRINTF("Out of memory - blkif_info_t\n");
goto fail;
}
- er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
- if (er)
- goto fail;
- be->blkif->info = blk;
+ er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
+ if (er)
+ goto fail;
+ be->blkif->info = blk;
- if (deverr) {
- /*Dev number was not available, try to set manually*/
- pdev = convert_dev_name_to_num(blk->params);
- be->pdev = pdev;
- }
-
- er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
+ if (deverr) {
+ /*Dev number was not available, try to set manually*/
+ pdev = convert_dev_name_to_num(blk->params);
+ be->pdev = pdev;
+ }
- if (er != 0) {
- DPRINTF("Unable to open device %s\n",blk->params);
+ er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
+ if (er != 0) {
+ DPRINTF("Unable to open device %s\n",blk->params);
goto fail;
}
- DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
- }
+ DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
+ }
+
/* Supply the information about the device to xenstore */
- er = xs_printf(h, be->backpath, "sectors", "%lu",
+ er = xs_printf(h, be->backpath, "sectors", "%llu",
be->blkif->ops->get_size(be->blkif));
if (er == 0) {
@@ -283,10 +281,10 @@ static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w,
*asserts that xenstore structure is always 7 levels deep
*e.g. /local/domain/0/backend/vbd/1/2049
*/
- len = strsep_len(bepath, '/', 7);
- if (len < 0)
- goto free_be;
- bepath[len] = '\0';
+ len = strsep_len(bepath, '/', 7);
+ if (len < 0)
+ goto free_be;
+ bepath[len] = '\0';
be = malloc(sizeof(*be));
if (!be) {
@@ -318,22 +316,21 @@ static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w,
if ( (be != NULL) && (be->blkif != NULL) )
backend_remove(h, be);
else goto free_be;
- if (bepath)
+ if (bepath)
free(bepath);
return;
}
- /* Are we already tracking this device? */
- if (be_exists_be(bepath)) {
+ /* Are we already tracking this device? */
+ if (be_exists_be(bepath))
goto free_be;
- }
be->backpath = bepath;
- be->frontpath = frontend;
+ be->frontpath = frontend;
- list_add(&be->list, &belist);
+ list_add(&be->list, &belist);
- DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
+ DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
DPRINTF("\tFRONTEND (%s),(%ld)\n", frontend,be->frontend_id);
ueblktap_setup(h, bepath);
@@ -342,11 +339,10 @@ static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w,
free_be:
if (frontend)
free(frontend);
- if (bepath)
+ if (bepath)
free(bepath);
if (be)
free(be);
- return;
}
/**
@@ -356,16 +352,10 @@ static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w,
*are created, we initalise the state and attach a disk.
*/
-int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
+int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid)
{
- char *domid, *path;
+ char *path;
struct xenbus_watch *vbd_watch;
- int er;
-
- domid = get_dom_domid(h, domname);
-
- DPRINTF("%s: %s\n",
- domname, (domid != NULL) ? domid : "[ not found! ]");
asprintf(&path, "/local/domain/%s/backend/tap", domid);
if (path == NULL)
@@ -378,10 +368,67 @@ int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
}
vbd_watch->node = path;
vbd_watch->callback = ueblktap_probe;
- er = register_xenbus_watch(h, vbd_watch);
- if (er == 0) {
+ if (register_xenbus_watch(h, vbd_watch) != 0) {
DPRINTF("ERROR: adding vbd probe watch %s\n", path);
return -EINVAL;
}
return 0;
}
+
+/* Asynch callback to check for /local/domain/<DOMID>/name */
+void check_dom(struct xs_handle *h, struct xenbus_watch *w,
+ const char *bepath_im)
+{
+ char *domid;
+
+ domid = get_dom_domid(h);
+ if (domid == NULL)
+ return;
+
+ add_blockdevice_probe_watch(h, domid);
+ free(domid);
+ unregister_xenbus_watch(h, w);
+}
+
+/* We must wait for xend to register /local/domain/<DOMID> */
+int watch_for_domid(struct xs_handle *h)
+{
+ struct xenbus_watch *domid_watch;
+ char *path = NULL;
+
+ asprintf(&path, "/local/domain");
+ if (path == NULL)
+ return -ENOMEM;
+
+ domid_watch = malloc(sizeof(struct xenbus_watch));
+ if (domid_watch == NULL) {
+ DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path);
+ return -EINVAL;
+ }
+
+ domid_watch->node = path;
+ domid_watch->callback = check_dom;
+
+ if (register_xenbus_watch(h, domid_watch) != 0) {
+ DPRINTF("ERROR: adding vbd probe watch %s\n", path);
+ return -EINVAL;
+ }
+
+ DPRINTF("Set async watch for /local/domain\n");
+
+ return 0;
+}
+
+int setup_probe_watch(struct xs_handle *h)
+{
+ char *domid;
+ int ret;
+
+ domid = get_dom_domid(h);
+ if (domid == NULL)
+ return watch_for_domid(h);
+
+ ret = add_blockdevice_probe_watch(h, domid);
+ free(domid);
+ return ret;
+}