|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/daemon/indirect.c.device-node-control autofs-5.0.3/daemon/indirect.c
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/daemon/indirect.c.device-node-control 2008-02-25 08:58:46.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -43,6 +43,8 @@ extern pthread_attr_t thread_attr;
|
|
Ian Kent |
e6cf32 |
static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
Ian Kent |
e6cf32 |
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+static const unsigned int indirect = AUTOFS_TYPE_INDIRECT;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
struct mnt_list *this;
|
|
Ian Kent |
e6cf32 |
@@ -88,19 +90,20 @@ static int unlink_mount_tree(struct auto
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static int do_mount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
time_t timeout = ap->exp_timeout;
|
|
Ian Kent |
e6cf32 |
char *options = NULL;
|
|
Ian Kent |
e6cf32 |
const char *type, *map_name = NULL;
|
|
Ian Kent |
e6cf32 |
struct stat st;
|
|
Ian Kent |
e6cf32 |
struct mnt_list *mnts;
|
|
Ian Kent |
e6cf32 |
- int cl_flags, ret;
|
|
Ian Kent |
e6cf32 |
+ int ret;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
|
|
Ian Kent |
e6cf32 |
if (mnts) {
|
|
Ian Kent |
e6cf32 |
ret = unlink_mount_tree(ap, mnts);
|
|
Ian Kent |
e6cf32 |
free_mnt_list(mnts);
|
|
Ian Kent |
e6cf32 |
if (!ret) {
|
|
Ian Kent |
e6cf32 |
- debug(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ error(ap->logopt,
|
|
Ian Kent |
e6cf32 |
"already mounted as other than autofs "
|
|
Ian Kent |
e6cf32 |
"or failed to unlink entry in tree");
|
|
Ian Kent |
e6cf32 |
goto out_err;
|
|
Ian Kent |
e6cf32 |
@@ -108,8 +111,10 @@ static int do_mount_autofs_indirect(stru
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
options = make_options_string(ap->path, ap->kpipefd, NULL);
|
|
Ian Kent |
e6cf32 |
- if (!options)
|
|
Ian Kent |
e6cf32 |
+ if (!options) {
|
|
Ian Kent |
e6cf32 |
+ error(ap->logopt, "options string error");
|
|
Ian Kent |
e6cf32 |
goto out_err;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/* In case the directory doesn't exist, try to mkdir it */
|
|
Ian Kent |
e6cf32 |
if (mkdir_path(ap->path, 0555) < 0) {
|
|
Ian Kent |
e6cf32 |
@@ -147,22 +152,15 @@ static int do_mount_autofs_indirect(stru
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
options = NULL;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- /* Root directory for ioctl()'s */
|
|
Ian Kent |
e6cf32 |
- ap->ioctlfd = open(ap->path, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
- if (ap->ioctlfd < 0) {
|
|
Ian Kent |
e6cf32 |
+ if (ops->open(ap->logopt, &ap->ioctlfd, -1, ap->path, indirect)) {
|
|
Ian Kent |
e6cf32 |
crit(ap->logopt,
|
|
Ian Kent |
e6cf32 |
"failed to create ioctl fd for autofs path %s", ap->path);
|
|
Ian Kent |
e6cf32 |
goto out_umount;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- if ((cl_flags = fcntl(ap->ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ap->ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
|
|
Ian Kent |
e6cf32 |
+ ops->timeout(ap->logopt, ap->ioctlfd, &timeout);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (ap->exp_timeout)
|
|
Ian Kent |
e6cf32 |
info(ap->logopt,
|
|
Ian Kent |
e6cf32 |
@@ -235,8 +233,10 @@ int mount_autofs_indirect(struct autofs_
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
- int ret, rv, retries;
|
|
Ian Kent |
e6cf32 |
+ int rv, retries;
|
|
Ian Kent |
e6cf32 |
+ unsigned int ret;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/*
|
|
Ian Kent |
e6cf32 |
* Since submounts look after themselves the parent never knows
|
|
Ian Kent |
e6cf32 |
@@ -248,7 +248,7 @@ int umount_autofs_indirect(struct autofs
|
|
Ian Kent |
e6cf32 |
lookup_source_close_ioctlfd(ap->parent, ap->path);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/* If we are trying to shutdown make sure we can umount */
|
|
Ian Kent |
e6cf32 |
- rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret;;
|
|
Ian Kent |
e6cf32 |
+ rv = ops->askumount(ap->logopt, ap->ioctlfd, &ret;;
|
|
Ian Kent |
e6cf32 |
if (rv == -1) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
logerr("ioctl failed: %s", estr);
|
|
Ian Kent |
e6cf32 |
@@ -258,8 +258,8 @@ int umount_autofs_indirect(struct autofs
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
- close(ap->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->catatonic(ap->logopt, ap->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ap->ioctlfd);
|
|
Ian Kent |
e6cf32 |
ap->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
close(ap->state_pipe[0]);
|
|
Ian Kent |
e6cf32 |
close(ap->state_pipe[1]);
|
|
Ian Kent |
e6cf32 |
@@ -320,48 +320,6 @@ force_umount:
|
|
Ian Kent |
e6cf32 |
return rv;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
-static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when)
|
|
Ian Kent |
e6cf32 |
-{
|
|
Ian Kent |
e6cf32 |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
- int ret, retries;
|
|
Ian Kent |
e6cf32 |
- struct stat st;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (fstat(ioctlfd, &st) == -1) {
|
|
Ian Kent |
e6cf32 |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
- debug(ap->logopt, "fstat failed: %s", estr);
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- retries = (count_mounts(ap->logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- while (retries--) {
|
|
Ian Kent |
e6cf32 |
- struct timespec tm = {0, 100000000};
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- /* Ggenerate expire message for the mount. */
|
|
Ian Kent |
e6cf32 |
- ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_DIRECT, &when);
|
|
Ian Kent |
e6cf32 |
- if (ret == -1) {
|
|
Ian Kent |
e6cf32 |
- /* Mount has gone away */
|
|
Ian Kent |
e6cf32 |
- if (errno == EBADF || errno == EINVAL)
|
|
Ian Kent |
e6cf32 |
- return 1;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- /*
|
|
Ian Kent |
e6cf32 |
- * Other than EAGAIN is an expire error so continue.
|
|
Ian Kent |
e6cf32 |
- * Kernel will try the next mount.
|
|
Ian Kent |
e6cf32 |
- */
|
|
Ian Kent |
e6cf32 |
- if (errno == EAGAIN)
|
|
Ian Kent |
e6cf32 |
- break;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- nanosleep(&tm, NULL);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (!ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
|
|
Ian Kent |
e6cf32 |
- if (!ret)
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- return 1;
|
|
Ian Kent |
e6cf32 |
-}
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
static void mnts_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
struct mnt_list *mnts = (struct mnt_list *) arg;
|
|
Ian Kent |
e6cf32 |
@@ -371,6 +329,7 @@ static void mnts_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap;
|
|
Ian Kent |
e6cf32 |
struct mapent *me = NULL;
|
|
Ian Kent |
e6cf32 |
struct mnt_list *mnts = NULL, *next;
|
|
Ian Kent |
e6cf32 |
@@ -458,8 +417,8 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
e6cf32 |
debug(ap->logopt, "expire %s", next->path);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
e6cf32 |
- ret = expire_indirect(ap, ioctlfd, next->path, now);
|
|
Ian Kent |
e6cf32 |
- if (!ret)
|
|
Ian Kent |
e6cf32 |
+ ret = ops->expire(ap->logopt, ioctlfd, next->path, now);
|
|
Ian Kent |
e6cf32 |
+ if (ret)
|
|
Ian Kent |
e6cf32 |
left++;
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
@@ -472,8 +431,8 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
e6cf32 |
*/
|
|
Ian Kent |
e6cf32 |
if (mnts) {
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
e6cf32 |
- ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
|
|
Ian Kent |
e6cf32 |
- if (!ret)
|
|
Ian Kent |
e6cf32 |
+ ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, now);
|
|
Ian Kent |
e6cf32 |
+ if (ret)
|
|
Ian Kent |
e6cf32 |
left++;
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
@@ -495,8 +454,8 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
e6cf32 |
pthread_cleanup_pop(1);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (submnts)
|
|
Ian Kent |
e6cf32 |
- debug(ap->logopt,
|
|
Ian Kent |
e6cf32 |
- "%d submounts remaining in %s", submnts, ap->path);
|
|
Ian Kent |
e6cf32 |
+ info(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ "%d submounts remaining in %s", submnts, ap->path);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/*
|
|
Ian Kent |
e6cf32 |
* EXPIRE_MULTI is synchronous, so we can be sure (famous last
|
|
Ian Kent |
e6cf32 |
@@ -527,8 +486,11 @@ static void pending_cond_destroy(void *a
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void expire_send_fail(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt = arg;
|
|
Ian Kent |
e6cf32 |
- send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ struct autofs_point *ap = mt->ap;
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void free_pending_args(void *arg)
|
|
Ian Kent |
e6cf32 |
@@ -546,6 +508,7 @@ static void expire_mutex_unlock(void *ar
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void *do_expire_indirect(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap;
|
|
Ian Kent |
e6cf32 |
int status, state;
|
|
Ian Kent |
e6cf32 |
@@ -572,9 +535,11 @@ static void *do_expire_indirect(void *ar
|
|
Ian Kent |
e6cf32 |
status = do_expire(mt->ap, mt->name, mt->len);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
e6cf32 |
if (status)
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, mt->wait_queue_token, -status);
|
|
Ian Kent |
e6cf32 |
else
|
|
Ian Kent |
e6cf32 |
- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_ready(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
pthread_cleanup_pop(0);
|
|
Ian Kent |
e6cf32 |
@@ -586,6 +551,7 @@ static void *do_expire_indirect(void *ar
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_indirect_t *pkt)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
pthread_t thid;
|
|
Ian Kent |
e6cf32 |
@@ -600,7 +566,8 @@ int handle_packet_expire_indirect(struct
|
|
Ian Kent |
e6cf32 |
if (!mt) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
logerr("malloc: %s", estr);
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, pkt->wait_queue_token, -ENOMEM);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
@@ -622,7 +589,8 @@ int handle_packet_expire_indirect(struct
|
|
Ian Kent |
e6cf32 |
status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
|
|
Ian Kent |
e6cf32 |
if (status) {
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "expire thread create failed");
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, pkt->wait_queue_token, -status);
|
|
Ian Kent |
e6cf32 |
expire_mutex_unlock(NULL);
|
|
Ian Kent |
e6cf32 |
pending_cond_destroy(mt);
|
|
Ian Kent |
e6cf32 |
free_pending_args(mt);
|
|
Ian Kent |
e6cf32 |
@@ -647,8 +615,11 @@ int handle_packet_expire_indirect(struct
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void mount_send_fail(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt = arg;
|
|
Ian Kent |
e6cf32 |
- send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ struct autofs_point *ap = mt->ap;
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void mount_mutex_unlock(void *arg)
|
|
Ian Kent |
e6cf32 |
@@ -660,6 +631,7 @@ static void mount_mutex_unlock(void *arg
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void *do_mount_indirect(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap;
|
|
Ian Kent |
e6cf32 |
char buf[PATH_MAX + 1];
|
|
Ian Kent |
e6cf32 |
@@ -837,10 +809,13 @@ cont:
|
|
Ian Kent |
e6cf32 |
status = lookup_nss_mount(ap, NULL, mt->name, mt->len);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
e6cf32 |
if (status) {
|
|
Ian Kent |
e6cf32 |
- send_ready(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_ready(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
info(ap->logopt, "mounted %s", buf);
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ /* TODO: get mount return status from lookup_nss_mount */
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
info(ap->logopt, "failed to mount %s", buf);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
@@ -854,6 +829,7 @@ cont:
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missing_indirect_t *pkt)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
pthread_t thid;
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
@@ -868,7 +844,8 @@ int handle_packet_missing_indirect(struc
|
|
Ian Kent |
e6cf32 |
if (ap->shutdown ||
|
|
Ian Kent |
e6cf32 |
ap->state == ST_SHUTDOWN_FORCE ||
|
|
Ian Kent |
e6cf32 |
ap->state == ST_SHUTDOWN) {
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, pkt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
@@ -877,7 +854,8 @@ int handle_packet_missing_indirect(struc
|
|
Ian Kent |
e6cf32 |
if (!mt) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
logerr("malloc: %s", estr);
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, pkt->wait_queue_token, -ENOMEM);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
@@ -903,7 +881,8 @@ int handle_packet_missing_indirect(struc
|
|
Ian Kent |
e6cf32 |
status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
|
|
Ian Kent |
e6cf32 |
if (status) {
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "expire thread create failed");
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ap->ioctlfd, pkt->wait_queue_token, -status);
|
|
Ian Kent |
e6cf32 |
mount_mutex_unlock(NULL);
|
|
Ian Kent |
e6cf32 |
pending_cond_destroy(mt);
|
|
Ian Kent |
e6cf32 |
free_pending_args(mt);
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/daemon/state.c.device-node-control autofs-5.0.3/daemon/state.c
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/daemon/state.c.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/daemon/state.c 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -93,6 +93,7 @@ void nextstate(int statefd, enum states
|
|
Ian Kent |
e6cf32 |
*/
|
|
Ian Kent |
e6cf32 |
void expire_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
pthread_t thid = pthread_self();
|
|
Ian Kent |
e6cf32 |
struct expire_args *ec;
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap;
|
|
Ian Kent |
e6cf32 |
@@ -113,7 +114,8 @@ void expire_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/* Check to see if expire process finished */
|
|
Ian Kent |
e6cf32 |
if (thid == ap->exp_thread) {
|
|
Ian Kent |
e6cf32 |
- int rv, idle;
|
|
Ian Kent |
e6cf32 |
+ unsigned int idle;
|
|
Ian Kent |
e6cf32 |
+ int rv;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
ap->exp_thread = 0;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -135,7 +137,7 @@ void expire_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
* allowing it to shutdown.
|
|
Ian Kent |
e6cf32 |
*/
|
|
Ian Kent |
e6cf32 |
if (ap->submount && !success) {
|
|
Ian Kent |
e6cf32 |
- rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &idle);
|
|
Ian Kent |
e6cf32 |
+ rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle);
|
|
Ian Kent |
e6cf32 |
if (!rv && idle && ap->submount > 1) {
|
|
Ian Kent |
e6cf32 |
next = ST_SHUTDOWN_PENDING;
|
|
Ian Kent |
e6cf32 |
break;
|
|
Ian Kent |
e6cf32 |
@@ -160,7 +162,7 @@ void expire_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
* shutdown return to ready state unless we have
|
|
Ian Kent |
e6cf32 |
* been signaled to shutdown.
|
|
Ian Kent |
e6cf32 |
*/
|
|
Ian Kent |
e6cf32 |
- rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &idle);
|
|
Ian Kent |
e6cf32 |
+ rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle);
|
|
Ian Kent |
e6cf32 |
if (!idle && !ap->shutdown) {
|
|
Ian Kent |
e6cf32 |
next = ST_READY;
|
|
Ian Kent |
e6cf32 |
if (!ap->submount)
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/daemon/lookup.c.device-node-control autofs-5.0.3/daemon/lookup.c
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/daemon/lookup.c.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/daemon/lookup.c 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -1148,7 +1148,8 @@ int lookup_source_close_ioctlfd(struct a
|
|
Ian Kent |
e6cf32 |
me = cache_lookup_distinct(mc, key);
|
|
Ian Kent |
e6cf32 |
if (me) {
|
|
Ian Kent |
e6cf32 |
if (me->ioctlfd != -1) {
|
|
Ian Kent |
e6cf32 |
- close(me->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, me->ioctlfd);
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/daemon/direct.c.device-node-control autofs-5.0.3/daemon/direct.c
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/daemon/direct.c.device-node-control 2008-02-25 08:58:46.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/daemon/direct.c 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -42,6 +42,9 @@
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
extern pthread_attr_t thread_attr;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+static const unsigned int direct = AUTOFS_TYPE_DIRECT;
|
|
Ian Kent |
e6cf32 |
+static const unsigned int offset = AUTOFS_TYPE_OFFSET;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
struct mnt_params {
|
|
Ian Kent |
e6cf32 |
char *options;
|
|
Ian Kent |
e6cf32 |
};
|
|
Ian Kent |
e6cf32 |
@@ -88,6 +91,7 @@ static void mnts_cleanup(void *arg)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
int ioctlfd, rv, left, retries;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -106,23 +110,13 @@ int do_umount_autofs_direct(struct autof
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
ioctlfd = me->ioctlfd;
|
|
Ian Kent |
e6cf32 |
- } else {
|
|
Ian Kent |
e6cf32 |
- int cl_flags;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
- if (ioctlfd != -1) {
|
|
Ian Kent |
e6cf32 |
- if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
+ } else
|
|
Ian Kent |
e6cf32 |
+ ops->open(ap->logopt, &ioctlfd, -1, me->key, direct);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (ioctlfd >= 0) {
|
|
Ian Kent |
e6cf32 |
- int status = 1;
|
|
Ian Kent |
e6cf32 |
+ unsigned int status = 1;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
|
|
Ian Kent |
e6cf32 |
+ rv = ops->askumount(ap->logopt, ioctlfd, &status);
|
|
Ian Kent |
e6cf32 |
if (rv) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "ioctl failed: %s", estr);
|
|
Ian Kent |
e6cf32 |
@@ -135,19 +129,17 @@ int do_umount_autofs_direct(struct autof
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->catatonic(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
goto force_umount;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->catatonic(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
error(ap->logopt,
|
|
Ian Kent |
e6cf32 |
"couldn't get ioctl fd for direct mount %s", me->key);
|
|
Ian Kent |
e6cf32 |
- debug(ap->logopt, "open: %s", estr);
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -297,10 +289,11 @@ static int unlink_mount_tree(struct auto
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct mnt_params *mp;
|
|
Ian Kent |
e6cf32 |
time_t timeout = ap->exp_timeout;
|
|
Ian Kent |
e6cf32 |
struct stat st;
|
|
Ian Kent |
e6cf32 |
- int status, ret, ioctlfd, cl_flags;
|
|
Ian Kent |
e6cf32 |
+ int status, ret, ioctlfd;
|
|
Ian Kent |
e6cf32 |
struct list_head list;
|
|
Ian Kent |
e6cf32 |
const char *map_name;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -313,16 +306,8 @@ int do_mount_autofs_direct(struct autofs
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
save_ioctlfd = ioctlfd = me->ioctlfd;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- if (ioctlfd == -1) {
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
- if (ioctlfd != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags = fcntl(ioctlfd, F_GETFD, 0);
|
|
Ian Kent |
e6cf32 |
- if (cl_flags != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
+ if (ioctlfd == -1)
|
|
Ian Kent |
e6cf32 |
+ ops->open(ap->logopt, &ioctlfd, -1, me->key, direct);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (ioctlfd < 0) {
|
|
Ian Kent |
e6cf32 |
error(ap->logopt,
|
|
Ian Kent |
e6cf32 |
@@ -331,13 +316,14 @@ int do_mount_autofs_direct(struct autofs
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout);
|
|
Ian Kent |
e6cf32 |
+ ops->timeout(ap->logopt, ioctlfd, &tout);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (save_ioctlfd == -1)
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
if (!unlink_mount_tree(ap, &list)) {
|
|
Ian Kent |
e6cf32 |
debug(ap->logopt,
|
|
Ian Kent |
e6cf32 |
"already mounted as other than autofs "
|
|
Ian Kent |
e6cf32 |
@@ -402,22 +388,16 @@ int do_mount_autofs_direct(struct autofs
|
|
Ian Kent |
e6cf32 |
goto out_err;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- /* Root directory for ioctl()'s */
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
+ ops->open(ap->logopt, &ioctlfd, -1, me->key, direct);
|
|
Ian Kent |
e6cf32 |
if (ioctlfd < 0) {
|
|
Ian Kent |
e6cf32 |
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
|
|
Ian Kent |
e6cf32 |
goto out_umount;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
/* Calculate the timeouts */
|
|
Ian Kent |
e6cf32 |
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
|
|
Ian Kent |
e6cf32 |
+ ops->timeout(ap->logopt, ioctlfd, &timeout);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (ap->exp_timeout)
|
|
Ian Kent |
e6cf32 |
info(ap->logopt,
|
|
Ian Kent |
e6cf32 |
@@ -438,14 +418,14 @@ int do_mount_autofs_direct(struct autofs
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
debug(ap->logopt, "mounted trigger %s", me->key);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
out_close:
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
out_umount:
|
|
Ian Kent |
e6cf32 |
/* TODO: maybe force umount (-l) */
|
|
Ian Kent |
e6cf32 |
umount(me->key);
|
|
Ian Kent |
e6cf32 |
@@ -537,8 +517,9 @@ int mount_autofs_direct(struct autofs_po
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
- int ioctlfd, cl_flags, rv = 1, retries;
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, rv = 1, retries;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (me->ioctlfd != -1) {
|
|
Ian Kent |
e6cf32 |
if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) {
|
|
Ian Kent |
e6cf32 |
@@ -555,20 +536,13 @@ int umount_autofs_offset(struct autofs_p
|
|
Ian Kent |
e6cf32 |
me->key);
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
- if (ioctlfd != -1) {
|
|
Ian Kent |
e6cf32 |
- if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
+ ops->open(ap->logopt, &ioctlfd, -1, me->key, offset);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (ioctlfd >= 0) {
|
|
Ian Kent |
e6cf32 |
- int status = 1;
|
|
Ian Kent |
e6cf32 |
+ unsigned int status = 1;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
|
|
Ian Kent |
e6cf32 |
+ rv = ops->askumount(ap->logopt, ioctlfd, &status);
|
|
Ian Kent |
e6cf32 |
if (rv) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
logerr("ioctl failed: %s", estr);
|
|
Ian Kent |
e6cf32 |
@@ -581,14 +555,14 @@ int umount_autofs_offset(struct autofs_p
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->catatonic(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
goto force_umount;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->catatonic(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
struct stat st;
|
|
Ian Kent |
e6cf32 |
char *estr;
|
|
Ian Kent |
e6cf32 |
@@ -653,11 +627,12 @@ force_umount:
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
struct mnt_params *mp;
|
|
Ian Kent |
e6cf32 |
time_t timeout = ap->exp_timeout;
|
|
Ian Kent |
e6cf32 |
struct stat st;
|
|
Ian Kent |
e6cf32 |
- int ioctlfd, cl_flags, status, ret;
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, status, ret;
|
|
Ian Kent |
e6cf32 |
const char *type, *map_name = NULL;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
|
|
Ian Kent |
e6cf32 |
@@ -760,19 +735,13 @@ int mount_autofs_offset(struct autofs_po
|
|
Ian Kent |
e6cf32 |
goto out_err;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- /* Root directory for ioctl()'s */
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
+ ops->open(ap->logopt, &ioctlfd, -1, me->key, offset);
|
|
Ian Kent |
e6cf32 |
if (ioctlfd < 0) {
|
|
Ian Kent |
e6cf32 |
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
|
|
Ian Kent |
e6cf32 |
goto out_umount;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
|
|
Ian Kent |
e6cf32 |
+ ops->timeout(ap->logopt, ioctlfd, &timeout);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
ret = fstat(ioctlfd, &st);
|
|
Ian Kent |
e6cf32 |
if (ret == -1) {
|
|
Ian Kent |
e6cf32 |
@@ -783,14 +752,14 @@ int mount_autofs_offset(struct autofs_po
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
debug(ap->logopt, "mounted trigger %s", me->key);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
out_close:
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
out_umount:
|
|
Ian Kent |
e6cf32 |
umount(me->key);
|
|
Ian Kent |
e6cf32 |
out_err:
|
|
Ian Kent |
e6cf32 |
@@ -800,53 +769,9 @@ out_err:
|
|
Ian Kent |
e6cf32 |
return -1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
-static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
|
|
Ian Kent |
e6cf32 |
-{
|
|
Ian Kent |
e6cf32 |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
- int ret, retries;
|
|
Ian Kent |
e6cf32 |
- struct stat st;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (fstat(ioctlfd, &st) == -1) {
|
|
Ian Kent |
e6cf32 |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
- debug(logopt, "fstat failed: %s", estr);
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- while (retries--) {
|
|
Ian Kent |
e6cf32 |
- struct timespec tm = {0, 100000000};
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- /* Ggenerate expire message for the mount. */
|
|
Ian Kent |
e6cf32 |
- ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_DIRECT, &when);
|
|
Ian Kent |
e6cf32 |
- if (ret == -1) {
|
|
Ian Kent |
e6cf32 |
- /* Mount has gone away */
|
|
Ian Kent |
e6cf32 |
- if (errno == EBADF || errno == EINVAL)
|
|
Ian Kent |
e6cf32 |
- return 1;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- /*
|
|
Ian Kent |
e6cf32 |
- * Other than EAGAIN is an expire error so continue.
|
|
Ian Kent |
e6cf32 |
- * Kernel try the same mount again, limited by
|
|
Ian Kent |
e6cf32 |
- * retries (ie. number of mounts directly under
|
|
Ian Kent |
e6cf32 |
- * mount point, should always be one for direct
|
|
Ian Kent |
e6cf32 |
- * mounts).
|
|
Ian Kent |
e6cf32 |
- */
|
|
Ian Kent |
e6cf32 |
- if (errno == EAGAIN)
|
|
Ian Kent |
e6cf32 |
- break;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- nanosleep(&tm, NULL);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (!ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
|
|
Ian Kent |
e6cf32 |
- if (!ret)
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- return 1;
|
|
Ian Kent |
e6cf32 |
-}
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
void *expire_proc_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct mnt_list *mnts = NULL, *next;
|
|
Ian Kent |
e6cf32 |
struct list_head list, *p;
|
|
Ian Kent |
e6cf32 |
struct expire_args *ea;
|
|
Ian Kent |
e6cf32 |
@@ -958,8 +883,8 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
ioctlfd = me->ioctlfd;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ret = expire_direct(ioctlfd, next->path, now, ap->logopt);
|
|
Ian Kent |
e6cf32 |
- if (!ret) {
|
|
Ian Kent |
e6cf32 |
+ ret = ops->expire(ap->logopt, ioctlfd, next->path, now);
|
|
Ian Kent |
e6cf32 |
+ if (ret) {
|
|
Ian Kent |
e6cf32 |
left++;
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
e6cf32 |
continue;
|
|
Ian Kent |
e6cf32 |
@@ -991,8 +916,8 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
debug(ap->logopt, "send expire to trigger %s", next->path);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
e6cf32 |
- ret = expire_direct(ioctlfd, next->path, now, ap->logopt);
|
|
Ian Kent |
e6cf32 |
- if (!ret)
|
|
Ian Kent |
e6cf32 |
+ ret = ops->expire(ap->logopt, ioctlfd, next->path, now);
|
|
Ian Kent |
e6cf32 |
+ if (ret)
|
|
Ian Kent |
e6cf32 |
left++;
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
@@ -1023,8 +948,11 @@ static void pending_cond_destroy(void *a
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void expire_send_fail(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt = arg;
|
|
Ian Kent |
e6cf32 |
- send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ struct autofs_point *ap = mt->ap;
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void free_pending_args(void *arg)
|
|
Ian Kent |
e6cf32 |
@@ -1042,6 +970,7 @@ static void expire_mutex_unlock(void *ar
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void *do_expire_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap;
|
|
Ian Kent |
e6cf32 |
size_t len;
|
|
Ian Kent |
e6cf32 |
@@ -1076,15 +1005,16 @@ static void *do_expire_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
status = do_expire(ap, mt->name, len);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
e6cf32 |
if (status)
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
else {
|
|
Ian Kent |
e6cf32 |
struct mapent *me;
|
|
Ian Kent |
e6cf32 |
cache_readlock(mt->mc);
|
|
Ian Kent |
e6cf32 |
me = cache_lookup_distinct(mt->mc, mt->name);
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
cache_unlock(mt->mc);
|
|
Ian Kent |
e6cf32 |
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -1097,6 +1027,7 @@ static void *do_expire_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_direct_t *pkt)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct map_source *map;
|
|
Ian Kent |
e6cf32 |
struct mapent_cache *mc = NULL;
|
|
Ian Kent |
e6cf32 |
struct mapent *me = NULL;
|
|
Ian Kent |
e6cf32 |
@@ -1146,7 +1077,8 @@ int handle_packet_expire_direct(struct a
|
|
Ian Kent |
e6cf32 |
if (!mt) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "malloc: %s", estr);
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, me->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ me->ioctlfd, pkt->wait_queue_token, -ENOMEM);
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
@@ -1175,7 +1107,8 @@ int handle_packet_expire_direct(struct a
|
|
Ian Kent |
e6cf32 |
status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
|
|
Ian Kent |
e6cf32 |
if (status) {
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "expire thread create failed");
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, mt->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ mt->ioctlfd, pkt->wait_queue_token, -status);
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
expire_mutex_unlock(NULL);
|
|
Ian Kent |
e6cf32 |
pending_cond_destroy(mt);
|
|
Ian Kent |
e6cf32 |
@@ -1203,9 +1136,11 @@ int handle_packet_expire_direct(struct a
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void mount_send_fail(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt = arg;
|
|
Ian Kent |
e6cf32 |
- send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ struct autofs_point *ap = mt->ap;
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void mount_mutex_unlock(void *arg)
|
|
Ian Kent |
e6cf32 |
@@ -1217,6 +1152,7 @@ static void mount_mutex_unlock(void *arg
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
static void *do_mount_direct(void *arg)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap;
|
|
Ian Kent |
e6cf32 |
struct passwd pw;
|
|
Ian Kent |
e6cf32 |
@@ -1409,15 +1345,19 @@ cont:
|
|
Ian Kent |
e6cf32 |
cache_unlock(mt->mc);
|
|
Ian Kent |
e6cf32 |
if (set_fd) {
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = mt->ioctlfd;
|
|
Ian Kent |
e6cf32 |
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->send_ready(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
- send_ready(ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->send_ready(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
info(ap->logopt, "mounted %s", mt->name);
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
- send_fail(mt->ap->logopt, mt->ioctlfd, mt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ /* TODO: get mount return status from lookup_nss_mount */
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, mt->ioctlfd);
|
|
Ian Kent |
e6cf32 |
info(ap->logopt, "failed to mount %s", mt->name);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
@@ -1431,6 +1371,7 @@ cont:
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_direct_t *pkt)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct map_source *map;
|
|
Ian Kent |
e6cf32 |
struct mapent_cache *mc = NULL;
|
|
Ian Kent |
e6cf32 |
struct mapent *me = NULL;
|
|
Ian Kent |
e6cf32 |
@@ -1438,7 +1379,8 @@ int handle_packet_missing_direct(struct
|
|
Ian Kent |
e6cf32 |
struct pending_args *mt;
|
|
Ian Kent |
e6cf32 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
int status = 0;
|
|
Ian Kent |
e6cf32 |
- int ioctlfd, cl_flags, state;
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, state;
|
|
Ian Kent |
e6cf32 |
+ unsigned int type;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -1475,12 +1417,16 @@ int handle_packet_missing_direct(struct
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+ type = direct;
|
|
Ian Kent |
e6cf32 |
+ if (me->multi != me && !list_empty(&me->multi_list))
|
|
Ian Kent |
e6cf32 |
+ type = offset;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
if (me->ioctlfd != -1) {
|
|
Ian Kent |
e6cf32 |
/* Maybe someone did a manual umount, clean up ! */
|
|
Ian Kent |
e6cf32 |
ioctlfd = me->ioctlfd;
|
|
Ian Kent |
e6cf32 |
me->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
} else
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
+ ops->open(ap->logopt, &ioctlfd, -1, me->key, type);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
if (ioctlfd == -1) {
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
@@ -1490,11 +1436,6 @@ int handle_packet_missing_direct(struct
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
e6cf32 |
- cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
- fcntl(ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
debug(ap->logopt, "token %ld, name %s, request pid %u",
|
|
Ian Kent |
e6cf32 |
(unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -1502,8 +1443,9 @@ int handle_packet_missing_direct(struct
|
|
Ian Kent |
e6cf32 |
if (ap->shutdown ||
|
|
Ian Kent |
e6cf32 |
ap->state == ST_SHUTDOWN_FORCE ||
|
|
Ian Kent |
e6cf32 |
ap->state == ST_SHUTDOWN) {
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ioctlfd, pkt->wait_queue_token, -ENOENT);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
@@ -1513,8 +1455,9 @@ int handle_packet_missing_direct(struct
|
|
Ian Kent |
e6cf32 |
if (!mt) {
|
|
Ian Kent |
e6cf32 |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "malloc: %s", estr);
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ioctlfd, pkt->wait_queue_token, -ENOMEM);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
e6cf32 |
return 1;
|
|
Ian Kent |
e6cf32 |
@@ -1542,8 +1485,9 @@ int handle_packet_missing_direct(struct
|
|
Ian Kent |
e6cf32 |
status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
|
|
Ian Kent |
e6cf32 |
if (status) {
|
|
Ian Kent |
e6cf32 |
error(ap->logopt, "missing mount thread create failed");
|
|
Ian Kent |
e6cf32 |
- send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->send_fail(ap->logopt,
|
|
Ian Kent |
e6cf32 |
+ ioctlfd, pkt->wait_queue_token, -status);
|
|
Ian Kent |
e6cf32 |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
e6cf32 |
cache_unlock(mc);
|
|
Ian Kent |
e6cf32 |
mount_mutex_unlock(NULL);
|
|
Ian Kent |
e6cf32 |
pending_cond_destroy(mt);
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/daemon/automount.c.device-node-control autofs-5.0.3/daemon/automount.c
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/daemon/automount.c.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/daemon/automount.c 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -579,40 +579,6 @@ int umount_autofs(struct autofs_point *a
|
|
Ian Kent |
e6cf32 |
return ret;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
-int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token)
|
|
Ian Kent |
e6cf32 |
-{
|
|
Ian Kent |
e6cf32 |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (wait_queue_token == 0)
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- debug(logopt, "token = %d", wait_queue_token);
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (ioctl(ioctlfd, AUTOFS_IOC_READY, wait_queue_token) < 0) {
|
|
Ian Kent |
e6cf32 |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
- logerr("AUTOFS_IOC_READY: error %s", estr);
|
|
Ian Kent |
e6cf32 |
- return 1;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
-}
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
-int send_fail(unsigned logopt, int ioctlfd, unsigned int wait_queue_token)
|
|
Ian Kent |
e6cf32 |
-{
|
|
Ian Kent |
e6cf32 |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (wait_queue_token == 0)
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- debug(logopt, "token = %d", wait_queue_token);
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
- if (ioctl(ioctlfd, AUTOFS_IOC_FAIL, wait_queue_token) < 0) {
|
|
Ian Kent |
e6cf32 |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
- logerr("AUTOFS_IOC_FAIL: error %s", estr);
|
|
Ian Kent |
e6cf32 |
- return 1;
|
|
Ian Kent |
e6cf32 |
- }
|
|
Ian Kent |
e6cf32 |
- return 0;
|
|
Ian Kent |
e6cf32 |
-}
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
static size_t get_kpkt_len(void)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
size_t pkt_len = sizeof(struct autofs_v5_packet);
|
|
Ian Kent |
e6cf32 |
@@ -1540,7 +1506,9 @@ void *handle_mounts(void *arg)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
while (ap->state != ST_SHUTDOWN) {
|
|
Ian Kent |
e6cf32 |
if (handle_packet(ap)) {
|
|
Ian Kent |
e6cf32 |
- int ret, result;
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
+ unsigned int result;
|
|
Ian Kent |
e6cf32 |
+ int ret;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
state_mutex_lock(ap);
|
|
Ian Kent |
e6cf32 |
/*
|
|
Ian Kent |
e6cf32 |
@@ -1557,7 +1525,7 @@ void *handle_mounts(void *arg)
|
|
Ian Kent |
e6cf32 |
* If the ioctl fails assume the kernel doesn't have
|
|
Ian Kent |
e6cf32 |
* AUTOFS_IOC_ASKUMOUNT and just continue.
|
|
Ian Kent |
e6cf32 |
*/
|
|
Ian Kent |
e6cf32 |
- ret = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &result);
|
|
Ian Kent |
e6cf32 |
+ ret = ops->askumount(ap->logopt, ap->ioctlfd, &result);
|
|
Ian Kent |
e6cf32 |
if (ret == -1) {
|
|
Ian Kent |
e6cf32 |
state_mutex_unlock(ap);
|
|
Ian Kent |
e6cf32 |
break;
|
|
Ian Kent |
e6cf32 |
@@ -2055,6 +2023,8 @@ int main(int argc, char *argv[])
|
|
Ian Kent |
e6cf32 |
exit(1);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+ init_ioctl_ctl();
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
if (!alarm_start_handler()) {
|
|
Ian Kent |
e6cf32 |
logerr("%s: failed to create alarm handler thread!", program);
|
|
Ian Kent |
e6cf32 |
master_kill(master_list);
|
|
Ian Kent |
e6cf32 |
@@ -2099,6 +2069,8 @@ int main(int argc, char *argv[])
|
|
Ian Kent |
e6cf32 |
if (dh)
|
|
Ian Kent |
e6cf32 |
dlclose(dh);
|
|
Ian Kent |
e6cf32 |
#endif
|
|
Ian Kent |
e6cf32 |
+ close_ioctl_ctl();
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
info(logging, "autofs stopped");
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
exit(0);
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/include/automount.h.device-node-control autofs-5.0.3/include/automount.h
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/include/automount.h.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/include/automount.h 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -29,6 +29,7 @@
|
|
Ian Kent |
e6cf32 |
#include "log.h"
|
|
Ian Kent |
e6cf32 |
#include "rpc_subs.h"
|
|
Ian Kent |
e6cf32 |
#include "parse_subs.h"
|
|
Ian Kent |
e6cf32 |
+#include "dev-ioctl-lib.h"
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
#ifdef WITH_DMALLOC
|
|
Ian Kent |
e6cf32 |
#include <dmalloc.h>
|
|
Ian Kent |
e6cf32 |
@@ -70,6 +71,10 @@ int load_autofs4_module(void);
|
|
Ian Kent |
e6cf32 |
#define SMB_SUPER_MAGIC 0x0000517BL
|
|
Ian Kent |
e6cf32 |
#define CIFS_MAGIC_NUMBER 0xFF534D42L
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_TYPE_INDIRECT 0x0001
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_TYPE_DIRECT 0x0002
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_TYPE_OFFSET 0x0004
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
/* This sould be enough for at least 20 host aliases */
|
|
Ian Kent |
e6cf32 |
#define HOST_ENT_BUF_SIZE 2048
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -367,7 +372,7 @@ void free_mnt_list(struct mnt_list *list
|
|
Ian Kent |
e6cf32 |
int contained_in_local_fs(const char *path);
|
|
Ian Kent |
e6cf32 |
int is_mounted(const char *table, const char *path, unsigned int type);
|
|
Ian Kent |
e6cf32 |
int has_fstab_option(const char *opt);
|
|
Ian Kent |
e6cf32 |
-char *find_mnt_ino(const char *table, dev_t dev, ino_t ino);
|
|
Ian Kent |
e6cf32 |
+int find_mnt_devid(const char *table, const char *path, char *devid, unsigned int type);
|
|
Ian Kent |
e6cf32 |
char *get_offset(const char *prefix, char *offset,
|
|
Ian Kent |
e6cf32 |
struct list_head *head, struct list_head **pos);
|
|
Ian Kent |
e6cf32 |
void add_ordered_list(struct mnt_list *ent, struct list_head *head);
|
|
Ian Kent |
e6cf32 |
@@ -377,6 +382,7 @@ int tree_get_mnt_list(struct mnt_list *m
|
|
Ian Kent |
e6cf32 |
int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
|
|
Ian Kent |
e6cf32 |
int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
|
|
Ian Kent |
e6cf32 |
int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
|
|
Ian Kent |
e6cf32 |
+int tree_find_mnt_devid(struct mnt_list *mnts, const char *path, char *devid, unsigned int type);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/* Core automount definitions */
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -470,8 +476,6 @@ struct autofs_point {
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
void *handle_mounts(void *arg);
|
|
Ian Kent |
e6cf32 |
int umount_multi(struct autofs_point *ap, const char *path, int incl);
|
|
Ian Kent |
e6cf32 |
-int send_ready(unsigned logopt, int ioctlfd, unsigned int wait_queue_token);
|
|
Ian Kent |
e6cf32 |
-int send_fail(unsigned logopt, int ioctlfd, unsigned int wait_queue_token);
|
|
Ian Kent |
e6cf32 |
int do_expire(struct autofs_point *ap, const char *name, int namelen);
|
|
Ian Kent |
e6cf32 |
void *expire_proc_indirect(void *);
|
|
Ian Kent |
e6cf32 |
void *expire_proc_direct(void *);
|
|
Ian Kent |
e6cf32 |
diff -up /dev/null autofs-5.0.3/include/linux/auto_dev-ioctl.h
|
|
Ian Kent |
e6cf32 |
--- /dev/null 2008-02-25 17:16:11.149000952 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/include/linux/auto_dev-ioctl.h 2008-02-25 09:03:44.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -0,0 +1,113 @@
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * linux/include/linux/auto_dev-ioctl.h
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Ian Kent <raven@themaw.net>
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * This file is part of the Linux kernel and is made available under
|
|
Ian Kent |
e6cf32 |
+ * the terms of the GNU General Public License, version 2, or at your
|
|
Ian Kent |
e6cf32 |
+ * option, any later version, incorporated herein by reference.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#ifndef _LINUX_AUTO_DEV_IOCTL_H
|
|
Ian Kent |
e6cf32 |
+#define _LINUX_AUTO_DEV_IOCTL_H
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#include <linux/types.h>
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEVID_LEN 16
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * An ioctl interface for autofs mount point control.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * All theioctls use this structure.
|
|
Ian Kent |
e6cf32 |
+ * When sending a path size must account for the total length
|
|
Ian Kent |
e6cf32 |
+ * of the chunk of memory.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+struct autofs_dev_ioctl {
|
|
Ian Kent |
e6cf32 |
+ __u32 ver_major;
|
|
Ian Kent |
e6cf32 |
+ __u32 ver_minor;
|
|
Ian Kent |
e6cf32 |
+ __u32 size; /* total size of data passed in
|
|
Ian Kent |
e6cf32 |
+ * including this struct */
|
|
Ian Kent |
e6cf32 |
+ __s32 ioctlfd; /* automount command fd */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ __u32 arg1; /* Command parameters */
|
|
Ian Kent |
e6cf32 |
+ __u32 arg2;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ char path[0];
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
|
|
Ian Kent |
e6cf32 |
+ in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
|
|
Ian Kent |
e6cf32 |
+ in->size = sizeof(struct autofs_dev_ioctl);
|
|
Ian Kent |
e6cf32 |
+ in->ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
+ in->arg1 = 0;
|
|
Ian Kent |
e6cf32 |
+ in->arg2 = 0;
|
|
Ian Kent |
e6cf32 |
+ return;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * If you change this make sure you make the corresponding change
|
|
Ian Kent |
e6cf32 |
+ * to autofs-dev-ioctl.c:lookup_ioctl()
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+enum {
|
|
Ian Kent |
e6cf32 |
+ /* Get various version info */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_PROTOVER_CMD,
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Set mount we're acting on */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Close mount ioctl fd */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Mount/expire status returns */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_READY_CMD,
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_FAIL_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Automount active/inactive */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_CATATONIC_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Expiry timeout */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Get mount last requesting uid and gid */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_REQUESTOR_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Check for eligible expire candidates */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_EXPIRE_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Request busy status */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /* Check if path is a mountpoint */
|
|
Ian Kent |
e6cf32 |
+ AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_IOCTL 0x93
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_VERSION _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_PROTOVER _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_PROTOSUBVER _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_OPENMOUNT _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_CLOSEMOUNT _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_READY _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_FAIL _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_SETPIPEFD _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_CATATONIC _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_TIMEOUT _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_REQUESTOR _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_REQUESTOR_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_EXPIRE _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_ASKUMOUNT _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#endif /* _LINUX_AUTO_DEV_IOCTL_H */
|
|
Ian Kent |
e6cf32 |
diff -up /dev/null autofs-5.0.3/include/mounts.h
|
|
Ian Kent |
e6cf32 |
--- /dev/null 2008-02-25 17:16:11.149000952 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/include/mounts.h 2008-02-25 09:03:44.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -0,0 +1,96 @@
|
|
Ian Kent |
e6cf32 |
+/* ----------------------------------------------------------------------- *
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * mounts.h - header file for mount utilities module.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2004-2006 Ian Kent <raven@themaw.net> - All Rights Reserved.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * This program is free software; you can redistribute it and/or modify
|
|
Ian Kent |
e6cf32 |
+ * it under the terms of the GNU General Public License as published by
|
|
Ian Kent |
e6cf32 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
Ian Kent |
e6cf32 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
Ian Kent |
e6cf32 |
+ * version; incorporated herein by reference.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * ----------------------------------------------------------------------- */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#ifndef MOUNTS_H
|
|
Ian Kent |
e6cf32 |
+#define MOUNTS_H
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_TYPE_INDIRECT 0x0001
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_TYPE_DIRECT 0x0002
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_TYPE_OFFSET 0x0004
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define MNTS_ALL 0x0001
|
|
Ian Kent |
e6cf32 |
+#define MNTS_REAL 0x0002
|
|
Ian Kent |
e6cf32 |
+#define MNTS_AUTOFS 0x0004
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define REMOUNT_SUCCESS 0x0000
|
|
Ian Kent |
e6cf32 |
+#define REMOUNT_OPEN_FAIL 0x0001
|
|
Ian Kent |
e6cf32 |
+#define REMOUNT_STAT_FAIL 0x0002
|
|
Ian Kent |
e6cf32 |
+#define REMOUNT_READ_MAP 0x0004
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+extern const unsigned int indirect;
|
|
Ian Kent |
e6cf32 |
+extern const unsigned int direct;
|
|
Ian Kent |
e6cf32 |
+extern const unsigned int offset;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+struct mapent;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+struct mnt_list {
|
|
Ian Kent |
e6cf32 |
+ char *path;
|
|
Ian Kent |
e6cf32 |
+ char *fs_name;
|
|
Ian Kent |
e6cf32 |
+ char *fs_type;
|
|
Ian Kent |
e6cf32 |
+ char *opts;
|
|
Ian Kent |
e6cf32 |
+ pid_t owner;
|
|
Ian Kent |
e6cf32 |
+ /*
|
|
Ian Kent |
e6cf32 |
+ * List operations ie. get_mnt_list.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+ struct mnt_list *next;
|
|
Ian Kent |
e6cf32 |
+ /*
|
|
Ian Kent |
e6cf32 |
+ * Tree operations ie. tree_make_tree,
|
|
Ian Kent |
e6cf32 |
+ * tree_get_mnt_list etc.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+ struct mnt_list *left;
|
|
Ian Kent |
e6cf32 |
+ struct mnt_list *right;
|
|
Ian Kent |
e6cf32 |
+ struct list_head self;
|
|
Ian Kent |
e6cf32 |
+ struct list_head list;
|
|
Ian Kent |
e6cf32 |
+ struct list_head entries;
|
|
Ian Kent |
e6cf32 |
+ struct list_head sublist;
|
|
Ian Kent |
e6cf32 |
+ /*
|
|
Ian Kent |
e6cf32 |
+ * Offset mount handling ie. add_ordered_list
|
|
Ian Kent |
e6cf32 |
+ * and get_offset.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+ struct list_head ordered;
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+unsigned int query_kproto_ver(void);
|
|
Ian Kent |
e6cf32 |
+unsigned int get_kver_major(void);
|
|
Ian Kent |
e6cf32 |
+unsigned int get_kver_minor(void);
|
|
Ian Kent |
e6cf32 |
+char *make_options_string(char *path, int kernel_pipefd, char *extra);
|
|
Ian Kent |
e6cf32 |
+char *make_mnt_name_string(char *path);
|
|
Ian Kent |
e6cf32 |
+struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
|
|
Ian Kent |
e6cf32 |
+struct mnt_list *reverse_mnt_list(struct mnt_list *list);
|
|
Ian Kent |
e6cf32 |
+void free_mnt_list(struct mnt_list *list);
|
|
Ian Kent |
e6cf32 |
+int contained_in_local_fs(const char *path);
|
|
Ian Kent |
e6cf32 |
+int is_mounted(const char *table, const char *path, unsigned int type);
|
|
Ian Kent |
e6cf32 |
+int has_fstab_option(const char *opt);
|
|
Ian Kent |
e6cf32 |
+int find_mnt_devid(const char *table, const char *path, char *devid, const unsigned int type);
|
|
Ian Kent |
e6cf32 |
+char *get_offset(const char *prefix, char *offset,
|
|
Ian Kent |
e6cf32 |
+ struct list_head *head, struct list_head **pos);
|
|
Ian Kent |
e6cf32 |
+void add_ordered_list(struct mnt_list *ent, struct list_head *head);
|
|
Ian Kent |
e6cf32 |
+void tree_free_mnt_tree(struct mnt_list *tree);
|
|
Ian Kent |
e6cf32 |
+struct mnt_list *tree_make_mnt_tree(const char *table, const char *path);
|
|
Ian Kent |
e6cf32 |
+int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
|
|
Ian Kent |
e6cf32 |
+int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
|
|
Ian Kent |
e6cf32 |
+int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
|
|
Ian Kent |
e6cf32 |
+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
|
|
Ian Kent |
e6cf32 |
+int tree_find_mnt_devid(struct mnt_list *mnts, const char *path, char *devid, const unsigned int type);
|
|
Ian Kent |
e6cf32 |
+void set_tsd_user_vars(unsigned int, uid_t, gid_t);
|
|
Ian Kent |
e6cf32 |
+const char *mount_type_str(unsigned int);
|
|
Ian Kent |
e6cf32 |
+void notify_mount_result(struct autofs_point *, const char *, const char *);
|
|
Ian Kent |
e6cf32 |
+int remount_active_mount(struct autofs_point *, struct mapent_cache *,
|
|
Ian Kent |
e6cf32 |
+ const char *, dev_t devid, const unsigned int, int *);
|
|
Ian Kent |
e6cf32 |
+int umount_ent(struct autofs_point *, const char *);
|
|
Ian Kent |
e6cf32 |
+int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
|
|
Ian Kent |
e6cf32 |
+int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#endif
|
|
Ian Kent |
e6cf32 |
diff -up /dev/null autofs-5.0.3/include/dev-ioctl-lib.h
|
|
Ian Kent |
e6cf32 |
--- /dev/null 2008-02-25 17:16:11.149000952 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/include/dev-ioctl-lib.h 2008-02-25 09:03:44.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -0,0 +1,62 @@
|
|
Ian Kent |
e6cf32 |
+/* ----------------------------------------------------------------------- *
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * dev-ioctl-lib.h - autofs device control.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Ian Kent <raven@themaw.net>
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * This program is free software; you can redistribute it and/or modify
|
|
Ian Kent |
e6cf32 |
+ * it under the terms of the GNU General Public License as published by
|
|
Ian Kent |
e6cf32 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
Ian Kent |
e6cf32 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
Ian Kent |
e6cf32 |
+ * version.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * This program is distributed in the hope that it will be useful,
|
|
Ian Kent |
e6cf32 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Ian Kent |
e6cf32 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Ian Kent |
e6cf32 |
+ * GNU General Public License for more details.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * ----------------------------------------------------------------------- */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#ifndef AUTOFS_DEV_IOCTL_LIB_H
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_DEV_IOCTL_LIB_H
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#include <sys/types.h>
|
|
Ian Kent |
e6cf32 |
+#include "linux/auto_dev-ioctl.h"
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define CONTROL_DEVICE "/dev/autofs"
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#define DEV_IOCTL_IS_MOUNTED 0x0001
|
|
Ian Kent |
e6cf32 |
+#define DEV_IOCTL_IS_AUTOFS 0x0002
|
|
Ian Kent |
e6cf32 |
+#define DEV_IOCTL_IS_OTHER 0x0004
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+struct ioctl_ctl {
|
|
Ian Kent |
e6cf32 |
+ int devfd;
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops;
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+struct ioctl_ops {
|
|
Ian Kent |
e6cf32 |
+ int (*version)(unsigned int, int, struct autofs_dev_ioctl *);
|
|
Ian Kent |
e6cf32 |
+ int (*protover)(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+ int (*protosubver)(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+ int (*open)(unsigned int, int *, dev_t, const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+ int (*close)(unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+ int (*send_ready)(unsigned int, int, unsigned int);
|
|
Ian Kent |
e6cf32 |
+ int (*send_fail)(unsigned int, int, unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+ int (*setpipefd)(unsigned int, int, int);
|
|
Ian Kent |
e6cf32 |
+ int (*catatonic)(unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+ int (*timeout)(unsigned int, int, time_t *);
|
|
Ian Kent |
e6cf32 |
+ int (*requestor)(unsigned int, int, const char *, uid_t *, gid_t *);
|
|
Ian Kent |
e6cf32 |
+ int (*expire)(unsigned int, int, const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+ int (*askumount)(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+ int (*ismountpoint)(unsigned int, int, const char *, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+void init_ioctl_ctl(void);
|
|
Ian Kent |
e6cf32 |
+void close_ioctl_ctl(void);
|
|
Ian Kent |
e6cf32 |
+struct ioctl_ops *get_ioctl_ops(void);
|
|
Ian Kent |
e6cf32 |
+struct autofs_dev_ioctl *alloc_ioctl_ctl_open(const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+void free_ioctl_ctl_open(struct autofs_dev_ioctl *);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#endif
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/CHANGELOG.device-node-control autofs-5.0.3/CHANGELOG
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/CHANGELOG.device-node-control 2008-02-25 08:58:46.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/CHANGELOG 2008-02-25 09:07:32.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -8,6 +8,7 @@
|
|
Ian Kent |
e6cf32 |
- another fix for don't fail on empty master map.
|
|
Ian Kent |
e6cf32 |
- fix expire working harder than needed.
|
|
Ian Kent |
e6cf32 |
- fix unlink of mount tree incorrectly causing autofs mount fail.
|
|
Ian Kent |
e6cf32 |
+- add miscellaneous device node interface library.
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
14/01/2008 autofs-5.0.3
|
|
Ian Kent |
e6cf32 |
-----------------------
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/redhat/autofs.init.in.device-node-control autofs-5.0.3/redhat/autofs.init.in
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/redhat/autofs.init.in.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/redhat/autofs.init.in 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -13,6 +13,7 @@
|
|
Ian Kent |
e6cf32 |
DAEMON=@@sbindir@@/automount
|
|
Ian Kent |
e6cf32 |
prog=`basename $DAEMON`
|
|
Ian Kent |
e6cf32 |
MODULE="autofs4"
|
|
Ian Kent |
e6cf32 |
+DEVICE="autofs"
|
|
Ian Kent |
e6cf32 |
initdir=@@initdir@@
|
|
Ian Kent |
e6cf32 |
confdir=@@autofsconfdir@@
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -56,6 +57,15 @@ function start() {
|
|
Ian Kent |
e6cf32 |
echo
|
|
Ian Kent |
e6cf32 |
return $RETVAL
|
|
Ian Kent |
e6cf32 |
fi
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ # Check misc device
|
|
Ian Kent |
e6cf32 |
+ if [ -e "/proc/misc" ]; then
|
|
Ian Kent |
e6cf32 |
+ MINOR=`awk "/$DEVICE/ {print \\$1}" /proc/misc`
|
|
Ian Kent |
e6cf32 |
+ if [ -n "$MINOR" -a ! -c "/dev/$DEVICE" ]; then
|
|
Ian Kent |
e6cf32 |
+ mknod -m 0600 /dev/$DEVICE c 10 $MINOR
|
|
Ian Kent |
e6cf32 |
+ fi
|
|
Ian Kent |
e6cf32 |
+ fi
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
echo -n $"Starting $prog: "
|
|
Ian Kent |
e6cf32 |
$prog $OPTIONS
|
|
Ian Kent |
e6cf32 |
RETVAL=$?
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/lib/master_parse.y.device-node-control autofs-5.0.3/lib/master_parse.y
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/lib/master_parse.y.device-node-control 2008-02-25 08:58:46.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/lib/master_parse.y 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -796,6 +796,7 @@ int master_parse_entry(const char *buffe
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
} else {
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
struct autofs_point *ap = entry->ap;
|
|
Ian Kent |
e6cf32 |
time_t tout = timeout;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
@@ -807,7 +808,7 @@ int master_parse_entry(const char *buffe
|
|
Ian Kent |
e6cf32 |
ap->exp_timeout = timeout;
|
|
Ian Kent |
e6cf32 |
ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
|
Ian Kent |
e6cf32 |
if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
|
|
Ian Kent |
e6cf32 |
- ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout);
|
|
Ian Kent |
e6cf32 |
+ ops->timeout(ap->logopt, ap->ioctlfd, &tout);
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
entry->ap->random_selection = random_selection;
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/lib/mounts.c.device-node-control autofs-5.0.3/lib/mounts.c
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/lib/mounts.c.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/lib/mounts.c 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -38,6 +38,7 @@ static const char kver_options_template[
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
unsigned int query_kproto_ver(void)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
Ian Kent |
e6cf32 |
char dir[] = "/tmp/autoXXXXXX", *t_dir;
|
|
Ian Kent |
e6cf32 |
char options[MAX_OPTIONS_LEN + 1];
|
|
Ian Kent |
e6cf32 |
pid_t pgrp = getpgrp();
|
|
Ian Kent |
e6cf32 |
@@ -70,7 +71,7 @@ unsigned int query_kproto_ver(void)
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
close(pipefd[1]);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ioctlfd = open(t_dir, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
+ ops->open(LOGOPT_NONE, &ioctlfd, -1, t_dir, AUTOFS_TYPE_INDIRECT);
|
|
Ian Kent |
e6cf32 |
if (ioctlfd == -1) {
|
|
Ian Kent |
e6cf32 |
umount(t_dir);
|
|
Ian Kent |
e6cf32 |
close(pipefd[0]);
|
|
Ian Kent |
e6cf32 |
@@ -78,11 +79,11 @@ unsigned int query_kproto_ver(void)
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
+ ops->catatonic(LOGOPT_NONE, ioctlfd);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/* If this ioctl() doesn't work, it is kernel version 2 */
|
|
Ian Kent |
e6cf32 |
- if (ioctl(ioctlfd, AUTOFS_IOC_PROTOVER, &kver.major) == -1) {
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ if (ops->protover(LOGOPT_NONE, ioctlfd, &kver.major)) {
|
|
Ian Kent |
e6cf32 |
+ ops->close(LOGOPT_NONE, ioctlfd);
|
|
Ian Kent |
e6cf32 |
umount(t_dir);
|
|
Ian Kent |
e6cf32 |
close(pipefd[0]);
|
|
Ian Kent |
e6cf32 |
rmdir(t_dir);
|
|
Ian Kent |
e6cf32 |
@@ -90,15 +91,15 @@ unsigned int query_kproto_ver(void)
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
/* If this ioctl() doesn't work, version is 4 or less */
|
|
Ian Kent |
e6cf32 |
- if (ioctl(ioctlfd, AUTOFS_IOC_PROTOSUBVER, &kver.minor) == -1) {
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ if (ops->protosubver(LOGOPT_NONE, ioctlfd, &kver.minor)) {
|
|
Ian Kent |
e6cf32 |
+ ops->close(LOGOPT_NONE, ioctlfd);
|
|
Ian Kent |
e6cf32 |
umount(t_dir);
|
|
Ian Kent |
e6cf32 |
close(pipefd[0]);
|
|
Ian Kent |
e6cf32 |
rmdir(t_dir);
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+ ops->close(LOGOPT_NONE, ioctlfd);
|
|
Ian Kent |
e6cf32 |
umount(t_dir);
|
|
Ian Kent |
e6cf32 |
close(pipefd[0]);
|
|
Ian Kent |
e6cf32 |
rmdir(t_dir);
|
|
Ian Kent |
e6cf32 |
@@ -456,49 +457,75 @@ int has_fstab_option(const char *opt)
|
|
Ian Kent |
e6cf32 |
return ret;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
-char *find_mnt_ino(const char *table, dev_t dev, ino_t ino)
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Find the device number of an autofs mount with given path and
|
|
Ian Kent |
e6cf32 |
+ * type (eg..AUTOFS_TYPE_DIRECT). An autofs display mount option
|
|
Ian Kent |
e6cf32 |
+ * "dev=<device number>" is provided by the kernel module for this.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * The device number is used by the kernel to identify the autofs
|
|
Ian Kent |
e6cf32 |
+ * super block when searching for the mount.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+int find_mnt_devid(const char *table,
|
|
Ian Kent |
e6cf32 |
+ const char *path, char *devid, unsigned int type)
|
|
Ian Kent |
e6cf32 |
{
|
|
Ian Kent |
e6cf32 |
- struct mntent mnt_wrk;
|
|
Ian Kent |
e6cf32 |
struct mntent *mnt;
|
|
Ian Kent |
e6cf32 |
+ struct mntent mnt_wrk;
|
|
Ian Kent |
e6cf32 |
char buf[PATH_MAX * 3];
|
|
Ian Kent |
e6cf32 |
- char *path = NULL;
|
|
Ian Kent |
e6cf32 |
- unsigned long l_dev = (unsigned long) dev;
|
|
Ian Kent |
e6cf32 |
- unsigned long l_ino = (unsigned long) ino;
|
|
Ian Kent |
e6cf32 |
FILE *tab;
|
|
Ian Kent |
e6cf32 |
+ char *dev;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
tab = setmntent(table, "r");
|
|
Ian Kent |
e6cf32 |
if (!tab) {
|
|
Ian Kent |
e6cf32 |
- char *estr = strerror_r(errno, buf, (size_t) PATH_MAX - 1);
|
|
Ian Kent |
e6cf32 |
- logerr("setmntent: %s", estr);
|
|
Ian Kent |
e6cf32 |
+ printf("failed to open mount table\n");
|
|
Ian Kent |
e6cf32 |
return 0;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+ dev = NULL;
|
|
Ian Kent |
e6cf32 |
while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
|
|
Ian Kent |
e6cf32 |
- char *p_dev, *p_ino;
|
|
Ian Kent |
e6cf32 |
- unsigned long m_dev, m_ino;
|
|
Ian Kent |
e6cf32 |
-
|
|
Ian Kent |
e6cf32 |
if (strcmp(mnt->mnt_type, "autofs"))
|
|
Ian Kent |
e6cf32 |
continue;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- p_dev = strstr(mnt->mnt_opts, "dev=");
|
|
Ian Kent |
e6cf32 |
- if (!p_dev)
|
|
Ian Kent |
e6cf32 |
- continue;
|
|
Ian Kent |
e6cf32 |
- sscanf(p_dev, "dev=%lu", &m_dev);
|
|
Ian Kent |
e6cf32 |
- if (m_dev != l_dev)
|
|
Ian Kent |
e6cf32 |
+ if (strcmp(mnt->mnt_dir, path))
|
|
Ian Kent |
e6cf32 |
continue;
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- p_ino = strstr(mnt->mnt_opts, "ino=");
|
|
Ian Kent |
e6cf32 |
- if (!p_ino)
|
|
Ian Kent |
e6cf32 |
- continue;
|
|
Ian Kent |
e6cf32 |
- sscanf(p_ino, "ino=%lu", &m_ino);
|
|
Ian Kent |
e6cf32 |
- if (m_ino == l_ino) {
|
|
Ian Kent |
e6cf32 |
- path = strdup(mnt->mnt_dir);
|
|
Ian Kent |
e6cf32 |
+ switch (type) {
|
|
Ian Kent |
e6cf32 |
+ case AUTOFS_TYPE_INDIRECT:
|
|
Ian Kent |
e6cf32 |
+ if (!hasmntopt(mnt, "indirect"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ case AUTOFS_TYPE_DIRECT:
|
|
Ian Kent |
e6cf32 |
+ if (!hasmntopt(mnt, "direct"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ case AUTOFS_TYPE_OFFSET:
|
|
Ian Kent |
e6cf32 |
+ if (!hasmntopt(mnt, "offset"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ dev = hasmntopt(mnt, "dev");
|
|
Ian Kent |
e6cf32 |
+ if (dev) {
|
|
Ian Kent |
e6cf32 |
+ char *start = strchr(dev, '=') + 1;
|
|
Ian Kent |
e6cf32 |
+ char *end = strchr(start, ',');
|
|
Ian Kent |
e6cf32 |
+ if (end)
|
|
Ian Kent |
e6cf32 |
+ *end = '\0';
|
|
Ian Kent |
e6cf32 |
+ if (start) {
|
|
Ian Kent |
e6cf32 |
+ int len = strlen(start);
|
|
Ian Kent |
e6cf32 |
+ memcpy(devid, start, len);
|
|
Ian Kent |
e6cf32 |
+ devid[len] = '\0';
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
break;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
endmntent(tab);
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
- return path;
|
|
Ian Kent |
e6cf32 |
+ if (!dev)
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 1;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
char *get_offset(const char *prefix, char *offset,
|
|
Ian Kent |
e6cf32 |
@@ -976,3 +1003,70 @@ int tree_is_mounted(struct mnt_list *mnt
|
|
Ian Kent |
e6cf32 |
return mounted;
|
|
Ian Kent |
e6cf32 |
}
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+int tree_find_mnt_devid(struct mnt_list *mnts,
|
|
Ian Kent |
e6cf32 |
+ const char *path, char *devid, unsigned int type)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct list_head *p;
|
|
Ian Kent |
e6cf32 |
+ struct list_head list;
|
|
Ian Kent |
e6cf32 |
+ size_t len = strlen(path);
|
|
Ian Kent |
e6cf32 |
+ char *dev;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ INIT_LIST_HEAD(&list);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!tree_find_mnt_ents(mnts, &list, path))
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ dev = NULL;
|
|
Ian Kent |
e6cf32 |
+ list_for_each(p, &list) {
|
|
Ian Kent |
e6cf32 |
+ struct mnt_list *mptr;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ mptr = list_entry(p, struct mnt_list, entries);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (strcmp(mptr->fs_type, "autofs"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (strlen(mptr->path) < len)
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (strcmp(mptr->path, path))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ switch (type) {
|
|
Ian Kent |
e6cf32 |
+ case AUTOFS_TYPE_INDIRECT:
|
|
Ian Kent |
e6cf32 |
+ if (!strstr(mptr->opts, "indirect"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ case AUTOFS_TYPE_DIRECT:
|
|
Ian Kent |
e6cf32 |
+ if (!strstr(mptr->opts, "direct"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ case AUTOFS_TYPE_OFFSET:
|
|
Ian Kent |
e6cf32 |
+ if (!strstr(mptr->opts, "offset"))
|
|
Ian Kent |
e6cf32 |
+ continue;
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ dev = strstr(mptr->opts, "dev");
|
|
Ian Kent |
e6cf32 |
+ if (dev) {
|
|
Ian Kent |
e6cf32 |
+ char *start = strchr(dev, '=') + 1;
|
|
Ian Kent |
e6cf32 |
+ char *end = strchr(start, ',');
|
|
Ian Kent |
e6cf32 |
+ if (end)
|
|
Ian Kent |
e6cf32 |
+ *end = '\0';
|
|
Ian Kent |
e6cf32 |
+ if (start) {
|
|
Ian Kent |
e6cf32 |
+ int len = strlen(start);
|
|
Ian Kent |
e6cf32 |
+ memcpy(devid, start, len);
|
|
Ian Kent |
e6cf32 |
+ devid[len] = '\0';
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ *end = ',';
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!dev)
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 1;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/lib/Makefile.device-node-control autofs-5.0.3/lib/Makefile
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/lib/Makefile.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/lib/Makefile 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -7,12 +7,13 @@ include ../Makefile.rules
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \
|
|
Ian Kent |
e6cf32 |
master_tok.l master_parse.y nss_tok.c nss_parse.tab.c \
|
|
Ian Kent |
e6cf32 |
- args.c alarm.c macros.c master.c defaults.c parse_subs.c
|
|
Ian Kent |
e6cf32 |
+ args.c alarm.c macros.c master.c defaults.c parse_subs.c \
|
|
Ian Kent |
e6cf32 |
+ dev-ioctl-lib.c
|
|
Ian Kent |
e6cf32 |
RPCS = mount.h mount_clnt.c mount_xdr.c
|
|
Ian Kent |
e6cf32 |
OBJS = cache.o mount_clnt.o mount_xdr.o cat_path.o rpc_subs.o \
|
|
Ian Kent |
e6cf32 |
mounts.o log.o nsswitch.o master_tok.o master_parse.tab.o \
|
|
Ian Kent |
e6cf32 |
nss_tok.o nss_parse.tab.o args.o alarm.o macros.o master.o \
|
|
Ian Kent |
e6cf32 |
- defaults.o parse_subs.o
|
|
Ian Kent |
e6cf32 |
+ defaults.o parse_subs.o dev-ioctl-lib.o
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h \
|
|
Ian Kent |
e6cf32 |
master_tok.c master_parse.tab.c master_parse.tab.h
|
|
Ian Kent |
e6cf32 |
diff -up /dev/null autofs-5.0.3/lib/dev-ioctl-lib.c
|
|
Ian Kent |
e6cf32 |
--- /dev/null 2008-02-25 17:16:11.149000952 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/lib/dev-ioctl-lib.c 2008-02-25 09:03:44.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -0,0 +1,747 @@
|
|
Ian Kent |
e6cf32 |
+/* ----------------------------------------------------------------------- *
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * ctl-dev-lib.c - module for Linux automount mount table lookup functions
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
|
|
Ian Kent |
e6cf32 |
+ * Copyright 2008 Ian Kent <raven@themaw.net> - All Rights Reserved
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * This program is free software; you can redistribute it and/or modify
|
|
Ian Kent |
e6cf32 |
+ * it under the terms of the GNU General Public License as published by
|
|
Ian Kent |
e6cf32 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
Ian Kent |
e6cf32 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
Ian Kent |
e6cf32 |
+ * version; incorporated herein by reference.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * ----------------------------------------------------------------------- */
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#include <stdio.h>
|
|
Ian Kent |
e6cf32 |
+#include <stdlib.h>
|
|
Ian Kent |
e6cf32 |
+#include <string.h>
|
|
Ian Kent |
e6cf32 |
+#include <errno.h>
|
|
Ian Kent |
e6cf32 |
+#include <limits.h>
|
|
Ian Kent |
e6cf32 |
+#include <sys/types.h>
|
|
Ian Kent |
e6cf32 |
+#include <sys/stat.h>
|
|
Ian Kent |
e6cf32 |
+#include <sys/ioctl.h>
|
|
Ian Kent |
e6cf32 |
+#include <fcntl.h>
|
|
Ian Kent |
e6cf32 |
+#include <mntent.h>
|
|
Ian Kent |
e6cf32 |
+#include <errno.h>
|
|
Ian Kent |
e6cf32 |
+#include <sys/vfs.h>
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#include "automount.h"
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* ioctld control function interface */
|
|
Ian Kent |
e6cf32 |
+static struct ioctl_ctl ctl = { -1, NULL };
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+#ifndef AUTOFS_SUPER_MAGIC
|
|
Ian Kent |
e6cf32 |
+#define AUTOFS_SUPER_MAGIC 0x0187
|
|
Ian Kent |
e6cf32 |
+#endif
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Define functions for autofs ioctl control.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * We provide two interfaces. One which routes ioctls via a
|
|
Ian Kent |
e6cf32 |
+ * miscelaneous device node and can be used to obtain an ioctl
|
|
Ian Kent |
e6cf32 |
+ * file descriptor for autofs mounts that are covered by an
|
|
Ian Kent |
e6cf32 |
+ * active mount (eg. active direct or multi-mount offsets).
|
|
Ian Kent |
e6cf32 |
+ * The other provides the traditional autofs ioctl implementation.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * The miscielaneous device control functions are prefixed with
|
|
Ian Kent |
e6cf32 |
+ * dev_ctl_ and the traditional ones are prefixed with ioctl_.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_version(unsigned int, int, struct autofs_dev_ioctl *);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_protover(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_protosubver(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_open(unsigned int, int *, dev_t, const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_close(unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_send_ready(unsigned int, int, unsigned int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_send_fail(unsigned int, int, unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_setpipefd(unsigned int, int, int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_catatonic(unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_timeout(unsigned int, int, time_t *);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_requestor(unsigned int, int, const char *, uid_t *, gid_t *);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_expire(unsigned int, int, const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_askumount(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_ismountpoint(unsigned int, int, const char *, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_protover(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_protosubver(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_open(unsigned int, int *, dev_t, const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_close(unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_send_ready(unsigned int, int, unsigned int);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_send_fail(unsigned int, int, unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_catatonic(unsigned int, int);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_timeout(unsigned int, int, time_t *);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_expire(unsigned int, int, const char *, unsigned int);
|
|
Ian Kent |
e6cf32 |
+static int ioctl_askumount(unsigned int, int, unsigned int *);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static struct ioctl_ops dev_ioctl_ops = {
|
|
Ian Kent |
e6cf32 |
+ .version = dev_ioctl_version,
|
|
Ian Kent |
e6cf32 |
+ .protover = dev_ioctl_protover,
|
|
Ian Kent |
e6cf32 |
+ .protosubver = dev_ioctl_protosubver,
|
|
Ian Kent |
e6cf32 |
+ .open = dev_ioctl_open,
|
|
Ian Kent |
e6cf32 |
+ .close = dev_ioctl_close,
|
|
Ian Kent |
e6cf32 |
+ .send_ready = dev_ioctl_send_ready,
|
|
Ian Kent |
e6cf32 |
+ .send_fail = dev_ioctl_send_fail,
|
|
Ian Kent |
e6cf32 |
+ .setpipefd = dev_ioctl_setpipefd,
|
|
Ian Kent |
e6cf32 |
+ .catatonic = dev_ioctl_catatonic,
|
|
Ian Kent |
e6cf32 |
+ .timeout = dev_ioctl_timeout,
|
|
Ian Kent |
e6cf32 |
+ .requestor = dev_ioctl_requestor,
|
|
Ian Kent |
e6cf32 |
+ .expire = dev_ioctl_expire,
|
|
Ian Kent |
e6cf32 |
+ .askumount = dev_ioctl_askumount,
|
|
Ian Kent |
e6cf32 |
+ .ismountpoint = dev_ioctl_ismountpoint
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static struct ioctl_ops ioctl_ops = {
|
|
Ian Kent |
e6cf32 |
+ .version = NULL,
|
|
Ian Kent |
e6cf32 |
+ .protover = ioctl_protover,
|
|
Ian Kent |
e6cf32 |
+ .protosubver = ioctl_protosubver,
|
|
Ian Kent |
e6cf32 |
+ .open = ioctl_open,
|
|
Ian Kent |
e6cf32 |
+ .close = ioctl_close,
|
|
Ian Kent |
e6cf32 |
+ .send_ready = ioctl_send_ready,
|
|
Ian Kent |
e6cf32 |
+ .send_fail = ioctl_send_fail,
|
|
Ian Kent |
e6cf32 |
+ .setpipefd = NULL,
|
|
Ian Kent |
e6cf32 |
+ .catatonic = ioctl_catatonic,
|
|
Ian Kent |
e6cf32 |
+ .timeout = ioctl_timeout,
|
|
Ian Kent |
e6cf32 |
+ .requestor = NULL,
|
|
Ian Kent |
e6cf32 |
+ .expire = ioctl_expire,
|
|
Ian Kent |
e6cf32 |
+ .askumount = ioctl_askumount,
|
|
Ian Kent |
e6cf32 |
+ .ismountpoint = NULL
|
|
Ian Kent |
e6cf32 |
+};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Allocate the control struct that holds the misc device file
|
|
Ian Kent |
e6cf32 |
+ * descriptor and operation despatcher table.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+void init_ioctl_ctl(void)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ int devfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ctl.ops)
|
|
Ian Kent |
e6cf32 |
+ return;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ devfd = open(CONTROL_DEVICE, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
+ if (devfd == -1)
|
|
Ian Kent |
e6cf32 |
+ ctl.ops = &ioctl_ops;
|
|
Ian Kent |
e6cf32 |
+ else {
|
|
Ian Kent |
e6cf32 |
+ int cl_flags = fcntl(devfd, F_GETFD, 0);
|
|
Ian Kent |
e6cf32 |
+ if (cl_flags != -1) {
|
|
Ian Kent |
e6cf32 |
+ cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
+ fcntl(devfd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ ctl.devfd = devfd;
|
|
Ian Kent |
e6cf32 |
+ ctl.ops = &dev_ioctl_ops;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ return;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+void close_ioctl_ctl(void)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ if (ctl.devfd != -1) {
|
|
Ian Kent |
e6cf32 |
+ close(ctl.devfd);
|
|
Ian Kent |
e6cf32 |
+ ctl.devfd = -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ ctl.ops = NULL;
|
|
Ian Kent |
e6cf32 |
+ return;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Return a pointer to the operations control struct */
|
|
Ian Kent |
e6cf32 |
+struct ioctl_ops *get_ioctl_ops(void)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ if (!ctl.ops)
|
|
Ian Kent |
e6cf32 |
+ init_ioctl_ctl();
|
|
Ian Kent |
e6cf32 |
+ return ctl.ops;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Get kenrel version of misc device code */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_version(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, struct autofs_dev_ioctl *param)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ param->ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_VERSION, param) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Get major version of autofs kernel module mount protocol */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_protover(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int *major)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *major = param.arg1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_protover(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int *major)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return ioctl(ioctlfd, AUTOFS_IOC_PROTOVER, major);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Get minor version of autofs kernel module mount protocol */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_protosubver(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int *minor)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *minor = param.arg1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_protosubver(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int *minor)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return ioctl(ioctlfd, AUTOFS_IOC_PROTOSUBVER, minor);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Allocate a parameter struct for misc device ioctl used when
|
|
Ian Kent |
e6cf32 |
+ * opening an autofs mount point. Attach the path to the end
|
|
Ian Kent |
e6cf32 |
+ * of the struct. and lookup the device number if not given.
|
|
Ian Kent |
e6cf32 |
+ * Locating the device number relies on the mount option
|
|
Ian Kent |
e6cf32 |
+ * "dev=<device number>" being present in the autofs fs mount
|
|
Ian Kent |
e6cf32 |
+ * options.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static struct autofs_dev_ioctl *alloc_dev_ioctl_open(const char *path, dev_t devid, unsigned int type)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl *ioctl;
|
|
Ian Kent |
e6cf32 |
+ size_t size, p_len;
|
|
Ian Kent |
e6cf32 |
+ dev_t devno = devid;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!path)
|
|
Ian Kent |
e6cf32 |
+ return NULL;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (devno == -1) {
|
|
Ian Kent |
e6cf32 |
+ char device[AUTOFS_DEVID_LEN];
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!find_mnt_devid(_PROC_MOUNTS, path, device, type)) {
|
|
Ian Kent |
e6cf32 |
+ errno = ENOENT;
|
|
Ian Kent |
e6cf32 |
+ return NULL;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ devno = strtoul(device, NULL, 0);
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ p_len = strlen(path);
|
|
Ian Kent |
e6cf32 |
+ size = sizeof(struct autofs_dev_ioctl) + p_len + 1;
|
|
Ian Kent |
e6cf32 |
+ ioctl = malloc(size);
|
|
Ian Kent |
e6cf32 |
+ if (!ioctl) {
|
|
Ian Kent |
e6cf32 |
+ errno = ENOMEM;
|
|
Ian Kent |
e6cf32 |
+ return NULL;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(ioctl);
|
|
Ian Kent |
e6cf32 |
+ ioctl->size = size;
|
|
Ian Kent |
e6cf32 |
+ memcpy(ioctl->path, path, p_len);
|
|
Ian Kent |
e6cf32 |
+ ioctl->path[p_len] = '\0';
|
|
Ian Kent |
e6cf32 |
+ ioctl->arg1 = devno;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return ioctl;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static void free_dev_ioctl_open(struct autofs_dev_ioctl *ioctl)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ free(ioctl);
|
|
Ian Kent |
e6cf32 |
+ return;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Allocate a parameter struct for misc device ioctl which includes
|
|
Ian Kent |
e6cf32 |
+ * a path. This is used when getting the last mount requestor uid
|
|
Ian Kent |
e6cf32 |
+ * and gid and when checking if a path within the autofs filesystem
|
|
Ian Kent |
e6cf32 |
+ * is a mount point. We add the path to the end of the struct.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static struct autofs_dev_ioctl *alloc_dev_ioctl_path(int ioctlfd, const char *path)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl *ioctl;
|
|
Ian Kent |
e6cf32 |
+ size_t size, p_len;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!path)
|
|
Ian Kent |
e6cf32 |
+ return NULL;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ p_len = strlen(path);
|
|
Ian Kent |
e6cf32 |
+ size = sizeof(struct autofs_dev_ioctl) + p_len + 1;
|
|
Ian Kent |
e6cf32 |
+ ioctl = malloc(size);
|
|
Ian Kent |
e6cf32 |
+ if (!ioctl) {
|
|
Ian Kent |
e6cf32 |
+ errno = ENOMEM;
|
|
Ian Kent |
e6cf32 |
+ return NULL;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(ioctl);
|
|
Ian Kent |
e6cf32 |
+ ioctl->ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+ ioctl->size = size;
|
|
Ian Kent |
e6cf32 |
+ memcpy(ioctl->path, path, p_len);
|
|
Ian Kent |
e6cf32 |
+ ioctl->path[p_len] = '\0';
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return ioctl;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static void free_dev_ioctl_path(struct autofs_dev_ioctl *ioctl)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ free(ioctl);
|
|
Ian Kent |
e6cf32 |
+ return;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Get a file descriptor for control operations */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_open(unsigned int logopt, int *ioctlfd,
|
|
Ian Kent |
e6cf32 |
+ dev_t devid, const char *path, unsigned int type)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl *param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ param = alloc_dev_ioctl_open(path, devid, type);
|
|
Ian Kent |
e6cf32 |
+ if (!param)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) == -1) {
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ free_dev_ioctl_open(param);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *ioctlfd = param->ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ free_dev_ioctl_open(param);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_open(unsigned int logopt, int *ioctlfd,
|
|
Ian Kent |
e6cf32 |
+ dev_t devid, const char *path, unsigned int type)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct statfs sfs;
|
|
Ian Kent |
e6cf32 |
+ int save_errno, fd, cl_flags;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *ioctlfd = -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ fd = open(path, O_RDONLY);
|
|
Ian Kent |
e6cf32 |
+ if (fd == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ cl_flags = fcntl(fd, F_GETFD, 0);
|
|
Ian Kent |
e6cf32 |
+ if (cl_flags != -1) {
|
|
Ian Kent |
e6cf32 |
+ cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
e6cf32 |
+ fcntl(fd, F_SETFD, cl_flags);
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (fstatfs(fd, &sfs) == -1) {
|
|
Ian Kent |
e6cf32 |
+ save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ goto err;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (sfs.f_type != AUTOFS_SUPER_MAGIC) {
|
|
Ian Kent |
e6cf32 |
+ save_errno = ENOENT;
|
|
Ian Kent |
e6cf32 |
+ goto err;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *ioctlfd = fd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+err:
|
|
Ian Kent |
e6cf32 |
+ close(fd);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Close */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_close(unsigned int logopt, int ioctlfd)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_CLOSEMOUNT, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_close(unsigned int logopt, int ioctlfd)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return close(ioctlfd);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Send ready status for given token */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_send_ready(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int token)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (token == 0) {
|
|
Ian Kent |
e6cf32 |
+ errno = EINVAL;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ debug(logopt, "token = %d", token);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+ param.arg1 = token;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_READY, ¶m) == -1) {
|
|
Ian Kent |
e6cf32 |
+ char *estr, buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
+ logerr("AUTOFS_DEV_IOCTL_READY: error %s", estr);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_send_ready(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int token)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ if (token == 0) {
|
|
Ian Kent |
e6cf32 |
+ errno = EINVAL;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ debug(logopt, "token = %d", token);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ioctlfd, AUTOFS_IOC_READY, token) == -1) {
|
|
Ian Kent |
e6cf32 |
+ char *estr, buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
+ logerr("AUTOFS_IOC_READY: error %s", estr);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Send ready status for given token.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * The device node ioctl implementation allows for sending a status
|
|
Ian Kent |
e6cf32 |
+ * of other than ENOENT, unlike the tradional interface.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_send_fail(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int token, int status)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (token == 0) {
|
|
Ian Kent |
e6cf32 |
+ errno = EINVAL;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ debug(logopt, "token = %d", token);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+ param.arg1 = token;
|
|
Ian Kent |
e6cf32 |
+ param.arg2 = status;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_FAIL, ¶m) == -1) {
|
|
Ian Kent |
e6cf32 |
+ char *estr, buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
+ logerr("AUTOFS_DEV_IOCTL_FAIL: error %s", estr);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_send_fail(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int token, int status)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ if (token == 0) {
|
|
Ian Kent |
e6cf32 |
+ errno = EINVAL;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ debug(logopt, "token = %d", token);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ioctlfd, AUTOFS_IOC_FAIL, token) == -1) {
|
|
Ian Kent |
e6cf32 |
+ char *estr, buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
+ logerr("AUTOFS_IOC_FAIL: error %s", estr);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Set the pipe fd for kernel communication.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * Normally this is set at mount using an option but if we
|
|
Ian Kent |
e6cf32 |
+ * are reconnecting to a busy mount then we need to use this
|
|
Ian Kent |
e6cf32 |
+ * to tell the autofs kernel module about the new pipe fd. In
|
|
Ian Kent |
e6cf32 |
+ * order to protect mounts against incorrectly setting the
|
|
Ian Kent |
e6cf32 |
+ * pipefd we also require that the autofs mount be catatonic.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * If successful this also sets the process group id used to
|
|
Ian Kent |
e6cf32 |
+ * identify the controlling process to the process group of
|
|
Ian Kent |
e6cf32 |
+ * the caller.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_setpipefd(unsigned int logopt, int ioctlfd, int pipefd)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (pipefd == -1) {
|
|
Ian Kent |
e6cf32 |
+ errno = EBADF;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+ param.arg1 = pipefd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_SETPIPEFD, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Make the autofs mount point catatonic, no longer responsive to
|
|
Ian Kent |
e6cf32 |
+ * mount requests. Also closes the kernel pipe file descriptor.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_catatonic(unsigned int logopt, int ioctlfd)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_CATATONIC, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_catatonic(unsigned int logopt, int ioctlfd)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Set the autofs mount timeout */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t *timeout)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+ param.arg1 = *timeout;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *timeout = param.arg1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t *timeout)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, timeout);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Get the uid and gid of the last request for the mountpoint, path.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * When reconstructing an autofs mount tree with active mounts
|
|
Ian Kent |
e6cf32 |
+ * we need to re-connect to mounts that may have used the original
|
|
Ian Kent |
e6cf32 |
+ * process uid and gid (or string variations of them) for mount
|
|
Ian Kent |
e6cf32 |
+ * lookups within the map entry.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_requestor(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, const char *path,
|
|
Ian Kent |
e6cf32 |
+ uid_t *uid, gid_t *gid)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl *param;
|
|
Ian Kent |
e6cf32 |
+ int err;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!path)
|
|
Ian Kent |
e6cf32 |
+ errno = EINVAL;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *uid = -1;
|
|
Ian Kent |
e6cf32 |
+ *gid = -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ param = alloc_dev_ioctl_path(ioctlfd, path);
|
|
Ian Kent |
e6cf32 |
+ if (!param)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ err = ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_REQUESTOR, param);
|
|
Ian Kent |
e6cf32 |
+ if (err == -1) {
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ free_dev_ioctl_open(param);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *uid = param->arg1;
|
|
Ian Kent |
e6cf32 |
+ *gid = param->arg2;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ free_dev_ioctl_path(param);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Call repeatedly until it returns EAGAIN, meaning there's nothing
|
|
Ian Kent |
e6cf32 |
+ * more that can be done.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int expire(unsigned int logopt, int cmd, int fd,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, const char *path, void *arg)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ char buf[MAX_ERR_BUF];
|
|
Ian Kent |
e6cf32 |
+ struct stat st;
|
|
Ian Kent |
e6cf32 |
+ unsigned int retries;
|
|
Ian Kent |
e6cf32 |
+ unsigned int ret;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (fstat(ioctlfd, &st) == -1) {
|
|
Ian Kent |
e6cf32 |
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
e6cf32 |
+ debug(logopt, "fstat failed: %s", estr);
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ retries = (count_mounts(logopt, path, st.st_dev) + 1) * EXPIRE_RETRIES;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ while (retries--) {
|
|
Ian Kent |
e6cf32 |
+ struct timespec tm = {0, 100000000};
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ ret = ioctl(fd, cmd, arg);
|
|
Ian Kent |
e6cf32 |
+ if (ret == -1) {
|
|
Ian Kent |
e6cf32 |
+ /* Mount has gone away */
|
|
Ian Kent |
e6cf32 |
+ if (errno == EBADF || errno == EINVAL)
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ /*
|
|
Ian Kent |
e6cf32 |
+ * Other than EAGAIN is an expire error so continue.
|
|
Ian Kent |
e6cf32 |
+ * Kernel will try the next mount for indirect
|
|
Ian Kent |
e6cf32 |
+ * mounts. For direct mounts it will just try the
|
|
Ian Kent |
e6cf32 |
+ * same mount again, limited by retries (ie. number
|
|
Ian Kent |
e6cf32 |
+ * of mounts directly under mount point, should
|
|
Ian Kent |
e6cf32 |
+ * always be one for direct mounts).
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+ if (errno == EAGAIN)
|
|
Ian Kent |
e6cf32 |
+ break;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ nanosleep(&tm, NULL);
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ctl.ops->askumount(logopt, ioctlfd, &ret))
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!ret)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_expire(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, const char *path, unsigned int when)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+ param.arg1 = when;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return expire(logopt, AUTOFS_DEV_IOCTL_EXPIRE,
|
|
Ian Kent |
e6cf32 |
+ ctl.devfd, ioctlfd, path, (void *) ¶m;;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_expire(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, const char *path, unsigned int when)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return expire(logopt, AUTOFS_IOC_EXPIRE_MULTI,
|
|
Ian Kent |
e6cf32 |
+ ioctlfd, ioctlfd, path, (void *) &when);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/* Check if autofs mount point is in use */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_askumount(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int *busy)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl param;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ init_autofs_dev_ioctl(¶m;;
|
|
Ian Kent |
e6cf32 |
+ param.ioctlfd = ioctlfd;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_ASKUMOUNT, ¶m) == -1)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *busy = param.arg1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+static int ioctl_askumount(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, unsigned int *busy)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ return ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, busy);
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+/*
|
|
Ian Kent |
e6cf32 |
+ * Check if the given path is a mountpoint.
|
|
Ian Kent |
e6cf32 |
+ *
|
|
Ian Kent |
e6cf32 |
+ * The path is considered a mountpoint if it is itself a mountpoint
|
|
Ian Kent |
e6cf32 |
+ * or contains a mount, such as a multi-mount without a root mount.
|
|
Ian Kent |
e6cf32 |
+ * In addition, if the path is itself a mountpoint we return whether
|
|
Ian Kent |
e6cf32 |
+ * the mounted file system is an autofs filesystem or other file
|
|
Ian Kent |
e6cf32 |
+ * system.
|
|
Ian Kent |
e6cf32 |
+ */
|
|
Ian Kent |
e6cf32 |
+static int dev_ioctl_ismountpoint(unsigned int logopt,
|
|
Ian Kent |
e6cf32 |
+ int ioctlfd, const char *path,
|
|
Ian Kent |
e6cf32 |
+ unsigned int *mountpoint)
|
|
Ian Kent |
e6cf32 |
+{
|
|
Ian Kent |
e6cf32 |
+ struct autofs_dev_ioctl *param;
|
|
Ian Kent |
e6cf32 |
+ int err;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ *mountpoint = 0;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (!path) {
|
|
Ian Kent |
e6cf32 |
+ errno = EINVAL;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ param = alloc_dev_ioctl_path(ioctlfd, path);
|
|
Ian Kent |
e6cf32 |
+ if (!param)
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ err = ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_ISMOUNTPOINT, param);
|
|
Ian Kent |
e6cf32 |
+ if (err == -1) {
|
|
Ian Kent |
e6cf32 |
+ int save_errno = errno;
|
|
Ian Kent |
e6cf32 |
+ free_dev_ioctl_open(param);
|
|
Ian Kent |
e6cf32 |
+ errno = save_errno;
|
|
Ian Kent |
e6cf32 |
+ return -1;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (param->arg1) {
|
|
Ian Kent |
e6cf32 |
+ *mountpoint = DEV_IOCTL_IS_MOUNTED;
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ if (param->arg2) {
|
|
Ian Kent |
e6cf32 |
+ if (param->arg2 == AUTOFS_SUPER_MAGIC)
|
|
Ian Kent |
e6cf32 |
+ *mountpoint |= DEV_IOCTL_IS_AUTOFS;
|
|
Ian Kent |
e6cf32 |
+ else
|
|
Ian Kent |
e6cf32 |
+ *mountpoint |= DEV_IOCTL_IS_OTHER;
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+ }
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ free_dev_ioctl_path(param);
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
+ return 0;
|
|
Ian Kent |
e6cf32 |
+}
|
|
Ian Kent |
e6cf32 |
diff -up autofs-5.0.3/samples/rc.autofs.in.device-node-control autofs-5.0.3/samples/rc.autofs.in
|
|
Ian Kent |
e6cf32 |
--- autofs-5.0.3/samples/rc.autofs.in.device-node-control 2008-01-14 13:39:16.000000000 +0900
|
|
Ian Kent |
e6cf32 |
+++ autofs-5.0.3/samples/rc.autofs.in 2008-02-25 09:03:12.000000000 +0900
|
|
Ian Kent |
e6cf32 |
@@ -12,6 +12,7 @@
|
|
Ian Kent |
e6cf32 |
DAEMON=@@sbindir@@/automount
|
|
Ian Kent |
e6cf32 |
prog=`basename $DAEMON`
|
|
Ian Kent |
e6cf32 |
MODULE="autofs4"
|
|
Ian Kent |
e6cf32 |
+DEVICE="autofs"
|
|
Ian Kent |
e6cf32 |
confdir=@@autofsconfdir@@
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
test -e $DAEMON || exit 0
|
|
Ian Kent |
e6cf32 |
@@ -47,6 +48,14 @@ function start() {
|
|
Ian Kent |
e6cf32 |
return 1
|
|
Ian Kent |
e6cf32 |
fi
|
|
Ian Kent |
e6cf32 |
|
|
Ian Kent |
e6cf32 |
+ # Check misc device
|
|
Ian Kent |
e6cf32 |
+ if [ -e "/proc/misc" ]; then
|
|
Ian Kent |
e6cf32 |
+ MINOR=`awk "/$DEVICE/ {print \\$1}" /proc/misc`
|
|
Ian Kent |
e6cf32 |
+ if [ -n "$MINOR" -a ! -c "/dev/$DEVICE" ]; then
|
|
Ian Kent |
e6cf32 |
+ mknod -m 0600 /dev/$DEVICE c 10 $MINOR
|
|
Ian Kent |
e6cf32 |
+ fi
|
|
Ian Kent |
e6cf32 |
+ fi
|
|
Ian Kent |
e6cf32 |
+
|
|
Ian Kent |
e6cf32 |
$prog $OPTIONS
|
|
Ian Kent |
e6cf32 |
RETVAL=$?
|
|
Ian Kent |
e6cf32 |
if [ $RETVAL -eq 0 ] ; then
|