/*
* Author: Brian Behlendorf <behlendorf1@llnl.gov>
*/
-#ifndef HAVE_ZFS_MULTIHOST
-#include <sys/list.h>
-#define list_move_tail(a, b) spl_list_move_tail(a, b)
-#include <sys/spa.h>
-#endif
#include "mount_utils.h"
#include <stddef.h>
#include <stdio.h>
int zlpb_ldd_offset;
/* Function pointer responsible for reading in the @prop
* property from @zhp and storing it in @ldd_field */
+#ifdef HAVE_ZFS_NVLIST_CONST_INTERFACES
+ int (*zlpb_get_prop_fn)(zfs_handle_t *zhp, const char *prop,
+ void *ldd_field);
+#else
int (*zlpb_get_prop_fn)(zfs_handle_t *zhp, char *prop, void *ldd_field);
+#endif
/* 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);
};
/* Forward declarations needed to initialize the ldd prop bridge list */
+#ifdef HAVE_ZFS_NVLIST_CONST_INTERFACES
+static int zfs_get_prop_int(zfs_handle_t *, const char *, void *);
+static int zfs_get_prop_str(zfs_handle_t *, const char *, void *);
+#else
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 *);
+#endif
+static int zfs_set_prop_int(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.
return zfs_remove_prop(zhp, nvl, propname);
}
-static int zfs_erase_allprops(zfs_handle_t *zhp)
-{
- nvlist_t *nvl;
- nvpair_t *curr = NULL;
-
- nvl = zfs_get_user_props(zhp);
- if (!nvl)
- return ENOENT;
-
- curr = nvlist_next_nvpair(nvl, curr);
- while (curr) {
- nvpair_t *next = nvlist_next_nvpair(nvl, curr);
-
- zfs_remove_prop(zhp, nvl, nvpair_name(curr));
- curr = next;
- }
-
- 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)
+#ifdef HAVE_ZFS_NVLIST_CONST_INTERFACES
+static int zfs_is_special_ldd_prop_param(const char *name)
+#else
+static int zfs_is_special_ldd_prop_param(char *name)
+#endif
{
- FILE *f;
- unsigned long hostid;
- int rc;
+ int i;
- f = fopen("/proc/sys/kernel/spl/hostid", "r");
- if (f == NULL)
- goto out;
+ 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;
- rc = fscanf(f, "%lx", &hostid);
- fclose(f);
- if (rc == 1)
- return hostid;
-out:
return 0;
}
-unsigned long _hostid_from_module_param(void)
+static int zfs_erase_allprops(zfs_handle_t *zhp)
{
- FILE *f;
- unsigned long hostid;
- int rc;
-
- f = fopen("/sys/module/spl/parameters/spl_hostid", "r");
- if (f == NULL)
- goto out;
+ nvlist_t *props;
+ nvpair_t *nvp;
+ size_t str_size = 1024 * 1024;
+ char *strs, *cur;
+ int rc = 0;
- rc = fscanf(f, "%li", &hostid);
- fclose(f);
- if (rc == 1)
- return hostid;
-out:
- return 0;
-}
+ strs = malloc(str_size);
+ if (!strs)
+ return ENOMEM;
+ cur = strs;
-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;
+ 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;
- rc = fscanf(f, "%ms%*[\n]", &spl_hostid_path);
- fclose(f);
- if (rc == 0 || !spl_hostid_path)
- goto out;
+ if (zfs_is_special_ldd_prop_param(nvpair_name(nvp)))
+ continue;
- /* 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;
+ 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;
}
- /* 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();
+ free(strs);
+ return rc;
}
-#endif
/*
* Map '<key>=<value> ...' pairs in the passed string to dataset properties
if (strstr(mop->mo_ldd.ldd_params, PARAM_FAILNODE) == NULL)
return 0;
-#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 "
vprint("Writing %s properties\n", ds);
- if (mop->mo_flags & MO_ERASE_ALL)
+ if (mop->mo_flags & MO_ERASE_ALL) {
ret = zfs_erase_allprops(zhp);
+ if (ret < 0) {
+ fprintf(stderr, "zfs_erase_allprops Failed: %d\n", ret);
+ goto out_close;
+ }
+ }
ret = zfs_set_prop_params(zhp, ldd->ldd_params);
for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++) {
return add_param(mop->mo_ldd.ldd_params, key, "");
}
+#ifdef HAVE_ZFS_NVLIST_CONST_INTERFACES
+static int zfs_get_prop_int(zfs_handle_t *zhp, const char *prop, void *val)
+{
+ const char *propstr;
+#else
static int zfs_get_prop_int(zfs_handle_t *zhp, char *prop, void *val)
{
- nvlist_t *propval;
char *propstr;
+#endif
+ nvlist_t *propval;
int ret;
ret = nvlist_lookup_nvlist(zfs_get_user_props(zhp), prop, &propval);
return ret;
}
+#ifdef HAVE_ZFS_NVLIST_CONST_INTERFACES
+static int zfs_get_prop_str(zfs_handle_t *zhp, const char *prop, void *val)
+{
+ const char *propstr;
+#else
static int zfs_get_prop_str(zfs_handle_t *zhp, char *prop, void *val)
{
- nvlist_t *propval;
char *propstr;
+#endif
+ nvlist_t *propval;
int ret;
ret = nvlist_lookup_nvlist(zfs_get_user_props(zhp), prop, &propval);
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;
-#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,
"but zpool does not have multihost enabled\n",
progname, ds);
}
-#endif
out_close:
zfs_close(zhp);
snprintf(str, len, " -o %s", mop->mo_mkfsopts);
if (mop->mo_device_kb)
snprintf(str, len, " -o quota=%llu",
- mop->mo_device_kb * 1024);
+ (unsigned long long)mop->mo_device_kb * 1024);
return str;
}
* 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) {
-#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: