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


   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) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Nexenta Systems, Inc.
  25  * Copyright (c) 2014, 2016 by Delphix. All rights reserved.

  26  */
  27 
  28 /*
  29  * NFS specific functions
  30  */

  31 #include <stdio.h>
  32 #include <string.h>
  33 #include <ctype.h>
  34 #include <stdlib.h>
  35 #include <unistd.h>
  36 #include <zone.h>
  37 #include <errno.h>
  38 #include <locale.h>
  39 #include <signal.h>
  40 #include <strings.h>
  41 #include "libshare.h"
  42 #include "libshare_impl.h"
  43 #include <nfs/export.h>
  44 #include <pwd.h>
  45 #include <grp.h>
  46 #include <limits.h>
  47 #include <libscf.h>
  48 #include <syslog.h>
  49 #include <rpcsvc/daemon_utils.h>
  50 #include "nfslog_config.h"
  51 #include "nfslogtab.h"
  52 #include "libshare_nfs.h"
  53 #include <nfs/nfs.h>
  54 #include <nfs/nfssys.h>
  55 #include <netconfig.h>
  56 #include "smfcfg.h"


1888                          */
1889                         if (sectype == NULL) {
1890                                 err = SA_NO_MEMORY;
1891                                 (void) printf(dgettext(TEXT_DOMAIN,
1892                                     "NFS: Cannot share %s: "
1893                                     "no memory\n"), path);
1894                                 goto out;
1895                         }
1896                         sec = (sa_security_t)sa_get_derived_security(
1897                             share, sectype, "nfs", 1);
1898                         sp[i].s_window = DEF_WIN;
1899                         sp[i].s_rootcnt = 0;
1900                         sp[i].s_rootnames = NULL;
1901                         (void) fill_security_from_secopts(&sp[i], sec);
1902                         if (sec != NULL)
1903                                 sa_free_derived_security(sec);
1904                         if (sectype != NULL)
1905                                 sa_free_attr_string(sectype);
1906                 }
1907         }
1908         /*
1909          * when we get here, we can do the exportfs system call and
1910          * initiate things. We probably want to enable the
1911          * svc:/network/nfs/server service first if it isn't running.
1912          */
1913         /* check svc:/network/nfs/server status and start if needed */
1914         /* now add the share to the internal tables */
1915         printarg(path, &export);
1916         /*
1917          * call the exportfs system call which is implemented
1918          * via the nfssys() call as the EXPORTFS subfunction.
1919          */
1920         if (iszfs) {
1921                 struct exportfs_args ea;
1922                 share_t sh;
1923                 char *str;
1924                 priv_set_t *priv_effective;
1925                 int privileged;
1926 
1927                 /*
1928                  * If we aren't a privileged user
1929                  * and NFS server service isn't running
1930                  * then print out an error message
1931                  * and return EPERM
1932                  */
1933 
1934                 priv_effective = priv_allocset();
1935                 (void) getppriv(PRIV_EFFECTIVE, priv_effective);
1936 
1937                 privileged = (priv_isfullset(priv_effective) == B_TRUE);
1938                 priv_freeset(priv_effective);
1939 
1940                 if (!privileged &&
1941                     (str = smf_get_state(NFS_SERVER_SVC)) != NULL) {
1942                         err = 0;
1943                         if (strcmp(str, SCF_STATE_STRING_ONLINE) != 0) {
1944                                 (void) printf(dgettext(TEXT_DOMAIN,
1945                                     "NFS: Cannot share remote "
1946                                     "filesystem: %s\n"), path);
1947                                 (void) printf(dgettext(TEXT_DOMAIN,
1948                                     "NFS: Service needs to be enabled "
1949                                     "by a privileged user\n"));
1950                                 err = SA_SYSTEM_ERR;
1951                                 errno = EPERM;
1952                         }
1953                         free(str);
1954                 }
1955 
1956                 if (err == 0) {
1957                         ea.dname = path;
1958                         ea.uex = &export;
1959 
1960                         (void) sa_sharetab_fill_zfs(share, &sh, "nfs");
1961                         err = sa_share_zfs(share, NULL, path, &sh,
1962                             &ea, ZFS_SHARE_NFS);
1963                         if (err != SA_OK) {
1964                                 errno = err;
1965                                 err = -1;
1966                         }
1967                         sa_emptyshare(&sh);
1968                 }
1969         } else {
1970                 err = exportfs(path, &export);
1971         }
1972 
1973         if (err < 0) {
1974                 err = SA_SYSTEM_ERR;
1975                 switch (errno) {
1976                 case EREMOTE:
1977                         (void) printf(dgettext(TEXT_DOMAIN,
1978                             "NFS: Cannot share filesystems "
1979                             "in non-global zones: %s\n"), path);
1980                         err = SA_NOT_SUPPORTED;
1981                         break;
1982                 case EPERM:
1983                         if (getzoneid() != GLOBAL_ZONEID) {
1984                                 (void) printf(dgettext(TEXT_DOMAIN,
1985                                     "NFS: Cannot share file systems "
1986                                     "in non-global zones: %s\n"), path);
1987                                 err = SA_NOT_SUPPORTED;
1988                                 break;
1989                         }
1990                         err = SA_NO_PERMISSION;
1991                         break;
1992                 case EEXIST:
1993                         err = SA_SHARE_EXISTS;
1994                         break;
1995                 default:
1996                         break;
1997                 }
1998         } else {
1999                 /* update sharetab with an add/modify */
2000                 if (!iszfs) {
2001                         (void) sa_update_sharetab(share, "nfs");
2002                 }
2003         }
2004 
2005         if (err == SA_OK) {
2006                 /*
2007                  * enable services as needed. This should probably be
2008                  * done elsewhere in order to minimize the calls to
2009                  * check services.


2081                 sh.sh_fstype = "nfs";
2082 
2083                 err = sa_share_zfs(share, NULL, path, &sh,
2084                     &ea, ZFS_UNSHARE_NFS);
2085                 if (err != SA_OK) {
2086                         errno = err;
2087                         err = -1;
2088                 }
2089         } else {
2090                 err = exportfs(path, NULL);
2091         }
2092         if (err < 0) {
2093                 /*
2094                  * TBD: only an error in some
2095                  * cases - need better analysis
2096                  */
2097                 switch (errno) {
2098                 case EPERM:
2099                 case EACCES:
2100                         ret = SA_NO_PERMISSION;
2101                         if (getzoneid() != GLOBAL_ZONEID) {
2102                                 ret = SA_NOT_SUPPORTED;
2103                         }
2104                         break;
2105                 case EINVAL:
2106                 case ENOENT:
2107                         ret = SA_NO_SUCH_PATH;
2108                         break;
2109                 default:
2110                         ret = SA_SYSTEM_ERR;
2111                         break;
2112                 }
2113         }
2114         if (ret == SA_OK || ret == SA_NO_SUCH_PATH) {
2115                 handle = sa_find_group_handle((sa_group_t)share);
2116                 if (!iszfs)
2117                         (void) sa_delete_sharetab(handle, path, "nfs");
2118                 /* just in case it was logged */
2119                 (void) nfslogtab_deactivate(path);
2120         }
2121         return (ret);
2122 }
2123 




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

  24  * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
  25  * Copyright 2018 Nexenta Systems, Inc.
  26  */
  27 
  28 /*
  29  * NFS specific functions
  30  */
  31 
  32 #include <stdio.h>
  33 #include <string.h>
  34 #include <ctype.h>
  35 #include <stdlib.h>
  36 #include <unistd.h>

  37 #include <errno.h>
  38 #include <locale.h>
  39 #include <signal.h>
  40 #include <strings.h>
  41 #include "libshare.h"
  42 #include "libshare_impl.h"
  43 #include <nfs/export.h>
  44 #include <pwd.h>
  45 #include <grp.h>
  46 #include <limits.h>
  47 #include <libscf.h>
  48 #include <syslog.h>
  49 #include <rpcsvc/daemon_utils.h>
  50 #include "nfslog_config.h"
  51 #include "nfslogtab.h"
  52 #include "libshare_nfs.h"
  53 #include <nfs/nfs.h>
  54 #include <nfs/nfssys.h>
  55 #include <netconfig.h>
  56 #include "smfcfg.h"


1888                          */
1889                         if (sectype == NULL) {
1890                                 err = SA_NO_MEMORY;
1891                                 (void) printf(dgettext(TEXT_DOMAIN,
1892                                     "NFS: Cannot share %s: "
1893                                     "no memory\n"), path);
1894                                 goto out;
1895                         }
1896                         sec = (sa_security_t)sa_get_derived_security(
1897                             share, sectype, "nfs", 1);
1898                         sp[i].s_window = DEF_WIN;
1899                         sp[i].s_rootcnt = 0;
1900                         sp[i].s_rootnames = NULL;
1901                         (void) fill_security_from_secopts(&sp[i], sec);
1902                         if (sec != NULL)
1903                                 sa_free_derived_security(sec);
1904                         if (sectype != NULL)
1905                                 sa_free_attr_string(sectype);
1906                 }
1907         }
1908 





1909         /* now add the share to the internal tables */
1910         printarg(path, &export);
1911         /*
1912          * call the exportfs system call which is implemented
1913          * via the nfssys() call as the EXPORTFS subfunction.
1914          */
1915         if (iszfs) {
1916                 struct exportfs_args ea;
1917                 share_t sh;



1918 






























1919                 ea.dname = path;
1920                 ea.uex = &export;
1921 
1922                 (void) sa_sharetab_fill_zfs(share, &sh, "nfs");
1923                 err = sa_share_zfs(share, NULL, path, &sh, &ea, ZFS_SHARE_NFS);

1924                 if (err != SA_OK) {
1925                         errno = err;
1926                         err = -1;
1927                 }
1928                 sa_emptyshare(&sh);

1929         } else {
1930                 err = exportfs(path, &export);
1931         }
1932 
1933         if (err < 0) {
1934                 err = SA_SYSTEM_ERR;
1935                 switch (errno) {






1936                 case EPERM:







1937                         err = SA_NO_PERMISSION;
1938                         break;
1939                 case EEXIST:
1940                         err = SA_SHARE_EXISTS;
1941                         break;
1942                 default:
1943                         break;
1944                 }
1945         } else {
1946                 /* update sharetab with an add/modify */
1947                 if (!iszfs) {
1948                         (void) sa_update_sharetab(share, "nfs");
1949                 }
1950         }
1951 
1952         if (err == SA_OK) {
1953                 /*
1954                  * enable services as needed. This should probably be
1955                  * done elsewhere in order to minimize the calls to
1956                  * check services.


2028                 sh.sh_fstype = "nfs";
2029 
2030                 err = sa_share_zfs(share, NULL, path, &sh,
2031                     &ea, ZFS_UNSHARE_NFS);
2032                 if (err != SA_OK) {
2033                         errno = err;
2034                         err = -1;
2035                 }
2036         } else {
2037                 err = exportfs(path, NULL);
2038         }
2039         if (err < 0) {
2040                 /*
2041                  * TBD: only an error in some
2042                  * cases - need better analysis
2043                  */
2044                 switch (errno) {
2045                 case EPERM:
2046                 case EACCES:
2047                         ret = SA_NO_PERMISSION;



2048                         break;
2049                 case EINVAL:
2050                 case ENOENT:
2051                         ret = SA_NO_SUCH_PATH;
2052                         break;
2053                 default:
2054                         ret = SA_SYSTEM_ERR;
2055                         break;
2056                 }
2057         }
2058         if (ret == SA_OK || ret == SA_NO_SUCH_PATH) {
2059                 handle = sa_find_group_handle((sa_group_t)share);
2060                 if (!iszfs)
2061                         (void) sa_delete_sharetab(handle, path, "nfs");
2062                 /* just in case it was logged */
2063                 (void) nfslogtab_deactivate(path);
2064         }
2065         return (ret);
2066 }
2067