glusterfs/contrib/macfuse/mount_darwin.c
ShyamsundarR 20ef211cfa libglusterfs: Move devel headers under glusterfs directory
libglusterfs devel package headers are referenced in code using
include semantics for a program, this while it works can be better
especially when dealing with out of tree xlator builds or in
general out of tree devel package usage.

Towards this, the following changes are done,
- moved all devel headers under a glusterfs directory
- Included these headers using system header notation <> in all
code outside of libglusterfs
- Included these headers using own program notation "" within
libglusterfs

This change although big, is just moving around the headers and
making it correct when including these headers from other sources.

This helps us correctly include libglusterfs includes without
namespace conflicts.

Change-Id: Id2a98854e671a7ee5d73be44da5ba1a74252423b
Updates: bz#1193929
Signed-off-by: ShyamsundarR <srangana@redhat.com>
2018-12-05 21:47:04 +00:00

265 lines
8.0 KiB
C

/*
* Derived from mount_bsd.c from the fuse distribution.
*
* FUSE: Filesystem in Userspace
* Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>
* Copyright (C) 2007-2009 Amit Singh <asingh@gmail.com>
* Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
*
* This program can be distributed under the terms of the GNU LGPLv2.
* See the file COPYING.LIB.
*/
#undef _POSIX_C_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <paths.h>
#include <libproc.h>
#include <sys/utsname.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <AssertMacros.h>
#include "fuse_param.h"
#include "fuse_ioctl.h"
#include "glusterfs/glusterfs.h"
#include "glusterfs/logging.h"
#include "glusterfs/common-utils.h"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
int
gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
pid_t *mnt_pid, int status_fd) /* Not used on OS X */
{
int fd = 0;
int pid = 0;
int ret = 0;
char *fdnam = NULL;
char *dev = NULL;
char vstr[4];
unsigned vval = 0;
int i = 0;
const char *mountprog = OSXFUSE_MOUNT_PROG;
sig_t chldf = SIG_ERR;
char version[MAXHOSTNAMELEN + 1] = { 0 };
size_t version_len = MAXHOSTNAMELEN;
size_t version_len_desired = 0;
int r = 0;
char devpath[MAXPATHLEN] = { 0 };;
if (!mountpoint) {
gf_log ("glustefs-fuse", GF_LOG_ERROR,
"missing or invalid mount point");
goto err;
}
/* mount_fusefs should not try to spawn the daemon */
setenv("MOUNT_FUSEFS_SAFE", "1", 1);
/* to notify mount_fusefs it's called from lib */
setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
chldf = signal(SIGCHLD, SIG_DFL); /* So that we can wait4() below. */
if (chldf == SIG_ERR) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"signal() returned SIG_ERR: %s",
strerror(errno));
goto err;
}
/* check for user<->kernel match. */
ret = sysctlbyname(SYSCTL_OSXFUSE_VERSION_NUMBER, version,
&version_len, NULL, (size_t)0);
if (ret != 0) {
gf_log ("glustefs-fuse", GF_LOG_ERROR,
"sysctlbyname() returned error: %s",
strerror(errno));
goto err;
}
/* sysctlbyname() includes the trailing '\0' in version_len */
version_len_desired = sizeof ("2.x.y");
if (version_len != version_len_desired) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"version length mismatch for OSXFUSE %s",
version);
ret = -1;
goto err;
}
for (i = 0; i < 3; i++)
vstr[i] = version[2*i];
vstr[3] = '\0';
vval = strtoul(vstr, NULL, 10);
if (vval < 264) {
GFFUSE_LOGERR("OSXFUSE version %s is not supported", version);
ret = -1;
goto err;
}
gf_log("glusterfs-fuse", GF_LOG_INFO,
"OSXFUSE kext version supported %s", version);
fdnam = getenv("FUSE_DEV_FD");
if (fdnam) {
fd = strtol(fdnam, NULL, 10);
if (fd < 0) {
GFFUSE_LOGERR("invalid value given in FUSE_DEV_FD");
ret = -1;
goto err;
}
goto mount;
}
dev = getenv("FUSE_DEV_NAME");
if (!dev) {
for (r = 0; r < OSXFUSE_NDEVICES; r++) {
snprintf(devpath, MAXPATHLEN - 1,
_PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r);
if ((fd = open(devpath, O_RDWR)) < 0) {
GFFUSE_LOGERR("failed to open device %s (%s)",
devpath,
strerror(errno));
goto err;
}
dev = devpath;
goto mount;
}
}
fd = open(dev, O_RDWR);
if (fd < 0) {
GFFUSE_LOGERR("failed to open device %s (%s)", dev,
strerror(errno));
ret = -1;
goto err;
}
mount:
signal(SIGCHLD, chldf);
pid = fork();
if (pid == -1) {
GFFUSE_LOGERR("fork() failed (%s)", strerror(errno));
ret = -1;
goto err;
}
if (pid == 0) {
pid = fork();
if (pid == -1) {
GFFUSE_LOGERR("fork() failed (%s)", strerror(errno));
ret = -1;
goto err;
}
if (pid == 0) {
const char *argv[32];
int a = 0;
char *opts = NULL;
if (asprintf(&opts, "%s,fssubtype=glusterfs",
mnt_param) == -1) {
GFFUSE_LOGERR("asprintf() error: %s",
strerror(errno));
ret = -1;
goto err;
}
if (!fdnam)
asprintf(&fdnam, "%d", fd);
argv[a++] = mountprog;
if (opts) {
argv[a++] = "-o";
argv[a++] = opts;
}
argv[a++] = fdnam;
argv[a++] = mountpoint;
argv[a++] = NULL;
{
char title[MAXPATHLEN + 1] = { 0 };
u_int32_t len = MAXPATHLEN;
int ret = proc_pidpath(getpid(), title, len);
if (ret) {
setenv("MOUNT_FUSEFS_DAEMON_PATH",
title, 1);
}
}
execvp(mountprog, (char **) argv);
GFFUSE_LOGERR("OSXFUSE: failed to exec mount"
" program (%s)", strerror(errno));
_exit(1);
}
_exit(0);
}
ret = fd;
err:
if (ret == -1) {
if (fd > 0) {
close(fd);
}
}
return ret;
}
void
gf_fuse_unmount(const char *mountpoint, int fd)
{
int ret;
struct stat sbuf;
char dev[128];
char resolved_path[PATH_MAX];
char *ep, *rp = NULL;
unsigned int hs_complete = 0;
ret = ioctl(fd, FUSEDEVIOCGETHANDSHAKECOMPLETE, &hs_complete);
if (ret || !hs_complete) {
return;
}
if (fstat(fd, &sbuf) == -1) {
return;
}
devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
if (strncmp(dev, OSXFUSE_DEVICE_BASENAME,
sizeof(OSXFUSE_DEVICE_BASENAME) - 1)) {
return;
}
strtol(dev + sizeof(OSXFUSE_DEVICE_BASENAME) - 1, &ep, 10);
if (*ep != '\0') {
return;
}
rp = realpath(mountpoint, resolved_path);
if (rp) {
ret = unmount(resolved_path, 0);
}
close(fd);
return;
}