X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Flibmount_utils_zfs.c;h=9e468ada0ae4b4d4eecff9685e3d49cd81ff9dde;hb=56b4b112a497661de8dbf5a851c7a045d470deff;hp=920682c30dd912b1964cf28b84444bb6632d6e58;hpb=d6f57eda898cc80a1cff49ad3875021749563dbf;p=fs%2Flustre-release.git diff --git a/lustre/utils/libmount_utils_zfs.c b/lustre/utils/libmount_utils_zfs.c index 920682c..9e468ad 100644 --- a/lustre/utils/libmount_utils_zfs.c +++ b/lustre/utils/libmount_utils_zfs.c @@ -20,19 +20,23 @@ * GPL HEADER END */ /* - * Copyright (c) 2012, 2016, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. * Use is subject to license terms. */ /* * Author: Brian Behlendorf */ +#ifndef HAVE_ZFS_MULTIHOST +#include +#define list_move_tail(a, b) spl_list_move_tail(a, b) +#include +#endif #include "mount_utils.h" #include #include #include #include - -#define HOSTID_PATH "/etc/hostid" +#include /* Persistent mount data is stored in these user attributes */ #define LDD_PREFIX "lustre:" @@ -188,6 +192,114 @@ static int zfs_erase_allprops(zfs_handle_t *zhp) return 0; } +/* + * ZFS on linux 0.7.0-rc5 commit 379ca9cf2beba802f096273e89e30914a2d6bafc + * Multi-modifier protection (MMP) + * + * Introduced spa_get_hostid() along with a few constants like + * ZPOOL_CONFIG_MMP_HOSTID that can be checked to imply availablity of + * spa_get_hostid. Supply a fallback when spa_get_hostid is not + * available. + * + * This can be removed when zfs 0.6.x support is dropped. + */ +#if !defined(ZPOOL_CONFIG_MMP_HOSTID) && !defined(HAVE_ZFS_MULTIHOST) +unsigned long _hostid_from_proc(void) +{ + FILE *f; + unsigned long hostid; + int rc; + + f = fopen("/proc/sys/kernel/spl/hostid", "r"); + if (f == NULL) + goto out; + + rc = fscanf(f, "%lx", &hostid); + fclose(f); + if (rc == 1) + return hostid; +out: + return 0; +} + +unsigned long _hostid_from_module_param(void) +{ + FILE *f; + unsigned long hostid; + int rc; + + f = fopen("/sys/module/spl/parameters/spl_hostid", "r"); + if (f == NULL) + goto out; + + rc = fscanf(f, "%li", &hostid); + fclose(f); + if (rc == 1) + return hostid; +out: + return 0; +} + +unsigned long _from_module_param_indirect(void) +{ + FILE *f; + unsigned long hostid = 0; + uint32_t hwid; + int rc; + char *spl_hostid_path = NULL; + + /* read the module parameter for HW_HOSTID_PATH */ + f = fopen("/sys/module/spl/parameters/spl_hostid_path", "r"); + if (f == NULL) { + fatal(); + fprintf(stderr, "Failed to open spl_hostid_path param: %s\n", + strerror(errno)); + goto out; + } + + rc = fscanf(f, "%ms%*[\n]", &spl_hostid_path); + fclose(f); + if (rc == 0 || !spl_hostid_path) + goto out; + + /* read the hostid from the file */ + f = fopen(spl_hostid_path, "r"); + if (f == NULL) { + fatal(); + fprintf(stderr, "Failed to open %s param: %s\n", + spl_hostid_path, strerror(errno)); + goto out; + } + + /* hostid is the first 4 bytes in native endian order */ + rc = fread(&hwid, sizeof(uint32_t), 1, f); + fclose(f); + if (rc == 1) + hostid = (unsigned long)hwid; + +out: + if (spl_hostid_path) + free(spl_hostid_path); + + return hostid; +} + +unsigned long spa_get_hostid(void) +{ + unsigned long hostid; + + hostid = _hostid_from_proc(); + if (hostid) + return hostid; + + /* if /proc isn't available, try /sys */ + hostid = _hostid_from_module_param(); + if (hostid) + return hostid; + + return _from_module_param_indirect(); +} +#endif /* * Map '= ...' pairs in the passed string to dataset properties @@ -237,45 +349,16 @@ static int zfs_set_prop_params(zfs_handle_t *zhp, char *params) 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: +#ifdef HAVE_ZFS_MULTIHOST + hostid = get_system_hostid(); +#else + hostid = spa_get_hostid(); +#endif if (hostid == 0) { if (mop->mo_flags & MO_NOHOSTID_CHECK) { fprintf(stderr, "WARNING: spl_hostid not set. ZFS has " @@ -477,8 +560,22 @@ int zfs_read_ldd(char *ds, struct lustre_disk_data *ldd) ldd->ldd_mount_type = LDD_MT_ZFS; ret = 0; + +#ifdef HAVE_ZFS_MULTIHOST + if (strstr(ldd->ldd_params, PARAM_FAILNODE) != NULL) { + zpool_handle_t *pool = zfs_get_pool_handle(zhp); + uint64_t mh = zpool_get_prop_int(pool, ZPOOL_PROP_MULTIHOST, + NULL); + if (!mh) + fprintf(stderr, "%s: %s is configured for failover " + "but zpool does not have multihost enabled\n", + progname, ds); + } +#endif + out_close: zfs_close(zhp); + out: return ret; } @@ -543,6 +640,9 @@ static char *zfs_mkfs_opts(struct mkfs_opts *mop, char *str, int len) if (strlen(mop->mo_mkfsopts) != 0) snprintf(str, len, " -o %s", mop->mo_mkfsopts); + if (mop->mo_device_kb) + snprintf(str, len, " -o quota=%llu", + (unsigned long long)mop->mo_device_kb * 1024); return str; } @@ -667,6 +767,7 @@ int zfs_make_lustre(struct mkfs_opts *mop) php = zpool_open(g_zfs, pool); if (php) { pool_exists = 1; + zpool_set_prop(php, "canmount", "off"); zpool_close(php); } @@ -701,27 +802,30 @@ int zfs_make_lustre(struct mkfs_opts *mop) /* * Set Options on ZPOOL * - * ALL - canmount=off + * ALL - canmount=off (set above) * 0.7.0 - multihost=on + * 0.7.0 - feature@userobj_accounting=enabled */ +#if defined(HAVE_ZFS_MULTIHOST) || defined(HAVE_DMU_USEROBJ_ACCOUNTING) php = zpool_open(g_zfs, pool); if (php) { - if (pool_exists) - zpool_set_prop(php, "canmount", "off"); - +#ifdef HAVE_ZFS_MULTIHOST zpool_set_prop(php, "multihost", "on"); - +#endif +#ifdef HAVE_DMU_USEROBJ_ACCOUNTING + zpool_set_prop(php, "feature@userobj_accounting", "enabled"); +#endif zpool_close(php); } +#endif /* * Create the ZFS filesystem with any required mkfs options: * - canmount=off is set to prevent zfs automounting - * - 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 create -o canmount=off %s %s", zfs_mkfs_opts(mop, mkfs_tmp, PATH_MAX), ds); vprint("mkfs_cmd = %s\n", mkfs_cmd); @@ -733,6 +837,42 @@ int zfs_make_lustre(struct mkfs_opts *mop) goto out; } + /* + * Attempt to set dataset properties to reasonable defaults + * to optimize performance, unless the values were specified + * at the mkfs command line. Some ZFS pools or ZFS versions + * do not support these properties. We can safely ignore the + * errors and continue in those cases. + * + * zfs 0.6.1 - system attribute based xattrs + * zfs 0.6.5 - large block support + * zfs 0.7.0 - large dnode support + * + * Check if zhp is NULL as a defensive measure. Any dataset + * validation errors that would cause zfs_open() to fail + * should have been caught earlier. + */ + zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM); + if (zhp) { + /* zfs 0.6.1 - system attribute based xattrs */ + if (!strstr(mop->mo_mkfsopts, "xattr=")) + zfs_set_prop_str(zhp, "xattr", "sa"); + + /* zfs 0.7.0 - large dnode support */ + if (!strstr(mop->mo_mkfsopts, "dnodesize=") && + !strstr(mop->mo_mkfsopts, "dnsize=")) + zfs_set_prop_str(zhp, "dnodesize", "auto"); + + if (IS_OST(&mop->mo_ldd)) { + /* zfs 0.6.5 - large block support */ + if (!strstr(mop->mo_mkfsopts, "recordsize=") && + !strstr(mop->mo_mkfsopts, "recsize=")) + zfs_set_prop_str(zhp, "recordsize", "1M"); + } + + zfs_close(zhp); + } + out: if (pool != NULL) free(pool);