[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 16 of 16 RFC] blktap3: Implement libxl__blktap_devpath and libxl__device_destroy_tapdisk
Provide implementation for the libxl__blktap_devpath and libxl__device_destroy_tapdisk functions: the former spawns the tapdisk process, the latter destroys it. Both of these functions use the blktap_find function, a function that lists all running tapdisks and looks for one serving a specific file. Finally, link libxl with the blktap3 control library. diff -r b12c1bb767d3 -r 0f87cc018fb6 tools/libxl/Makefile --- a/tools/libxl/Makefile Wed Oct 24 17:28:12 2012 +0100 +++ b/tools/libxl/Makefile Wed Oct 24 17:42:44 2012 +0100 @@ -20,7 +20,7 @@ LIBUUID_LIBS += -luuid endif LIBXL_LIBS = -LIBXL_LIBS = $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS) +LIBXL_LIBS = $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS) $(LDLIBS_libblktapctl) CFLAGS_LIBXL += $(CFLAGS_libxenctrl) CFLAGS_LIBXL += $(CFLAGS_libxenguest) @@ -29,7 +29,9 @@ CFLAGS_LIBXL += $(CFLAGS_libblktapctl) CFLAGS_LIBXL += -Wshadow CFLAGS += $(PTHREAD_CFLAGS) -LDFLAGS += $(PTHREAD_LDFLAGS) +override LDFLAGS += \ + $(PTHREAD_LDFLAGS) \ + -L $(XEN_BLKTAP3)/control LIBXL_LIBS += $(PTHREAD_LIBS) LIBXLU_LIBS = @@ -172,6 +174,7 @@ libxenlight.so.$(MAJOR): libxenlight.so. ln -sf $< $@ libxenlight.so.$(MAJOR).$(MINOR): $(LIBXL_OBJS) + make -C $(XEN_BLKTAP3) $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) libxenlight.a: $(LIBXL_OBJS) diff -r b12c1bb767d3 -r 0f87cc018fb6 tools/libxl/libxl_blktap3.c --- a/tools/libxl/libxl_blktap3.c Wed Oct 24 17:28:12 2012 +0100 +++ b/tools/libxl/libxl_blktap3.c Wed Oct 24 17:42:44 2012 +0100 @@ -1,11 +1,176 @@ +/* + * FIXME license + */ + #include "libxl_osdeps.h" #include "libxl_internal.h" +#include "tap-ctl.h" -int libxl__blktap_devpath(libxl__gc *gc, const char *disk, - libxl_disk_format format) { - return -ENOSYS; +/** + * Retrieves the tapdisk serving the specified file. + * + * @param type + * @param path + * @param tap output parameter that receives the tapdisk information + * + * @return 0 on success, an error code otherwise + * + * TODO If neither type nor path are specified, the first tapdisk will be + * returned. Not sure if this behaviour is desirable... + */ +static int blktap_find(libxl__gc *gc, const char *type, const char *path, + struct tap_list *tap) +{ + struct tqh_tap_list list; + struct tap_list *entry, *next_t; + int ret = -ENOENT, err; + + /* + * Get all the tapdisks. + */ + TAILQ_INIT(&list); + err = tap_ctl_list(&list); + if (err) { + LOG(DEBUG, "can't list tapdisks: %s\n", strerror(err)); + return err; + } + + if (TAILQ_EMPTY(&list)) + return ret; + + tap_list_for_each_entry_safe(entry, next_t, &list) { + + /* + * Look for the tapdisk that matches the type and path. If the user + * supplied a NULL type/path, it's treated as a matching one. + */ + + if (type && (!entry->type || strcmp(entry->type, type))) + continue; + + if (path && (!entry->path || strcmp(entry->path, path))) + continue; + + *tap = *entry; + + /* + * Set them to NULL so that when the user calls tap_ctl_list_free it + * won't free them. The strings weren't copied by the assignment above! + */ + tap->type = tap->path = NULL; + + ret = 0; + break; + } + + tap_ctl_list_free(&list); + + return ret; } -int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *be_path) { - return -ENOSYS; +/** + * Creates a tapdisk for the specified path. + * + * TODO document parameters + * + * @param gc + * @param disk + * @param format + * + * @returns 0 on success, an error code otherwise + */ +int libxl__blktap_devpath(libxl__gc *gc, const char *disk, + libxl_disk_format format) +{ + const char *type = NULL; + char *params = NULL; + struct tap_list tap; + int err = 0; + + type = libxl__device_disk_string_of_format(format); + + /* + * Ensure that no other tapdisk is serving this path. + * XXX Does libxl protect us against race conditions? What if somebody + * manually attaches a tapdisk to this path? + */ + if (!(err = blktap_find(gc, type, disk, &tap))) { + LOG(DEBUG, "tapdisk %d already serving %s\n", tap.pid, disk); + return 0; + } + + LOG(DEBUG, "tapdisk not found\n"); + + /* + * TODO Should we worry about return codes other than ENOENT? + */ + + params = libxl__sprintf(gc, "%s:%s", type, disk); + if (!(err = tap_ctl_create(params, 0, -1, NULL))) { + LOG(DEBUG, "created tapdisk\n"); + return 0; + } + + LOG(ERROR, "error creating tapdisk: %s\n", strerror(err)); + + return err; } + +/** + * Destroys the tapdisk serving the specified path. + * + * TODO document parameters + * + * @param gc + * @param be_path + * + * @returns 0 on success, an error code otherwise + */ +int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *be_path) +{ + char *disk; + int err; + struct tap_list tap; + + LOG(DEBUG, "destroying tapdisk %s\n", be_path); + + /* + * TODO is the path is in the following format? + * <backend type>:/path/to/file + */ + disk = strchr(be_path, ':'); + if (!disk) { + LOG(ERROR, "Unable to parse params %s", be_path); + return ERROR_INVAL; + } + + /* + * Replace the ':' with '\0' effectively creating two strings in the same + * buffer: the first is the type and the second is the path. + */ + *disk++ = '\0'; + + err = blktap_find(gc, be_path, disk, &tap); + if (err < 0) { + /* returns -errno */ + LOGEV(ERROR, -err, "Unable to find type %s disk %s", be_path, disk); + return ERROR_FAIL; + } + + err = tap_ctl_destroy(tap.pid, tap.minor, 0, NULL); + if (err < 0) { + LOGEV(ERROR, -err, "Failed to destroy tap device id %d minor %d", + tap.pid, tap.minor); + return ERROR_FAIL; + } + + return 0; +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |