X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fmount_utils_zfs.c;h=cdb45cb1d260bff1b19c0fed360b1df4bb19985c;hb=2c6232e35297fc12a80f2ab27fd374a46728050d;hp=b337c77fe7a031479c6669004a8111d983c62ced;hpb=b5aaf716806e37cc5a94821e024e076fb1f12f1e;p=fs%2Flustre-release.git diff --git a/lustre/utils/mount_utils_zfs.c b/lustre/utils/mount_utils_zfs.c index b337c77..cdb45cb 100644 --- a/lustre/utils/mount_utils_zfs.c +++ b/lustre/utils/mount_utils_zfs.c @@ -20,18 +20,19 @@ * GPL HEADER END */ /* - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2014, Intel Corporation. * Use is subject to license terms. - * */ /* * Author: Brian Behlendorf */ #include "mount_utils.h" +#include #include #include #include -#include + +#define HOSTID_PATH "/etc/hostid" /* Persistent mount data is stored in these user attributes */ #define LDD_PREFIX "lustre:" @@ -104,84 +105,8 @@ 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 **); - nvpair_t * (*nvlist_next_nvpair)(nvlist_t *, nvpair_t *); - char * (*nvpair_name)(nvpair_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) - DLSYM(handle_nvpair, nvlist_next_nvpair); -#define nvlist_next_nvpair (*sym.nvlist_next_nvpair) - DLSYM(handle_nvpair, nvpair_name); -#define nvpair_name (*sym.nvpair_name) - - 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, void *val) { char str[64]; @@ -219,7 +144,7 @@ static int zfs_set_prop_params(zfs_handle_t *zhp, char *params) { char *params_dup, *token, *key, *value; char *save_token = NULL; - char prop_name[ZFS_MAXNAMELEN]; + char prop_name[ZFS_MAXPROPLEN]; int ret = 0; params_dup = strdup(params); @@ -251,6 +176,62 @@ static int zfs_set_prop_params(zfs_handle_t *zhp, char *params) 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) { @@ -272,7 +253,7 @@ int zfs_write_ldd(struct mkfs_opts *mop) 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) { @@ -280,6 +261,10 @@ int zfs_write_ldd(struct mkfs_opts *mop) goto out; } + ret = zfs_check_hostid(mop); + if (ret != 0) + goto out; + vprint("Writing %s properties\n", ds); for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++) { @@ -354,7 +339,7 @@ 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 key[ZFS_MAXPROPLEN]; char *value; int ret = 0; @@ -471,7 +456,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/. */ @@ -488,14 +473,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", @@ -528,6 +513,10 @@ int zfs_make_lustre(struct mkfs_opts *mop) return EINVAL; } + ret = zfs_check_hostid(mop); + if (ret != 0) + goto out; + pool = strdup(ds); if (pool == NULL) return ENOMEM; @@ -605,13 +594,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); @@ -635,9 +623,14 @@ 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) + char *wanted_mountopts, size_t len) { if (osd_check_zfs_setup() == 0) return EINVAL; @@ -688,39 +681,25 @@ int zfs_init(void) { int ret = 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 */ + g_zfs = libzfs_init(); + if (g_zfs == NULL) { + /* Try to load zfs.ko and retry libzfs_init() */ - handle_libzfs = dlopen("libzfs.so.1", RTLD_LAZY); - if (handle_libzfs == NULL) - return EINVAL; + ret = system("/sbin/modprobe -q zfs"); - handle_nvpair = dlopen("libnvpair.so.1", RTLD_LAZY); - if (handle_nvpair == NULL) { - ret = EINVAL; - goto out; + if (ret == 0) { + g_zfs = libzfs_init(); + if (g_zfs == NULL) + ret = EINVAL; + } } - ret = zfs_populate_symbols(); - if (ret) - goto out; + if (ret == 0) + osd_zfs_setup = 1; - if (libzfs_load_module("zfs") != 0) { - /* The ZFS modules are not installed */ - ret = EINVAL; - goto out; - } + else + fprintf(stderr, "Failed to initialize ZFS library: %d\n", ret); - g_zfs = libzfs_init(); - if (g_zfs == NULL) { - fprintf(stderr, "Failed to initialize ZFS library\n"); - ret = EINVAL; - } -out: - osd_zfs_setup = 1; - if (ret) - zfs_fini(); return ret; } @@ -730,14 +709,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; }