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                         }
 
 |