* GPL HEADER END
*/
/*
- * Copyright (c) 2011, 2012 Whamcloud, Inc.
+ * Copyright (c) 2012, 2016, Intel Corporation.
* Use is subject to license terms.
- *
*/
/*
* Author: Brian Behlendorf <behlendorf1@llnl.gov>
*/
-
+#include "mount_utils.h"
+#include <stddef.h>
#include <stdio.h>
#include <string.h>
-#include <libzfs/libzfs.h>
-#include <dlfcn.h>
+#include <libzfs.h>
+
+#define HOSTID_PATH "/etc/hostid"
+
+/* 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);
* 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_MAXPROPLEN];
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;
}
+static int zfs_check_hostid(struct mkfs_opts *mop)
+{
+ FILE *f;
+ unsigned long hostid;
+ int rc;
+
+ if (strstr(mop->mo_ldd.ldd_params, PARAM_FAILNODE) == NULL)
+ return 0;
+
+ f = fopen("/sys/module/spl/parameters/spl_hostid", "r");
+ if (f == NULL) {
+ fatal();
+ fprintf(stderr, "Failed to open spl_hostid: %s\n",
+ strerror(errno));
+ return errno;
+ }
+ rc = fscanf(f, "%li", &hostid);
+ fclose(f);
+ if (rc != 1) {
+ fatal();
+ fprintf(stderr, "Failed to read spl_hostid: %d\n", rc);
+ return rc;
+ }
+
+ if (hostid != 0)
+ return 0;
+
+ f = fopen(HOSTID_PATH, "r");
+ if (f == NULL)
+ goto out;
+
+ rc = fread(&hostid, sizeof(uint32_t), 1, f);
+ fclose(f);
+
+ if (rc != 1) {
+ fprintf(stderr, "Failed to read "HOSTID_PATH": %d\n",
+ rc);
+ hostid = 0;
+ }
+
+out:
+ if (hostid == 0) {
+ if (mop->mo_flags & MO_NOHOSTID_CHECK) {
+ fprintf(stderr, "WARNING: spl_hostid not set. ZFS has "
+ "no zpool import protection\n");
+ } else {
+ fatal();
+ fprintf(stderr, "spl_hostid not set. See %s(8)",
+ progname);
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int osd_check_zfs_setup(void)
{
if (osd_zfs_setup == 0) {
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;
+ goto out;
zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM);
if (zhp == NULL) {
goto out;
}
- 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_check_hostid(mop);
+ if (ret != 0)
+ goto out;
- ret = zfs_set_prop_param(zhp, ldd, PARAM_FAILNODE, LDD_FAILNODE_PROP);
- if (ret)
- goto out_close;
+ vprint("Writing %s properties\n", ds);
- 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);
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;
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;
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_MAXPROPLEN];
+ 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;
}
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;
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;
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;
/*
* 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/.
*/
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",
return EINVAL;
}
+ ret = zfs_check_hostid(mop);
+ if (ret != 0)
+ goto out;
+
pool = strdup(ds);
if (pool == NULL)
return ENOMEM;
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 */
/*
* 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);
return ret;
}
-int zfs_prepare_lustre(struct mkfs_opts *mop,
- char *default_mountopts, int default_len,
- char *always_mountopts, int always_len)
+int zfs_enable_quota(struct mkfs_opts *mop)
{
- int ret;
+ fprintf(stderr, "this option is not only valid for zfs\n");
+ return ENOSYS;
+}
+int zfs_prepare_lustre(struct mkfs_opts *mop,
+ char *wanted_mountopts, size_t len)
+{
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;
+
+ return 0;
+}
- /* 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 */
+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;
+ /* Try to load zfs.ko and retry libzfs_init() */
+
+ ret = system("/sbin/modprobe -q zfs");
+
+ if (ret == 0) {
+ g_zfs = libzfs_init();
+ if (g_zfs == NULL)
+ ret = EINVAL;
+ }
}
-out:
- osd_zfs_setup = 1;
- if (ret)
- zfs_fini();
+
+ if (ret == 0)
+ osd_zfs_setup = 1;
+
+ else
+ fprintf(stderr, "Failed to initialize ZFS library: %d\n", ret);
+
return ret;
}
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;
}