We discussed this on the phone call earlier this year; nothing really came of it, as far as I can tell (I asked on Slack as well). I have a use for having per-dataset properties that will be used by the system, so I unilaterally decided on a user property format of ${ORGANIZATION}.system:${property}. As an example, org.freebsd.system:mount. (E.g., "zfs create -o mountdir=/path -o org.freebsd.system:mount=nocover Test/mount_test".)
I’m attaching some diffs below, but they’re REALLY NOT GREAT, they’re just an attempt to see if it would work. Please let me know any feedback for how this concept can be improved. Sean. ------------------------------------------ openzfs: openzfs-developer Permalink: https://openzfs.topicbox.com/groups/developer/T8fe2995beab65b3c-M1e1140bae1df502ea4e95ebb Delivery options: https://openzfs.topicbox.com/groups/developer/subscription
diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c index bb5a2a94ccc..518e3f667a5 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c @@ -549,6 +549,7 @@ parseprop(nvlist_t *props, char *propname) "specified multiple times\n"), propname); return (-1); } + fprintf(stderr, "nvlist_add_string(%p, %s, %s)\n", props, propname, propval); if (nvlist_add_string(props, propname, propval) != 0) nomem(); return (0); @@ -6926,6 +6927,36 @@ manual_mount(int argc, char **argv) /* check for legacy mountpoint and complain appropriately */ ret = 0; if (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) { +#ifdef __FreeBSD__ + nvlist_t *user_props; + char *mount_options; + const static char *prop_name = "org.freebsd.system:mount"; + user_props = zfs_get_user_props(zhp); + if (user_props != NULL) { + size_t nitems; + char *prop_name = "org.freebsd.system:mount"; + if (nvlist_exists(user_props, prop_name)) { + char mntopts_tmp[MNT_LINE_MAX]; + nvlist_t *opts_nvlist = NULL; + + opts_nvlist = fnvlist_lookup_nvlist(user_props, prop_name); + mount_options = fnvlist_lookup_string(opts_nvlist, "value"); + if (mount_options && + mount_options[0] != '\0') { + strlcpy(mntopts_tmp, + mount_options, MNT_LINE_MAX); + if (mntopts[0] != '\0') { + strlcat(mntopts_tmp, + ",", MNT_LINE_MAX); + strlcat(mntopts_tmp, + mntopts, + MNT_LINE_MAX); + } + strcpy(mntopts, mntopts_tmp); + } + } + } +#endif if (zmount(dataset, path, flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { (void) fprintf(stderr, gettext("mount failed: %s\n"), diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c index 0efeba631af..822f97ca1a2 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c @@ -387,6 +387,44 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } #endif +#ifdef __FreeBSD__ + /* + * Get the user property org.freebsd.system:mount + * Append it to mntopts + */ + nvlist_t *user_props; + char *mount_options = NULL; + + user_props = zfs_get_user_props(zhp); + if (user_props != NULL) { + const static char *prop_name = "org.freebsd.system:mount"; + if (nvlist_exists(user_props, prop_name) == B_TRUE) { + char mntopts_tmp[MNT_LINE_MAX]; + nvlist_t *opts_nvlist = NULL; + + /* + * Bad things will happen if the prop exists, + * but isn't an nvlist, and doesn't have the + * key "value". + */ + opts_nvlist = fnvlist_lookup_nvlist(user_props, prop_name); + mount_options = fnvlist_lookup_string(opts_nvlist, "value"); + if (mount_options != NULL && + mount_options[0] != '\0') { + strlcpy(mntopts_tmp, + mount_options, MNT_LINE_MAX); + if (mntopts[0] != '\0') { + strlcat(mntopts_tmp, + ",", MNT_LINE_MAX); + strlcat(mntopts_tmp, + mntopts, + MNT_LINE_MAX); + } + strcpy(mntopts, mntopts_tmp); + } + } + } +#endif /* __FreeBSD__ */ /* perform the mount */ if (zmount(zfs_get_name(zhp), mountpoint, flags,