[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2 of 7 v4] blktap3/tapback: Introduces functionality required to access XenStore
This patch introduces convenience functions that read/write values from/to XenStore. Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx> --- Changed since v2: * Introduced makefile to facilitate development. * Removed functions (v)mprintf as (v)asprintf suffice. * Ensure tapback_xs_vread (a) returns a NULL terminated string, and (b) the returned string doesn't contain NULL characters, apart from the NULL-terminating one. * Removed unnecessary variable initialisations. * Minor whitespace clean up. * Fixed typo in tapback_xs_vread. * function tapback_xs_vread: handle corner case where the value returned by xs_read is a zero-length string. diff --git a/tools/blktap3/tapback/Makefile b/tools/blktap3/tapback/Makefile new file mode 100644 --- /dev/null +++ b/tools/blktap3/tapback/Makefile @@ -0,0 +1,31 @@ +XEN_ROOT := $(CURDIR)/../../../ +include $(XEN_ROOT)/tools/Rules.mk + +BLKTAP_ROOT := .. + +# -D_GNU_SOURCE is required by vasprintf. +override CFLAGS += \ + -I$(BLKTAP_ROOT)/include \ + -I$(BLKTAP_ROOT)/control \ + -D_GNU_SOURCE \ + $(CFLAGS_libxenstore) \ + $(CFLAGS_libxenctrl) \ + $(CFLAGS_xeninclude) \ + -Wall \ + -Wextra \ + -Werror + +# FIXME cause trouble +override CFLAGS += \ + -Wno-old-style-declaration \ + -Wno-sign-compare \ + -Wno-type-limits + +override LDFLAGS += \ + $(LDLIBS_libxenstore) \ + $(LDFLAGS_libxenctrl) + +clean: + rm -f *.o *.o.d .*.o.d + +.PHONY: clean install diff --git a/tools/blktap3/tapback/xenstore.c b/tools/blktap3/tapback/xenstore.c new file mode 100644 --- /dev/null +++ b/tools/blktap3/tapback/xenstore.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2012 Citrix Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <xenstore.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "blktap3.h" +#include "tapback.h" +#include "xenstore.h" + +char * +tapback_xs_vread(struct xs_handle * const xs, xs_transaction_t xst, + const char * const fmt, va_list ap) +{ + char *path, *data = NULL; + unsigned int len = 0; + + assert(xs); + + if (vasprintf(&path, fmt, ap) == -1) + goto fail; + assert(path); + + data = xs_read(xs, xst, path, &len); + free(path); + + if (!data) + return NULL; + + assert(len >= 0); + + /* + * Make sure the returned string is NULL-terminated. + */ + if ((len > 0 && data[len - 1] != '\0') || (len == 0 && data[0] != '\0')) { + char *_data = strndup(data, len); + if (!_data) + /* TODO log error */ + goto fail; + free(data); + data = _data; + } + + /* + * Make sure the returned string does not containing NULL characters, apart + * from the NULL-terminating one. + * + * We should be checking for extraneous NULLs before duplicating the + * buffer, but this way logic is simplified. + */ + if (strrchr(data, '\0') - data != len) + /* TODO log error */ + goto fail; + + return data; +fail: + free(data); + return NULL; +} + +__printf(3, 4) +char * +tapback_xs_read(struct xs_handle * const xs, xs_transaction_t xst, + const char * const fmt, ...) +{ + va_list ap; + char *s; + + assert(xs); + + va_start(ap, fmt); + s = tapback_xs_vread(xs, xst, fmt, ap); + va_end(ap); + + return s; +} + +char * +tapback_device_read(const vbd_t * const device, const char * const path) +{ + assert(device); + assert(path); + + return tapback_xs_read(blktap3_daemon.xs, blktap3_daemon.xst, + "%s/%d/%s/%s", BLKTAP3_BACKEND_PATH, device->domid, device->name, + path); +} + +char * +tapback_device_read_otherend(vbd_t * const device, + const char * const path) +{ + assert(device); + assert(path); + + return tapback_xs_read(blktap3_daemon.xs, blktap3_daemon.xst, "%s/%s", + device->frontend_path, path); +} + +__scanf(3, 4) +int +tapback_device_scanf_otherend(vbd_t * const device, + const char * const path, const char * const fmt, ...) +{ + va_list ap; + int n = 0; + char *s = NULL; + + assert(device); + assert(path); + + if (!(s = tapback_device_read_otherend(device, path))) + return -1; + va_start(ap, fmt); + n = vsscanf(s, fmt, ap); + free(s); + va_end(ap); + + return n; +} + +__printf(4, 5) +int +tapback_device_printf(vbd_t * const device, const char * const key, + const bool mkread, const char * const fmt, ...) +{ + va_list ap; + int err = 0; + char *path = NULL, *val = NULL; + bool nerr = false; + + assert(device); + assert(key); + + if (-1 == asprintf(&path, "%s/%d/%s/%s", BLKTAP3_BACKEND_PATH, + device->domid, device->name, key)) { + err = -errno; + goto fail; + } + + va_start(ap, fmt); + if (-1 == vasprintf(&val, fmt, ap)) + val = NULL; + va_end(ap); + + if (!val) { + err = -errno; + goto fail; + } + + if (!(nerr = xs_write(blktap3_daemon.xs, blktap3_daemon.xst, path, val, + strlen(val)))) { + err = -errno; + goto fail; + } + + if (mkread) { + struct xs_permissions perms = { + device->domid, + XS_PERM_READ + }; + + if (!(nerr = xs_set_permissions(blktap3_daemon.xs, blktap3_daemon.xst, + path, &perms, 1))) { + err = -errno; + goto fail; + } + } + +fail: + free(path); + free(val); + + return err; +} diff --git a/tools/blktap3/tapback/xenstore.h b/tools/blktap3/tapback/xenstore.h new file mode 100644 --- /dev/null +++ b/tools/blktap3/tapback/xenstore.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012 Citrix Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +/** + * Retrieves the XenStore value of the specified key of the VBD's front-end. + * The caller must free the returned buffer. + * + * @param device the VBD + * @param path key under the front-end directory + * @returns a buffer containing the value, or NULL on error + */ +char * +tapback_device_read_otherend(vbd_t * const device, + const char * const path); + +/** + * Writes to XenStore backened/tapback/<domid>/<devname>/@key = @fmt. + * + * @param device the VBD + * @param key the key to write to + * @param mkread TODO + * @param fmt format + * @returns 0 on success, an error code otherwise + */ +__printf(4, 5) +int +tapback_device_printf(vbd_t * const device, const char * const key, + const bool mkread, const char * const fmt, ...); + +/** + * Reads the specified XenStore path under the front-end directory in a + * scanf-like manner. + * + * @param device the VBD + * @param path XenStore path to read + * @param fmt format + */ +__scanf(3, 4) +int +tapback_device_scanf_otherend(vbd_t * const device, + const char * const path, const char * const fmt, ...); + +/** + * Retrieves the value of the specified of the device from XenStore, + * i.e. backend/tapback/<domid>/<devname>/@path + * The caller must free the returned buffer. + * + * @param device the VBD + * @param path the XenStore key + * @returns a buffer containing the value, or NULL on error + */ +char * +tapback_device_read(const vbd_t * const device, const char * const path); + +/** + * Reads the specified XenStore path. The caller must free the returned buffer. + * + * @param xs handle to XenStore + * @param xst XenStore transaction + * @param fmt format + * @param ap arguments + * @returns a buffer containing the value, or NULL on error + */ +char * +tapback_xs_vread(struct xs_handle * const xs, xs_transaction_t xst, + const char * const fmt, va_list ap); + +/** + * Reads the specified XenStore path. The caller must free the returned buffer. + * + * @param xs handle to XenStore + * @param xst XenStore transaction + * @param fmt format + * @returns a buffer containing the value, or NULL on error + */ +__printf(3, 4) +char * +tapback_xs_read(struct xs_handle * const xs, xs_transaction_t xst, + const char * const fmt, ...); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |