Changeset View
Changeset View
Standalone View
Standalone View
cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c
Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <strings.h> | #include <strings.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <zone.h> | #include <zone.h> | ||||
#include <sys/mntent.h> | #include <sys/mntent.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/statvfs.h> | #include <sys/statvfs.h> | ||||
#ifdef __FreeBSD__ | |||||
#include <sys/sysctl.h> | |||||
#endif | |||||
#include <libzfs.h> | #include <libzfs.h> | ||||
#include "libzfs_impl.h" | #include "libzfs_impl.h" | ||||
#include <thread_pool.h> | #include <thread_pool.h> | ||||
#include <libshare.h> | #include <libshare.h> | ||||
#define MAXISALEN 257 /* based on sysinfo(2) man page */ | #define MAXISALEN 257 /* based on sysinfo(2) man page */ | ||||
▲ Show 20 Lines • Show All 263 Lines • ▼ Show 20 Lines | zfs_mount(zfs_handle_t *zhp, const char *options, int flags) | ||||
char mountpoint[ZFS_MAXPROPLEN]; | char mountpoint[ZFS_MAXPROPLEN]; | ||||
if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) | if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) | ||||
return (0); | return (0); | ||||
return (zfs_mount_at(zhp, options, flags, mountpoint)); | return (zfs_mount_at(zhp, options, flags, mountpoint)); | ||||
} | } | ||||
#ifdef __FreeBSD__ | |||||
/* | |||||
* A helper function to look for FreeBSD-specific | |||||
* mount options, pre-mount. Right now, this looks | |||||
* at sysctl vfs.zfs.mount_options. The results from | |||||
* this need to be freed by the caller, and should be | |||||
* prepended to any user-requested mount options (since | |||||
* a user-requested option may undo one of the system | |||||
* default options). | |||||
*/ | |||||
char * | |||||
freebsd_default_mount_options(zfs_handle_t *zhp) | |||||
{ | |||||
char *retval = NULL; | |||||
size_t len = 0; | |||||
int rv; | |||||
rv = sysctlbyname("vfs.zfs.mount_options", NULL, &len, NULL, 0); | |||||
delphij: I think it would be safer to do:
```
if (sysctlbyname("vfs.zfs.mount_options", NULL, &len… | |||||
if (rv == -1) | |||||
return (NULL); | |||||
retval = malloc(len+1); | |||||
Not Done Inline Actionsretval should be checked before proceeding. Assuming malloc failed and returned NULL, we are essentially doing the same sysctlbyname above here, and would get 0, then write to the reserved block. delphij: retval should be checked before proceeding. Assuming malloc failed and returned NULL, we are… | |||||
Done Inline ActionsI changed up this code a bit. I'd actually had two implementations of the function at one point, and deleted the wrong one -- correct one uses strlcat and strlcpy, and more checks. sef: I changed up this code a bit. I'd actually had two implementations of the function at one… | |||||
rv = sysctlbyname("vfs.zfs.mount_options", retval, &len, NULL, 0); | |||||
if (rv == 0) { | |||||
retval[len] = 0; /* Ensure NUL end */ | |||||
return (retval); | |||||
} | |||||
free(retval); | |||||
return (NULL); | |||||
} | |||||
#endif /* __FreeBSD__ */ | |||||
int | int | ||||
zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, | zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, | ||||
const char *mountpoint) | const char *mountpoint) | ||||
{ | { | ||||
struct stat buf; | struct stat buf; | ||||
char mntopts[MNT_LINE_MAX]; | char mntopts[MNT_LINE_MAX]; | ||||
libzfs_handle_t *hdl = zhp->zfs_hdl; | libzfs_handle_t *hdl = zhp->zfs_hdl; | ||||
#ifdef __FreeBSD__ | |||||
char *default_mount_opts; | |||||
#endif | |||||
if (options == NULL) | if (options == NULL) | ||||
mntopts[0] = '\0'; | mntopts[0] = '\0'; | ||||
else | else | ||||
(void) strlcpy(mntopts, options, sizeof (mntopts)); | (void) strlcpy(mntopts, options, sizeof (mntopts)); | ||||
/* | /* | ||||
* If the pool is imported read-only then all mounts must be read-only | * If the pool is imported read-only then all mounts must be read-only | ||||
Show All 27 Lines | if ((flags & MS_OVERLAY) == 0 && | ||||
!dir_is_empty(mountpoint)) { | !dir_is_empty(mountpoint)) { | ||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, | zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, | ||||
"directory is not empty")); | "directory is not empty")); | ||||
return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, | return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, | ||||
dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); | dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef __FreeBSD__ | |||||
default_mount_opts = freebsd_default_mount_options(zhp); | |||||
if (default_mount_opts != NULL) { | |||||
const char *tmp = strdup(mntopts); | |||||
if (mntopts[0] != '\0') | |||||
Done Inline Actionsthis if..else block should be enclosed in a if (tmp != NULL) condition because tmp can be NULL. delphij: this if..else block should be enclosed in a if (tmp != NULL) condition because tmp can be NULL. | |||||
(void)snprintf(mntopts, sizeof(mntopts), "%s,%s", | |||||
default_mount_opts, tmp); | |||||
else | |||||
strlcpy(mntopts, default_mount_opts, sizeof(mntopts)); | |||||
free(tmp); | |||||
free(default_mount_opts); | |||||
} | |||||
#endif /* __FreeBSD__ */ | |||||
/* perform the mount */ | /* perform the mount */ | ||||
if (zmount(zfs_get_name(zhp), mountpoint, flags, | if (zmount(zfs_get_name(zhp), mountpoint, flags, | ||||
MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { | MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { | ||||
/* | /* | ||||
* Generic errors are nasty, but there are just way too many | * Generic errors are nasty, but there are just way too many | ||||
* from mount(), and they're well-understood. We pick a few | * from mount(), and they're well-understood. We pick a few | ||||
* common ones to improve upon. | * common ones to improve upon. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 1,315 Lines • Show Last 20 Lines |
I think it would be safer to do:
here.