Whamcloud - gitweb
LU-6816 utils: remove libzfs_load_module() call
[fs/lustre-release.git] / lustre / utils / mount_utils_zfs.c
index d824306..854f174 100644 (file)
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2011, 2012 Whamcloud, Inc.
+ * Copyright (c) 2012, 2014, Intel Corporation.
  * Use is subject to license terms.
- *
  */
 /*
  * Author: Brian Behlendorf <behlendorf1@llnl.gov>
  */
-
+#include "mount_utils.h"
 #include <stdio.h>
 #include <string.h>
-#include <libzfs/libzfs.h>
-#include <dlfcn.h>
+#include <libzfs.h>
+
+/* Persistent mount data is stored in these user attributes */
+#define LDD_PREFIX             "lustre:"
+#define LDD_VERSION_PROP       LDD_PREFIX "version"
+#define LDD_FLAGS_PROP         LDD_PREFIX "flags"
+#define LDD_INDEX_PROP         LDD_PREFIX "index"
+#define LDD_FSNAME_PROP                LDD_PREFIX "fsname"
+#define LDD_SVNAME_PROP                LDD_PREFIX "svname"
+#define LDD_UUID_PROP          LDD_PREFIX "uuid"
+#define LDD_USERDATA_PROP      LDD_PREFIX "userdata"
+#define LDD_MOUNTOPTS_PROP     LDD_PREFIX "mountopts"
+
+/* This structure is used to help bridge the gap between the ZFS
+ * properties Lustre uses and their corresponding internal LDD fields.
+ * It is meant to be used internally by the mount utility only. */
+struct zfs_ldd_prop_bridge {
+       /* Contains the publicly visible name for the property
+        * (i.e. what is shown when running "zfs get") */
+       char *zlpb_prop_name;
+       /* Contains the offset into the lustre_disk_data structure where
+        * the value of this property is or will be stored. (i.e. the
+        * property is read from and written to this offset within ldd) */
+       int   zlpb_ldd_offset;
+       /* Function pointer responsible for reading in the @prop
+        * property from @zhp and storing it in @ldd_field */
+       int (*zlpb_get_prop_fn)(zfs_handle_t *zhp, char *prop, void *ldd_field);
+       /* Function pointer responsible for writing the value of @ldd_field
+        * into the @prop dataset property in @zhp */
+       int (*zlpb_set_prop_fn)(zfs_handle_t *zhp, char *prop, void *ldd_field);
+};
 
-#include "mount_utils.h"
+/* Forward declarations needed to initialize the ldd prop bridge list */
+static int zfs_get_prop_int(zfs_handle_t *, char *, void *);
+static int zfs_set_prop_int(zfs_handle_t *, char *, void *);
+static int zfs_get_prop_str(zfs_handle_t *, char *, void *);
+static int zfs_set_prop_str(zfs_handle_t *, char *, void *);
+
+/* Helper for initializing the entries in the special_ldd_prop_params list.
+ *    - @name: stored directly in the zlpb_prop_name field
+ *             (e.g. lustre:fsname, lustre:version, etc.)
+ *    - @field: the field in the lustre_disk_data which directly maps to
+ *              the @name property. (e.g. ldd_fsname, ldd_config_ver, etc.)
+ *    - @type: The type of @field. Only "int" and "str" are supported.
+ */
+#define ZLB_INIT(name, field, type)                    \
+{                                                      \
+       name, offsetof(struct lustre_disk_data, field), \
+       zfs_get_prop_ ## type, zfs_set_prop_ ## type    \
+}
 
-/* Persistent mount data is stored in these user  attributes */
-#define LDD_VERSION_PROP                "lustre:version"
-#define LDD_FLAGS_PROP                  "lustre:flags"
-#define LDD_INDEX_PROP                  "lustre:index"
-#define LDD_FSNAME_PROP                 "lustre:fsname"
-#define LDD_SVNAME_PROP                 "lustre:svname"
-#define LDD_UUID_PROP                   "lustre:uuid"
-#define LDD_USERDATA_PROP               "lustre:userdata"
-#define LDD_MOUNTOPTS_PROP              "lustre:mountopts"
-#define LDD_MGSNODE_PROP                "lustre:mgsnode"
-#define LDD_FAILNODE_PROP               "lustre:failnode"
-#define LDD_FAILMODE_PROP               "lustre:failmode"
-#define LDD_IDENTITY_UPCALL_PROP        "lustre:identity_upcall"
+/* These ldd properties are special because they all have their own
+ * individual fields in the lustre_disk_data structure, as opposed to
+ * being globbed into the ldd_params field. As such, these need special
+ * handling when reading/writing the ldd structure to/from persistent
+ * storage. */
+struct zfs_ldd_prop_bridge special_ldd_prop_params[] = {
+       ZLB_INIT(LDD_VERSION_PROP,   ldd_config_ver, int),
+       ZLB_INIT(LDD_FLAGS_PROP,     ldd_flags,      int),
+       ZLB_INIT(LDD_INDEX_PROP,     ldd_svindex,    int),
+       ZLB_INIT(LDD_FSNAME_PROP,    ldd_fsname,     str),
+       ZLB_INIT(LDD_SVNAME_PROP,    ldd_svname,     str),
+       ZLB_INIT(LDD_UUID_PROP,      ldd_uuid,       str),
+       ZLB_INIT(LDD_USERDATA_PROP,  ldd_userdata,   str),
+       ZLB_INIT(LDD_MOUNTOPTS_PROP, ldd_mount_opts, str),
+       { NULL }
+};
 
 /* indicate if the ZFS OSD has been successfully setup */
 static int osd_zfs_setup = 0;
 
 static libzfs_handle_t *g_zfs;
 
-/* dynamic linking handles for libzfs & libnvpair */
-static void *handle_libzfs;
-static void *handle_nvpair;
-
-/* symbol table looked up with dlsym */
-struct zfs_symbols {
-       libzfs_handle_t *(*libzfs_init)(void);
-       void            (*libzfs_fini)(libzfs_handle_t *);
-       int             (*libzfs_load_module)(char *);
-       zfs_handle_t*   (*zfs_open)(libzfs_handle_t *, const char *, int);
-       int             (*zfs_destroy)(zfs_handle_t *, boolean_t);
-       void            (*zfs_close)(zfs_handle_t *);
-       int     (*zfs_prop_set)(zfs_handle_t*, const char*, const char*);
-       nvlist_t*       (*zfs_get_user_props)  (zfs_handle_t *);
-       int             (*zfs_name_valid)(const char *, zfs_type_t);
-       zpool_handle_t* (*zpool_open)(libzfs_handle_t *, const char *);
-       void            (*zpool_close)(zpool_handle_t *zhp);
-       int             (*nvlist_lookup_string)(nvlist_t*, const char*, char**);
-       int     (*nvlist_lookup_nvlist)(nvlist_t *, const char *, nvlist_t **);
-};
-
-static struct zfs_symbols sym;
 void zfs_fini(void);
 
-#define DLSYM(handle, func)                                        \
-       do {                                                       \
-               sym.func = (typeof(sym.func))dlsym(handle, #func); \
-       } while(0)
-
-/* populate the symbol table after a successful call to dlopen() */
-static int zfs_populate_symbols(void)
-{
-       char *error;
-
-       dlerror(); /* Clear any existing error */
-
-       DLSYM(handle_libzfs, libzfs_init);
-#define libzfs_init (*sym.libzfs_init)
-       DLSYM(handle_libzfs, libzfs_fini);
-#define libzfs_fini (*sym.libzfs_fini)
-       DLSYM(handle_libzfs, libzfs_load_module);
-#define libzfs_load_module (*sym.libzfs_load_module)
-       DLSYM(handle_libzfs, zfs_open);
-#define zfs_open (*sym.zfs_open)
-       DLSYM(handle_libzfs, zfs_destroy);
-#define zfs_destroy (*sym.zfs_destroy)
-       DLSYM(handle_libzfs, zfs_close);
-#define zfs_close (*sym.zfs_close)
-       DLSYM(handle_libzfs, zfs_prop_set);
-#define zfs_prop_set (*sym.zfs_prop_set)
-       DLSYM(handle_libzfs, zfs_get_user_props);
-#define zfs_get_user_props (*sym.zfs_get_user_props)
-       DLSYM(handle_libzfs, zfs_name_valid);
-#define zfs_name_valid (*sym.zfs_name_valid)
-       DLSYM(handle_libzfs, zpool_open);
-#define zpool_open (*sym.zpool_open)
-       DLSYM(handle_libzfs, zpool_close);
-#define zpool_close (*sym.zpool_close)
-       DLSYM(handle_nvpair, nvlist_lookup_string);
-#define nvlist_lookup_string (*sym.nvlist_lookup_string)
-       DLSYM(handle_nvpair, nvlist_lookup_nvlist);
-#define nvlist_lookup_nvlist (*sym.nvlist_lookup_nvlist)
-
-       error = dlerror();
-       if (error != NULL) {
-               fatal();
-               fprintf(stderr, "%s\n", error);
-               return EINVAL;
-       }
-       return 0;
-}
-
-static int zfs_set_prop_int(zfs_handle_t *zhp, char *prop, __u32 val)
+static int zfs_set_prop_int(zfs_handle_t *zhp, char *prop, void *val)
 {
        char str[64];
        int ret;
 
-       (void) snprintf(str, sizeof (str), "%lu", (unsigned long)val);
+       (void) snprintf(str, sizeof (str), "%i", *(int *)val);
        vprint("  %s=%s\n", prop, str);
        ret = zfs_prop_set(zhp, prop, str);
 
@@ -142,30 +120,56 @@ static int zfs_set_prop_int(zfs_handle_t *zhp, char *prop, __u32 val)
  * Write the zfs property string, note that properties with a NULL or
  * zero-length value will not be written and 0 returned.
  */
-static int zfs_set_prop_str(zfs_handle_t *zhp, char *prop, char *val)
+static int zfs_set_prop_str(zfs_handle_t *zhp, char *prop, void *val)
 {
        int ret = 0;
 
        if (val && strlen(val) > 0) {
-               vprint("  %s=%s\n", prop, val);
-               ret = zfs_prop_set(zhp, prop, val);
+               vprint("  %s=%s\n", prop, (char *)val);
+               ret = zfs_prop_set(zhp, prop, (char *)val);
        }
 
        return ret;
 }
 
-static int zfs_set_prop_param(zfs_handle_t *zhp, struct lustre_disk_data *ldd,
-                             char *param, char *prop)
+/*
+ * Map '<key>=<value> ...' pairs in the passed string to dataset properties
+ * of the form 'lustre:<key>=<value>'.  Malformed <key>=<value> pairs will
+ * be skipped.
+ */
+static int zfs_set_prop_params(zfs_handle_t *zhp, char *params)
 {
-       char *str;
+       char *params_dup, *token, *key, *value;
+       char *save_token = NULL;
+       char prop_name[ZFS_MAXNAMELEN];
        int ret = 0;
 
-       if (get_param(ldd->ldd_params, param, &str) == 0) {
-               vprint("  %s=%s\n", prop, str);
-               ret = zfs_prop_set(zhp, prop, str);
-               free(str);
+       params_dup = strdup(params);
+       if (params_dup == NULL)
+               return ENOMEM;
+
+       token = strtok_r(params_dup, " ", &save_token);
+       while (token) {
+               key = strtok(token, "=");
+               if (key == NULL)
+                       continue;
+
+               value = strtok(NULL, "=");
+               if (value == NULL)
+                       continue;
+
+               sprintf(prop_name, "%s%s", LDD_PREFIX, key);
+               vprint("  %s=%s\n", prop_name, value);
+
+               ret = zfs_prop_set(zhp, prop_name, value);
+               if (ret)
+                       break;
+
+               token = strtok_r(NULL, " ", &save_token);
        }
 
+       free(params_dup);
+
        return ret;
 }
 
@@ -186,7 +190,8 @@ int zfs_write_ldd(struct mkfs_opts *mop)
        struct lustre_disk_data *ldd = &mop->mo_ldd;
        char *ds = mop->mo_device;
        zfs_handle_t *zhp;
-       int ret = EINVAL;
+       struct zfs_ldd_prop_bridge *bridge;
+       int i, ret = EINVAL;
 
        if (osd_check_zfs_setup() == 0)
                return EINVAL;
@@ -199,54 +204,15 @@ int zfs_write_ldd(struct mkfs_opts *mop)
 
        vprint("Writing %s properties\n", ds);
 
-       ret = zfs_set_prop_int(zhp, LDD_VERSION_PROP, ldd->ldd_config_ver);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_int(zhp, LDD_FLAGS_PROP, ldd->ldd_flags);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_int(zhp, LDD_INDEX_PROP, ldd->ldd_svindex);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_str(zhp, LDD_FSNAME_PROP, ldd->ldd_fsname);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_str(zhp, LDD_SVNAME_PROP, ldd->ldd_svname);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_str(zhp, LDD_UUID_PROP, (char *)ldd->ldd_uuid);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_str(zhp, LDD_USERDATA_PROP, ldd->ldd_userdata);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_str(zhp, LDD_MOUNTOPTS_PROP, ldd->ldd_mount_opts);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_param(zhp, ldd, PARAM_MGSNODE, LDD_MGSNODE_PROP);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_param(zhp, ldd, PARAM_FAILNODE, LDD_FAILNODE_PROP);
-       if (ret)
-               goto out_close;
-
-       ret = zfs_set_prop_param(zhp, ldd, PARAM_FAILMODE, LDD_FAILMODE_PROP);
-       if (ret)
-               goto out_close;
+       for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++) {
+               bridge = &special_ldd_prop_params[i];
+               ret = bridge->zlpb_set_prop_fn(zhp, bridge->zlpb_prop_name,
+                                       (void *)ldd + bridge->zlpb_ldd_offset);
+               if (ret)
+                       goto out_close;
+       }
 
-       ret = zfs_set_prop_param(zhp, ldd, PARAM_MDT PARAM_ID_UPCALL,
-                                LDD_IDENTITY_UPCALL_PROP);
-       if (ret)
-               goto out_close;
+       ret = zfs_set_prop_params(zhp, ldd->ldd_params);
 
 out_close:
        zfs_close(zhp);
@@ -254,7 +220,7 @@ out:
        return ret;
 }
 
-static int zfs_get_prop_int(zfs_handle_t *zhp, char *prop, __u32 *val)
+static int zfs_get_prop_int(zfs_handle_t *zhp, char *prop, void *val)
 {
        nvlist_t *propval;
        char *propstr;
@@ -269,14 +235,14 @@ static int zfs_get_prop_int(zfs_handle_t *zhp, char *prop, __u32 *val)
                return ret;
 
        errno = 0;
-       *val = strtoul(propstr, NULL, 10);
+       *(__u32 *)val = strtoul(propstr, NULL, 10);
        if (errno)
                return errno;
 
        return ret;
 }
 
-static int zfs_get_prop_str(zfs_handle_t *zhp, char *prop, char *val)
+static int zfs_get_prop_str(zfs_handle_t *zhp, char *prop, void *val)
 {
        nvlist_t *propval;
        char *propstr;
@@ -295,22 +261,53 @@ static int zfs_get_prop_str(zfs_handle_t *zhp, char *prop, char *val)
        return ret;
 }
 
-static int zfs_get_prop_param(zfs_handle_t *zhp, struct lustre_disk_data *ldd,
-               char *param, char *prop)
+static int zfs_is_special_ldd_prop_param(char *name)
 {
-       nvlist_t *propval;
-       char *propstr;
-       int ret;
+       int i;
 
-       ret = nvlist_lookup_nvlist(zfs_get_user_props(zhp), prop, &propval);
-       if (ret)
-               return ret;
+       for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++)
+               if (!strcmp(name, special_ldd_prop_params[i].zlpb_prop_name))
+                       return 1;
 
-       ret = nvlist_lookup_string(propval, ZPROP_VALUE, &propstr);
-       if (ret)
-               return ret;
+       return 0;
+}
+
+static int zfs_get_prop_params(zfs_handle_t *zhp, char *param, int len)
+{
+       nvlist_t *props;
+       nvpair_t *nvp;
+       char key[ZFS_MAXNAMELEN];
+       char *value;
+       int ret = 0;
+
+       props = zfs_get_user_props(zhp);
+       if (props == NULL)
+               return ENOENT;
+
+       value = malloc(len);
+       if (value == NULL)
+               return ENOMEM;
+
+       nvp = NULL;
+       while (nvp = nvlist_next_nvpair(props, nvp), nvp) {
+               ret = zfs_get_prop_str(zhp, nvpair_name(nvp), value);
+               if (ret)
+                       break;
+
+               if (strncmp(nvpair_name(nvp), LDD_PREFIX, strlen(LDD_PREFIX)))
+                       continue;
 
-       ret = add_param(ldd->ldd_params, param, propstr);
+               if (zfs_is_special_ldd_prop_param(nvpair_name(nvp)))
+                       continue;
+
+               sprintf(key, "%s=",  nvpair_name(nvp) + strlen(LDD_PREFIX));
+
+               ret = add_param(param, key, value);
+               if (ret)
+                       break;
+       }
+
+       free(value);
 
        return ret;
 }
@@ -322,7 +319,8 @@ static int zfs_get_prop_param(zfs_handle_t *zhp, struct lustre_disk_data *ldd,
 int zfs_read_ldd(char *ds,  struct lustre_disk_data *ldd)
 {
        zfs_handle_t *zhp;
-       int ret = EINVAL;
+       struct zfs_ldd_prop_bridge *bridge;
+       int i, ret = EINVAL;
 
        if (osd_check_zfs_setup() == 0)
                return EINVAL;
@@ -331,52 +329,15 @@ int zfs_read_ldd(char *ds,  struct lustre_disk_data *ldd)
        if (zhp == NULL)
                goto out;
 
-       ret = zfs_get_prop_int(zhp, LDD_VERSION_PROP, &ldd->ldd_config_ver);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_int(zhp, LDD_FLAGS_PROP, &ldd->ldd_flags);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_int(zhp, LDD_INDEX_PROP, &ldd->ldd_svindex);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_str(zhp, LDD_FSNAME_PROP, ldd->ldd_fsname);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_str(zhp, LDD_SVNAME_PROP, ldd->ldd_svname);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_str(zhp, LDD_UUID_PROP, (char *)ldd->ldd_uuid);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_str(zhp, LDD_USERDATA_PROP, ldd->ldd_userdata);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_str(zhp, LDD_MOUNTOPTS_PROP, ldd->ldd_mount_opts);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_param(zhp, ldd, PARAM_MGSNODE, LDD_MGSNODE_PROP);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_param(zhp, ldd, PARAM_FAILNODE, LDD_FAILNODE_PROP);
-       if (ret && (ret != ENOENT))
-               goto out_close;
-
-       ret = zfs_get_prop_param(zhp, ldd, PARAM_FAILMODE, LDD_FAILMODE_PROP);
-       if (ret && (ret != ENOENT))
-               goto out_close;
+       for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++) {
+               bridge = &special_ldd_prop_params[i];
+               ret = bridge->zlpb_get_prop_fn(zhp, bridge->zlpb_prop_name,
+                                       (void *)ldd + bridge->zlpb_ldd_offset);
+               if (ret && (ret != ENOENT))
+                       goto out_close;
+       }
 
-       ret = zfs_get_prop_param(zhp, ldd, PARAM_MDT PARAM_ID_UPCALL,
-                                LDD_IDENTITY_UPCALL_PROP);
+       ret = zfs_get_prop_params(zhp, ldd->ldd_params, 4096);
        if (ret && (ret != ENOENT))
                goto out_close;
 
@@ -398,7 +359,6 @@ int zfs_is_lustre(char *ds, unsigned *mount_type)
 
        ret = zfs_read_ldd(ds, &tmp_ldd);
        if ((ret == 0) && (tmp_ldd.ldd_config_ver > 0) &&
-           (strlen(tmp_ldd.ldd_fsname) > 0) &&
            (strlen(tmp_ldd.ldd_svname) > 0)) {
                *mount_type = tmp_ldd.ldd_mount_type;
                return 1;
@@ -433,7 +393,7 @@ static int zfs_create_vdev(struct mkfs_opts *mop, char *vdev)
 
        /*
         * Verify a file exists at the provided absolute path.  If it doesn't
-        * and mo_device_sz is set attempt to create a file vdev to be used.
+        * and mo_device_kb is set attempt to create a file vdev to be used.
         * Relative paths will be passed directly to 'zpool create' which
         * will check multiple multiple locations under /dev/.
         */
@@ -450,14 +410,14 @@ static int zfs_create_vdev(struct mkfs_opts *mop, char *vdev)
                        return ret;
                }
 
-               if (mop->mo_device_sz == 0) {
+               if (mop->mo_device_kb == 0) {
                        fatal();
                        fprintf(stderr, "Unable to create vdev due to "
                                "missing --device-size=#N(KB) parameter\n");
                        return EINVAL;
                }
 
-               ret = file_create(vdev, mop->mo_device_sz);
+               ret = file_create(vdev, mop->mo_device_kb);
                if (ret) {
                        fatal();
                        fprintf(stderr, "Unable to create vdev %s (%d)\n",
@@ -506,7 +466,7 @@ int zfs_make_lustre(struct mkfs_opts *mop)
                goto out;
        }
 
-       /* Due to zfs_name_valid() check the '/' must exist */
+       /* Due to zfs_prepare_lustre() check the '/' must exist */
        strchr(pool, '/')[0] = '\0';
 
        /* If --reformat was given attempt to destroy the previous dataset */
@@ -567,13 +527,12 @@ int zfs_make_lustre(struct mkfs_opts *mop)
        /*
         * Create the ZFS filesystem with any required mkfs options:
         * - canmount=off is set to prevent zfs automounting
-        * - version=4 is set because SA are not yet handled by the osd
+        * - xattr=sa is set to use system attribute based xattrs
         */
        memset(mkfs_cmd, 0, PATH_MAX);
        snprintf(mkfs_cmd, PATH_MAX,
                 "zfs create -o canmount=off -o xattr=sa%s %s",
-                zfs_mkfs_opts(mop, mkfs_tmp, PATH_MAX),
-                ds);
+                zfs_mkfs_opts(mop, mkfs_tmp, PATH_MAX), ds);
 
        vprint("mkfs_cmd = %s\n", mkfs_cmd);
        ret = run_command(mkfs_cmd, PATH_MAX);
@@ -597,62 +556,73 @@ out:
        return ret;
 }
 
+int zfs_enable_quota(struct mkfs_opts *mop)
+{
+       fprintf(stderr, "this option is not only valid for zfs\n");
+       return ENOSYS;
+}
+
 int zfs_prepare_lustre(struct mkfs_opts *mop,
                char *default_mountopts, int default_len,
                char *always_mountopts, int always_len)
 {
-       int ret;
-
        if (osd_check_zfs_setup() == 0)
                return EINVAL;
 
-       ret = zfs_name_valid(mop->mo_device, ZFS_TYPE_FILESYSTEM);
-       if (!ret) {
+       if (zfs_name_valid(mop->mo_device, ZFS_TYPE_FILESYSTEM) == 0) {
                fatal();
                fprintf(stderr, "Invalid filesystem name %s\n", mop->mo_device);
                return EINVAL;
        }
 
+       if (strchr(mop->mo_device, '/') == NULL) {
+               fatal();
+               fprintf(stderr, "Missing pool in filesystem name %s\n",
+                       mop->mo_device);
+               return EINVAL;
+       }
+
        return 0;
 }
 
-int zfs_init(void)
+int zfs_tune_lustre(char *dev, struct mount_opts *mop)
 {
-       int ret = 0;
+       if (osd_check_zfs_setup() == 0)
+               return EINVAL;
 
-       /* If the ZFS libs are not installed, don't print an error to avoid
-        * spamming ldiskfs users. An error message will still be printed if
-        * someone tries to do some real work involving a ZFS backend */
+       return 0;
+}
+
+int zfs_label_lustre(struct mount_opts *mop)
+{
+       zfs_handle_t *zhp;
+       int ret;
 
-       handle_libzfs = dlopen("libzfs.so", RTLD_LAZY);
-       if (handle_libzfs == NULL)
+       if (osd_check_zfs_setup() == 0)
                return EINVAL;
 
-       handle_nvpair = dlopen("libnvpair.so", RTLD_LAZY);
-       if (handle_nvpair == NULL) {
-               ret = EINVAL;
-               goto out;
-       }
+       zhp = zfs_open(g_zfs, mop->mo_source, ZFS_TYPE_FILESYSTEM);
+       if (zhp == NULL)
+               return EINVAL;
 
-       ret = zfs_populate_symbols();
-       if (ret)
-               goto out;
+       ret = zfs_set_prop_str(zhp, LDD_SVNAME_PROP, mop->mo_ldd.ldd_svname);
+       zfs_close(zhp);
 
-       if (libzfs_load_module("zfs") != 0) {
-               /* The ZFS modules are not installed */
-               ret = EINVAL;
-               goto out;
-       }
+       return ret;
+}
+
+int zfs_init(void)
+{
+       int ret = 0;
 
        g_zfs = libzfs_init();
        if (g_zfs == NULL) {
                fprintf(stderr, "Failed to initialize ZFS library\n");
                ret = EINVAL;
+       } else {
+               osd_zfs_setup = 1;
        }
-out:
-       osd_zfs_setup = 1;
-       if (ret)
-               zfs_fini();
+
        return ret;
 }
 
@@ -662,14 +632,5 @@ void zfs_fini(void)
                libzfs_fini(g_zfs);
                g_zfs = NULL;
        }
-       if (handle_nvpair) {
-               dlclose(handle_nvpair);
-               handle_nvpair = NULL;
-       }
-       if (handle_libzfs) {
-               dlclose(handle_libzfs);
-               handle_libzfs = NULL;
-       }
-
        osd_zfs_setup = 0;
 }