git://git.camperquake.de
/
zfs.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Illumos #1748: desire support for reguid in zfs
[zfs.git]
/
lib
/
libshare
/
nfs.c
diff --git
a/lib/libshare/nfs.c
b/lib/libshare/nfs.c
index
4d13014
..
56725d2
100644
(file)
--- a/
lib/libshare/nfs.c
+++ b/
lib/libshare/nfs.c
@@
-48,6
+48,10
@@
typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value,
typedef int (*nfs_host_callback_t)(const char *sharepath, const char *host,
const char *security, const char *access, void *cookie);
typedef int (*nfs_host_callback_t)(const char *sharepath, const char *host,
const char *security, const char *access, void *cookie);
+/**
+ * Invokes the specified callback function for each Solaris share option
+ * listed in the specified string.
+ */
static int
foreach_nfs_shareopt(const char *shareopts,
nfs_shareopt_callback_t callback, void *cookie)
static int
foreach_nfs_shareopt(const char *shareopts,
nfs_shareopt_callback_t callback, void *cookie)
@@
-111,6
+115,11
@@
typedef struct nfs_host_cookie_s {
const char *security;
} nfs_host_cookie_t;
const char *security;
} nfs_host_cookie_t;
+/**
+ * Helper function for foreach_nfs_host. This function checks whether the
+ * current share option is a host specification and invokes a callback
+ * function with information about the host.
+ */
static int
foreach_nfs_host_cb(const char *opt, const char *value, void *pcookie)
{
static int
foreach_nfs_host_cb(const char *opt, const char *value, void *pcookie)
{
@@
-164,6
+173,9
@@
foreach_nfs_host_cb(const char *opt, const char *value, void *pcookie)
return SA_OK;
}
return SA_OK;
}
+/**
+ * Invokes a callback function for all NFS hosts that are set for a share.
+ */
static int
foreach_nfs_host(sa_share_impl_t impl_share, nfs_host_callback_t callback,
void *cookie)
static int
foreach_nfs_host(sa_share_impl_t impl_share, nfs_host_callback_t callback,
void *cookie)
@@
-182,6
+194,9
@@
foreach_nfs_host(sa_share_impl_t impl_share, nfs_host_callback_t callback,
&udata);
}
&udata);
}
+/**
+ * Converts a Solaris NFS host specification to its Linux equivalent.
+ */
static int
get_linux_hostspec(const char *solaris_hostspec, char **plinux_hostspec)
{
static int
get_linux_hostspec(const char *solaris_hostspec, char **plinux_hostspec)
{
@@
-206,34
+221,17
@@
get_linux_hostspec(const char *solaris_hostspec, char **plinux_hostspec)
return SA_OK;
}
return SA_OK;
}
+/**
+ * Used internally by nfs_enable_share to enable sharing for a single host.
+ */
static int
nfs_enable_share_one(const char *sharepath, const char *host,
const char *security, const char *access, void *pcookie)
{
static int
nfs_enable_share_one(const char *sharepath, const char *host,
const char *security, const char *access, void *pcookie)
{
- pid_t pid;
- int rc, status;
+ int rc;
char *linuxhost, *hostpath, *opts;
const char *linux_opts = (const char *)pcookie;
char *linuxhost, *hostpath, *opts;
const char *linux_opts = (const char *)pcookie;
-
- pid = fork();
-
- if (pid < 0)
- return SA_SYSTEM_ERR;
-
- if (pid > 0) {
- while ((rc = waitpid(pid, &status, 0)) <= 0 && errno == EINTR)
- ; /* empty loop body */
-
- if (rc <= 0)
- return SA_SYSTEM_ERR;
-
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- return SA_CONFIG_ERR;
-
- return SA_OK;
- }
-
- /* child */
+ char *argv[6];
/* exportfs -i -o sec=XX,rX,<opts> <host>:<sharepath> */
/* exportfs -i -o sec=XX,rX,<opts> <host>:<sharepath> */
@@
-268,18
+266,27
@@
nfs_enable_share_one(const char *sharepath, const char *host,
fprintf(stderr, "sharing %s with opts %s\n", hostpath, opts);
#endif
fprintf(stderr, "sharing %s with opts %s\n", hostpath, opts);
#endif
- rc = execlp("/usr/sbin/exportfs", "exportfs", "-i", \
- "-o", opts, hostpath, NULL);
+ argv[0] = "/usr/sbin/exportfs";
+ argv[1] = "-i";
+ argv[2] = "-o";
+ argv[3] = opts;
+ argv[4] = hostpath;
+ argv[5] = NULL;
- if (rc < 0) {
- free(hostpath);
- free(opts);
- exit(1);
- }
+ rc = libzfs_run_process(argv[0], argv, 0);
- exit(0);
+ free(hostpath);
+ free(opts);
+
+ if (rc < 0)
+ return SA_SYSTEM_ERR;
+ else
+ return SA_OK;
}
}
+/**
+ * Adds a Linux share option to an array of NFS options.
+ */
static int
add_linux_shareopt(char **plinux_opts, const char *key, const char *value)
{
static int
add_linux_shareopt(char **plinux_opts, const char *key, const char *value)
{
@@
-312,6
+319,10
@@
add_linux_shareopt(char **plinux_opts, const char *key, const char *value)
return SA_OK;
}
return SA_OK;
}
+/**
+ * Validates and converts a single Solaris share option to its Linux
+ * equivalent.
+ */
static int
get_linux_shareopts_cb(const char *key, const char *value, void *cookie)
{
static int
get_linux_shareopts_cb(const char *key, const char *value, void *cookie)
{
@@
-349,7
+360,7
@@
get_linux_shareopts_cb(const char *key, const char *value, void *cookie)
strcmp(key, "root_squash") != 0 &&
strcmp(key, "no_root_squash") != 0 &&
strcmp(key, "all_squash") != 0 &&
strcmp(key, "root_squash") != 0 &&
strcmp(key, "no_root_squash") != 0 &&
strcmp(key, "all_squash") != 0 &&
- strcmp(key, "no_all_squash") != 0 &&
+ strcmp(key, "no_all_squash") != 0 &&
strcmp(key, "fsid") != 0 &&
strcmp(key, "anonuid") != 0 && strcmp(key, "anongid") != 0) {
return SA_SYNTAX_ERR;
}
strcmp(key, "anonuid") != 0 && strcmp(key, "anongid") != 0) {
return SA_SYNTAX_ERR;
}
@@
-359,6
+370,10
@@
get_linux_shareopts_cb(const char *key, const char *value, void *cookie)
return SA_OK;
}
return SA_OK;
}
+/**
+ * Takes a string containing Solaris share options (e.g. "sync,no_acl") and
+ * converts them to a NULL-terminated array of Linux NFS options.
+ */
static int
get_linux_shareopts(const char *shareopts, char **plinux_opts)
{
static int
get_linux_shareopts(const char *shareopts, char **plinux_opts)
{
@@
-383,6
+398,9
@@
get_linux_shareopts(const char *shareopts, char **plinux_opts)
return rc;
}
return rc;
}
+/**
+ * Enables NFS sharing for the specified share.
+ */
static int
nfs_enable_share(sa_share_impl_t impl_share)
{
static int
nfs_enable_share(sa_share_impl_t impl_share)
{
@@
-410,33
+428,16
@@
nfs_enable_share(sa_share_impl_t impl_share)
return rc;
}
return rc;
}
+/**
+ * Used internally by nfs_disable_share to disable sharing for a single host.
+ */
static int
nfs_disable_share_one(const char *sharepath, const char *host,
const char *security, const char *access, void *cookie)
{
static int
nfs_disable_share_one(const char *sharepath, const char *host,
const char *security, const char *access, void *cookie)
{
- pid_t pid;
- int rc, status;
+ int rc;
char *linuxhost, *hostpath;
char *linuxhost, *hostpath;
-
- pid = fork();
-
- if (pid < 0)
- return SA_SYSTEM_ERR;
-
- if (pid > 0) {
- while ((rc = waitpid(pid, &status, 0)) <= 0 && errno == EINTR)
- ; /* empty loop body */
-
- if (rc <= 0)
- return SA_SYSTEM_ERR;
-
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- return SA_CONFIG_ERR;
-
- return SA_OK;
- }
-
- /* child */
+ char *argv[4];
rc = get_linux_hostspec(host, &linuxhost);
rc = get_linux_hostspec(host, &linuxhost);
@@
-458,17
+459,24
@@
nfs_disable_share_one(const char *sharepath, const char *host,
fprintf(stderr, "unsharing %s\n", hostpath);
#endif
fprintf(stderr, "unsharing %s\n", hostpath);
#endif
- rc = execlp("/usr/sbin/exportfs", "exportfs", "-u", \
- hostpath, NULL);
+ argv[0] = "/usr/sbin/exportfs";
+ argv[1] = "-u";
+ argv[2] = hostpath;
+ argv[3] = NULL;
- if (rc < 0) {
- free(hostpath);
- exit(1);
- }
+ rc = libzfs_run_process(argv[0], argv, 0);
- exit(0);
+ free(hostpath);
+
+ if (rc < 0)
+ return SA_SYSTEM_ERR;
+ else
+ return SA_OK;
}
}
+/**
+ * Disables NFS sharing for the specified share.
+ */
static int
nfs_disable_share(sa_share_impl_t impl_share)
{
static int
nfs_disable_share(sa_share_impl_t impl_share)
{
@@
-483,6
+491,9
@@
nfs_disable_share(sa_share_impl_t impl_share)
return foreach_nfs_host(impl_share, nfs_disable_share_one, NULL);
}
return foreach_nfs_host(impl_share, nfs_disable_share_one, NULL);
}
+/**
+ * Checks whether the specified NFS share options are syntactically correct.
+ */
static int
nfs_validate_shareopts(const char *shareopts)
{
static int
nfs_validate_shareopts(const char *shareopts)
{
@@
-499,6
+510,9
@@
nfs_validate_shareopts(const char *shareopts)
return SA_OK;
}
return SA_OK;
}
+/**
+ * Checks whether a share is currently active.
+ */
static boolean_t
is_share_active(sa_share_impl_t impl_share)
{
static boolean_t
is_share_active(sa_share_impl_t impl_share)
{
@@
-557,6
+571,12
@@
is_share_active(sa_share_impl_t impl_share)
return B_FALSE;
}
return B_FALSE;
}
+/**
+ * Called to update a share's options. A share's options might be out of
+ * date if the share was loaded from disk (i.e. /etc/dfs/sharetab) and the
+ * "sharenfs" dataset property has changed in the meantime. This function
+ * also takes care of re-enabling the share if necessary.
+ */
static int
nfs_update_shareopts(sa_share_impl_t impl_share, const char *resource,
const char *shareopts)
static int
nfs_update_shareopts(sa_share_impl_t impl_share, const char *resource,
const char *shareopts)
@@
-594,7
+614,10
@@
nfs_update_shareopts(sa_share_impl_t impl_share, const char *resource,
return SA_OK;
}
return SA_OK;
}
-
+/**
+ * Clears a share's NFS options. Used by libshare to
+ * clean up shares that are about to be free()'d.
+ */
static void
nfs_clear_shareopts(sa_share_impl_t impl_share)
{
static void
nfs_clear_shareopts(sa_share_impl_t impl_share)
{
@@
-680,6
+703,9
@@
nfs_check_exportfs(void)
exit(0);
}
exit(0);
}
+/**
+ * Initializes the NFS functionality of libshare.
+ */
void
libshare_nfs_init(void)
{
void
libshare_nfs_init(void)
{