Example #1
0
char *
tapback_device_read(const vbd_t * const device, xs_transaction_t xst,
        const char * const path)
{
    ASSERT(device);
    ASSERT(path);

    return tapback_xs_read(device->backend->xs, xst, "%s/%s/%s",
            device->backend->path, device->name, path);
}
Example #2
0
char *
tapback_device_read_otherend(vbd_t * const device, xs_transaction_t xst,
        const char * const path)
{
    ASSERT(device);
    ASSERT(path);
    ASSERT(device->frontend_path);

    return tapback_xs_read(device->backend->xs, xst, "%s/%s",
            device->frontend_path, path);
}
Example #3
0
int
tapback_xs_exists(struct xs_handle * const xs, xs_transaction_t xst,
        char *path, const int *len)
{
    int err = 0;
    char *s = NULL;
    bool exists = false;
    char c = '\0';

    ASSERT(xs);
    ASSERT(path);

    if (len) {
        c = path[*len];
        path[*len] = '\0';
    }

    s = tapback_xs_read(xs, xst, "%s", path);
    if (s)
        exists = true;
    else {
        err = errno;
        ASSERT(err != 0);
        if (err == ENOENT) {
            err = 0;
            exists = false;
        }
    }

    free(s);

    if (len)
        path[*len] = c;

    if (!err) {
        if (exists) {
            return 1;
        } else {
            return 0;
        }
    } else {
        return -err;
    }
}
Example #4
0
int
tapback_backend_handle_otherend_watch(backend_t *backend,
		const char * const path)
{
    vbd_t *device = NULL;
    int err = 0, state = 0;
    char *s = NULL, *end = NULL, *_path = NULL;

	ASSERT(backend);
    ASSERT(path);

    /*
     * Find the device that has the same front-end state path.
     *
     * There should definitely be such a device in our list, otherwise this
     * function would not have executed at all, since we would not be waiting
     * on that XenStore path.  The XenStore path we wait for is:
     * /local/domain/<domid>/device/vbd/<devname>/state. In order to watch this
     * path, it means that we have received a device create request, so the
     * device will be there.
     *
     * TODO Instead of this linear search we could do better (hash table etc).
     */
    tapback_backend_find_device(backend, device,
            device->frontend_state_path &&
			!strcmp(device->frontend_state_path, path));
    if (!device) {
        WARN(NULL, "path \'%s\' does not correspond to a known device\n",
                path);
        return ENODEV;
    }

    /*
     * Read the new front-end's state.
     */
	s = tapback_xs_read(device->backend->xs, XBT_NULL, "%s",
			device->frontend_state_path);
    if (!s) {
        err = errno;
		/*
         * If the front-end XenBus node is missing, the XenBus device has been
         * removed: remove the XenBus back-end node.
		 */
		if (err == ENOENT) {
            err = asprintf(&_path, "%s/%s/%d/%d", XENSTORE_BACKEND,
                    device->backend->name, device->domid, device->devid);
            if (err == -1) {
                err = errno;
                WARN(device, "failed to asprintf for %d/%d: %s\n",
                        strerror(err));
                goto out;
            }
            err = 0;
            if (!xs_rm(device->backend->xs, XBT_NULL, _path)) {
                if (errno != ENOENT) {
                    err = errno;
                    WARN(device, "failed to remove %s: %s\n", path,
                            strerror(err));
                }
            }
		}
    } else {
        state = strtol(s, &end, 0);
        if (*end != 0 || end == s) {
            WARN(device, "invalid XenBus state '%s'\n", s);
            err = EINVAL;
        } else
            err = frontend_changed(device, state);
    }

out:
    free(s);
    free(_path);
    return err;
}