[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.