3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright (c) 2014, 2017 by Delphix. All rights reserved.
26 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
27 * Copyright 2017 Joyent, Inc.
28 * Copyright 2017 RackTop Systems.
29 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
30 */
31
32 /*
33 * Routines to manage ZFS mounts. We separate all the nasty routines that have
34 * to deal with the OS. The following functions are the main entry points --
35 * they are used by mount and unmount and when changing a filesystem's
36 * mountpoint.
37 *
38 * zfs_is_mounted()
39 * zfs_mount()
40 * zfs_unmount()
41 * zfs_unmountall()
42 *
43 * This file also contains the functions used to manage sharing filesystems via
44 * NFS and iSCSI:
45 *
604 PROTO_SMB) != SHARED_NOT_SHARED);
605 }
606
607 /*
608 * Make sure things will work if libshare isn't installed by using
609 * wrapper functions that check to see that the pointers to functions
610 * initialized in _zfs_init_libshare() are actually present.
611 */
612
613 static sa_handle_t (*_sa_init)(int);
614 static sa_handle_t (*_sa_init_arg)(int, void *);
615 static int (*_sa_service)(sa_handle_t);
616 static void (*_sa_fini)(sa_handle_t);
617 static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
618 static int (*_sa_enable_share)(sa_share_t, char *);
619 static int (*_sa_disable_share)(sa_share_t, char *);
620 static char *(*_sa_errorstr)(int);
621 static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
622 static boolean_t (*_sa_needs_refresh)(sa_handle_t *);
623 static libzfs_handle_t *(*_sa_get_zfs_handle)(sa_handle_t);
624 static int (*_sa_zfs_process_share)(sa_handle_t, sa_group_t, sa_share_t,
625 char *, char *, zprop_source_t, char *, char *, char *);
626 static void (*_sa_update_sharetab_ts)(sa_handle_t);
627
628 /*
629 * _zfs_init_libshare()
630 *
631 * Find the libshare.so.1 entry points that we use here and save the
632 * values to be used later. This is triggered by the runtime loader.
633 * Make sure the correct ISA version is loaded.
634 */
635
636 #pragma init(_zfs_init_libshare)
637 static void
638 _zfs_init_libshare(void)
639 {
640 void *libshare;
641 char path[MAXPATHLEN];
642 char isa[MAXISALEN];
643
644 #if defined(_LP64)
645 if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
653 if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
654 _sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
655 _sa_init_arg = (sa_handle_t (*)(int, void *))dlsym(libshare,
656 "sa_init_arg");
657 _sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
658 _sa_service = (int (*)(sa_handle_t))dlsym(libshare,
659 "sa_service");
660 _sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
661 dlsym(libshare, "sa_find_share");
662 _sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
663 "sa_enable_share");
664 _sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
665 "sa_disable_share");
666 _sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
667 _sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
668 dlsym(libshare, "sa_parse_legacy_options");
669 _sa_needs_refresh = (boolean_t (*)(sa_handle_t *))
670 dlsym(libshare, "sa_needs_refresh");
671 _sa_get_zfs_handle = (libzfs_handle_t *(*)(sa_handle_t))
672 dlsym(libshare, "sa_get_zfs_handle");
673 _sa_zfs_process_share = (int (*)(sa_handle_t, sa_group_t,
674 sa_share_t, char *, char *, zprop_source_t, char *,
675 char *, char *))dlsym(libshare, "sa_zfs_process_share");
676 _sa_update_sharetab_ts = (void (*)(sa_handle_t))
677 dlsym(libshare, "sa_update_sharetab_ts");
678 if (_sa_init == NULL || _sa_init_arg == NULL ||
679 _sa_fini == NULL || _sa_find_share == NULL ||
680 _sa_enable_share == NULL || _sa_disable_share == NULL ||
681 _sa_errorstr == NULL || _sa_parse_legacy_options == NULL ||
682 _sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
683 _sa_zfs_process_share == NULL || _sa_service == NULL ||
684 _sa_update_sharetab_ts == NULL) {
685 _sa_init = NULL;
686 _sa_init_arg = NULL;
687 _sa_service = NULL;
688 _sa_fini = NULL;
689 _sa_disable_share = NULL;
690 _sa_enable_share = NULL;
691 _sa_errorstr = NULL;
692 _sa_parse_legacy_options = NULL;
693 (void) dlclose(libshare);
694 _sa_needs_refresh = NULL;
695 _sa_get_zfs_handle = NULL;
696 _sa_zfs_process_share = NULL;
697 _sa_update_sharetab_ts = NULL;
698 }
699 }
700 }
701
702 /*
703 * zfs_init_libshare(zhandle, service)
704 *
705 * Initialize the libshare API if it hasn't already been initialized.
706 * In all cases it returns 0 if it succeeded and an error if not. The
707 * service value is which part(s) of the API to initialize and is a
708 * direct map to the libshare sa_init(service) interface.
709 */
710 static int
711 zfs_init_libshare_impl(libzfs_handle_t *zhandle, int service, void *arg)
712 {
713 /*
714 * libshare is either not installed or we're in a branded zone. The
715 * rest of the wrapper functions around the libshare calls already
716 * handle NULL function pointers, but we don't want the callers of
863 }
864
865 for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
866 /*
867 * Return success if there are no share options.
868 */
869 if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
870 shareopts, sizeof (shareopts), &sourcetype, sourcestr,
871 ZFS_MAXPROPLEN, B_FALSE) != 0 ||
872 strcmp(shareopts, "off") == 0)
873 continue;
874 ret = zfs_init_libshare_arg(hdl, service, zhp);
875 if (ret != SA_OK) {
876 (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
877 dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
878 zfs_get_name(zhp), _sa_errorstr != NULL ?
879 _sa_errorstr(ret) : "");
880 return (-1);
881 }
882
883 /*
884 * If the 'zoned' property is set, then zfs_is_mountable()
885 * will have already bailed out if we are in the global zone.
886 * But local zones cannot be NFS servers, so we ignore it for
887 * local zones as well.
888 */
889 if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
890 continue;
891
892 share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
893 if (share == NULL) {
894 /*
895 * This may be a new file system that was just
896 * created so isn't in the internal cache
897 * (second time through). Rather than
898 * reloading the entire configuration, we can
899 * assume ZFS has done the checking and it is
900 * safe to add this to the internal
901 * configuration.
902 */
903 if (_sa_zfs_process_share(hdl->libzfs_sharehdl,
904 NULL, NULL, mountpoint,
905 proto_table[*curr_proto].p_name, sourcetype,
906 shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
907 (void) zfs_error_fmt(hdl,
908 proto_table[*curr_proto].p_share_err,
909 dgettext(TEXT_DOMAIN, "cannot share '%s'"),
910 zfs_get_name(zhp));
911 return (-1);
912 }
913 share = zfs_sa_find_share(hdl->libzfs_sharehdl,
914 mountpoint);
915 }
916 if (share != NULL) {
917 int err;
918 err = zfs_sa_enable_share(share,
919 proto_table[*curr_proto].p_name);
920 if (err != SA_OK) {
921 (void) zfs_error_fmt(hdl,
922 proto_table[*curr_proto].p_share_err,
923 dgettext(TEXT_DOMAIN, "cannot share '%s'"),
924 zfs_get_name(zhp));
925 return (-1);
926 }
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * Copyright 2019 Nexenta Systems, Inc.
28 * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
29 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
30 * Copyright 2017 Joyent, Inc.
31 * Copyright 2017 RackTop Systems.
32 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
33 */
34
35 /*
36 * Routines to manage ZFS mounts. We separate all the nasty routines that have
37 * to deal with the OS. The following functions are the main entry points --
38 * they are used by mount and unmount and when changing a filesystem's
39 * mountpoint.
40 *
41 * zfs_is_mounted()
42 * zfs_mount()
43 * zfs_unmount()
44 * zfs_unmountall()
45 *
46 * This file also contains the functions used to manage sharing filesystems via
47 * NFS and iSCSI:
48 *
607 PROTO_SMB) != SHARED_NOT_SHARED);
608 }
609
610 /*
611 * Make sure things will work if libshare isn't installed by using
612 * wrapper functions that check to see that the pointers to functions
613 * initialized in _zfs_init_libshare() are actually present.
614 */
615
616 static sa_handle_t (*_sa_init)(int);
617 static sa_handle_t (*_sa_init_arg)(int, void *);
618 static int (*_sa_service)(sa_handle_t);
619 static void (*_sa_fini)(sa_handle_t);
620 static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
621 static int (*_sa_enable_share)(sa_share_t, char *);
622 static int (*_sa_disable_share)(sa_share_t, char *);
623 static char *(*_sa_errorstr)(int);
624 static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
625 static boolean_t (*_sa_needs_refresh)(sa_handle_t *);
626 static libzfs_handle_t *(*_sa_get_zfs_handle)(sa_handle_t);
627 static int (* _sa_get_zfs_share)(sa_handle_t, char *, zfs_handle_t *);
628 static void (*_sa_update_sharetab_ts)(sa_handle_t);
629
630 /*
631 * _zfs_init_libshare()
632 *
633 * Find the libshare.so.1 entry points that we use here and save the
634 * values to be used later. This is triggered by the runtime loader.
635 * Make sure the correct ISA version is loaded.
636 */
637
638 #pragma init(_zfs_init_libshare)
639 static void
640 _zfs_init_libshare(void)
641 {
642 void *libshare;
643 char path[MAXPATHLEN];
644 char isa[MAXISALEN];
645
646 #if defined(_LP64)
647 if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
655 if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
656 _sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
657 _sa_init_arg = (sa_handle_t (*)(int, void *))dlsym(libshare,
658 "sa_init_arg");
659 _sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
660 _sa_service = (int (*)(sa_handle_t))dlsym(libshare,
661 "sa_service");
662 _sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
663 dlsym(libshare, "sa_find_share");
664 _sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
665 "sa_enable_share");
666 _sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
667 "sa_disable_share");
668 _sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
669 _sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
670 dlsym(libshare, "sa_parse_legacy_options");
671 _sa_needs_refresh = (boolean_t (*)(sa_handle_t *))
672 dlsym(libshare, "sa_needs_refresh");
673 _sa_get_zfs_handle = (libzfs_handle_t *(*)(sa_handle_t))
674 dlsym(libshare, "sa_get_zfs_handle");
675 _sa_get_zfs_share = (int (*)(sa_handle_t, char *,
676 zfs_handle_t *)) dlsym(libshare, "sa_get_zfs_share");
677 _sa_update_sharetab_ts = (void (*)(sa_handle_t))
678 dlsym(libshare, "sa_update_sharetab_ts");
679 if (_sa_init == NULL || _sa_init_arg == NULL ||
680 _sa_fini == NULL || _sa_find_share == NULL ||
681 _sa_enable_share == NULL || _sa_disable_share == NULL ||
682 _sa_errorstr == NULL || _sa_parse_legacy_options == NULL ||
683 _sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
684 _sa_get_zfs_share == NULL || _sa_service == NULL ||
685 _sa_update_sharetab_ts == NULL) {
686 _sa_init = NULL;
687 _sa_init_arg = NULL;
688 _sa_service = NULL;
689 _sa_fini = NULL;
690 _sa_disable_share = NULL;
691 _sa_enable_share = NULL;
692 _sa_errorstr = NULL;
693 _sa_parse_legacy_options = NULL;
694 (void) dlclose(libshare);
695 _sa_needs_refresh = NULL;
696 _sa_get_zfs_handle = NULL;
697 _sa_get_zfs_share = NULL;
698 _sa_update_sharetab_ts = NULL;
699 }
700 }
701 }
702
703 /*
704 * zfs_init_libshare(zhandle, service)
705 *
706 * Initialize the libshare API if it hasn't already been initialized.
707 * In all cases it returns 0 if it succeeded and an error if not. The
708 * service value is which part(s) of the API to initialize and is a
709 * direct map to the libshare sa_init(service) interface.
710 */
711 static int
712 zfs_init_libshare_impl(libzfs_handle_t *zhandle, int service, void *arg)
713 {
714 /*
715 * libshare is either not installed or we're in a branded zone. The
716 * rest of the wrapper functions around the libshare calls already
717 * handle NULL function pointers, but we don't want the callers of
864 }
865
866 for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
867 /*
868 * Return success if there are no share options.
869 */
870 if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
871 shareopts, sizeof (shareopts), &sourcetype, sourcestr,
872 ZFS_MAXPROPLEN, B_FALSE) != 0 ||
873 strcmp(shareopts, "off") == 0)
874 continue;
875 ret = zfs_init_libshare_arg(hdl, service, zhp);
876 if (ret != SA_OK) {
877 (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
878 dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
879 zfs_get_name(zhp), _sa_errorstr != NULL ?
880 _sa_errorstr(ret) : "");
881 return (-1);
882 }
883
884 share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
885 if (share == NULL) {
886 /*
887 * This may be a new file system that was just
888 * created so isn't in the internal cache.
889 * Rather than reloading the entire configuration,
890 * we can add just this one share to the cache.
891 */
892 if ((_sa_get_zfs_share == NULL) ||
893 (_sa_get_zfs_share(hdl->libzfs_sharehdl, "zfs", zhp)
894 != SA_OK)) {
895 (void) zfs_error_fmt(hdl,
896 proto_table[*curr_proto].p_share_err,
897 dgettext(TEXT_DOMAIN, "cannot share '%s'"),
898 zfs_get_name(zhp));
899 return (-1);
900 }
901 share = zfs_sa_find_share(hdl->libzfs_sharehdl,
902 mountpoint);
903 }
904 if (share != NULL) {
905 int err;
906 err = zfs_sa_enable_share(share,
907 proto_table[*curr_proto].p_name);
908 if (err != SA_OK) {
909 (void) zfs_error_fmt(hdl,
910 proto_table[*curr_proto].p_share_err,
911 dgettext(TEXT_DOMAIN, "cannot share '%s'"),
912 zfs_get_name(zhp));
913 return (-1);
914 }
|