vanhofen
3 years ago
126 changed files with 2128 additions and 12162 deletions
@ -0,0 +1,19 @@ |
|||
#!/bin/bash |
|||
|
|||
version=5.1.8 |
|||
url=https://mirrors.edge.kernel.org/pub/linux/daemons/autofs/v5/patches-5.1.9 |
|||
|
|||
cd patches |
|||
wget -N $url/patch_order_$version |
|||
i=0 |
|||
cat patch_order_$version | while read p; do |
|||
case "$p" in |
|||
*.patch) |
|||
i=$((i+1)) |
|||
t=$(printf "%04d\n" $i)-$p |
|||
if [ ! -f $t ]; then |
|||
wget -O $t $url/$p |
|||
fi |
|||
;; |
|||
esac |
|||
done |
@ -0,0 +1,139 @@ |
|||
autofs-5.1.8 - fix kernel mount status notification |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The status return for attempted mount notification is not done |
|||
correctly in some cases leading to a status being sent to the |
|||
kernel multiple times or the send causing an error. |
|||
|
|||
We must send a status to the kernel but it needs to be the correct |
|||
one. It definitely shouldn't be sent twice for the same mount attempt |
|||
and shouldn't be failing. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 2 ++ |
|||
daemon/direct.c | 19 +++++++++++-------- |
|||
daemon/indirect.c | 19 +++++++++++-------- |
|||
3 files changed, 24 insertions(+), 16 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 3be6119a..18a2f29c 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -1,3 +1,5 @@
|
|||
+- fix kernel mount status notification.
|
|||
+
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
- remove mount.x and rpcgen dependencies. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 4a56486b..c2331155 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -1147,12 +1147,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|||
return 0; |
|||
} |
|||
|
|||
-static void mount_send_fail(void *arg)
|
|||
+static void mount_send_status(void *arg)
|
|||
{ |
|||
struct ioctl_ops *ops = get_ioctl_ops(); |
|||
struct pending_args *mt = arg; |
|||
struct autofs_point *ap = mt->ap; |
|||
- ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|||
+
|
|||
+ if (mt->status)
|
|||
+ ops->send_fail(ap->logopt, mt->ioctlfd,
|
|||
+ mt->wait_queue_token, mt->status);
|
|||
+ else
|
|||
+ ops->send_ready(ap->logopt,
|
|||
+ mt->ioctlfd, mt->wait_queue_token);
|
|||
ops->close(ap->logopt, mt->ioctlfd); |
|||
} |
|||
|
|||
@@ -1181,7 +1187,8 @@ static void *do_mount_direct(void *arg)
|
|||
|
|||
pending_mutex_unlock(args); |
|||
|
|||
- pthread_cleanup_push(mount_send_fail, &mt);
|
|||
+ mt.status = 0;
|
|||
+ pthread_cleanup_push(mount_send_status, &mt);
|
|||
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); |
|||
|
|||
@@ -1195,9 +1202,7 @@ static void *do_mount_direct(void *arg)
|
|||
if (status == -1) { |
|||
error(ap->logopt, |
|||
"can't stat direct mount trigger %s", mt.name); |
|||
- ops->send_fail(ap->logopt,
|
|||
- mt.ioctlfd, mt.wait_queue_token, -ENOENT);
|
|||
- ops->close(ap->logopt, mt.ioctlfd);
|
|||
+ mt.status = -ENOENT;
|
|||
pthread_setcancelstate(state, NULL); |
|||
pthread_exit(NULL); |
|||
} |
|||
@@ -1207,8 +1212,6 @@ static void *do_mount_direct(void *arg)
|
|||
error(ap->logopt, |
|||
"direct trigger not valid or already mounted %s", |
|||
mt.name); |
|||
- ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|||
- ops->close(ap->logopt, mt.ioctlfd);
|
|||
pthread_setcancelstate(state, NULL); |
|||
pthread_exit(NULL); |
|||
} |
|||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|||
index b73c2781..23ef9f41 100644
|
|||
--- a/daemon/indirect.c
|
|||
+++ b/daemon/indirect.c
|
|||
@@ -683,13 +683,18 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
|
|||
return 0; |
|||
} |
|||
|
|||
-static void mount_send_fail(void *arg)
|
|||
+static void mount_send_status(void *arg)
|
|||
{ |
|||
struct ioctl_ops *ops = get_ioctl_ops(); |
|||
struct pending_args *mt = arg; |
|||
struct autofs_point *ap = mt->ap; |
|||
- ops->send_fail(ap->logopt,
|
|||
- ap->ioctlfd, mt->wait_queue_token, -ENOENT);
|
|||
+
|
|||
+ if (mt->status)
|
|||
+ ops->send_fail(ap->logopt, ap->ioctlfd,
|
|||
+ mt->wait_queue_token, mt->status);
|
|||
+ else
|
|||
+ ops->send_ready(ap->logopt,
|
|||
+ ap->ioctlfd, mt->wait_queue_token);
|
|||
} |
|||
|
|||
static void *do_mount_indirect(void *arg) |
|||
@@ -718,7 +723,8 @@ static void *do_mount_indirect(void *arg)
|
|||
|
|||
pending_mutex_unlock(args); |
|||
|
|||
- pthread_cleanup_push(mount_send_fail, &mt);
|
|||
+ mt.status = 0;
|
|||
+ pthread_cleanup_push(mount_send_status, &mt);
|
|||
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); |
|||
|
|||
@@ -731,9 +737,7 @@ static void *do_mount_indirect(void *arg)
|
|||
len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len); |
|||
if (!len) { |
|||
crit(ap->logopt, "path to be mounted is to long"); |
|||
- ops->send_fail(ap->logopt,
|
|||
- ap->ioctlfd, mt.wait_queue_token,
|
|||
- -ENAMETOOLONG);
|
|||
+ mt.status = -ENAMETOOLONG;
|
|||
pthread_setcancelstate(state, NULL); |
|||
pthread_exit(NULL); |
|||
} |
|||
@@ -742,7 +746,6 @@ static void *do_mount_indirect(void *arg)
|
|||
if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) { |
|||
error(ap->logopt, |
|||
"indirect trigger not valid or already mounted %s", buf); |
|||
- ops->send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
|
|||
pthread_setcancelstate(state, NULL); |
|||
pthread_exit(NULL); |
|||
} |
@ -0,0 +1,41 @@ |
|||
autofs-5.1.8 - fix fedfs build flags |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Dynamic executables should be compiled with -fPIE and linked with -pie. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
fedfs/Makefile | 4 ++-- |
|||
2 files changed, 3 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 18a2f29c..61090a99 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -1,4 +1,5 @@
|
|||
- fix kernel mount status notification. |
|||
+- fix fedfs build flags.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/fedfs/Makefile b/fedfs/Makefile
|
|||
index dff749e4..65b2a2f5 100644
|
|||
--- a/fedfs/Makefile
|
|||
+++ b/fedfs/Makefile
|
|||
@@ -23,12 +23,12 @@ LDFLAGS += -rdynamic
|
|||
all: mount.fedfs fedfs-map-nfs4 |
|||
|
|||
mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) |
|||
- $(CC) -o mount.fedfs \
|
|||
+ $(CC) $(DAEMON_LDFLAGS) -o mount.fedfs \
|
|||
$(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) \ |
|||
$(LDFLAGS) $(LIBRESOLV) $(LIBS) |
|||
|
|||
fedfs-map-nfs4: $(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) |
|||
- $(CC) -o fedfs-map-nfs4 \
|
|||
+ $(CC) $(DAEMON_LDFLAGS) -o fedfs-map-nfs4 \
|
|||
$(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) \ |
|||
$(LDFLAGS) $(LIBRESOLV) $(LIBS) |
|||
|
@ -0,0 +1,60 @@ |
|||
autofs-5.1.8 - fix set open file limit |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The check of whether the open file limit needs to be changed is not |
|||
right, it checks the hard open file limit against what autofs wants |
|||
to set it to which is always less than this value. Consequently the |
|||
open file limit isn't changed. |
|||
|
|||
autofs should be changing only the soft open file limit but it is |
|||
setting both the hard and soft limits. The system hard limit is much |
|||
higer than the autofs maximum open files so the hard limit should be |
|||
left alone. |
|||
|
|||
While we are here increase the requested maximum soft open file limit |
|||
to 20k. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 7 ++++--- |
|||
2 files changed, 5 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 61090a99..0cbfbe87 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -1,5 +1,6 @@
|
|||
- fix kernel mount status notification. |
|||
- fix fedfs build flags. |
|||
+- fix set open file limit.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index cc286892..b8cbdc1b 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -94,7 +94,7 @@ struct startup_cond suc = {
|
|||
pthread_key_t key_thread_stdenv_vars; |
|||
pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L; |
|||
|
|||
-#define MAX_OPEN_FILES 10240
|
|||
+#define MAX_OPEN_FILES 20480
|
|||
|
|||
int aquire_flag_file(void); |
|||
void release_flag_file(void); |
|||
@@ -2486,9 +2486,10 @@ int main(int argc, char *argv[])
|
|||
} |
|||
|
|||
res = getrlimit(RLIMIT_NOFILE, &rlim); |
|||
- if (res == -1 || rlim.rlim_max <= MAX_OPEN_FILES) {
|
|||
+ if (res == -1 || rlim.rlim_cur <= MAX_OPEN_FILES) {
|
|||
rlim.rlim_cur = MAX_OPEN_FILES; |
|||
- rlim.rlim_max = MAX_OPEN_FILES;
|
|||
+ if (rlim.rlim_max < MAX_OPEN_FILES)
|
|||
+ rlim.rlim_max = MAX_OPEN_FILES;
|
|||
} |
|||
res = setrlimit(RLIMIT_NOFILE, &rlim); |
|||
if (res) |
@ -0,0 +1,175 @@ |
|||
autofs-5.1.8 - improve descriptor open error reporting |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add error message reporting to the descriptor open functions. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 3 --- |
|||
daemon/spawn.c | 29 +++++++++++++++++++++++++++++ |
|||
lib/mounts.c | 10 ++-------- |
|||
modules/lookup_program.c | 5 +---- |
|||
5 files changed, 33 insertions(+), 15 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0cbfbe87..870fd8f3 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -1,6 +1,7 @@
|
|||
- fix kernel mount status notification. |
|||
- fix fedfs build flags. |
|||
- fix set open file limit. |
|||
+- improve descriptor open error reporting.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index b8cbdc1b..b47c485b 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -868,9 +868,6 @@ static int create_logpri_fifo(struct autofs_point *ap)
|
|||
|
|||
fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK); |
|||
if (fd < 0) { |
|||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
- crit(ap->logopt,
|
|||
- "Failed to open %s: %s", fifo_name, estr);
|
|||
unlink(fifo_name); |
|||
ret = -1; |
|||
goto out_free; |
|||
diff --git a/daemon/spawn.c b/daemon/spawn.c
|
|||
index 7992c5ab..914e5288 100644
|
|||
--- a/daemon/spawn.c
|
|||
+++ b/daemon/spawn.c
|
|||
@@ -94,7 +94,12 @@ int open_fd(const char *path, int flags)
|
|||
#endif |
|||
fd = open(path, flags); |
|||
if (fd == -1) { |
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr;
|
|||
+
|
|||
open_mutex_unlock(); |
|||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
|||
+ logerr("failed to open file: %s", estr);
|
|||
return -1; |
|||
} |
|||
check_cloexec(fd); |
|||
@@ -113,7 +118,12 @@ int open_fd_mode(const char *path, int flags, int mode)
|
|||
#endif |
|||
fd = open(path, flags, mode); |
|||
if (fd == -1) { |
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr;
|
|||
+
|
|||
open_mutex_unlock(); |
|||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
|||
+ logerr("failed to open file: %s", estr);
|
|||
return -1; |
|||
} |
|||
check_cloexec(fd); |
|||
@@ -123,6 +133,8 @@ int open_fd_mode(const char *path, int flags, int mode)
|
|||
|
|||
int open_pipe(int pipefd[2]) |
|||
{ |
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr;
|
|||
int ret; |
|||
|
|||
open_mutex_lock(); |
|||
@@ -145,6 +157,8 @@ done:
|
|||
return 0; |
|||
err: |
|||
open_mutex_unlock(); |
|||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
|||
+ logerr("failed to open pipe: %s", estr);
|
|||
return -1; |
|||
} |
|||
|
|||
@@ -159,7 +173,12 @@ int open_sock(int domain, int type, int protocol)
|
|||
#endif |
|||
fd = socket(domain, type, protocol); |
|||
if (fd == -1) { |
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr;
|
|||
+
|
|||
open_mutex_unlock(); |
|||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
|||
+ logerr("failed to open socket: %s", estr);
|
|||
return -1; |
|||
} |
|||
check_cloexec(fd); |
|||
@@ -184,7 +203,12 @@ FILE *open_fopen_r(const char *path)
|
|||
#endif |
|||
f = fopen(path, "r"); |
|||
if (f == NULL) { |
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr;
|
|||
+
|
|||
open_mutex_unlock(); |
|||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
|||
+ logerr("failed to open file: %s", estr);
|
|||
return NULL; |
|||
} |
|||
check_cloexec(fileno(f)); |
|||
@@ -209,7 +233,12 @@ FILE *open_setmntent_r(const char *table)
|
|||
#endif |
|||
tab = fopen(table, "r"); |
|||
if (tab == NULL) { |
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr;
|
|||
+
|
|||
open_mutex_unlock(); |
|||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
|||
+ logerr("failed to open mount table: %s", estr);
|
|||
return NULL; |
|||
} |
|||
check_cloexec(fileno(tab)); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 4c866885..39b7fe81 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2169,11 +2169,8 @@ struct mnt_list *get_mnt_list(const char *path, int include)
|
|||
return NULL; |
|||
|
|||
tab = open_fopen_r(_PROC_MOUNTS); |
|||
- if (!tab) {
|
|||
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
|
|||
- logerr("fopen: %s", estr);
|
|||
+ if (!tab)
|
|||
return NULL; |
|||
- }
|
|||
|
|||
while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { |
|||
len = strlen(mnt->mnt_dir); |
|||
@@ -2280,11 +2277,8 @@ static int table_is_mounted(const char *mp, unsigned int type)
|
|||
return 0; |
|||
|
|||
tab = open_fopen_r(_PROC_MOUNTS); |
|||
- if (!tab) {
|
|||
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
|
|||
- logerr("fopen: %s", estr);
|
|||
+ if (!tab)
|
|||
return 0; |
|||
- }
|
|||
|
|||
while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { |
|||
size_t len = strlen(mnt->mnt_dir); |
|||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
|||
index 691abedb..b5eb1117 100644
|
|||
--- a/modules/lookup_program.c
|
|||
+++ b/modules/lookup_program.c
|
|||
@@ -214,11 +214,8 @@ static char *lookup_one(struct autofs_point *ap,
|
|||
* want to send stderr to the syslog, and we don't use spawnl() |
|||
* because we need the pipe hooks |
|||
*/ |
|||
- if (open_pipe(pipefd)) {
|
|||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
- logerr(MODPREFIX "pipe: %s", estr);
|
|||
+ if (open_pipe(pipefd))
|
|||
goto out_error; |
|||
- }
|
|||
if (open_pipe(epipefd)) { |
|||
close(pipefd[0]); |
|||
close(pipefd[1]); |
@ -0,0 +1,91 @@ |
|||
autofs-5.1.8 - fix root offset error handling |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If mounting the root or offsets of a multi-mount root fails any mounts |
|||
done so far need to be umounted and the multi-mount offset tree deleted |
|||
so it can be created cleanly and possibly mounted the next time it's |
|||
triggered. |
|||
|
|||
Also, if a subtree that is not the multi-mount root fails the expire |
|||
alarm needs to be re-instated so other subtrees (at least the root) |
|||
will continue to expire. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 10 +++++++++- |
|||
modules/parse_sun.c | 6 ++++++ |
|||
3 files changed, 16 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 870fd8f3..6f18a0bb 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -2,6 +2,7 @@
|
|||
- fix fedfs build flags. |
|||
- fix set open file limit. |
|||
- improve descriptor open error reporting. |
|||
+- fix root offset error handling.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index c2331155..8810900c 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -1167,6 +1167,7 @@ static void *do_mount_direct(void *arg)
|
|||
struct ioctl_ops *ops = get_ioctl_ops(); |
|||
struct pending_args *args, mt; |
|||
struct autofs_point *ap; |
|||
+ struct mapent *me;
|
|||
struct stat st; |
|||
int status, state; |
|||
|
|||
@@ -1230,7 +1231,6 @@ static void *do_mount_direct(void *arg)
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); |
|||
if (status) { |
|||
struct mnt_list *sbmnt; |
|||
- struct mapent *me;
|
|||
struct statfs fs; |
|||
unsigned int close_fd = 0; |
|||
unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; |
|||
@@ -1271,6 +1271,14 @@ static void *do_mount_direct(void *arg)
|
|||
mt.ioctlfd, mt.wait_queue_token, -ENOENT); |
|||
ops->close(ap->logopt, mt.ioctlfd); |
|||
info(ap->logopt, "failed to mount %s", mt.name); |
|||
+
|
|||
+ /* If this is a multi-mount subtree mount failure
|
|||
+ * ensure the tree continues to expire.
|
|||
+ */
|
|||
+ me = cache_lookup_distinct(mt.mc, mt.name);
|
|||
+ if (me && IS_MM(me) && !IS_MM_ROOT(me))
|
|||
+ conditional_alarm_add(ap, ap->exp_runfreq);
|
|||
+ cache_unlock(mt.mc);
|
|||
} |
|||
pthread_setcancelstate(state, NULL); |
|||
|
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index d9ac0c94..56fe4161 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1142,6 +1142,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
if (!len) { |
|||
warn(ap->logopt, "path loo long"); |
|||
cache_unlock(mc); |
|||
+ cache_writelock(mc);
|
|||
+ tree_mapent_delete_offsets(mc, name);
|
|||
+ cache_unlock(mc);
|
|||
return 1; |
|||
} |
|||
key[len] = '/'; |
|||
@@ -1186,6 +1189,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
cache_unlock(mc); |
|||
error(ap->logopt, MODPREFIX |
|||
"failed to mount offset triggers"); |
|||
+ cache_writelock(mc);
|
|||
+ tree_mapent_delete_offsets(mc, name);
|
|||
+ cache_unlock(mc);
|
|||
return 1; |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
autofs-5.1.8 - fix fix root offset error handling |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The change to fix root offset error handlling is missing a cache read |
|||
lock prior to the key lookup, the following unmatched unlock then |
|||
causes a hang. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 1 + |
|||
2 files changed, 2 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 6f18a0bb..f81b0259 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -3,6 +3,7 @@
|
|||
- fix set open file limit. |
|||
- improve descriptor open error reporting. |
|||
- fix root offset error handling. |
|||
+- fix fix root offset error handling.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 8810900c..cf3f24d7 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -1275,6 +1275,7 @@ static void *do_mount_direct(void *arg)
|
|||
/* If this is a multi-mount subtree mount failure |
|||
* ensure the tree continues to expire. |
|||
*/ |
|||
+ cache_readlock(mt.mc);
|
|||
me = cache_lookup_distinct(mt.mc, mt.name); |
|||
if (me && IS_MM(me) && !IS_MM_ROOT(me)) |
|||
conditional_alarm_add(ap, ap->exp_runfreq); |
@ -0,0 +1,42 @@ |
|||
autofs-5.1.8 - fix nonstrict fail handling of last offset mount |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
When mounting a list of multi-mount offsets the offset mount should |
|||
succeed even if there's a mount failure for the non-strict case (the |
|||
default). |
|||
|
|||
But currently if the last offset mount fails the multi-mount fails |
|||
regardless of whether the mount is non-strict or not. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f81b0259..bd1f672c 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -4,6 +4,7 @@
|
|||
- improve descriptor open error reporting. |
|||
- fix root offset error handling. |
|||
- fix fix root offset error handling. |
|||
+- fix nonstrict fail handling of last offset mount.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 39b7fe81..b4229908 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1940,7 +1940,7 @@ static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr)
|
|||
tree_mapent_mount_offsets(oe, !ctxt->strict); |
|||
} |
|||
|
|||
- return ret;
|
|||
+ return (ctxt->strict ? ret : 1);
|
|||
} |
|||
|
|||
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict) |
@ -0,0 +1,50 @@ |
|||
autofs-5.1.8 - dont fail on duplicate host export entry |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If we encounter a duplicate host export entry don't fail, just ignore |
|||
it and return the duplicate. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 6 ++++-- |
|||
2 files changed, 5 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index bd1f672c..aaf20cd6 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -5,6 +5,7 @@
|
|||
- fix root offset error handling. |
|||
- fix fix root offset error handling. |
|||
- fix nonstrict fail handling of last offset mount. |
|||
+- dont fail on duplicate offset entry tree add.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index b4229908..451849a6 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1341,7 +1341,7 @@ static struct tree_node *tree_add_node(struct tree_node *root, void *ptr)
|
|||
} |
|||
|
|||
if (!eq) |
|||
- error(LOGOPT_ANY, "cannot add duplicate entry to tree");
|
|||
+ return p;
|
|||
else { |
|||
if (eq < 0) |
|||
return tree_add_left(p, ptr); |
|||
@@ -1515,8 +1515,10 @@ static int tree_host_cmp(struct tree_node *n, void *ptr)
|
|||
int eq; |
|||
|
|||
eq = strcmp(exp->dir, n_exp->dir); |
|||
- if (!eq)
|
|||
+ if (!eq) {
|
|||
+ error(LOGOPT_ANY, "duplicate entry %s ignored", exp->dir);
|
|||
return 0; |
|||
+ }
|
|||
return (exp_len < n_exp_len) ? -1 : 1; |
|||
} |
|||
|
@ -0,0 +1,40 @@ |
|||
autofs-5.1.8 - fix loop under run in cache_get_offset_parent() |
|||
|
|||
From: Frank Sorenson <sorenson@redhat.com> |
|||
|
|||
To avoid reading memory outside of the the string |
|||
allocated for parent, tail needs to stop when it |
|||
reaches or passes parent, even if it doesn't |
|||
actually equal parent. |
|||
|
|||
Signed-off-by: Frank Sorenson <sorenson@redhat.com> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/cache.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index aaf20cd6..b4b064ff 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -6,6 +6,7 @@
|
|||
- fix fix root offset error handling. |
|||
- fix nonstrict fail handling of last offset mount. |
|||
- dont fail on duplicate offset entry tree add. |
|||
+- fix loop under run in cache_get_offset_parent().
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index 66dda5d9..8aed28ea 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -710,7 +710,7 @@ struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key)
|
|||
*tail = 0; |
|||
|
|||
tail--; |
|||
- if (tail == parent)
|
|||
+ if (tail <= parent)
|
|||
break; |
|||
|
|||
me = cache_lookup_distinct(mc, parent); |
@ -0,0 +1,38 @@ |
|||
autofs-5.1.8 - bailout on rpc systemerror |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If there's a system error (eg. oversize packet received) just give up |
|||
since redoing the call would likely end up with the same error. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/rpc_subs.c | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b4b064ff..575f186d 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -7,6 +7,7 @@
|
|||
- fix nonstrict fail handling of last offset mount. |
|||
- dont fail on duplicate offset entry tree add. |
|||
- fix loop under run in cache_get_offset_parent(). |
|||
+- bailout on rpc systemerror.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|||
index 7b8162b4..ee7f94b9 100644
|
|||
--- a/lib/rpc_subs.c
|
|||
+++ b/lib/rpc_subs.c
|
|||
@@ -1195,6 +1195,8 @@ static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exp
|
|||
info->timeout); |
|||
if (status == RPC_SUCCESS) |
|||
break; |
|||
+ if (status == RPC_SYSTEMERROR)
|
|||
+ break;
|
|||
if (++vers_entry > 2) |
|||
break; |
|||
CLNT_CONTROL(client, CLSET_VERS, |
@ -0,0 +1,102 @@ |
|||
autofs-5.1.8 - fix nfsv4 only mounts should not use rpcbind |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Commit 606795ecfaa1 ("autofs-5.1.7 - also require TCP_REQUESTED when |
|||
setting NFS port" together with commit 26fb6b5408be) caused NFSv4 only |
|||
mounts to also use rpcbind to probe availability which breaks the |
|||
requirememt that this type of mount not use rpcbind at all. |
|||
|
|||
Fix this by treating fstype=nfs4 mounts as a special case which doesn't |
|||
use rpcbind. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/replicated.h | 2 ++ |
|||
modules/mount_nfs.c | 13 +++++++------ |
|||
modules/replicated.c | 4 ++-- |
|||
4 files changed, 12 insertions(+), 8 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 575f186d..4e5e82d0 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -8,6 +8,7 @@
|
|||
- dont fail on duplicate offset entry tree add. |
|||
- fix loop under run in cache_get_offset_parent(). |
|||
- bailout on rpc systemerror. |
|||
+- fix nfsv4 only mounts should not use rpcbind.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/include/replicated.h b/include/replicated.h
|
|||
index 95ff1f0d..f889a56a 100644
|
|||
--- a/include/replicated.h
|
|||
+++ b/include/replicated.h
|
|||
@@ -35,6 +35,8 @@
|
|||
#define NFS3_REQUESTED NFS3_SUPPORTED |
|||
#define NFS4_REQUESTED NFS4_SUPPORTED |
|||
|
|||
+#define NFS4_ONLY_REQUESTED 0x0800
|
|||
+
|
|||
#define TCP_SUPPORTED 0x0001 |
|||
#define UDP_SUPPORTED 0x0002 |
|||
#define TCP_REQUESTED TCP_SUPPORTED |
|||
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
|
|||
index 0ab87dcf..feb5afcd 100644
|
|||
--- a/modules/mount_nfs.c
|
|||
+++ b/modules/mount_nfs.c
|
|||
@@ -92,7 +92,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
mount_default_proto = defaults_get_mount_nfs_default_proto(); |
|||
vers = NFS_VERS_DEFAULT | NFS_PROTO_DEFAULT; |
|||
if (strcmp(fstype, "nfs4") == 0) |
|||
- vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED;
|
|||
+ vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED | NFS4_ONLY_REQUESTED;
|
|||
else if (mount_default_proto == 4) |
|||
vers = vers | NFS4_VERS_DEFAULT; |
|||
|
|||
@@ -157,15 +157,16 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
} else { |
|||
/* Is any version of NFSv4 in the options */ |
|||
if (_strncmp("vers=4", cp, 6) == 0 || |
|||
- _strncmp("nfsvers=4", cp, 9) == 0)
|
|||
- vers = NFS4_VERS_MASK | TCP_SUPPORTED;
|
|||
- else if (_strncmp("vers=3", cp, o_len) == 0 ||
|
|||
+ _strncmp("nfsvers=4", cp, 9) == 0) {
|
|||
+ vers &= ~(NFS_VERS_MASK);
|
|||
+ vers |= NFS4_VERS_MASK | TCP_SUPPORTED | NFS4_ONLY_REQUESTED;
|
|||
+ } else if (_strncmp("vers=3", cp, o_len) == 0 ||
|
|||
_strncmp("nfsvers=3", cp, o_len) == 0) { |
|||
- vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK);
|
|||
+ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK | NFS4_ONLY_REQUESTED);
|
|||
vers |= NFS3_REQUESTED; |
|||
} else if (_strncmp("vers=2", cp, o_len) == 0 || |
|||
_strncmp("nfsvers=2", cp, o_len) == 0) { |
|||
- vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK);
|
|||
+ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK | NFS4_ONLY_REQUESTED);
|
|||
vers |= NFS2_REQUESTED; |
|||
} else if (strstr(cp, "port=") == cp && |
|||
o_len - 5 < 25) { |
|||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|||
index 09075dd0..cdb7c617 100644
|
|||
--- a/modules/replicated.c
|
|||
+++ b/modules/replicated.c
|
|||
@@ -291,7 +291,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
|
|||
|
|||
rpc_info->proto = proto; |
|||
if (port < 0) { |
|||
- if ((version & NFS4_REQUESTED) && (version & TCP_REQUESTED))
|
|||
+ if (version & NFS4_REQUESTED && (version & NFS4_ONLY_REQUESTED))
|
|||
rpc_info->port = NFS_PORT; |
|||
else |
|||
port = 0; |
|||
@@ -525,7 +525,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
|
|||
{ |
|||
struct conn_info pm_info, rpc_info; |
|||
time_t timeout = RPC_TIMEOUT; |
|||
- unsigned int supported, vers = (NFS_VERS_MASK | NFS4_VERS_MASK);
|
|||
+ unsigned int supported, vers = (NFS_VERS_MASK | NFS4_VERS_MASK | NFS4_ONLY_REQUESTED);
|
|||
int ret = 0; |
|||
|
|||
if (!check_address_proto(logopt, host, version)) |
@ -0,0 +1,48 @@ |
|||
autofs-5.1.8 - simplify cache_add() a little |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If a map entry is being added to an existing hash chain there's an |
|||
unneccessarily complicted setting of ->next of the last entry. |
|||
|
|||
Just initialize the map entry ->next field instead and remove the |
|||
confusing assignment. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/cache.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 4e5e82d0..5b37460f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -9,6 +9,7 @@
|
|||
- fix loop under run in cache_get_offset_parent(). |
|||
- bailout on rpc systemerror. |
|||
- fix nfsv4 only mounts should not use rpcbind. |
|||
+- simplify cache_add() a little.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index 8aed28ea..4f908daf 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -564,6 +564,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
me->dev = (dev_t) -1; |
|||
me->ino = (ino_t) -1; |
|||
me->flags = 0; |
|||
+ me->next = NULL;
|
|||
|
|||
/* |
|||
* We need to add to the end if values exist in order to |
|||
@@ -583,7 +584,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
|
|||
existing = next; |
|||
} |
|||
- me->next = existing->next;
|
|||
existing->next = me; |
|||
} |
|||
return CHE_OK; |
@ -0,0 +1,59 @@ |
|||
autofs-5.1.8 - fix use after free in tree_mapent_delete_offset_tree() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The key field of the map entry of the root of the map entry tree to be |
|||
deleted can't be used for the key parameter, fix it. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 16 +++++++++++++--- |
|||
2 files changed, 14 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5b37460f..f05c9c6b 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -10,6 +10,7 @@
|
|||
- bailout on rpc systemerror. |
|||
- fix nfsv4 only mounts should not use rpcbind. |
|||
- simplify cache_add() a little. |
|||
+- fix use after free in tree_mapent_delete_offset_tree().
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 451849a6..c731f464 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1666,16 +1666,26 @@ static int tree_mapent_delete_offset_tree(struct tree_node *root)
|
|||
*/ |
|||
if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { |
|||
struct tree_node *root = MAPENT_ROOT(me); |
|||
+ char *key;
|
|||
|
|||
- debug(logopt, "deleting offset key %s", me->key);
|
|||
+ key = strdup(me->key);
|
|||
+ if (!key) {
|
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
+ error(logopt, "strdup: %s", estr);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ debug(logopt, "deleting offset key %s", key);
|
|||
|
|||
/* cache_delete won't delete an active offset */ |
|||
MAPENT_SET_ROOT(me, NULL); |
|||
- ret = cache_delete(me->mc, me->key);
|
|||
+ ret = cache_delete(me->mc, key);
|
|||
if (ret != CHE_OK) { |
|||
MAPENT_SET_ROOT(me, root); |
|||
- warn(logopt, "failed to delete offset %s", me->key);
|
|||
+ warn(logopt, "failed to delete offset %s", key);
|
|||
} |
|||
+ free(key);
|
|||
} else { |
|||
MAPENT_SET_ROOT(me, NULL); |
|||
MAPENT_SET_PARENT(me, NULL); |
@ -0,0 +1,44 @@ |
|||
autofs-5.1.8 - fix memory leak in xdr_exports() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Converting xdr_exports() to not be recursive introduced a memory leak |
|||
if an error is encountered, fix it. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/rpc_subs.c | 7 ++++++- |
|||
2 files changed, 7 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f05c9c6b..9d57a21b 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -11,6 +11,7 @@
|
|||
- fix nfsv4 only mounts should not use rpcbind. |
|||
- simplify cache_add() a little. |
|||
- fix use after free in tree_mapent_delete_offset_tree(). |
|||
+- fix memory leak in xdr_exports().
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|||
index ee7f94b9..0c833af0 100644
|
|||
--- a/lib/rpc_subs.c
|
|||
+++ b/lib/rpc_subs.c
|
|||
@@ -1151,8 +1151,13 @@ bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports)
|
|||
|
|||
export = (char **) exports; |
|||
while (1) { |
|||
- if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export))
|
|||
+ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) {
|
|||
+ if (*exports) {
|
|||
+ rpc_exports_free(*exports);
|
|||
+ *exports = NULL;
|
|||
+ }
|
|||
return FALSE; |
|||
+ }
|
|||
if (!*export) |
|||
break; |
|||
export = (char **) &((struct exportinfo *) *export)->next; |
@ -0,0 +1,39 @@ |
|||
autofs-5.1.8 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Don't call pthread_getspecific() if key_thread_attempt_id is NULL in |
|||
case the pthread_getspecific() implementation doesn't check for this. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/log.c | 3 +++ |
|||
2 files changed, 4 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9d57a21b..dacc2fa0 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -12,6 +12,7 @@
|
|||
- simplify cache_add() a little. |
|||
- fix use after free in tree_mapent_delete_offset_tree(). |
|||
- fix memory leak in xdr_exports(). |
|||
+- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/log.c b/lib/log.c
|
|||
index 0cb47d7e..d1edef28 100644
|
|||
--- a/lib/log.c
|
|||
+++ b/lib/log.c
|
|||
@@ -38,6 +38,9 @@ static char *prepare_attempt_prefix(const char *msg)
|
|||
char buffer[ATTEMPT_ID_SIZE + 1]; |
|||
char *prefixed_msg = NULL; |
|||
|
|||
+ if (!key_thread_attempt_id)
|
|||
+ return NULL;
|
|||
+
|
|||
attempt_id = pthread_getspecific(key_thread_attempt_id); |
|||
if (attempt_id) { |
|||
int len = sizeof(buffer) + 1 + strlen(msg) + 1; |
@ -0,0 +1,68 @@ |
|||
autofs-5.1.8 - fix sysconf(3) return handling |
|||
|
|||
From: Fabian Groffen <grobian@gentoo.org> |
|||
|
|||
The sysconf(3) return handling doesn't handle a -1 return with errno |
|||
not changed which indicated a maximum or minimum limit that's not |
|||
known. |
|||
|
|||
Add handling of this case. |
|||
|
|||
Signed-off-by: Fabian Groffen <grobian@gentoo.org> |
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 13 +++++++++++-- |
|||
2 files changed, 12 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index dacc2fa0..a063a126 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -13,6 +13,7 @@
|
|||
- fix use after free in tree_mapent_delete_offset_tree(). |
|||
- fix memory leak in xdr_exports(). |
|||
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id. |
|||
+- fix sysconf(3) return handling.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index c731f464..ad8f3de4 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2385,11 +2385,17 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
|
|||
|
|||
/* Try to get passwd info */ |
|||
|
|||
+ /* sysconf may return -1 with unchanged errno to indicate unlimited
|
|||
+ * size, same for the call for _SC_GETGR_R_SIZE_MAX below
|
|||
+ */
|
|||
+ errno = 0;
|
|||
tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); |
|||
- if (tmplen < 0) {
|
|||
+ if (tmplen < 0 && errno != 0) {
|
|||
error(logopt, "failed to get buffer size for getpwuid_r"); |
|||
goto free_tsv; |
|||
} |
|||
+ if (tmplen < 0)
|
|||
+ tmplen = 1024; /* assume something reasonable */
|
|||
|
|||
pw_tmp = malloc(tmplen + 1); |
|||
if (!pw_tmp) { |
|||
@@ -2422,11 +2428,14 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
|
|||
|
|||
/* Try to get group info */ |
|||
|
|||
+ errno = 0;
|
|||
grplen = sysconf(_SC_GETGR_R_SIZE_MAX); |
|||
- if (grplen < 0) {
|
|||
+ if (grplen < 0 && errno != 0) {
|
|||
error(logopt, "failed to get buffer size for getgrgid_r"); |
|||
goto free_tsv_home; |
|||
} |
|||
+ if (grplen < 0)
|
|||
+ grplen = 1024;
|
|||
|
|||
gr_tmp = NULL; |
|||
status = ERANGE; |
@ -0,0 +1,85 @@ |
|||
autofs-5.1.8 - remove nonstrict parameter from tree_mapent_umount_offsets() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The nonstrict parameter of tree_mapent_umount_offsets() ins't useful |
|||
because if a real mount at the base of a sub-tree fails to umount all |
|||
we can do is re-instate the offset mounts under it which must succeed |
|||
for the mount tree to remain useful. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 2 +- |
|||
include/mounts.h | 2 +- |
|||
lib/mounts.c | 6 +++--- |
|||
4 files changed, 6 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index a063a126..5402b88d 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -14,6 +14,7 @@
|
|||
- fix memory leak in xdr_exports(). |
|||
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id. |
|||
- fix sysconf(3) return handling. |
|||
+- remove nonstrict parameter from tree_mapent_umount_offsets().
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index b47c485b..353e4f54 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -558,7 +558,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
struct mapent *tmp; |
|||
int ret; |
|||
|
|||
- ret = tree_mapent_umount_offsets(me, 1);
|
|||
+ ret = tree_mapent_umount_offsets(me);
|
|||
if (!ret) { |
|||
warn(ap->logopt, |
|||
"some offset mounts still present under %s", path); |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index ddb7e4c5..23c7ba1c 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -182,7 +182,7 @@ int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct
|
|||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); |
|||
void tree_mapent_cleanup_offsets(struct mapent *oe); |
|||
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); |
|||
-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict);
|
|||
+int tree_mapent_umount_offsets(struct mapent *oe);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index ad8f3de4..617c1d54 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1843,7 +1843,7 @@ static int tree_mapent_umount_offset(struct mapent *oe, void *ptr)
|
|||
* Check for and umount subtree offsets resulting from |
|||
* nonstrict mount fail. |
|||
*/ |
|||
- ret = tree_mapent_umount_offsets(oe, ctxt->strict);
|
|||
+ ret = tree_mapent_umount_offsets(oe);
|
|||
if (!ret) |
|||
return 0; |
|||
|
|||
@@ -1975,14 +1975,14 @@ static int tree_mapent_umount_offsets_work(struct tree_node *n, void *ptr)
|
|||
return tree_mapent_umount_offset(oe, ptr); |
|||
} |
|||
|
|||
-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict)
|
|||
+int tree_mapent_umount_offsets(struct mapent *oe)
|
|||
{ |
|||
struct tree_node *base = MAPENT_NODE(oe); |
|||
struct autofs_point *ap = oe->mc->ap; |
|||
struct traverse_subtree_context ctxt = { |
|||
.ap = ap, |
|||
.base = base, |
|||
- .strict = !nonstrict,
|
|||
+ .strict = 1,
|
|||
}; |
|||
int ret; |
|||
|
@ -0,0 +1,116 @@ |
|||
autofs-5.1.8 - fix handling of incorrect return from umount_ent() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Commit 0210535df4b ("autofs-5.1.0 - gaurd against incorrect umount |
|||
return") guards against umount_ent() returning a fail when the mount |
|||
has actually been umounted. |
|||
|
|||
But we also see umount_ent() return success when in fact the mount has |
|||
not been umounted leading to incorrect handling of automounts. |
|||
|
|||
So checking the return of umount_ent() isn't always giving the correct |
|||
result in more than just one case, consequently we should ignore the |
|||
result from the spawned umount(8) and check if the mount has in fact |
|||
been umounted. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 3 +-- |
|||
lib/mounts.c | 19 ++++++++++--------- |
|||
3 files changed, 12 insertions(+), 11 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5402b88d..72a5aa59 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -15,6 +15,7 @@
|
|||
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id. |
|||
- fix sysconf(3) return handling. |
|||
- remove nonstrict parameter from tree_mapent_umount_offsets(). |
|||
+- fix handling of incorrect return from umount_ent().
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 353e4f54..85847edf 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -609,8 +609,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
struct mnt_list *mnt; |
|||
|
|||
debug(ap->logopt, "unmounting dir = %s", path); |
|||
- if (umount_ent(ap, path) &&
|
|||
- is_mounted(path, MNTS_REAL)) {
|
|||
+ if (umount_ent(ap, path)) {
|
|||
warn(ap->logopt, "could not umount dir %s", path); |
|||
left++; |
|||
goto done; |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 617c1d54..a3f9dfd7 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(struct mapent *oe, void *ptr)
|
|||
*/ |
|||
if (oe->ioctlfd != -1 || |
|||
is_mounted(oe->key, MNTS_REAL)) { |
|||
- if (umount_ent(ap, oe->key) &&
|
|||
- is_mounted(oe->key, MNTS_REAL)) {
|
|||
+ if (umount_ent(ap, oe->key)) {
|
|||
debug(ap->logopt, |
|||
"offset %s has active mount, invalidate", |
|||
oe->key); |
|||
@@ -2010,8 +2009,7 @@ int tree_mapent_umount_offsets(struct mapent *oe)
|
|||
*/ |
|||
if (is_mounted(mp, MNTS_REAL)) { |
|||
info(ap->logopt, "unmounting dir = %s", mp); |
|||
- if (umount_ent(ap, mp) &&
|
|||
- is_mounted(mp, MNTS_REAL)) {
|
|||
+ if (umount_ent(ap, mp)) {
|
|||
if (!tree_mapent_mount_offsets(oe, 1)) |
|||
warn(ap->logopt, |
|||
"failed to remount offset triggers"); |
|||
@@ -2982,6 +2980,7 @@ void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
|
|||
|
|||
int umount_ent(struct autofs_point *ap, const char *path) |
|||
{ |
|||
+ unsigned int mounted;
|
|||
int rv; |
|||
|
|||
if (ap->state != ST_SHUTDOWN_FORCE) |
|||
@@ -2993,6 +2992,8 @@ int umount_ent(struct autofs_point *ap, const char *path)
|
|||
rv = spawn_umount(ap->logopt, "-l", path, NULL); |
|||
} |
|||
|
|||
+ mounted = is_mounted(path, MNTS_REAL);
|
|||
+
|
|||
if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { |
|||
/* |
|||
* Verify that we actually unmounted the thing. This is a |
|||
@@ -3004,20 +3005,20 @@ int umount_ent(struct autofs_point *ap, const char *path)
|
|||
* so that we do not try to call rmdir_path on the |
|||
* directory. |
|||
*/ |
|||
- if (is_mounted(path, MNTS_REAL)) {
|
|||
+ if (mounted) {
|
|||
crit(ap->logopt, |
|||
"the umount binary reported that %s was " |
|||
"unmounted, but there is still something " |
|||
"mounted on this path.", path); |
|||
- rv = -1;
|
|||
+ mounted = -1;
|
|||
} |
|||
} |
|||
|
|||
- /* On success, check for mounted mount and remove it if found */
|
|||
- if (!rv)
|
|||
+ /* If mount is gone remove it from mounted mounts list. */
|
|||
+ if (!mounted)
|
|||
mnts_remove_mount(path, MNTS_MOUNTED); |
|||
|
|||
- return rv;
|
|||
+ return mounted;
|
|||
} |
|||
|
|||
int umount_amd_ext_mount(struct autofs_point *ap, const char *path) |
@ -0,0 +1,135 @@ |
|||
autofs-5.1.8 - dont use initgroups() at spawn |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The initgroups(3) function isn't safe to use between fork() and |
|||
exec() in a threaded program. |
|||
|
|||
Using it this way often leads to a hang for even moderate work |
|||
loads. |
|||
|
|||
But the getgrouplist()/setgroups() combination can be used safely |
|||
in this case and this patch changes autofs to use these (the safety |
|||
of using of setgroups() is yet to to be documented). |
|||
|
|||
A large portion of the work on this patch has been contributed |
|||
by Roberto Bergantinos <rbergant@redhat.com>. |
|||
|
|||
Reported-by: Roberto Bergantinos <rbergant@redhat.com> |
|||
Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()") |
|||
Signed-off-by: Roberto Bergantinos <rbergant@redhat.com> |
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- |
|||
2 files changed, 48 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 72a5aa59..e1214323 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -16,6 +16,7 @@
|
|||
- fix sysconf(3) return handling. |
|||
- remove nonstrict parameter from tree_mapent_umount_offsets(). |
|||
- fix handling of incorrect return from umount_ent(). |
|||
+- dont use initgroups() at spawn.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/spawn.c b/daemon/spawn.c
|
|||
index 914e5288..6f8856a9 100644
|
|||
--- a/daemon/spawn.c
|
|||
+++ b/daemon/spawn.c
|
|||
@@ -26,6 +26,7 @@
|
|||
#include <sys/wait.h> |
|||
#include <sys/stat.h> |
|||
#include <sys/mount.h> |
|||
+#include <pwd.h>
|
|||
|
|||
#include "automount.h" |
|||
|
|||
@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, unsigned int wait,
|
|||
struct thread_stdenv_vars *tsv; |
|||
pid_t euid = 0; |
|||
gid_t egid = 0; |
|||
+ gid_t *groups = NULL;
|
|||
+ gid_t *saved_groups = NULL;
|
|||
+ int ngroups = 0;
|
|||
+ int nsaved_groups = 0;
|
|||
|
|||
if (open_pipe(pipefd)) |
|||
return -1; |
|||
@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, unsigned int wait,
|
|||
} |
|||
|
|||
open_mutex_lock(); |
|||
+
|
|||
+ if (euid) {
|
|||
+ struct passwd *pwd;
|
|||
+
|
|||
+ pwd = getpwuid(getuid());
|
|||
+ if (!pwd)
|
|||
+ fprintf(stderr,
|
|||
+ "warning: getpwuid: can't get current username\n");
|
|||
+ else {
|
|||
+ /* get number of groups for current gid */
|
|||
+ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups);
|
|||
+ saved_groups = malloc(nsaved_groups * sizeof(gid_t));
|
|||
+
|
|||
+ /* get current gid groups list */
|
|||
+ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups);
|
|||
+ }
|
|||
+
|
|||
+ /* get number of groups of mount triggering process */
|
|||
+ getgrouplist(tsv->user, egid, NULL, &ngroups);
|
|||
+ groups = malloc(ngroups * sizeof(gid_t));
|
|||
+
|
|||
+ /* get groups list of mount triggering process */
|
|||
+ getgrouplist(tsv->user, egid, groups, &ngroups);
|
|||
+ }
|
|||
+
|
|||
f = fork(); |
|||
if (f == 0) { |
|||
char **pargv = (char **) argv; |
|||
@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, unsigned int wait,
|
|||
if (!tsv->user) |
|||
fprintf(stderr, |
|||
"warning: can't init groups\n"); |
|||
- else if (initgroups(tsv->user, egid) == -1)
|
|||
- fprintf(stderr,
|
|||
- "warning: initgroups: %s\n",
|
|||
- strerror(errno));
|
|||
+ else if (groups) {
|
|||
+ if (setgroups(ngroups, groups) == -1)
|
|||
+ fprintf(stderr,
|
|||
+ "warning: setgroups: %s\n",
|
|||
+ strerror(errno));
|
|||
+ free(groups);
|
|||
+ }
|
|||
|
|||
if (setegid(egid) == -1) |
|||
fprintf(stderr, |
|||
@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, unsigned int wait,
|
|||
strerror(errno)); |
|||
if (pgrp >= 0) |
|||
setpgid(0, pgrp); |
|||
+ /* Reset groups for trigger of trailing mount */
|
|||
+ if (euid && saved_groups) {
|
|||
+ setgroups(nsaved_groups, saved_groups);
|
|||
+ free(saved_groups);
|
|||
+ }
|
|||
|
|||
/* |
|||
* The kernel leaves mount type autofs alone because |
|||
@@ -474,6 +512,11 @@ done:
|
|||
pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); |
|||
open_mutex_unlock(); |
|||
|
|||
+ if (groups)
|
|||
+ free(groups);
|
|||
+ if (saved_groups)
|
|||
+ free(saved_groups);
|
|||
+
|
|||
close(pipefd[1]); |
|||
|
|||
if (f < 0) { |
@ -0,0 +1,60 @@ |
|||
autofs-5.1.8 - fix bashism in configure |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
configure scripts need to work with a POSIX-compliant shell, |
|||
so let's not use a bashism here. |
|||
|
|||
``` |
|||
checking for res_query in -lresolv... yes |
|||
checking for libhesiod... no |
|||
./configure: 4880: test: 0: unexpected operator |
|||
checking how to run the C preprocessor... gcc -E |
|||
``` |
|||
|
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
configure.in | 6 +++--- |
|||
2 files changed, 4 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index e1214323..dd76b02f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -17,6 +17,7 @@
|
|||
- remove nonstrict parameter from tree_mapent_umount_offsets(). |
|||
- fix handling of incorrect return from umount_ent(). |
|||
- dont use initgroups() at spawn. |
|||
+- fix bashism in configure.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/configure.in b/configure.in
|
|||
index 750ffb48..723bb30d 100644
|
|||
--- a/configure.in
|
|||
+++ b/configure.in
|
|||
@@ -262,7 +262,7 @@ if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0"
|
|||
then |
|||
HAVE_HESIOD=0 |
|||
AF_CHECK_LIBHESIOD() |
|||
- if test "$HAVE_HESIOD" == "1"; then
|
|||
+ if test "$HAVE_HESIOD" = "1"; then
|
|||
AC_DEFINE(WITH_HESIOD,1, |
|||
[Define if using Hesiod as a source of automount maps]) |
|||
fi |
|||
@@ -337,11 +337,11 @@ AC_ARG_WITH(sasl,
|
|||
SASL_FLAGS="-I${withval}/include" |
|||
fi |
|||
) |
|||
-if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
|
|||
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" = "1"
|
|||
then |
|||
HAVE_SASL=0 |
|||
AC_CHECK_LIB(sasl2, sasl_client_start, HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2", , -lsasl2 $LIBS) |
|||
- if test "$HAVE_SASL" == "1"; then
|
|||
+ if test "$HAVE_SASL" = "1"; then
|
|||
AC_DEFINE(WITH_SASL,1, |
|||
[Define if using SASL authentication with the LDAP module]) |
|||
fi |
@ -0,0 +1,46 @@ |
|||
autofs-5.1.8 - fix missing include in hash.h |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
Fixes a build failure with the musl libc: |
|||
``` |
|||
../include/hash.h:74:8: error: unknown type name '__always_inline' |
|||
74 | static __always_inline uint32_t hash_64(uint64_t val, unsigned int bits) |
|||
| ^~~~~~~~~~~~~~~ |
|||
``` |
|||
|
|||
We need to include stddef.h from linux-headers to ensure _always_inline |
|||
is always defined. |
|||
|
|||
Bug: https://bugs.gentoo.org/828918 |
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/hash.h | 1 + |
|||
2 files changed, 2 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index dd76b02f..53b487eb 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -18,6 +18,7 @@
|
|||
- fix handling of incorrect return from umount_ent(). |
|||
- dont use initgroups() at spawn. |
|||
- fix bashism in configure. |
|||
+- musl: fix missing include in hash.h.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/include/hash.h b/include/hash.h
|
|||
index 2447f293..010acd7e 100644
|
|||
--- a/include/hash.h
|
|||
+++ b/include/hash.h
|
|||
@@ -3,6 +3,7 @@
|
|||
/* Fast hashing routine for ints, longs and pointers. |
|||
(C) 2002 Nadia Yvette Chambers, IBM */ |
|||
|
|||
+#include <linux/stddef.h>
|
|||
#include <sys/types.h> |
|||
#include <stdint.h> |
|||
|
@ -0,0 +1,48 @@ |
|||
autofs-5.1.8 - define fallback dummy NSS config path |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
On musl, _PATH_NSSWITCH_CONF won't be defined (it doesn't support NSS), |
|||
so let's give it a dummy path when it's not defined by glibc. |
|||
|
|||
Fixes build failures like: |
|||
``` |
|||
../include/nsswitch.h:27:23: error: '_PATH_NSSWITCH_CONF' undeclared (first use in this function) |
|||
27 | #define NSSWITCH_FILE _PATH_NSSWITCH_CONF |
|||
| ^~~~~~~~~~~~~~~~~~~ |
|||
``` |
|||
|
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/nsswitch.h | 4 ++++ |
|||
2 files changed, 5 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 53b487eb..0627db48 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -19,6 +19,7 @@
|
|||
- dont use initgroups() at spawn. |
|||
- fix bashism in configure. |
|||
- musl: fix missing include in hash.h. |
|||
+- musl: define fallback dummy NSS config path
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/include/nsswitch.h b/include/nsswitch.h
|
|||
index d3e40277..8376113e 100644
|
|||
--- a/include/nsswitch.h
|
|||
+++ b/include/nsswitch.h
|
|||
@@ -24,6 +24,10 @@
|
|||
#include <netdb.h> |
|||
#include "list.h" |
|||
|
|||
+#ifndef _PATH_NSSWITCH_CONF
|
|||
+#define _PATH_NSSWITCH_CONF "/dev/null"
|
|||
+#endif
|
|||
+
|
|||
#define NSSWITCH_FILE _PATH_NSSWITCH_CONF |
|||
|
|||
enum nsswitch_status { |
@ -0,0 +1,77 @@ |
|||
autofs-5.1.8 - avoid internal stat.h definitions |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/lookup.c | 6 +++--- |
|||
modules/lookup_multi.c | 4 ++-- |
|||
3 files changed, 6 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0627db48..98c8da8d 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -20,6 +20,7 @@
|
|||
- fix bashism in configure. |
|||
- musl: fix missing include in hash.h. |
|||
- musl: define fallback dummy NSS config path |
|||
+- musl: avoid internal stat.h definitions.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|||
index 0b281f83..4a286d6b 100644
|
|||
--- a/daemon/lookup.c
|
|||
+++ b/daemon/lookup.c
|
|||
@@ -397,7 +397,7 @@ static int read_file_source_instance(struct autofs_point *ap, struct map_source
|
|||
return NSS_STATUS_NOTFOUND; |
|||
} |
|||
|
|||
- if (st.st_mode & __S_IEXEC)
|
|||
+ if (st.st_mode & S_IEXEC)
|
|||
type = src_prog; |
|||
else |
|||
type = src_file; |
|||
@@ -930,7 +930,7 @@ static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_
|
|||
return NSS_STATUS_NOTFOUND; |
|||
} |
|||
|
|||
- if (st.st_mode & __S_IEXEC)
|
|||
+ if (st.st_mode & S_IEXEC)
|
|||
type = src_prog; |
|||
else |
|||
type = src_file; |
|||
@@ -1077,7 +1077,7 @@ static struct map_source *lookup_get_map_source(struct master_mapent *entry)
|
|||
if (!S_ISREG(st.st_mode)) |
|||
return NULL; |
|||
|
|||
- if (st.st_mode & __S_IEXEC)
|
|||
+ if (st.st_mode & S_IEXEC)
|
|||
type = "program"; |
|||
else |
|||
type = "file"; |
|||
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
|
|||
index fadd2ea6..cf109de9 100644
|
|||
--- a/modules/lookup_multi.c
|
|||
+++ b/modules/lookup_multi.c
|
|||
@@ -247,7 +247,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch
|
|||
continue; |
|||
} |
|||
|
|||
- if (st.st_mode & __S_IEXEC)
|
|||
+ if (st.st_mode & S_IEXEC)
|
|||
type = src_prog; |
|||
else |
|||
type = src_file; |
|||
@@ -452,7 +452,7 @@ int lookup_reinit(const char *my_mapfmt,
|
|||
continue; |
|||
} |
|||
|
|||
- if (st.st_mode & __S_IEXEC)
|
|||
+ if (st.st_mode & S_IEXEC)
|
|||
type = src_prog; |
|||
else |
|||
type = src_file; |
@ -0,0 +1,46 @@ |
|||
autofs-5.1.8 - add missing include to hash.h for _WORDSIZE |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
Fixes build failure on musl like: |
|||
``` |
|||
../include/hash.h:22:2: error: #error Wordsize not 32 or 64 |
|||
22 | #error Wordsize not 32 or 64 |
|||
| ^~~~~ |
|||
``` |
|||
|
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/hash.h | 5 +++++ |
|||
2 files changed, 6 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 98c8da8d..02f8ef5f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -21,6 +21,7 @@
|
|||
- musl: fix missing include in hash.h. |
|||
- musl: define fallback dummy NSS config path |
|||
- musl: avoid internal stat.h definitions. |
|||
+- musl: add missing include to hash.h for _WORDSIZE.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/include/hash.h b/include/hash.h
|
|||
index 010acd7e..0f1d7b5d 100644
|
|||
--- a/include/hash.h
|
|||
+++ b/include/hash.h
|
|||
@@ -3,6 +3,11 @@
|
|||
/* Fast hashing routine for ints, longs and pointers. |
|||
(C) 2002 Nadia Yvette Chambers, IBM */ |
|||
|
|||
+#ifdef __GLIBC__
|
|||
+#include <bits/wordsize.h>
|
|||
+#else
|
|||
+#include <bits/reg.h>
|
|||
+#endif
|
|||
#include <linux/stddef.h> |
|||
#include <sys/types.h> |
|||
#include <stdint.h> |
@ -0,0 +1,47 @@ |
|||
autofs-5.1.8 - add missing include to log.h for pid_t |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
Fixes build failures on musl like: |
|||
``` |
|||
../include/log.h:49:8: error: unknown type name 'pid_t' |
|||
49 | extern pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label); |
|||
| ^~~~~ |
|||
../include/log.h:49:51: error: unknown type name 'pid_t'; did you mean 'gid_t'? |
|||
49 | extern pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label); |
|||
| ^~~~~ |
|||
| gid_t |
|||
``` |
|||
|
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/log.h | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 02f8ef5f..794cd04b 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -22,6 +22,7 @@
|
|||
- musl: define fallback dummy NSS config path |
|||
- musl: avoid internal stat.h definitions. |
|||
- musl: add missing include to hash.h for _WORDSIZE. |
|||
+- musl: add missing include to log.h for pid_t.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/include/log.h b/include/log.h
|
|||
index 69eed96b..a7b09f92 100644
|
|||
--- a/include/log.h
|
|||
+++ b/include/log.h
|
|||
@@ -17,6 +17,8 @@
|
|||
#ifndef LOG_H |
|||
#define LOG_H |
|||
|
|||
+#include <unistd.h>
|
|||
+
|
|||
/* Define logging functions */ |
|||
|
|||
#define LOGOPT_NONE 0x0000 |
@ -0,0 +1,56 @@ |
|||
autofs-5.1.8 - define _SWORD_TYPE for musl |
|||
|
|||
From: Sam James <sam@gentoo.org> |
|||
|
|||
Copy the definition from glibc. Fixes build failures like: |
|||
``` |
|||
automount.c:280:35: error: '__SWORD_TYPE' undeclared (first use in this function) |
|||
280 | if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) { |
|||
| ^~~~~~~~~~~~ |
|||
automount.c:280:35: note: each undeclared identifier is reported only once for each function it appears in |
|||
automount.c:280:48: error: expected ')' before numeric constant |
|||
280 | if (fs.f_type != (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) { |
|||
| ~ ^ |
|||
| ) |
|||
``` |
|||
|
|||
Tested-by: Yixun Lan <dlan@gentoo.org> |
|||
Signed-off-by: Sam James <sam@gentoo.org> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 10 ++++++++++ |
|||
2 files changed, 11 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 794cd04b..2e84b954 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -23,6 +23,7 @@
|
|||
- musl: avoid internal stat.h definitions. |
|||
- musl: add missing include to hash.h for _WORDSIZE. |
|||
- musl: add missing include to log.h for pid_t. |
|||
+- musl: define _SWORD_TYPE.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 85847edf..32f95a53 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -48,6 +48,16 @@
|
|||
#endif |
|||
#endif |
|||
|
|||
+#ifndef __SWORD_TYPE
|
|||
+#if __WORDSIZE == 32
|
|||
+# define __SWORD_TYPE int
|
|||
+#elif __WORDSIZE == 64
|
|||
+# define __SWORD_TYPE long int
|
|||
+#else
|
|||
+#error
|
|||
+#endif
|
|||
+#endif
|
|||
+
|
|||
const char *program; /* Initialized with argv[0] */ |
|||
const char *version = VERSION_STRING; /* Program version */ |
|||
const char *libdir = AUTOFS_LIB_DIR; /* Location of library modules */ |
@ -0,0 +1,62 @@ |
|||
autofs-5.1.8 - add autofs_strerror_r() helper for musl |
|||
|
|||
From: Fabian Groffen <grobian@gentoo.org> |
|||
|
|||
If using musl libc the XSI-compliant variant strerror_r() which returns |
|||
an integer instead of a pointer so add a helper function to handle this |
|||
case. |
|||
|
|||
Signed-off-by: Fabian Groffen <grobian@gentoo.org> |
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/automount.h | 5 +++++ |
|||
lib/log.c | 10 ++++++++++ |
|||
3 files changed, 16 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2e84b954..4f4ee181 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -24,6 +24,7 @@
|
|||
- musl: add missing include to hash.h for _WORDSIZE. |
|||
- musl: add missing include to log.h for pid_t. |
|||
- musl: define _SWORD_TYPE. |
|||
+- add autofs_strerror_r() helper for musl.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index 947ed16d..d2d05d89 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -43,6 +43,11 @@
|
|||
|
|||
#define ENABLE_CORES 1 |
|||
|
|||
+#ifndef __GLIBC__
|
|||
+# define strerror_r(N,B,S) autofs_strerror_r(N,B,S)
|
|||
+char *autofs_strerror_r(int errnum, char *buf, size_t buflen); /* GNU */
|
|||
+#endif
|
|||
+
|
|||
/* We MUST have the paths to mount(8) and umount(8) */ |
|||
#ifndef HAVE_MOUNT |
|||
#error Failed to locate mount(8)! |
|||
diff --git a/lib/log.c b/lib/log.c
|
|||
index d1edef28..43eccc07 100644
|
|||
--- a/lib/log.c
|
|||
+++ b/lib/log.c
|
|||
@@ -367,3 +367,13 @@ pid_t log_pidinfo(struct autofs_point *ap, pid_t pid, char *label) {
|
|||
|
|||
return ppid; |
|||
} |
|||
+
|
|||
+#ifndef __GLIBC__
|
|||
+# undef strerror_r
|
|||
+char *autofs_strerror_r(int errnum, char *buf, size_t buflen) {
|
|||
+ int s = strerror_r(errnum, buf, buflen);
|
|||
+ if (s)
|
|||
+ return NULL;
|
|||
+ return buf;
|
|||
+}
|
|||
+#endif
|
@ -0,0 +1,104 @@ |
|||
autofs-5.1.8 - update configure |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Update generated configure with autoconf and autoheader. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
configure | 20 ++++++++++++++++---- |
|||
2 files changed, 17 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 4f4ee181..2b4ddeb9 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -25,6 +25,7 @@
|
|||
- musl: add missing include to log.h for pid_t. |
|||
- musl: define _SWORD_TYPE. |
|||
- add autofs_strerror_r() helper for musl. |
|||
+- update configure.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/configure b/configure
|
|||
index 394a8d55..dc1c62db 100755
|
|||
--- a/configure
|
|||
+++ b/configure
|
|||
@@ -710,6 +710,7 @@ infodir
|
|||
docdir |
|||
oldincludedir |
|||
includedir |
|||
+runstatedir
|
|||
localstatedir |
|||
sharedstatedir |
|||
sysconfdir |
|||
@@ -810,6 +811,7 @@ datadir='${datarootdir}'
|
|||
sysconfdir='${prefix}/etc' |
|||
sharedstatedir='${prefix}/com' |
|||
localstatedir='${prefix}/var' |
|||
+runstatedir='${localstatedir}/run'
|
|||
includedir='${prefix}/include' |
|||
oldincludedir='/usr/include' |
|||
docdir='${datarootdir}/doc/${PACKAGE}' |
|||
@@ -1062,6 +1064,15 @@ do
|
|||
| -silent | --silent | --silen | --sile | --sil) |
|||
silent=yes ;; |
|||
|
|||
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
|
|||
+ | --runstate | --runstat | --runsta | --runst | --runs \
|
|||
+ | --run | --ru | --r)
|
|||
+ ac_prev=runstatedir ;;
|
|||
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
|||
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
|||
+ | --run=* | --ru=* | --r=*)
|
|||
+ runstatedir=$ac_optarg ;;
|
|||
+
|
|||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) |
|||
ac_prev=sbindir ;; |
|||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ |
|||
@@ -1199,7 +1210,7 @@ fi
|
|||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ |
|||
datadir sysconfdir sharedstatedir localstatedir includedir \ |
|||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ |
|||
- libdir localedir mandir
|
|||
+ libdir localedir mandir runstatedir
|
|||
do |
|||
eval ac_val=\$$ac_var |
|||
# Remove trailing slashes. |
|||
@@ -1352,6 +1363,7 @@ Fine tuning of the installation directories:
|
|||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc] |
|||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] |
|||
--localstatedir=DIR modifiable single-machine data [PREFIX/var] |
|||
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
|||
--libdir=DIR object code libraries [EPREFIX/lib] |
|||
--includedir=DIR C header files [PREFIX/include] |
|||
--oldincludedir=DIR C header files for non-gcc [/usr/include] |
|||
@@ -4877,7 +4889,7 @@ rm -f core conftest.err conftest.$ac_objext \
|
|||
# restore libs |
|||
LIBS="$af_check_hesiod_save_libs" |
|||
|
|||
- if test "$HAVE_HESIOD" == "1"; then
|
|||
+ if test "$HAVE_HESIOD" = "1"; then
|
|||
|
|||
$as_echo "#define WITH_HESIOD 1" >>confdefs.h |
|||
|
|||
@@ -5521,7 +5533,7 @@ if test "${with_sasl+set}" = set; then :
|
|||
|
|||
fi |
|||
|
|||
-if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1"
|
|||
+if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" = "1"
|
|||
then |
|||
HAVE_SASL=0 |
|||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sasl_client_start in -lsasl2" >&5 |
|||
@@ -5564,7 +5576,7 @@ if test "x$ac_cv_lib_sasl2_sasl_client_start" = xyes; then :
|
|||
HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2" |
|||
fi |
|||
|
|||
- if test "$HAVE_SASL" == "1"; then
|
|||
+ if test "$HAVE_SASL" = "1"; then
|
|||
|
|||
$as_echo "#define WITH_SASL 1" >>confdefs.h |
|||
|
@ -0,0 +1,113 @@ |
|||
autofs-5.1.8 - handle innetgr() not present in musl |
|||
|
|||
From: Fabian Groffen <grobian@gentoo.org> |
|||
|
|||
The function innetgr(3) may not be present in musl libc, add a check |
|||
for this. |
|||
|
|||
Originally contributed by Fabian, modified by me. |
|||
|
|||
Signed-off-by: Fabian Groffen <grobian@gentoo.org> |
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
configure | 9 +++++---- |
|||
configure.in | 2 +- |
|||
include/config.h.in | 3 +++ |
|||
modules/parse_amd.c | 7 +++++++ |
|||
5 files changed, 17 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2b4ddeb9..1f7c93ab 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -26,6 +26,7 @@
|
|||
- musl: define _SWORD_TYPE. |
|||
- add autofs_strerror_r() helper for musl. |
|||
- update configure. |
|||
+- handle innetgr() not present in musl.
|
|||
|
|||
19/10/2021 autofs-5.1.8 |
|||
- add xdr_exports(). |
|||
diff --git a/configure b/configure
|
|||
index dc1c62db..90ce6e0e 100755
|
|||
--- a/configure
|
|||
+++ b/configure
|
|||
@@ -4239,12 +4239,13 @@ fi
|
|||
|
|||
|
|||
|
|||
-for ac_func in pipe2
|
|||
+for ac_func in pipe2 innetgr
|
|||
do : |
|||
- ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
|
|||
-if test "x$ac_cv_func_pipe2" = xyes; then :
|
|||
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
|||
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
|||
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
|||
cat >>confdefs.h <<_ACEOF |
|||
-#define HAVE_PIPE2 1
|
|||
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
|||
_ACEOF |
|||
|
|||
fi |
|||
diff --git a/configure.in b/configure.in
|
|||
index 723bb30d..68cbd44a 100644
|
|||
--- a/configure.in
|
|||
+++ b/configure.in
|
|||
@@ -169,7 +169,7 @@ AF_CHECK_SSS_LIB(SSS_AUTOFS, libsss_autofs.so)
|
|||
AC_SUBST(HAVE_SSS_AUTOFS) |
|||
AC_SUBST(sssldir) |
|||
|
|||
-AC_CHECK_FUNCS(pipe2)
|
|||
+AC_CHECK_FUNCS(pipe2 innetgr)
|
|||
|
|||
# |
|||
# Newer mounts have the -s (sloppy) option to ignore unknown options, |
|||
diff --git a/include/config.h.in b/include/config.h.in
|
|||
index 4e36b390..4f8daa86 100644
|
|||
--- a/include/config.h.in
|
|||
+++ b/include/config.h.in
|
|||
@@ -30,6 +30,9 @@
|
|||
/* Define to 1 if you have the `getservbyname' function. */ |
|||
#undef HAVE_GETSERVBYNAME |
|||
|
|||
+/* Define to 1 if you have the `innetgr' function. */
|
|||
+#undef HAVE_INNETGR
|
|||
+
|
|||
/* Define to 1 if you have the <inttypes.h> header file. */ |
|||
#undef HAVE_INTTYPES_H |
|||
|
|||
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
|
|||
index 163174cd..5090060d 100644
|
|||
--- a/modules/parse_amd.c
|
|||
+++ b/modules/parse_amd.c
|
|||
@@ -425,6 +425,7 @@ static int sel_in_network(struct autofs_point *ap,
|
|||
return ret; |
|||
} |
|||
|
|||
+#ifdef HAVE_INNETGR
|
|||
static int sel_netgrp(struct autofs_point *ap, |
|||
struct selector *s, struct substvar *sv) |
|||
{ |
|||
@@ -489,6 +490,7 @@ out:
|
|||
|
|||
return ret; |
|||
} |
|||
+#endif
|
|||
|
|||
static int eval_selector(struct autofs_point *ap, |
|||
struct amd_entry *this, struct substvar *sv) |
|||
@@ -628,7 +630,12 @@ static int eval_selector(struct autofs_point *ap,
|
|||
switch (s->sel->selector) { |
|||
case SEL_NETGRP: |
|||
case SEL_NETGRPD: |
|||
+#ifndef HAVE_INNETGR
|
|||
+ error(logopt, MODPREFIX
|
|||
+ "netgroups not available, function innetgr(3) not available");
|
|||
+#else
|
|||
ret = sel_netgrp(ap, s, sv); |
|||
+#endif
|
|||
break; |
|||
|
|||
default: |
@ -1,48 +0,0 @@ |
|||
autofs-5.1.7 - Fix option for master read wait |
|||
|
|||
From: Goldwyn Rodrigues <rgoldwyn@suse.de> |
|||
|
|||
The master-wait program option expects a value, and if provided |
|||
automount crashes with the following trace: |
|||
|
|||
#0 __GI_____strtoul_l_internal (nptr=0x0, endptr=0x7fffffffe120, base=0, group=<optimized out>, |
|||
loc=0x7ffff77a63a0 <_nl_global_locale>) at ../stdlib/strtol_l.c:292 |
|||
#1 0x0000555555562c52 in getnumopt () |
|||
#2 0x0000555555564ec0 in main () |
|||
|
|||
This is because the options string is not correct and does not expect |
|||
an argument for master-wait (M), which sets optarg to NULL. |
|||
|
|||
Fixes: e68f07f ("autofs-5.1.2 - add master read wait option") |
|||
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> |
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index fe49740e..0b577909 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -4,6 +4,7 @@
|
|||
- dont use realloc in host exports list processing. |
|||
- use sprintf() when constructing hosts mapent. |
|||
- fix mnts_remove_amdmount() uses wrong list. |
|||
+- Fix option for master read wait.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index e476f6b2..7fa92877 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -2274,7 +2274,7 @@ int main(int argc, char *argv[])
|
|||
time_t timeout; |
|||
time_t age = monotonic_time(NULL); |
|||
struct rlimit rlim; |
|||
- const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM";
|
|||
+ const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM:";
|
|||
static const struct option long_options[] = { |
|||
{"help", 0, 0, 'h'}, |
|||
{"pid-file", 1, 0, 'p'}, |
@ -1,136 +0,0 @@ |
|||
autofs-5.1.7 - add a len field to struct autofs_point |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add a path length field to struct autofs_point since the path length |
|||
is needed at various times avoiding additional strlen() calls. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/lookup.c | 2 +- |
|||
daemon/master.c | 1 + |
|||
include/automount.h | 1 + |
|||
lib/mounts.c | 6 +++--- |
|||
modules/parse_amd.c | 4 ++-- |
|||
modules/parse_sun.c | 4 ++-- |
|||
7 files changed, 11 insertions(+), 8 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 60924b3f..0dae6761 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -30,6 +30,7 @@
|
|||
- rename tree implementation functions. |
|||
- add some multi-mount macros. |
|||
- remove unused functions cache_dump_multi() and cache_dump_cache(). |
|||
+- add a len field to struct autofs_point.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|||
index 8c9a82b5..5116b927 100644
|
|||
--- a/daemon/lookup.c
|
|||
+++ b/daemon/lookup.c
|
|||
@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
|
|||
return NSS_STATUS_UNKNOWN; |
|||
} |
|||
|
|||
- m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2);
|
|||
+ m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2);
|
|||
if (!m_key) { |
|||
error(ap->logopt, |
|||
"failed to allocate storage for search key"); |
|||
diff --git a/daemon/master.c b/daemon/master.c
|
|||
index da527a61..022fb9dd 100644
|
|||
--- a/daemon/master.c
|
|||
+++ b/daemon/master.c
|
|||
@@ -86,6 +86,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
|
|||
free(ap); |
|||
return 0; |
|||
} |
|||
+ ap->len = strlen(ap->path);
|
|||
ap->pref = NULL; |
|||
|
|||
ap->entry = entry; |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index e917515b..34485859 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -548,6 +548,7 @@ struct kernel_mod_version {
|
|||
struct autofs_point { |
|||
pthread_t thid; |
|||
char *path; /* Mount point name */ |
|||
+ size_t len; /* Length of mount point name */
|
|||
mode_t mode; /* Mount point mode */ |
|||
char *pref; /* amd prefix */ |
|||
int pipefd; /* File descriptor for pipe */ |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index f6f20fc0..b478ecb4 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1158,7 +1158,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
|||
if (!mp) |
|||
goto fail; |
|||
} else { |
|||
- int len = strlen(ap->path) + strlen(name) + 2;
|
|||
+ int len = ap->len + strlen(name) + 2;
|
|||
|
|||
mp = malloc(len); |
|||
if (!mp) |
|||
@@ -2495,9 +2495,9 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
|
|||
dir = strdup(oe->key); |
|||
|
|||
if (ap->flags & MOUNT_FLAG_GHOST) |
|||
- split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1;
|
|||
+ split = ap->len + strlen(MM_ROOT(oe)->key) + 1;
|
|||
else |
|||
- split = strlen(ap->path);
|
|||
+ split = ap->len;
|
|||
|
|||
dir[split] = '\0'; |
|||
path = &dir[split + 1]; |
|||
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
|
|||
index d3e8a450..5a9079d6 100644
|
|||
--- a/modules/parse_amd.c
|
|||
+++ b/modules/parse_amd.c
|
|||
@@ -147,7 +147,7 @@ static struct substvar *add_lookup_vars(struct autofs_point *ap,
|
|||
struct mapent *me; |
|||
int len; |
|||
|
|||
- len = strlen(ap->path) + 1 + key_len + 1;
|
|||
+ len = ap->len + 1 + key_len + 1;
|
|||
if (len > PATH_MAX) { |
|||
error(ap->logopt, MODPREFIX |
|||
"error: lookup key is greater than PATH_MAX"); |
|||
@@ -1319,7 +1319,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name,
|
|||
char *target; |
|||
size_t len; |
|||
|
|||
- len = strlen(ap->path) + strlen(entry->rhost) + 2;
|
|||
+ len = ap->len + strlen(entry->rhost) + 2;
|
|||
target = malloc(len); |
|||
if (!target) { |
|||
warn(ap->logopt, MODPREFIX |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index b11c6693..b1f64ca0 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1154,7 +1154,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
mm_root = mm_key; |
|||
start = strlen(mm_key); |
|||
} else { |
|||
- start = strlen(ap->path) + strlen(mm_key) + 1;
|
|||
+ start = ap->len + strlen(mm_key) + 1;
|
|||
mm_root = alloca(start + 3); |
|||
strcpy(mm_root, ap->path); |
|||
strcat(mm_root, "/"); |
|||
@@ -1477,7 +1477,7 @@ dont_expand:
|
|||
} |
|||
strcpy(m_root, name); |
|||
} else { |
|||
- m_root_len = strlen(ap->path) + name_len + 1;
|
|||
+ m_root_len = ap->len + name_len + 1;
|
|||
m_root = alloca(m_root_len + 1); |
|||
if (!m_root) { |
|||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
@ -1,51 +0,0 @@ |
|||
autofs-5.1.7 - add buffer length check to rmdir_path() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add a length check before copying the incoming path string to the work |
|||
buffer. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 8 ++++++-- |
|||
2 files changed, 7 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ded0f00f..38304720 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -86,6 +86,7 @@
|
|||
- add mapent path length check in handle_packet_expire_direct(). |
|||
- add copy length check in umount_autofs_indirect(). |
|||
- add some buffer length checks to master map parser. |
|||
+- add buffer length check to rmdir_path().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 45e0833f..114b013a 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -241,15 +241,19 @@ int mkdir_path(const char *path, mode_t mode)
|
|||
int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev) |
|||
{ |
|||
int len = strlen(path); |
|||
- char buf[PATH_MAX];
|
|||
+ char buf[PATH_MAX + 1];
|
|||
char *cp; |
|||
int first = 1; |
|||
struct stat st; |
|||
struct statfs fs; |
|||
|
|||
+ if (len > PATH_MAX) {
|
|||
+ error(ap->logopt, "path longer than maximum length");
|
|||
+ return -1;
|
|||
+ }
|
|||
strcpy(buf, path); |
|||
- cp = buf + len;
|
|||
|
|||
+ cp = buf + len;
|
|||
do { |
|||
*cp = '\0'; |
|||
|
@ -1,108 +0,0 @@ |
|||
autofs-5.1.7 - add buffer length checks to autofs mount_mount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
|
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/mount_autofs.c | 59 +++++++++++++++++++++++++++++++++--------------- |
|||
2 files changed, 41 insertions(+), 19 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 6ab4813d..17926916 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -88,6 +88,7 @@
|
|||
- add some buffer length checks to master map parser. |
|||
- add buffer length check to rmdir_path(). |
|||
- eliminate buffer usage from handle_mounts_cleanup(). |
|||
+- add buffer length checks to autofs mount_mount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
|
|||
index 0bcbb343..b2233573 100644
|
|||
--- a/modules/mount_autofs.c
|
|||
+++ b/modules/mount_autofs.c
|
|||
@@ -50,8 +50,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|||
{ |
|||
struct startup_cond suc; |
|||
pthread_t thid; |
|||
- char realpath[PATH_MAX];
|
|||
- char mountpoint[PATH_MAX];
|
|||
+ char realpath[PATH_MAX + 1];
|
|||
+ char mountpoint[PATH_MAX + 1];
|
|||
const char **argv; |
|||
int argc, status; |
|||
int nobind = ap->flags & MOUNT_FLAG_NOBIND; |
|||
@@ -68,32 +68,53 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|||
struct mnt_list *mnt; |
|||
char buf[MAX_ERR_BUF]; |
|||
char *options, *p; |
|||
- int len, ret;
|
|||
+ int err, ret;
|
|||
int hosts = 0; |
|||
|
|||
/* Root offset of multi-mount */ |
|||
- len = strlen(root);
|
|||
- if (root[len - 1] == '/') {
|
|||
- strcpy(realpath, ap->path);
|
|||
- strcat(realpath, "/");
|
|||
- strcat(realpath, name);
|
|||
- len--;
|
|||
- strncpy(mountpoint, root, len);
|
|||
- mountpoint[len] = '\0';
|
|||
+ if (root[strlen(root) - 1] == '/') {
|
|||
+ err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for realpath");
|
|||
+ return 1;
|
|||
+ }
|
|||
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
|
|||
+ return 1;
|
|||
+ }
|
|||
+ mountpoint[err - 1] = 0;
|
|||
} else if (*name == '/') { |
|||
if (ap->flags & MOUNT_FLAG_REMOUNT) { |
|||
- strcpy(mountpoint, name);
|
|||
- strcpy(realpath, name);
|
|||
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", name);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
|
|||
+ return 1;
|
|||
+ }
|
|||
+ err = snprintf(realpath, PATH_MAX + 1, "%s", name);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for realpath");
|
|||
+ return 1;
|
|||
+ }
|
|||
} else { |
|||
- strcpy(mountpoint, root);
|
|||
- strcpy(realpath, name);
|
|||
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
|
|||
+ return 1;
|
|||
+ }
|
|||
+ err = snprintf(realpath, PATH_MAX + 1, "%s", name);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for realpath");
|
|||
+ return 1;
|
|||
+ }
|
|||
} |
|||
} else { |
|||
- strcpy(mountpoint, root);
|
|||
- strcat(mountpoint, "/");
|
|||
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name);
|
|||
+ if (err > PATH_MAX) {
|
|||
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
|
|||
+ return 1;
|
|||
+ }
|
|||
strcpy(realpath, mountpoint); |
|||
- strcat(mountpoint, name);
|
|||
- strcat(realpath, name);
|
|||
} |
|||
|
|||
options = NULL; |
@ -1,51 +0,0 @@ |
|||
autofs-5.1.7 - add copy length check in umount_autofs_indirect() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add a source length check before copying to a work buffer in |
|||
umount_autofs_indirect(). |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/indirect.c | 13 +++++++++++-- |
|||
2 files changed, 12 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5fdb4c0a..be0b9d85 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -84,6 +84,7 @@
|
|||
- fix use of possibly NULL var in lookup_program.c:match_key(). |
|||
- fix incorrect print format specifiers in get_pkt(). |
|||
- add mapent path length check in handle_packet_expire_direct(). |
|||
+- add copy length check in umount_autofs_indirect().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|||
index 9f2ca6a0..b73c2781 100644
|
|||
--- a/daemon/indirect.c
|
|||
+++ b/daemon/indirect.c
|
|||
@@ -238,10 +238,19 @@ int umount_autofs_indirect(struct autofs_point *ap, const char *root)
|
|||
int rv, retries; |
|||
unsigned int unused; |
|||
|
|||
- if (root)
|
|||
+ if (root) {
|
|||
+ if (strlen(root) > PATH_MAX) {
|
|||
+ error(ap->logopt, "mountpoint path too long");
|
|||
+ return 1;
|
|||
+ }
|
|||
strcpy(mountpoint, root); |
|||
- else
|
|||
+ } else {
|
|||
+ if (ap->len > PATH_MAX) {
|
|||
+ error(ap->logopt, "mountpoint path too long");
|
|||
+ return 1;
|
|||
+ }
|
|||
strcpy(mountpoint, ap->path); |
|||
+ }
|
|||
|
|||
/* If we are trying to shutdown make sure we can umount */ |
|||
rv = ops->askumount(ap->logopt, ap->ioctlfd, &unused); |
@ -1,104 +0,0 @@ |
|||
autofs-5.1.7 - add ext_mount_hash_mutex lock helpers |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: check_return: Calling "pthread_mutex_lock" without checking |
|||
return value. |
|||
|
|||
Well, I use helpers to do this in many places so can't really disagree. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 26 ++++++++++++++++++++------ |
|||
2 files changed, 21 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b1b28888..ff44ac25 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -65,6 +65,7 @@
|
|||
- fix double free in parse_mapent(). |
|||
- refactor lookup_prune_one_cache() a bit. |
|||
- cater for empty mounts list in mnts_get_expire_list(). |
|||
+- add ext_mount_hash_mutex lock helpers.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 3996eb5e..c24d1a88 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -788,6 +788,20 @@ char *make_mnt_name_string(char *path)
|
|||
return mnt_name; |
|||
} |
|||
|
|||
+static void ext_mount_hash_mutex_lock(void)
|
|||
+{
|
|||
+ int status = pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ if (status)
|
|||
+ fatal(status);
|
|||
+}
|
|||
+
|
|||
+static void ext_mount_hash_mutex_unlock(void)
|
|||
+{
|
|||
+ int status = pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ if (status)
|
|||
+ fatal(status);
|
|||
+}
|
|||
+
|
|||
static struct ext_mount *ext_mount_lookup(const char *mp) |
|||
{ |
|||
uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash)); |
|||
@@ -806,7 +820,7 @@ int ext_mount_add(const char *path, const char *umount)
|
|||
struct ext_mount *em; |
|||
int ret = 0; |
|||
|
|||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_lock();
|
|||
|
|||
em = ext_mount_lookup(path); |
|||
if (em) { |
|||
@@ -840,7 +854,7 @@ int ext_mount_add(const char *path, const char *umount)
|
|||
|
|||
ret = 1; |
|||
done: |
|||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_unlock();
|
|||
return ret; |
|||
} |
|||
|
|||
@@ -849,7 +863,7 @@ int ext_mount_remove(const char *path)
|
|||
struct ext_mount *em; |
|||
int ret = 0; |
|||
|
|||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_lock();
|
|||
|
|||
em = ext_mount_lookup(path); |
|||
if (!em) |
|||
@@ -867,7 +881,7 @@ int ext_mount_remove(const char *path)
|
|||
ret = 1; |
|||
} |
|||
done: |
|||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_unlock();
|
|||
return ret; |
|||
} |
|||
|
|||
@@ -876,13 +890,13 @@ int ext_mount_inuse(const char *path)
|
|||
struct ext_mount *em; |
|||
int ret = 0; |
|||
|
|||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_lock();
|
|||
em = ext_mount_lookup(path); |
|||
if (!em) |
|||
goto done; |
|||
ret = em->ref; |
|||
done: |
|||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_unlock();
|
|||
return ret; |
|||
} |
|||
|
@ -1,42 +0,0 @@ |
|||
autofs-5.1.7 - add length check in umount_subtree_mounts() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: fixed_size_dest: You might overrun the 4097-character |
|||
fixed-size string "key" by copying "me->key" without |
|||
checking the length. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 5 +++++ |
|||
2 files changed, 6 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 224f58d6..9e385ba9 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -55,6 +55,7 @@
|
|||
- fix possible memory leak in master_parse(). |
|||
- fix possible memory leak in mnts_add_amdmount(). |
|||
- fix double unlock in parse_mount(). |
|||
+- add length check in umount_subtree_mounts().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 48472d5f..70506d83 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
left++; |
|||
} |
|||
|
|||
+ if (me->len > PATH_MAX) {
|
|||
+ crit(ap->logopt, "me->key too long for buffer");
|
|||
+ return 1;
|
|||
+ }
|
|||
+
|
|||
strcpy(key, me->key); |
|||
|
|||
cache_unlock(mc); |
@ -1,60 +0,0 @@ |
|||
autofs-5.1.7 - add mapent path length check in handle_packet_expire_direct() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Since direct mount expire requests from the kernel need to look up their |
|||
map entry and copy the path to a request processing struct fix length |
|||
char array the copy length should be checked. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 12 ++++++++---- |
|||
2 files changed, 9 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0dac7318..5fdb4c0a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -83,6 +83,7 @@
|
|||
- use default stack size for threads. |
|||
- fix use of possibly NULL var in lookup_program.c:match_key(). |
|||
- fix incorrect print format specifiers in get_pkt(). |
|||
+- add mapent path length check in handle_packet_expire_direct().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index d37dd676..4a56486b 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -1039,13 +1039,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|||
map = map->next; |
|||
} |
|||
|
|||
- if (!me) {
|
|||
+ if (!me || me->len >= PATH_MAX) {
|
|||
/* |
|||
* Shouldn't happen as we have been sent this following |
|||
* successful thread creation and lookup. |
|||
*/ |
|||
- crit(ap->logopt, "can't find map entry for (%lu,%lu)",
|
|||
- (unsigned long) pkt->dev, (unsigned long) pkt->ino);
|
|||
+ if (!me)
|
|||
+ crit(ap->logopt, "can't find map entry for (%lu,%lu)",
|
|||
+ (unsigned long) pkt->dev, (unsigned long) pkt->ino);
|
|||
+ else {
|
|||
+ cache_unlock(mc);
|
|||
+ crit(ap->logopt, "lookup key is too long");
|
|||
+ }
|
|||
master_source_unlock(ap->entry); |
|||
pthread_setcancelstate(state, NULL); |
|||
return 1; |
|||
@@ -1091,7 +1096,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|||
mt->ap = ap; |
|||
mt->ioctlfd = me->ioctlfd; |
|||
mt->mc = mc; |
|||
- /* TODO: check length here */
|
|||
strcpy(mt->name, me->key); |
|||
mt->dev = me->dev; |
|||
mt->type = NFY_EXPIRE; |
@ -1,177 +0,0 @@ |
|||
autofs-5.1.7 - add mapent tree implementation |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add a struct mapent basic tree implementation. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/automount.h | 4 ++++ |
|||
include/mounts.h | 8 ++++++++ |
|||
lib/cache.c | 9 ++++++++- |
|||
lib/mounts.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
|||
5 files changed, 71 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 74571570..8841f72f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -32,6 +32,7 @@
|
|||
- remove unused functions cache_dump_multi() and cache_dump_cache(). |
|||
- add a len field to struct autofs_point. |
|||
- make tree implementation data independent. |
|||
+- add mapent tree implementation.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index 34485859..ebc2007f 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -166,10 +166,14 @@ struct mapent {
|
|||
struct mapent_cache *mc; |
|||
struct map_source *source; |
|||
/* Need to know owner if we're a multi-mount */ |
|||
+ struct tree_node *mm_root;
|
|||
+ struct tree_node *mm_parent;
|
|||
+ struct tree_node node;
|
|||
struct mapent *multi; |
|||
/* Parent nesting point within multi-mount */ |
|||
struct mapent *parent; |
|||
char *key; |
|||
+ size_t len;
|
|||
char *mapent; |
|||
struct stack *stack; |
|||
time_t age; |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index 71d29566..fd7c6183 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -66,6 +66,13 @@ struct tree_node {
|
|||
#define MNT_LIST(n) (container_of(n, struct mnt_list, node)) |
|||
#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) |
|||
|
|||
+#define MAPENT(n) (container_of(n, struct mapent, node))
|
|||
+#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node)
|
|||
+#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root)
|
|||
+#define MAPENT_PARENT(p) ((struct tree_node *) ((struct mapent *) p)->mm_parent)
|
|||
+#define MAPENT_SET_ROOT(p, r) { (((struct mapent *) p)->mm_root = (struct tree_node *) r); }
|
|||
+#define MAPENT_SET_PARENT(p, n) { (((struct mapent *) p)->mm_parent = (struct tree_node *) n); }
|
|||
+
|
|||
typedef struct tree_node *(*tree_new_t) (void *ptr); |
|||
typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr); |
|||
typedef void (*tree_free_t) (struct tree_node *n); |
|||
@@ -161,6 +168,7 @@ unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
|
|||
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); |
|||
void mnts_put_expire_list(struct list_head *mnts); |
|||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); |
|||
+struct tree_node *tree_mapent_root(struct mapent *me);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index 629c4d0a..6dfaeff5 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -546,17 +546,21 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
struct mapent *me, *existing = NULL; |
|||
char *pkey, *pent; |
|||
u_int32_t hashval = hash(key, mc->size); |
|||
+ size_t len;
|
|||
|
|||
me = (struct mapent *) malloc(sizeof(struct mapent)); |
|||
if (!me) |
|||
return CHE_FAIL; |
|||
|
|||
- pkey = malloc(strlen(key) + 1);
|
|||
+ len = strlen(key);
|
|||
+
|
|||
+ pkey = malloc(len + 1);
|
|||
if (!pkey) { |
|||
free(me); |
|||
return CHE_FAIL; |
|||
} |
|||
me->key = strcpy(pkey, key); |
|||
+ me->len = len;
|
|||
|
|||
if (mapent) { |
|||
pent = malloc(strlen(mapent) + 1); |
|||
@@ -575,6 +579,9 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
me->status = 0; |
|||
me->mc = mc; |
|||
me->source = ms; |
|||
+ me->mm_root = NULL;
|
|||
+ me->mm_parent = NULL;
|
|||
+ INIT_TREE_NODE(&me->node);
|
|||
INIT_LIST_HEAD(&me->ino_index); |
|||
INIT_LIST_HEAD(&me->multi_list); |
|||
me->multi = NULL; |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index a6d1c5a7..40ebf9cf 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = {
|
|||
}; |
|||
static struct tree_ops *tree_mnt_ops = &mnt_ops; |
|||
|
|||
+static struct tree_node *tree_mapent_new(void *ptr);
|
|||
+static int tree_mapent_cmp(struct tree_node *n, void *ptr);
|
|||
+static void tree_mapent_free(struct tree_node *n);
|
|||
+
|
|||
+static struct tree_ops mapent_ops = {
|
|||
+ .new = tree_mapent_new,
|
|||
+ .cmp = tree_mapent_cmp,
|
|||
+ .free = tree_mapent_free,
|
|||
+};
|
|||
+static struct tree_ops *tree_mapent_ops = &mapent_ops;
|
|||
+
|
|||
unsigned int linux_version_code(void) |
|||
{ |
|||
struct utsname my_utsname; |
|||
@@ -1431,6 +1442,45 @@ void mnts_put_expire_list(struct list_head *mnts)
|
|||
mnts_hash_mutex_unlock(); |
|||
} |
|||
|
|||
+struct tree_node *tree_mapent_root(struct mapent *me)
|
|||
+{
|
|||
+ return tree_root(tree_mapent_ops, me);
|
|||
+}
|
|||
+
|
|||
+static struct tree_node *tree_mapent_new(void *ptr)
|
|||
+{
|
|||
+ struct tree_node *n = MAPENT_NODE(ptr);
|
|||
+
|
|||
+ n->ops = tree_mapent_ops;
|
|||
+ n->left = NULL;
|
|||
+ n->right = NULL;
|
|||
+
|
|||
+ return n;
|
|||
+}
|
|||
+
|
|||
+static int tree_mapent_cmp(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct mapent *n_me = MAPENT(n);
|
|||
+ size_t n_me_len = n_me->len;
|
|||
+ struct mapent *me = ptr;
|
|||
+ size_t me_len = me->len;
|
|||
+
|
|||
+ if (strncmp(me->key, n_me->key, n_me_len) == 0) {
|
|||
+ if (me_len < n_me_len)
|
|||
+ return -1;
|
|||
+ else if (me_len > n_me_len)
|
|||
+ return 1;
|
|||
+ }
|
|||
+ return strcmp(me->key, n_me->key);
|
|||
+}
|
|||
+
|
|||
+static void tree_mapent_free(struct tree_node *n)
|
|||
+{
|
|||
+ n->ops = NULL;
|
|||
+ n->left = NULL;
|
|||
+ n->right = NULL;
|
|||
+}
|
|||
+
|
|||
/* From glibc decode_name() */ |
|||
/* Since the values in a line are separated by spaces, a name cannot |
|||
* contain a space. Therefore some programs encode spaces in names |
@ -1,55 +0,0 @@ |
|||
autofs-5.1.7 - add missing desciption of null map option |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The description of how the -null master map option behaves is |
|||
mising from auto.master(5). |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
man/auto.master.5.in | 19 +++++++++++++++++++ |
|||
2 files changed, 20 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b29d2ed8..f5f0da76 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -76,6 +76,7 @@
|
|||
- eliminate redundant cache lookup in tree_mapent_add_node(). |
|||
- fix hosts map offset order. |
|||
- fix direct mount deadlock. |
|||
+- add missing description of null map option.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|||
index 72fbfd23..16717015 100644
|
|||
--- a/man/auto.master.5.in
|
|||
+++ b/man/auto.master.5.in
|
|||
@@ -265,6 +265,25 @@ accessing /net/myserver will mount exports from myserver on directories below
|
|||
NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev" options |
|||
unless overridden by explicitly specifying the "suid", "dev" options in the |
|||
master map entry. |
|||
+.SH BUILTIN MAP \-null
|
|||
+If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent
|
|||
+master map entry with the given path.
|
|||
+.P
|
|||
+It can only be used for paths that appear in the master map (or in direct mount maps).
|
|||
+.P
|
|||
+An indirect mount map top level mount point path can be nulled. If so no mounts from
|
|||
+the nulled mount are performed (essentially it isn't mounted).
|
|||
+.P
|
|||
+Direct mount map path entries can be nulled. Since they must be present at startup
|
|||
+they are (notionally) part of the master map.
|
|||
+.P
|
|||
+A nulled master map entry path will ignore a single subsequent matching entry. Any
|
|||
+matching entry following that will be treated as it normally would be. An example
|
|||
+use of this is allowing local master map entries to override remote ones.
|
|||
+.P
|
|||
+NOTE: If a duplicate master map entry path is seen (excluding paths of null entries)
|
|||
+it will be ignored and noted in the log, that is the first encountered master map
|
|||
+entry is used unless there is a corresponding null entry.
|
|||
.SH LDAP MAPS |
|||
If the map type \fBldap\fP is specified the mapname is of the form |
|||
\fB[//servername/]dn\fP, where the optional \fBservername\fP is |
@ -1,42 +0,0 @@ |
|||
autofs-5.1.7 - add missing free in handle_mounts() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: error[doubleFree]: Memory pointed to by 'root' is freed twice |
|||
|
|||
No it's not, but root isn't freed before the fatal call which crashes |
|||
automount so add a free() before the fatal() call. |
|||
|
|||
It appears Coverity doesn't recognise pthread_exit() as an exit condition. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9c3ede45..62a918a9 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -50,6 +50,7 @@
|
|||
- check for offset with no mount location. |
|||
- remove mounts_mutex. |
|||
- remove unused variable from get_exports(). |
|||
+- add missing free in handle_mounts().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 28c4d1ee..48472d5f 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -1922,6 +1922,8 @@ void *handle_mounts(void *arg)
|
|||
status = pthread_mutex_lock(&suc->mutex); |
|||
if (status) { |
|||
logerr("failed to lock startup condition mutex!"); |
|||
+ if (root)
|
|||
+ free(root);
|
|||
fatal(status); |
|||
} |
|||
|
@ -1,310 +0,0 @@ |
|||
autofs-5.1.7 - add mount and umount offsets functions |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add tree_mapent_mount_offsets() and tree_mapent_umount_offsets() to |
|||
the mapent tree handling implementation. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 |
|||
include/mounts.h | 2 |
|||
lib/mounts.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|||
3 files changed, 263 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0bd6f181..892f7581 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -39,6 +39,7 @@
|
|||
- fix mount_fullpath(). |
|||
- add tree_mapent_cleanup_offsets(). |
|||
- add set_offset_tree_catatonic(). |
|||
+- add mount and umount offsets functions.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index 5441ee0e..e56f80ba 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -172,6 +172,8 @@ struct tree_node *tree_mapent_root(struct mapent *me);
|
|||
int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); |
|||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); |
|||
void tree_mapent_cleanup_offsets(struct mapent *oe); |
|||
+int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
|
|||
+int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index f075a27e..f7c29475 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1692,6 +1692,266 @@ void tree_mapent_cleanup_offsets(struct mapent *oe)
|
|||
} |
|||
} |
|||
|
|||
+static int tree_mapent_rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
|
|||
+{
|
|||
+ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe));
|
|||
+ char *dir, *path;
|
|||
+ unsigned int split;
|
|||
+ int ret;
|
|||
+
|
|||
+ if (ap->type == LKP_DIRECT)
|
|||
+ return rmdir_path(ap, oe->key, mm_root->dev);
|
|||
+
|
|||
+ dir = strdup(oe->key);
|
|||
+
|
|||
+ if (ap->flags & MOUNT_FLAG_GHOST)
|
|||
+ split = ap->len + mm_root->len + 1;
|
|||
+ else
|
|||
+ split = ap->len;
|
|||
+
|
|||
+ dir[split] = '\0';
|
|||
+ path = &dir[split + 1];
|
|||
+
|
|||
+ if (chdir(dir) == -1) {
|
|||
+ error(ap->logopt, "failed to chdir to %s", dir);
|
|||
+ free(dir);
|
|||
+ return -1;
|
|||
+ }
|
|||
+
|
|||
+ ret = rmdir_path(ap, path, ap->dev);
|
|||
+
|
|||
+ free(dir);
|
|||
+
|
|||
+ if (chdir("/") == -1)
|
|||
+ error(ap->logopt, "failed to chdir to /");
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int tree_mapent_mount_offset(struct mapent *oe, void *ptr)
|
|||
+{
|
|||
+ struct traverse_subtree_context *ctxt = ptr;
|
|||
+ struct autofs_point *ap = ctxt->ap;
|
|||
+ int ret;
|
|||
+
|
|||
+ debug(ap->logopt, "mount offset %s", oe->key);
|
|||
+
|
|||
+ ret = mount_autofs_offset(ap, oe);
|
|||
+ if (ret < MOUNT_OFFSET_OK) {
|
|||
+ if (ret != MOUNT_OFFSET_IGNORE) {
|
|||
+ warn(ap->logopt, "failed to mount offset");
|
|||
+ return 0;
|
|||
+ } else {
|
|||
+ debug(ap->logopt,
|
|||
+ "ignoring \"nohide\" trigger %s", oe->key);
|
|||
+ /*
|
|||
+ * Ok, so we shouldn't modify the mapent but
|
|||
+ * mount requests are blocked at a point above
|
|||
+ * this and expire only uses the mapent key or
|
|||
+ * holds the cache write lock.
|
|||
+ */
|
|||
+ free(oe->mapent);
|
|||
+ oe->mapent = NULL;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ return 1;
|
|||
+}
|
|||
+
|
|||
+static int tree_mapent_umount_offset(struct mapent *oe, void *ptr)
|
|||
+{
|
|||
+ struct traverse_subtree_context *ctxt = ptr;
|
|||
+ struct autofs_point *ap = ctxt->ap;
|
|||
+ int ret = 1;
|
|||
+
|
|||
+ /*
|
|||
+ * Check for and umount subtree offsets resulting from
|
|||
+ * nonstrict mount fail.
|
|||
+ */
|
|||
+ ret = tree_mapent_umount_offsets(oe, ctxt->strict);
|
|||
+ if (!ret)
|
|||
+ return 0;
|
|||
+
|
|||
+ /*
|
|||
+ * If an offset that has an active mount has been removed
|
|||
+ * from the multi-mount we don't want to attempt to trigger
|
|||
+ * mounts for it. Obviously this is because it has been
|
|||
+ * removed, but less obvious is the potential strange
|
|||
+ * behaviour that can result if we do try and mount it
|
|||
+ * again after it's been expired. For example, if an NFS
|
|||
+ * file system is no longer exported and is later umounted
|
|||
+ * it can be mounted again without any error message but
|
|||
+ * shows as an empty directory. That's going to confuse
|
|||
+ * people for sure.
|
|||
+ *
|
|||
+ * If the mount cannot be umounted (the process is now
|
|||
+ * using a stale mount) the offset needs to be invalidated
|
|||
+ * so no further mounts will be attempted but the offset
|
|||
+ * cache entry must remain so expires can continue to
|
|||
+ * attempt to umount it. If the mount can be umounted and
|
|||
+ * the offset is removed, at least for NFS we will get
|
|||
+ * ESTALE errors when attempting list the directory.
|
|||
+ */
|
|||
+ if (oe->ioctlfd != -1 ||
|
|||
+ is_mounted(oe->key, MNTS_REAL)) {
|
|||
+ if (umount_ent(ap, oe->key) &&
|
|||
+ is_mounted(oe->key, MNTS_REAL)) {
|
|||
+ debug(ap->logopt,
|
|||
+ "offset %s has active mount, invalidate",
|
|||
+ oe->key);
|
|||
+ /*
|
|||
+ * Ok, so we shouldn't modify the mapent but
|
|||
+ * mount requests are blocked at a point above
|
|||
+ * this and expire only uses the mapent key or
|
|||
+ * holds the cache write lock.
|
|||
+ */
|
|||
+ if (oe->mapent) {
|
|||
+ free(oe->mapent);
|
|||
+ oe->mapent = NULL;
|
|||
+ }
|
|||
+ return 0;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ /* Don't bother if there's noting to umount. */
|
|||
+ if (!is_mounted(oe->key, MNTS_AUTOFS))
|
|||
+ goto done;
|
|||
+
|
|||
+ debug(ap->logopt, "umount offset %s", oe->key);
|
|||
+
|
|||
+ if (umount_autofs_offset(ap, oe)) {
|
|||
+ warn(ap->logopt, "failed to umount offset");
|
|||
+ ret = 0;
|
|||
+ } else {
|
|||
+ struct stat st;
|
|||
+ int ret;
|
|||
+
|
|||
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
|
|||
+ goto done;
|
|||
+
|
|||
+ /*
|
|||
+ * An error due to partial directory removal is
|
|||
+ * ok so only try and remount the offset if the
|
|||
+ * actual mount point still exists.
|
|||
+ */
|
|||
+ ret = tree_mapent_rmdir_path_offset(ap, oe);
|
|||
+ if (ret == -1 && !stat(oe->key, &st)) {
|
|||
+ ret = tree_mapent_mount_offset(oe, ctxt);
|
|||
+ /* But we did origianlly create this */
|
|||
+ oe->flags |= MOUNT_FLAG_DIR_CREATED;
|
|||
+ }
|
|||
+ }
|
|||
+done:
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct traverse_subtree_context *ctxt = ptr;
|
|||
+ struct mapent *oe = MAPENT(n);
|
|||
+ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe));
|
|||
+ struct autofs_point *ap = ctxt->ap;
|
|||
+ int ret;
|
|||
+
|
|||
+ if (!oe->mapent)
|
|||
+ return 1;
|
|||
+
|
|||
+ /* Stale offset, no longer present in the mapent */
|
|||
+ if (oe->age != mm_root->age) {
|
|||
+ /* Best effort */
|
|||
+ tree_mapent_umount_offset(oe, ctxt);
|
|||
+ return 1;
|
|||
+ }
|
|||
+
|
|||
+ ret = tree_mapent_mount_offset(oe, ctxt);
|
|||
+
|
|||
+ /*
|
|||
+ * If re-constructing a multi-mount it's necessary to walk
|
|||
+ * into nested mounts, unlike the usual "mount only what's
|
|||
+ * needed as you go" behavior.
|
|||
+ */
|
|||
+ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
|
|||
+ if (oe->ioctlfd != -1 ||
|
|||
+ is_mounted(oe->key, MNTS_REAL))
|
|||
+ /* Best effort */
|
|||
+ tree_mapent_mount_offsets(oe, !ctxt->strict);
|
|||
+ }
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict)
|
|||
+{
|
|||
+ struct tree_node *base = MAPENT_NODE(oe);
|
|||
+ struct traverse_subtree_context ctxt = {
|
|||
+ .ap = oe->mc->ap,
|
|||
+ .base = base,
|
|||
+ .strict = !nonstrict,
|
|||
+ };
|
|||
+
|
|||
+ return tree_mapent_traverse_subtree(base,
|
|||
+ tree_mapent_mount_offsets_work, &ctxt);
|
|||
+}
|
|||
+
|
|||
+static int tree_mapent_umount_offsets_work(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct mapent *oe = MAPENT(n);
|
|||
+
|
|||
+ return tree_mapent_umount_offset(oe, ptr);
|
|||
+}
|
|||
+
|
|||
+int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict)
|
|||
+{
|
|||
+ struct tree_node *base = MAPENT_NODE(oe);
|
|||
+ struct autofs_point *ap = oe->mc->ap;
|
|||
+ struct traverse_subtree_context ctxt = {
|
|||
+ .ap = ap,
|
|||
+ .base = base,
|
|||
+ .strict = !nonstrict,
|
|||
+ };
|
|||
+ int ret;
|
|||
+
|
|||
+ ret = tree_mapent_traverse_subtree(base,
|
|||
+ tree_mapent_umount_offsets_work, &ctxt);
|
|||
+ if (ret && tree_mapent_is_root(oe)) {
|
|||
+ char mp[PATH_MAX + 1];
|
|||
+
|
|||
+ /*
|
|||
+ * The map entry cache stores mapent keys. For indirect
|
|||
+ * mount maps they are single direcory components so when
|
|||
+ * one of these keys is the root of a multi-mount the mount
|
|||
+ * path must be constructed.
|
|||
+ */
|
|||
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) {
|
|||
+ error(ap->logopt, "mount path is too long");
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ /*
|
|||
+ * Special case.
|
|||
+ * If we can't umount the root container then we can't
|
|||
+ * delete the offsets from the cache and we need to put
|
|||
+ * the offset triggers back.
|
|||
+ */
|
|||
+ if (is_mounted(mp, MNTS_REAL)) {
|
|||
+ info(ap->logopt, "unmounting dir = %s", mp);
|
|||
+ if (umount_ent(ap, mp) &&
|
|||
+ is_mounted(mp, MNTS_REAL)) {
|
|||
+ if (!tree_mapent_mount_offsets(oe, 1))
|
|||
+ warn(ap->logopt,
|
|||
+ "failed to remount offset triggers");
|
|||
+ return 0;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
+ /* check for mounted mount entry and remove it if found */
|
|||
+ mnts_remove_mount(mp, MNTS_MOUNTED);
|
|||
+
|
|||
+ }
|
|||
+
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
/* From glibc decode_name() */ |
|||
/* Since the values in a line are separated by spaces, a name cannot |
|||
* contain a space. Therefore some programs encode spaces in names |
@ -1,50 +0,0 @@ |
|||
autofs-5.1.7 - add set_offset_tree_catatonic() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add tree mapent support function set_offset_tree_catatonic(). |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 15 +++++++++++++++ |
|||
2 files changed, 16 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 89d4cfa0..0bd6f181 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -38,6 +38,7 @@
|
|||
- add tree_mapent_traverse_subtree(). |
|||
- fix mount_fullpath(). |
|||
- add tree_mapent_cleanup_offsets(). |
|||
+- add set_offset_tree_catatonic().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index ba573b9a..f075a27e 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2578,6 +2578,21 @@ static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int i
|
|||
return 0; |
|||
} |
|||
|
|||
+static int set_offset_tree_catatonic_work(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct mapent *me = MAPENT(n);
|
|||
+ struct autofs_point *ap = me->mc->ap;
|
|||
+
|
|||
+ set_mount_catatonic(ap, me, me->ioctlfd);
|
|||
+
|
|||
+ return 1;
|
|||
+}
|
|||
+
|
|||
+static void set_offset_tree_catatonic(struct autofs_point *ap, struct mapent *me)
|
|||
+{
|
|||
+ tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL);
|
|||
+}
|
|||
+
|
|||
static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) |
|||
{ |
|||
if (!list_empty(&me->multi_list)) { |
@ -1,257 +0,0 @@ |
|||
autofs-5.1.7 - add some buffer length checks to master map parser |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add some checks for buffer overflow to the master map parser. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master_parse.y | 38 +++++++++++++++----------- |
|||
daemon/master_tok.l | 73 ++++++++++++++++++++++++++++++++++++++++++++----- |
|||
3 files changed, 88 insertions(+), 24 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index be0b9d85..ded0f00f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -85,6 +85,7 @@
|
|||
- fix incorrect print format specifiers in get_pkt(). |
|||
- add mapent path length check in handle_packet_expire_direct(). |
|||
- add copy length check in umount_autofs_indirect(). |
|||
+- add some buffer length checks to master map parser.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
|
|||
index 7480c36a..2d78f082 100644
|
|||
--- a/daemon/master_parse.y
|
|||
+++ b/daemon/master_parse.y
|
|||
@@ -29,6 +29,7 @@
|
|||
#include "master.h" |
|||
|
|||
#define MAX_ERR_LEN 512 |
|||
+#define STRTYPE_LEN 2048
|
|||
|
|||
extern struct master *master_list; |
|||
|
|||
@@ -79,6 +80,7 @@ static int local_argc;
|
|||
static unsigned int propagation; |
|||
|
|||
static char errstr[MAX_ERR_LEN]; |
|||
+static int errlen;
|
|||
|
|||
static unsigned int verbose; |
|||
static unsigned int debug; |
|||
@@ -521,10 +523,11 @@ dnattrs: DNATTR EQUAL DNNAME
|
|||
strcasecmp($1, "ou") && |
|||
strcasecmp($1, "automountMapName") && |
|||
strcasecmp($1, "nisMapName")) { |
|||
- strcpy(errstr, $1);
|
|||
- strcat(errstr, "=");
|
|||
- strcat(errstr, $3);
|
|||
- master_notify(errstr);
|
|||
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|||
+ if (errlen < MAX_ERR_LEN)
|
|||
+ master_notify(errstr);
|
|||
+ else
|
|||
+ master_notify("error string too long");
|
|||
YYABORT; |
|||
} |
|||
strcpy($$, $1); |
|||
@@ -537,10 +540,11 @@ dnattrs: DNATTR EQUAL DNNAME
|
|||
strcasecmp($1, "ou") && |
|||
strcasecmp($1, "automountMapName") && |
|||
strcasecmp($1, "nisMapName")) { |
|||
- strcpy(errstr, $1);
|
|||
- strcat(errstr, "=");
|
|||
- strcat(errstr, $3);
|
|||
- master_notify(errstr);
|
|||
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|||
+ if (errlen < MAX_ERR_LEN)
|
|||
+ master_notify(errstr);
|
|||
+ else
|
|||
+ master_notify("error string too long");
|
|||
YYABORT; |
|||
} |
|||
strcpy($$, $1); |
|||
@@ -565,10 +569,11 @@ dnattr: DNATTR EQUAL DNNAME
|
|||
{ |
|||
if (!strcasecmp($1, "automountMapName") || |
|||
!strcasecmp($1, "nisMapName")) { |
|||
- strcpy(errstr, $1);
|
|||
- strcat(errstr, "=");
|
|||
- strcat(errstr, $3);
|
|||
- master_notify(errstr);
|
|||
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|||
+ if (errlen < MAX_ERR_LEN)
|
|||
+ master_notify(errstr);
|
|||
+ else
|
|||
+ master_notify("error string too long");
|
|||
YYABORT; |
|||
} |
|||
strcpy($$, $1); |
|||
@@ -579,10 +584,11 @@ dnattr: DNATTR EQUAL DNNAME
|
|||
{ |
|||
if (!strcasecmp($1, "automountMapName") || |
|||
!strcasecmp($1, "nisMapName")) { |
|||
- strcpy(errstr, $1);
|
|||
- strcat(errstr, "=");
|
|||
- strcat(errstr, $3);
|
|||
- master_notify(errstr);
|
|||
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|||
+ if (errlen < MAX_ERR_LEN)
|
|||
+ master_notify(errstr);
|
|||
+ else
|
|||
+ master_notify("error string too long");
|
|||
YYABORT; |
|||
} |
|||
strcpy($$, $1); |
|||
diff --git a/daemon/master_tok.l b/daemon/master_tok.l
|
|||
index 87a6b958..e2d15bce 100644
|
|||
--- a/daemon/master_tok.l
|
|||
+++ b/daemon/master_tok.l
|
|||
@@ -23,6 +23,7 @@
|
|||
#endif /* ECHO */ |
|||
static void master_echo(void); /* forward definition */ |
|||
#define ECHO master_echo() |
|||
+static void master_error(char *s);
|
|||
|
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
@@ -80,6 +81,8 @@ char *bptr;
|
|||
char *optr = buff; |
|||
unsigned int tlen; |
|||
|
|||
+#define STRTYPE_LEN 2048
|
|||
+
|
|||
%} |
|||
|
|||
%option nounput |
|||
@@ -217,7 +220,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|||
bptr += tlen; |
|||
yyless(tlen); |
|||
} else { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (tlen <= STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("MULTITYPE: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return(MULTITYPE); |
|||
} |
|||
} |
|||
@@ -239,7 +248,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|||
bptr += tlen; |
|||
yyless(tlen); |
|||
} else { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (tlen <= STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("MAPTYPE: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return(MAPTYPE); |
|||
} |
|||
} |
|||
@@ -327,12 +342,24 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|||
{OPTWS}\\\n{OPTWS} {} |
|||
|
|||
{DNSERVERSTR} { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (master_leng < STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("DNSERVER: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return DNSERVER; |
|||
} |
|||
|
|||
{DNATTRSTR}/"=" { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (master_leng < STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("DNATTR: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return DNATTR; |
|||
} |
|||
|
|||
@@ -341,12 +368,24 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|||
} |
|||
|
|||
{DNNAMESTR1}/","{DNATTRSTR}"=" { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (master_leng < STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("DNNAME: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return DNNAME; |
|||
} |
|||
|
|||
{DNNAMESTR2} { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (master_leng < STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("DNNAME: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return DNNAME; |
|||
} |
|||
|
|||
@@ -357,7 +396,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|||
{WS}"=" | |
|||
"="{WS} { |
|||
BEGIN(INITIAL); |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (master_leng < STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("SPACE: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return SPACE; |
|||
} |
|||
|
|||
@@ -419,7 +464,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|||
} |
|||
|
|||
{OPTIONSTR} { |
|||
- strcpy(master_lval.strtype, master_text);
|
|||
+ if (master_leng < STRTYPE_LEN)
|
|||
+ strcpy(master_lval.strtype, master_text);
|
|||
+ else {
|
|||
+ master_error("OPTION: value too large, truncated");
|
|||
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|||
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|||
+ }
|
|||
return(OPTION); |
|||
} |
|||
|
|||
@@ -459,6 +510,12 @@ static void master_echo(void)
|
|||
return; |
|||
} |
|||
|
|||
+static void master_error(char *s)
|
|||
+{
|
|||
+ logmsg("%s");
|
|||
+ return;
|
|||
+}
|
|||
+
|
|||
#ifdef FLEX_SCANNER |
|||
|
|||
void master_set_scan_buffer(const char *buffer) |
@ -1,552 +0,0 @@ |
|||
autofs-5.1.7 - add some multi-mount macros |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add convienience macros IS_MM() to check is a mapent is part of a |
|||
multi-mount, IS_MM_ROOT() to check if a mapent is the root of a |
|||
multi-mount tree and MM_ROOT() to return the multi-mount root mapent. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 14 +++++++------- |
|||
daemon/direct.c | 6 +++--- |
|||
daemon/lookup.c | 10 +++++----- |
|||
include/automount.h | 5 +++++ |
|||
lib/cache.c | 30 +++++++++++++++--------------- |
|||
lib/mounts.c | 14 +++++++------- |
|||
modules/lookup_file.c | 4 ++-- |
|||
modules/lookup_hosts.c | 4 ++-- |
|||
modules/lookup_ldap.c | 4 ++-- |
|||
modules/lookup_nisplus.c | 4 ++-- |
|||
modules/lookup_program.c | 4 ++-- |
|||
modules/lookup_sss.c | 4 ++-- |
|||
modules/lookup_yp.c | 4 ++-- |
|||
modules/parse_sun.c | 12 ++++++------ |
|||
15 files changed, 63 insertions(+), 57 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 1bf20699..3ba748d7 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -28,6 +28,7 @@
|
|||
- rename path to m_offset in update_offset_entry(). |
|||
- don't pass root to do_mount_autofs_offset(). |
|||
- rename tree implementation functions. |
|||
+- add some multi-mount macros.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 62530b6b..f4608fc9 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -545,27 +545,27 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
|
|||
if (me) { |
|||
mc = me->mc; |
|||
- is_mm_root = (me->multi == me);
|
|||
+ is_mm_root = IS_MM_ROOT(me);
|
|||
} |
|||
|
|||
left = 0; |
|||
|
|||
- if (me && me->multi) {
|
|||
+ if (me && IS_MM(me)) {
|
|||
char root[PATH_MAX + 1]; |
|||
char key[PATH_MAX + 1]; |
|||
struct mapent *tmp; |
|||
int status; |
|||
char *base; |
|||
|
|||
- if (!strchr(me->multi->key, '/'))
|
|||
+ if (!strchr(MM_ROOT(me)->key, '/'))
|
|||
/* Indirect multi-mount root */ |
|||
/* sprintf okay - if it's mounted, it's |
|||
* PATH_MAX or less bytes */ |
|||
- sprintf(root, "%s/%s", ap->path, me->multi->key);
|
|||
+ sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key);
|
|||
else |
|||
- strcpy(root, me->multi->key);
|
|||
+ strcpy(root, MM_ROOT(me)->key);
|
|||
|
|||
- if (is_mm_root)
|
|||
+ if (IS_MM_ROOT(me))
|
|||
base = NULL; |
|||
else |
|||
base = me->key + strlen(root); |
|||
@@ -588,7 +588,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
return 0; |
|||
} |
|||
|
|||
- if (!left && is_mm_root) {
|
|||
+ if (!left && IS_MM_ROOT(me)) {
|
|||
status = cache_delete_offset_list(mc, me->key); |
|||
if (status != CHE_OK) { |
|||
warn(ap->logopt, "couldn't delete offset list"); |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 5c1146a7..3f4f5704 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -686,7 +686,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|||
* a mount that has been automatically mounted by |
|||
* the kernel NFS client. |
|||
*/ |
|||
- if (me->multi != me &&
|
|||
+ if (!IS_MM_ROOT(me) &&
|
|||
is_mounted(me->key, MNTS_REAL)) |
|||
return MOUNT_OFFSET_IGNORE; |
|||
|
|||
@@ -1220,11 +1220,11 @@ static void *do_mount_direct(void *arg)
|
|||
* for direct mount multi-mounts with no real mount at |
|||
* their base so they will be expired. |
|||
*/ |
|||
- if (close_fd && me == me->multi)
|
|||
+ if (close_fd && IS_MM_ROOT(me))
|
|||
close_fd = 0; |
|||
if (!close_fd) |
|||
me->ioctlfd = mt.ioctlfd; |
|||
- if (me->multi && me->multi != me)
|
|||
+ if (IS_MM(me) && !IS_MM_ROOT(me))
|
|||
flags |= MNTS_OFFSET; |
|||
} |
|||
ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); |
|||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|||
index 2fea0c0b..8c9a82b5 100644
|
|||
--- a/daemon/lookup.c
|
|||
+++ b/daemon/lookup.c
|
|||
@@ -748,7 +748,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root)
|
|||
goto next; |
|||
|
|||
/* It's a busy multi-mount - leave till next time */ |
|||
- if (list_empty(&me->multi_list))
|
|||
+ if (IS_MM(me))
|
|||
error(ap->logopt, |
|||
"invalid key %s", me->key); |
|||
goto next; |
|||
@@ -838,12 +838,12 @@ static int lookup_amd_instance(struct autofs_point *ap,
|
|||
char *m_key; |
|||
|
|||
me = cache_lookup_distinct(map->mc, name); |
|||
- if (!me || !me->multi) {
|
|||
+ if (!me || !IS_MM(me)) {
|
|||
error(ap->logopt, "expected multi mount entry not found"); |
|||
return NSS_STATUS_UNKNOWN; |
|||
} |
|||
|
|||
- m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 2);
|
|||
+ m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2);
|
|||
if (!m_key) { |
|||
error(ap->logopt, |
|||
"failed to allocate storage for search key"); |
|||
@@ -852,7 +852,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
|
|||
|
|||
strcpy(m_key, ap->path); |
|||
strcat(m_key, "/"); |
|||
- strcat(m_key, me->multi->key);
|
|||
+ strcat(m_key, MM_ROOT(me)->key);
|
|||
|
|||
mnt = mnts_find_amdmount(m_key); |
|||
free(m_key); |
|||
@@ -1355,7 +1355,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
* created on demand and managed by expire and don't |
|||
* prune the multi-map owner map entry. |
|||
*/ |
|||
- if (*me->key == '/' || me->multi == me) {
|
|||
+ if (*me->key == '/' || IS_MM_ROOT(me)) {
|
|||
me = cache_enumerate(mc, me); |
|||
continue; |
|||
} |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index fa6f5d63..e917515b 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -183,6 +183,11 @@ struct mapent {
|
|||
ino_t ino; |
|||
}; |
|||
|
|||
+#define IS_MM(me) (me->multi)
|
|||
+#define IS_MM_ROOT(me) (me->multi == me)
|
|||
+#define MM_ROOT(me) (me->multi)
|
|||
+#define MM_PARENT(me) (me->parent)
|
|||
+
|
|||
void cache_lock_cleanup(void *arg); |
|||
void cache_readlock(struct mapent_cache *mc); |
|||
void cache_writelock(struct mapent_cache *mc); |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index a90bbb1d..1d9f5cc7 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -374,7 +374,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc)
|
|||
|
|||
while (me) { |
|||
/* Multi mount entries are not primary */ |
|||
- if (me->multi && me->multi != me) {
|
|||
+ if (IS_MM(me) && !IS_MM_ROOT(me)) {
|
|||
me = me->next; |
|||
continue; |
|||
} |
|||
@@ -397,7 +397,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me)
|
|||
this = me->next; |
|||
while (this) { |
|||
/* Multi mount entries are not primary */ |
|||
- if (this->multi && this->multi != this) {
|
|||
+ if (IS_MM(this) && !IS_MM_ROOT(this)) {
|
|||
this = this->next; |
|||
continue; |
|||
} |
|||
@@ -413,7 +413,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me)
|
|||
|
|||
while (this) { |
|||
/* Multi mount entries are not primary */ |
|||
- if (this->multi && this->multi != this) {
|
|||
+ if (IS_MM(this) && !IS_MM_ROOT(this)) {
|
|||
this = this->next; |
|||
continue; |
|||
} |
|||
@@ -435,7 +435,7 @@ struct mapent *cache_lookup_key_next(struct mapent *me)
|
|||
next = me->next; |
|||
while (next) { |
|||
/* Multi mount entries are not primary */ |
|||
- if (me->multi && me->multi != me)
|
|||
+ if (IS_MM(me) && !IS_MM_ROOT(me))
|
|||
continue; |
|||
if (!strcmp(me->key, next->key)) |
|||
return next; |
|||
@@ -706,7 +706,7 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k
|
|||
me = cache_lookup_distinct(mc, key); |
|||
if (me) { |
|||
cache_add_ordered_offset(me, &owner->multi_list); |
|||
- me->multi = owner;
|
|||
+ MM_ROOT(me) = owner;
|
|||
goto done; |
|||
} |
|||
ret = CHE_FAIL; |
|||
@@ -814,14 +814,14 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
|
|||
this = cache_lookup_distinct(mc, offset); |
|||
if (!this) |
|||
return 0; |
|||
- if (!this->multi)
|
|||
+ if (!IS_MM(this))
|
|||
return 0; |
|||
|
|||
parent = get_offset_parent(mc, offset); |
|||
if (parent) |
|||
this->parent = parent; |
|||
else |
|||
- this->parent = this->multi;
|
|||
+ this->parent = MM_ROOT(this);
|
|||
|
|||
return 1; |
|||
} |
|||
@@ -879,7 +879,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
|
|||
return CHE_FAIL; |
|||
|
|||
if (strcmp(key, me->key) == 0) { |
|||
- if (me->multi && me->multi == me)
|
|||
+ if (IS_MM(me) && IS_MM_ROOT(me))
|
|||
return CHE_FAIL; |
|||
mc->hash[hashval] = me->next; |
|||
goto delete; |
|||
@@ -889,7 +889,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
|
|||
pred = me; |
|||
me = me->next; |
|||
if (strcmp(key, me->key) == 0) { |
|||
- if (me->multi && me->multi == me)
|
|||
+ if (IS_MM(me) && IS_MM_ROOT(me))
|
|||
return CHE_FAIL; |
|||
pred->next = me->next; |
|||
goto delete; |
|||
@@ -927,7 +927,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
|
|||
me = me->next; |
|||
if (strcmp(key, me->key) == 0) { |
|||
struct stack *s = me->stack; |
|||
- if (me->multi && !list_empty(&me->multi_list)) {
|
|||
+ if (IS_MM(me)) {
|
|||
ret = CHE_FAIL; |
|||
goto done; |
|||
} |
|||
@@ -956,7 +956,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
|
|||
|
|||
if (strcmp(key, me->key) == 0) { |
|||
struct stack *s = me->stack; |
|||
- if (me->multi && !list_empty(&me->multi_list)) {
|
|||
+ if (IS_MM(me)) {
|
|||
ret = CHE_FAIL; |
|||
goto done; |
|||
} |
|||
@@ -995,7 +995,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
|
|||
return CHE_FAIL; |
|||
|
|||
/* Not offset list owner */ |
|||
- if (me->multi != me)
|
|||
+ if (!IS_MM_ROOT(me))
|
|||
return CHE_FAIL; |
|||
|
|||
head = &me->multi_list; |
|||
@@ -1016,13 +1016,13 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
|
|||
this = list_entry(next, struct mapent, multi_list); |
|||
next = next->next; |
|||
list_del_init(&this->multi_list); |
|||
- this->multi = NULL;
|
|||
+ MM_ROOT(this) = NULL;
|
|||
debug(logopt, "deleting offset key %s", this->key); |
|||
status = cache_delete(mc, this->key); |
|||
if (status == CHE_FAIL) { |
|||
warn(logopt, |
|||
"failed to delete offset %s", this->key); |
|||
- this->multi = me;
|
|||
+ MM_ROOT(this) = me;
|
|||
/* TODO: add list back in */ |
|||
remain++; |
|||
} |
|||
@@ -1030,7 +1030,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
|
|||
|
|||
if (!remain) { |
|||
list_del_init(&me->multi_list); |
|||
- me->multi = NULL;
|
|||
+ MM_ROOT(me) = NULL;
|
|||
} |
|||
|
|||
if (remain) |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index f5b905a6..f6f20fc0 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2163,7 +2163,7 @@ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
|
|||
} else { |
|||
me->flags &= ~MOUNT_FLAG_DIR_CREATED; |
|||
if (type == t_offset) { |
|||
- if (!is_mounted(me->parent->key, MNTS_REAL))
|
|||
+ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
|
|||
me->flags |= MOUNT_FLAG_DIR_CREATED; |
|||
} |
|||
} |
|||
@@ -2310,7 +2310,7 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
|
|||
goto next; |
|||
|
|||
/* Only need to set offset mounts catatonic */ |
|||
- if (me->multi && me->multi == me)
|
|||
+ if (IS_MM(me) && IS_MM_ROOT(me))
|
|||
set_multi_mount_tree_catatonic(ap, me); |
|||
next: |
|||
me = cache_enumerate(mc, me); |
|||
@@ -2330,7 +2330,7 @@ next:
|
|||
void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) |
|||
{ |
|||
/* Set offset mounts catatonic for this mapent */ |
|||
- if (me->multi && me->multi == me)
|
|||
+ if (IS_MM(me) && IS_MM_ROOT(me))
|
|||
set_multi_mount_tree_catatonic(ap, me); |
|||
set_mount_catatonic(ap, me, me->ioctlfd); |
|||
} |
|||
@@ -2490,12 +2490,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
|
|||
int ret; |
|||
|
|||
if (ap->type == LKP_DIRECT) |
|||
- return rmdir_path(ap, oe->key, oe->multi->dev);
|
|||
+ return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev);
|
|||
|
|||
dir = strdup(oe->key); |
|||
|
|||
if (ap->flags & MOUNT_FLAG_GHOST) |
|||
- split = strlen(ap->path) + strlen(oe->multi->key) + 1;
|
|||
+ split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1;
|
|||
else |
|||
split = strlen(ap->path); |
|||
|
|||
@@ -2690,7 +2690,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
oe = cache_lookup_distinct(me->mc, key); |
|||
if (!oe || !oe->mapent) |
|||
goto cont; |
|||
- if (oe->age != me->multi->age) {
|
|||
+ if (oe->age != MM_ROOT(me)->age) {
|
|||
/* Best effort */ |
|||
do_umount_offset(ap, oe, root, start); |
|||
goto cont; |
|||
@@ -2724,7 +2724,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
|
|||
left = do_umount_multi_triggers(ap, me, root, start, base); |
|||
|
|||
- if (!left && me->multi == me) {
|
|||
+ if (!left && IS_MM_ROOT(me)) {
|
|||
/* |
|||
* Special case. |
|||
* If we can't umount the root container then we can't |
|||
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
|||
index f46a04f0..6afc5587 100644
|
|||
--- a/modules/lookup_file.c
|
|||
+++ b/modules/lookup_file.c
|
|||
@@ -1199,8 +1199,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
|
|||
cache_readlock(mc); |
|||
me = cache_lookup_distinct(mc, key); |
|||
- if (me && me->multi)
|
|||
- lkp_key = strdup(me->multi->key);
|
|||
+ if (me && IS_MM(me))
|
|||
+ lkp_key = strdup(MM_ROOT(me)->key);
|
|||
else if (!ap->pref) |
|||
lkp_key = strdup(key); |
|||
else { |
|||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|||
index c1ebb7f6..7e101ddb 100644
|
|||
--- a/modules/lookup_hosts.c
|
|||
+++ b/modules/lookup_hosts.c
|
|||
@@ -177,7 +177,7 @@ static void update_hosts_mounts(struct autofs_point *ap,
|
|||
me = cache_lookup_first(mc); |
|||
while (me) { |
|||
/* Hosts map entry not yet expanded or already expired */ |
|||
- if (!me->multi)
|
|||
+ if (!IS_MM(me))
|
|||
goto next; |
|||
|
|||
debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key); |
|||
@@ -200,7 +200,7 @@ next:
|
|||
* Hosts map entry not yet expanded, already expired |
|||
* or not the base of the tree |
|||
*/ |
|||
- if (!me->multi || me->multi != me)
|
|||
+ if (!IS_MM(me) || !IS_MM_ROOT(me))
|
|||
goto cont; |
|||
|
|||
debug(ap->logopt, MODPREFIX |
|||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|||
index 3624dd86..3e43fc01 100644
|
|||
--- a/modules/lookup_ldap.c
|
|||
+++ b/modules/lookup_ldap.c
|
|||
@@ -3700,8 +3700,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
if (ap->type == LKP_INDIRECT && *key != '/') { |
|||
cache_readlock(mc); |
|||
me = cache_lookup_distinct(mc, key); |
|||
- if (me && me->multi)
|
|||
- lkp_key = strdup(me->multi->key);
|
|||
+ if (me && IS_MM(me))
|
|||
+ lkp_key = strdup(MM_ROOT(me)->key);
|
|||
else if (!ap->pref) |
|||
lkp_key = strdup(key); |
|||
else { |
|||
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
|
|||
index cbd03cdb..6e9a85d1 100644
|
|||
--- a/modules/lookup_nisplus.c
|
|||
+++ b/modules/lookup_nisplus.c
|
|||
@@ -722,8 +722,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
if (ap->type == LKP_INDIRECT && *key != '/') { |
|||
cache_readlock(mc); |
|||
me = cache_lookup_distinct(mc, key); |
|||
- if (me && me->multi)
|
|||
- lkp_key = strdup(me->multi->key);
|
|||
+ if (me && IS_MM(me))
|
|||
+ lkp_key = strdup(MM_ROOT(me)->key);
|
|||
else if (!ap->pref) |
|||
lkp_key = strdup(key); |
|||
else { |
|||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
|||
index ca209488..70f27545 100644
|
|||
--- a/modules/lookup_program.c
|
|||
+++ b/modules/lookup_program.c
|
|||
@@ -646,7 +646,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
name_len, ent, ctxt->parse->context); |
|||
goto out_free; |
|||
} else { |
|||
- if (me->multi && me->multi != me) {
|
|||
+ if (IS_MM(me) && !IS_MM_ROOT(me)) {
|
|||
cache_unlock(mc); |
|||
warn(ap->logopt, MODPREFIX |
|||
"unexpected lookup for active multi-mount" |
|||
@@ -657,7 +657,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
cache_writelock(mc); |
|||
me = cache_lookup_distinct(mc, name); |
|||
if (me) { |
|||
- if (me->multi)
|
|||
+ if (IS_MM(me))
|
|||
cache_delete_offset_list(mc, name); |
|||
cache_delete(mc, name); |
|||
} |
|||
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
|
|||
index ccd605af..ad834626 100644
|
|||
--- a/modules/lookup_sss.c
|
|||
+++ b/modules/lookup_sss.c
|
|||
@@ -1055,8 +1055,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
|
|||
cache_readlock(mc); |
|||
me = cache_lookup_distinct(mc, key); |
|||
- if (me && me->multi)
|
|||
- lkp_key = strdup(me->multi->key);
|
|||
+ if (me && IS_MM(me))
|
|||
+ lkp_key = strdup(MM_ROOT(me)->key);
|
|||
else |
|||
lkp_key = strdup(key); |
|||
cache_unlock(mc); |
|||
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
|
|||
index 38f75497..8bccb72f 100644
|
|||
--- a/modules/lookup_yp.c
|
|||
+++ b/modules/lookup_yp.c
|
|||
@@ -826,8 +826,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
if (ap->type == LKP_INDIRECT && *key != '/') { |
|||
cache_readlock(mc); |
|||
me = cache_lookup_distinct(mc, key); |
|||
- if (me && me->multi)
|
|||
- lkp_key = strdup(me->multi->key);
|
|||
+ if (me && IS_MM(me))
|
|||
+ lkp_key = strdup(MM_ROOT(me)->key);
|
|||
else if (!ap->pref) |
|||
lkp_key = strdup(key); |
|||
else { |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 34d4441e..b11c6693 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1148,7 +1148,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
|
|||
rv = 0; |
|||
|
|||
- mm_key = me->multi->key;
|
|||
+ mm_key = MM_ROOT(me)->key;
|
|||
|
|||
if (*mm_key == '/') { |
|||
mm_root = mm_key; |
|||
@@ -1162,7 +1162,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
} |
|||
mm_root_len = strlen(mm_root); |
|||
|
|||
- if (me == me->multi) {
|
|||
+ if (IS_MM_ROOT(me)) {
|
|||
char key[PATH_MAX + 1]; |
|||
|
|||
if (mm_root_len + 1 > PATH_MAX) { |
|||
@@ -1179,7 +1179,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
|
|||
/* Mount root offset if it exists */ |
|||
ro = cache_lookup_distinct(me->mc, key); |
|||
- if (ro && ro->age == me->multi->age) {
|
|||
+ if (ro && ro->age == MM_ROOT(me)->age) {
|
|||
char *myoptions, *ro_loc; |
|||
int namelen = name ? strlen(name) : 0; |
|||
int ro_len; |
|||
@@ -1350,7 +1350,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
|||
if (*name == '/') { |
|||
cache_readlock(mc); |
|||
me = cache_lookup_distinct(mc, name); |
|||
- if (me && me->multi && me->multi != me) {
|
|||
+ if (me && IS_MM(me) && !IS_MM_ROOT(me)) {
|
|||
cache_unlock(mc); |
|||
mapent_len = strlen(mapent) + 1; |
|||
pmapent = malloc(mapent_len + 1); |
|||
@@ -1505,7 +1505,7 @@ dont_expand:
|
|||
} |
|||
|
|||
/* So we know we're the multi-mount root */ |
|||
- if (!me->multi)
|
|||
+ if (!IS_MM(me))
|
|||
me->multi = me; |
|||
else { |
|||
/* |
|||
@@ -1630,7 +1630,7 @@ dont_expand:
|
|||
*/ |
|||
cache_readlock(mc); |
|||
if (*name == '/' && |
|||
- (me = cache_lookup_distinct(mc, name)) && me->multi) {
|
|||
+ (me = cache_lookup_distinct(mc, name)) && IS_MM(me)) {
|
|||
cache_unlock(mc); |
|||
loc = strdup(p); |
|||
if (!loc) { |
@ -1,133 +0,0 @@ |
|||
autofs-5.1.7 - add tree_mapent_add_node() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add function tree_mapent_add_node() to the mapent tree handling |
|||
implementation. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/automount.h | 1 + |
|||
include/mounts.h | 1 + |
|||
lib/cache.c | 5 ++--- |
|||
lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ |
|||
5 files changed, 52 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 8841f72f..85730eda 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -33,6 +33,7 @@
|
|||
- add a len field to struct autofs_point. |
|||
- make tree implementation data independent. |
|||
- add mapent tree implementation. |
|||
+- add tree_mapent_add_node().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index ebc2007f..f6023e27 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -216,6 +216,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); |
|||
int cache_lookup_negative(struct mapent *me, const char *key); |
|||
void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); |
|||
+struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key);
|
|||
int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); |
|||
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); |
|||
int cache_delete(struct mapent_cache *mc, const char *key); |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index fd7c6183..a0e60e24 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -169,6 +169,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
|
|||
void mnts_put_expire_list(struct list_head *mnts); |
|||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); |
|||
struct tree_node *tree_mapent_root(struct mapent *me); |
|||
+int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index 6dfaeff5..7c409a56 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -749,8 +749,7 @@ void cache_update_negative(struct mapent_cache *mc,
|
|||
} |
|||
|
|||
|
|||
-static struct mapent *get_offset_parent(struct mapent_cache *mc,
|
|||
- const char *key)
|
|||
+struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key)
|
|||
{ |
|||
struct mapent *me; |
|||
char *parent, *tail; |
|||
@@ -796,7 +795,7 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
|
|||
if (!IS_MM(this)) |
|||
return 0; |
|||
|
|||
- parent = get_offset_parent(mc, offset);
|
|||
+ parent = cache_get_offset_parent(mc, offset);
|
|||
if (parent) |
|||
this->parent = parent; |
|||
else |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 40ebf9cf..a0bf3d52 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1481,6 +1481,53 @@ static void tree_mapent_free(struct tree_node *n)
|
|||
n->right = NULL; |
|||
} |
|||
|
|||
+int tree_mapent_add_node(struct mapent_cache *mc,
|
|||
+ const char *root, const char *key)
|
|||
+{
|
|||
+ unsigned int logopt = mc->ap->logopt;
|
|||
+ struct tree_node *tree, *n;
|
|||
+ struct mapent *base;
|
|||
+ struct mapent *parent;
|
|||
+ struct mapent *me;
|
|||
+
|
|||
+ base = cache_lookup_distinct(mc, root);
|
|||
+ if (!base) {
|
|||
+ error(logopt,
|
|||
+ "failed to find multi-mount root for key %s", key);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ if (MAPENT_ROOT(base) != MAPENT_NODE(base)) {
|
|||
+ error(logopt,
|
|||
+ "failed to find multi-mount root of offset tree",
|
|||
+ key);
|
|||
+ return 0;
|
|||
+ }
|
|||
+ tree = MAPENT_ROOT(base);
|
|||
+
|
|||
+ me = cache_lookup_distinct(mc, key);
|
|||
+ if (!me) {
|
|||
+ error(logopt,
|
|||
+ "failed to find key %s of multi-mount", key);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ n = tree_add_node(tree, me);
|
|||
+ if (!n)
|
|||
+ return 0;
|
|||
+
|
|||
+ MAPENT_SET_ROOT(me, tree)
|
|||
+
|
|||
+ /* Set the subtree parent */
|
|||
+ parent = cache_get_offset_parent(mc, key);
|
|||
+ if (!parent)
|
|||
+ MAPENT_SET_PARENT(me, tree)
|
|||
+ else
|
|||
+ MAPENT_SET_PARENT(me, MAPENT_NODE(parent))
|
|||
+
|
|||
+ return 1;
|
|||
+}
|
|||
+
|
|||
/* From glibc decode_name() */ |
|||
/* Since the values in a line are separated by spaces, a name cannot |
|||
* contain a space. Therefore some programs encode spaces in names |
@ -1,94 +0,0 @@ |
|||
autofs-5.1.7 - add tree_mapent_cleanup_offsets() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add function tree_mapent_cleanup_offsets() to the mapent tree handling |
|||
implementation. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/mounts.h | 1 + |
|||
lib/mounts.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ |
|||
3 files changed, 47 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index e2fd532c..89d4cfa0 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -37,6 +37,7 @@
|
|||
- add tree_mapent_delete_offsets(). |
|||
- add tree_mapent_traverse_subtree(). |
|||
- fix mount_fullpath(). |
|||
+- add tree_mapent_cleanup_offsets().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index b5a1193b..5441ee0e 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -171,6 +171,7 @@ void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned
|
|||
struct tree_node *tree_mapent_root(struct mapent *me); |
|||
int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); |
|||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); |
|||
+void tree_mapent_cleanup_offsets(struct mapent *oe);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 497c28c9..ba573b9a 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1647,6 +1647,51 @@ int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key)
|
|||
return 1; |
|||
} |
|||
|
|||
+static void tree_mapent_umount_mount(struct autofs_point *ap, const char *mp)
|
|||
+{
|
|||
+ if (is_mounted(mp, MNTS_ALL)) {
|
|||
+ if (umount(mp)) {
|
|||
+ error(ap->logopt, "error recovering from mount fail");
|
|||
+ error(ap->logopt, "cannot umount %s", mp);
|
|||
+ }
|
|||
+ }
|
|||
+}
|
|||
+
|
|||
+static int tree_mapent_cleanup_offsets_work(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct mapent *oe = MAPENT(n);
|
|||
+ struct traverse_subtree_context *ctxt = ptr;
|
|||
+
|
|||
+ tree_mapent_umount_mount(ctxt->ap, oe->key);
|
|||
+
|
|||
+ return 1;
|
|||
+}
|
|||
+
|
|||
+void tree_mapent_cleanup_offsets(struct mapent *oe)
|
|||
+{
|
|||
+ struct tree_node *base = MAPENT_NODE(oe);
|
|||
+ struct traverse_subtree_context ctxt = {
|
|||
+ .ap = oe->mc->ap,
|
|||
+ .base = base,
|
|||
+ .strict = 0,
|
|||
+ };
|
|||
+ struct autofs_point *ap = oe->mc->ap;
|
|||
+
|
|||
+ tree_mapent_traverse_subtree(base, tree_mapent_cleanup_offsets_work, &ctxt);
|
|||
+
|
|||
+ /* Cleanup base mount after offsets have been cleaned up */
|
|||
+ if (*oe->key == '/')
|
|||
+ tree_mapent_umount_mount(ap, oe->key);
|
|||
+ else {
|
|||
+ char mp[PATH_MAX + 1];
|
|||
+
|
|||
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key))
|
|||
+ error(ap->logopt, "mount path is too long");
|
|||
+ else
|
|||
+ tree_mapent_umount_mount(ap, mp);
|
|||
+ }
|
|||
+}
|
|||
+
|
|||
/* From glibc decode_name() */ |
|||
/* Since the values in a line are separated by spaces, a name cannot |
|||
* contain a space. Therefore some programs encode spaces in names |
@ -1,119 +0,0 @@ |
|||
autofs-5.1.7 - add tree_mapent_delete_offsets() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add function tree_mapent_delete_offsets() to the mapent tree handling |
|||
implementation. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/mounts.h | 1 + |
|||
lib/mounts.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|||
3 files changed, 72 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 85730eda..488b4996 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -34,6 +34,7 @@
|
|||
- make tree implementation data independent. |
|||
- add mapent tree implementation. |
|||
- add tree_mapent_add_node(). |
|||
+- add tree_mapent_delete_offsets().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index a0e60e24..b5a1193b 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -170,6 +170,7 @@ void mnts_put_expire_list(struct list_head *mnts);
|
|||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); |
|||
struct tree_node *tree_mapent_root(struct mapent *me); |
|||
int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); |
|||
+int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index a0bf3d52..eb700c79 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1528,6 +1528,76 @@ int tree_mapent_add_node(struct mapent_cache *mc,
|
|||
return 1; |
|||
} |
|||
|
|||
+static int tree_mapent_delete_offset_tree(struct tree_node *root)
|
|||
+{
|
|||
+ struct mapent *me = MAPENT(root);
|
|||
+ unsigned int logopt = me->mc->ap->logopt;
|
|||
+ int ret = CHE_OK;
|
|||
+
|
|||
+ if (root->left) {
|
|||
+ ret = tree_mapent_delete_offset_tree(root->left);
|
|||
+ if (!ret)
|
|||
+ return 0;
|
|||
+ root->left = NULL;
|
|||
+ }
|
|||
+ if (root->right) {
|
|||
+ ret = tree_mapent_delete_offset_tree(root->right);
|
|||
+ if (!ret)
|
|||
+ return 0;
|
|||
+ root->right = NULL;
|
|||
+ }
|
|||
+
|
|||
+ /* Keep the owner of the multi-mount offset tree and clear
|
|||
+ * the root and parent when done.
|
|||
+ */
|
|||
+ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) {
|
|||
+ struct tree_node *root = MAPENT_ROOT(me);
|
|||
+
|
|||
+ debug(logopt, "deleting offset key %s", me->key);
|
|||
+
|
|||
+ /* cache_delete won't delete an active offset */
|
|||
+ MAPENT_SET_ROOT(me, NULL);
|
|||
+ ret = cache_delete(me->mc, me->key);
|
|||
+ if (ret != CHE_OK) {
|
|||
+ MAPENT_SET_ROOT(me, root);
|
|||
+ warn(logopt, "failed to delete offset %s", me->key);
|
|||
+ }
|
|||
+ } else {
|
|||
+ MAPENT_SET_ROOT(me, NULL);
|
|||
+ MAPENT_SET_PARENT(me, NULL);
|
|||
+ }
|
|||
+
|
|||
+ return ret == CHE_OK ? 1 : 0;
|
|||
+}
|
|||
+
|
|||
+int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key)
|
|||
+{
|
|||
+ unsigned int logopt = mc->ap->logopt;
|
|||
+ struct mapent *me;
|
|||
+
|
|||
+ me = cache_lookup_distinct(mc, key);
|
|||
+ if (!me) {
|
|||
+ error(logopt,
|
|||
+ "failed to find multi-mount root for key %s", key);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ /* Not offset list owner */
|
|||
+ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) {
|
|||
+ error(logopt,
|
|||
+ "mapent for key %s is not multi-mount owner", key);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ if (!tree_mapent_delete_offset_tree(MAPENT_ROOT(me))) {
|
|||
+ error(logopt,
|
|||
+ "could not delete map entry offsets for key %s", key);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ return 1;
|
|||
+}
|
|||
+
|
|||
/* From glibc decode_name() */ |
|||
/* Since the values in a line are separated by spaces, a name cannot |
|||
* contain a space. Therefore some programs encode spaces in names |
@ -1,83 +0,0 @@ |
|||
autofs-5.1.7 - add tree_mapent_traverse_subtree() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add function tree_mapent_traverse_subtree() that enumerates offsets from |
|||
a given base node bounded by subtree nesting points. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ |
|||
2 files changed, 48 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 488b4996..390028ac 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -35,6 +35,7 @@
|
|||
- add mapent tree implementation. |
|||
- add tree_mapent_add_node(). |
|||
- add tree_mapent_delete_offsets(). |
|||
+- add tree_mapent_traverse_subtree().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index eb700c79..fded4c09 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_cache *mc,
|
|||
return 1; |
|||
} |
|||
|
|||
+static inline int tree_mapent_is_root(struct mapent *oe)
|
|||
+{
|
|||
+ /* Offset "/" is a special case, it's looked up and mounted
|
|||
+ * seperately because the offset tree may or may not have a
|
|||
+ * real mount at the base and the triggers inside it need to
|
|||
+ * be mounted in either case. Also the order requires the
|
|||
+ * offset at the top of the (sub)tree to be handled after
|
|||
+ * the traversal.
|
|||
+ */
|
|||
+ return (oe->key[oe->len - 1] == '/' ||
|
|||
+ MAPENT_ROOT(oe) == MAPENT_NODE(oe));
|
|||
+}
|
|||
+
|
|||
+struct traverse_subtree_context {
|
|||
+ struct autofs_point *ap;
|
|||
+ struct tree_node *base;
|
|||
+ int strict;
|
|||
+};
|
|||
+
|
|||
+static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
|||
+{
|
|||
+ struct traverse_subtree_context *ctxt = ptr;
|
|||
+ struct mapent *oe = MAPENT(n);
|
|||
+ int ret = 1;
|
|||
+
|
|||
+ if (n->left) {
|
|||
+ ret = tree_mapent_traverse_subtree(n->left, work, ctxt);
|
|||
+ if (!ret && ctxt->strict)
|
|||
+ goto done;
|
|||
+ }
|
|||
+
|
|||
+ /* Node is not multi-mount root and is part of current subtree */
|
|||
+ if (!tree_mapent_is_root(oe) && MAPENT_PARENT(oe) == ctxt->base) {
|
|||
+ ret = work(n, ctxt);
|
|||
+ if (!ret && ctxt->strict)
|
|||
+ goto done;
|
|||
+ }
|
|||
+
|
|||
+ if (n->right) {
|
|||
+ ret = tree_mapent_traverse_subtree(n->right, work, ctxt);
|
|||
+ if (!ret && ctxt->strict)
|
|||
+ goto done;
|
|||
+ }
|
|||
+done:
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
static int tree_mapent_delete_offset_tree(struct tree_node *root) |
|||
{ |
|||
struct mapent *me = MAPENT(root); |
@ -1,335 +0,0 @@ |
|||
autofs-5.1.7 - add xdr_exports() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Add an xdr_exports() function to get NFS exports from a server. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 3 + |
|||
include/rpc_subs.h | 14 ++++++ |
|||
lib/rpc_subs.c | 120 +++++++++++++++++++++++++++++++++++------------- |
|||
modules/lookup_hosts.c | 25 +++------- |
|||
4 files changed, 112 insertions(+), 50 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2c48484b..84050e91 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -1,3 +1,6 @@
|
|||
+
|
|||
+- add xdr_exports().
|
|||
+
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
- update ldap READMEs and schema definitions. |
|||
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
|
|||
index 7ba4b93f..080f19d9 100644
|
|||
--- a/include/rpc_subs.h
|
|||
+++ b/include/rpc_subs.h
|
|||
@@ -17,6 +17,7 @@
|
|||
#define _RPC_SUBS_H |
|||
|
|||
#include <rpc/rpc.h> |
|||
+#include <rpc/types.h>
|
|||
#include <rpc/pmap_prot.h> |
|||
#include <linux/nfs.h> |
|||
#include <linux/nfs2.h> |
|||
@@ -47,6 +48,17 @@
|
|||
|
|||
#define HOST_ENT_BUF_SIZE 2048 |
|||
|
|||
+struct hostinfo {
|
|||
+ char *name;
|
|||
+ struct hostinfo *next;
|
|||
+};
|
|||
+
|
|||
+struct exportinfo {
|
|||
+ char *dir;
|
|||
+ struct hostinfo *hosts;
|
|||
+ struct exportinfo *next;
|
|||
+};
|
|||
+
|
|||
struct conn_info { |
|||
const char *host; |
|||
struct sockaddr *addr; |
|||
@@ -71,6 +83,8 @@ int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *);
|
|||
int rpc_ping_proto(struct conn_info *); |
|||
int rpc_ping(const char *, int, unsigned int, long, long, unsigned int); |
|||
double monotonic_elapsed(struct timespec, struct timespec); |
|||
+struct exportinfo *rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
|
|||
+void rpc_exports_free(struct exportinfo *exports);
|
|||
const char *get_addr_string(struct sockaddr *, char *, socklen_t); |
|||
|
|||
#endif |
|||
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|||
index 643b7687..7b8162b4 100644
|
|||
--- a/lib/rpc_subs.c
|
|||
+++ b/lib/rpc_subs.c
|
|||
@@ -41,7 +41,6 @@ const rpcprog_t rpcb_prog = PMAPPROG;
|
|||
const rpcvers_t rpcb_version = PMAPVERS; |
|||
#endif |
|||
|
|||
-#include "mount.h"
|
|||
#include "rpc_subs.h" |
|||
#include "replicated.h" |
|||
#include "automount.h" |
|||
@@ -58,6 +57,17 @@ const rpcvers_t rpcb_version = PMAPVERS;
|
|||
|
|||
#define MAX_NETWORK_LEN 255 |
|||
|
|||
+#define EXPPATHLEN 1024
|
|||
+#define EXPNAMELEN 255
|
|||
+
|
|||
+#define MOUNTPROG 100005
|
|||
+
|
|||
+#define MOUNTVERS 1
|
|||
+#define MOUNTVERS_NFSV3 3
|
|||
+#define MOUNTVERS_POSIX 2
|
|||
+
|
|||
+#define MOUNTPROC_EXPORT 5
|
|||
+
|
|||
/* Get numeric value of the n bits starting at position p */ |
|||
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) |
|||
|
|||
@@ -1102,7 +1112,55 @@ double monotonic_elapsed(struct timespec start, struct timespec end)
|
|||
return t2 - t1; |
|||
} |
|||
|
|||
-static int rpc_get_exports_proto(struct conn_info *info, exports *exp)
|
|||
+static bool_t xdr_host(XDR *xdrs, struct hostinfo *host)
|
|||
+{
|
|||
+ if (!xdr_string(xdrs, &host->name, EXPNAMELEN))
|
|||
+ return FALSE;
|
|||
+ return TRUE;
|
|||
+}
|
|||
+
|
|||
+static bool_t xdr_hosts(XDR *xdrs, struct hostinfo **hosts)
|
|||
+{
|
|||
+ unsigned int size = sizeof(struct hostinfo);
|
|||
+ char **host;
|
|||
+
|
|||
+ host = (char **) hosts;
|
|||
+ while (1) {
|
|||
+ if (!xdr_pointer(xdrs, host, size, (xdrproc_t) xdr_host))
|
|||
+ return FALSE;
|
|||
+ if (!*host)
|
|||
+ break;
|
|||
+ host = (char **) &((struct hostinfo *) *host)->next;
|
|||
+ }
|
|||
+ return TRUE;
|
|||
+}
|
|||
+
|
|||
+static bool_t xdr_export(XDR *xdrs, struct exportinfo *export)
|
|||
+{
|
|||
+ if (!xdr_string(xdrs, &export->dir, EXPPATHLEN))
|
|||
+ return FALSE;
|
|||
+ if (!xdr_hosts(xdrs, &export->hosts))
|
|||
+ return FALSE;
|
|||
+ return TRUE;
|
|||
+}
|
|||
+
|
|||
+bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports)
|
|||
+{
|
|||
+ unsigned int size = sizeof(struct exportinfo);
|
|||
+ char **export;
|
|||
+
|
|||
+ export = (char **) exports;
|
|||
+ while (1) {
|
|||
+ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export))
|
|||
+ return FALSE;
|
|||
+ if (!*export)
|
|||
+ break;
|
|||
+ export = (char **) &((struct exportinfo *) *export)->next;
|
|||
+ }
|
|||
+ return TRUE;
|
|||
+}
|
|||
+
|
|||
+static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exports)
|
|||
{ |
|||
CLIENT *client; |
|||
enum clnt_stat status; |
|||
@@ -1133,7 +1191,7 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp)
|
|||
while (1) { |
|||
status = clnt_call(client, MOUNTPROC_EXPORT, |
|||
(xdrproc_t) xdr_void, NULL, |
|||
- (xdrproc_t) xdr_exports, (caddr_t) exp,
|
|||
+ (xdrproc_t) xdr_exports, (caddr_t) exports,
|
|||
info->timeout); |
|||
if (status == RPC_SUCCESS) |
|||
break; |
|||
@@ -1168,41 +1226,43 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp)
|
|||
return 1; |
|||
} |
|||
|
|||
-static void rpc_export_free(exports item)
|
|||
+static void rpc_export_free(struct exportinfo *export)
|
|||
{ |
|||
- groups grp;
|
|||
- groups tmp;
|
|||
-
|
|||
- if (item->ex_dir)
|
|||
- free(item->ex_dir);
|
|||
-
|
|||
- grp = item->ex_groups;
|
|||
- while (grp) {
|
|||
- if (grp->gr_name)
|
|||
- free(grp->gr_name);
|
|||
- tmp = grp;
|
|||
- grp = grp->gr_next;
|
|||
+ struct hostinfo *host, *tmp;
|
|||
+
|
|||
+ if (export->dir)
|
|||
+ free(export->dir);
|
|||
+
|
|||
+ host = export->hosts;
|
|||
+ while (host) {
|
|||
+ if (host->name)
|
|||
+ free(host->name);
|
|||
+ tmp = host;
|
|||
+ host = host->next;
|
|||
free(tmp); |
|||
} |
|||
- free(item);
|
|||
+ free(export);
|
|||
} |
|||
|
|||
-void rpc_exports_free(exports list)
|
|||
+void rpc_exports_free(struct exportinfo *exports)
|
|||
{ |
|||
- exports tmp;
|
|||
+ struct exportinfo *export, *tmp;
|
|||
|
|||
- while (list) {
|
|||
- tmp = list;
|
|||
- list = list->ex_next;
|
|||
+ export = exports;
|
|||
+ while (export) {
|
|||
+ tmp = export;
|
|||
+ export = export->next;
|
|||
rpc_export_free(tmp); |
|||
} |
|||
return; |
|||
} |
|||
|
|||
-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option)
|
|||
+struct exportinfo *rpc_get_exports(const char *host,
|
|||
+ long seconds, long micros,
|
|||
+ unsigned int option)
|
|||
{ |
|||
struct conn_info info; |
|||
- exports exportlist;
|
|||
+ struct exportinfo *exports = NULL;
|
|||
struct pmap parms; |
|||
int status; |
|||
|
|||
@@ -1231,11 +1291,9 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in
|
|||
if (status < 0) |
|||
goto try_tcp; |
|||
|
|||
- memset(&exportlist, '\0', sizeof(exportlist));
|
|||
-
|
|||
- status = rpc_get_exports_proto(&info, &exportlist);
|
|||
+ status = rpc_get_exports_proto(&info, &exports);
|
|||
if (status) |
|||
- return exportlist;
|
|||
+ return exports;
|
|||
|
|||
try_tcp: |
|||
info.proto = IPPROTO_TCP; |
|||
@@ -1246,13 +1304,11 @@ try_tcp:
|
|||
if (status < 0) |
|||
return NULL; |
|||
|
|||
- memset(&exportlist, '\0', sizeof(exportlist));
|
|||
-
|
|||
- status = rpc_get_exports_proto(&info, &exportlist);
|
|||
+ status = rpc_get_exports_proto(&info, &exports);
|
|||
if (!status) |
|||
return NULL; |
|||
|
|||
- return exportlist;
|
|||
+ return exports;
|
|||
} |
|||
|
|||
const char *get_addr_string(struct sockaddr *sa, char *name, socklen_t len) |
|||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|||
index 744062e2..81a4eb18 100644
|
|||
--- a/modules/lookup_hosts.c
|
|||
+++ b/modules/lookup_hosts.c
|
|||
@@ -20,14 +20,6 @@
|
|||
#include <sys/stat.h> |
|||
#include <netdb.h> |
|||
|
|||
-/*
|
|||
- * Avoid annoying compiler noise by using an alternate name for
|
|||
- * typedef name in mount.h
|
|||
- */
|
|||
-#define name __dummy_type_name
|
|||
-#include "mount.h"
|
|||
-#undef name
|
|||
-
|
|||
#define MODULE_LOOKUP |
|||
#include "automount.h" |
|||
#include "nsswitch.h" |
|||
@@ -43,9 +35,6 @@ struct lookup_context {
|
|||
|
|||
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ |
|||
|
|||
-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
|
|||
-void rpc_exports_free(exports list);
|
|||
-
|
|||
int lookup_init(const char *mapfmt, |
|||
int argc, const char *const *argv, void **context) |
|||
{ |
|||
@@ -99,7 +88,7 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
{ |
|||
char buf[MAX_ERR_BUF]; |
|||
char *mapent; |
|||
- exports exp, this;
|
|||
+ struct exportinfo *exp, *this;
|
|||
|
|||
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); |
|||
|
|||
@@ -111,7 +100,7 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
if (mapent) { |
|||
int len = strlen(mapent) + 1; |
|||
|
|||
- len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3;
|
|||
+ len += strlen(host) + 2*(strlen(this->dir) + 2) + 3;
|
|||
mapent = realloc(mapent, len); |
|||
if (!mapent) { |
|||
char *estr; |
|||
@@ -121,10 +110,10 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
return NULL; |
|||
} |
|||
strcat(mapent, " \""); |
|||
- strcat(mapent, this->ex_dir);
|
|||
+ strcat(mapent, this->dir);
|
|||
strcat(mapent, "\""); |
|||
} else { |
|||
- int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3;
|
|||
+ int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3;
|
|||
|
|||
mapent = malloc(len); |
|||
if (!mapent) { |
|||
@@ -135,16 +124,16 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
return NULL; |
|||
} |
|||
strcpy(mapent, "\""); |
|||
- strcat(mapent, this->ex_dir);
|
|||
+ strcat(mapent, this->dir);
|
|||
strcat(mapent, "\""); |
|||
} |
|||
strcat(mapent, " \""); |
|||
strcat(mapent, host); |
|||
strcat(mapent, ":"); |
|||
- strcat(mapent, this->ex_dir);
|
|||
+ strcat(mapent, this->dir);
|
|||
strcat(mapent, "\""); |
|||
|
|||
- this = this->ex_next;
|
|||
+ this = this->next;
|
|||
} |
|||
rpc_exports_free(exp); |
|||
|
@ -1,38 +0,0 @@ |
|||
autofs-5.1.7 - also require TCP_REQUESTED when setting NFS port |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Set the NFS service port to the default (2049) only if tcp protocol is |
|||
being used and not alternate port has been given. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/replicated.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5d2c2c88..fd5b800a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -91,6 +91,7 @@
|
|||
- add buffer length checks to autofs mount_mount(). |
|||
- make NFS version check flags consistent. |
|||
- refactor get_nfs_info(). |
|||
+- also require TCP_REQUESTED when setting NFS port.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|||
index e03c9d25..09075dd0 100644
|
|||
--- a/modules/replicated.c
|
|||
+++ b/modules/replicated.c
|
|||
@@ -291,7 +291,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
|
|||
|
|||
rpc_info->proto = proto; |
|||
if (port < 0) { |
|||
- if (version & NFS4_REQUESTED)
|
|||
+ if ((version & NFS4_REQUESTED) && (version & TCP_REQUESTED))
|
|||
rpc_info->port = NFS_PORT; |
|||
else |
|||
port = 0; |
@ -1,44 +0,0 @@ |
|||
autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: var_deref_model: Passing null pointer "tree" to |
|||
"tree_traverse_inorder", which dereferences it. |
|||
|
|||
This obviously can't happen but deal with it anyway to quiet Coverity. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 6 ++++-- |
|||
2 files changed, 5 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b79aebc8..b1b28888 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -64,6 +64,7 @@
|
|||
- fix missing lock release in mount_subtree(). |
|||
- fix double free in parse_mapent(). |
|||
- refactor lookup_prune_one_cache() a bit. |
|||
+- cater for empty mounts list in mnts_get_expire_list().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 883e3743..3996eb5e 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
|||
} |
|||
} |
|||
|
|||
- tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
|||
- tree_free(tree);
|
|||
+ if (tree) {
|
|||
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
|||
+ tree_free(tree);
|
|||
+ }
|
|||
done: |
|||
mnts_hash_mutex_unlock(); |
|||
} |
@ -1,50 +0,0 @@ |
|||
autofs-5.1.7 - check for offset with no mount location |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Offsets need to have a mount location, check for it. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 15 ++++++++++++++- |
|||
2 files changed, 15 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index a9209755..42914160 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -47,6 +47,7 @@
|
|||
- pass root length to mount_fullpath(). |
|||
- remove unused function master_submount_list_empty(). |
|||
- move amd mounts removal into lib/mounts.c. |
|||
+- check for offset with no mount location.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index b1c2611c..a81d4028 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -801,7 +801,20 @@ update_offset_entry(struct autofs_point *ap,
|
|||
|
|||
memset(m_mapent, 0, MAPENT_MAX_LEN + 1); |
|||
|
|||
- /* Internal hosts map may have loc == NULL */
|
|||
+ if (!loc || !*loc) {
|
|||
+ const char *type = ap->entry->maps->type;
|
|||
+
|
|||
+ /* If it's not the internal hosts map it must have a
|
|||
+ * mount location.
|
|||
+ */
|
|||
+ if (!type || strcmp(type, "hosts")) {
|
|||
+ error(ap->logopt,
|
|||
+ MODPREFIX "syntax error in offset %s -> %s",
|
|||
+ m_offset, loc);
|
|||
+ return CHE_FAIL;
|
|||
+ }
|
|||
+ }
|
|||
+
|
|||
if (!*m_offset) { |
|||
error(ap->logopt, |
|||
MODPREFIX "syntax error in offset %s -> %s", m_offset, loc); |
@ -1,64 +0,0 @@ |
|||
autofs-5.1.7 - cleanup cache_delete() a little |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
There's no reason to use local function storage for the passed in key |
|||
just use the given key. |
|||
|
|||
Also, if there's no hash array entry for the key then there's no cache |
|||
entry so don't return a fail for this case. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/cache.c | 11 +++-------- |
|||
2 files changed, 4 insertions(+), 8 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 6419052d..e822efec 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -24,6 +24,7 @@
|
|||
- eliminate some strlen calls in offset handling. |
|||
- don't add offset mounts to mounted mounts table. |
|||
- reduce umount EBUSY check delay. |
|||
+- cleanup cache_delete() a little.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index 03d0499a..a90bbb1d 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -917,20 +917,15 @@ int cache_delete(struct mapent_cache *mc, const char *key)
|
|||
struct mapent *me = NULL, *pred; |
|||
u_int32_t hashval = hash(key, mc->size); |
|||
int ret = CHE_OK; |
|||
- char this[PATH_MAX];
|
|||
-
|
|||
- strcpy(this, key);
|
|||
|
|||
me = mc->hash[hashval]; |
|||
- if (!me) {
|
|||
- ret = CHE_FAIL;
|
|||
+ if (!me)
|
|||
goto done; |
|||
- }
|
|||
|
|||
while (me->next != NULL) { |
|||
pred = me; |
|||
me = me->next; |
|||
- if (strcmp(this, me->key) == 0) {
|
|||
+ if (strcmp(key, me->key) == 0) {
|
|||
struct stack *s = me->stack; |
|||
if (me->multi && !list_empty(&me->multi_list)) { |
|||
ret = CHE_FAIL; |
|||
@@ -959,7 +954,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
|
|||
if (!me) |
|||
goto done; |
|||
|
|||
- if (strcmp(this, me->key) == 0) {
|
|||
+ if (strcmp(key, me->key) == 0) {
|
|||
struct stack *s = me->stack; |
|||
if (me->multi && !list_empty(&me->multi_list)) { |
|||
ret = CHE_FAIL; |
@ -1,207 +0,0 @@ |
|||
autofs-5.1.7 - don't add offset mounts to mounted mounts table |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Multi-mount offset mounts are added to the mounted mounts table whether |
|||
they have a real mount or not. If there are a large number of offsets |
|||
this can add unnecessary overhead to the mounted mounts table processing. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 14 ++++---------- |
|||
daemon/indirect.c | 4 +++- |
|||
include/mounts.h | 2 +- |
|||
lib/mounts.c | 43 +++++++++++-------------------------------- |
|||
5 files changed, 20 insertions(+), 44 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index cb709773..b144f6aa 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -22,6 +22,7 @@
|
|||
- remove unused mount offset list lock functions. |
|||
- eliminate count_mounts() from expire_proc_indirect(). |
|||
- eliminate some strlen calls in offset handling. |
|||
+- don't add offset mounts to mounted mounts table.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 311a98ba..fbfebbdd 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -605,9 +605,6 @@ force_umount:
|
|||
} else |
|||
info(ap->logopt, "umounted offset mount %s", me->key); |
|||
|
|||
- if (!rv)
|
|||
- mnts_remove_mount(me->key, MNTS_OFFSET);
|
|||
-
|
|||
return rv; |
|||
} |
|||
|
|||
@@ -761,12 +758,6 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|||
notify_mount_result(ap, me->key, timeout, str_offset); |
|||
ops->close(ap->logopt, ioctlfd); |
|||
|
|||
- mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET);
|
|||
- if (!mnt)
|
|||
- error(ap->logopt,
|
|||
- "failed to add offset mount %s to mounted list",
|
|||
- me->key);
|
|||
-
|
|||
debug(ap->logopt, "mounted trigger %s", me->key); |
|||
|
|||
return MOUNT_OFFSET_OK; |
|||
@@ -1214,6 +1205,7 @@ static void *do_mount_direct(void *arg)
|
|||
struct mapent *me; |
|||
struct statfs fs; |
|||
unsigned int close_fd = 0; |
|||
+ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED;
|
|||
|
|||
sbmnt = mnts_find_submount(mt.name); |
|||
if (statfs(mt.name, &fs) == -1 || |
|||
@@ -1232,6 +1224,8 @@ static void *do_mount_direct(void *arg)
|
|||
close_fd = 0; |
|||
if (!close_fd) |
|||
me->ioctlfd = mt.ioctlfd; |
|||
+ if (me->multi && me->multi != me)
|
|||
+ flags |= MNTS_OFFSET;
|
|||
} |
|||
ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); |
|||
cache_unlock(mt.mc); |
|||
@@ -1240,7 +1234,7 @@ static void *do_mount_direct(void *arg)
|
|||
|
|||
info(ap->logopt, "mounted %s", mt.name); |
|||
|
|||
- mnts_set_mounted_mount(ap, mt.name);
|
|||
+ mnts_set_mounted_mount(ap, mt.name, flags);
|
|||
|
|||
conditional_alarm_add(ap, ap->exp_runfreq); |
|||
} else { |
|||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|||
index b259ebdc..eddcfff7 100644
|
|||
--- a/daemon/indirect.c
|
|||
+++ b/daemon/indirect.c
|
|||
@@ -747,12 +747,14 @@ static void *do_mount_indirect(void *arg)
|
|||
status = lookup_nss_mount(ap, NULL, mt.name, mt.len); |
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); |
|||
if (status) { |
|||
+ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED;
|
|||
+
|
|||
ops->send_ready(ap->logopt, |
|||
ap->ioctlfd, mt.wait_queue_token); |
|||
|
|||
info(ap->logopt, "mounted %s", buf); |
|||
|
|||
- mnts_set_mounted_mount(ap, mt.name);
|
|||
+ mnts_set_mounted_mount(ap, mt.name, flags);
|
|||
|
|||
conditional_alarm_add(ap, ap->exp_runfreq); |
|||
} else { |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index e3022b23..ac480c06 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -131,7 +131,7 @@ struct mnt_list *get_mnt_list(const char *path, int include);
|
|||
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); |
|||
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); |
|||
void mnts_put_expire_list(struct list_head *mnts); |
|||
-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name);
|
|||
+void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
|
|||
int unlink_mount_tree(struct autofs_point *ap, const char *mp); |
|||
void free_mnt_list(struct mnt_list *list); |
|||
int is_mounted(const char *mp, unsigned int type); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 04fe3d00..25ae2e1d 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1172,7 +1172,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
|||
this = mnts_get_mount(mp); |
|||
if (this) { |
|||
this->flags |= flags; |
|||
- if (list_empty(&this->mount))
|
|||
+ if ((this->flags & MNTS_MOUNTED) && list_empty(&this->mount))
|
|||
list_add(&this->mount, &ap->mounts); |
|||
} |
|||
mnts_hash_mutex_unlock(); |
|||
@@ -1193,42 +1193,23 @@ void mnts_remove_mount(const char *mp, unsigned int flags)
|
|||
this = mnts_lookup(mp); |
|||
if (this && this->flags & flags) { |
|||
this->flags &= ~flags; |
|||
- if (!(this->flags & (MNTS_OFFSET|MNTS_MOUNTED)))
|
|||
+ if (!(this->flags & MNTS_MOUNTED))
|
|||
list_del_init(&this->mount); |
|||
__mnts_put_mount(this); |
|||
} |
|||
mnts_hash_mutex_unlock(); |
|||
} |
|||
|
|||
-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name)
|
|||
+void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags)
|
|||
{ |
|||
struct mnt_list *mnt; |
|||
|
|||
- mnt = mnts_add_mount(ap, name, MNTS_MOUNTED);
|
|||
+ mnt = mnts_add_mount(ap, name, flags);
|
|||
if (!mnt) { |
|||
error(ap->logopt, |
|||
"failed to add mount %s to mounted list", name); |
|||
return; |
|||
} |
|||
-
|
|||
- /* Offset mount failed but non-strict returns success */
|
|||
- if (mnt->flags & MNTS_OFFSET &&
|
|||
- !is_mounted(mnt->mp, MNTS_REAL)) {
|
|||
- mnt->flags &= ~MNTS_MOUNTED;
|
|||
- mnts_put_mount(mnt);
|
|||
- }
|
|||
-
|
|||
- /* Housekeeping.
|
|||
- * Set the base type of the mounted mount.
|
|||
- * MNTS_AUTOFS and MNTS_OFFSET are set at mount time and
|
|||
- * are used during expire.
|
|||
- */
|
|||
- if (!(mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET))) {
|
|||
- if (ap->type == LKP_INDIRECT)
|
|||
- mnt->flags |= MNTS_INDIRECT;
|
|||
- else
|
|||
- mnt->flags |= MNTS_DIRECT;
|
|||
- }
|
|||
} |
|||
|
|||
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap) |
|||
@@ -1947,17 +1928,13 @@ static int do_remount_direct(struct autofs_point *ap,
|
|||
|
|||
ret = lookup_nss_mount(ap, NULL, path, strlen(path)); |
|||
if (ret) { |
|||
- struct mnt_list *mnt;
|
|||
+ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED;
|
|||
|
|||
/* If it's an offset mount add a mount reference */ |
|||
- if (type == t_offset) {
|
|||
- mnt = mnts_add_mount(ap, path, MNTS_OFFSET);
|
|||
- if (!mnt)
|
|||
- error(ap->logopt,
|
|||
- "failed to add mount %s to mounted list", path);
|
|||
- }
|
|||
+ if (type == t_offset)
|
|||
+ flags |= MNTS_OFFSET;
|
|||
|
|||
- mnts_set_mounted_mount(ap, path);
|
|||
+ mnts_set_mounted_mount(ap, path, flags);
|
|||
|
|||
info(ap->logopt, "re-connected to %s", path); |
|||
|
|||
@@ -2032,7 +2009,9 @@ static int do_remount_indirect(struct autofs_point *ap, const unsigned int type,
|
|||
|
|||
ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len); |
|||
if (ret) { |
|||
- mnts_set_mounted_mount(ap, buf);
|
|||
+ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED;
|
|||
+
|
|||
+ mnts_set_mounted_mount(ap, buf, flags);
|
|||
|
|||
info(ap->logopt, "re-connected to %s", buf); |
|||
|
@ -1,64 +0,0 @@ |
|||
autofs-5.1.7 - don't pass root to do_mount_autofs_offset() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The root parameter of do_mount_autofs_offset() is used only in a |
|||
debug log message. It doesn't really add any value to debugging |
|||
so remove it. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 9 ++++----- |
|||
2 files changed, 5 insertions(+), 5 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0e9ca94f..2a07bd45 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -26,6 +26,7 @@
|
|||
- reduce umount EBUSY check delay. |
|||
- cleanup cache_delete() a little. |
|||
- rename path to m_offset in update_offset_entry(). |
|||
+- don't pass root to do_mount_autofs_offset().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 25ae2e1d..289500da 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2453,13 +2453,12 @@ out:
|
|||
return rv; |
|||
} |
|||
|
|||
-static int do_mount_autofs_offset(struct autofs_point *ap,
|
|||
- struct mapent *oe, const char *root)
|
|||
+static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe)
|
|||
{ |
|||
int mounted = 0; |
|||
int ret; |
|||
|
|||
- debug(ap->logopt, "mount offset %s at %s", oe->key, root);
|
|||
+ debug(ap->logopt, "mount offset %s", oe->key);
|
|||
|
|||
ret = mount_autofs_offset(ap, oe); |
|||
if (ret >= MOUNT_OFFSET_OK) |
|||
@@ -2651,7 +2650,7 @@ static int do_umount_offset(struct autofs_point *ap,
|
|||
*/ |
|||
ret = rmdir_path_offset(ap, oe); |
|||
if (ret == -1 && !stat(oe->key, &st)) { |
|||
- ret = do_mount_autofs_offset(ap, oe, root);
|
|||
+ ret = do_mount_autofs_offset(ap, oe);
|
|||
if (ret) |
|||
left++; |
|||
/* But we did origianlly create this */ |
|||
@@ -2697,7 +2696,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
goto cont; |
|||
} |
|||
|
|||
- mounted += do_mount_autofs_offset(ap, oe, root);
|
|||
+ mounted += do_mount_autofs_offset(ap, oe);
|
|||
|
|||
/* |
|||
* If re-constructing a multi-mount it's necessary to walk |
@ -1,45 +0,0 @@ |
|||
autofs-5.1.7 - dont try umount after stat() ENOENT fail |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: Calling function "umount" that uses "me->key" after a check |
|||
function. This can cause a time-of-check, time-of-use race |
|||
condition. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 6 +++++- |
|||
2 files changed, 6 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 7add6c55..c7bc0c39 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -57,6 +57,7 @@
|
|||
- fix double unlock in parse_mount(). |
|||
- add length check in umount_subtree_mounts(). |
|||
- fix flags check in umount_multi(). |
|||
+- dont try umount after stat() ENOENT fail.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index a33f9f91..3bd714e6 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|||
|
|||
ret = stat(me->key, &st); |
|||
if (ret == -1) { |
|||
+ int save_errno = errno;
|
|||
+
|
|||
error(ap->logopt, |
|||
"failed to stat direct mount trigger %s", me->key); |
|||
- goto out_umount;
|
|||
+ if (save_errno != ENOENT)
|
|||
+ goto out_umount;
|
|||
+ goto out_err;
|
|||
} |
|||
|
|||
ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); |
@ -1,47 +0,0 @@ |
|||
autofs-5.1.7 - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Using an ioctl (AUTOFS_DEV_IOCTL_CLOSEMOUNT) to close an autofs mount |
|||
file handle can race with copy_to_user() so the file handle needs to |
|||
be closed using close(2) instead. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/dev-ioctl-lib.c | 10 +--------- |
|||
2 files changed, 2 insertions(+), 9 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 06bf24b8..51e7767e 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -68,6 +68,7 @@
|
|||
- add ext_mount_hash_mutex lock helpers. |
|||
- fix amd section mounts map reload. |
|||
- fix dandling symlink creation if nis support is not available. |
|||
+- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
|
|||
index e7a1b42a..6b549d73 100644
|
|||
--- a/lib/dev-ioctl-lib.c
|
|||
+++ b/lib/dev-ioctl-lib.c
|
|||
@@ -404,15 +404,7 @@ err:
|
|||
/* 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;
|
|||
+ return close(ioctlfd);
|
|||
} |
|||
|
|||
static int ioctl_close(unsigned int logopt, int ioctlfd) |
@ -1,112 +0,0 @@ |
|||
autofs-5.1.7 - dont use realloc in host exports list processing |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If a server exports list is very large calling realloc(3) for each |
|||
export is slow. It's better to traverse the exports list twice, once |
|||
to calculate the length of the mapent then allocate the memory and |
|||
traverse the exports list again to construct the mapent. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/lookup_hosts.c | 59 +++++++++++++++++++++--------------------------- |
|||
2 files changed, 27 insertions(+), 33 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 19af245e..1bd6ac7f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -1,6 +1,7 @@
|
|||
|
|||
- add xdr_exports(). |
|||
- remove mount.x and rpcgen dependencies. |
|||
+- dont use realloc in host exports list processing.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|||
index 81a4eb18..e3ee0ab8 100644
|
|||
--- a/modules/lookup_hosts.c
|
|||
+++ b/modules/lookup_hosts.c
|
|||
@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
char buf[MAX_ERR_BUF]; |
|||
char *mapent; |
|||
struct exportinfo *exp, *this; |
|||
+ size_t hostlen = strlen(host);
|
|||
+ size_t mapent_len;
|
|||
|
|||
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); |
|||
|
|||
exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER); |
|||
|
|||
- mapent = NULL;
|
|||
this = exp; |
|||
+ mapent_len = 0;
|
|||
while (this) { |
|||
- if (mapent) {
|
|||
- int len = strlen(mapent) + 1;
|
|||
-
|
|||
- len += strlen(host) + 2*(strlen(this->dir) + 2) + 3;
|
|||
- mapent = realloc(mapent, len);
|
|||
- if (!mapent) {
|
|||
- char *estr;
|
|||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
- error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
- rpc_exports_free(exp);
|
|||
- return NULL;
|
|||
- }
|
|||
- strcat(mapent, " \"");
|
|||
- strcat(mapent, this->dir);
|
|||
- strcat(mapent, "\"");
|
|||
- } else {
|
|||
- int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3;
|
|||
-
|
|||
- mapent = malloc(len);
|
|||
- if (!mapent) {
|
|||
- char *estr;
|
|||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
- error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
- rpc_exports_free(exp);
|
|||
- return NULL;
|
|||
- }
|
|||
+ mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
|
|||
+ this = this->next;
|
|||
+ }
|
|||
+
|
|||
+ mapent = malloc(mapent_len + 1);
|
|||
+ if (!mapent) {
|
|||
+ char *estr;
|
|||
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
+ error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
|
|||
+ rpc_exports_free(exp);
|
|||
+ return NULL;
|
|||
+ }
|
|||
+ *mapent = 0;
|
|||
+
|
|||
+ this = exp;
|
|||
+ while (this) {
|
|||
+ if (!*mapent)
|
|||
strcpy(mapent, "\""); |
|||
- strcat(mapent, this->dir);
|
|||
- strcat(mapent, "\"");
|
|||
- }
|
|||
+ else
|
|||
+ strcat(mapent, " \"");
|
|||
+ strcat(mapent, this->dir);
|
|||
+ strcat(mapent, "\"");
|
|||
+
|
|||
strcat(mapent, " \""); |
|||
strcat(mapent, host); |
|||
strcat(mapent, ":"); |
|||
@@ -137,9 +133,6 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
} |
|||
rpc_exports_free(exp); |
|||
|
|||
- if (!mapent)
|
|||
- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
|
|||
-
|
|||
return mapent; |
|||
} |
|||
|
@ -1,86 +0,0 @@ |
|||
autofs-5.1.7 - eliminate buffer usage from handle_mounts_cleanup() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
This buffer was originally added because a SEGV was seen accessing |
|||
the ap->path field on shutdown. |
|||
|
|||
But this was actually caused by calling master_remove_mapent() too |
|||
early which adds the map entry to the master map join list that leads |
|||
to freeing the autofs_point (ap in the code) which also frees ap->path. |
|||
|
|||
But the master map join list is protected by the master map mutex which |
|||
is held until after all the accesses are completed. So whatever the |
|||
problem was it doesn't appear to be present any more. |
|||
|
|||
Nevertheless, to be sure, delay the call to master_remove_mapent() until |
|||
after all accesses to ap->path are completed. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 13 ++++++------- |
|||
2 files changed, 7 insertions(+), 7 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 38304720..6ab4813d 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -87,6 +87,7 @@
|
|||
- add copy length check in umount_autofs_indirect(). |
|||
- add some buffer length checks to master map parser. |
|||
- add buffer length check to rmdir_path(). |
|||
+- eliminate buffer usage from handle_mounts_cleanup().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 114b013a..cc286892 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -1716,7 +1716,6 @@ void handle_mounts_startup_cond_destroy(void *arg)
|
|||
static void handle_mounts_cleanup(void *arg) |
|||
{ |
|||
struct autofs_point *ap; |
|||
- char path[PATH_MAX + 1];
|
|||
char buf[MAX_ERR_BUF]; |
|||
unsigned int clean = 0, submount, logopt; |
|||
unsigned int pending = 0; |
|||
@@ -1726,7 +1725,6 @@ static void handle_mounts_cleanup(void *arg)
|
|||
logopt = ap->logopt; |
|||
submount = ap->submount; |
|||
|
|||
- strcpy(path, ap->path);
|
|||
if (!submount && strcmp(ap->path, "/-") && |
|||
ap->flags & MOUNT_FLAG_DIR_CREATED) |
|||
clean = 1; |
|||
@@ -1751,8 +1749,8 @@ static void handle_mounts_cleanup(void *arg)
|
|||
/* Don't signal the handler if we have already done so */ |
|||
if (!list_empty(&master_list->completed)) |
|||
pending = 1; |
|||
- master_remove_mapent(ap->entry);
|
|||
- master_source_unlock(ap->entry);
|
|||
+
|
|||
+ info(logopt, "shut down path %s", ap->path);
|
|||
|
|||
destroy_logpri_fifo(ap); |
|||
|
|||
@@ -1768,14 +1766,15 @@ static void handle_mounts_cleanup(void *arg)
|
|||
} |
|||
|
|||
if (clean) { |
|||
- if (rmdir(path) == -1) {
|
|||
+ if (rmdir(ap->path) == -1) {
|
|||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
warn(logopt, "failed to remove dir %s: %s", |
|||
- path, estr);
|
|||
+ ap->path, estr);
|
|||
} |
|||
} |
|||
|
|||
- info(logopt, "shut down path %s", path);
|
|||
+ master_remove_mapent(ap->entry);
|
|||
+ master_source_unlock(ap->entry);
|
|||
|
|||
/* |
|||
* If we are not a submount send a signal to the signal handler |
@ -1,378 +0,0 @@ |
|||
autofs-5.1.7 - eliminate cache_lookup_offset() usage |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The function cache_lookup_offset() will do a linear search when |
|||
looking for an offset. If the number of offsets is large this |
|||
can be a lot of overhead. |
|||
|
|||
But it's possible to use the information already present where |
|||
this is called to to do a hashed lookup instead. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 82 +++++++++++++++++++++++++++++++++------------------ |
|||
modules/parse_sun.c | 77 ++++++++++++++++++++++++++++++------------------ |
|||
3 files changed, 102 insertions(+), 58 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0b577909..484bd866 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -5,6 +5,7 @@
|
|||
- use sprintf() when constructing hosts mapent. |
|||
- fix mnts_remove_amdmount() uses wrong list. |
|||
- Fix option for master read wait. |
|||
+- eliminate cache_lookup_offset() usage.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index ccbd52e0..42e8ef07 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2495,24 +2495,27 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
char *offset = path; |
|||
struct mapent *oe; |
|||
struct list_head *pos = NULL; |
|||
- unsigned int fs_path_len;
|
|||
+ unsigned int root_len = strlen(root);
|
|||
int mounted; |
|||
|
|||
- fs_path_len = start + strlen(base);
|
|||
- if (fs_path_len > PATH_MAX)
|
|||
- return -1;
|
|||
-
|
|||
mounted = 0; |
|||
offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); |
|||
while (offset) { |
|||
- int plen = fs_path_len + strlen(offset);
|
|||
+ char key[PATH_MAX + 1];
|
|||
+ int key_len = root_len + strlen(offset);
|
|||
|
|||
- if (plen > PATH_MAX) {
|
|||
+ if (key_len > PATH_MAX) {
|
|||
warn(ap->logopt, "path loo long"); |
|||
goto cont; |
|||
} |
|||
|
|||
- oe = cache_lookup_offset(base, offset, start, &me->multi_list);
|
|||
+ /* The root offset is always mounted seperately so the
|
|||
+ * offset path will always be root + offset.
|
|||
+ */
|
|||
+ strcpy(key, root);
|
|||
+ strcat(key, offset);
|
|||
+
|
|||
+ oe = cache_lookup_distinct(me->mc, key);
|
|||
if (!oe || !oe->mapent) |
|||
goto cont; |
|||
|
|||
@@ -2525,12 +2528,8 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
*/ |
|||
if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { |
|||
if (oe->ioctlfd != -1 || |
|||
- is_mounted(oe->key, MNTS_REAL)) {
|
|||
- char oe_root[PATH_MAX + 1];
|
|||
- strcpy(oe_root, root);
|
|||
- strcat(oe_root, offset);
|
|||
- mount_multi_triggers(ap, oe, oe_root, strlen(oe_root), base);
|
|||
- }
|
|||
+ is_mounted(oe->key, MNTS_REAL))
|
|||
+ mount_multi_triggers(ap, oe, key, strlen(key), base);
|
|||
} |
|||
cont: |
|||
offset = cache_get_offset(base, |
|||
@@ -2584,6 +2583,8 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
const char o_root[] = "/"; |
|||
const char *mm_base; |
|||
int left, start; |
|||
+ unsigned int root_len;
|
|||
+ unsigned int mm_base_len;
|
|||
|
|||
left = 0; |
|||
start = strlen(root); |
|||
@@ -2597,11 +2598,28 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
|
|||
pos = NULL; |
|||
offset = path; |
|||
+ root_len = start;
|
|||
+ mm_base_len = strlen(mm_base);
|
|||
|
|||
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { |
|||
+ char key[PATH_MAX + 1];
|
|||
+ int key_len = root_len + strlen(offset);
|
|||
char *oe_base; |
|||
|
|||
- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
|
|||
+ if (mm_base_len > 1)
|
|||
+ key_len += mm_base_len;
|
|||
+
|
|||
+ if (key_len > PATH_MAX) {
|
|||
+ warn(ap->logopt, "path loo long");
|
|||
+ continue;
|
|||
+ }
|
|||
+
|
|||
+ strcpy(key, root);
|
|||
+ if (mm_base_len > 1)
|
|||
+ strcat(key, mm_base);
|
|||
+ strcat(key, offset);
|
|||
+
|
|||
+ oe = cache_lookup_distinct(me->mc, key);
|
|||
/* root offset is a special case */ |
|||
if (!oe || (strlen(oe->key) - start) == 1) |
|||
continue; |
|||
@@ -2686,13 +2704,14 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
char *root; |
|||
char mm_top[PATH_MAX + 1]; |
|||
char path[PATH_MAX + 1]; |
|||
- char buf[MAX_ERR_BUF];
|
|||
char *offset; |
|||
struct mapent *oe; |
|||
struct list_head *mm_root, *pos; |
|||
const char o_root[] = "/"; |
|||
const char *mm_base; |
|||
int left, start; |
|||
+ unsigned int root_len;
|
|||
+ unsigned int mm_base_len;
|
|||
time_t age; |
|||
|
|||
if (top) |
|||
@@ -2720,14 +2739,30 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
|
|||
pos = NULL; |
|||
offset = path; |
|||
+ root_len = start;
|
|||
+ mm_base_len = strlen(mm_base);
|
|||
age = me->multi->age; |
|||
|
|||
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { |
|||
+ char key[PATH_MAX + 1];
|
|||
+ int key_len = root_len + strlen(offset);
|
|||
char *oe_base; |
|||
- char *key;
|
|||
int ret; |
|||
|
|||
- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
|
|||
+ if (mm_base_len > 1)
|
|||
+ key_len += mm_base_len;
|
|||
+
|
|||
+ if (key_len > PATH_MAX) {
|
|||
+ warn(ap->logopt, "path loo long");
|
|||
+ continue;
|
|||
+ }
|
|||
+
|
|||
+ strcpy(key, root);
|
|||
+ if (mm_base_len > 1)
|
|||
+ strcat(key, mm_base);
|
|||
+ strcat(key, offset);
|
|||
+
|
|||
+ oe = cache_lookup_distinct(me->mc, key);
|
|||
/* root offset is a special case */ |
|||
if (!oe || (strlen(oe->key) - start) == 1) |
|||
continue; |
|||
@@ -2778,14 +2813,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
} |
|||
} |
|||
|
|||
- key = strdup(oe->key);
|
|||
- if (!key) {
|
|||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
- error(ap->logopt, "malloc: %s", estr);
|
|||
- left++;
|
|||
- continue;
|
|||
- }
|
|||
-
|
|||
debug(ap->logopt, "umount offset %s", oe->key); |
|||
|
|||
if (umount_autofs_offset(ap, oe)) { |
|||
@@ -2800,7 +2827,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
if (cache_delete_offset(oe->mc, key) == CHE_FAIL) |
|||
error(ap->logopt, |
|||
"failed to delete offset key %s", key); |
|||
- free(key);
|
|||
continue; |
|||
} |
|||
|
|||
@@ -2816,7 +2842,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
left++; |
|||
/* But we did origianlly create this */ |
|||
oe->flags |= MOUNT_FLAG_DIR_CREATED; |
|||
- free(key);
|
|||
continue; |
|||
} |
|||
/* |
|||
@@ -2834,7 +2859,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
error(ap->logopt, |
|||
"failed to delete offset key %s", key); |
|||
} |
|||
- free(key);
|
|||
} |
|||
|
|||
return left; |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 4b137f99..819d6adc 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1086,6 +1086,8 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
|
|||
struct list_head *mm_root, *pos; |
|||
const char o_root[] = "/"; |
|||
const char *mm_base; |
|||
+ unsigned int root_len;
|
|||
+ unsigned int mm_base_len;
|
|||
|
|||
mm_root = &me->multi->multi_list; |
|||
|
|||
@@ -1095,16 +1097,31 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
|
|||
mm_base = base; |
|||
|
|||
pos = NULL; |
|||
+ root_len = strlen(root);
|
|||
+ mm_base_len = strlen(mm_base);
|
|||
|
|||
/* Make sure "none" of the offsets have an active mount. */ |
|||
while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) { |
|||
- oe = cache_lookup_offset(mm_base, poffset, start, &me->multi_list);
|
|||
- /* root offset is a special case */
|
|||
- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
|
|||
+ unsigned int path_len = root_len + strlen(poffset);
|
|||
+
|
|||
+ if (mm_base_len > 1)
|
|||
+ path_len += mm_base_len;
|
|||
+
|
|||
+ if (path_len > PATH_MAX) {
|
|||
+ warn(ap->logopt, "path loo long");
|
|||
continue; |
|||
+ }
|
|||
|
|||
strcpy(path, root); |
|||
+ if (mm_base_len > 1)
|
|||
+ strcat(path, mm_base);
|
|||
strcat(path, poffset); |
|||
+
|
|||
+ oe = cache_lookup_distinct(me->mc, path);
|
|||
+ /* root offset is a special case */
|
|||
+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
|
|||
+ continue;
|
|||
+
|
|||
if (umount(path)) { |
|||
error(ap->logopt, "error recovering from mount fail"); |
|||
error(ap->logopt, "cannot umount offset %s", path); |
|||
@@ -1117,17 +1134,14 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
|
|||
static int mount_subtree(struct autofs_point *ap, struct mapent *me, |
|||
const char *name, char *loc, char *options, void *ctxt) |
|||
{ |
|||
- struct mapent *mm;
|
|||
struct mapent *ro; |
|||
char *mm_root, *mm_base, *mm_key; |
|||
- const char *mnt_root;
|
|||
- unsigned int mm_root_len, mnt_root_len;
|
|||
+ unsigned int mm_root_len;
|
|||
int start, ret = 0, rv; |
|||
|
|||
rv = 0; |
|||
|
|||
- mm = me->multi;
|
|||
- mm_key = mm->key;
|
|||
+ mm_key = me->multi->key;
|
|||
|
|||
if (*mm_key == '/') { |
|||
mm_root = mm_key; |
|||
@@ -1141,20 +1155,26 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
} |
|||
mm_root_len = strlen(mm_root); |
|||
|
|||
- mnt_root = mm_root;
|
|||
- mnt_root_len = mm_root_len;
|
|||
-
|
|||
if (me == me->multi) { |
|||
+ char key[PATH_MAX + 1];
|
|||
+
|
|||
+ if (mm_root_len + 1 > PATH_MAX) {
|
|||
+ warn(ap->logopt, "path loo long");
|
|||
+ return 1;
|
|||
+ }
|
|||
+
|
|||
/* name = NULL */ |
|||
/* destination = mm_root */ |
|||
mm_base = "/"; |
|||
|
|||
+ strcpy(key, mm_root);
|
|||
+ strcat(key, mm_base);
|
|||
+
|
|||
/* Mount root offset if it exists */ |
|||
- ro = cache_lookup_offset(mm_base, mm_base, strlen(mm_root), &me->multi_list);
|
|||
+ ro = cache_lookup_distinct(me->mc, key);
|
|||
if (ro) { |
|||
- char *myoptions, *ro_loc, *tmp;
|
|||
+ char *myoptions, *ro_loc;
|
|||
int namelen = name ? strlen(name) : 0; |
|||
- const char *root;
|
|||
int ro_len; |
|||
|
|||
myoptions = NULL; |
|||
@@ -1172,13 +1192,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
if (ro_loc) |
|||
ro_len = strlen(ro_loc); |
|||
|
|||
- tmp = alloca(mnt_root_len + 2);
|
|||
- strcpy(tmp, mnt_root);
|
|||
- tmp[mnt_root_len] = '/';
|
|||
- tmp[mnt_root_len + 1] = '\0';
|
|||
- root = tmp;
|
|||
-
|
|||
- rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt);
|
|||
+ rv = sun_mount(ap, key, name, namelen, ro_loc, ro_len, myoptions, ctxt);
|
|||
|
|||
free(myoptions); |
|||
if (ro_loc) |
|||
@@ -1186,11 +1200,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
} |
|||
|
|||
if (ro && rv == 0) { |
|||
- ret = mount_multi_triggers(ap, me, mnt_root, start, mm_base);
|
|||
+ ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
|
|||
if (ret == -1) { |
|||
error(ap->logopt, MODPREFIX |
|||
"failed to mount offset triggers"); |
|||
- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
|
|||
+ cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
|
|||
return 1; |
|||
} |
|||
} else if (rv <= 0) { |
|||
@@ -1206,24 +1220,29 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
int loclen = strlen(loc); |
|||
int namelen = strlen(name); |
|||
|
|||
- mnt_root = name;
|
|||
-
|
|||
/* name = mm_root + mm_base */ |
|||
/* destination = mm_root + mm_base = name */ |
|||
mm_base = &me->key[start]; |
|||
|
|||
- rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt);
|
|||
+ rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt);
|
|||
if (rv == 0) { |
|||
- ret = mount_multi_triggers(ap, me->multi, mnt_root, start, mm_base);
|
|||
+ ret = mount_multi_triggers(ap, me->multi, name, start, mm_base);
|
|||
if (ret == -1) { |
|||
error(ap->logopt, MODPREFIX |
|||
"failed to mount offset triggers"); |
|||
- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
|
|||
+ cleanup_multi_triggers(ap, me, name, start, mm_base);
|
|||
return 1; |
|||
} |
|||
} else if (rv < 0) { |
|||
- char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
|
|||
+ char mm_root_base[PATH_MAX + 1];
|
|||
+ unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1;
|
|||
|
|||
+ if (mm_root_base_len > PATH_MAX) {
|
|||
+ warn(ap->logopt, MODPREFIX "path too long");
|
|||
+ cache_delete_offset_list(me->mc, name);
|
|||
+ return 1;
|
|||
+ }
|
|||
+
|
|||
strcpy(mm_root_base, mm_root); |
|||
strcat(mm_root_base, mm_base); |
|||
|
@ -1,290 +0,0 @@ |
|||
autofs-5.1.7 - eliminate clean_stale_multi_triggers() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Eliminate clean_stale_multi_triggers() by checking for stale offsets at |
|||
the time mount_subtree() is called. |
|||
|
|||
This should result in the same behaviour but eliminate an additional |
|||
seperate traversal of the offset list. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 |
|||
lib/mounts.c | 209 ++++++++++----------------------------------------- |
|||
modules/parse_sun.c | 10 -- |
|||
3 files changed, 43 insertions(+), 177 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5a3bedc1..b1ce7b69 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -12,6 +12,7 @@
|
|||
- remove redundant variables from mount_autofs_offset(). |
|||
- remove unused parameter form do_mount_autofs_offset(). |
|||
- refactor umount_multi_triggers(). |
|||
+- eliminate clean_stale_multi_triggers().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 5268ba5b..a9abbebf 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2601,10 +2601,44 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
|
|||
oe_base = oe->key + strlen(root); |
|||
left += do_umount_multi_triggers(ap, oe, root, oe_base); |
|||
|
|||
+ /*
|
|||
+ * If an offset that has an active mount has been removed
|
|||
+ * from the multi-mount we don't want to attempt to trigger
|
|||
+ * mounts for it. Obviously this is because it has been
|
|||
+ * removed, but less obvious is the potential strange
|
|||
+ * behaviour that can result if we do try and mount it
|
|||
+ * again after it's been expired. For example, if an NFS
|
|||
+ * file system is no longer exported and is later umounted
|
|||
+ * it can be mounted again without any error message but
|
|||
+ * shows as an empty directory. That's going to confuse
|
|||
+ * people for sure.
|
|||
+ *
|
|||
+ * If the mount cannot be umounted (the process is now
|
|||
+ * using a stale mount) the offset needs to be invalidated
|
|||
+ * so no further mounts will be attempted but the offset
|
|||
+ * cache entry must remain so expires can continue to
|
|||
+ * attempt to umount it. If the mount can be umounted and
|
|||
+ * the offset is removed, at least for NFS we will get
|
|||
+ * ESTALE errors when attempting list the directory.
|
|||
+ */
|
|||
if (oe->ioctlfd != -1 || |
|||
is_mounted(oe->key, MNTS_REAL)) { |
|||
- left++;
|
|||
- return left;
|
|||
+ if (umount_ent(ap, oe->key) &&
|
|||
+ is_mounted(oe->key, MNTS_REAL)) {
|
|||
+ debug(ap->logopt,
|
|||
+ "offset %s has active mount, invalidate",
|
|||
+ oe->key);
|
|||
+ /*
|
|||
+ * Ok, so we shouldn't modify the mapent but
|
|||
+ * mount requests are blocked at a point above
|
|||
+ * this and expire only uses the mapent key.
|
|||
+ */
|
|||
+ if (oe->mapent) {
|
|||
+ free(oe->mapent);
|
|||
+ oe->mapent = NULL;
|
|||
+ }
|
|||
+ return ++left;
|
|||
+ }
|
|||
} |
|||
|
|||
debug(ap->logopt, "umount offset %s", oe->key); |
|||
@@ -2666,6 +2700,11 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
oe = cache_lookup_distinct(me->mc, key); |
|||
if (!oe || !oe->mapent) |
|||
goto cont; |
|||
+ if (oe->age != me->multi->age) {
|
|||
+ /* Best effort */
|
|||
+ do_umount_offset(ap, oe, root);
|
|||
+ goto cont;
|
|||
+ }
|
|||
|
|||
mounted += do_mount_autofs_offset(ap, oe, root); |
|||
|
|||
@@ -2725,169 +2764,3 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
|
|||
return left; |
|||
} |
|||
-
|
|||
-int clean_stale_multi_triggers(struct autofs_point *ap,
|
|||
- struct mapent *me, char *top, const char *base)
|
|||
-{
|
|||
- char *root;
|
|||
- char mm_top[PATH_MAX + 1];
|
|||
- char path[PATH_MAX + 1];
|
|||
- char *offset;
|
|||
- struct mapent *oe;
|
|||
- struct list_head *mm_root, *pos;
|
|||
- const char o_root[] = "/";
|
|||
- const char *mm_base;
|
|||
- int left, start;
|
|||
- unsigned int root_len;
|
|||
- unsigned int mm_base_len;
|
|||
- time_t age;
|
|||
-
|
|||
- if (top)
|
|||
- root = top;
|
|||
- else {
|
|||
- if (!strchr(me->multi->key, '/'))
|
|||
- /* Indirect multi-mount root */
|
|||
- /* sprintf okay - if it's mounted, it's
|
|||
- * PATH_MAX or less bytes */
|
|||
- sprintf(mm_top, "%s/%s", ap->path, me->multi->key);
|
|||
- else
|
|||
- strcpy(mm_top, me->multi->key);
|
|||
- root = mm_top;
|
|||
- }
|
|||
-
|
|||
- left = 0;
|
|||
- start = strlen(root);
|
|||
-
|
|||
- mm_root = &me->multi->multi_list;
|
|||
-
|
|||
- if (!base)
|
|||
- mm_base = o_root;
|
|||
- else
|
|||
- mm_base = base;
|
|||
-
|
|||
- pos = NULL;
|
|||
- offset = path;
|
|||
- root_len = start;
|
|||
- mm_base_len = strlen(mm_base);
|
|||
- age = me->multi->age;
|
|||
-
|
|||
- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
|
|||
- char key[PATH_MAX + 1];
|
|||
- int key_len = root_len + strlen(offset);
|
|||
- char *oe_base;
|
|||
- int ret;
|
|||
-
|
|||
- if (mm_base_len > 1)
|
|||
- key_len += mm_base_len;
|
|||
-
|
|||
- if (key_len > PATH_MAX) {
|
|||
- warn(ap->logopt, "path loo long");
|
|||
- continue;
|
|||
- }
|
|||
-
|
|||
- strcpy(key, root);
|
|||
- if (mm_base_len > 1)
|
|||
- strcat(key, mm_base);
|
|||
- strcat(key, offset);
|
|||
-
|
|||
- oe = cache_lookup_distinct(me->mc, key);
|
|||
- /* root offset is a special case */
|
|||
- if (!oe || (strlen(oe->key) - start) == 1)
|
|||
- continue;
|
|||
-
|
|||
- /* Check for and umount stale subtree offsets */
|
|||
- oe_base = oe->key + strlen(root);
|
|||
- ret = clean_stale_multi_triggers(ap, oe, root, oe_base);
|
|||
- left += ret;
|
|||
- if (ret)
|
|||
- continue;
|
|||
-
|
|||
- if (oe->age == age)
|
|||
- continue;
|
|||
-
|
|||
- /*
|
|||
- * If an offset that has an active mount has been removed
|
|||
- * from the multi-mount we don't want to attempt to trigger
|
|||
- * mounts for it. Obviously this is because it has been
|
|||
- * removed, but less obvious is the potential strange
|
|||
- * behaviour that can result if we do try and mount it
|
|||
- * again after it's been expired. For example, if an NFS
|
|||
- * file system is no longer exported and is later umounted
|
|||
- * it can be mounted again without any error message but
|
|||
- * shows as an empty directory. That's going to confuse
|
|||
- * people for sure.
|
|||
- *
|
|||
- * If the mount cannot be umounted (the process is now
|
|||
- * using a stale mount) the offset needs to be invalidated
|
|||
- * so no further mounts will be attempted but the offset
|
|||
- * cache entry must remain so expires can continue to
|
|||
- * attempt to umount it. If the mount can be umounted and
|
|||
- * the offset is removed, at least for NFS we will get
|
|||
- * ESTALE errors when attempting list the directory.
|
|||
- */
|
|||
- if (oe->ioctlfd != -1 ||
|
|||
- is_mounted(oe->key, MNTS_REAL)) {
|
|||
- if (umount_ent(ap, oe->key) &&
|
|||
- is_mounted(oe->key, MNTS_REAL)) {
|
|||
- debug(ap->logopt,
|
|||
- "offset %s has active mount, invalidate",
|
|||
- oe->key);
|
|||
- if (oe->mapent) {
|
|||
- free(oe->mapent);
|
|||
- oe->mapent = NULL;
|
|||
- }
|
|||
- left++;
|
|||
- continue;
|
|||
- }
|
|||
- }
|
|||
-
|
|||
- debug(ap->logopt, "umount offset %s", oe->key);
|
|||
-
|
|||
- if (umount_autofs_offset(ap, oe)) {
|
|||
- warn(ap->logopt, "failed to umount offset %s", key);
|
|||
- left++;
|
|||
- } else {
|
|||
- struct stat st;
|
|||
-
|
|||
- /* Mount point not ours to delete ? */
|
|||
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) {
|
|||
- debug(ap->logopt, "delete offset key %s", key);
|
|||
- if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
|
|||
- error(ap->logopt,
|
|||
- "failed to delete offset key %s", key);
|
|||
- continue;
|
|||
- }
|
|||
-
|
|||
- /*
|
|||
- * An error due to partial directory removal is
|
|||
- * ok so only try and remount the offset if the
|
|||
- * actual mount point still exists.
|
|||
- */
|
|||
- ret = rmdir_path_offset(ap, oe);
|
|||
- if (ret == -1 && !stat(oe->key, &st)) {
|
|||
- ret = do_mount_autofs_offset(ap, oe, root);
|
|||
- if (ret) {
|
|||
- left++;
|
|||
- /* But we did origianlly create this */
|
|||
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
|
|||
- continue;
|
|||
- }
|
|||
- /*
|
|||
- * Fall through if the trigger can't be mounted
|
|||
- * again, since there is no offset there can't
|
|||
- * be any mount requests so remove the map
|
|||
- * entry from the cache. There's now a dead
|
|||
- * offset mount, but what else can we do ....
|
|||
- */
|
|||
- }
|
|||
-
|
|||
- debug(ap->logopt, "delete offset key %s", key);
|
|||
-
|
|||
- if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
|
|||
- error(ap->logopt,
|
|||
- "failed to delete offset key %s", key);
|
|||
- }
|
|||
- }
|
|||
-
|
|||
- return left;
|
|||
-}
|
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index f42af7b7..f4d5125c 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1176,7 +1176,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
|
|||
/* Mount root offset if it exists */ |
|||
ro = cache_lookup_distinct(me->mc, key); |
|||
- if (ro) {
|
|||
+ if (ro && ro->age == me->multi->age) {
|
|||
char *myoptions, *ro_loc; |
|||
int namelen = name ? strlen(name) : 0; |
|||
int ro_len; |
|||
@@ -1610,14 +1610,6 @@ dont_expand:
|
|||
free(myoptions); |
|||
} while (*p == '/' || (*p == '"' && *(p + 1) == '/')); |
|||
|
|||
- /*
|
|||
- * We've got the ordered list of multi-mount entries so go
|
|||
- * through and remove any stale entries if this is the top
|
|||
- * of the multi-mount and set the parent entry of each.
|
|||
- */
|
|||
- if (me == me->multi)
|
|||
- clean_stale_multi_triggers(ap, me, NULL, NULL);
|
|||
-
|
|||
rv = mount_subtree(ap, me, name, NULL, options, ctxt); |
|||
|
|||
cache_multi_unlock(me); |
@ -1,140 +0,0 @@ |
|||
autofs-5.1.7 - eliminate count_mounts() from expire_proc_indirect() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The count_mounts() function traverses the directory tree under a given |
|||
automount in order to count the number of mounts. |
|||
|
|||
If there are many directories (such as when there is a very large |
|||
number of offset trigger mounts) this can take a long time. |
|||
|
|||
Eliminate the call in expire_proc_indirect() by changing the expire |
|||
ioctl function to better use the expire return from the kernel. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 4 ++-- |
|||
daemon/indirect.c | 10 +++++----- |
|||
lib/dev-ioctl-lib.c | 21 +++++++++++++-------- |
|||
4 files changed, 21 insertions(+), 15 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index c5619d2e..0b78eb62 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -20,6 +20,7 @@
|
|||
- pass mapent_cache to update_offset_entry(). |
|||
- fix inconsistent locking in parse_mount(). |
|||
- remove unused mount offset list lock functions. |
|||
+- eliminate count_mounts() from expire_proc_indirect().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index c41c680f..311a98ba 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -884,7 +884,7 @@ cont:
|
|||
ioctlfd = me->ioctlfd; |
|||
|
|||
ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); |
|||
- if (ret) {
|
|||
+ if (ret == 1) {
|
|||
left++; |
|||
pthread_setcancelstate(cur_state, NULL); |
|||
continue; |
|||
@@ -910,7 +910,7 @@ cont:
|
|||
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); |
|||
ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); |
|||
- if (ret)
|
|||
+ if (ret == 1)
|
|||
left++; |
|||
pthread_setcancelstate(cur_state, NULL); |
|||
} |
|||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|||
index 65cfe4e3..b259ebdc 100644
|
|||
--- a/daemon/indirect.c
|
|||
+++ b/daemon/indirect.c
|
|||
@@ -358,7 +358,6 @@ void *expire_proc_indirect(void *arg)
|
|||
struct expire_args ec; |
|||
unsigned int how; |
|||
int offsets, submnts, count; |
|||
- int retries;
|
|||
int ioctlfd, cur_state; |
|||
int status, ret, left; |
|||
|
|||
@@ -496,7 +495,7 @@ void *expire_proc_indirect(void *arg)
|
|||
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); |
|||
ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); |
|||
- if (ret)
|
|||
+ if (ret == 1)
|
|||
left++; |
|||
pthread_setcancelstate(cur_state, NULL); |
|||
} |
|||
@@ -507,10 +506,11 @@ void *expire_proc_indirect(void *arg)
|
|||
* so we need to umount or unlink them here. |
|||
*/ |
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); |
|||
- retries = (count_mounts(ap, ap->path, ap->dev) + 1);
|
|||
- while (retries--) {
|
|||
+ while (1) {
|
|||
ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how); |
|||
- if (ret)
|
|||
+ if (ret != 0 && errno == EAGAIN)
|
|||
+ break;
|
|||
+ if (ret == 1)
|
|||
left++; |
|||
} |
|||
pthread_setcancelstate(cur_state, NULL); |
|||
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
|
|||
index 7040c3da..e7a1b42a 100644
|
|||
--- a/lib/dev-ioctl-lib.c
|
|||
+++ b/lib/dev-ioctl-lib.c
|
|||
@@ -650,6 +650,7 @@ static int expire(unsigned int logopt,
|
|||
{ |
|||
int ret, retries = EXPIRE_RETRIES; |
|||
unsigned int may_umount; |
|||
+ int save_errno = 0;
|
|||
|
|||
while (retries--) { |
|||
struct timespec tm = {0, 100000000}; |
|||
@@ -657,9 +658,11 @@ static int expire(unsigned int logopt,
|
|||
/* Ggenerate expire message for the mount. */ |
|||
ret = ioctl(fd, cmd, arg); |
|||
if (ret == -1) { |
|||
+ save_errno = errno;
|
|||
+
|
|||
/* Mount has gone away */ |
|||
if (errno == EBADF || errno == EINVAL) |
|||
- return 0;
|
|||
+ break;
|
|||
|
|||
/* |
|||
* Other than EAGAIN is an expire error so continue. |
|||
@@ -673,14 +676,16 @@ static int expire(unsigned int logopt,
|
|||
nanosleep(&tm, NULL); |
|||
} |
|||
|
|||
- may_umount = 0;
|
|||
- if (ctl.ops->askumount(logopt, ioctlfd, &may_umount))
|
|||
- return -1;
|
|||
-
|
|||
- if (!may_umount)
|
|||
- return 1;
|
|||
+ if (!ret || save_errno == EAGAIN) {
|
|||
+ may_umount = 0;
|
|||
+ if (!ctl.ops->askumount(logopt, ioctlfd, &may_umount)) {
|
|||
+ if (!may_umount)
|
|||
+ ret = 1;
|
|||
+ }
|
|||
+ }
|
|||
+ errno = save_errno;
|
|||
|
|||
- return 0;
|
|||
+ return ret;
|
|||
} |
|||
|
|||
static int dev_ioctl_expire(unsigned int logopt, |
@ -1,90 +0,0 @@ |
|||
autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Since we need to create the offset tree after adding the offset entries |
|||
to the mapent cache (from a list.h list) there's no need to lookup the |
|||
mapent in tree_mapent_add_node() and validate it. Just use it directly |
|||
when calling tree_mapent_add_node() and avoid a cache lookup on every |
|||
node addition. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/mounts.h | 2 +- |
|||
lib/mounts.c | 13 ++----------- |
|||
modules/parse_sun.c | 2 +- |
|||
4 files changed, 5 insertions(+), 13 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5a767360..81b6ce6a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -73,6 +73,7 @@
|
|||
- fix amd hosts mount expire. |
|||
- fix offset entries order. |
|||
- use mapent tree root for tree_mapent_add_node(). |
|||
+- eliminate redundant cache lookup in tree_mapent_add_node().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index f7768ce5..5a7a0b89 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
|
|||
void mnts_put_expire_list(struct list_head *mnts); |
|||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); |
|||
struct tree_node *tree_mapent_root(struct mapent *me); |
|||
-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
|
|||
+int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
|
|||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); |
|||
void tree_mapent_cleanup_offsets(struct mapent *oe); |
|||
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 9ec547ea..6b24a6c2 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree_node *n)
|
|||
} |
|||
|
|||
int tree_mapent_add_node(struct mapent_cache *mc, |
|||
- struct tree_node *root, const char *key)
|
|||
+ struct tree_node *root, struct mapent *me)
|
|||
{ |
|||
- unsigned int logopt = mc->ap->logopt;
|
|||
struct tree_node *n; |
|||
struct mapent *parent; |
|||
- struct mapent *me;
|
|||
-
|
|||
- me = cache_lookup_distinct(mc, key);
|
|||
- if (!me) {
|
|||
- error(logopt,
|
|||
- "failed to find key %s of multi-mount", key);
|
|||
- return 0;
|
|||
- }
|
|||
|
|||
n = tree_add_node(root, me); |
|||
if (!n) |
|||
@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_cache *mc,
|
|||
MAPENT_SET_ROOT(me, root) |
|||
|
|||
/* Set the subtree parent */ |
|||
- parent = cache_get_offset_parent(mc, key);
|
|||
+ parent = cache_get_offset_parent(mc, me->key);
|
|||
if (!parent) |
|||
MAPENT_SET_PARENT(me, root) |
|||
else |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index c75bcc8e..12844a30 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1546,7 +1546,7 @@ dont_expand:
|
|||
return 1; |
|||
} |
|||
list_for_each_entry_safe(oe, tmp, &offsets, work) { |
|||
- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
|
|||
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe))
|
|||
error(ap->logopt, "failed to add offset %s to tree", oe->key); |
|||
list_del_init(&oe->work); |
|||
} |
@ -1,216 +0,0 @@ |
|||
autofs-5.1.7 - eliminate some more alloca usage |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Quite a bit of the alloca(3) usage has been eliminated over time. |
|||
Use malloc(3) for some more cases that might need to allocate a largish |
|||
amount of storage. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/lookup_program.c | 11 ++++++++++- |
|||
modules/lookup_yp.c | 22 +++++++++++++++++++--- |
|||
modules/parse_sun.c | 18 ++++++++++++++---- |
|||
modules/replicated.c | 19 ++++++------------- |
|||
5 files changed, 50 insertions(+), 21 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 8d050552..2b7cfaa0 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -79,6 +79,7 @@
|
|||
- add missing description of null map option. |
|||
- fix nonstrict offset mount fail handling. |
|||
- fix concat_options() error handling. |
|||
+- eliminate some more alloca usage.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
|||
index 6cab52c8..028580e5 100644
|
|||
--- a/modules/lookup_program.c
|
|||
+++ b/modules/lookup_program.c
|
|||
@@ -636,7 +636,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
char *ent = NULL; |
|||
|
|||
if (me->mapent) { |
|||
- ent = alloca(strlen(me->mapent) + 1);
|
|||
+ ent = malloc(strlen(me->mapent) + 1);
|
|||
+ if (!ent) {
|
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
+ cache_unlock(mc);
|
|||
+ goto out_free;
|
|||
+ }
|
|||
strcpy(ent, me->mapent); |
|||
} |
|||
cache_unlock(mc); |
|||
@@ -644,6 +651,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
ap->entry->current = source; |
|||
ret = ctxt->parse->parse_mount(ap, name, |
|||
name_len, ent, ctxt->parse->context); |
|||
+ if (ent)
|
|||
+ free(ent);
|
|||
goto out_free; |
|||
} else { |
|||
if (IS_MM(me) && !IS_MM_ROOT(me)) { |
|||
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
|
|||
index 8bccb72f..d2a4b5a5 100644
|
|||
--- a/modules/lookup_yp.c
|
|||
+++ b/modules/lookup_yp.c
|
|||
@@ -254,7 +254,7 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
|
|||
|
|||
len = ypkeylen + 1 + vallen + 2; |
|||
|
|||
- buffer = alloca(len);
|
|||
+ buffer = malloc(len);
|
|||
if (!buffer) { |
|||
error(logopt, MODPREFIX "could not malloc parse buffer"); |
|||
return 0; |
|||
@@ -267,6 +267,8 @@ int yp_all_master_callback(int status, char *ypkey, int ypkeylen,
|
|||
|
|||
master_parse_entry(buffer, timeout, logging, age); |
|||
|
|||
+ free(buffer);
|
|||
+
|
|||
return 0; |
|||
} |
|||
|
|||
@@ -368,7 +370,12 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
|
|||
return 0; |
|||
} |
|||
|
|||
- mapent = alloca(vallen + 1);
|
|||
+ mapent = malloc(vallen + 1);
|
|||
+ if (!mapent) {
|
|||
+ error(logopt, MODPREFIX "could not malloc mapent buffer");
|
|||
+ free(key);
|
|||
+ return 0;
|
|||
+ }
|
|||
strncpy(mapent, val, vallen); |
|||
*(mapent + vallen) = '\0'; |
|||
|
|||
@@ -377,6 +384,7 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen,
|
|||
cache_unlock(mc); |
|||
|
|||
free(key); |
|||
+ free(mapent);
|
|||
|
|||
if (ret == CHE_FAIL) |
|||
return -1; |
|||
@@ -904,7 +912,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
} |
|||
if (me && (me->source == source || *me->key == '/')) { |
|||
mapent_len = strlen(me->mapent); |
|||
- mapent = alloca(mapent_len + 1);
|
|||
+ mapent = malloc(mapent_len + 1);
|
|||
+ if (!mapent) {
|
|||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
+ cache_unlock(mc);
|
|||
+ free(lkp_key);
|
|||
+ return NSS_STATUS_TRYAGAIN;
|
|||
+ }
|
|||
strcpy(mapent, me->mapent); |
|||
} |
|||
} |
|||
@@ -929,6 +944,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|||
|
|||
ret = ctxt->parse->parse_mount(ap, key, key_len, |
|||
mapent, ctxt->parse->context); |
|||
+ free(mapent);
|
|||
if (ret) { |
|||
/* Don't update negative cache when re-connecting */ |
|||
if (ap->flags & MOUNT_FLAG_REMOUNT) |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 9190165d..d9ac0c94 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -668,9 +668,16 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|||
} |
|||
} |
|||
|
|||
+ what = malloc(loclen + 1);
|
|||
+ if (!what) {
|
|||
+ char buf[MAX_ERR_BUF];
|
|||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
+ return 1;
|
|||
+ }
|
|||
+
|
|||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); |
|||
if (!strcmp(fstype, "nfs") || !strcmp(fstype, "nfs4")) { |
|||
- what = alloca(loclen + 1);
|
|||
memcpy(what, loc, loclen); |
|||
what[loclen] = '\0'; |
|||
|
|||
@@ -706,10 +713,10 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|||
rv = mount_nfs->mount_mount(ap, root, name, namelen, |
|||
what, fstype, options, mount_nfs->context); |
|||
} else { |
|||
- if (!loclen)
|
|||
+ if (!loclen) {
|
|||
+ free(what);
|
|||
what = NULL; |
|||
- else {
|
|||
- what = alloca(loclen + 1);
|
|||
+ } else {
|
|||
if (*loc == ':') { |
|||
loclen--; |
|||
memcpy(what, loc + 1, loclen); |
|||
@@ -728,6 +735,9 @@ static int sun_mount(struct autofs_point *ap, const char *root,
|
|||
/* Generic mount routine */ |
|||
rv = do_mount(ap, root, name, namelen, what, fstype, options); |
|||
} |
|||
+ if (what)
|
|||
+ free(what);
|
|||
+
|
|||
pthread_setcancelstate(cur_state, NULL); |
|||
|
|||
if (nonstrict && rv) |
|||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|||
index 03d4ba1e..ffaf519f 100644
|
|||
--- a/modules/replicated.c
|
|||
+++ b/modules/replicated.c
|
|||
@@ -1041,25 +1041,18 @@ done:
|
|||
return ret; |
|||
} |
|||
|
|||
-static int add_path(struct host *hosts, const char *path, int len)
|
|||
+static int add_path(struct host *hosts, const char *path)
|
|||
{ |
|||
struct host *this; |
|||
- char *tmp, *tmp2;
|
|||
-
|
|||
- tmp = alloca(len + 1);
|
|||
- if (!tmp)
|
|||
- return 0;
|
|||
-
|
|||
- strncpy(tmp, path, len);
|
|||
- tmp[len] = '\0';
|
|||
+ char *tmp;
|
|||
|
|||
this = hosts; |
|||
while (this) { |
|||
if (!this->path) { |
|||
- tmp2 = strdup(tmp);
|
|||
- if (!tmp2)
|
|||
+ tmp = strdup(path);
|
|||
+ if (!tmp)
|
|||
return 0; |
|||
- this->path = tmp2;
|
|||
+ this->path = tmp;
|
|||
} |
|||
this = this->next; |
|||
} |
|||
@@ -1188,7 +1181,7 @@ int parse_location(unsigned logopt, struct host **hosts,
|
|||
} |
|||
} |
|||
|
|||
- if (!add_path(*hosts, path, strlen(path))) {
|
|||
+ if (!add_path(*hosts, path)) {
|
|||
free_host_list(hosts); |
|||
free(str); |
|||
return 0; |
@ -1,128 +0,0 @@ |
|||
autofs-5.1.7 - eliminate some strlen calls in offset handling |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
There are a number of places where strlen() is used to re-calculate |
|||
the length of a string. Eliminate some of those by calculating the |
|||
length once and passing it to the functions that do the re-calculation. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 30 +++++++++++++++++------------- |
|||
2 files changed, 18 insertions(+), 13 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0b78eb62..cb709773 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -21,6 +21,7 @@
|
|||
- fix inconsistent locking in parse_mount(). |
|||
- remove unused mount offset list lock functions. |
|||
- eliminate count_mounts() from expire_proc_indirect(). |
|||
+- eliminate some strlen calls in offset handling.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 0fcd4087..04fe3d00 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2540,10 +2540,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
|
|||
return ret; |
|||
} |
|||
|
|||
-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
|
|||
+static int do_umount_offset(struct autofs_point *ap,
|
|||
+ struct mapent *oe, const char *root, int start);
|
|||
|
|||
static int do_umount_multi_triggers(struct autofs_point *ap, |
|||
- struct mapent *me, const char *root, const char *base)
|
|||
+ struct mapent *me, const char *root,
|
|||
+ int start, const char *base)
|
|||
{ |
|||
char path[PATH_MAX + 1]; |
|||
char *offset; |
|||
@@ -2551,12 +2553,11 @@ static int do_umount_multi_triggers(struct autofs_point *ap,
|
|||
struct list_head *mm_root, *pos; |
|||
const char o_root[] = "/"; |
|||
const char *mm_base; |
|||
- int left, start;
|
|||
+ int left;
|
|||
unsigned int root_len; |
|||
unsigned int mm_base_len; |
|||
|
|||
left = 0; |
|||
- start = strlen(root);
|
|||
|
|||
mm_root = &me->multi->multi_list; |
|||
|
|||
@@ -2592,13 +2593,14 @@ static int do_umount_multi_triggers(struct autofs_point *ap,
|
|||
if (!oe || (strlen(oe->key) - start) == 1) |
|||
continue; |
|||
|
|||
- left += do_umount_offset(ap, oe, root);
|
|||
+ left += do_umount_offset(ap, oe, root, start);
|
|||
} |
|||
|
|||
return left; |
|||
} |
|||
|
|||
-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
|
|||
+static int do_umount_offset(struct autofs_point *ap,
|
|||
+ struct mapent *oe, const char *root, int start)
|
|||
{ |
|||
char *oe_base; |
|||
int left = 0; |
|||
@@ -2607,8 +2609,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
|
|||
* Check for and umount subtree offsets resulting from |
|||
* nonstrict mount fail. |
|||
*/ |
|||
- oe_base = oe->key + strlen(root);
|
|||
- left += do_umount_multi_triggers(ap, oe, root, oe_base);
|
|||
+ oe_base = oe->key + start;
|
|||
+ left += do_umount_multi_triggers(ap, oe, root, start, oe_base);
|
|||
|
|||
/* |
|||
* If an offset that has an active mount has been removed |
|||
@@ -2712,7 +2714,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
goto cont; |
|||
if (oe->age != me->multi->age) { |
|||
/* Best effort */ |
|||
- do_umount_offset(ap, oe, root);
|
|||
+ do_umount_offset(ap, oe, root, start);
|
|||
goto cont; |
|||
} |
|||
|
|||
@@ -2726,7 +2728,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
|
|||
if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { |
|||
if (oe->ioctlfd != -1 || |
|||
is_mounted(oe->key, MNTS_REAL)) |
|||
- mount_multi_triggers(ap, oe, key, strlen(key), base);
|
|||
+ mount_multi_triggers(ap, oe, key, key_len, base);
|
|||
} |
|||
cont: |
|||
offset = cache_get_offset(base, |
|||
@@ -2738,9 +2740,11 @@ cont:
|
|||
|
|||
int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) |
|||
{ |
|||
- int left;
|
|||
+ int left, start;
|
|||
+
|
|||
+ start = strlen(root);
|
|||
|
|||
- left = do_umount_multi_triggers(ap, me, root, base);
|
|||
+ left = do_umount_multi_triggers(ap, me, root, start, base);
|
|||
|
|||
if (!left && me->multi == me) { |
|||
/* |
|||
@@ -2753,7 +2757,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
info(ap->logopt, "unmounting dir = %s", root); |
|||
if (umount_ent(ap, root) && |
|||
is_mounted(root, MNTS_REAL)) { |
|||
- if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0)
|
|||
+ if (mount_multi_triggers(ap, me, root, start, "/") < 0)
|
|||
warn(ap->logopt, |
|||
"failed to remount offset triggers"); |
|||
return ++left; |
@ -1,52 +0,0 @@ |
|||
autofs-5.1.7 - fix amd hosts mount expire |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
When swicthing to use the mnt_list to track mounts for expire, if the |
|||
amd hosts map entry name is for the host short name, the amd mount |
|||
entry for the short name gets removed. This causes a subsequent mounts |
|||
for host exports to fail. |
|||
|
|||
What should happen is the short name amd entry not be removed and a |
|||
mounted mount entry for the symlinked FQDN mount added so it expires. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_amd.c | 9 +++++---- |
|||
2 files changed, 6 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 698cc27a..94eb6a2c 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -70,6 +70,7 @@
|
|||
- fix dandling symlink creation if nis support is not available. |
|||
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. |
|||
- fix lookup_prune_one_cache() refactoring change. |
|||
+- fix amd hosts mount expire.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
|
|||
index 64c1ce63..163174cd 100644
|
|||
--- a/modules/parse_amd.c
|
|||
+++ b/modules/parse_amd.c
|
|||
@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
|||
if (!rv) { |
|||
/* |
|||
* If entry->path doesn't match the mnt->mp then |
|||
- * the mount point path has changed and a new
|
|||
- * mnt_list entry added for it, so remove the
|
|||
- * original.
|
|||
+ * it's a "host" map and the mount point path is
|
|||
+ * different to the lookup name. Add a new mnt_list
|
|||
+ * entry so that both the symlinked name and the
|
|||
+ * mount expire.
|
|||
*/ |
|||
if (strcmp(this->path, mnt->mp)) |
|||
- mnts_remove_amdmount(this->path);
|
|||
+ mnts_add_mount(ap, this->rhost, MNTS_INDIRECT|MNTS_MOUNTED);
|
|||
break; |
|||
} |
|||
/* Not mounted, remove the mnt_list entry from amdmount list */ |
@ -1,124 +0,0 @@ |
|||
autofs-5.1.7 - fix amd section mounts map reload |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Master map section mounts (amd format mounts) get umounted on reload. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
|||
2 files changed, 81 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ff44ac25..ddc07912 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -66,6 +66,7 @@
|
|||
- refactor lookup_prune_one_cache() a bit. |
|||
- cater for empty mounts list in mnts_get_expire_list(). |
|||
- add ext_mount_hash_mutex lock helpers. |
|||
+- fix amd section mounts map reload.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master.c b/daemon/master.c
|
|||
index 84743f80..f99359c5 100644
|
|||
--- a/daemon/master.c
|
|||
+++ b/daemon/master.c
|
|||
@@ -882,6 +882,83 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int f
|
|||
return master; |
|||
} |
|||
|
|||
+static void master_update_amd_mount_section_mount(struct master *master,
|
|||
+ const char *path, time_t age)
|
|||
+{
|
|||
+ unsigned int m_logopt = master->logopt;
|
|||
+ struct master_mapent *entry;
|
|||
+ struct map_source *source;
|
|||
+ unsigned int loglevel;
|
|||
+ unsigned int logopt;
|
|||
+ unsigned int flags;
|
|||
+ time_t timeout;
|
|||
+ char *map;
|
|||
+ char *opts;
|
|||
+
|
|||
+ entry = master_find_mapent(master, path);
|
|||
+ if (!entry)
|
|||
+ return;
|
|||
+
|
|||
+ map = conf_amd_get_map_name(path);
|
|||
+ if (!map)
|
|||
+ return;
|
|||
+
|
|||
+ /* amd top level mounts have only one map */
|
|||
+ source = entry->maps;
|
|||
+ if (strcmp(source->name, map) != 0) {
|
|||
+ struct map_source *new;
|
|||
+ char *type;
|
|||
+ char *argv[2];
|
|||
+
|
|||
+ type = conf_amd_get_map_type(path);
|
|||
+ argv[0] = map;
|
|||
+ argv[1] = NULL;
|
|||
+
|
|||
+ new = master_add_map_source(entry, type, "amd",
|
|||
+ age, 1, (const char **) argv);
|
|||
+ if (!new) {
|
|||
+ error(m_logopt,
|
|||
+ "failed to add source for amd section mount %s",
|
|||
+ path);
|
|||
+ if (type)
|
|||
+ free(type);
|
|||
+ goto out;
|
|||
+ }
|
|||
+ master_free_map_source(source, 0);
|
|||
+ entry->maps = new;
|
|||
+ source = new;
|
|||
+ if (type)
|
|||
+ free(type);
|
|||
+ }
|
|||
+
|
|||
+ loglevel = conf_amd_get_log_options();
|
|||
+ logopt = m_logopt;
|
|||
+ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO)
|
|||
+ logopt = LOGOPT_DEBUG;
|
|||
+ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR)
|
|||
+ logopt = LOGOPT_VERBOSE;
|
|||
+
|
|||
+ flags = conf_amd_get_flags(path);
|
|||
+ if (flags & CONF_BROWSABLE_DIRS)
|
|||
+ entry->ap->flags |= MOUNT_FLAG_GHOST;
|
|||
+
|
|||
+ opts = conf_amd_get_map_options(path);
|
|||
+ if (opts) {
|
|||
+ if (strstr(opts, "cache:=all"))
|
|||
+ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL;
|
|||
+ free(opts);
|
|||
+ }
|
|||
+
|
|||
+ entry->ap->logopt = logopt;
|
|||
+
|
|||
+ timeout = conf_amd_get_dismount_interval(path);
|
|||
+ set_exp_timeout(entry->ap, source, timeout);
|
|||
+ source->master_line = 0;
|
|||
+ entry->age = age;
|
|||
+out:
|
|||
+ free(map);
|
|||
+}
|
|||
+
|
|||
static void master_add_amd_mount_section_mounts(struct master *master, time_t age) |
|||
{ |
|||
unsigned int m_logopt = master->logopt; |
|||
@@ -916,8 +993,10 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag
|
|||
* master map it's not a duplicate, don't issue |
|||
* an error message. |
|||
*/ |
|||
- if (ret == 1)
|
|||
+ if (ret == 1) {
|
|||
+ master_update_amd_mount_section_mount(master, path, age);
|
|||
goto next; |
|||
+ }
|
|||
info(m_logopt, |
|||
"amd section mount path conflict, %s ignored", |
|||
path); |
@ -1,40 +0,0 @@ |
|||
autofs-5.1.7 - fix arg not used in error print |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: extra_argument: This argument was not used by the format |
|||
string: "key". |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 4 +--- |
|||
2 files changed, 2 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f11aa1c7..1d56c96f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -60,6 +60,7 @@
|
|||
- dont try umount after stat() ENOENT fail. |
|||
- remove redundant assignment in master_add_amd_mount_section_mounts(). |
|||
- fix dead code in mnts_add_mount(). |
|||
+- fix arg not used in error print.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 018b9c80..883e3743 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_cache *mc,
|
|||
} |
|||
|
|||
if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { |
|||
- error(logopt,
|
|||
- "failed to find multi-mount root of offset tree",
|
|||
- key);
|
|||
+ error(logopt, "key %s is not multi-mount root", root);
|
|||
return 0; |
|||
} |
|||
tree = MAPENT_ROOT(base); |
@ -1,124 +0,0 @@ |
|||
autofs-5.1.7 - fix concat_options() error handling |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
There's a possibility of a memory leak in the mount options processing |
|||
when calling concat_options() in parse_mount() of the Sun format map |
|||
entry parsing. |
|||
|
|||
There's also a case in do_init() of the Sun map format parsing where |
|||
a previously freed value is used in a logging statement without being |
|||
set to MULL. |
|||
|
|||
So ensure concat_options() always frees it's arguments so that the |
|||
handling can be consistent in all places. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 24 +++++++++++------------- |
|||
2 files changed, 12 insertions(+), 13 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ecffa933..8d050552 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -78,6 +78,7 @@
|
|||
- fix direct mount deadlock. |
|||
- add missing description of null map option. |
|||
- fix nonstrict offset mount fail handling. |
|||
+- fix concat_options() error handling.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index cdf515c6..9190165d 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -380,7 +380,8 @@ static int do_init(int argc, const char *const *argv, struct parse_context *ctxt
|
|||
if (!tmp) { |
|||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
logerr(MODPREFIX "concat_options: %s", estr); |
|||
- free(gbl_options);
|
|||
+ /* freed in concat_options */
|
|||
+ ctxt->optstr = NULL;
|
|||
} else |
|||
ctxt->optstr = tmp; |
|||
} else { |
|||
@@ -492,12 +493,16 @@ static char *concat_options(char *left, char *right)
|
|||
char *ret; |
|||
|
|||
if (left == NULL || *left == '\0') { |
|||
+ if (!right || *right == '\0')
|
|||
+ return NULL;
|
|||
ret = strdup(right); |
|||
free(right); |
|||
return ret; |
|||
} |
|||
|
|||
if (right == NULL || *right == '\0') { |
|||
+ if (left == NULL || *left == '\0')
|
|||
+ return NULL;
|
|||
ret = strdup(left); |
|||
free(left); |
|||
return ret; |
|||
@@ -508,6 +513,8 @@ static char *concat_options(char *left, char *right)
|
|||
if (ret == NULL) { |
|||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
logerr(MODPREFIX "malloc: %s", estr); |
|||
+ free(left);
|
|||
+ free(right);
|
|||
return NULL; |
|||
} |
|||
|
|||
@@ -989,14 +996,13 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
|
|||
if (newopt && strstr(newopt, myoptions)) { |
|||
free(myoptions); |
|||
myoptions = newopt; |
|||
- } else {
|
|||
+ } else if (newopt) {
|
|||
tmp = concat_options(myoptions, newopt); |
|||
if (!tmp) { |
|||
char *estr; |
|||
estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(logopt, MODPREFIX |
|||
"concat_options: %s", estr); |
|||
- free(myoptions);
|
|||
return 0; |
|||
} |
|||
myoptions = tmp; |
|||
@@ -1358,16 +1364,12 @@ dont_expand:
|
|||
if (mnt_options && noptions && strstr(noptions, mnt_options)) { |
|||
free(mnt_options); |
|||
mnt_options = noptions; |
|||
- } else {
|
|||
+ } else if (noptions) {
|
|||
tmp = concat_options(mnt_options, noptions); |
|||
if (!tmp) { |
|||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(ap->logopt, |
|||
MODPREFIX "concat_options: %s", estr); |
|||
- if (noptions)
|
|||
- free(noptions);
|
|||
- if (mnt_options)
|
|||
- free(mnt_options);
|
|||
free(options); |
|||
free(pmapent); |
|||
return 1; |
|||
@@ -1387,15 +1389,11 @@ dont_expand:
|
|||
if (options && mnt_options && strstr(mnt_options, options)) { |
|||
free(options); |
|||
options = mnt_options; |
|||
- } else {
|
|||
+ } else if (mnt_options) {
|
|||
tmp = concat_options(options, mnt_options); |
|||
if (!tmp) { |
|||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(ap->logopt, MODPREFIX "concat_options: %s", estr); |
|||
- if (options)
|
|||
- free(options);
|
|||
- if (mnt_options)
|
|||
- free(mnt_options);
|
|||
free(pmapent); |
|||
return 1; |
|||
} |
@ -1,39 +0,0 @@ |
|||
autofs-5.1.7 - fix dandling symlink creation if nis support is not available |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If NIS support is not available a dangling symlink is created pointing |
|||
from lookup_nis.so to (a non-existent) lookup_yp.so. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/Makefile | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ddc07912..06bf24b8 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -67,6 +67,7 @@
|
|||
- cater for empty mounts list in mnts_get_expire_list(). |
|||
- add ext_mount_hash_mutex lock helpers. |
|||
- fix amd section mounts map reload. |
|||
+- fix dandling symlink creation if nis support is not available.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/Makefile b/modules/Makefile
|
|||
index 91dc20ab..6908da06 100644
|
|||
--- a/modules/Makefile
|
|||
+++ b/modules/Makefile
|
|||
@@ -77,7 +77,9 @@ install: all
|
|||
install -c $(MODS) -m 755 $(INSTALLROOT)$(autofslibdir) |
|||
-rm -f $(INSTALLROOT)$(autofslibdir)/mount_smbfs.so |
|||
ln -fs lookup_file.so $(INSTALLROOT)$(autofslibdir)/lookup_files.so |
|||
+ifeq ($(YPCLNT), 1)
|
|||
ln -fs lookup_yp.so $(INSTALLROOT)$(autofslibdir)/lookup_nis.so |
|||
+endif
|
|||
ifeq ($(LDAP), 1) |
|||
ln -fs lookup_ldap.so $(INSTALLROOT)$(autofslibdir)/lookup_ldaps.so |
|||
endif |
@ -1,55 +0,0 @@ |
|||
autofs-5.1.7 - fix dead code in mnts_add_mount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);". |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 8 ++------ |
|||
2 files changed, 3 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f95b1aa6..f11aa1c7 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -59,6 +59,7 @@
|
|||
- fix flags check in umount_multi(). |
|||
- dont try umount after stat() ENOENT fail. |
|||
- remove redundant assignment in master_add_amd_mount_section_mounts(). |
|||
+- fix dead code in mnts_add_mount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index ef69cec1..018b9c80 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
|||
if (*name == '/') { |
|||
mp = strdup(name); |
|||
if (!mp) |
|||
- goto fail;
|
|||
+ return NULL;
|
|||
} else { |
|||
int len = ap->len + strlen(name) + 2; |
|||
|
|||
mp = malloc(len); |
|||
if (!mp) |
|||
- goto fail;
|
|||
+ return NULL;
|
|||
strcpy(mp, ap->path); |
|||
strcat(mp, "/"); |
|||
strcat(mp, name); |
|||
@@ -1228,10 +1228,6 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
|||
free(mp); |
|||
|
|||
return this; |
|||
-fail:
|
|||
- if (mp)
|
|||
- free(mp);
|
|||
- return NULL;
|
|||
} |
|||
|
|||
void mnts_remove_mount(const char *mp, unsigned int flags) |
@ -1,135 +0,0 @@ |
|||
autofs-5.1.7 - fix direct mount deadlock |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
When umounting direct mounts at exit or when umounting mounts no |
|||
longer in the map on re-load a deadlock can occur. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 22 +++++++++++++++++++++- |
|||
daemon/state.c | 14 +++++++++----- |
|||
3 files changed, 31 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9e341e06..b29d2ed8 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -75,6 +75,7 @@
|
|||
- use mapent tree root for tree_mapent_add_node(). |
|||
- eliminate redundant cache lookup in tree_mapent_add_node(). |
|||
- fix hosts map offset order. |
|||
+- fix direct mount deadlock.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 3bd714e6..d37dd676 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg)
|
|||
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) |
|||
{ |
|||
struct ioctl_ops *ops = get_ioctl_ops(); |
|||
+ struct mapent_cache *mc = me->mc;
|
|||
char buf[MAX_ERR_BUF]; |
|||
int ioctlfd = -1, rv, left, retries; |
|||
+ char key[PATH_MAX + 1];
|
|||
+ struct mapent *tmp;
|
|||
int opened = 0; |
|||
|
|||
- left = umount_multi(ap, me->key, 0);
|
|||
+ if (me->len > PATH_MAX) {
|
|||
+ error(ap->logopt, "path too long");
|
|||
+ return 1;
|
|||
+ }
|
|||
+ strcpy(key, me->key);
|
|||
+
|
|||
+ cache_unlock(mc);
|
|||
+ left = umount_multi(ap, key, 0);
|
|||
+ cache_readlock(mc);
|
|||
+ tmp = cache_lookup_distinct(mc, key);
|
|||
+ if (tmp != me) {
|
|||
+ error(ap->logopt, "key %s no longer in mapent cache", key);
|
|||
+ return -1;
|
|||
+ }
|
|||
if (left) { |
|||
warn(ap->logopt, "could not unmount %d dirs under %s", |
|||
left, me->key); |
|||
@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_point *ap)
|
|||
mc = map->mc; |
|||
pthread_cleanup_push(cache_lock_cleanup, mc); |
|||
cache_readlock(mc); |
|||
+restart:
|
|||
me = cache_enumerate(mc, NULL); |
|||
while (me) { |
|||
int error; |
|||
@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_point *ap)
|
|||
* failed umount. |
|||
*/ |
|||
error = do_umount_autofs_direct(ap, me); |
|||
+ /* cache became invalid, restart */
|
|||
+ if (error == -1)
|
|||
+ goto restart;
|
|||
if (!error) |
|||
goto done; |
|||
|
|||
diff --git a/daemon/state.c b/daemon/state.c
|
|||
index 091210a5..5156bb21 100644
|
|||
--- a/daemon/state.c
|
|||
+++ b/daemon/state.c
|
|||
@@ -324,11 +324,12 @@ static void do_readmap_cleanup(void *arg)
|
|||
return; |
|||
} |
|||
|
|||
-static void do_readmap_mount(struct autofs_point *ap,
|
|||
+static int do_readmap_mount(struct autofs_point *ap,
|
|||
struct map_source *map, struct mapent *me, time_t now) |
|||
{ |
|||
struct mapent_cache *nc; |
|||
struct mapent *ne, *nested, *valid; |
|||
+ int ret = 0;
|
|||
|
|||
nc = ap->entry->master->nc; |
|||
|
|||
@@ -387,7 +388,7 @@ static void do_readmap_mount(struct autofs_point *ap,
|
|||
cache_unlock(vmc); |
|||
error(ap->logopt, |
|||
"failed to find expected existing valid map entry"); |
|||
- return;
|
|||
+ return ret;
|
|||
} |
|||
/* Take over the mount if there is one */ |
|||
valid->ioctlfd = me->ioctlfd; |
|||
@@ -406,14 +407,14 @@ static void do_readmap_mount(struct autofs_point *ap,
|
|||
ap->exp_runfreq = runfreq; |
|||
} |
|||
} else if (!is_mounted(me->key, MNTS_REAL)) |
|||
- do_umount_autofs_direct(ap, me);
|
|||
+ ret = do_umount_autofs_direct(ap, me);
|
|||
else |
|||
debug(ap->logopt, |
|||
"%s is mounted", me->key); |
|||
} else |
|||
do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map)); |
|||
|
|||
- return;
|
|||
+ return ret;
|
|||
} |
|||
|
|||
static void *do_readmap(void *arg) |
|||
@@ -480,9 +481,12 @@ static void *do_readmap(void *arg)
|
|||
mc = map->mc; |
|||
pthread_cleanup_push(cache_lock_cleanup, mc); |
|||
cache_readlock(mc); |
|||
+restart:
|
|||
me = cache_enumerate(mc, NULL); |
|||
while (me) { |
|||
- do_readmap_mount(ap, map, me, now);
|
|||
+ int ret = do_readmap_mount(ap, map, me, now);
|
|||
+ if (ret == -1)
|
|||
+ goto restart;
|
|||
me = cache_enumerate(mc, me); |
|||
} |
|||
lookup_prune_one_cache(ap, map->mc, now); |
@ -1,39 +0,0 @@ |
|||
autofs-5.1.7 - fix double free in parse_mapent() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: |
|||
in parse_mapent(): double_free: Calling "free" frees pointer "newopt" |
|||
which has already been freed. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 2 -- |
|||
2 files changed, 1 insertion(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ff3d88eb..81461978 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -62,6 +62,7 @@
|
|||
- fix dead code in mnts_add_mount(). |
|||
- fix arg not used in error print. |
|||
- fix missing lock release in mount_subtree(). |
|||
+- fix double free in parse_mapent().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 5d15f892..03a63290 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -974,8 +974,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
|
|||
estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(logopt, MODPREFIX |
|||
"concat_options: %s", estr); |
|||
- if (newopt)
|
|||
- free(newopt);
|
|||
free(myoptions); |
|||
return 0; |
|||
} |
@ -1,37 +0,0 @@ |
|||
autofs-5.1.7 - fix double unlock in parse_mount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it |
|||
is unlocked. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 1 - |
|||
2 files changed, 1 insertion(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2e3b9fd7..224f58d6 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -54,6 +54,7 @@
|
|||
- remove redundant if check. |
|||
- fix possible memory leak in master_parse(). |
|||
- fix possible memory leak in mnts_add_amdmount(). |
|||
+- fix double unlock in parse_mount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index a81d4028..05f53fc2 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1526,7 +1526,6 @@ dont_expand:
|
|||
if (!loc) { |
|||
free(options); |
|||
free(pmapent); |
|||
- cache_unlock(mc);
|
|||
warn(ap->logopt, MODPREFIX "out of memory"); |
|||
return 1; |
|||
} |
@ -1,38 +0,0 @@ |
|||
autofs-5.1.7 - fix flags check in umount_multi() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: operator_confusion: "ap->flags | 1" is always 1/true |
|||
regardless of the values of its operand. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9e385ba9..7add6c55 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -56,6 +56,7 @@
|
|||
- fix possible memory leak in mnts_add_amdmount(). |
|||
- fix double unlock in parse_mount(). |
|||
- add length check in umount_subtree_mounts(). |
|||
+- fix flags check in umount_multi().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 70506d83..23235a7d 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -662,7 +662,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
|||
/* Check if the autofs mount has browse mode enabled. |
|||
* If so re-create the directory entry. |
|||
*/ |
|||
- if (ap->flags | MOUNT_FLAG_GHOST) {
|
|||
+ if (ap->flags & MOUNT_FLAG_GHOST) {
|
|||
int ret; |
|||
|
|||
/* If the browse directory create fails log an |
@ -1,300 +0,0 @@ |
|||
autofs-5.1.7 - fix hosts map offset order |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Map entry offset paths need to be in shortest to longest order but |
|||
exports from a server could come in any order. If there are a large |
|||
number of exports this can result in a lot of overhead when adding |
|||
the offset to the ordered list used to mount the offset during parsing |
|||
since the path length of exports can vary a lot. |
|||
|
|||
So leverage the tree implemention to sort the export offsets into |
|||
shortest to longest order as we go when constructing the mapent from |
|||
the exports list. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/automount.h | 2 + |
|||
include/mounts.h | 8 ++++++ |
|||
include/rpc_subs.h | 3 ++ |
|||
lib/mounts.c | 57 ++++++++++++++++++++++++++++++++++++++-- |
|||
modules/lookup_hosts.c | 69 ++++++++++++++++++++++++++++++++++++++---------- |
|||
6 files changed, 123 insertions(+), 17 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 81b6ce6a..9e341e06 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -74,6 +74,7 @@
|
|||
- fix offset entries order. |
|||
- use mapent tree root for tree_mapent_add_node(). |
|||
- eliminate redundant cache lookup in tree_mapent_add_node(). |
|||
+- fix hosts map offset order.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index d279744d..947ed16d 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -31,9 +31,9 @@
|
|||
#include "master.h" |
|||
#include "macros.h" |
|||
#include "log.h" |
|||
+#include "mounts.h"
|
|||
#include "rpc_subs.h" |
|||
#include "parse_subs.h" |
|||
-#include "mounts.h"
|
|||
#include "dev-ioctl-lib.h" |
|||
#include "parse_amd.h" |
|||
|
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index 5a7a0b89..ddb7e4c5 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -52,6 +52,7 @@ extern const unsigned int t_direct;
|
|||
extern const unsigned int t_offset; |
|||
|
|||
struct mnt_list; |
|||
+struct exportinfo;
|
|||
struct mapent; |
|||
|
|||
struct tree_ops; |
|||
@@ -66,6 +67,9 @@ struct tree_node {
|
|||
#define MNT_LIST(n) (container_of(n, struct mnt_list, node)) |
|||
#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) |
|||
|
|||
+#define EXPORTINFO(n) (container_of(n, struct exportinfo, node))
|
|||
+#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node)
|
|||
+
|
|||
#define MAPENT(n) (container_of(n, struct mapent, node)) |
|||
#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node) |
|||
#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root) |
|||
@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsig
|
|||
void mnts_remove_mount(const char *mp, unsigned int flags); |
|||
struct mnt_list *get_mnt_list(const char *path, int include); |
|||
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); |
|||
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr);
|
|||
+void tree_free(struct tree_node *root);
|
|||
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); |
|||
void mnts_put_expire_list(struct list_head *mnts); |
|||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); |
|||
+struct tree_node *tree_host_root(struct exportinfo *exp);
|
|||
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp);
|
|||
struct tree_node *tree_mapent_root(struct mapent *me); |
|||
int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); |
|||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); |
|||
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
|
|||
index 080f19d9..debf2df0 100644
|
|||
--- a/include/rpc_subs.h
|
|||
+++ b/include/rpc_subs.h
|
|||
@@ -23,6 +23,8 @@
|
|||
#include <linux/nfs2.h> |
|||
#include <linux/nfs3.h> |
|||
|
|||
+#include "automount.h"
|
|||
+
|
|||
#define NFS4_VERSION 4 |
|||
|
|||
/* rpc helper subs */ |
|||
@@ -57,6 +59,7 @@ struct exportinfo {
|
|||
char *dir; |
|||
struct hostinfo *hosts; |
|||
struct exportinfo *next; |
|||
+ struct tree_node node;
|
|||
}; |
|||
|
|||
struct conn_info { |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 6b24a6c2..5a4602e3 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = {
|
|||
}; |
|||
static struct tree_ops *tree_mnt_ops = &mnt_ops; |
|||
|
|||
+static struct tree_node *tree_host_new(void *ptr);
|
|||
+static int tree_host_cmp(struct tree_node *n, void *ptr);
|
|||
+static void tree_host_free(struct tree_node *n);
|
|||
+
|
|||
+static struct tree_ops host_ops = {
|
|||
+ .new = tree_host_new,
|
|||
+ .cmp = tree_host_cmp,
|
|||
+ .free = tree_host_free,
|
|||
+};
|
|||
+static struct tree_ops *tree_host_ops = &host_ops;
|
|||
+
|
|||
static struct tree_node *tree_mapent_new(void *ptr); |
|||
static int tree_mapent_cmp(struct tree_node *n, void *ptr); |
|||
static void tree_mapent_free(struct tree_node *n); |
|||
@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(struct tree_node *root, void *ptr)
|
|||
return NULL; |
|||
} |
|||
|
|||
-static void tree_free(struct tree_node *root)
|
|||
+void tree_free(struct tree_node *root)
|
|||
{ |
|||
struct tree_ops *ops = root->ops; |
|||
|
|||
@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node *root)
|
|||
ops->free(root); |
|||
} |
|||
|
|||
-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
|||
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
|||
{ |
|||
int ret; |
|||
|
|||
@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_head *mnts)
|
|||
mnts_hash_mutex_unlock(); |
|||
} |
|||
|
|||
+struct tree_node *tree_host_root(struct exportinfo *exp)
|
|||
+{
|
|||
+ return tree_root(tree_host_ops, exp);
|
|||
+}
|
|||
+
|
|||
+static struct tree_node *tree_host_new(void *ptr)
|
|||
+{
|
|||
+ struct tree_node *n = EXPORT_NODE(ptr);
|
|||
+
|
|||
+ n->ops = tree_host_ops;
|
|||
+ n->left = NULL;
|
|||
+ n->right = NULL;
|
|||
+
|
|||
+ return n;
|
|||
+}
|
|||
+
|
|||
+static int tree_host_cmp(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct exportinfo *n_exp = EXPORTINFO(n);
|
|||
+ size_t n_exp_len = strlen(n_exp->dir);
|
|||
+ struct exportinfo *exp = ptr;
|
|||
+ size_t exp_len = strlen(exp->dir);
|
|||
+ int eq;
|
|||
+
|
|||
+ eq = strcmp(exp->dir, n_exp->dir);
|
|||
+ if (!eq)
|
|||
+ return 0;
|
|||
+ return (exp_len < n_exp_len) ? -1 : 1;
|
|||
+}
|
|||
+
|
|||
+static void tree_host_free(struct tree_node *n)
|
|||
+{
|
|||
+ n->ops = NULL;
|
|||
+ n->left = NULL;
|
|||
+ n->right = NULL;
|
|||
+}
|
|||
+
|
|||
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp)
|
|||
+{
|
|||
+ return tree_add_node(root, exp);
|
|||
+}
|
|||
+
|
|||
struct tree_node *tree_mapent_root(struct mapent *me) |
|||
{ |
|||
return tree_root(tree_mapent_ops, me); |
|||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|||
index 24edf00c..26c224f6 100644
|
|||
--- a/modules/lookup_hosts.c
|
|||
+++ b/modules/lookup_hosts.c
|
|||
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|||
return NSS_STATUS_UNKNOWN; |
|||
} |
|||
|
|||
+struct work_info {
|
|||
+ char *mapent;
|
|||
+ const char *host;
|
|||
+ int pos;
|
|||
+};
|
|||
+
|
|||
+static int tree_host_work(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct exportinfo *exp = EXPORTINFO(n);
|
|||
+ struct work_info *wi = ptr;
|
|||
+ int len;
|
|||
+
|
|||
+ if (!wi->pos)
|
|||
+ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"",
|
|||
+ exp->dir, wi->host, exp->dir);
|
|||
+ else
|
|||
+ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"",
|
|||
+ exp->dir, wi->host, exp->dir);
|
|||
+ wi->pos += len;
|
|||
+
|
|||
+ return 1;
|
|||
+}
|
|||
+
|
|||
static char *get_exports(struct autofs_point *ap, const char *host) |
|||
{ |
|||
char buf[MAX_ERR_BUF]; |
|||
char *mapent; |
|||
struct exportinfo *exp, *this; |
|||
+ struct tree_node *tree = NULL;
|
|||
+ struct work_info wi;
|
|||
size_t hostlen = strlen(host); |
|||
size_t mapent_len; |
|||
- int len, pos;
|
|||
|
|||
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); |
|||
|
|||
@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
this = exp; |
|||
mapent_len = 0; |
|||
while (this) { |
|||
+ struct tree_node *n;
|
|||
+
|
|||
mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; |
|||
+
|
|||
+ if (!tree) {
|
|||
+ tree = tree_host_root(this);
|
|||
+ if (!tree) {
|
|||
+ error(ap->logopt, "failed to create exports tree root");
|
|||
+ rpc_exports_free(exp);
|
|||
+ return NULL;
|
|||
+ }
|
|||
+ goto next;
|
|||
+ }
|
|||
+
|
|||
+ n = tree_host_add_node(tree, this);
|
|||
+ if (!n) {
|
|||
+ error(ap->logopt, "failed to add exports tree node");
|
|||
+ tree_free(tree);
|
|||
+ rpc_exports_free(exp);
|
|||
+ return NULL;
|
|||
+ }
|
|||
+next:
|
|||
this = this->next; |
|||
} |
|||
|
|||
@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_point *ap, const char *host)
|
|||
} |
|||
*mapent = 0; |
|||
|
|||
- pos = 0;
|
|||
- this = exp;
|
|||
- if (this) {
|
|||
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
|
|||
- this->dir, host, this->dir);
|
|||
- pos += len;
|
|||
- this = this->next;
|
|||
- }
|
|||
+ wi.mapent = mapent;
|
|||
+ wi.host = host;
|
|||
+ wi.pos = 0;
|
|||
|
|||
- while (this) {
|
|||
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
|
|||
- this->dir, host, this->dir);
|
|||
- pos += len;
|
|||
- this = this->next;
|
|||
+ if (!tree) {
|
|||
+ free(mapent);
|
|||
+ mapent = NULL;
|
|||
+ } else {
|
|||
+ tree_traverse_inorder(tree, tree_host_work, &wi);
|
|||
+ tree_free(tree);
|
|||
} |
|||
rpc_exports_free(exp); |
|||
|
@ -1,251 +0,0 @@ |
|||
autofs-5.1.7 - fix inconsistent locking in parse_mount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Some map entry cache locking inconsistencies have crept in. |
|||
|
|||
In parse_mount() of the sun format parser the cache read lock is too |
|||
heavily used and has too broad a scope. This has lead to some operations |
|||
that should hold the write lock being called with only the read lock. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 9 ++++++++- |
|||
modules/parse_sun.c | 53 ++++++++++++++++++++++++++++++++------------------- |
|||
3 files changed, 42 insertions(+), 21 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index c60a9ed3..d25b19c8 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -18,6 +18,7 @@
|
|||
- fix inconsistent locking in umount_subtree_mounts(). |
|||
- fix return from umount_subtree_mounts() on offset list delete. |
|||
- pass mapent_cache to update_offset_entry(). |
|||
+- fix inconsistent locking in parse_mount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 5ebfe5fd..0fcd4087 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2491,6 +2491,12 @@ static int do_mount_autofs_offset(struct autofs_point *ap,
|
|||
else { |
|||
debug(ap->logopt, "ignoring \"nohide\" trigger %s", |
|||
oe->key); |
|||
+ /*
|
|||
+ * Ok, so we shouldn't modify the mapent but
|
|||
+ * mount requests are blocked at a point above
|
|||
+ * this and expire only uses the mapent key or
|
|||
+ * holds the cache write lock.
|
|||
+ */
|
|||
free(oe->mapent); |
|||
oe->mapent = NULL; |
|||
} |
|||
@@ -2634,7 +2640,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
|
|||
/* |
|||
* Ok, so we shouldn't modify the mapent but |
|||
* mount requests are blocked at a point above |
|||
- * this and expire only uses the mapent key.
|
|||
+ * this and expire only uses the mapent key or
|
|||
+ * holds the cache write lock.
|
|||
*/ |
|||
if (oe->mapent) { |
|||
free(oe->mapent); |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 95251bee..a6630a76 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -851,10 +851,12 @@ update_offset_entry(struct autofs_point *ap,
|
|||
strcpy(m_mapent, loc); |
|||
} |
|||
|
|||
+ cache_writelock(mc);
|
|||
ret = cache_update_offset(mc, name, m_key, m_mapent, age); |
|||
|
|||
if (!cache_set_offset_parent(mc, m_key)) |
|||
error(ap->logopt, "failed to set offset parent"); |
|||
+ cache_unlock(mc);
|
|||
|
|||
if (ret == CHE_DUPLICATE) { |
|||
warn(ap->logopt, MODPREFIX |
|||
@@ -1128,14 +1130,22 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
|
|||
return; |
|||
} |
|||
|
|||
-static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
+static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
const char *name, char *loc, char *options, void *ctxt) |
|||
{ |
|||
+ struct mapent *me;
|
|||
struct mapent *ro; |
|||
char *mm_root, *mm_base, *mm_key; |
|||
unsigned int mm_root_len; |
|||
int start, ret = 0, rv; |
|||
|
|||
+ cache_readlock(mc);
|
|||
+ me = cache_lookup_distinct(mc, name);
|
|||
+ if (!me) {
|
|||
+ cache_unlock(mc);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
rv = 0; |
|||
|
|||
mm_key = me->multi->key; |
|||
@@ -1180,9 +1190,12 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
rv = parse_mapent(ro->mapent, |
|||
options, &myoptions, &ro_loc, ap->logopt); |
|||
if (!rv) { |
|||
+ cache_unlock(mc);
|
|||
warn(ap->logopt, |
|||
MODPREFIX "failed to parse root offset"); |
|||
- cache_delete_offset_list(me->mc, name);
|
|||
+ cache_writelock(mc);
|
|||
+ cache_delete_offset_list(mc, name);
|
|||
+ cache_unlock(mc);
|
|||
return 1; |
|||
} |
|||
ro_len = 0; |
|||
@@ -1199,9 +1212,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
if ((ro && rv == 0) || rv <= 0) { |
|||
ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); |
|||
if (ret == -1) { |
|||
+ cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
|
|||
+ cache_unlock(mc);
|
|||
error(ap->logopt, MODPREFIX |
|||
"failed to mount offset triggers"); |
|||
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
|
|||
return 1; |
|||
} |
|||
} |
|||
@@ -1217,9 +1231,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
if (rv == 0) { |
|||
ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); |
|||
if (ret == -1) { |
|||
+ cleanup_multi_triggers(ap, me, name, start, mm_base);
|
|||
+ cache_unlock(mc);
|
|||
error(ap->logopt, MODPREFIX |
|||
"failed to mount offset triggers"); |
|||
- cleanup_multi_triggers(ap, me, name, start, mm_base);
|
|||
return 1; |
|||
} |
|||
} else if (rv < 0) { |
|||
@@ -1227,8 +1242,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; |
|||
|
|||
if (mm_root_base_len > PATH_MAX) { |
|||
+ cache_unlock(mc);
|
|||
warn(ap->logopt, MODPREFIX "path too long"); |
|||
- cache_delete_offset_list(me->mc, name);
|
|||
+ cache_writelock(mc);
|
|||
+ cache_delete_offset_list(mc, name);
|
|||
+ cache_unlock(mc);
|
|||
return 1; |
|||
} |
|||
|
|||
@@ -1237,13 +1255,15 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
|
|||
|
|||
ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base); |
|||
if (ret == -1) { |
|||
+ cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
|
|||
+ cache_unlock(mc);
|
|||
error(ap->logopt, MODPREFIX |
|||
"failed to mount offset triggers"); |
|||
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
|
|||
return 1; |
|||
} |
|||
} |
|||
} |
|||
+ cache_unlock(mc);
|
|||
|
|||
/* Mount for base of tree failed */ |
|||
if (rv > 0) |
|||
@@ -1484,7 +1504,6 @@ dont_expand:
|
|||
return 1; |
|||
} |
|||
|
|||
- cache_multi_writelock(me);
|
|||
/* So we know we're the multi-mount root */ |
|||
if (!me->multi) |
|||
me->multi = me; |
|||
@@ -1509,14 +1528,13 @@ dont_expand:
|
|||
if (source->flags & MAP_FLAG_FORMAT_AMD) { |
|||
free(options); |
|||
free(pmapent); |
|||
- cache_multi_unlock(me);
|
|||
cache_unlock(mc); |
|||
pthread_setcancelstate(cur_state, NULL); |
|||
return 0; |
|||
} |
|||
} |
|||
-
|
|||
age = me->age; |
|||
+ cache_unlock(mc);
|
|||
|
|||
/* It's a multi-mount; deal with it */ |
|||
do { |
|||
@@ -1537,8 +1555,8 @@ dont_expand:
|
|||
|
|||
if (!path) { |
|||
warn(ap->logopt, MODPREFIX "null path or out of memory"); |
|||
+ cache_writelock(mc);
|
|||
cache_delete_offset_list(mc, name); |
|||
- cache_multi_unlock(me);
|
|||
cache_unlock(mc); |
|||
free(options); |
|||
free(pmapent); |
|||
@@ -1554,8 +1572,8 @@ dont_expand:
|
|||
|
|||
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); |
|||
if (!l) { |
|||
+ cache_writelock(mc);
|
|||
cache_delete_offset_list(mc, name); |
|||
- cache_multi_unlock(me);
|
|||
cache_unlock(mc); |
|||
free(path); |
|||
free(options); |
|||
@@ -1573,8 +1591,8 @@ dont_expand:
|
|||
|
|||
if (status != CHE_OK) { |
|||
warn(ap->logopt, MODPREFIX "error adding multi-mount"); |
|||
+ cache_writelock(mc);
|
|||
cache_delete_offset_list(mc, name); |
|||
- cache_multi_unlock(me);
|
|||
cache_unlock(mc); |
|||
free(path); |
|||
free(options); |
|||
@@ -1592,10 +1610,7 @@ dont_expand:
|
|||
free(myoptions); |
|||
} while (*p == '/' || (*p == '"' && *(p + 1) == '/')); |
|||
|
|||
- rv = mount_subtree(ap, me, name, NULL, options, ctxt);
|
|||
-
|
|||
- cache_multi_unlock(me);
|
|||
- cache_unlock(mc);
|
|||
+ rv = mount_subtree(ap, mc, name, NULL, options, ctxt);
|
|||
|
|||
free(options); |
|||
free(pmapent); |
|||
@@ -1616,6 +1631,7 @@ dont_expand:
|
|||
cache_readlock(mc); |
|||
if (*name == '/' && |
|||
(me = cache_lookup_distinct(mc, name)) && me->multi) { |
|||
+ cache_unlock(mc);
|
|||
loc = strdup(p); |
|||
if (!loc) { |
|||
free(options); |
|||
@@ -1624,10 +1640,7 @@ dont_expand:
|
|||
warn(ap->logopt, MODPREFIX "out of memory"); |
|||
return 1; |
|||
} |
|||
- cache_multi_writelock(me);
|
|||
- rv = mount_subtree(ap, me, name, loc, options, ctxt);
|
|||
- cache_multi_unlock(me);
|
|||
- cache_unlock(mc);
|
|||
+ rv = mount_subtree(ap, mc, name, loc, options, ctxt);
|
|||
free(loc); |
|||
free(options); |
|||
free(pmapent); |
@ -1,135 +0,0 @@ |
|||
autofs-5.1.7 - fix inconsistent locking in umount_subtree_mounts() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Some map entry cache locking inconsistencies have crept in. |
|||
|
|||
In umount_subtree_mounts() the cache write lock should be held when |
|||
deleting multi-mount cache entries. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 42 ++++++++++++++++++++++++++++++------------ |
|||
lib/mounts.c | 8 -------- |
|||
3 files changed, 31 insertions(+), 20 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 1dded118..64e619ec 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -15,6 +15,7 @@
|
|||
- eliminate clean_stale_multi_triggers(). |
|||
- simplify mount_subtree() mount check. |
|||
- fix mnts_get_expire_list() expire list construction. |
|||
+- fix inconsistent locking in umount_subtree_mounts().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 7fa92877..93bd8556 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -527,8 +527,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
struct mapent_cache *mc; |
|||
struct mapent *me; |
|||
unsigned int is_mm_root = 0; |
|||
+ int cur_state;
|
|||
int left; |
|||
|
|||
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|||
+
|
|||
me = lookup_source_mapent(ap, path, LKP_DISTINCT); |
|||
if (!me) { |
|||
char *ind_key; |
|||
@@ -548,11 +551,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
left = 0; |
|||
|
|||
if (me && me->multi) { |
|||
- char root[PATH_MAX];
|
|||
+ char root[PATH_MAX + 1];
|
|||
+ char key[PATH_MAX + 1];
|
|||
+ struct mapent *tmp;
|
|||
+ int status;
|
|||
char *base; |
|||
- int cur_state;
|
|||
-
|
|||
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|||
|
|||
if (!strchr(me->multi->key, '/')) |
|||
/* Indirect multi-mount root */ |
|||
@@ -567,25 +570,40 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
else |
|||
base = me->key + strlen(root); |
|||
|
|||
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|||
- /* Lock the closest parent nesting point for umount */
|
|||
- cache_multi_writelock(me->parent);
|
|||
- if (umount_multi_triggers(ap, me, root, base)) {
|
|||
+ left = umount_multi_triggers(ap, me, root, base);
|
|||
+ if (left) {
|
|||
warn(ap->logopt, |
|||
"some offset mounts still present under %s", path); |
|||
+ }
|
|||
+
|
|||
+ strcpy(key, me->key);
|
|||
+
|
|||
+ cache_unlock(mc);
|
|||
+ cache_writelock(mc);
|
|||
+ tmp = cache_lookup_distinct(mc, key);
|
|||
+ /* mapent went away while we waited? */
|
|||
+ if (tmp != me) {
|
|||
+ cache_unlock(mc);
|
|||
+ pthread_setcancelstate(cur_state, NULL);
|
|||
+ return 0;
|
|||
+ }
|
|||
+
|
|||
+ if (!left && is_mm_root) {
|
|||
+ status = cache_delete_offset_list(mc, me->key);
|
|||
+ if (status != CHE_OK)
|
|||
+ warn(ap->logopt, "couldn't delete offset list");
|
|||
left++; |
|||
} |
|||
- cache_multi_unlock(me->parent);
|
|||
+
|
|||
if (ap->entry->maps && |
|||
(ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD)) |
|||
cache_pop_mapent(me); |
|||
- pthread_setcancelstate(cur_state, NULL);
|
|||
- pthread_cleanup_pop(0);
|
|||
} |
|||
-
|
|||
if (me) |
|||
cache_unlock(mc); |
|||
|
|||
+ pthread_setcancelstate(cur_state, NULL);
|
|||
+
|
|||
if (left || is_autofs_fs) |
|||
return left; |
|||
|
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 87813b16..5ebfe5fd 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -2736,9 +2736,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
left = do_umount_multi_triggers(ap, me, root, base); |
|||
|
|||
if (!left && me->multi == me) { |
|||
- struct mapent_cache *mc = me->mc;
|
|||
- int status;
|
|||
-
|
|||
/* |
|||
* Special case. |
|||
* If we can't umount the root container then we can't |
|||
@@ -2756,11 +2753,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
|
|||
} |
|||
} |
|||
|
|||
- /* We're done - clean out the offsets */
|
|||
- status = cache_delete_offset_list(mc, me->key);
|
|||
- if (status != CHE_OK)
|
|||
- warn(ap->logopt, "couldn't delete offset list");
|
|||
-
|
|||
/* check for mounted mount entry and remove it if found */ |
|||
mnts_remove_mount(root, MNTS_MOUNTED); |
|||
} |
@ -1,44 +0,0 @@ |
|||
autofs-5.1.7 - fix incorrect print format specifiers in get_pkt() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 4 ++-- |
|||
2 files changed, 3 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 680dbbd7..0dac7318 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -82,6 +82,7 @@
|
|||
- eliminate some more alloca usage. |
|||
- use default stack size for threads. |
|||
- fix use of possibly NULL var in lookup_program.c:match_key(). |
|||
+- fix incorrect print format specifiers in get_pkt().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index d7432350..45e0833f 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -1116,7 +1116,7 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt)
|
|||
estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(ap->logopt, |
|||
"read error on state pipe, " |
|||
- "read %u, error %s",
|
|||
+ "read %lu, error %s",
|
|||
read, estr); |
|||
st_mutex_unlock(); |
|||
continue; |
|||
@@ -1134,7 +1134,7 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt)
|
|||
estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(ap->logopt, |
|||
"read error on request pipe, " |
|||
- "read %u, expected %u error %s",
|
|||
+ "read %lu, expected %lu error %s",
|
|||
read, kpkt_len, estr); |
|||
} |
|||
return read; |
@ -1,64 +0,0 @@ |
|||
autofs-5.1.7 - fix is mounted check on non existent path |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
When checking if a path is a mount point the case of a non-existent path |
|||
was not being handled. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/dev-ioctl-lib.c | 3 +++ |
|||
lib/mounts.c | 12 +++++++++++- |
|||
3 files changed, 15 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 484bd866..e55fd66a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -6,6 +6,7 @@
|
|||
- fix mnts_remove_amdmount() uses wrong list. |
|||
- Fix option for master read wait. |
|||
- eliminate cache_lookup_offset() usage. |
|||
+- fix is mounted check on non existent path.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
|
|||
index e8519236..7040c3da 100644
|
|||
--- a/lib/dev-ioctl-lib.c
|
|||
+++ b/lib/dev-ioctl-lib.c
|
|||
@@ -759,6 +759,9 @@ static int dev_ioctl_ismountpoint(unsigned int logopt,
|
|||
int save_errno = errno; |
|||
free_dev_ioctl_path(param); |
|||
errno = save_errno; |
|||
+ /* Path doesn't exist */
|
|||
+ if (errno == ENOENT)
|
|||
+ return 0;
|
|||
return -1; |
|||
} |
|||
|
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 42e8ef07..fe931b20 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1649,8 +1649,18 @@ static int table_is_mounted(const char *mp, unsigned int type)
|
|||
struct mntent mnt_wrk; |
|||
char buf[PATH_MAX * 3]; |
|||
size_t mp_len = strlen(mp); |
|||
+ struct stat st;
|
|||
FILE *tab; |
|||
- int ret = 0;
|
|||
+ int ret;
|
|||
+
|
|||
+ ret = stat(mp, &st);
|
|||
+ if (ret == -1) {
|
|||
+ if (errno == ENOENT) {
|
|||
+ /* Path does not exist */
|
|||
+ return 0;
|
|||
+ }
|
|||
+ ret = 0;
|
|||
+ }
|
|||
|
|||
if (!mp || !mp_len || mp_len >= PATH_MAX) |
|||
return 0; |
@ -1,60 +0,0 @@ |
|||
autofs-5.1.7 - fix lookup_prune_one_cache() refactoring change |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Commit 256963d6b (autofs-5.1.7 - refactor lookup_prune_one_cache() a bit) |
|||
changed the position of the getting the next enumeration map entry but |
|||
failed to update a couple of other locations that assume the next map |
|||
entry has been set. Under certain fairly common conditions this leads |
|||
to an infinite loop. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/lookup.c | 5 ++++- |
|||
2 files changed, 5 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 51e7767e..698cc27a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -69,6 +69,7 @@
|
|||
- fix amd section mounts map reload. |
|||
- fix dandling symlink creation if nis support is not available. |
|||
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. |
|||
+- fix lookup_prune_one_cache() refactoring change.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|||
index 3e9722e4..0b281f83 100644
|
|||
--- a/daemon/lookup.c
|
|||
+++ b/daemon/lookup.c
|
|||
@@ -1379,6 +1379,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
if (!key || strchr(key, '*')) { |
|||
if (key) |
|||
free(key); |
|||
+ me = cache_enumerate(mc, me);
|
|||
continue; |
|||
} |
|||
|
|||
@@ -1386,6 +1387,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
if (!path) { |
|||
warn(ap->logopt, "can't malloc storage for path"); |
|||
free(key); |
|||
+ me = cache_enumerate(mc, me);
|
|||
continue; |
|||
} |
|||
|
|||
@@ -1413,9 +1415,10 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
} |
|||
if (!valid && |
|||
is_mounted(path, MNTS_REAL)) { |
|||
- debug(ap->logopt, "prune posponed, %s mounted", path);
|
|||
+ debug(ap->logopt, "prune postponed, %s mounted", path);
|
|||
free(key); |
|||
free(path); |
|||
+ me = cache_enumerate(mc, me);
|
|||
continue; |
|||
} |
|||
if (valid) |
@ -1,36 +0,0 @@ |
|||
autofs-5.1.7 - fix missing lock release in mount_subtree() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Covarity: missing_unlock: Returning without unlocking "mc->rwlock". |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 1 + |
|||
2 files changed, 2 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 1d56c96f..ff3d88eb 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -61,6 +61,7 @@
|
|||
- remove redundant assignment in master_add_amd_mount_section_mounts(). |
|||
- fix dead code in mnts_add_mount(). |
|||
- fix arg not used in error print. |
|||
+- fix missing lock release in mount_subtree().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 05f53fc2..5d15f892 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1105,6 +1105,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); |
|||
if (!len) { |
|||
warn(ap->logopt, "path loo long"); |
|||
+ cache_unlock(mc);
|
|||
return 1; |
|||
} |
|||
key[len] = '/'; |
@ -1,40 +0,0 @@ |
|||
autofs-5.1.7 - fix mnts_get_expire_list() expire list construction |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The mnts_get_expire_list() function is supposed to return an ordered |
|||
list of expire candidates but it is not checking the mounted status |
|||
of list entries and is returning a larger list than is needed. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 3 +++ |
|||
2 files changed, 4 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f5c5641a..1dded118 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -14,6 +14,7 @@
|
|||
- refactor umount_multi_triggers(). |
|||
- eliminate clean_stale_multi_triggers(). |
|||
- simplify mount_subtree() mount check. |
|||
+- fix mnts_get_expire_list() expire list construction.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index a9abbebf..87813b16 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1364,6 +1364,9 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
|||
list_for_each_entry(mnt, &ap->mounts, mount) { |
|||
struct node *n; |
|||
|
|||
+ if (!(mnt->flags & MNTS_MOUNTED))
|
|||
+ continue;
|
|||
+
|
|||
__mnts_get_mount(mnt); |
|||
|
|||
if (!tree) { |
@ -1,38 +0,0 @@ |
|||
autofs-5.1.7 - fix mnts_remove_amdmount() uses wrong list |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Function mnts_remove_amdmount() uses the wrong list when removing an |
|||
amd mount. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index d613e5ca..fe49740e 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -3,6 +3,7 @@
|
|||
- remove mount.x and rpcgen dependencies. |
|||
- dont use realloc in host exports list processing. |
|||
- use sprintf() when constructing hosts mapent. |
|||
+- fix mnts_remove_amdmount() uses wrong list.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index dbeb77b5..ccbd52e0 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1124,7 +1124,7 @@ void mnts_remove_amdmount(const char *mp)
|
|||
if (!(this && this->flags & MNTS_AMD_MOUNT)) |
|||
goto done; |
|||
this->flags &= ~MNTS_AMD_MOUNT; |
|||
- list_del_init(&this->submount);
|
|||
+ list_del_init(&this->amdmount);
|
|||
if (this->ext_mp) { |
|||
free(this->ext_mp); |
|||
this->ext_mp = NULL; |
@ -1,67 +0,0 @@ |
|||
autofs-5.1.7 - fix mount_fullpath() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
mount_fullpath() incorrecly fills fullpath with the contents of root |
|||
when name[0] == '/'. The cases root[last] == '/' and name[0] == '/' |
|||
need to be handled seperately. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 4 +++- |
|||
modules/parse_amd.c | 6 ++++-- |
|||
3 files changed, 8 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 390028ac..e2fd532c 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -36,6 +36,7 @@
|
|||
- add tree_mapent_add_node(). |
|||
- add tree_mapent_delete_offsets(). |
|||
- add tree_mapent_traverse_subtree(). |
|||
+- fix mount_fullpath().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index fded4c09..497c28c9 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -371,8 +371,10 @@ int mount_fullpath(char *fullpath, size_t max_len,
|
|||
/* Root offset of multi-mount or direct or offset mount. |
|||
* Direct or offset mount, name (or root) is absolute path. |
|||
*/ |
|||
- if (root[last] == '/' || *name == '/')
|
|||
+ if (root[last] == '/')
|
|||
len = snprintf(fullpath, max_len, "%s", root); |
|||
+ else if (*name == '/')
|
|||
+ len = snprintf(fullpath, max_len, "%s", name);
|
|||
else |
|||
len = snprintf(fullpath, max_len, "%s/%s", root, name); |
|||
|
|||
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
|
|||
index 5a9079d6..64c1ce63 100644
|
|||
--- a/modules/parse_amd.c
|
|||
+++ b/modules/parse_amd.c
|
|||
@@ -1177,7 +1177,8 @@ static int do_generic_mount(struct autofs_point *ap, const char *name,
|
|||
* the automount filesystem. |
|||
*/ |
|||
if (!is_mounted(entry->fs, MNTS_REAL)) { |
|||
- ret = do_mount(ap, entry->fs, "/", 1,
|
|||
+ ret = do_mount(ap, entry->fs,
|
|||
+ entry->fs, strlen(entry->fs),
|
|||
target, entry->type, opts); |
|||
if (ret) |
|||
goto out; |
|||
@@ -1227,7 +1228,8 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name,
|
|||
mount_nfs->context); |
|||
} else { |
|||
if (!is_mounted(entry->fs, MNTS_REAL)) { |
|||
- ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1,
|
|||
+ ret = mount_nfs->mount_mount(ap, entry->fs,
|
|||
+ entry->fs, strlen(entry->fs),
|
|||
target, entry->type, opts, |
|||
mount_nfs->context); |
|||
if (ret) |
@ -1,60 +0,0 @@ |
|||
autofs-5.1.7 - fix nonstrict offset mount fail handling |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If a triggered offset mount fails automount is not handling nonstrict |
|||
mount failure correctly. |
|||
|
|||
The nonstrict mount failure handling needs to convert an offset mount |
|||
failure to a success if the offset subtree below the failed mount is not |
|||
empty otherwise it must return the failure. The previous implementation |
|||
used -1 to indicate the subtree was empty and that was used to detect |
|||
when the mount should fail instead of converting the fail to a success. |
|||
|
|||
Make the new implementation do the same. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 2 +- |
|||
modules/parse_sun.c | 2 +- |
|||
3 files changed, 3 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f5f0da76..ecffa933 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -77,6 +77,7 @@
|
|||
- fix hosts map offset order. |
|||
- fix direct mount deadlock. |
|||
- add missing description of null map option. |
|||
+- fix nonstrict offset mount fail handling.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 5a4602e3..4c866885 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work
|
|||
{ |
|||
struct traverse_subtree_context *ctxt = ptr; |
|||
struct mapent *oe = MAPENT(n); |
|||
- int ret = 1;
|
|||
+ int ret = -1;
|
|||
|
|||
if (n->left) { |
|||
ret = tree_mapent_traverse_subtree(n->left, work, ctxt); |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 12844a30..cdf515c6 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
* offsets to be mounted. |
|||
*/ |
|||
rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); |
|||
- if (rv == 0) {
|
|||
+ if (rv <= 0) {
|
|||
ret = tree_mapent_mount_offsets(me, 1); |
|||
if (!ret) { |
|||
tree_mapent_cleanup_offsets(me); |
@ -1,207 +0,0 @@ |
|||
autofs-5.1.7 - fix offset entries order |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
While it's rare it's possible that a mapent entry might not have |
|||
it's offsets in shortest to longest path order. |
|||
|
|||
If this happens adding an entry to the mapent tree can result in |
|||
an incorrect tree topology that doesn't work. That's because adding |
|||
tree entries ensures that nodes in a sub-tree are placed below the |
|||
containing node so the containing node must be present for that to |
|||
work. This topology is critical to the performance of map entries |
|||
that have a very large number of offsets such as an NFS server with |
|||
many exports. |
|||
|
|||
There's no other choice but make a traversal after the offset entries |
|||
have all been added to create the mapent tree. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/automount.h | 1 + |
|||
lib/cache.c | 1 + |
|||
modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++---------- |
|||
4 files changed, 62 insertions(+), 15 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 94eb6a2c..7b360f52 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -71,6 +71,7 @@
|
|||
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. |
|||
- fix lookup_prune_one_cache() refactoring change. |
|||
- fix amd hosts mount expire. |
|||
+- fix offset entries order.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index 51a0bf0e..d279744d 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -169,6 +169,7 @@ struct mapent {
|
|||
/* Parent nesting point within multi-mount */ |
|||
struct tree_node *mm_parent; |
|||
struct tree_node node; |
|||
+ struct list_head work;
|
|||
char *key; |
|||
size_t len; |
|||
char *mapent; |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index ef761739..66dda5d9 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
me->mm_parent = NULL; |
|||
INIT_TREE_NODE(&me->node); |
|||
INIT_LIST_HEAD(&me->ino_index); |
|||
+ INIT_LIST_HEAD(&me->work);
|
|||
me->ioctlfd = -1; |
|||
me->dev = (dev_t) -1; |
|||
me->ino = (ino_t) -1; |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 03a63290..b206a326 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -789,14 +789,15 @@ static int check_is_multi(const char *mapent)
|
|||
|
|||
static int |
|||
update_offset_entry(struct autofs_point *ap, |
|||
- struct mapent_cache *mc, const char *name,
|
|||
- const char *m_root, int m_root_len,
|
|||
+ struct mapent_cache *mc, struct list_head *offsets,
|
|||
+ const char *name, const char *m_root, int m_root_len,
|
|||
const char *m_offset, const char *myoptions, |
|||
const char *loc, time_t age) |
|||
{ |
|||
char m_key[PATH_MAX + 1]; |
|||
char m_mapent[MAPENT_MAX_LEN + 1]; |
|||
int o_len, m_key_len, m_options_len, m_mapent_len; |
|||
+ struct mapent *me;
|
|||
int ret; |
|||
|
|||
memset(m_mapent, 0, MAPENT_MAX_LEN + 1); |
|||
@@ -862,8 +863,29 @@ update_offset_entry(struct autofs_point *ap,
|
|||
cache_writelock(mc); |
|||
ret = cache_update_offset(mc, name, m_key, m_mapent, age); |
|||
|
|||
- if (!tree_mapent_add_node(mc, name, m_key))
|
|||
- error(ap->logopt, "failed to add offset %s to tree", m_key);
|
|||
+ me = cache_lookup_distinct(mc, m_key);
|
|||
+ if (me && list_empty(&me->work)) {
|
|||
+ struct list_head *last;
|
|||
+
|
|||
+ /* Offset entries really need to be in shortest to
|
|||
+ * longest path order. If not and the list of offsets
|
|||
+ * is large there will be a performace hit.
|
|||
+ */
|
|||
+ list_for_each_prev(last, offsets) {
|
|||
+ struct mapent *this;
|
|||
+
|
|||
+ this = list_entry(last, struct mapent, work);
|
|||
+ if (me->len >= this->len) {
|
|||
+ if (last->next == offsets)
|
|||
+ list_add_tail(&me->work, offsets);
|
|||
+ else
|
|||
+ list_add_tail(&me->work, last);
|
|||
+ break;
|
|||
+ }
|
|||
+ }
|
|||
+ if (list_empty(&me->work))
|
|||
+ list_add(&me->work, offsets);
|
|||
+ }
|
|||
cache_unlock(mc); |
|||
|
|||
if (ret == CHE_DUPLICATE) { |
|||
@@ -1209,6 +1231,25 @@ static char *do_expandsunent(const char *src, const char *key,
|
|||
return mapent; |
|||
} |
|||
|
|||
+static void cleanup_offset_entries(struct autofs_point *ap,
|
|||
+ struct mapent_cache *mc,
|
|||
+ struct list_head *offsets)
|
|||
+{
|
|||
+ struct mapent *me, *tmp;
|
|||
+ int ret;
|
|||
+
|
|||
+ if (list_empty(offsets))
|
|||
+ return;
|
|||
+ cache_writelock(mc);
|
|||
+ list_for_each_entry_safe(me, tmp, offsets, work) {
|
|||
+ list_del(&me->work);
|
|||
+ ret = cache_delete(mc, me->key);
|
|||
+ if (ret != CHE_OK)
|
|||
+ crit(ap->logopt, "failed to delete offset %s", me->key);
|
|||
+ }
|
|||
+ cache_unlock(mc);
|
|||
+}
|
|||
+
|
|||
/* |
|||
* syntax is: |
|||
* [-options] location [location] ... |
|||
@@ -1228,7 +1269,8 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
|||
char buf[MAX_ERR_BUF]; |
|||
struct map_source *source; |
|||
struct mapent_cache *mc; |
|||
- struct mapent *me;
|
|||
+ struct mapent *me, *oe, *tmp;
|
|||
+ LIST_HEAD(offsets);
|
|||
char *pmapent, *options; |
|||
const char *p; |
|||
int mapent_len, rv = 0; |
|||
@@ -1444,9 +1486,7 @@ dont_expand:
|
|||
|
|||
if (!m_offset) { |
|||
warn(ap->logopt, MODPREFIX "null path or out of memory"); |
|||
- cache_writelock(mc);
|
|||
- tree_mapent_delete_offsets(mc, name);
|
|||
- cache_unlock(mc);
|
|||
+ cleanup_offset_entries(ap, mc, &offsets);
|
|||
free(options); |
|||
free(pmapent); |
|||
pthread_setcancelstate(cur_state, NULL); |
|||
@@ -1461,9 +1501,7 @@ dont_expand:
|
|||
|
|||
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); |
|||
if (!l) { |
|||
- cache_writelock(mc);
|
|||
- tree_mapent_delete_offsets(mc, name);
|
|||
- cache_unlock(mc);
|
|||
+ cleanup_offset_entries(ap, mc, &offsets);
|
|||
free(m_offset); |
|||
free(options); |
|||
free(pmapent); |
|||
@@ -1474,15 +1512,13 @@ dont_expand:
|
|||
p += l; |
|||
p = skipspace(p); |
|||
|
|||
- status = update_offset_entry(ap, mc,
|
|||
+ status = update_offset_entry(ap, mc, &offsets,
|
|||
name, m_root, m_root_len, |
|||
m_offset, myoptions, loc, age); |
|||
|
|||
if (status != CHE_OK) { |
|||
warn(ap->logopt, MODPREFIX "error adding multi-mount"); |
|||
- cache_writelock(mc);
|
|||
- tree_mapent_delete_offsets(mc, name);
|
|||
- cache_unlock(mc);
|
|||
+ cleanup_offset_entries(ap, mc, &offsets);
|
|||
free(m_offset); |
|||
free(options); |
|||
free(pmapent); |
|||
@@ -1499,6 +1535,14 @@ dont_expand:
|
|||
free(myoptions); |
|||
} while (*p == '/' || (*p == '"' && *(p + 1) == '/')); |
|||
|
|||
+ cache_writelock(mc);
|
|||
+ list_for_each_entry_safe(oe, tmp, &offsets, work) {
|
|||
+ if (!tree_mapent_add_node(mc, name, oe->key))
|
|||
+ error(ap->logopt, "failed to add offset %s to tree", oe->key);
|
|||
+ list_del_init(&oe->work);
|
|||
+ }
|
|||
+ cache_unlock(mc);
|
|||
+
|
|||
rv = mount_subtree(ap, mc, name, NULL, options, ctxt); |
|||
|
|||
free(options); |
@ -1,38 +0,0 @@ |
|||
autofs-5.1.7 - fix possible memory leak in master_parse() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)" |
|||
leaks the storage that "path" points to. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master_parse.y | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2186cbe3..b797f6dc 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -52,6 +52,7 @@
|
|||
- remove unused variable from get_exports(). |
|||
- add missing free in handle_mounts(). |
|||
- remove redundant if check. |
|||
+- fix possible memory leak in master_parse().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
|
|||
index 08e44b57..7480c36a 100644
|
|||
--- a/daemon/master_parse.y
|
|||
+++ b/daemon/master_parse.y
|
|||
@@ -155,6 +155,8 @@ file: {
|
|||
line: |
|||
| PATH mapspec |
|||
{ |
|||
+ if (path)
|
|||
+ free(path);
|
|||
path = master_strdup($1); |
|||
if (!path) { |
|||
local_free_vars(); |
@ -1,58 +0,0 @@ |
|||
autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: leaked_storage: Variable "ext_mp" going out of scope leaks |
|||
the storage it points to. |
|||
|
|||
Same applies to the other duped fields destined for the mnt_list struct. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 20 ++++++++++---------- |
|||
2 files changed, 11 insertions(+), 10 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b797f6dc..2e3b9fd7 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -53,6 +53,7 @@
|
|||
- add missing free in handle_mounts(). |
|||
- remove redundant if check. |
|||
- fix possible memory leak in master_parse(). |
|||
+- fix possible memory leak in mnts_add_amdmount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index c8a7bf00..ef69cec1 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *en
|
|||
|
|||
mnts_hash_mutex_lock(); |
|||
this = mnts_get_mount(entry->path); |
|||
- if (this) {
|
|||
- this->ext_mp = ext_mp;
|
|||
- this->amd_pref = pref;
|
|||
- this->amd_type = type;
|
|||
- this->amd_opts = opts;
|
|||
- this->amd_cache_opts = entry->cache_opts;
|
|||
- this->flags |= MNTS_AMD_MOUNT;
|
|||
- if (list_empty(&this->amdmount))
|
|||
- list_add_tail(&this->amdmount, &ap->amdmounts);
|
|||
- }
|
|||
+ if (!this)
|
|||
+ goto fail;
|
|||
+ this->ext_mp = ext_mp;
|
|||
+ this->amd_pref = pref;
|
|||
+ this->amd_type = type;
|
|||
+ this->amd_opts = opts;
|
|||
+ this->amd_cache_opts = entry->cache_opts;
|
|||
+ this->flags |= MNTS_AMD_MOUNT;
|
|||
+ if (list_empty(&this->amdmount))
|
|||
+ list_add_tail(&this->amdmount, &ap->amdmounts);
|
|||
mnts_hash_mutex_unlock(); |
|||
|
|||
return this; |
@ -1,44 +0,0 @@ |
|||
autofs-5.1.7 - fix return from umount_subtree_mounts() on offset list delete |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
When there are no mounts left in a subtree of offset mounts the offset |
|||
list is deleted. If all goes well deleting the list this shouldn't cause |
|||
a positive return from umount_subtree_mounts() (essentially saying that |
|||
the umount of the subtree has not succeeded). |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 5 +++-- |
|||
2 files changed, 4 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 64e619ec..6e0edd74 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -16,6 +16,7 @@
|
|||
- simplify mount_subtree() mount check. |
|||
- fix mnts_get_expire_list() expire list construction. |
|||
- fix inconsistent locking in umount_subtree_mounts(). |
|||
+- fix return from umount_subtree_mounts() on offset list delete.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 93bd8556..62530b6b 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -590,9 +590,10 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
|
|||
if (!left && is_mm_root) { |
|||
status = cache_delete_offset_list(mc, me->key); |
|||
- if (status != CHE_OK)
|
|||
+ if (status != CHE_OK) {
|
|||
warn(ap->logopt, "couldn't delete offset list"); |
|||
- left++;
|
|||
+ left++;
|
|||
+ }
|
|||
} |
|||
|
|||
if (ap->entry->maps && |
@ -1,43 +0,0 @@ |
|||
autofs-5.1.7 - fix use of possibly NULL var in lookup_program.c:match_key() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The lookup key used in match_key() should not be NULL. |
|||
|
|||
A check for a malloc() failure of the lookup key is missing in one of |
|||
the two cases in match_key() so add it. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/lookup_program.c | 5 +++++ |
|||
2 files changed, 6 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 61f3547a..680dbbd7 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -81,6 +81,7 @@
|
|||
- fix concat_options() error handling. |
|||
- eliminate some more alloca usage. |
|||
- use default stack size for threads. |
|||
+- fix use of possibly NULL var in lookup_program.c:match_key().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
|||
index 028580e5..691abedb 100644
|
|||
--- a/modules/lookup_program.c
|
|||
+++ b/modules/lookup_program.c
|
|||
@@ -468,6 +468,11 @@ static int match_key(struct autofs_point *ap,
|
|||
|
|||
if (!is_amd_format) { |
|||
lkp_key = strdup(name); |
|||
+ if (!lkp_key) {
|
|||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|||
+ return NSS_STATUS_UNAVAIL;
|
|||
+ }
|
|||
lkp_len = name_len; |
|||
} else { |
|||
size_t len; |
@ -1,69 +0,0 @@ |
|||
autofs-5.1.7 - make NFS version check flags consistent |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Several of the NFS connection macros have the same value so that they |
|||
can be used as internal code documentation of what is being done. |
|||
|
|||
Adjust the protocol macro naming to be consistent in a few places. |
|||
|
|||
Also make sure the correct flags are set for the function they indicate. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/mount_nfs.c | 16 +++++++++------- |
|||
2 files changed, 10 insertions(+), 7 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 17926916..c27973bb 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -89,6 +89,7 @@
|
|||
- add buffer length check to rmdir_path(). |
|||
- eliminate buffer usage from handle_mounts_cleanup(). |
|||
- add buffer length checks to autofs mount_mount(). |
|||
+- make NFS version check flags consistent.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
|
|||
index 0314a78f..0ab87dcf 100644
|
|||
--- a/modules/mount_nfs.c
|
|||
+++ b/modules/mount_nfs.c
|
|||
@@ -178,18 +178,20 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
port = 0; |
|||
} else if (_strncmp("proto=udp", cp, o_len) == 0 || |
|||
_strncmp("udp", cp, o_len) == 0) { |
|||
- vers &= ~TCP_SUPPORTED;
|
|||
+ vers &= ~TCP_REQUESTED;
|
|||
+ vers |= UDP_REQUESTED;
|
|||
} else if (_strncmp("proto=udp6", cp, o_len) == 0 || |
|||
_strncmp("udp6", cp, o_len) == 0) { |
|||
- vers &= ~TCP_SUPPORTED;
|
|||
- vers |= UDP6_REQUESTED;
|
|||
+ vers &= ~(TCP_REQUESTED|TCP6_REQUESTED);
|
|||
+ vers |= (UDP_REQUESTED|UDP6_REQUESTED);
|
|||
} else if (_strncmp("proto=tcp", cp, o_len) == 0 || |
|||
_strncmp("tcp", cp, o_len) == 0) { |
|||
- vers &= ~UDP_SUPPORTED;
|
|||
+ vers &= ~UDP_REQUESTED;
|
|||
+ vers |= TCP_REQUESTED;
|
|||
} else if (_strncmp("proto=tcp6", cp, o_len) == 0 || |
|||
_strncmp("tcp6", cp, o_len) == 0) { |
|||
- vers &= ~UDP_SUPPORTED;
|
|||
- vers |= TCP6_REQUESTED;
|
|||
+ vers &= ~(UDP_REQUESTED|UDP6_REQUESTED);
|
|||
+ vers |= TCP_REQUESTED|TCP6_REQUESTED;
|
|||
} |
|||
/* Check for options that also make sense |
|||
with bind mounts */ |
|||
@@ -246,7 +248,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
mount_default_proto == 4 && |
|||
(vers & NFS_VERS_MASK) != 0 && |
|||
(vers & NFS4_VERS_MASK) != 0 && |
|||
- !(vers & UDP6_REQUESTED)) {
|
|||
+ !(vers & (UDP_REQUESTED|UDP6_REQUESTED))) {
|
|||
unsigned int v4_probe_ok = 0; |
|||
struct host *tmp = new_host(hosts->name, 0, |
|||
hosts->addr, hosts->addr_len, |
@ -1,352 +0,0 @@ |
|||
autofs-5.1.7 - make tree implementation data independent |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Generalise the tree implementation so that it's independent of the |
|||
data structure that's used. |
|||
|
|||
Do this by refactoring it into core tree functions and functions |
|||
specific to the data structure to be used so that different data |
|||
structures can be used when needed by adding an implementation for |
|||
the data structure specific functions. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 |
|||
include/mounts.h | 29 +++++++++ |
|||
lib/mounts.c | 174 ++++++++++++++++++++++++++++++++++-------------------- |
|||
3 files changed, 140 insertions(+), 64 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 0dae6761..74571570 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -31,6 +31,7 @@
|
|||
- add some multi-mount macros. |
|||
- remove unused functions cache_dump_multi() and cache_dump_cache(). |
|||
- add a len field to struct autofs_point. |
|||
+- make tree implementation data independent.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index ac480c06..71d29566 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -51,10 +51,36 @@ extern const unsigned int t_indirect;
|
|||
extern const unsigned int t_direct; |
|||
extern const unsigned int t_offset; |
|||
|
|||
+struct mnt_list;
|
|||
struct mapent; |
|||
|
|||
+struct tree_ops;
|
|||
+
|
|||
+struct tree_node {
|
|||
+ struct tree_ops *ops;
|
|||
+ struct tree_node *left;
|
|||
+ struct tree_node *right;
|
|||
+};
|
|||
+#define INIT_TREE_NODE(ptr) ((ptr)->ops = NULL, (ptr)->left = NULL, (ptr)->right = NULL)
|
|||
+
|
|||
+#define MNT_LIST(n) (container_of(n, struct mnt_list, node))
|
|||
+#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node)
|
|||
+
|
|||
+typedef struct tree_node *(*tree_new_t) (void *ptr);
|
|||
+typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr);
|
|||
+typedef void (*tree_free_t) (struct tree_node *n);
|
|||
+
|
|||
+struct tree_ops {
|
|||
+ tree_new_t new;
|
|||
+ tree_cmp_t cmp;
|
|||
+ tree_free_t free;
|
|||
+};
|
|||
+
|
|||
+typedef int (*tree_work_fn_t) (struct tree_node *n, void *ptr);
|
|||
+
|
|||
struct mnt_list { |
|||
char *mp; |
|||
+ size_t len;
|
|||
unsigned int flags; |
|||
|
|||
/* Hash of all mounts */ |
|||
@@ -79,6 +105,9 @@ struct mnt_list {
|
|||
unsigned int amd_cache_opts; |
|||
struct list_head amdmount; |
|||
|
|||
+ /* Tree operations */
|
|||
+ struct tree_node node;
|
|||
+
|
|||
/* |
|||
* List operations ie. get_mnt_list. |
|||
*/ |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index b478ecb4..a6d1c5a7 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -68,6 +68,17 @@ static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||
static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS); |
|||
static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER; |
|||
|
|||
+static struct tree_node *tree_mnt_new(void *ptr);
|
|||
+static int tree_mnt_cmp(struct tree_node *n, void *ptr);
|
|||
+static void tree_mnt_free(struct tree_node *n);
|
|||
+
|
|||
+static struct tree_ops mnt_ops = {
|
|||
+ .new = tree_mnt_new,
|
|||
+ .cmp = tree_mnt_cmp,
|
|||
+ .free = tree_mnt_free,
|
|||
+};
|
|||
+static struct tree_ops *tree_mnt_ops = &mnt_ops;
|
|||
+
|
|||
unsigned int linux_version_code(void) |
|||
{ |
|||
struct utsname my_utsname; |
|||
@@ -904,6 +915,7 @@ static struct mnt_list *mnts_alloc_mount(const char *mp)
|
|||
this = NULL; |
|||
goto done; |
|||
} |
|||
+ this->len = strlen(mp);
|
|||
|
|||
this->ref = 1; |
|||
INIT_HLIST_NODE(&this->hash); |
|||
@@ -912,6 +924,7 @@ static struct mnt_list *mnts_alloc_mount(const char *mp)
|
|||
INIT_LIST_HEAD(&this->submount_work); |
|||
INIT_LIST_HEAD(&this->amdmount); |
|||
INIT_LIST_HEAD(&this->expire); |
|||
+ INIT_TREE_NODE(&this->node);
|
|||
done: |
|||
return this; |
|||
} |
|||
@@ -1225,91 +1238,58 @@ done:
|
|||
return has_mounted_mounts; |
|||
} |
|||
|
|||
-struct tree_node {
|
|||
- struct mnt_list *mnt;
|
|||
- struct tree_node *left;
|
|||
- struct tree_node *right;
|
|||
-};
|
|||
-
|
|||
-static struct tree_node *tree_new(struct mnt_list *mnt)
|
|||
+static inline struct tree_node *tree_root(struct tree_ops *ops, void *ptr)
|
|||
{ |
|||
- struct tree_node *n;
|
|||
-
|
|||
- n = malloc(sizeof(struct tree_node));
|
|||
- if (!n)
|
|||
- return NULL;
|
|||
- memset(n, 0, sizeof(struct tree_node));
|
|||
- n->mnt = mnt;
|
|||
-
|
|||
- return n;
|
|||
-}
|
|||
-
|
|||
-static struct tree_node *tree_root(struct mnt_list *mnt)
|
|||
-{
|
|||
- struct tree_node *n;
|
|||
-
|
|||
- n = tree_new(mnt);
|
|||
- if (!n) {
|
|||
- error(LOGOPT_ANY, "failed to allcate tree root");
|
|||
- return NULL;
|
|||
- }
|
|||
-
|
|||
- return n;
|
|||
+ return ops->new(ptr);
|
|||
} |
|||
|
|||
-static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt)
|
|||
+static struct tree_node *tree_add_left(struct tree_node *n, void *ptr)
|
|||
{ |
|||
struct tree_node *new; |
|||
|
|||
- new = tree_new(mnt);
|
|||
- if (!new) {
|
|||
- error(LOGOPT_ANY, "failed to allcate tree node");
|
|||
- return NULL;
|
|||
- }
|
|||
+ new = n->ops->new(ptr);
|
|||
n->left = new; |
|||
|
|||
- return n;
|
|||
+ return new;
|
|||
} |
|||
|
|||
-static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt)
|
|||
+static struct tree_node *tree_add_right(struct tree_node *n, void *ptr)
|
|||
{ |
|||
struct tree_node *new; |
|||
|
|||
- new = tree_new(mnt);
|
|||
- if (!new) {
|
|||
- error(LOGOPT_ANY, "failed to allcate tree node");
|
|||
- return NULL;
|
|||
- }
|
|||
+ new = n->ops->new(ptr);
|
|||
n->right = new; |
|||
|
|||
- return n;
|
|||
+ return new;
|
|||
} |
|||
|
|||
-static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt)
|
|||
+static struct tree_node *tree_add_node(struct tree_node *root, void *ptr)
|
|||
{ |
|||
struct tree_node *p, *q; |
|||
- unsigned int mp_len;
|
|||
-
|
|||
- mp_len = strlen(mnt->mp);
|
|||
+ struct tree_ops *ops = root->ops;
|
|||
+ int eq;
|
|||
|
|||
q = root; |
|||
p = root; |
|||
|
|||
- while (q && strcmp(mnt->mp, p->mnt->mp)) {
|
|||
+ while (q) {
|
|||
p = q; |
|||
- if (mp_len < strlen(p->mnt->mp))
|
|||
+ eq = ops->cmp(p, ptr);
|
|||
+ if (!eq)
|
|||
+ break;
|
|||
+ if (eq < 0)
|
|||
q = p->left; |
|||
else |
|||
q = p->right; |
|||
} |
|||
|
|||
- if (strcmp(mnt->mp, p->mnt->mp) == 0)
|
|||
- error(LOGOPT_ANY, "duplicate entry in mounts list");
|
|||
+ if (!eq)
|
|||
+ error(LOGOPT_ANY, "cannot add duplicate entry to tree");
|
|||
else { |
|||
- if (mp_len < strlen(p->mnt->mp))
|
|||
- return tree_add_left(p, mnt);
|
|||
+ if (eq < 0)
|
|||
+ return tree_add_left(p, ptr);
|
|||
else |
|||
- return tree_add_right(p, mnt);
|
|||
+ return tree_add_right(p, ptr);
|
|||
} |
|||
|
|||
return NULL; |
|||
@@ -1317,26 +1297,92 @@ static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *
|
|||
|
|||
static void tree_free(struct tree_node *root) |
|||
{ |
|||
+ struct tree_ops *ops = root->ops;
|
|||
+
|
|||
if (root->right) |
|||
tree_free(root->right); |
|||
if (root->left) |
|||
tree_free(root->left); |
|||
- free(root);
|
|||
+ ops->free(root);
|
|||
} |
|||
|
|||
-static void tree_traverse(struct tree_node *n, struct list_head *mnts)
|
|||
+static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
|||
{ |
|||
- if (n->right)
|
|||
- tree_traverse(n->right, mnts);
|
|||
- list_add_tail(&n->mnt->expire, mnts);
|
|||
- if (n->left)
|
|||
- tree_traverse(n->left, mnts);
|
|||
+ int ret;
|
|||
+
|
|||
+ if (n->left) {
|
|||
+ ret = tree_traverse_inorder(n->left, work, ptr);
|
|||
+ if (!ret)
|
|||
+ goto done;
|
|||
+ }
|
|||
+ ret = work(n, ptr);
|
|||
+ if (!ret)
|
|||
+ goto done;
|
|||
+ if (n->right) {
|
|||
+ ret = tree_traverse_inorder(n->right, work, ptr);
|
|||
+ if (!ret)
|
|||
+ goto done;
|
|||
+ }
|
|||
+done:
|
|||
+ return ret;
|
|||
+}
|
|||
+
|
|||
+static struct tree_node *tree_mnt_root(struct mnt_list *mnt)
|
|||
+{
|
|||
+ return tree_root(tree_mnt_ops, mnt);
|
|||
+}
|
|||
+
|
|||
+static struct tree_node *tree_mnt_new(void *ptr)
|
|||
+{
|
|||
+ struct tree_node *n = MNT_LIST_NODE(ptr);
|
|||
+
|
|||
+ n->ops = tree_mnt_ops;
|
|||
+ n->left = NULL;
|
|||
+ n->right = NULL;
|
|||
+
|
|||
+ return n;
|
|||
+}
|
|||
+
|
|||
+static int tree_mnt_cmp(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct mnt_list *n_mnt = MNT_LIST(n);
|
|||
+ size_t n_mnt_len = n_mnt->len;
|
|||
+ struct mnt_list *mnt = ptr;
|
|||
+ size_t mnt_len = mnt->len;
|
|||
+ int eq;
|
|||
+
|
|||
+ eq = strcmp(mnt->mp, n_mnt->mp);
|
|||
+ if (!eq)
|
|||
+ return 0;
|
|||
+ return (mnt_len < n_mnt_len) ? -1 : 1;
|
|||
+}
|
|||
+
|
|||
+static void tree_mnt_free(struct tree_node *n)
|
|||
+{
|
|||
+ n->ops = NULL;
|
|||
+ n->left = NULL;
|
|||
+ n->right = NULL;
|
|||
+}
|
|||
+
|
|||
+static int tree_mnt_expire_list_work(struct tree_node *n, void *ptr)
|
|||
+{
|
|||
+ struct mnt_list *mnt = MNT_LIST(n);
|
|||
+ struct list_head *mnts = ptr;
|
|||
+
|
|||
+ /* The expire of the root offset of an offset tree is the same
|
|||
+ * as expiring the offset tree root itself (if theree is a root
|
|||
+ * offset).
|
|||
+ */
|
|||
+ if (mnt->mp[mnt->len - 1] != '/')
|
|||
+ list_add(&mnt->expire, mnts);
|
|||
+
|
|||
+ return 1;
|
|||
} |
|||
|
|||
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) |
|||
{ |
|||
- struct mnt_list *mnt;
|
|||
struct tree_node *tree = NULL; |
|||
+ struct mnt_list *mnt;
|
|||
|
|||
mnts_hash_mutex_lock(); |
|||
if (list_empty(&ap->mounts)) |
|||
@@ -1351,7 +1397,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
|||
__mnts_get_mount(mnt); |
|||
|
|||
if (!tree) { |
|||
- tree = tree_root(mnt);
|
|||
+ tree = tree_mnt_root(mnt);
|
|||
if (!tree) { |
|||
error(LOGOPT_ANY, "failed to create expire tree root"); |
|||
goto done; |
|||
@@ -1367,7 +1413,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
|||
} |
|||
} |
|||
|
|||
- tree_traverse(tree, mnts);
|
|||
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
|||
tree_free(tree); |
|||
done: |
|||
mnts_hash_mutex_unlock(); |
@ -1,118 +0,0 @@ |
|||
autofs-5.1.7 - move amd mounts removal into lib/mounts.c |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Move the amd mounts removal from master_free_autofs_point() into |
|||
lib/mounts.c along with the rest of the amd mount handling. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master.c | 12 +----------- |
|||
include/mounts.h | 1 + |
|||
lib/mounts.c | 28 ++++++++++++++++++++++++---- |
|||
4 files changed, 27 insertions(+), 15 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 002da042..a9209755 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -46,6 +46,7 @@
|
|||
- use mount_fullpath() in one spot in parse_mount(). |
|||
- pass root length to mount_fullpath(). |
|||
- remove unused function master_submount_list_empty(). |
|||
+- move amd mounts removal into lib/mounts.c.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master.c b/daemon/master.c
|
|||
index af9cd79f..b288e070 100644
|
|||
--- a/daemon/master.c
|
|||
+++ b/daemon/master.c
|
|||
@@ -143,22 +143,12 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
|
|||
|
|||
void master_free_autofs_point(struct autofs_point *ap) |
|||
{ |
|||
- struct list_head *p, *head;
|
|||
int status; |
|||
|
|||
if (!ap) |
|||
return; |
|||
|
|||
- mounts_mutex_lock(ap);
|
|||
- head = &ap->amdmounts;
|
|||
- p = head->next;
|
|||
- while (p != head) {
|
|||
- struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount);
|
|||
- p = p->next;
|
|||
- ext_mount_remove(mnt->ext_mp);
|
|||
- mnts_remove_amdmount(mnt->mp);
|
|||
- }
|
|||
- mounts_mutex_unlock(ap);
|
|||
+ mnts_remove_amdmounts(ap);
|
|||
|
|||
status = pthread_mutex_destroy(&ap->mounts_mutex); |
|||
if (status) |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index d7980976..1b376b3d 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -161,6 +161,7 @@ void mnts_remove_submount(const char *mp);
|
|||
struct mnt_list *mnts_find_amdmount(const char *path); |
|||
struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry); |
|||
void mnts_remove_amdmount(const char *mp); |
|||
+void mnts_remove_amdmounts(struct autofs_point *ap);
|
|||
struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags); |
|||
void mnts_remove_mount(const char *mp, unsigned int flags); |
|||
struct mnt_list *get_mnt_list(const char *path, int include); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 6b8e4c92..c8a7bf00 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1144,14 +1144,13 @@ fail:
|
|||
return NULL; |
|||
} |
|||
|
|||
-void mnts_remove_amdmount(const char *mp)
|
|||
+static void __mnts_remove_amdmount(const char *mp)
|
|||
{ |
|||
struct mnt_list *this; |
|||
|
|||
- mnts_hash_mutex_lock();
|
|||
this = mnts_lookup(mp); |
|||
if (!(this && this->flags & MNTS_AMD_MOUNT)) |
|||
- goto done;
|
|||
+ return;
|
|||
this->flags &= ~MNTS_AMD_MOUNT; |
|||
list_del_init(&this->amdmount); |
|||
if (this->ext_mp) { |
|||
@@ -1172,7 +1171,28 @@ void mnts_remove_amdmount(const char *mp)
|
|||
} |
|||
this->amd_cache_opts = 0; |
|||
__mnts_put_mount(this); |
|||
-done:
|
|||
+}
|
|||
+
|
|||
+void mnts_remove_amdmount(const char *mp)
|
|||
+{
|
|||
+ mnts_hash_mutex_lock();
|
|||
+ __mnts_remove_amdmount(mp);
|
|||
+ mnts_hash_mutex_unlock();
|
|||
+}
|
|||
+
|
|||
+void mnts_remove_amdmounts(struct autofs_point *ap)
|
|||
+{
|
|||
+ struct list_head *head, *p;
|
|||
+
|
|||
+ mnts_hash_mutex_lock();
|
|||
+ head = &ap->amdmounts;
|
|||
+ p = head->next;
|
|||
+ while (p != head) {
|
|||
+ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount);
|
|||
+ p = p->next;
|
|||
+ ext_mount_remove(mnt->ext_mp);
|
|||
+ __mnts_remove_amdmount(mnt->mp);
|
|||
+ }
|
|||
mnts_hash_mutex_unlock(); |
|||
} |
|||
|
@ -1,72 +0,0 @@ |
|||
autofs-5.1.7 - pass mapent_cache to update_offset_entry() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Pass mapent_cache to update_offset_entry() rather than use the wait/signal |
|||
mechanism, it isn't needed here. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 22 ++++++---------------- |
|||
2 files changed, 7 insertions(+), 16 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 6e0edd74..c60a9ed3 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -17,6 +17,7 @@
|
|||
- fix mnts_get_expire_list() expire list construction. |
|||
- fix inconsistent locking in umount_subtree_mounts(). |
|||
- fix return from umount_subtree_mounts() on offset list delete. |
|||
+- pass mapent_cache to update_offset_entry().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 1142e8a3..95251bee 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -793,24 +793,17 @@ static int check_is_multi(const char *mapent)
|
|||
} |
|||
|
|||
static int |
|||
-update_offset_entry(struct autofs_point *ap, const char *name,
|
|||
+update_offset_entry(struct autofs_point *ap,
|
|||
+ struct mapent_cache *mc, const char *name,
|
|||
const char *m_root, int m_root_len, |
|||
- const char *path, const char *myoptions, const char *loc,
|
|||
- time_t age)
|
|||
+ const char *path, const char *myoptions,
|
|||
+ const char *loc, time_t age)
|
|||
{ |
|||
- struct map_source *source;
|
|||
- struct mapent_cache *mc;
|
|||
char m_key[PATH_MAX + 1]; |
|||
char m_mapent[MAPENT_MAX_LEN + 1]; |
|||
int p_len, m_key_len, m_options_len, m_mapent_len; |
|||
int ret; |
|||
|
|||
- source = ap->entry->current;
|
|||
- ap->entry->current = NULL;
|
|||
- master_source_current_signal(ap->entry);
|
|||
-
|
|||
- mc = source->mc;
|
|||
-
|
|||
memset(m_mapent, 0, MAPENT_MAX_LEN + 1); |
|||
|
|||
/* Internal hosts map may have loc == NULL */ |
|||
@@ -1574,11 +1567,8 @@ dont_expand:
|
|||
p += l; |
|||
p = skipspace(p); |
|||
|
|||
- master_source_current_wait(ap->entry);
|
|||
- ap->entry->current = source;
|
|||
-
|
|||
- status = update_offset_entry(ap, name,
|
|||
- m_root, m_root_len,
|
|||
+ status = update_offset_entry(ap, mc,
|
|||
+ name, m_root, m_root_len,
|
|||
path, myoptions, loc, age); |
|||
|
|||
if (status != CHE_OK) { |
@ -1,171 +0,0 @@ |
|||
autofs-5.1.7 - pass root length to mount_fullpath() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
The length of root may already be known, add a parameter to allow |
|||
passing it to mount_fullpath() so a strlen() call can be avoided. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
include/mounts.h | 2 +- |
|||
lib/mounts.c | 11 +++++++---- |
|||
modules/mount_bind.c | 2 +- |
|||
modules/mount_changer.c | 2 +- |
|||
modules/mount_ext2.c | 2 +- |
|||
modules/mount_generic.c | 2 +- |
|||
modules/mount_nfs.c | 2 +- |
|||
modules/parse_sun.c | 4 ++-- |
|||
9 files changed, 16 insertions(+), 12 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 8494f0dc..1c9e2a2d 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -44,6 +44,7 @@
|
|||
- remove obsolete functions. |
|||
- remove redundant local var from sun_mount(). |
|||
- use mount_fullpath() in one spot in parse_mount(). |
|||
+- pass root length to mount_fullpath().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index ec895e1c..d7980976 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -131,7 +131,7 @@ int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
|
|||
extern unsigned int nfs_mount_uses_string_options; |
|||
|
|||
int mount_fullpath(char *fullpath, size_t max_len, |
|||
- const char *root, const char *name);
|
|||
+ const char *root, size_t root_len, const char *name);
|
|||
|
|||
struct amd_entry; |
|||
|
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index c120d2a8..6b8e4c92 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -362,11 +362,14 @@ int check_nfs_mount_version(struct nfs_mount_vers *vers,
|
|||
#endif |
|||
|
|||
int mount_fullpath(char *fullpath, size_t max_len, |
|||
- const char *root, const char *name)
|
|||
+ const char *root, size_t root_len, const char *name)
|
|||
{ |
|||
int last, len; |
|||
|
|||
- last = strlen(root) - 1;
|
|||
+ if (root_len)
|
|||
+ last = root_len - 1;
|
|||
+ else
|
|||
+ last = strlen(root) - 1;
|
|||
|
|||
/* Root offset of multi-mount or direct or offset mount. |
|||
* Direct or offset mount, name (or root) is absolute path. |
|||
@@ -1685,7 +1688,7 @@ void tree_mapent_cleanup_offsets(struct mapent *oe)
|
|||
else { |
|||
char mp[PATH_MAX + 1]; |
|||
|
|||
- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key))
|
|||
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key))
|
|||
error(ap->logopt, "mount path is too long"); |
|||
else |
|||
tree_mapent_umount_mount(ap, mp); |
|||
@@ -1922,7 +1925,7 @@ int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict)
|
|||
* one of these keys is the root of a multi-mount the mount |
|||
* path must be constructed. |
|||
*/ |
|||
- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) {
|
|||
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key)) {
|
|||
error(ap->logopt, "mount path is too long"); |
|||
return 0; |
|||
} |
|||
diff --git a/modules/mount_bind.c b/modules/mount_bind.c
|
|||
index c17c6f18..7f64332b 100644
|
|||
--- a/modules/mount_bind.c
|
|||
+++ b/modules/mount_bind.c
|
|||
@@ -122,7 +122,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
} |
|||
} |
|||
|
|||
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
|
|||
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
|
|||
if (!len) { |
|||
error(ap->logopt, |
|||
MODPREFIX "mount point path too long"); |
|||
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
|
|||
index d02b5f45..8adb9f9a 100644
|
|||
--- a/modules/mount_changer.c
|
|||
+++ b/modules/mount_changer.c
|
|||
@@ -59,7 +59,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
|
|||
fstype = "iso9660"; |
|||
|
|||
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
|
|||
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
|
|||
if (!len) { |
|||
error(ap->logopt, |
|||
MODPREFIX "mount point path too long"); |
|||
diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c
|
|||
index 53e6ee10..f4002e58 100644
|
|||
--- a/modules/mount_ext2.c
|
|||
+++ b/modules/mount_ext2.c
|
|||
@@ -55,7 +55,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
if (defaults_get_mount_verbose()) |
|||
mountlog = &log_info; |
|||
|
|||
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
|
|||
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
|
|||
if (!len) { |
|||
error(ap->logopt, |
|||
MODPREFIX "mount point path too long"); |
|||
diff --git a/modules/mount_generic.c b/modules/mount_generic.c
|
|||
index c9deb7ae..8cd0f4ab 100644
|
|||
--- a/modules/mount_generic.c
|
|||
+++ b/modules/mount_generic.c
|
|||
@@ -54,7 +54,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
if (defaults_get_mount_verbose()) |
|||
mountlog = &log_info; |
|||
|
|||
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
|
|||
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
|
|||
if (!len) { |
|||
error(ap->logopt, |
|||
MODPREFIX "mount point path too long"); |
|||
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
|
|||
index c70210f4..0314a78f 100644
|
|||
--- a/modules/mount_nfs.c
|
|||
+++ b/modules/mount_nfs.c
|
|||
@@ -213,7 +213,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
|||
} |
|||
|
|||
/* Construct mount point directory */ |
|||
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
|
|||
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
|
|||
if (!len) { |
|||
error(ap->logopt, |
|||
MODPREFIX "mount point path too long"); |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index d3fc6c7f..b1c2611c 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1089,7 +1089,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
struct mapent *ro; |
|||
size_t len; |
|||
|
|||
- len = mount_fullpath(key, PATH_MAX, ap->path, me->key);
|
|||
+ len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key);
|
|||
if (!len) { |
|||
warn(ap->logopt, "path loo long"); |
|||
return 1; |
|||
@@ -1359,7 +1359,7 @@ dont_expand:
|
|||
time_t age; |
|||
int l; |
|||
|
|||
- m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name);
|
|||
+ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, ap->len, name);
|
|||
if (!m_root_len) { |
|||
error(ap->logopt, |
|||
MODPREFIX "multi-mount root path too long"); |
@ -1,83 +0,0 @@ |
|||
autofs-5.1.7 - reduce umount EBUSY check delay |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Some time ago I had to wait and retry umount() for autofs mounts |
|||
becuase I found EBUSY would be returned for a time after the call |
|||
causing false negative umount returns. |
|||
|
|||
I think that problem has been resolved but removing the retry is |
|||
probably a little risky. |
|||
|
|||
But the wait time is quite long at one fifth of a second so reduce |
|||
that to one twentieth of a second and increase the retries to make |
|||
it more resposive. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 4 ++-- |
|||
daemon/indirect.c | 2 +- |
|||
include/automount.h | 2 +- |
|||
4 files changed, 5 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b144f6aa..6419052d 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -23,6 +23,7 @@
|
|||
- eliminate count_mounts() from expire_proc_indirect(). |
|||
- eliminate some strlen calls in offset handling. |
|||
- don't add offset mounts to mounted mounts table. |
|||
+- reduce umount EBUSY check delay.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index fbfebbdd..5c1146a7 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -150,7 +150,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
|
|||
|
|||
retries = UMOUNT_RETRIES; |
|||
while ((rv = umount(me->key)) == -1 && retries--) { |
|||
- struct timespec tm = {0, 200000000};
|
|||
+ struct timespec tm = {0, 50000000};
|
|||
if (errno != EBUSY) |
|||
break; |
|||
nanosleep(&tm, NULL); |
|||
@@ -573,7 +573,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|||
|
|||
retries = UMOUNT_RETRIES; |
|||
while ((rv = umount(me->key)) == -1 && retries--) { |
|||
- struct timespec tm = {0, 200000000};
|
|||
+ struct timespec tm = {0, 50000000};
|
|||
if (errno != EBUSY) |
|||
break; |
|||
nanosleep(&tm, NULL); |
|||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|||
index eddcfff7..9f2ca6a0 100644
|
|||
--- a/daemon/indirect.c
|
|||
+++ b/daemon/indirect.c
|
|||
@@ -265,7 +265,7 @@ int umount_autofs_indirect(struct autofs_point *ap, const char *root)
|
|||
|
|||
retries = UMOUNT_RETRIES; |
|||
while ((rv = umount(mountpoint)) == -1 && retries--) { |
|||
- struct timespec tm = {0, 200000000};
|
|||
+ struct timespec tm = {0, 50000000};
|
|||
if (errno != EBUSY) |
|||
break; |
|||
nanosleep(&tm, NULL); |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index 69445b92..fa6f5d63 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/include/automount.h
|
|||
@@ -140,7 +140,7 @@ struct autofs_point;
|
|||
#define NULL_MAP_HASHSIZE 64 |
|||
#define NEGATIVE_TIMEOUT 10 |
|||
#define POSITIVE_TIMEOUT 120 |
|||
-#define UMOUNT_RETRIES 8
|
|||
+#define UMOUNT_RETRIES 16
|
|||
#define EXPIRE_RETRIES 3 |
|||
|
|||
struct mapent_cache { |
@ -1,206 +0,0 @@ |
|||
autofs-5.1.7 - refactor get_nfs_info() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Make getting a portmap client and getting a service port from portmap |
|||
helper functions and simplify the return handling. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 |
|||
modules/replicated.c | 135 ++++++++++++++++++++++++++++---------------------- |
|||
2 files changed, 76 insertions(+), 60 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index c27973bb..5d2c2c88 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -90,6 +90,7 @@
|
|||
- eliminate buffer usage from handle_mounts_cleanup(). |
|||
- add buffer length checks to autofs mount_mount(). |
|||
- make NFS version check flags consistent. |
|||
+- refactor get_nfs_info().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/replicated.c b/modules/replicated.c
|
|||
index ffaf519f..e03c9d25 100644
|
|||
--- a/modules/replicated.c
|
|||
+++ b/modules/replicated.c
|
|||
@@ -223,6 +223,49 @@ void free_host_list(struct host **list)
|
|||
*list = NULL; |
|||
} |
|||
|
|||
+static unsigned int get_portmap_client(unsigned logopt,
|
|||
+ struct conn_info *pm_info, struct host *host,
|
|||
+ int proto)
|
|||
+{
|
|||
+ unsigned int status;
|
|||
+
|
|||
+ /* On success client is stored in pm_info->client */
|
|||
+ status = rpc_portmap_getclient(pm_info,
|
|||
+ host->name, host->addr, host->addr_len,
|
|||
+ proto, RPC_CLOSE_DEFAULT);
|
|||
+ if (status == -EHOSTUNREACH)
|
|||
+ debug(logopt,
|
|||
+ "host not reachable getting portmap client");
|
|||
+ else if (status)
|
|||
+ debug(logopt, "error 0x%d getting portmap client");
|
|||
+
|
|||
+ return status;
|
|||
+}
|
|||
+
|
|||
+static unsigned int get_portmap_port(unsigned logopt,
|
|||
+ struct conn_info *pm_info, struct pmap *parms,
|
|||
+ unsigned long vers, unsigned int version,
|
|||
+ short unsigned int *port)
|
|||
+{
|
|||
+ unsigned int status;
|
|||
+ short unsigned int nfs_port;
|
|||
+
|
|||
+ parms->pm_vers = vers;
|
|||
+ status = rpc_portmap_getport(pm_info, parms, &nfs_port);
|
|||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
|||
+ debug(logopt,
|
|||
+ "host not reachable or timed out getting service port");
|
|||
+ } else if (status < 0) {
|
|||
+ if (!(version & NFS_VERS_MASK))
|
|||
+ debug(logopt, "error 0x%d getting service port");
|
|||
+ }
|
|||
+
|
|||
+ if (!status)
|
|||
+ *port = nfs_port;
|
|||
+
|
|||
+ return status;
|
|||
+}
|
|||
+
|
|||
static unsigned int get_nfs_info(unsigned logopt, struct host *host, |
|||
struct conn_info *pm_info, struct conn_info *rpc_info, |
|||
int proto, unsigned int version, int port) |
|||
@@ -263,33 +306,20 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
|
|||
goto v3_ver; |
|||
|
|||
if (!port) { |
|||
- status = rpc_portmap_getclient(pm_info,
|
|||
- host->name, host->addr, host->addr_len,
|
|||
- proto, RPC_CLOSE_DEFAULT);
|
|||
- if (status == -EHOSTUNREACH) {
|
|||
- debug(logopt,
|
|||
- "host not reachable getting portmap client");
|
|||
- supported = status;
|
|||
- goto done_ver;
|
|||
- } else if (status) {
|
|||
- debug(logopt, "error 0x%d getting portmap client");
|
|||
+ status = get_portmap_client(logopt, pm_info, host, proto);
|
|||
+ if (status) {
|
|||
+ if (status == -EHOSTUNREACH)
|
|||
+ supported = status;
|
|||
goto done_ver; |
|||
} |
|||
- parms.pm_vers = NFS4_VERSION;
|
|||
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
|
|||
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
|||
- debug(logopt,
|
|||
- "host not reachable or timed out getting service port");
|
|||
- supported = status;
|
|||
- goto done_ver;
|
|||
- } else if (status < 0) {
|
|||
- if (version & NFS_VERS_MASK)
|
|||
+ status = get_portmap_port(logopt, pm_info, &parms,
|
|||
+ NFS4_VERSION, version, &rpc_info->port);
|
|||
+ if (status) {
|
|||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
|
|||
+ supported = status;
|
|||
+ if (status < 0 && version & NFS_VERS_MASK)
|
|||
goto v3_ver; /* MOUNT_NFS_DEFAULT_PROTOCOL=4 */ |
|||
- else {
|
|||
- debug(logopt,
|
|||
- "error 0x%d getting service port");
|
|||
- goto done_ver;
|
|||
- }
|
|||
+ goto done_ver;
|
|||
} |
|||
} |
|||
|
|||
@@ -334,31 +364,22 @@ v3_ver:
|
|||
goto v2_ver; |
|||
|
|||
if (!port && !pm_info->client) { |
|||
- status = rpc_portmap_getclient(pm_info,
|
|||
- host->name, host->addr, host->addr_len,
|
|||
- proto, RPC_CLOSE_DEFAULT);
|
|||
- if (status == -EHOSTUNREACH) {
|
|||
- debug(logopt,
|
|||
- "host not reachable getting portmap client");
|
|||
- supported = status;
|
|||
- goto done_ver;
|
|||
- } else if (status) {
|
|||
- debug(logopt,
|
|||
- "error 0x%d getting getting portmap client");
|
|||
+ status = get_portmap_client(logopt, pm_info, host, proto);
|
|||
+ if (status) {
|
|||
+ if (status == -EHOSTUNREACH)
|
|||
+ supported = status;
|
|||
goto done_ver; |
|||
} |
|||
} |
|||
|
|||
if (!port) { |
|||
- parms.pm_vers = NFS3_VERSION;
|
|||
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
|
|||
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
|||
- debug(logopt,
|
|||
- "host not reachable or timed out getting service port");
|
|||
- supported = status;
|
|||
+ status = get_portmap_port(logopt, pm_info, &parms,
|
|||
+ NFS3_VERSION, version, &rpc_info->port);
|
|||
+ if (status) {
|
|||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
|
|||
+ supported = status;
|
|||
goto done_ver; |
|||
- } else if (status < 0)
|
|||
- goto v2_ver;
|
|||
+ }
|
|||
} |
|||
|
|||
if (rpc_info->proto == IPPROTO_UDP) |
|||
@@ -399,28 +420,22 @@ v2_ver:
|
|||
goto done_ver; |
|||
|
|||
if (!port && !pm_info->client) { |
|||
- status = rpc_portmap_getclient(pm_info,
|
|||
- host->name, host->addr, host->addr_len,
|
|||
- proto, RPC_CLOSE_DEFAULT);
|
|||
- if (status == -EHOSTUNREACH) {
|
|||
- debug(logopt,
|
|||
- "host not reachable getting portmap client");
|
|||
- supported = status;
|
|||
- goto done_ver;
|
|||
- } else if (status)
|
|||
+ status = get_portmap_client(logopt, pm_info, host, proto);
|
|||
+ if (status) {
|
|||
+ if (status == -EHOSTUNREACH)
|
|||
+ supported = status;
|
|||
goto done_ver; |
|||
+ }
|
|||
} |
|||
|
|||
if (!port) { |
|||
- parms.pm_vers = NFS2_VERSION;
|
|||
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
|
|||
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
|||
- debug(logopt,
|
|||
- "host not reachable or timed out getting service port");
|
|||
- supported = status;
|
|||
- goto done_ver;
|
|||
- } else if (status < 0)
|
|||
+ status = get_portmap_port(logopt, pm_info, &parms,
|
|||
+ NFS2_VERSION, version, &rpc_info->port);
|
|||
+ if (status) {
|
|||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
|
|||
+ supported = status;
|
|||
goto done_ver; |
|||
+ }
|
|||
} |
|||
|
|||
if (rpc_info->proto == IPPROTO_UDP) |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue