595 {
596 return (zfs_is_shared_proto(zhp, where,
597 PROTO_NFS) != SHARED_NOT_SHARED);
598 }
599
600 boolean_t
601 zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
602 {
603 return (zfs_is_shared_proto(zhp, where,
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 void (*_sa_fini)(sa_handle_t);
616 static sa_share_t (*_sa_find_share)(sa_handle_t, char *);
617 static int (*_sa_enable_share)(sa_share_t, char *);
618 static int (*_sa_disable_share)(sa_share_t, char *);
619 static char *(*_sa_errorstr)(int);
620 static int (*_sa_parse_legacy_options)(sa_group_t, char *, char *);
621 static boolean_t (*_sa_needs_refresh)(sa_handle_t *);
622 static libzfs_handle_t *(*_sa_get_zfs_handle)(sa_handle_t);
623 static int (*_sa_zfs_process_share)(sa_handle_t, sa_group_t, sa_share_t,
624 char *, char *, zprop_source_t, char *, char *, char *);
625 static void (*_sa_update_sharetab_ts)(sa_handle_t);
626
627 /*
628 * _zfs_init_libshare()
629 *
630 * Find the libshare.so.1 entry points that we use here and save the
631 * values to be used later. This is triggered by the runtime loader.
632 * Make sure the correct ISA version is loaded.
633 */
634
637 _zfs_init_libshare(void)
638 {
639 void *libshare;
640 char path[MAXPATHLEN];
641 char isa[MAXISALEN];
642
643 #if defined(_LP64)
644 if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1)
645 isa[0] = '\0';
646 #else
647 isa[0] = '\0';
648 #endif
649 (void) snprintf(path, MAXPATHLEN,
650 "/usr/lib/%s/libshare.so.1", isa);
651
652 if ((libshare = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)) != NULL) {
653 _sa_init = (sa_handle_t (*)(int))dlsym(libshare, "sa_init");
654 _sa_init_arg = (sa_handle_t (*)(int, void *))dlsym(libshare,
655 "sa_init_arg");
656 _sa_fini = (void (*)(sa_handle_t))dlsym(libshare, "sa_fini");
657 _sa_find_share = (sa_share_t (*)(sa_handle_t, char *))
658 dlsym(libshare, "sa_find_share");
659 _sa_enable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
660 "sa_enable_share");
661 _sa_disable_share = (int (*)(sa_share_t, char *))dlsym(libshare,
662 "sa_disable_share");
663 _sa_errorstr = (char *(*)(int))dlsym(libshare, "sa_errorstr");
664 _sa_parse_legacy_options = (int (*)(sa_group_t, char *, char *))
665 dlsym(libshare, "sa_parse_legacy_options");
666 _sa_needs_refresh = (boolean_t (*)(sa_handle_t *))
667 dlsym(libshare, "sa_needs_refresh");
668 _sa_get_zfs_handle = (libzfs_handle_t *(*)(sa_handle_t))
669 dlsym(libshare, "sa_get_zfs_handle");
670 _sa_zfs_process_share = (int (*)(sa_handle_t, sa_group_t,
671 sa_share_t, char *, char *, zprop_source_t, char *,
672 char *, char *))dlsym(libshare, "sa_zfs_process_share");
673 _sa_update_sharetab_ts = (void (*)(sa_handle_t))
674 dlsym(libshare, "sa_update_sharetab_ts");
675 if (_sa_init == NULL || _sa_init_arg == NULL ||
676 _sa_fini == NULL || _sa_find_share == NULL ||
677 _sa_enable_share == NULL || _sa_disable_share == NULL ||
678 _sa_errorstr == NULL || _sa_parse_legacy_options == NULL ||
679 _sa_needs_refresh == NULL || _sa_get_zfs_handle == NULL ||
680 _sa_zfs_process_share == NULL ||
681 _sa_update_sharetab_ts == NULL) {
682 _sa_init = NULL;
683 _sa_init_arg = NULL;
684 _sa_fini = NULL;
685 _sa_disable_share = NULL;
686 _sa_enable_share = NULL;
687 _sa_errorstr = NULL;
688 _sa_parse_legacy_options = NULL;
689 (void) dlclose(libshare);
690 _sa_needs_refresh = NULL;
691 _sa_get_zfs_handle = NULL;
692 _sa_zfs_process_share = NULL;
693 _sa_update_sharetab_ts = NULL;
694 }
695 }
696 }
697
698 /*
699 * zfs_init_libshare(zhandle, service)
700 *
701 * Initialize the libshare API if it hasn't already been initialized.
702 * In all cases it returns 0 if it succeeded and an error if not. The
703 * service value is which part(s) of the API to initialize and is a
822 if (_sa_disable_share != NULL)
823 return (_sa_disable_share(share, proto));
824 return (SA_CONFIG_ERR);
825 }
826
827 /*
828 * Share the given filesystem according to the options in the specified
829 * protocol specific properties (sharenfs, sharesmb). We rely
830 * on "libshare" to the dirty work for us.
831 */
832 static int
833 zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
834 {
835 char mountpoint[ZFS_MAXPROPLEN];
836 char shareopts[ZFS_MAXPROPLEN];
837 char sourcestr[ZFS_MAXPROPLEN];
838 libzfs_handle_t *hdl = zhp->zfs_hdl;
839 sa_share_t share;
840 zfs_share_proto_t *curr_proto;
841 zprop_source_t sourcetype;
842 int ret;
843
844 if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
845 return (0);
846
847 for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
848 /*
849 * Return success if there are no share options.
850 */
851 if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
852 shareopts, sizeof (shareopts), &sourcetype, sourcestr,
853 ZFS_MAXPROPLEN, B_FALSE) != 0 ||
854 strcmp(shareopts, "off") == 0)
855 continue;
856 ret = zfs_init_libshare_arg(hdl, SA_INIT_ONE_SHARE_FROM_HANDLE,
857 zhp);
858 if (ret != SA_OK) {
859 (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
860 dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
861 zfs_get_name(zhp), _sa_errorstr != NULL ?
862 _sa_errorstr(ret) : "");
863 return (-1);
864 }
865
866 /*
867 * If the 'zoned' property is set, then zfs_is_mountable()
868 * will have already bailed out if we are in the global zone.
869 * But local zones cannot be NFS servers, so we ignore it for
870 * local zones as well.
871 */
872 if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
873 continue;
874
875 share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
876 if (share == NULL) {
877 /*
931 {
932 return (zfs_share_proto(zhp, smb_only));
933 }
934
935 int
936 zfs_shareall(zfs_handle_t *zhp)
937 {
938 return (zfs_share_proto(zhp, share_all_proto));
939 }
940
941 /*
942 * Unshare a filesystem by mountpoint.
943 */
944 static int
945 unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
946 zfs_share_proto_t proto)
947 {
948 sa_share_t share;
949 int err;
950 char *mntpt;
951
952 /*
953 * Mountpoint could get trashed if libshare calls getmntany
954 * which it does during API initialization, so strdup the
955 * value.
956 */
957 mntpt = zfs_strdup(hdl, mountpoint);
958
959 /*
960 * make sure libshare initialized, initialize everything because we
961 * don't know what other unsharing may happen later. Functions up the
962 * stack are allowed to initialize instead a subset of shares at the
963 * time the set is known.
964 */
965 if ((err = zfs_init_libshare_arg(hdl, SA_INIT_ONE_SHARE_FROM_NAME,
966 (void *)name)) != SA_OK) {
967 free(mntpt); /* don't need the copy anymore */
968 return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
969 dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
970 name, _sa_errorstr(err)));
971 }
972
973 share = zfs_sa_find_share(hdl->libzfs_sharehdl, mntpt);
974 free(mntpt); /* don't need the copy anymore */
975
976 if (share != NULL) {
977 err = zfs_sa_disable_share(share, proto_table[proto].p_name);
978 if (err != SA_OK) {
979 return (zfs_error_fmt(hdl,
980 proto_table[proto].p_unshare_err,
981 dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
982 name, _sa_errorstr(err)));
983 }
984 } else {
985 return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
986 dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
1515 goto out;
1516
1517
1518 /*
1519 * Gather all non-snapshot datasets within the pool. Start by adding
1520 * the root filesystem for this pool to the list, and then iterate
1521 * over all child filesystems.
1522 */
1523 libzfs_add_handle(&cb, zfsp);
1524 if (zfs_iter_filesystems(zfsp, zfs_iter_cb, &cb) != 0)
1525 goto out;
1526
1527 ms.ms_mntopts = mntopts;
1528 ms.ms_mntflags = flags;
1529 zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
1530 zfs_mount_one, &ms, B_TRUE);
1531 if (ms.ms_mntstatus != 0)
1532 ret = ms.ms_mntstatus;
1533
1534 /*
1535 * Share all filesystems that need to be shared. This needs to be
1536 * a separate pass because libshare is not mt-safe, and so we need
1537 * to share serially.
1538 */
1539 sharearg.zhandle_arr = cb.cb_handles;
1540 sharearg.zhandle_len = cb.cb_used;
1541 if ((ret = zfs_init_libshare_arg(zhp->zpool_hdl,
1542 SA_INIT_SHARE_API_SELECTIVE, &sharearg)) != 0)
1543 goto out;
1544
1545 ms.ms_mntstatus = 0;
1546 zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
1547 zfs_share_one, &ms, B_FALSE);
1548 if (ms.ms_mntstatus != 0)
1549 ret = ms.ms_mntstatus;
1550
1551 out:
1552 for (int i = 0; i < cb.cb_used; i++)
1553 zfs_close(cb.cb_handles[i]);
1554 free(cb.cb_handles);
1555
1556 return (ret);
1557 }
|
595 {
596 return (zfs_is_shared_proto(zhp, where,
597 PROTO_NFS) != SHARED_NOT_SHARED);
598 }
599
600 boolean_t
601 zfs_is_shared_smb(zfs_handle_t *zhp, char **where)
602 {
603 return (zfs_is_shared_proto(zhp, where,
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
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)
646 isa[0] = '\0';
647 #else
648 isa[0] = '\0';
649 #endif
650 (void) snprintf(path, MAXPATHLEN,
651 "/usr/lib/%s/libshare.so.1", isa);
652
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
826 if (_sa_disable_share != NULL)
827 return (_sa_disable_share(share, proto));
828 return (SA_CONFIG_ERR);
829 }
830
831 /*
832 * Share the given filesystem according to the options in the specified
833 * protocol specific properties (sharenfs, sharesmb). We rely
834 * on "libshare" to the dirty work for us.
835 */
836 static int
837 zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
838 {
839 char mountpoint[ZFS_MAXPROPLEN];
840 char shareopts[ZFS_MAXPROPLEN];
841 char sourcestr[ZFS_MAXPROPLEN];
842 libzfs_handle_t *hdl = zhp->zfs_hdl;
843 sa_share_t share;
844 zfs_share_proto_t *curr_proto;
845 zprop_source_t sourcetype;
846 int service = SA_INIT_ONE_SHARE_FROM_HANDLE;
847 int ret;
848
849 if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
850 return (0);
851
852 /*
853 * Function may be called in a loop from higher up stack, with libshare
854 * initialized for multiple shares (SA_INIT_SHARE_API_SELECTIVE).
855 * zfs_init_libshare_arg will refresh the handle's cache if necessary.
856 * In this case we do not want to switch to per share initialization.
857 * Specify SA_INIT_SHARE_API to do full refresh, if refresh required.
858 */
859 if ((hdl->libzfs_sharehdl != NULL) && (_sa_service != NULL) &&
860 (_sa_service(hdl->libzfs_sharehdl) ==
861 SA_INIT_SHARE_API_SELECTIVE)) {
862 service = SA_INIT_SHARE_API;
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 /*
948 {
949 return (zfs_share_proto(zhp, smb_only));
950 }
951
952 int
953 zfs_shareall(zfs_handle_t *zhp)
954 {
955 return (zfs_share_proto(zhp, share_all_proto));
956 }
957
958 /*
959 * Unshare a filesystem by mountpoint.
960 */
961 static int
962 unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
963 zfs_share_proto_t proto)
964 {
965 sa_share_t share;
966 int err;
967 char *mntpt;
968 int service = SA_INIT_ONE_SHARE_FROM_NAME;
969
970 /*
971 * Mountpoint could get trashed if libshare calls getmntany
972 * which it does during API initialization, so strdup the
973 * value.
974 */
975 mntpt = zfs_strdup(hdl, mountpoint);
976
977 /*
978 * Function may be called in a loop from higher up stack, with libshare
979 * initialized for multiple shares (SA_INIT_SHARE_API_SELECTIVE).
980 * zfs_init_libshare_arg will refresh the handle's cache if necessary.
981 * In this case we do not want to switch to per share initialization.
982 * Specify SA_INIT_SHARE_API to do full refresh, if refresh required.
983 */
984 if ((hdl->libzfs_sharehdl != NULL) && (_sa_service != NULL) &&
985 (_sa_service(hdl->libzfs_sharehdl) ==
986 SA_INIT_SHARE_API_SELECTIVE)) {
987 service = SA_INIT_SHARE_API;
988 }
989
990 err = zfs_init_libshare_arg(hdl, service, (void *)name);
991 if (err != SA_OK) {
992 free(mntpt); /* don't need the copy anymore */
993 return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
994 dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
995 name, _sa_errorstr(err)));
996 }
997
998 share = zfs_sa_find_share(hdl->libzfs_sharehdl, mntpt);
999 free(mntpt); /* don't need the copy anymore */
1000
1001 if (share != NULL) {
1002 err = zfs_sa_disable_share(share, proto_table[proto].p_name);
1003 if (err != SA_OK) {
1004 return (zfs_error_fmt(hdl,
1005 proto_table[proto].p_unshare_err,
1006 dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
1007 name, _sa_errorstr(err)));
1008 }
1009 } else {
1010 return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
1011 dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
1540 goto out;
1541
1542
1543 /*
1544 * Gather all non-snapshot datasets within the pool. Start by adding
1545 * the root filesystem for this pool to the list, and then iterate
1546 * over all child filesystems.
1547 */
1548 libzfs_add_handle(&cb, zfsp);
1549 if (zfs_iter_filesystems(zfsp, zfs_iter_cb, &cb) != 0)
1550 goto out;
1551
1552 ms.ms_mntopts = mntopts;
1553 ms.ms_mntflags = flags;
1554 zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
1555 zfs_mount_one, &ms, B_TRUE);
1556 if (ms.ms_mntstatus != 0)
1557 ret = ms.ms_mntstatus;
1558
1559 /*
1560 * Initialize libshare SA_INIT_SHARE_API_SELECTIVE here
1561 * to avoid unnecessary load/unload of the libshare API
1562 * per shared dataset downstream.
1563 */
1564 sharearg.zhandle_arr = cb.cb_handles;
1565 sharearg.zhandle_len = cb.cb_used;
1566 if ((ret = zfs_init_libshare_arg(zhp->zpool_hdl,
1567 SA_INIT_SHARE_API_SELECTIVE, &sharearg)) != 0)
1568 goto out;
1569
1570 ms.ms_mntstatus = 0;
1571 zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
1572 zfs_share_one, &ms, B_FALSE);
1573 if (ms.ms_mntstatus != 0)
1574 ret = ms.ms_mntstatus;
1575
1576 out:
1577 for (int i = 0; i < cb.cb_used; i++)
1578 zfs_close(cb.cb_handles[i]);
1579 free(cb.cb_handles);
1580
1581 return (ret);
1582 }
|