|
[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 |