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