summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshare
diff options
context:
space:
mode:
authormarks <none@none>2007-07-05 10:16:54 -0700
committermarks <none@none>2007-07-05 10:16:54 -0700
commita1ef5d638807e0f28bbc72101fcc8370489935f9 (patch)
tree1866886493cf244188e0a892cc5b29ca0e43d1e1 /usr/src/lib/libshare
parent09d2ffaf252a141e1ca507d0ab2fa16538e14c93 (diff)
downloadillumos-joyent-a1ef5d638807e0f28bbc72101fcc8370489935f9.tar.gz
6576474 cannot share directory on zfs filesystems with mountpoint set to legacy
Diffstat (limited to 'usr/src/lib/libshare')
-rw-r--r--usr/src/lib/libshare/common/libshare_zfs.c80
1 files changed, 70 insertions, 10 deletions
diff --git a/usr/src/lib/libshare/common/libshare_zfs.c b/usr/src/lib/libshare/common/libshare_zfs.c
index 69bbf4075c..3fa7646b51 100644
--- a/usr/src/lib/libshare/common/libshare_zfs.c
+++ b/usr/src/lib/libshare/common/libshare_zfs.c
@@ -26,12 +26,15 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <stdio.h>
#include <libzfs.h>
#include <string.h>
#include <strings.h>
#include <libshare.h>
#include "libshare_impl.h"
#include <libintl.h>
+#include <sys/mnttab.h>
+#include <sys/mntent.h>
extern sa_share_t _sa_add_share(sa_group_t, char *, int, int *);
extern sa_group_t _sa_create_zfs_group(sa_group_t, char *);
@@ -221,6 +224,35 @@ mountpoint_compare(const void *a, const void *b)
}
/*
+ * return legacy mountpoint. Caller provides space for mountpoint.
+ */
+int
+get_legacy_mountpoint(char *path, char *mountpoint, size_t len)
+{
+ FILE *fp;
+ struct mnttab entry;
+
+ if ((fp = fopen(MNTTAB, "r")) == NULL) {
+ return (1);
+ }
+
+ while (getmntent(fp, &entry) == 0) {
+
+ if (entry.mnt_fstype == NULL ||
+ strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
+ continue;
+
+ if (strcmp(entry.mnt_mountp, path) == 0) {
+ (void) strlcpy(mountpoint, entry.mnt_special, len);
+ (void) fclose(fp);
+ return (0);
+ }
+ }
+ (void) fclose(fp);
+ return (1);
+}
+
+/*
* get_zfs_dataset(impl_handle, path)
*
* get the name of the ZFS dataset the path is equivalent to. The
@@ -229,7 +261,8 @@ mountpoint_compare(const void *a, const void *b)
*/
static char *
-get_zfs_dataset(sa_handle_impl_t impl_handle, char *path)
+get_zfs_dataset(sa_handle_impl_t impl_handle, char *path,
+ boolean_t search_mnttab)
{
size_t i, count = 0;
char *dataset = NULL;
@@ -249,8 +282,19 @@ get_zfs_dataset(sa_handle_impl_t impl_handle, char *path)
/* mountpoint must be a path */
if (strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) == 0 ||
- strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0)
+ strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) {
+ /*
+ * Search mmttab for mountpoint
+ */
+
+ if (search_mnttab == B_TRUE &&
+ get_legacy_mountpoint(path, mountpoint,
+ sizeof (mountpoint)) == 0) {
+ dataset = mountpoint;
+ break;
+ }
continue;
+ }
/* canmount must be set */
canmount[0] = '\0';
@@ -323,7 +367,7 @@ sa_zfs_is_shared(sa_handle_t sahandle, char *path)
char shareopts[ZFS_MAXPROPLEN];
libzfs_handle_t *libhandle;
- dataset = get_zfs_dataset((sa_handle_t)sahandle, path);
+ dataset = get_zfs_dataset((sa_handle_t)sahandle, path, B_FALSE);
if (dataset != NULL) {
libhandle = libzfs_init();
if (libhandle != NULL) {
@@ -738,7 +782,7 @@ sa_zfs_set_sharenfs(sa_group_t group, char *path, int on)
impl_handle = (sa_handle_impl_t)sa_find_group_handle(group);
assert(impl_handle != NULL);
if (impl_handle != NULL)
- dataset = get_zfs_dataset(impl_handle, path);
+ dataset = get_zfs_dataset(impl_handle, path, B_FALSE);
else
ret = SA_SYSTEM_ERR;
@@ -808,7 +852,7 @@ sa_zfs_update(sa_group_t group)
group);
if (impl_handle != NULL)
dataset = get_zfs_dataset(
- impl_handle, path);
+ impl_handle, path, B_FALSE);
else
ret = SA_SYSTEM_ERR;
@@ -945,6 +989,7 @@ sa_share_zfs(sa_share_t share, char *path, share_t *sh,
int err = EINVAL;
int i, j;
char newpath[MAXPATHLEN];
+ char *pathp;
/*
* First find the dataset name
@@ -959,14 +1004,29 @@ sa_share_zfs(sa_share_t share, char *path, share_t *sh,
/*
* If get_zfs_dataset fails, see if it is a subdirectory
*/
- (void) strlcpy(newpath, path, sizeof (newpath));
- while ((dataset = get_zfs_dataset(sahandle, newpath)) == NULL) {
+
+ pathp = path;
+ while ((dataset = get_zfs_dataset(sahandle, pathp, B_TRUE)) == NULL) {
char *p;
- if (p = strrchr(newpath, '/'))
- *p = '\0';
- else
+ if (pathp == path) {
+ (void) strlcpy(newpath, path, sizeof (newpath));
+ pathp = newpath;
+ }
+
+ /*
+ * chop off part of path, but if we are at root then
+ * make sure path is a /
+ */
+ if ((strlen(pathp) > 1) && (p = strrchr(pathp, '/'))) {
+ if (pathp == p) {
+ *(p + 1) = '\0'; /* skip over /, root case */
+ } else {
+ *p = '\0';
+ }
+ } else {
return (SA_SYSTEM_ERR);
+ }
}
libhandle = libzfs_init();