Print this page
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16


   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) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */

  25 /*
  26  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
  28  * Copyright 2017 RackTop Systems.

  29  */
  30 
  31 #include <stdio.h>
  32 #include <libzfs.h>
  33 #include <string.h>
  34 #include <strings.h>
  35 #include <errno.h>

  36 #include <libshare.h>
  37 #include "libshare_impl.h"
  38 #include <libintl.h>
  39 #include <sys/mnttab.h>
  40 #include <sys/mntent.h>
  41 #include <assert.h>
  42 
  43 extern sa_share_t _sa_add_share(sa_group_t, char *, int, int *, uint64_t);
  44 extern sa_group_t _sa_create_zfs_group(sa_group_t, char *);
  45 extern char *sa_fstype(char *);
  46 extern void set_node_attr(void *, char *, char *);
  47 extern int sa_is_share(void *);
  48 extern void sa_update_sharetab_ts(sa_handle_t);
  49 
  50 /*
  51  * File system specific code for ZFS. The original code was stolen
  52  * from the "zfs" command and modified to better suit this library's
  53  * usage.
  54  */
  55 


 221         char mountb[MAXPATHLEN];
 222 
 223         verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
 224             sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
 225         verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
 226             sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
 227 
 228         return (strcmp(mounta, mountb));
 229 }
 230 
 231 /*
 232  * return legacy mountpoint.  Caller provides space for mountpoint and
 233  * dataset.
 234  */
 235 int
 236 get_legacy_mountpoint(const char *path, char *dataset, size_t dlen,
 237     char *mountpoint, size_t mlen)
 238 {
 239         FILE *fp;
 240         struct mnttab entry;

 241 
 242         if ((fp = fopen(MNTTAB, "r")) == NULL) {
 243                 return (1);
 244         }
 245 
 246         while (getmntent(fp, &entry) == 0) {
 247 
 248                 if (entry.mnt_fstype == NULL ||
 249                     strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
 250                         continue;
 251 
 252                 if (strcmp(entry.mnt_mountp, path) == 0) {
 253                         if (mlen > 0)
 254                                 (void) strlcpy(mountpoint, entry.mnt_mountp,
 255                                     mlen);
 256                         if (dlen > 0)
 257                                 (void) strlcpy(dataset, entry.mnt_special,
 258                                     dlen);

 259                         break;
 260                 }
 261         }
 262         (void) fclose(fp);
 263         return (1);
 264 }
 265 
 266 
 267 /*
 268  * Verifies that a specific zfs filesystem handle meets the criteria necessary
 269  * to be used by libshare operations. See get_zfs_dataset.
 270  */
 271 static char *
 272 verify_zfs_handle(zfs_handle_t *hdl, const char *path, boolean_t search_mnttab)
 273 {
 274         char mountpoint[ZFS_MAXPROPLEN];
 275         char canmount[ZFS_MAXPROPLEN] = { 0 };
 276         /* must have a mountpoint */
 277         if (zfs_prop_get(hdl, ZFS_PROP_MOUNTPOINT, mountpoint,
 278             sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
 279                 /* no mountpoint */
 280                 return (NULL);
 281         }
 282 
 283         /* mountpoint must be a path */


 800             B_FALSE) != 0)
 801                 return (SA_SYSTEM_ERR);
 802 
 803         if (path != NULL)
 804                 (void) strncpy(path, mountpoint, sizeof (mountpoint));
 805         /*
 806          * zfs_get_name value must not be freed. It is just a
 807          * pointer to a value in the handle.
 808          */
 809         if ((dataset = (char *)zfs_get_name(fs_handle)) == NULL)
 810                 return (SA_SYSTEM_ERR);
 811 
 812         /*
 813          * only deal with "mounted" file systems since
 814          * unmounted file systems can't actually be shared.
 815          */
 816 
 817         if (!zfs_is_mounted(fs_handle, NULL))
 818                 return (SA_SYSTEM_ERR);
 819 







 820         nfs = nfs_inherited = B_FALSE;
 821 
 822         if (zfs_prop_get(fs_handle, ZFS_PROP_SHARENFS, nfsshareopts,
 823             sizeof (nfsshareopts), &source, nfssourcestr,
 824             ZFS_MAXPROPLEN, B_FALSE) == 0 &&
 825             strcmp(nfsshareopts, "off") != 0) {
 826                 if (source & ZPROP_SRC_INHERITED)
 827                         nfs_inherited = B_TRUE;
 828                 else
 829                         nfs = B_TRUE;
 830         }
 831 
 832         smb = smb_inherited = B_FALSE;
 833         if (zfs_prop_get(fs_handle, ZFS_PROP_SHARESMB, smbshareopts,
 834             sizeof (smbshareopts), &source, smbsourcestr,
 835             ZFS_MAXPROPLEN, B_FALSE) == 0 &&
 836             strcmp(smbshareopts, "off") != 0) {
 837                 if (source & ZPROP_SRC_INHERITED)
 838                         smb_inherited = B_TRUE;
 839                 else


 958         if (zfsgroup == NULL)
 959                 return (SA_OK);
 960 
 961         /*
 962          * need to walk the mounted ZFS pools and datasets to
 963          * find shares that are possible.
 964          */
 965         get_all_filesystems((sa_handle_impl_t)handle, &zlist, &count);
 966         qsort(zlist, count, sizeof (void *), mountpoint_compare);
 967 
 968         for (int i = 0; i < count; i++) {
 969                 err = sa_get_zfs_share_common(handle, zlist[i], NULL, zfsgroup);
 970         }
 971         /*
 972          * Don't need to free the "zlist" variable since it is only a
 973          * pointer to a cached value that will be freed when
 974          * sa_fini() is called.
 975          */
 976         return (err);
 977 }























 978 
 979 /*
 980  * Initializes only the handles specified in the sharearg for use with libshare.
 981  * This is used as a performance optimization relative to sa_get_zfs_shares.
 982  */
 983 int
 984 sa_get_one_zfs_share(sa_handle_t handle, char *groupname,
 985     sa_init_selective_arg_t *sharearg, char ***paths, size_t *paths_len)
 986 {
 987         sa_group_t zfsgroup;
 988         libzfs_handle_t *zfs_libhandle;
 989         int err;
 990 
 991         if ((err = prep_zfs_handle_and_group(handle, groupname, &zfs_libhandle,
 992             &zfsgroup, &err)) != SA_OK) {
 993                 return (err);
 994         }
 995         /* Not an error, this could be a legacy condition */
 996         if (zfsgroup == NULL)
 997                 return (SA_OK);




   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) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*

  27  * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
  28  * Copyright 2017 RackTop Systems.
  29  * Copyright 2019 Nexenta Systems, Inc.
  30  */
  31 
  32 #include <stdio.h>
  33 #include <libzfs.h>
  34 #include <string.h>
  35 #include <strings.h>
  36 #include <errno.h>
  37 #include <zone.h>
  38 #include <libshare.h>
  39 #include "libshare_impl.h"
  40 #include <libintl.h>
  41 #include <sys/mnttab.h>
  42 #include <sys/mntent.h>
  43 #include <assert.h>
  44 
  45 extern sa_share_t _sa_add_share(sa_group_t, char *, int, int *, uint64_t);
  46 extern sa_group_t _sa_create_zfs_group(sa_group_t, char *);
  47 extern char *sa_fstype(char *);
  48 extern void set_node_attr(void *, char *, char *);
  49 extern int sa_is_share(void *);
  50 extern void sa_update_sharetab_ts(sa_handle_t);
  51 
  52 /*
  53  * File system specific code for ZFS. The original code was stolen
  54  * from the "zfs" command and modified to better suit this library's
  55  * usage.
  56  */
  57 


 223         char mountb[MAXPATHLEN];
 224 
 225         verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
 226             sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
 227         verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
 228             sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
 229 
 230         return (strcmp(mounta, mountb));
 231 }
 232 
 233 /*
 234  * return legacy mountpoint.  Caller provides space for mountpoint and
 235  * dataset.
 236  */
 237 int
 238 get_legacy_mountpoint(const char *path, char *dataset, size_t dlen,
 239     char *mountpoint, size_t mlen)
 240 {
 241         FILE *fp;
 242         struct mnttab entry;
 243         int rc = 1;
 244 
 245         if ((fp = fopen(MNTTAB, "r")) == NULL) {
 246                 return (1);
 247         }
 248 
 249         while (getmntent(fp, &entry) == 0) {
 250 
 251                 if (entry.mnt_fstype == NULL ||
 252                     strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
 253                         continue;
 254 
 255                 if (strcmp(entry.mnt_mountp, path) == 0) {
 256                         if (mlen > 0)
 257                                 (void) strlcpy(mountpoint, entry.mnt_mountp,
 258                                     mlen);
 259                         if (dlen > 0)
 260                                 (void) strlcpy(dataset, entry.mnt_special,
 261                                     dlen);
 262                         rc = 0;
 263                         break;
 264                 }
 265         }
 266         (void) fclose(fp);
 267         return (rc);
 268 }
 269 
 270 
 271 /*
 272  * Verifies that a specific zfs filesystem handle meets the criteria necessary
 273  * to be used by libshare operations. See get_zfs_dataset.
 274  */
 275 static char *
 276 verify_zfs_handle(zfs_handle_t *hdl, const char *path, boolean_t search_mnttab)
 277 {
 278         char mountpoint[ZFS_MAXPROPLEN];
 279         char canmount[ZFS_MAXPROPLEN] = { 0 };
 280         /* must have a mountpoint */
 281         if (zfs_prop_get(hdl, ZFS_PROP_MOUNTPOINT, mountpoint,
 282             sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
 283                 /* no mountpoint */
 284                 return (NULL);
 285         }
 286 
 287         /* mountpoint must be a path */


 804             B_FALSE) != 0)
 805                 return (SA_SYSTEM_ERR);
 806 
 807         if (path != NULL)
 808                 (void) strncpy(path, mountpoint, sizeof (mountpoint));
 809         /*
 810          * zfs_get_name value must not be freed. It is just a
 811          * pointer to a value in the handle.
 812          */
 813         if ((dataset = (char *)zfs_get_name(fs_handle)) == NULL)
 814                 return (SA_SYSTEM_ERR);
 815 
 816         /*
 817          * only deal with "mounted" file systems since
 818          * unmounted file systems can't actually be shared.
 819          */
 820 
 821         if (!zfs_is_mounted(fs_handle, NULL))
 822                 return (SA_SYSTEM_ERR);
 823 
 824         /*
 825          * Ignore "zoned" datasets in global zone.
 826          */
 827         if (getzoneid() == GLOBAL_ZONEID &&
 828             zfs_prop_get_int(fs_handle, ZFS_PROP_ZONED))
 829                 return (SA_SYSTEM_ERR);
 830 
 831         nfs = nfs_inherited = B_FALSE;
 832 
 833         if (zfs_prop_get(fs_handle, ZFS_PROP_SHARENFS, nfsshareopts,
 834             sizeof (nfsshareopts), &source, nfssourcestr,
 835             ZFS_MAXPROPLEN, B_FALSE) == 0 &&
 836             strcmp(nfsshareopts, "off") != 0) {
 837                 if (source & ZPROP_SRC_INHERITED)
 838                         nfs_inherited = B_TRUE;
 839                 else
 840                         nfs = B_TRUE;
 841         }
 842 
 843         smb = smb_inherited = B_FALSE;
 844         if (zfs_prop_get(fs_handle, ZFS_PROP_SHARESMB, smbshareopts,
 845             sizeof (smbshareopts), &source, smbsourcestr,
 846             ZFS_MAXPROPLEN, B_FALSE) == 0 &&
 847             strcmp(smbshareopts, "off") != 0) {
 848                 if (source & ZPROP_SRC_INHERITED)
 849                         smb_inherited = B_TRUE;
 850                 else


 969         if (zfsgroup == NULL)
 970                 return (SA_OK);
 971 
 972         /*
 973          * need to walk the mounted ZFS pools and datasets to
 974          * find shares that are possible.
 975          */
 976         get_all_filesystems((sa_handle_impl_t)handle, &zlist, &count);
 977         qsort(zlist, count, sizeof (void *), mountpoint_compare);
 978 
 979         for (int i = 0; i < count; i++) {
 980                 err = sa_get_zfs_share_common(handle, zlist[i], NULL, zfsgroup);
 981         }
 982         /*
 983          * Don't need to free the "zlist" variable since it is only a
 984          * pointer to a cached value that will be freed when
 985          * sa_fini() is called.
 986          */
 987         return (err);
 988 }
 989 
 990 /*
 991  * Initializes shares for only the dataset specified fs_handle.
 992  * This is used as a performance optimization relative to sa_get_zfs_shares.
 993  */
 994 int
 995 sa_get_zfs_share(sa_handle_t handle, char *groupname, zfs_handle_t *fs_handle)
 996 {
 997         sa_group_t zfsgroup;
 998         libzfs_handle_t *zfs_libhandle;
 999         int err;
1000 
1001         if ((err = prep_zfs_handle_and_group(handle, groupname, &zfs_libhandle,
1002             &zfsgroup, &err)) != SA_OK) {
1003                 return (err);
1004         }
1005         /* Not an error, this could be a legacy condition */
1006         if (zfsgroup == NULL)
1007                 return (SA_OK);
1008 
1009         err = sa_get_zfs_share_common(handle, fs_handle, NULL, zfsgroup);
1010         return (err);
1011 }
1012 
1013 /*
1014  * Initializes only the handles specified in the sharearg for use with libshare.
1015  * This is used as a performance optimization relative to sa_get_zfs_shares.
1016  */
1017 int
1018 sa_get_one_zfs_share(sa_handle_t handle, char *groupname,
1019     sa_init_selective_arg_t *sharearg, char ***paths, size_t *paths_len)
1020 {
1021         sa_group_t zfsgroup;
1022         libzfs_handle_t *zfs_libhandle;
1023         int err;
1024 
1025         if ((err = prep_zfs_handle_and_group(handle, groupname, &zfs_libhandle,
1026             &zfsgroup, &err)) != SA_OK) {
1027                 return (err);
1028         }
1029         /* Not an error, this could be a legacy condition */
1030         if (zfsgroup == NULL)
1031                 return (SA_OK);