* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2016, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
* Use is subject to license terms.
*/
/*
#include <stdio.h>
#include <string.h>
#include <libzfs.h>
-
-#define HOSTID_PATH "/etc/hostid"
+#include <sys/systeminfo.h>
/* Persistent mount data is stored in these user attributes */
#define LDD_PREFIX "lustre:"
return zfs_remove_prop(zhp, nvl, propname);
}
+static int zfs_is_special_ldd_prop_param(char *name)
+{
+ int i;
+
+ 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;
+
+ return 0;
+}
+
static int zfs_erase_allprops(zfs_handle_t *zhp)
{
- nvlist_t *nvl;
- nvpair_t *curr = NULL;
+ nvlist_t *props;
+ nvpair_t *nvp;
+ size_t str_size = 1024 * 1024;
+ char *strs, *cur;
+ int rc = 0;
- nvl = zfs_get_user_props(zhp);
- if (!nvl)
+ strs = malloc(str_size);
+ if (!strs)
+ return ENOMEM;
+ cur = strs;
+
+ props = zfs_get_user_props(zhp);
+ if (props == NULL) {
+ free(strs);
return ENOENT;
+ }
+ nvp = NULL;
+ while (nvp = nvlist_next_nvpair(props, nvp), nvp) {
+ if (strncmp(nvpair_name(nvp), LDD_PREFIX, strlen(LDD_PREFIX)))
+ continue;
- curr = nvlist_next_nvpair(nvl, curr);
- while (curr) {
- nvpair_t *next = nvlist_next_nvpair(nvl, curr);
+ if (zfs_is_special_ldd_prop_param(nvpair_name(nvp)))
+ continue;
- zfs_remove_prop(zhp, nvl, nvpair_name(curr));
- curr = next;
+ rc = snprintf(cur, str_size - (cur - strs), "%s",
+ nvpair_name(nvp));
+ if (rc != strlen(nvpair_name(nvp))) {
+ fprintf(stderr, "%s: zfs has too many properties to erase, please repeat\n",
+ progname);
+ rc = EINVAL;
+ break;
+ }
+ cur += strlen(cur) + 1;
+ }
+ cur = strs;
+ while ( cur < (strs + str_size) && strlen(cur) > 0) {
+ zfs_prop_inherit(zhp, cur, false);
+ cur += strlen(cur) + 1;
}
- return 0;
+ free(strs);
+ return rc;
}
/*
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:
+ hostid = get_system_hostid();
if (hostid == 0) {
if (mop->mo_flags & MO_NOHOSTID_CHECK) {
fprintf(stderr, "WARNING: spl_hostid not set. ZFS has "
return ret;
}
-static int zfs_is_special_ldd_prop_param(char *name)
-{
- int i;
-
- 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;
-
- return 0;
-}
-
static int zfs_get_prop_params(zfs_handle_t *zhp, char *param)
{
nvlist_t *props;
ldd->ldd_mount_type = LDD_MT_ZFS;
ret = 0;
+
+ 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);
+ }
+
out_close:
zfs_close(zhp);
+
out:
return ret;
}
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;
}
php = zpool_open(g_zfs, pool);
if (php) {
pool_exists = 1;
+ zpool_set_prop(php, "canmount", "off");
zpool_close(php);
}
/*
* Set Options on ZPOOL
*
- * ALL - canmount=off
+ * ALL - canmount=off (set above)
* 0.7.0 - multihost=on
+ * 0.7.0 - feature@userobj_accounting=enabled
*/
php = zpool_open(g_zfs, pool);
if (php) {
- if (pool_exists)
- zpool_set_prop(php, "canmount", "off");
-
zpool_set_prop(php, "multihost", "on");
-
+ zpool_set_prop(php, "feature@userobj_accounting", "enabled");
zpool_close(php);
}
/*
* 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);
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);