import autofs-5.1.4-74.el8

This commit is contained in:
CentOS Sources 2021-11-09 05:04:07 -05:00 committed by Stepan Oksanichenko
parent 6c524ac8f9
commit 06023428b4
105 changed files with 23296 additions and 13 deletions

View File

@ -0,0 +1,37 @@
autofs-5.1.4 - remove unused function dump_master()
From: Ian Kent <raven@themaw.net>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/master.c | 11 -----------
2 files changed, 1 insertion(+), 11 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -112,6 +112,7 @@ xx/xx/2018 autofs-5.1.5
- dont prune offset map entries.
- simplify sss source stale check.
- use defines for expire type.
+- remove unused function dump_master().
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -1971,14 +1971,3 @@ int master_kill(struct master *master)
return 1;
}
-
-void dump_master(struct master *master)
-{
- struct list_head *p, *head;
-
- head = &master->mounts;
- list_for_each(p, head) {
- struct master_mapent *this = list_entry(p, struct master_mapent, list);
- logmsg("path %s", this->path);
- }
-}

View File

@ -0,0 +1,100 @@
autofs-5.1.4 - use defines for expire type
From: Ian Kent <raven@themaw.net>
The kernel defines for expire type such as an immediate expire
shoule be used to clearify what is being requested.
AUTOFS_EXP_IMMEDIATE corresponds to a SIGUSR1 prune operation.
AUTOFS_EXP_FORCE corresponds to an expire type not yet implemented in
the kernel, a SIGUSR2 forced expire. Define it in our internal autofs
kernel include file, the kernel will ignore it if it doesn't support it.
AUTOFS_EXP_LEAVES is no longer used in autofs version 5.
Finally add a define AUTOFS_EXP_NORMAL to indicate we're perfoming a
normal expire.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/state.c | 8 ++++----
include/linux/auto_fs4.h | 6 ++++--
include/state.h | 2 +-
4 files changed, 10 insertions(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -111,6 +111,7 @@ xx/xx/2018 autofs-5.1.5
- use a valid timeout in lookup_prune_one_cache().
- dont prune offset map entries.
- simplify sss source stale check.
+- use defines for expire type.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -634,7 +634,7 @@ static unsigned int st_prepare_shutdown(
ap->state = ST_SHUTDOWN_PENDING;
/* Unmount everything */
- exp = expire_proc(ap, 1);
+ exp = expire_proc(ap, AUTOFS_EXP_IMMEDIATE);
switch (exp) {
case EXP_ERROR:
case EXP_PARTIAL:
@@ -660,7 +660,7 @@ static unsigned int st_force_shutdown(st
ap->state = ST_SHUTDOWN_FORCE;
/* Unmount everything */
- exp = expire_proc(ap, 1);
+ exp = expire_proc(ap, AUTOFS_EXP_FORCE | AUTOFS_EXP_IMMEDIATE);
switch (exp) {
case EXP_ERROR:
case EXP_PARTIAL:
@@ -695,7 +695,7 @@ static unsigned int st_prune(struct auto
assert(ap->state == ST_READY);
ap->state = ST_PRUNE;
- switch (expire_proc(ap, 1)) {
+ switch (expire_proc(ap, AUTOFS_EXP_IMMEDIATE)) {
case EXP_ERROR:
case EXP_PARTIAL:
if (!ap->submount)
@@ -716,7 +716,7 @@ static unsigned int st_expire(struct aut
assert(ap->state == ST_READY);
ap->state = ST_EXPIRE;
- switch (expire_proc(ap, 0)) {
+ switch (expire_proc(ap, AUTOFS_EXP_NORMAL)) {
case EXP_ERROR:
case EXP_PARTIAL:
if (!ap->submount)
--- autofs-5.1.4.orig/include/linux/auto_fs4.h
+++ autofs-5.1.4/include/linux/auto_fs4.h
@@ -27,8 +27,10 @@
#define AUTOFS_PROTO_SUBVERSION 2
/* Mask for expire behaviour */
-#define AUTOFS_EXP_IMMEDIATE 1
-#define AUTOFS_EXP_LEAVES 2
+#define AUTOFS_EXP_NORMAL 0x00
+#define AUTOFS_EXP_IMMEDIATE 0x01
+#define AUTOFS_EXP_LEAVES 0x02
+#define AUTOFS_EXP_FORCE 0x04
#define AUTOFS_TYPE_ANY 0U
#define AUTOFS_TYPE_INDIRECT 1U
--- autofs-5.1.4.orig/include/state.h
+++ autofs-5.1.4/include/state.h
@@ -55,7 +55,7 @@ struct expire_args {
unsigned int signaled;
struct autofs_point *ap; /* autofs mount we are working on */
enum states state; /* State prune or expire */
- unsigned int how; /* Normal, immediate expire ? */
+ unsigned int how; /* Normal, immediate, forced expire ? */
int status; /* Return status */
};

View File

@ -0,0 +1,383 @@
autofs-5.1.5 - fix additional typing errors
From: Andreas P <nurgrak@gmail.com>
Fix some more typing errors.
imk: added changes discussed on mailing list.
Signed-off-by: Andreas P <nurgrak@gmail.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
INSTALL | 2 +-
README.replicated-server | 2 +-
man/auto.master.5.in | 14 +++++++-------
man/autofs.5 | 9 ++++-----
man/autofs.conf.5.in | 29 ++++++++++++++---------------
man/autofs_ldap_auth.conf.5.in | 2 +-
man/automount.8 | 2 +-
modules/lookup_ldap.c | 4 ++--
modules/replicated.c | 4 ++--
redhat/autofs.conf.default.in | 14 +++++++-------
redhat/autofs.sysconfig | 2 +-
samples/autofs.conf.default.in | 10 +++++-----
13 files changed, 47 insertions(+), 48 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -113,6 +113,7 @@ xx/xx/2018 autofs-5.1.5
- simplify sss source stale check.
- use defines for expire type.
- remove unused function dump_master().
+- fix additional typing errors.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/INSTALL
+++ autofs-5.1.4/INSTALL
@@ -119,7 +119,7 @@ For example, Fedora Core 4 kernel packag
would use the 2.6.12 patch because it applies the 2.6.12 release
candidate revision 6 patch. But the autofs patch doesn't apply
because the rpm also applies a patch somewhere that changes one
-area the the patch also changes but this change is not present
+area the patch also changes but this change is not present
in the 2.6.12 release kernel.
On the other hand, Fedora Core 3 kernel 2.6.12-1.1381_FC3
--- autofs-5.1.4.orig/README.replicated-server
+++ autofs-5.1.4/README.replicated-server
@@ -34,7 +34,7 @@ the following selection rules.
- PROXIMITY_OTHER, host is on a network not directlty
reachable through a local interface.
-2) NFS version and protocol is selected by caclculating the largest
+2) NFS version and protocol is selected by calculating the largest
number of hosts supporting an NFS version and protocol that
have the closest proximity. These hosts are added to the list
in response time order. Hosts may have a corresponding weight
--- autofs-5.1.4.orig/man/auto.master.5.in
+++ autofs-5.1.4/man/auto.master.5.in
@@ -211,12 +211,12 @@ due to application accesses triggered by
This option allows mount propagation of bind mounts to be set to
either \fIslave\fP or \fIprivate\fP. This option may be needed when using
multi-mounts that have bind mounts that bind to a file system that is
-propagation shared. This is becuase the bind mount will have the same
+propagation shared. This is because the bind mount will have the same
properties as its target which causes problems for offset mounts. When
this happens an unwanted offset mount is propagated back to the target
file system resulting in a deadlock when attempting to access the offset.
-This option is a an autofs pseudo mount option that can be used in the
-master map only. By default bind mounts will inherit the mount propagation
+This option is an autofs pseudo mount option that can be used in the
+master map only. By default, bind mounts will inherit the mount propagation
of the target file system.
.TP
.I "\-r, \-\-random-multimount-selection"
@@ -261,7 +261,7 @@ accessing /net/myserver will mount expor
/net/myserver.
.P
NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options
-unless overridden by explicily specifying the "suid", "dev" or "nointr" options in the
+unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the
master map entry.
.SH LDAP MAPS
If the map type \fBldap\fP is specified the mapname is of the form
@@ -277,7 +277,7 @@ configuration, in which case the map nam
.P
If no schema is set in the autofs configuration then autofs will check
each of the commonly used schema for a valid entry and if one is found
-it will used for subsequent lookups.
+it will be used for subsequent lookups.
.P
There are three common schemas in use:
.TP
@@ -351,7 +351,7 @@ connection is to be used then the client
locations must also be configured within the LDAP client.
.P
In OpenLDAP these may be configured in the \fBldap.conf\fP file or in the
-per-user configuration. For example it may be sensible to use the system
+per-user configuration. For example, it may be sensible to use the system
wide configuration for the location of the Certificate Authority certificate
and set the location of the client certificate and private key
in the per-user configuration. The location of these files and the configuration
@@ -399,5 +399,5 @@ configuration will be used to locate the
.BR autofs_ldap_auth.conf (5).
.SH AUTHOR
This manual page was written by Christoph Lameter <chris@waterf.org>,
-for the Debian GNU/Linux system. Edited by <hpa@transmeta.com> and
+for the Debian GNU/Linux system. Edited by <hpa@transmeta.com> and
Ian Kent <raven@themaw.net> .
--- autofs-5.1.4.orig/man/autofs.5
+++ autofs-5.1.4/man/autofs.5
@@ -64,7 +64,6 @@ can't be mounted.
.br
is used to make the weight the sole factor in selecting a server when multiple
servers are present in a map entry.
-and
.TP
.B \-no-use-weight-only
.br
@@ -192,7 +191,7 @@ SHOST Short hostname (domain part remove
.sp
If a program map is used these standard environment variables will have
a prefix of "AUTOFS_" to prevent interpreted languages like python from
-being able to load and execute arbitray code from a user home directory.
+being able to load and execute arbitrary code from a user home directory.
.RE
.sp
Additional entries can be defined with the \-Dvariable=Value map-option to
@@ -293,10 +292,10 @@ may be negated with the \fB!\fP.
For a \fBlocation\fP to be selected for a mount attempt all of its \fBselectors\fP
must evaluate to true. If a \fBlocation\fP is selected for a mount attempt
and succeeds the lookup is completed and returns success. If the mount
-attempt fails the proceedure continues with the next \fBlocation\fP until
+attempt fails the procedure continues with the next \fBlocation\fP until
they have all been tried.
-In addition some \fBselectors\fP take no argumenets, some one argument
+In addition, some \fBselectors\fP take no arguments, some one argument
and others optionally take two arguments.
The \fBselectors\fP that take no arguments are:
@@ -584,7 +583,7 @@ In the first line we have an NFS remote
another nfs mount for the exported directory /work/util from host zeus.
This would be mounted on /test/util.
-Finally we have an example of the use of the \fBsublink\fP option. In
+Finally, we have an example of the use of the \fBsublink\fP option. In
this case the filesystem bilbo:/shared would be mounted on a path
external the automount directory (under the direcory given by
configuration option auto_dir) and the path /test/local either
--- autofs-5.1.4.orig/man/autofs.conf.5.in
+++ autofs-5.1.4/man/autofs.conf.5.in
@@ -91,7 +91,7 @@ set default log level "none", "verbose"
.B force_standard_program_map_env
.br
override the use of a prefix with standard environment variables when a
-program map is executed. Since program maps are run as the privileded
+program map is executed. Since program maps are run as the privileged
user setting these standard environment variables opens automount(8) to
potential user privilege escalation when the program map is written in a
language that can load components from, for example, a user home directory
@@ -110,16 +110,15 @@ and a direct map with 8000 entries would
containing an average of 8 entries, which should be acceptable.
However, if excessive CPU usage is observed during automount lookups
-increasing this option can reduce the CPU overhead considerably becuase
+increasing this option can reduce the CPU overhead considerably because
it reduces the length of the search chains.
Note that the number of entries in a map doesn't necessarily relate
to the number of entries used in the map entry cache.
-There are three distinct cases, direct maps and indirect maps that
-use the "browse" option must be read in their entirity at program
-start so, in these two cases the map size does retate directly to
-the map entry cache size.
+There are two distinct cases where the map hash table can make a
+significant difference, direct maps and indirect maps that use the
+"browse" option.
For indirect maps that do not use the "browse" option entries are
added to the map entry cache at lookup so the number of active cache
@@ -174,7 +173,7 @@ by the number of retries that would be u
.B use_mount_request_log_id
.br
Set whether to use a mount request log id so that log entries for specific
-mount requests can be easily identified in logs that have multiple conncurrent
+mount requests can be easily identified in logs that have multiple concurrent
requests. Default is don't use mount request log ids.
.SS LDAP Configuration
.P
@@ -183,7 +182,7 @@ Configuration settings available are:
.B ldap_timeout
.br
Set the network response timeout (default 8).
-Set timeout value for the synchronous API calls. The default is the LDAP
+Set timeout value for the synchronous API calls. The default is the LDAP
library default of an infinite timeout.
.TP
.B ldap_network_timeout
@@ -323,7 +322,7 @@ cleaned on re-load, which is done when m
so these configuration entries are not used by autofs. An
exception to this is the case where the map is large. In this
case it may be necessary to read the whole map at startup even if
-browsing is is not enabled. Adding the cache:=all option to
+browsing is not enabled. Adding the cache:=all option to
map_options can be used to for this.
.TP
.B localhost_address
@@ -390,14 +389,14 @@ and that will be done.
Allow map keys to be shown in directory listings. This option
can have values of "yes" or "no". The default is "no". A variation
of this option, "browsable", can be used as a pseudo mount option
-in type "auto" map entries to provide provide browsing funtionality
+in type "auto" map entries to provide browsing functionality
in sub-mounts. The amd "browsable_dirs = full" option cannot be
implemented within the current autofs framework and is not supported.
.TP
.B exec_map_timeout
.br
-A timeout is not currently used for for program maps, might be
-implemented.
+A timeout is not currently used for program maps but this might be
+implemented in the future.
.TP
.B tag
.br
@@ -473,7 +472,7 @@ its official host name.
.TP
.B domain_strip
.br
-If set to "yes" the domain name part of the host is strippped
+If set to "yes" the domain name part of the host is stripped
when normalizing hostnames. This can be useful when using of
the same maps in a multiple domain environment.
.TP
@@ -497,8 +496,8 @@ that is used for queries if ldap is to b
.B ldap_hostports
.br
This option has no default value set. It must be set to the URI
-of the LDAP server to be used for lookups wheni ldap is used a
-map source. It may contain a comma or space separated list of
+of the LDAP server to be used for lookups when ldap is used as
+a map source. It may contain a comma or space separated list of
LDAP URIs.
.TP
.B hesiod_base
--- autofs-5.1.4.orig/man/autofs_ldap_auth.conf.5.in
+++ autofs-5.1.4/man/autofs_ldap_auth.conf.5.in
@@ -56,7 +56,7 @@ required in order to perform ldap querie
sasl authenticated connections will be allowed. If it is set to no then
authentication is not needed for ldap server connections. If it is set to
autodetect then the ldap server will be queried to establish a suitable sasl
-authentication mechanism. If no suitable mechanism can be found, connections
+authentication mechanism. If no suitable mechanism can be found, connections
to the ldap server are made without authentication. Finally, if it is set to
simple, then simple authentication will be used instead of SASL.
.TP
--- autofs-5.1.4.orig/man/automount.8
+++ autofs-5.1.4/man/automount.8
@@ -89,7 +89,7 @@ that would be used by autofs for the who
.TP
.I "\-O, \-\-global-options"
Allows the specification of global mount options used for all master
-map entries. These options will either replace or be appened to options
+map entries. These options will either replace or be appended to options
given in a master map entry depending on the APPEND_OPTIONS configuration
setting.
.TP
--- autofs-5.1.4.orig/modules/lookup_ldap.c
+++ autofs-5.1.4/modules/lookup_ldap.c
@@ -1320,11 +1320,11 @@ auth_fail:
ret |= get_property(logopt, root, "external_key", &extern_key);
/*
* For EXTERNAL auth to function we need a client certificate
- * and and certificate key. The ca certificate used to verify
+ * and certificate key. The ca certificate used to verify
* the server certificate must also be set correctly in the
* global configuration as the connection must be encrypted
* and the server and client certificates must have been
- * verified for the EXTERNAL method to be offerred by the
+ * verified for the EXTERNAL method to be offered by the
* server. If the cert and key have not been set in the autofs
* configuration they must be set in the ldap rc file.
*/
--- autofs-5.1.4.orig/modules/replicated.c
+++ autofs-5.1.4/modules/replicated.c
@@ -24,11 +24,11 @@
* - PROXIMITY_OTHER, host is on a network not directlty
* reachable through a local interface.
*
- * 2) NFS version and protocol is selected by caclculating the largest
+ * 2) NFS version and protocol is selected by calculating the largest
* number of hosts supporting an NFS version and protocol that
* have the closest proximity. These hosts are added to the list
* in response time order. Hosts may have a corresponding weight
- * which essentially increaes response time and so influences the
+ * which essentially increases response time and so influences the
* host order.
*
* 3) Hosts at further proximity that support the selected NFS version
--- autofs-5.1.4.orig/redhat/autofs.conf.default.in
+++ autofs-5.1.4/redhat/autofs.conf.default.in
@@ -79,7 +79,7 @@ mount_nfs_default_protocol = 4
# are run as the privileded user this opens
# automount(8) to potential user privilege
# escalation when the program map is written
-# in a language that can load components from,
+# in a language that can load components from,
# for example, a user home directory.
#
# force_standard_program_map_env = no
@@ -87,7 +87,7 @@ mount_nfs_default_protocol = 4
# use_mount_request_log_id - Set whether to use a mount request log
# id so that log entries for specific mount
# requests can be easily identified in logs
-# that have multiple conncurrent requests.
+# that have multiple concurrent requests.
#
#use_mount_request_log_id = no
#
@@ -419,10 +419,10 @@ dismount_interval = 300
# appears to work reasonably well most of the time without the
# update).
#
-# autofs_use_lofs = yes
+#autofs_use_lofs = yes
#
# Several configuration options can be set per mount point.
-# In particulr map_type, map_name, map_defaults, search_path,
+# In particular map_type, map_name, map_defaults, search_path,
# browsable_dirs, dismount_interval and selectors_in_defaults
# (not all of which are currently implemented, see above).
#
@@ -431,6 +431,6 @@ dismount_interval = 300
# master map entry and the format will be inherited for type
# "auto" mounts.
#
-# [ /expamle/mount ]
-# dismount_interval = 60
-# map_type = nis
+#[ /example/mount ]
+#dismount_interval = 60
+#map_type = nis
--- autofs-5.1.4.orig/redhat/autofs.sysconfig
+++ autofs-5.1.4/redhat/autofs.sysconfig
@@ -1,5 +1,5 @@
#
-# Init syatem options
+# Init system options
#
# If the kernel supports using the autofs miscellanous device
# and you wish to use it you must set this configuration option
--- autofs-5.1.4.orig/samples/autofs.conf.default.in
+++ autofs-5.1.4/samples/autofs.conf.default.in
@@ -78,7 +78,7 @@ browse_mode = no
# are run as the privileded user this opens
# automount(8) to potential user privilege
# escalation when the program map is written
-# in a language that can load components from,
+# in a language that can load components from,
# for example, a user home directory.
#
# force_standard_program_map_env = no
@@ -86,7 +86,7 @@ browse_mode = no
# use_mount_request_log_id - Set whether to use a mount request log
# id so that log entries for specific mount
# requests can be easily identified in logs
-# that have multiple conncurrent requests.
+# that have multiple concurrent requests.
#
#use_mount_request_log_id = no
#
@@ -430,6 +430,6 @@ dismount_interval = 300
# master map entry and the format will be inherited for type
# "auto" mounts.
#
-# [ /expamle/mount ]
-# dismount_interval = 60
-# map_type = nis
+#[ /example/mount ]
+#dismount_interval = 60
+#map_type = nis

View File

@ -0,0 +1,202 @@
autofs-5.1.6 - add a hash index to mnt_list
From: Ian Kent <raven@themaw.net>
Add a hash index (and utility functions) to struct mnt_list.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 8 +++
lib/mounts.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -121,6 +121,7 @@ xx/xx/2018 autofs-5.1.5
- change mountpoint to mp in struct ext_mount.
- make external mounts independent of amd_entry.
- make external mounts use simpler hashtable.
+- add a hash index to mnt_list.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -54,10 +54,16 @@ struct mapent;
struct mnt_list {
char *mp;
unsigned int flags;
+
+ /* Hash of all mounts */
+ struct hlist_node hash;
+ unsigned int ref;
+
/*
* List operations ie. get_mnt_list.
*/
struct mnt_list *next;
+
/*
* Tree operations ie. tree_make_tree,
* tree_get_mnt_list etc.
@@ -100,6 +106,8 @@ char *make_mnt_name_string(char *path);
int ext_mount_add(const char *, const char *);
int ext_mount_remove(const char *);
int ext_mount_inuse(const char *);
+struct mnt_list *mnts_lookup_mount(const char *mp);
+void mnts_put_mount(struct mnt_list *mnt);
struct mnt_list *get_mnt_list(const char *path, int include);
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
void free_mnt_list(struct mnt_list *list);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -63,6 +63,11 @@ struct ext_mount {
static DEFINE_HASHTABLE(ext_mounts_hash, EXT_MOUNTS_HASH_BITS);
static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define MNTS_HASH_BITS 7
+
+static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS);
+static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
+
unsigned int linux_version_code(void)
{
struct utsname my_utsname;
@@ -832,6 +837,136 @@ done:
return ret;
}
+static void mnts_hash_mutex_lock(void)
+{
+ int status = pthread_mutex_lock(&mnts_hash_mutex);
+ if (status)
+ fatal(status);
+}
+
+static void mnts_hash_mutex_unlock(void)
+{
+ int status = pthread_mutex_unlock(&mnts_hash_mutex);
+ if (status)
+ fatal(status);
+}
+
+static struct mnt_list *mnts_lookup(const char *mp)
+{
+ uint32_t hval = hash(mp, HASH_SIZE(mnts_hash));
+ struct mnt_list *this;
+
+ if (hlist_empty(&mnts_hash[hval]))
+ return NULL;
+
+ hlist_for_each_entry(this, &mnts_hash[hval], hash) {
+ if (!strcmp(this->mp, mp) && this->ref)
+ return this;
+ }
+
+ return NULL;
+}
+
+static struct mnt_list *mnts_alloc_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = malloc(sizeof(*this));
+ if (!this)
+ goto done;
+ memset(this, 0, sizeof(*this));
+
+ this->mp = strdup(mp);
+ if (!this->mp) {
+ free(this);
+ this = NULL;
+ goto done;
+ }
+
+ this->ref = 1;
+ INIT_HLIST_NODE(&this->hash);
+done:
+ return this;
+}
+
+static void __mnts_get_mount(struct mnt_list *mnt)
+{
+ mnt->ref++;
+}
+
+static void __mnts_put_mount(struct mnt_list *mnt)
+{
+ mnt->ref--;
+ if (!mnt->ref) {
+ hash_del(&mnt->hash);
+ free(mnt->mp);
+ free(mnt);
+ }
+}
+
+static struct mnt_list *mnts_new_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = mnts_lookup(mp);
+ if (this) {
+ __mnts_get_mount(this);
+ goto done;
+ }
+
+ this = mnts_alloc_mount(mp);
+ if (!this)
+ goto done;
+
+ hash_add_str(mnts_hash, &this->hash, this->mp);
+done:
+ return this;
+}
+
+static struct mnt_list *mnts_get_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = mnts_lookup(mp);
+ if (this) {
+ __mnts_get_mount(this);
+ return this;
+ }
+
+ return mnts_new_mount(mp);
+}
+
+static struct mnt_list *__mnts_lookup_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = mnts_lookup(mp);
+ if (this)
+ __mnts_get_mount(this);
+
+ return this;
+}
+
+struct mnt_list *mnts_lookup_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ mnts_hash_mutex_lock();
+ this = __mnts_lookup_mount(mp);
+ mnts_hash_mutex_unlock();
+
+ return this;
+}
+
+void mnts_put_mount(struct mnt_list *mnt)
+{
+ if (!mnt)
+ return;
+ mnts_hash_mutex_lock();
+ __mnts_put_mount(mnt);
+ mnts_hash_mutex_unlock();
+}
+
/* 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

View File

@ -0,0 +1,334 @@
autofs-5.1.6 - add hashtable implementation
From: Ian Kent <raven@themaw.net>
Include the (slightly modified) Linux kernel hashtable implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 19 -----
include/hash.h | 101 +++++++++++++++++++++++++++++++
include/hashtable.h | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 269 insertions(+), 18 deletions(-)
create mode 100644 include/hash.h
create mode 100644 include/hashtable.h
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -117,6 +117,7 @@ xx/xx/2018 autofs-5.1.5
- make bind mounts propagation slave by default.
- fix browse dir not re-created on symlink expire.
- update list.h.
+- add hashtable implementation.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -22,6 +22,7 @@
#include <mntent.h>
#include "config.h"
#include "list.h"
+#include "hash.h"
#include <linux/auto_fs4.h>
@@ -143,24 +144,6 @@ struct autofs_point;
#define UMOUNT_RETRIES 8
#define EXPIRE_RETRIES 3
-static u_int32_t inline hash(const char *key, unsigned int size)
-{
- u_int32_t hashval;
- char *s = (char *) key;
-
- for (hashval = 0; *s != '\0';) {
- hashval += (unsigned char) *s++;
- hashval += (hashval << 10);
- hashval ^= (hashval >> 6);
- }
-
- hashval += (hashval << 3);
- hashval ^= (hashval >> 11);
- hashval += (hashval << 15);
-
- return hashval % size;
-}
-
struct mapent_cache {
pthread_rwlock_t rwlock;
unsigned int size;
--- /dev/null
+++ autofs-5.1.4/include/hash.h
@@ -0,0 +1,101 @@
+#ifndef _LINUX_HASH_H
+#define _LINUX_HASH_H
+/* Fast hashing routine for ints, longs and pointers.
+ (C) 2002 Nadia Yvette Chambers, IBM */
+
+#include <sys/types.h>
+#include <stdint.h>
+
+/*
+ * The "GOLDEN_RATIO_PRIME" is used in ifs/btrfs/brtfs_inode.h and
+ * fs/inode.c. It's not actually prime any more (the previous primes
+ * were actively bad for hashing), but the name remains.
+ */
+#if __WORDSIZE == 32
+#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
+#define hash_long(val, bits) hash_32(val, bits)
+#elif __WORDSIZE == 64
+#define hash_long(val, bits) hash_64(val, bits)
+#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
+#else
+#error Wordsize not 32 or 64
+#endif
+
+/* String based hash function */
+static uint32_t inline hash(const char *key, unsigned int size)
+{
+ u_int32_t hashval;
+ char *s = (char *) key;
+
+ for (hashval = 0; *s != '\0';) {
+ hashval += (unsigned char) *s++;
+ hashval += (hashval << 10);
+ hashval ^= (hashval >> 6);
+ }
+
+ hashval += (hashval << 3);
+ hashval ^= (hashval >> 11);
+ hashval += (hashval << 15);
+
+ return hashval % size;
+}
+
+/*
+ * This hash multiplies the input by a large odd number and takes the
+ * high bits. Since multiplication propagates changes to the most
+ * significant end only, it is essential that the high bits of the
+ * product be used for the hash value.
+ *
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * Although a random odd number will do, it turns out that the golden
+ * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice
+ * properties. (See Knuth vol 3, section 6.4, exercise 9.)
+ *
+ * These are the negative, (1 - phi) = phi**2 = (3 - sqrt(5))/2,
+ * which is very slightly easier to multiply by and makes no
+ * difference to the hash distribution.
+ */
+#define GOLDEN_RATIO_32 0x61C88647
+#define GOLDEN_RATIO_64 0x61C8864680B583EBull
+
+static inline uint32_t __hash_32(uint32_t val)
+{
+ return val * GOLDEN_RATIO_32;
+}
+
+static inline uint32_t hash_32(uint32_t val, unsigned int bits)
+{
+ /* High bits are more random, so use them. */
+ return __hash_32(val) >> (32 - bits);
+}
+
+static __always_inline uint32_t hash_64(uint64_t val, unsigned int bits)
+{
+#if __WORDSIZE == 64
+ /* 64x64-bit multiply is efficient on all 64-bit processors */
+ return val * GOLDEN_RATIO_64 >> (64 - bits);
+#else
+ /* Hash 64 bits using only 32x32-bit multiply. */
+ return hash_32((uint32_t) val ^ __hash_32(val >> 32), bits);
+#endif
+}
+
+static inline uint32_t hash_ptr(const void *ptr, unsigned int bits)
+{
+ return hash_long((unsigned long) ptr, bits);
+}
+
+/* This really should be called fold32_ptr; it does no hashing to speak of. */
+static inline uint32_t hash32_ptr(const void *ptr)
+{
+ unsigned long val = (unsigned long) ptr;
+
+#if __WORDSIZE == 64
+ val ^= (val >> 32);
+#endif
+ return (uint32_t) val;
+}
+
+#endif /* _LINUX_HASH_H */
--- /dev/null
+++ autofs-5.1.4/include/hashtable.h
@@ -0,0 +1,166 @@
+/*
+ * Statically sized hash table implementation
+ * (C) 2012 Sasha Levin <levinsasha928@gmail.com>
+ */
+
+#ifndef _LINUX_HASHTABLE_H
+#define _LINUX_HASHTABLE_H
+
+#include "list.h"
+#include "hash.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+#endif
+
+static inline unsigned int ilog2(unsigned long val) {
+ unsigned int ret = -1;
+
+ while (val != 0) {
+ val >>= 1;
+ ret++;
+ }
+ return ret;
+}
+
+#define DEFINE_HASHTABLE(name, bits) \
+ struct hlist_head name[1 << (bits)] = \
+ { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
+
+#define DECLARE_HASHTABLE(name, bits) \
+ struct hlist_head name[1 << (bits)]
+
+#define HASH_SIZE(name) (ARRAY_SIZE(name))
+#define HASH_BITS(name) ilog2(HASH_SIZE(name))
+
+/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
+#define hash_min(val, bits) \
+ (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
+
+static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
+{
+ unsigned int i;
+
+ for (i = 0; i < sz; i++)
+ INIT_HLIST_HEAD(&ht[i]);
+}
+
+/**
+ * hash_init - initialize a hash table
+ * @hashtable: hashtable to be initialized
+ *
+ * Calculates the size of the hashtable from the given parameter, otherwise
+ * same as hash_init_size.
+ *
+ * This has to be a macro since HASH_BITS() will not work on pointers since
+ * it calculates the size during preprocessing.
+ */
+#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable))
+
+/**
+ * hash_add - add an object to a hashtable
+ * @hashtable: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the key of the object to be added
+ */
+#define hash_add(hashtable, node, key) \
+ hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
+
+/**
+ * hash_add_str - add a string object to a hashtable
+ * @hashtable: hashtable to add to
+ * @node: the &struct hlist_node of the object to be added
+ * @key: the string key of the object to be added
+ */
+#define hash_add_str(hashtable, node, key) \
+ hlist_add_head(node, &hashtable[hash(key, HASH_SIZE(hashtable))])
+
+/**
+ * hash_hashed - check whether an object is in any hashtable
+ * @node: the &struct hlist_node of the object to be checked
+ */
+static inline int hash_hashed(struct hlist_node *node)
+{
+ return !hlist_unhashed(node);
+}
+
+static inline int __hash_empty(struct hlist_head *ht, unsigned int sz)
+{
+ unsigned int i;
+
+ for (i = 0; i < sz; i++)
+ if (!hlist_empty(&ht[i]))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * hash_empty - check whether a hashtable is empty
+ * @hashtable: hashtable to check
+ *
+ * This has to be a macro since HASH_BITS() will not work on pointers since
+ * it calculates the size during preprocessing.
+ */
+#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
+
+/**
+ * hash_del - remove an object from a hashtable
+ * @node: &struct hlist_node of the object to remove
+ */
+static inline void hash_del(struct hlist_node *node)
+{
+ hlist_del_init(node);
+}
+
+/**
+ * hash_for_each - iterate over a hashtable
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each(name, bkt, obj, member) \
+ for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
+ (bkt)++)\
+ hlist_for_each_entry(obj, &name[bkt], member)
+
+/**
+ * hash_for_each_safe - iterate over a hashtable safe against removal of
+ * hash entry
+ * @name: hashtable to iterate
+ * @bkt: integer to use as bucket loop cursor
+ * @tmp: a &struct used for temporary storage
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ */
+#define hash_for_each_safe(name, bkt, tmp, obj, member) \
+ for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
+ (bkt)++)\
+ hlist_for_each_entry_safe(obj, tmp, &name[bkt], member)
+
+/**
+ * hash_for_each_possible - iterate over all possible objects hashing to the
+ * same bucket
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible(name, obj, member, key) \
+ hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member)
+
+/**
+ * hash_for_each_possible_safe - iterate over all possible objects hashing to the
+ * same bucket safe against removals
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @tmp: a &struct used for temporary storage
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ */
+#define hash_for_each_possible_safe(name, obj, tmp, member, key) \
+ hlist_for_each_entry_safe(obj, tmp,\
+ &name[hash_min(key, HASH_BITS(name))], member)
+
+#endif

View File

@ -0,0 +1,225 @@
autofs-5.1.6 - add helper to construct mount point path
From: Ian Kent <raven@themaw.net>
Add convenience helper to construct mount point path.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 3 +++
lib/mounts.c | 23 +++++++++++++++++++++++
modules/mount_bind.c | 19 +++++--------------
modules/mount_changer.c | 19 +++++--------------
modules/mount_ext2.c | 19 +++++--------------
modules/mount_generic.c | 19 +++++--------------
modules/mount_nfs.c | 21 ++++++++-------------
8 files changed, 55 insertions(+), 69 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -135,6 +135,7 @@ xx/xx/2018 autofs-5.1.5
- move submount check into conditional_alarm_add().
- move lib/master.c to daemon/master.c.
- use master_list_empty() for list empty check.
+- add helper to construct mount point path.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -94,6 +94,9 @@ unsigned int linux_version_code(void);
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);
+
struct amd_entry;
struct substvar *addstdenv(struct substvar *sv, const char *prefix);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -339,6 +339,29 @@ int check_nfs_mount_version(struct nfs_m
}
#endif
+int mount_fullpath(char *fullpath, size_t max_len,
+ const char *root, const char *name)
+{
+ int last, len;
+
+ last = strlen(root) - 1;
+
+ /* Root offset of multi-mount or direct or offset mount.
+ * Direct or offset mount, name (or root) is absolute path.
+ */
+ if (root[last] == '/' || *name == '/')
+ len = snprintf(fullpath, max_len, "%s", root);
+ else
+ len = snprintf(fullpath, max_len, "%s/%s", root, name);
+
+ if (len >= max_len)
+ return 0;
+
+ fullpath[len] = '\0';
+
+ return len;
+}
+
static char *set_env_name(const char *prefix, const char *name, char *buf)
{
size_t len;
--- autofs-5.1.4.orig/modules/mount_bind.c
+++ autofs-5.1.4/modules/mount_bind.c
@@ -122,21 +122,12 @@ int mount_mount(struct autofs_point *ap,
}
}
- /* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- len = snprintf(fullpath, len, "%s", root);
- } else if (*name == '/') {
- /*
- * Direct or offset mount, name is absolute path so
- * don't use root (but with move mount changes root
- * is now the same as name).
- */
- len = sprintf(fullpath, "%s", root);
- } else {
- len = sprintf(fullpath, "%s/%s", root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ if (!len) {
+ error(ap->logopt,
+ MODPREFIX "mount point path too long");
+ return 1;
}
- fullpath[len] = '\0';
i = len;
while (--i > 0 && fullpath[i] == '/')
--- autofs-5.1.4.orig/modules/mount_changer.c
+++ autofs-5.1.4/modules/mount_changer.c
@@ -59,21 +59,12 @@ int mount_mount(struct autofs_point *ap,
fstype = "iso9660";
- /* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- len = snprintf(fullpath, len, "%s", root);
- } else if (*name == '/') {
- /*
- * Direct or offset mount, name is absolute path so
- * don't use root (but with move mount changes root
- * is now the same as name).
- */
- len = sprintf(fullpath, "%s", root);
- } else {
- len = sprintf(fullpath, "%s/%s", root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ if (!len) {
+ error(ap->logopt,
+ MODPREFIX "mount point path too long");
+ return 1;
}
- fullpath[len] = '\0';
debug(ap->logopt, MODPREFIX "calling umount %s", what);
--- autofs-5.1.4.orig/modules/mount_ext2.c
+++ autofs-5.1.4/modules/mount_ext2.c
@@ -55,21 +55,12 @@ int mount_mount(struct autofs_point *ap,
if (defaults_get_mount_verbose())
mountlog = &log_info;
- /* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- len = snprintf(fullpath, len, "%s", root);
- } else if (*name == '/') {
- /*
- * Direct or offset mount, name is absolute path so
- * don't use root (but with move mount changes root
- * is now the same as name).
- */
- len = sprintf(fullpath, "%s", root);
- } else {
- len = sprintf(fullpath, "%s/%s", root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ if (!len) {
+ error(ap->logopt,
+ MODPREFIX "mount point path too long");
+ return 1;
}
- fullpath[len] = '\0';
debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
--- autofs-5.1.4.orig/modules/mount_generic.c
+++ autofs-5.1.4/modules/mount_generic.c
@@ -54,21 +54,12 @@ int mount_mount(struct autofs_point *ap,
if (defaults_get_mount_verbose())
mountlog = &log_info;
- /* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- len = snprintf(fullpath, len, "%s", root);
- } else if (*name == '/') {
- /*
- * Direct or offset mount, name is absolute path so
- * don't use root (but with move mount changes root
- * is now the same as name).
- */
- len = sprintf(fullpath, "%s", root);
- } else {
- len = sprintf(fullpath, "%s/%s", root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ if (!len) {
+ error(ap->logopt,
+ MODPREFIX "mount point path too long");
+ return 1;
}
- fullpath[len] = '\0';
debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
--- autofs-5.1.4.orig/modules/mount_nfs.c
+++ autofs-5.1.4/modules/mount_nfs.c
@@ -212,6 +212,14 @@ int mount_mount(struct autofs_point *ap,
nfsoptions, nobind, nosymlink, ro);
}
+ /* Construct mount point directory */
+ len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ if (!len) {
+ error(ap->logopt,
+ MODPREFIX "mount point path too long");
+ return 1;
+ }
+
if (!parse_location(ap->logopt, &hosts, what, flags)) {
info(ap->logopt, MODPREFIX "no hosts available");
return 1;
@@ -266,19 +274,6 @@ dont_probe:
return 1;
}
- /* Construct and perhaps create mount point directory */
-
- /* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- len = snprintf(fullpath, len, "%s", root);
- } else if (*name == '/') {
- len = sprintf(fullpath, "%s", root);
- } else {
- len = sprintf(fullpath, "%s/%s", root, name);
- }
- fullpath[len] = '\0';
-
debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
status = mkdir_path(fullpath, mp_mode);

View File

@ -0,0 +1,74 @@
autofs-5.1.6 - change mountpoint to mp in struct ext_mount
From: Ian Kent <raven@themaw.net>
Use simple name mp instead of mountpoint in struct ext_mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 14 +++++++-------
2 files changed, 8 insertions(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -118,6 +118,7 @@ xx/xx/2018 autofs-5.1.5
- fix browse dir not re-created on symlink expire.
- update list.h.
- add hashtable implementation.
+- change mountpoint to mp in struct ext_mount.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -54,7 +54,7 @@ static size_t maxgrpbuf = 0;
#define EXT_MOUNTS_HASH_SIZE 50
struct ext_mount {
- char *mountpoint;
+ char *mp;
unsigned int umount;
struct list_head mount;
struct list_head mounts;
@@ -743,9 +743,9 @@ static void ext_mounts_hash_init(void)
ext_mounts_hash_init_done = 1;
}
-static struct ext_mount *ext_mount_lookup(const char *mountpoint)
+static struct ext_mount *ext_mount_lookup(const char *mp)
{
- u_int32_t hval = hash(mountpoint, EXT_MOUNTS_HASH_SIZE);
+ u_int32_t hval = hash(mp, EXT_MOUNTS_HASH_SIZE);
struct list_head *p, *head;
if (!ext_mounts_hash_init_done)
@@ -757,7 +757,7 @@ static struct ext_mount *ext_mount_looku
head = &ext_mounts_hash[hval];
list_for_each(p, head) {
struct ext_mount *this = list_entry(p, struct ext_mount, mount);
- if (!strcmp(this->mountpoint, mountpoint))
+ if (!strcmp(this->mp, mp))
return this;
}
return NULL;
@@ -788,8 +788,8 @@ int ext_mount_add(struct list_head *entr
if (!em)
goto done;
- em->mountpoint = strdup(path);
- if (!em->mountpoint) {
+ em->mp = strdup(path);
+ if (!em->mp) {
free(em);
goto done;
}
@@ -828,7 +828,7 @@ int ext_mount_remove(struct list_head *e
if (em->umount)
ret = 1;
if (list_empty(&em->mount)) {
- free(em->mountpoint);
+ free(em->mp);
free(em);
}
}

View File

@ -0,0 +1,52 @@
autofs-5.1.6 - fix browse dir not re-created on symlink expire
From: Ian Kent <raven@themaw.net>
If symlinks are being used for mounts and the autofs mount has browse mode
enabled when a symlink is removed at expire the browse mode directory needs
to be re-created.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -115,6 +115,7 @@ xx/xx/2018 autofs-5.1.5
- remove unused function dump_master().
- fix additional typing errors.
- make bind mounts propagation slave by default.
+- fix browse dir not re-created on symlink expire.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -651,6 +651,25 @@ int umount_multi(struct autofs_point *ap
"failed to remove symlink %s", path);
return 1;
}
+ /* Check if the autofs mount has browse mode enabled.
+ * If so re-create the directory entry.
+ */
+ if (ap->flags | MOUNT_FLAG_GHOST) {
+ int ret;
+
+ /* If the browse directory create fails log an
+ * error and continue anyway since the expire
+ * has succeeded.
+ */
+ ret = mkdir_path(path, mp_mode);
+ if (ret && errno != EEXIST) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(ap->logopt,
+ "mkdir_path %s failed: %s", path, estr);
+ }
+ }
/* Check for an external mount and attempt umount if needed */
mounts_mutex_lock(ap);
entry = __master_find_amdmount(ap, path);

View File

@ -19,17 +19,17 @@ Signed-off-by: Ian Kent <raven@themaw.net>
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -111,6 +111,7 @@ xx/xx/2018 autofs-5.1.5
- use a valid timeout in lookup_prune_one_cache().
- dont prune offset map entries.
- simplify sss source stale check.
@@ -75,6 +75,7 @@
- fix direct mount deadlock.
- fix lookup_prune_one_cache() refactoring change.
- add missing description of null map option.
+- fix empty mounts list return from unlink_mount_tree().
19/12/2017 autofs-5.1.4
- fix spec file url.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -954,9 +954,13 @@ int unlink_mount_tree(struct autofs_poin
@@ -2115,9 +2115,13 @@ int unlink_mount_tree(struct autofs_poin
struct mnt_list *mnts, *mnt;
int rv, ret = 1;

View File

@ -0,0 +1,60 @@
autofs-5.1.6 - fix program map multi-mount lookup after mount fail
From: Ian Kent <raven@themaw.net>
For the case of a singleton multi-mount program map lookup following
a mount fail (and the negative timeout has passed) the lookup key is
what's expected for an indirect map key but the the root offset map
entry already exists. This causes autofs to think it has an incorrect
lookup key and it fails the lookup when it should take the opptunity
to delete and update the cache entry since it's not actually in use
yet.
If a check is done to see if the lookup is for the root offset,
deleting the entry fails because it contains an offset. Later when
parsing is done the offset will get updated and can get out of sync
with the entry of the multi-mount owner. That's not a problem as the
offsets would be deleted on eventual expire but it's best to clean
out the entry and start a fresh so the most up to date map entry
is being used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_program.c | 7 +++++--
2 files changed, 6 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -27,6 +27,7 @@
- rename path to m_offset in update_offset_entry().
- don't pass root to do_mount_autofs_offset().
- rename tree implementation functions.
+- fix program map multi-mount lookup after mount fail.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_program.c
+++ autofs-5.1.4/modules/lookup_program.c
@@ -664,7 +664,7 @@ int lookup_mount(struct autofs_point *ap
name_len, ent, ctxt->parse->context);
goto out_free;
} else {
- if (me->multi) {
+ if (me->multi && me->multi != me) {
cache_unlock(mc);
warn(ap->logopt, MODPREFIX
"unexpected lookup for active multi-mount"
@@ -674,8 +674,11 @@ int lookup_mount(struct autofs_point *ap
cache_unlock(mc);
cache_writelock(mc);
me = cache_lookup_distinct(mc, name);
- if (me)
+ if (me) {
+ if (me->multi)
+ cache_delete_offset_list(mc, name);
cache_delete(mc, name);
+ }
cache_unlock(mc);
}
}

View File

@ -0,0 +1,48 @@
autofs-5.1.6 - fix remount expire
From: Ian Kent <raven@themaw.net>
When starting autofs when there are active mounts due to in use
mounts from a previous shutdown, and a mount entry has offsets,
and an offset doesn't have a real mount due to a non-strict fail
returning success for the remount a file handle is incorrectly
left open.
The file handle gets assingned to the offset entry for expires
but since there is no mount to expire it never gets closed which
prevents the multi-mount owner itself from expiring.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -126,6 +126,7 @@ xx/xx/2018 autofs-5.1.5
- use mnt_list for amdmounts.
- make umount_autofs() static.
- remove force parameter from umount_all().
+- fix remount expire.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2205,8 +2205,14 @@ int try_remount(struct autofs_point *ap,
if (fd != -1) {
if (type == t_indirect)
ap->ioctlfd = fd;
- else
+ else {
+ if (type == t_offset &&
+ !is_mounted(me->key, MNTS_REAL)) {
+ ops->close(ap->logopt, fd);
+ fd = -1;
+ }
me->ioctlfd = fd;
+ }
return 1;
}

View File

@ -0,0 +1,57 @@
autofs-5.1.6 - fix stale offset directories disable mount
From: Ian Kent <raven@themaw.net>
When starting autofs when there are active mounts due to in use
mounts from a previous shutdown, and a mount entry has offsets
that are within an autofs mount, the mount point directories are
incorrectly marked as not created by us when re-connecting to the
mount so they are not removed at expire.
Since the base autofs mount directory needs to be empty for mounts
to be triggered these directories disable automounting for the mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 12 ++++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -127,6 +127,7 @@ xx/xx/2018 autofs-5.1.5
- make umount_autofs() static.
- remove force parameter from umount_all().
- fix remount expire.
+- fix stale offset directories disable mount.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2182,15 +2182,23 @@ int try_remount(struct autofs_point *ap,
* number for the mount but we can't know if we created
* it or not. However, if this is an indirect mount with
* the nobrowse option we need to remove the mount point
- * directory at umount anyway.
+ * directory at umount anyway. Also, if this is an offset
+ * mount that's not within a real mount then we know we
+ * created it so we must remove it on expire for the mount
+ * to function.
*/
if (type == t_indirect) {
if (ap->flags & MOUNT_FLAG_GHOST)
ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
else
ap->flags |= MOUNT_FLAG_DIR_CREATED;
- } else
+ } else {
me->flags &= ~MOUNT_FLAG_DIR_CREATED;
+ if (type == t_offset) {
+ if (!is_mounted(me->parent->key, MNTS_REAL))
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
+ }
+ }
/*
* Either we opened the mount or we're re-reading the map.

View File

@ -0,0 +1,220 @@
autofs-5.1.6 - make bind mounts propagation slave by default
From: Ian Kent <raven@themaw.net>
Make setting mount propagation on bind mounts mandatory with a default
of propagation slave.
When using multi-mounts that have bind mounts the bind mount will have
the same properties as its parent which is commonly propagation shared.
And if the mount target is also propagation shared this can lead to a
deadlock when attempting to access the offset mounts. When this happens
an unwanted offset mount is propagated back to the target file system
resulting in a deadlock since the automount target is itself an
(unwanted) automount trigger.
This problem has been present much longer than I originally thought,
perhaps since mount propagation was introduced into the kernel, so
explicitly setting bind mount propagation is the sensible thing to do.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 9 +++++----
lib/master_parse.y | 29 +++++++++++++++++------------
lib/master_tok.l | 1 +
modules/mount_bind.c | 40 ++++++++++++++++++++++------------------
5 files changed, 46 insertions(+), 34 deletions(-)
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -551,14 +551,15 @@ struct kernel_mod_version {
#define MOUNT_FLAG_AMD_CACHE_ALL 0x0080
/* Set mount propagation for bind mounts */
-#define MOUNT_FLAG_SLAVE 0x0100
-#define MOUNT_FLAG_PRIVATE 0x0200
+#define MOUNT_FLAG_SHARED 0x0100
+#define MOUNT_FLAG_SLAVE 0x0200
+#define MOUNT_FLAG_PRIVATE 0x0400
/* Use strict expire semantics if requested and kernel supports it */
-#define MOUNT_FLAG_STRICTEXPIRE 0x0400
+#define MOUNT_FLAG_STRICTEXPIRE 0x0800
/* Indicator for applications to ignore the mount entry */
-#define MOUNT_FLAG_IGNORE 0x0800
+#define MOUNT_FLAG_IGNORE 0x1000
struct autofs_point {
pthread_t thid;
--- autofs-5.1.4.orig/lib/master_parse.y
+++ autofs-5.1.4/lib/master_parse.y
@@ -59,8 +59,6 @@ static long timeout;
static long negative_timeout;
static unsigned symlnk;
static unsigned strictexpire;
-static unsigned slave;
-static unsigned private;
static unsigned nobind;
static unsigned ghost;
extern unsigned global_selection_options;
@@ -72,6 +70,14 @@ static int tmp_argc;
static char **local_argv;
static int local_argc;
+#define PROPAGATION_SHARED MOUNT_FLAG_SHARED
+#define PROPAGATION_SLAVE MOUNT_FLAG_SLAVE
+#define PROPAGATION_PRIVATE MOUNT_FLAG_PRIVATE
+#define PROPAGATION_MASK (MOUNT_FLAG_SHARED | \
+ MOUNT_FLAG_SLAVE | \
+ MOUNT_FLAG_PRIVATE)
+static unsigned int propagation;
+
static char errstr[MAX_ERR_LEN];
static unsigned int verbose;
@@ -106,7 +112,7 @@ static int master_fprintf(FILE *, char *
%token MAP
%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE
%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE
-%token OPT_STRICTEXPIRE OPT_SLAVE OPT_PRIVATE
+%token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE
%token COLON COMMA NL DDASH
%type <strtype> map
%type <strtype> options
@@ -208,6 +214,7 @@ line:
| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
| PATH OPT_SYMLINK { master_notify($1); YYABORT; }
| PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; }
+ | PATH OPT_SHARED { master_notify($1); YYABORT; }
| PATH OPT_SLAVE { master_notify($1); YYABORT; }
| PATH OPT_PRIVATE { master_notify($1); YYABORT; }
| PATH OPT_NOBIND { master_notify($1); YYABORT; }
@@ -622,8 +629,9 @@ daemon_option: OPT_TIMEOUT NUMBER { time
| OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
| OPT_SYMLINK { symlnk = 1; }
| OPT_STRICTEXPIRE { strictexpire = 1; }
- | OPT_SLAVE { slave = 1; }
- | OPT_PRIVATE { private = 1; }
+ | OPT_SHARED { propagation = PROPAGATION_SHARED; }
+ | OPT_SLAVE { propagation = PROPAGATION_SLAVE; }
+ | OPT_PRIVATE { propagation = PROPAGATION_PRIVATE; }
| OPT_NOBIND { nobind = 1; }
| OPT_NOGHOST { ghost = 0; }
| OPT_GHOST { ghost = 1; }
@@ -697,8 +705,7 @@ static void local_init_vars(void)
negative_timeout = 0;
symlnk = 0;
strictexpire = 0;
- slave = 0;
- private = 0;
+ propagation = PROPAGATION_SLAVE;
nobind = 0;
ghost = defaults_get_browse_mode();
random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
@@ -888,7 +895,6 @@ int master_parse_entry(const char *buffe
ghost = 1;
}
-
if (!entry->ap) {
ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0);
if (!ret) {
@@ -899,6 +905,9 @@ int master_parse_entry(const char *buffe
return 0;
}
}
+ entry->ap->flags &= ~(PROPAGATION_MASK);
+ entry->ap->flags |= propagation;
+
if (random_selection)
entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
if (use_weight)
@@ -907,10 +916,6 @@ int master_parse_entry(const char *buffe
entry->ap->flags |= MOUNT_FLAG_SYMLINK;
if (strictexpire)
entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE;
- if (slave)
- entry->ap->flags |= MOUNT_FLAG_SLAVE;
- if (private)
- entry->ap->flags |= MOUNT_FLAG_PRIVATE;
if (negative_timeout)
entry->ap->negative_timeout = negative_timeout;
if (mode && mode < LONG_MAX)
--- autofs-5.1.4.orig/lib/master_tok.l
+++ autofs-5.1.4/lib/master_tok.l
@@ -389,6 +389,7 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTW
-?symlink { return(OPT_SYMLINK); }
-?nobind { return(OPT_NOBIND); }
-?nobrowse { return(OPT_NOGHOST); }
+ -?shared { return(OPT_SHARED); }
-?slave { return(OPT_SLAVE); }
-?private { return(OPT_PRIVATE); }
-?strictexpire { return(OPT_STRICTEXPIRE); }
--- autofs-5.1.4.orig/modules/mount_bind.c
+++ autofs-5.1.4/modules/mount_bind.c
@@ -153,6 +153,7 @@ int mount_mount(struct autofs_point *ap,
if (!symlnk && bind_works) {
int status, existed = 1;
+ int flags;
debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
@@ -190,24 +191,27 @@ int mount_mount(struct autofs_point *ap,
what, fstype, fullpath);
}
- if (ap->flags & (MOUNT_FLAG_SLAVE | MOUNT_FLAG_PRIVATE)) {
- int flags = MS_SLAVE;
-
- if (ap->flags & MOUNT_FLAG_PRIVATE)
- flags = MS_PRIVATE;
-
- /* The bind mount has succeeded but if the target
- * mount is propagation shared propagation of child
- * mounts (autofs offset mounts for example) back to
- * the target of the bind mount must be avoided or
- * autofs trigger mounts will deadlock.
- */
- err = mount(NULL, fullpath, NULL, flags, NULL);
- if (err) {
- warn(ap->logopt,
- "failed to set propagation for %s",
- fullpath, root);
- }
+ /* The bind mount has succeeded, now set the mount propagation.
+ *
+ * The default is propagation shared, change it if the master
+ * map entry has a different option specified.
+ */
+ flags = MS_SLAVE;
+ if (ap->flags & MOUNT_FLAG_PRIVATE)
+ flags = MS_PRIVATE;
+ else if (ap->flags & MOUNT_FLAG_SHARED)
+ flags = MS_SHARED;
+
+ /* Note: If the parent mount is propagation shared propagation
+ * of child mounts (autofs offset mounts for example) back to
+ * the target of the bind mount can happen in some cases and
+ * must be avoided or autofs trigger mounts will deadlock.
+ */
+ err = mount(NULL, fullpath, NULL, flags, NULL);
+ if (err) {
+ warn(ap->logopt,
+ "failed to set propagation for %s",
+ fullpath, root);
}
return 0;
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -114,6 +114,7 @@ xx/xx/2018 autofs-5.1.5
- use defines for expire type.
- remove unused function dump_master().
- fix additional typing errors.
+- make bind mounts propagation slave by default.
19/12/2017 autofs-5.1.4
- fix spec file url.

View File

@ -0,0 +1,382 @@
autofs-5.1.6 - make external mounts independent of amd_entry
From: Ian Kent <raven@themaw.net>
The external mounts used by amd map entries should not depend
on the amd map entry.
The external mounts list is keyed by the external mount path
and this should be what's used to locate them.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 4 -
include/mounts.h | 6 +-
include/parse_amd.h | 1
lib/master.c | 3 -
lib/mounts.c | 114 ++++++++++++++++++++++++++++++----------------------
modules/parse_amd.c | 14 +++---
7 files changed, 80 insertions(+), 63 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -119,6 +119,7 @@ xx/xx/2018 autofs-5.1.5
- update list.h.
- add hashtable implementation.
- change mountpoint to mp in struct ext_mount.
+- make external mounts independent of amd_entry.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -613,7 +613,7 @@ static int umount_subtree_mounts(struct
}
list_del(&entry->entries);
mounts_mutex_unlock(ap);
- umount_amd_ext_mount(ap, entry);
+ umount_amd_ext_mount(ap, entry->fs);
free_amd_entry(entry);
}
done:
@@ -679,7 +679,7 @@ int umount_multi(struct autofs_point *ap
}
list_del(&entry->entries);
mounts_mutex_unlock(ap);
- umount_amd_ext_mount(ap, entry);
+ umount_amd_ext_mount(ap, entry->fs);
free_amd_entry(entry);
return 0;
}
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -97,8 +97,8 @@ unsigned int get_kver_minor(void);
char *make_options_string(char *path, int pipefd,
const char *type, unsigned int flags);
char *make_mnt_name_string(char *path);
-int ext_mount_add(struct list_head *, const char *, unsigned int);
-int ext_mount_remove(struct list_head *, const char *);
+int ext_mount_add(const char *, const char *);
+int ext_mount_remove(const char *);
int ext_mount_inuse(const char *);
struct mnt_list *get_mnt_list(const char *path, int include);
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
@@ -118,7 +118,7 @@ int try_remount(struct autofs_point *, s
void set_indirect_mount_tree_catatonic(struct autofs_point *);
void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *);
int umount_ent(struct autofs_point *, const char *);
-int umount_amd_ext_mount(struct autofs_point *, struct amd_entry *);
+int umount_amd_ext_mount(struct autofs_point *, const char *);
int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
--- autofs-5.1.4.orig/include/parse_amd.h
+++ autofs-5.1.4/include/parse_amd.h
@@ -66,7 +66,6 @@ struct amd_entry {
struct selector *selector;
struct list_head list;
struct list_head entries;
- struct list_head ext_mount;
};
int amd_parse_list(struct autofs_point *,
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -154,10 +154,9 @@ void master_free_autofs_point(struct aut
while (p != head) {
struct amd_entry *entry = list_entry(p, struct amd_entry, entries);
p = p->next;
- if (!list_empty(&entry->ext_mount))
- ext_mount_remove(&entry->ext_mount, entry->fs);
if (!list_empty(&entry->entries))
list_del(&entry->entries);
+ ext_mount_remove(entry->fs);
free_amd_entry(entry);
}
mounts_mutex_unlock(ap);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -54,10 +54,10 @@ static size_t maxgrpbuf = 0;
#define EXT_MOUNTS_HASH_SIZE 50
struct ext_mount {
+ unsigned int ref;
char *mp;
- unsigned int umount;
+ char *umount;
struct list_head mount;
- struct list_head mounts;
};
static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE];
static unsigned int ext_mounts_hash_init_done = 0;
@@ -542,7 +542,6 @@ struct amd_entry *new_amd_entry(const st
new->path = path;
INIT_LIST_HEAD(&new->list);
INIT_LIST_HEAD(&new->entries);
- INIT_LIST_HEAD(&new->ext_mount);
return new;
}
@@ -763,7 +762,7 @@ static struct ext_mount *ext_mount_looku
return NULL;
}
-int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount)
+int ext_mount_add(const char *path, const char *umount)
{
struct ext_mount *em;
u_int32_t hval;
@@ -773,13 +772,7 @@ int ext_mount_add(struct list_head *entr
em = ext_mount_lookup(path);
if (em) {
- struct list_head *p, *head;
- head = &em->mounts;
- list_for_each(p, head) {
- if (p == entry)
- goto done;
- }
- list_add_tail(entry, &em->mounts);
+ em->ref++;
ret = 1;
goto done;
}
@@ -787,28 +780,34 @@ int ext_mount_add(struct list_head *entr
em = malloc(sizeof(struct ext_mount));
if (!em)
goto done;
+ memset(em, 0, sizeof(*em));
em->mp = strdup(path);
if (!em->mp) {
free(em);
goto done;
}
- em->umount = umount;
+ if (umount) {
+ em->umount = strdup(umount);
+ if (!em->umount) {
+ free(em->mp);
+ free(em);
+ goto done;
+ }
+ }
+ em->ref = 1;
INIT_LIST_HEAD(&em->mount);
- INIT_LIST_HEAD(&em->mounts);
hval = hash(path, EXT_MOUNTS_HASH_SIZE);
list_add_tail(&em->mount, &ext_mounts_hash[hval]);
- list_add_tail(entry, &em->mounts);
-
ret = 1;
done:
pthread_mutex_unlock(&ext_mount_hash_mutex);
return ret;
}
-int ext_mount_remove(struct list_head *entry, const char *path)
+int ext_mount_remove(const char *path)
{
struct ext_mount *em;
int ret = 0;
@@ -819,18 +818,18 @@ int ext_mount_remove(struct list_head *e
if (!em)
goto done;
- list_del_init(entry);
-
- if (!list_empty(&em->mounts))
+ em->ref--;
+ if (em->ref)
goto done;
else {
list_del_init(&em->mount);
- if (em->umount)
- ret = 1;
if (list_empty(&em->mount)) {
free(em->mp);
+ if (em->umount)
+ free(em->umount);
free(em);
}
+ ret = 1;
}
done:
pthread_mutex_unlock(&ext_mount_hash_mutex);
@@ -846,9 +845,7 @@ int ext_mount_inuse(const char *path)
em = ext_mount_lookup(path);
if (!em)
goto done;
-
- if (!list_empty(&em->mounts))
- ret = 1;
+ ret = em->ref;
done:
pthread_mutex_unlock(&ext_mount_hash_mutex);
return ret;
@@ -2092,29 +2089,49 @@ int umount_ent(struct autofs_point *ap,
return rv;
}
-int umount_amd_ext_mount(struct autofs_point *ap, struct amd_entry *entry)
+int umount_amd_ext_mount(struct autofs_point *ap, const char *path)
{
+ struct ext_mount *em;
+ char *umount = NULL;
+ char *mp;
int rv = 1;
- if (entry->umount) {
- char *prog, *str;
- char **argv;
- int argc = -1;
+ pthread_mutex_lock(&ext_mount_hash_mutex);
- str = strdup(entry->umount);
- if (!str)
+ em = ext_mount_lookup(path);
+ if (!em) {
+ pthread_mutex_unlock(&ext_mount_hash_mutex);
+ goto out;
+ }
+ mp = strdup(em->mp);
+ if (!mp) {
+ pthread_mutex_unlock(&ext_mount_hash_mutex);
+ goto out;
+ }
+ if (em->umount) {
+ umount = strdup(em->umount);
+ if (!umount) {
+ pthread_mutex_unlock(&ext_mount_hash_mutex);
+ free(mp);
goto out;
+ }
+ }
+
+ pthread_mutex_unlock(&ext_mount_hash_mutex);
+
+ if (umount) {
+ char *prog;
+ char **argv;
+ int argc = -1;
prog = NULL;
argv = NULL;
- argc = construct_argv(str, &prog, &argv);
- if (argc == -1) {
- free(str);
- goto out;
- }
+ argc = construct_argv(umount, &prog, &argv);
+ if (argc == -1)
+ goto done;
- if (!ext_mount_remove(&entry->ext_mount, entry->fs)) {
+ if (!ext_mount_remove(mp)) {
rv =0;
goto out_free;
}
@@ -2122,29 +2139,30 @@ int umount_amd_ext_mount(struct autofs_p
rv = spawnv(ap->logopt, prog, (const char * const *) argv);
if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv)))
error(ap->logopt,
- "failed to umount program mount at %s", entry->fs);
+ "failed to umount program mount at %s", mp);
else {
rv = 0;
- debug(ap->logopt,
- "umounted program mount at %s", entry->fs);
- rmdir_path(ap, entry->fs, ap->dev);
+ debug(ap->logopt, "umounted program mount at %s", mp);
+ rmdir_path(ap, mp, ap->dev);
}
out_free:
free_argv(argc, (const char **) argv);
- free(str);
- goto out;
+ goto done;
}
- if (ext_mount_remove(&entry->ext_mount, entry->fs)) {
- rv = umount_ent(ap, entry->fs);
+ if (ext_mount_remove(mp)) {
+ rv = umount_ent(ap, mp);
if (rv)
error(ap->logopt,
- "failed to umount external mount %s", entry->fs);
+ "failed to umount external mount %s", mp);
else
- debug(ap->logopt,
- "umounted external mount %s", entry->fs);
+ debug(ap->logopt, "umounted external mount %s", mp);
}
+done:
+ if (umount)
+ free(umount);
+ free(mp);
out:
return rv;
}
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1136,7 +1136,7 @@ symlink:
if (entry->sublink) {
/* failed to complete sublink mount */
- umount_amd_ext_mount(ap, entry);
+ umount_amd_ext_mount(ap, entry->fs);
}
out:
return ret;
@@ -1183,8 +1183,8 @@ static int do_generic_mount(struct autof
goto out;
umount = 1;
}
- /* We have an external mount */
- if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) {
+ /* If we have an external mount add it to the list */
+ if (umount && !ext_mount_add(entry->fs, entry->umount)) {
umount_ent(ap, entry->fs);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s",
@@ -1235,7 +1235,7 @@ static int do_nfs_mount(struct autofs_po
umount = 1;
}
/* We might be using an external mount */
- if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) {
+ if (umount && !ext_mount_add(entry->fs, entry->umount)) {
umount_ent(ap, entry->fs);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s", entry->fs);
@@ -1429,7 +1429,7 @@ static int do_program_mount(struct autof
/* An external mount with path entry->fs exists
* so ext_mount_add() won't fail.
*/
- ext_mount_add(&entry->ext_mount, entry->fs, 1);
+ ext_mount_add(entry->fs, entry->umount);
} else {
rv = mkdir_path(entry->fs, mp_mode);
if (rv && errno != EEXIST) {
@@ -1445,7 +1445,7 @@ static int do_program_mount(struct autof
rv = spawnv(ap->logopt, prog, (const char * const *) argv);
if (WIFEXITED(rv) && !WEXITSTATUS(rv)) {
- if (ext_mount_add(&entry->ext_mount, entry->fs, 1)) {
+ if (ext_mount_add(entry->fs, entry->umount)) {
rv = 0;
debug(ap->logopt, MODPREFIX
"%s: mounted %s", entry->type, entry->fs);
@@ -1470,7 +1470,7 @@ do_free:
if (!rv)
goto out;
- if (umount_amd_ext_mount(ap, entry)) {
+ if (umount_amd_ext_mount(ap, entry->fs)) {
if (!ext_mount_inuse(entry->fs))
rmdir_path(ap, entry->fs, ap->dev);
debug(ap->logopt, MODPREFIX

View File

@ -0,0 +1,128 @@
autofs-5.1.6 - make external mounts use simpler hashtable
From: Ian Kent <raven@themaw.net>
Use the added hashtable implementation for the external mounts
hashtable.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 49 +++++++++++++++----------------------------------
2 files changed, 16 insertions(+), 34 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -120,6 +120,7 @@ xx/xx/2018 autofs-5.1.5
- add hashtable implementation.
- change mountpoint to mp in struct ext_mount.
- make external mounts independent of amd_entry.
+- make external mounts use simpler hashtable.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -29,6 +29,7 @@
#include <libgen.h>
#include "automount.h"
+#include "hashtable.h"
#define MAX_OPTIONS_LEN 80
#define MAX_MNT_NAME_LEN 30
@@ -51,16 +52,15 @@ static const char kver_options_template[
extern size_t detached_thread_stack_size;
static size_t maxgrpbuf = 0;
-#define EXT_MOUNTS_HASH_SIZE 50
+#define EXT_MOUNTS_HASH_BITS 6
struct ext_mount {
unsigned int ref;
char *mp;
char *umount;
- struct list_head mount;
+ struct hlist_node mount;
};
-static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE];
-static unsigned int ext_mounts_hash_init_done = 0;
+static DEFINE_HASHTABLE(ext_mounts_hash, EXT_MOUNTS_HASH_BITS);
static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
unsigned int linux_version_code(void)
@@ -734,38 +734,22 @@ char *make_mnt_name_string(char *path)
return mnt_name;
}
-static void ext_mounts_hash_init(void)
-{
- int i;
- for (i = 0; i < EXT_MOUNTS_HASH_SIZE; i++)
- INIT_LIST_HEAD(&ext_mounts_hash[i]);
- ext_mounts_hash_init_done = 1;
-}
-
static struct ext_mount *ext_mount_lookup(const char *mp)
{
- u_int32_t hval = hash(mp, EXT_MOUNTS_HASH_SIZE);
- struct list_head *p, *head;
-
- if (!ext_mounts_hash_init_done)
- ext_mounts_hash_init();
-
- if (list_empty(&ext_mounts_hash[hval]))
- return NULL;
+ uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash));
+ struct ext_mount *this;
- head = &ext_mounts_hash[hval];
- list_for_each(p, head) {
- struct ext_mount *this = list_entry(p, struct ext_mount, mount);
+ hlist_for_each_entry(this, &ext_mounts_hash[hval], mount) {
if (!strcmp(this->mp, mp))
return this;
}
+
return NULL;
}
int ext_mount_add(const char *path, const char *umount)
{
struct ext_mount *em;
- u_int32_t hval;
int ret = 0;
pthread_mutex_lock(&ext_mount_hash_mutex);
@@ -796,10 +780,9 @@ int ext_mount_add(const char *path, cons
}
}
em->ref = 1;
- INIT_LIST_HEAD(&em->mount);
+ INIT_HLIST_NODE(&em->mount);
- hval = hash(path, EXT_MOUNTS_HASH_SIZE);
- list_add_tail(&em->mount, &ext_mounts_hash[hval]);
+ hash_add_str(ext_mounts_hash, &em->mount, em->mp);
ret = 1;
done:
@@ -822,13 +805,11 @@ int ext_mount_remove(const char *path)
if (em->ref)
goto done;
else {
- list_del_init(&em->mount);
- if (list_empty(&em->mount)) {
- free(em->mp);
- if (em->umount)
- free(em->umount);
- free(em);
- }
+ hlist_del_init(&em->mount);
+ free(em->mp);
+ if (em->umount)
+ free(em->umount);
+ free(em);
ret = 1;
}
done:

View File

@ -0,0 +1,86 @@
autofs-5.1.6 - make umount_autofs() static
From: Ian Kent <raven@themaw.net>
The function umount_autofs() is only called within daemon/automount.c
so make it static.
Also it's only ever called with it's force parameter true so remove
it as well and because this parameter is always true the failure case
when calling umount_all() never happens.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 11 +++++------
include/automount.h | 1 -
3 files changed, 6 insertions(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -124,6 +124,7 @@ xx/xx/2018 autofs-5.1.5
- add a hash index to mnt_list.
- use mnt_list for submounts.
- use mnt_list for amdmounts.
+- make umount_autofs() static.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -722,7 +722,7 @@ static int umount_all(struct autofs_poin
return left;
}
-int umount_autofs(struct autofs_point *ap, const char *root, int force)
+static int umount_autofs(struct autofs_point *ap, const char *root)
{
int ret = 0;
@@ -737,8 +737,7 @@ int umount_autofs(struct autofs_point *a
lookup_close_lookup(ap);
if (ap->type == LKP_INDIRECT) {
- if (umount_all(ap, force) && !force)
- return -1;
+ umount_all(ap, 1);
ret = umount_autofs_indirect(ap, root);
} else
ret = umount_autofs_direct(ap);
@@ -1867,7 +1866,7 @@ int handle_mounts_exit(struct autofs_poi
* to check for possible recovery.
*/
if (ap->type == LKP_DIRECT) {
- umount_autofs(ap, NULL, 1);
+ umount_autofs(ap, NULL);
handle_mounts_cleanup(ap);
return 1;
}
@@ -1878,7 +1877,7 @@ int handle_mounts_exit(struct autofs_poi
* so we can continue. This can happen if a lookup
* occurs while we're trying to umount.
*/
- ret = umount_autofs(ap, NULL, 1);
+ ret = umount_autofs(ap, NULL);
if (!ret) {
set_indirect_mount_tree_catatonic(ap);
handle_mounts_cleanup(ap);
@@ -1934,7 +1933,7 @@ void *handle_mounts(void *arg)
if (!(do_force_unlink & UNLINK_AND_EXIT))
crit(ap->logopt, "mount of %s failed!", ap->path);
suc->status = 1;
- umount_autofs(ap, root, 1);
+ umount_autofs(ap, root);
free(root);
pthread_setcancelstate(cancel_state, NULL);
pthread_exit(NULL);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -599,7 +599,6 @@ int mount_autofs_direct(struct autofs_po
int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset);
void submount_signal_parent(struct autofs_point *ap, unsigned int success);
void close_mount_fds(struct autofs_point *ap);
-int umount_autofs(struct autofs_point *ap, const char *root, int force);
int umount_autofs_indirect(struct autofs_point *ap, const char *root);
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me);
int umount_autofs_direct(struct autofs_point *ap);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,201 @@
autofs-5.1.6 - move submount check into conditional_alarm_add()
From: Ian Kent <raven@themaw.net>
The expire of submounts is driven by the top level autofs mount in the
mount tree so an expire alarm doesn't need to set if the autofs point
is a submount.
Take that check into conditional_alarm_add().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 6 ++----
daemon/direct.c | 3 +--
daemon/indirect.c | 3 +--
daemon/state.c | 26 +++++++++-----------------
lib/alarm.c | 2 ++
lib/mounts.c | 6 ++----
7 files changed, 18 insertions(+), 29 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -132,6 +132,7 @@ xx/xx/2018 autofs-5.1.5
- use struct mnt_list mounted list for expire.
- remove unused function tree_get_mnt_list().
- only add expre alarm for active mounts.
+- move submount check into conditional_alarm_add().
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -1843,8 +1843,7 @@ int handle_mounts_exit(struct autofs_poi
}
if (ap->state != ST_SHUTDOWN) {
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
if (ap->submount)
@@ -1888,8 +1887,7 @@ int handle_mounts_exit(struct autofs_poi
/* Failed shutdown returns to ready */
warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
if (ap->submount)
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1246,8 +1246,7 @@ static void *do_mount_direct(void *arg)
mnts_set_mounted_mount(ap, mt.name);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
/* TODO: get mount return status from lookup_nss_mount */
ops->send_fail(ap->logopt,
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -754,8 +754,7 @@ static void *do_mount_indirect(void *arg
mnts_set_mounted_mount(ap, mt.name);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
/* TODO: get mount return status from lookup_nss_mount */
ops->send_fail(ap->logopt,
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -154,7 +154,7 @@ void expire_cleanup(void *arg)
} else if (ap->submount > 1)
ap->submount = 1;
- if (ap->state == ST_EXPIRE && !ap->submount)
+ if (ap->state == ST_EXPIRE)
conditional_alarm_add(ap, ap->exp_runfreq);
/* FALLTHROUGH */
@@ -172,8 +172,7 @@ void expire_cleanup(void *arg)
rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle);
if (!rv && !idle && !ap->shutdown) {
next = ST_READY;
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
break;
}
@@ -186,8 +185,7 @@ void expire_cleanup(void *arg)
/* Failed shutdown returns to ready */
warn(ap->logopt, "filesystem %s still busy", ap->path);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
next = ST_READY;
break;
#endif
@@ -577,8 +575,7 @@ static unsigned int st_readmap(struct au
error(ap->logopt, "failed to malloc readmap cond struct");
/* It didn't work: return to ready */
st_ready(ap);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
return 0;
}
@@ -604,8 +601,7 @@ static unsigned int st_readmap(struct au
free(ra);
/* It didn't work: return to ready */
st_ready(ap);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
return 0;
}
ap->readmap_thread = thid;
@@ -640,8 +636,7 @@ static unsigned int st_prepare_shutdown(
case EXP_ERROR:
case EXP_PARTIAL:
/* It didn't work: return to ready */
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
@@ -666,8 +661,7 @@ static unsigned int st_force_shutdown(st
case EXP_ERROR:
case EXP_PARTIAL:
/* It didn't work: return to ready */
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
@@ -699,8 +693,7 @@ static unsigned int st_prune(struct auto
switch (expire_proc(ap, AUTOFS_EXP_IMMEDIATE)) {
case EXP_ERROR:
case EXP_PARTIAL:
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
@@ -720,8 +713,7 @@ static unsigned int st_expire(struct aut
switch (expire_proc(ap, AUTOFS_EXP_NORMAL)) {
case EXP_ERROR:
case EXP_PARTIAL:
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
--- autofs-5.1.4.orig/lib/alarm.c
+++ autofs-5.1.4/lib/alarm.c
@@ -187,6 +187,8 @@ int conditional_alarm_add(struct autofs_
{
int status;
+ if (ap->submount)
+ return 1;
if (!mnts_has_mounted_mounts(ap))
return 1;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1921,8 +1921,7 @@ static int do_remount_direct(struct auto
info(ap->logopt, "re-connected to %s", path);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
status = REMOUNT_FAIL;
info(ap->logopt, "failed to re-connect %s", path);
@@ -1997,8 +1996,7 @@ static int do_remount_indirect(struct au
info(ap->logopt, "re-connected to %s", buf);
- if (!ap->submount)
- conditional_alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
status = REMOUNT_FAIL;
info(ap->logopt, "failed to re-connect %s", buf);

View File

@ -0,0 +1,334 @@
autofs-5.1.6 - only add expire alarm for active mounts
From: Ian Kent <raven@themaw.net>
There's no need to add expire alarms for mount points that have no
expirable mounts.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 9 +-------
daemon/direct.c | 3 ++
daemon/indirect.c | 3 ++
daemon/state.c | 25 +++++++++++-----------
include/automount.h | 1
include/mounts.h | 1
lib/alarm.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++----
lib/mounts.c | 19 +++++++++++++++++
9 files changed, 96 insertions(+), 23 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -131,6 +131,7 @@ xx/xx/2018 autofs-5.1.5
- use struct mnt_list to track mounted mounts.
- use struct mnt_list mounted list for expire.
- remove unused function tree_get_mnt_list().
+- only add expre alarm for active mounts.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -1844,7 +1844,7 @@ int handle_mounts_exit(struct autofs_poi
if (ap->state != ST_SHUTDOWN) {
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
if (ap->submount)
@@ -1889,7 +1889,7 @@ int handle_mounts_exit(struct autofs_poi
/* Failed shutdown returns to ready */
warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path);
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
if (ap->submount)
@@ -1952,11 +1952,6 @@ void *handle_mounts(void *arg)
suc->status = 0;
pthread_cleanup_pop(1);
- /* We often start several automounters at the same time. Add some
- randomness so we don't all expire at the same time. */
- if (!ap->submount && ap->exp_runfreq)
- alarm_add(ap, ap->exp_runfreq + rand() % ap->exp_runfreq);
-
pthread_setcancelstate(cancel_state, NULL);
while (1) {
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1245,6 +1245,9 @@ static void *do_mount_direct(void *arg)
info(ap->logopt, "mounted %s", mt.name);
mnts_set_mounted_mount(ap, mt.name);
+
+ if (!ap->submount)
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
/* TODO: get mount return status from lookup_nss_mount */
ops->send_fail(ap->logopt,
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -753,6 +753,9 @@ static void *do_mount_indirect(void *arg
info(ap->logopt, "mounted %s", buf);
mnts_set_mounted_mount(ap, mt.name);
+
+ if (!ap->submount)
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
/* TODO: get mount return status from lookup_nss_mount */
ops->send_fail(ap->logopt,
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -155,7 +155,7 @@ void expire_cleanup(void *arg)
ap->submount = 1;
if (ap->state == ST_EXPIRE && !ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
/* FALLTHROUGH */
@@ -173,7 +173,7 @@ void expire_cleanup(void *arg)
if (!rv && !idle && !ap->shutdown) {
next = ST_READY;
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
break;
}
@@ -187,7 +187,7 @@ void expire_cleanup(void *arg)
/* Failed shutdown returns to ready */
warn(ap->logopt, "filesystem %s still busy", ap->path);
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
next = ST_READY;
break;
#endif
@@ -522,9 +522,10 @@ static void *do_readmap(void *arg)
* alarm will have been added. So add it here if there are
* now map entries.
*/
- if (append_alarm && ap->exp_runfreq)
- alarm_add(ap, ap->exp_runfreq +
- rand() % ap->exp_runfreq);
+ if (append_alarm && ap->exp_runfreq) {
+ time_t seconds = ap->exp_runfreq + rand() % ap->exp_runfreq;
+ conditional_alarm_add(ap, seconds);
+ }
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
@@ -577,7 +578,7 @@ static unsigned int st_readmap(struct au
/* It didn't work: return to ready */
st_ready(ap);
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
return 0;
}
@@ -604,7 +605,7 @@ static unsigned int st_readmap(struct au
/* It didn't work: return to ready */
st_ready(ap);
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
return 0;
}
ap->readmap_thread = thid;
@@ -640,7 +641,7 @@ static unsigned int st_prepare_shutdown(
case EXP_PARTIAL:
/* It didn't work: return to ready */
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
@@ -666,7 +667,7 @@ static unsigned int st_force_shutdown(st
case EXP_PARTIAL:
/* It didn't work: return to ready */
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
@@ -699,7 +700,7 @@ static unsigned int st_prune(struct auto
case EXP_ERROR:
case EXP_PARTIAL:
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
@@ -720,7 +721,7 @@ static unsigned int st_expire(struct aut
case EXP_ERROR:
case EXP_PARTIAL:
if (!ap->submount)
- alarm_add(ap, ap->exp_runfreq);
+ conditional_alarm_add(ap, ap->exp_runfreq);
st_ready(ap);
return 0;
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -637,6 +637,7 @@ static inline time_t monotonic_time(time
/* Expire alarm handling routines */
int alarm_start_handler(void);
int alarm_add(struct autofs_point *ap, time_t seconds);
+int conditional_alarm_add(struct autofs_point *ap, time_t seconds);
void alarm_delete(struct autofs_point *ap);
#endif
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -125,6 +125,7 @@ void mnts_remove_amdmount(const char *mp
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);
+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);
--- autofs-5.1.4.orig/lib/alarm.c
+++ autofs-5.1.4/lib/alarm.c
@@ -41,7 +41,7 @@ do { \
} while (0)
/* Insert alarm entry on ordered list. */
-int alarm_add(struct autofs_point *ap, time_t seconds)
+int __alarm_add(struct autofs_point *ap, time_t seconds)
{
struct list_head *head;
struct list_head *p;
@@ -62,8 +62,6 @@ int alarm_add(struct autofs_point *ap, t
new->cancel = 0;
new->time = now + seconds;
- alarm_lock();
-
head = &alarms;
/* Check if we have a pending alarm */
@@ -97,9 +95,42 @@ int alarm_add(struct autofs_point *ap, t
fatal(status);
}
+ return 1;
+}
+
+int alarm_add(struct autofs_point *ap, time_t seconds)
+{
+ int status;
+
+ alarm_lock();
+ status = __alarm_add(ap, seconds);
alarm_unlock();
- return 1;
+ return status;
+}
+
+static int __alarm_exists(struct autofs_point *ap)
+{
+ struct list_head *head;
+ struct list_head *p;
+
+ head = &alarms;
+
+ if (list_empty(head))
+ return 0;
+
+ p = head->next;
+ while (p != head) {
+ struct alarm *this;
+
+ this = list_entry(p, struct alarm, list);
+ p = p->next;
+
+ if (ap == this->ap)
+ return 1;
+ }
+
+ return 0;
}
void alarm_delete(struct autofs_point *ap)
@@ -152,6 +183,24 @@ void alarm_delete(struct autofs_point *a
return;
}
+int conditional_alarm_add(struct autofs_point *ap, time_t seconds)
+{
+ int status;
+
+ if (!mnts_has_mounted_mounts(ap))
+ return 1;
+
+ alarm_lock();
+ if (__alarm_exists(ap)) {
+ alarm_unlock();
+ return 1;
+ }
+ status = __alarm_add(ap, seconds);
+ alarm_unlock();
+
+ return status;
+}
+
static void *alarm_handler(void *arg)
{
struct list_head *head;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1208,6 +1208,19 @@ void mnts_set_mounted_mount(struct autof
}
}
+unsigned int mnts_has_mounted_mounts(struct autofs_point *ap)
+{
+ unsigned int has_mounted_mounts = 0;
+
+ mnts_hash_mutex_lock();
+ if (list_empty(&ap->mounts))
+ goto done;
+ has_mounted_mounts = 1;
+done:
+ mnts_hash_mutex_unlock();
+ return has_mounted_mounts;
+}
+
struct node {
struct mnt_list *mnt;
struct node *left;
@@ -1907,6 +1920,9 @@ static int do_remount_direct(struct auto
mnts_set_mounted_mount(ap, path);
info(ap->logopt, "re-connected to %s", path);
+
+ if (!ap->submount)
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
status = REMOUNT_FAIL;
info(ap->logopt, "failed to re-connect %s", path);
@@ -1980,6 +1996,9 @@ static int do_remount_indirect(struct au
mnts_set_mounted_mount(ap, buf);
info(ap->logopt, "re-connected to %s", buf);
+
+ if (!ap->submount)
+ conditional_alarm_add(ap, ap->exp_runfreq);
} else {
status = REMOUNT_FAIL;
info(ap->logopt, "failed to re-connect %s", buf);

View File

@ -0,0 +1,63 @@
autofs-5.1.6 - remove force parameter from umount_all()
From: Ian Kent <raven@themaw.net>
The function umount_all() is always called with it's force parameter
true so remove it.
Because the failure case is not used make the function void as well.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 9 +++------
2 files changed, 4 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -125,6 +125,7 @@ xx/xx/2018 autofs-5.1.5
- use mnt_list for submounts.
- use mnt_list for amdmounts.
- make umount_autofs() static.
+- remove force parameter from umount_all().
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -99,7 +99,6 @@ pthread_key_t key_thread_attempt_id = (p
int aquire_flag_file(void);
void release_flag_file(void);
-static int umount_all(struct autofs_point *ap, int force);
extern struct master *master_list;
@@ -710,16 +709,14 @@ int umount_multi(struct autofs_point *ap
return left;
}
-static int umount_all(struct autofs_point *ap, int force)
+static void umount_all(struct autofs_point *ap)
{
int left;
left = umount_multi(ap, ap->path, 0);
- if (force && left)
+ if (left)
warn(ap->logopt, "could not unmount %d dirs under %s",
left, ap->path);
-
- return left;
}
static int umount_autofs(struct autofs_point *ap, const char *root)
@@ -737,7 +734,7 @@ static int umount_autofs(struct autofs_p
lookup_close_lookup(ap);
if (ap->type == LKP_INDIRECT) {
- umount_all(ap, 1);
+ umount_all(ap);
ret = umount_autofs_indirect(ap, root);
} else
ret = umount_autofs_direct(ap);

View File

@ -0,0 +1,113 @@
autofs-5.1.6 - remove intr hosts map mount option
From: Ian Kent <raven@themaw.net>
Don't use the intr option on NFS mounts by default, it's been ignored
by the kernel for a long time now.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
man/auto.master.5.in | 4 ++--
man/autofs.5 | 4 ++--
modules/parse_sun.c | 9 +++------
samples/auto.misc | 2 +-
samples/auto.net | 2 +-
6 files changed, 10 insertions(+), 12 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -77,6 +77,7 @@
- add missing description of null map option.
- fix empty mounts list return from unlink_mount_tree().
- fix nonstrict offset mount fail handling.
+- remove intr hosts map mount option.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/man/auto.master.5.in
+++ autofs-5.1.4/man/auto.master.5.in
@@ -260,8 +260,8 @@ For example, with an entry in the master
accessing /net/myserver will mount exports from myserver on directories below
/net/myserver.
.P
-NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options
-unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the
+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
--- autofs-5.1.4.orig/man/autofs.5
+++ autofs-5.1.4/man/autofs.5
@@ -86,13 +86,13 @@ Indirect map:
.RS +.2i
.ta 1.0i 3.0i
.nf
-kernel \-ro,soft,intr ftp.kernel.org:/pub/linux
+kernel \-ro,soft ftp.kernel.org:/pub/linux
boot \-fstype=ext2 :/dev/hda1
windoze \-fstype=smbfs ://windoze/c
removable \-fstype=ext2 :/dev/hdd
cd \-fstype=iso9660,ro :/dev/hdc
floppy \-fstype=auto :/dev/fd0
-server \-rw,hard,intr / \-ro myserver.me.org:/ \\
+server \-rw,hard / \-ro myserver.me.org:/ \\
/usr myserver.me.org:/usr \\
/home myserver.me.org:/home
.fi
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -628,10 +628,9 @@ static int sun_mount(struct autofs_point
int len = strlen(options);
int suid = strstr(options, "suid") ? 0 : 7;
int dev = strstr(options, "dev") ? 0 : 6;
- int nointr = strstr(options, "nointr") ? 0 : 5;
- if (suid || dev || nointr) {
- char *tmp = alloca(len + suid + dev + nointr + 1);
+ if (suid || dev) {
+ char *tmp = alloca(len + suid + dev + 1);
if (!tmp) {
error(ap->logopt, MODPREFIX
"alloca failed for options");
@@ -645,8 +644,6 @@ static int sun_mount(struct autofs_point
strcat(tmp, ",nosuid");
if (dev)
strcat(tmp, ",nodev");
- if (nointr)
- strcat(tmp, ",intr");
options = tmp;
}
} else {
@@ -658,7 +655,7 @@ static int sun_mount(struct autofs_point
return -1;
return 1;
}
- strcpy(tmp, "nosuid,nodev,intr");
+ strcpy(tmp, "nosuid,nodev");
options = tmp;
}
}
--- autofs-5.1.4.orig/samples/auto.misc
+++ autofs-5.1.4/samples/auto.misc
@@ -6,7 +6,7 @@
cd -fstype=iso9660,ro,nosuid,nodev :/dev/cdrom
# the following entries are samples to pique your imagination
-#linux -ro,soft,intr ftp.example.org:/pub/linux
+#linux -ro,soft ftp.example.org:/pub/linux
#boot -fstype=ext2 :/dev/hda1
#floppy -fstype=auto :/dev/fd0
#floppy -fstype=ext2 :/dev/fd0
--- autofs-5.1.4.orig/samples/auto.net
+++ autofs-5.1.4/samples/auto.net
@@ -9,7 +9,7 @@ key="$1"
# add "nosymlink" here if you want to suppress symlinking local filesystems
# add "nonstrict" to make it OK for some filesystems to not mount
-opts="-fstype=nfs,hard,intr,nodev,nosuid"
+opts="-fstype=nfs,hard,nodev,nosuid"
for P in /bin /sbin /usr/bin /usr/sbin
do

View File

@ -0,0 +1,366 @@
autofs-5.1.6 - remove unused function tree_get_mnt_list()
From: Ian Kent <raven@themaw.net>
Remove the now unused function tree_get_mnt_list() and friends.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 17 ---
lib/mounts.c | 299 -------------------------------------------------------
3 files changed, 1 insertion(+), 316 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -130,6 +130,7 @@ xx/xx/2018 autofs-5.1.5
- fix stale offset directories disable mount.
- use struct mnt_list to track mounted mounts.
- use struct mnt_list mounted list for expire.
+- remove unused function tree_get_mnt_list().
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -83,20 +83,8 @@ struct mnt_list {
* List operations ie. get_mnt_list.
*/
struct mnt_list *next;
-
- /*
- * Tree operations ie. tree_make_tree,
- * tree_get_mnt_list etc.
- */
- struct mnt_list *left;
- struct mnt_list *right;
- struct list_head self;
- struct list_head list;
- struct list_head entries;
- struct list_head sublist;
};
-
struct nfs_mount_vers {
unsigned int major;
unsigned int minor;
@@ -143,11 +131,6 @@ void mnts_set_mounted_mount(struct autof
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);
-void tree_free_mnt_tree(struct mnt_list *tree);
-struct mnt_list *tree_make_mnt_tree(const char *path);
-int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
-int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
-int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
void set_tsd_user_vars(unsigned int, uid_t, gid_t);
const char *mount_type_str(unsigned int);
void set_exp_timeout(struct autofs_point *ap, struct map_source *source, time_t timeout);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1685,305 +1685,6 @@ int is_mounted(const char *mp, unsigned
return table_is_mounted(mp, type);
}
-/*
- * Since we have to look at the entire mount tree for direct
- * mounts (all mounts under "/") and we may have a large number
- * of entries to traverse again and again we need to
- * use a more efficient method than the routines above.
- *
- * Thre tree_... routines allow us to read the mount tree
- * once and pass it to subsequent functions for use. Since
- * it's a tree structure searching should be a low overhead
- * operation.
- */
-void tree_free_mnt_tree(struct mnt_list *tree)
-{
- struct list_head *head, *p;
-
- if (!tree)
- return;
-
- tree_free_mnt_tree(tree->left);
- tree_free_mnt_tree(tree->right);
-
- head = &tree->self;
- p = head->next;
- while (p != head) {
- struct mnt_list *this;
-
- this = list_entry(p, struct mnt_list, self);
-
- p = p->next;
-
- list_del(&this->self);
-
- free(this->mp);
-
- free(this);
- }
-
- free(tree->mp);
- free(tree);
-}
-
-/*
- * Make tree of system mounts in /proc/mounts.
- */
-struct mnt_list *tree_make_mnt_tree(const char *path)
-{
- FILE *tab;
- struct mntent mnt_wrk;
- char buf[PATH_MAX * 3];
- struct mntent *mnt;
- struct mnt_list *ent, *mptr;
- struct mnt_list *tree = NULL;
- size_t plen;
- int eq;
-
- tab = open_fopen_r(_PROC_MOUNTS);
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
- logerr("fopen: %s", estr);
- return NULL;
- }
-
- plen = strlen(path);
-
- while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
- size_t len = strlen(mnt->mnt_dir);
-
- /* Not matching path */
- if (strncmp(mnt->mnt_dir, path, plen))
- continue;
-
- /* Not a subdirectory of requested path */
- if (plen > 1 && len > plen && mnt->mnt_dir[plen] != '/')
- continue;
-
- ent = malloc(sizeof(*ent));
- if (!ent) {
- endmntent(tab);
- tree_free_mnt_tree(tree);
- return NULL;
- }
- memset(ent, 0, sizeof(*ent));
-
- INIT_LIST_HEAD(&ent->self);
- INIT_LIST_HEAD(&ent->list);
- INIT_LIST_HEAD(&ent->entries);
- INIT_LIST_HEAD(&ent->sublist);
-
- ent->mp = malloc(len + 1);
- if (!ent->mp) {
- endmntent(tab);
- free(ent);
- tree_free_mnt_tree(tree);
- return NULL;
- }
- strcpy(ent->mp, mnt->mnt_dir);
-
- if (!strcmp(mnt->mnt_type, "autofs"))
- ent->flags |= MNTS_AUTOFS;
-
- if (ent->flags & MNTS_AUTOFS) {
- if (strstr(mnt->mnt_opts, "indirect"))
- ent->flags |= MNTS_INDIRECT;
- else if (strstr(mnt->mnt_opts, "direct"))
- ent->flags |= MNTS_DIRECT;
- else if (strstr(mnt->mnt_opts, "offset"))
- ent->flags |= MNTS_OFFSET;
- }
-
- mptr = tree;
- while (mptr) {
- int elen = strlen(ent->mp);
- int mlen = strlen(mptr->mp);
-
- if (elen < mlen) {
- if (mptr->left) {
- mptr = mptr->left;
- continue;
- } else {
- mptr->left = ent;
- break;
- }
- } else if (elen > mlen) {
- if (mptr->right) {
- mptr = mptr->right;
- continue;
- } else {
- mptr->right = ent;
- break;
- }
- }
-
- eq = strcmp(ent->mp, mptr->mp);
- if (eq < 0) {
- if (mptr->left)
- mptr = mptr->left;
- else {
- mptr->left = ent;
- break;
- }
- } else if (eq > 0) {
- if (mptr->right)
- mptr = mptr->right;
- else {
- mptr->right = ent;
- break;
- }
- } else {
- list_add_tail(&ent->self, &mptr->self);
- break;
- }
- }
-
- if (!tree)
- tree = ent;
- }
- fclose(tab);
-
- return tree;
-}
-
-/*
- * Get list of mounts under "path" in longest->shortest order
- */
-int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include)
-{
- size_t mlen, plen;
-
- if (!mnts)
- return 0;
-
- plen = strlen(path);
- mlen = strlen(mnts->mp);
- if (mlen < plen)
- return tree_get_mnt_list(mnts->right, list, path, include);
- else {
- struct list_head *self, *p;
-
- tree_get_mnt_list(mnts->left, list, path, include);
-
- if ((!include && mlen <= plen) ||
- strncmp(mnts->mp, path, plen))
- goto skip;
-
- if (plen > 1 && mlen > plen && mnts->mp[plen] != '/')
- goto skip;
-
- INIT_LIST_HEAD(&mnts->list);
- list_add(&mnts->list, list);
-
- self = &mnts->self;
- list_for_each(p, self) {
- struct mnt_list *this;
-
- this = list_entry(p, struct mnt_list, self);
- INIT_LIST_HEAD(&this->list);
- list_add(&this->list, list);
- }
-skip:
- tree_get_mnt_list(mnts->right, list, path, include);
- }
-
- if (list_empty(list))
- return 0;
-
- return 1;
-}
-
-/*
- * Get list of mounts under "path" in longest->shortest order
- */
-int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include)
-{
- size_t mlen, plen;
-
- if (!mnts)
- return 0;
-
- plen = strlen(path);
- mlen = strlen(mnts->mp);
- if (mlen < plen)
- return tree_get_mnt_sublist(mnts->right, list, path, include);
- else {
- struct list_head *self, *p;
-
- tree_get_mnt_sublist(mnts->left, list, path, include);
-
- if ((!include && mlen <= plen) ||
- strncmp(mnts->mp, path, plen))
- goto skip;
-
- if (plen > 1 && mlen > plen && mnts->mp[plen] != '/')
- goto skip;
-
- INIT_LIST_HEAD(&mnts->sublist);
- list_add(&mnts->sublist, list);
-
- self = &mnts->self;
- list_for_each(p, self) {
- struct mnt_list *this;
-
- this = list_entry(p, struct mnt_list, self);
- INIT_LIST_HEAD(&this->sublist);
- list_add(&this->sublist, list);
- }
-skip:
- tree_get_mnt_sublist(mnts->right, list, path, include);
- }
-
- if (list_empty(list))
- return 0;
-
- return 1;
-}
-
-int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path)
-{
- int mlen, plen;
-
- if (!mnts)
- return 0;
-
- plen = strlen(path);
- mlen = strlen(mnts->mp);
- if (mlen < plen)
- return tree_find_mnt_ents(mnts->right, list, path);
- else if (mlen > plen)
- return tree_find_mnt_ents(mnts->left, list, path);
- else {
- struct list_head *self, *p;
-
- tree_find_mnt_ents(mnts->left, list, path);
-
- if (!strcmp(mnts->mp, path)) {
- INIT_LIST_HEAD(&mnts->entries);
- list_add(&mnts->entries, list);
- }
-
- self = &mnts->self;
- list_for_each(p, self) {
- struct mnt_list *this;
-
- this = list_entry(p, struct mnt_list, self);
-
- if (!strcmp(this->mp, path)) {
- INIT_LIST_HEAD(&this->entries);
- list_add(&this->entries, list);
- }
- }
-
- tree_find_mnt_ents(mnts->right, list, path);
-
- if (!list_empty(list))
- return 1;
- }
-
- return 0;
-}
-
void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
{
struct thread_stdenv_vars *tsv;

View File

@ -0,0 +1,513 @@
autofs-5.1.6 - update list.h
From: Ian Kent <raven@themaw.net>
Update autofs include/list.h mostly to include the hlist
implementation but also to simplify bits of it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/list.h | 402 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 378 insertions(+), 25 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -116,6 +116,7 @@ xx/xx/2018 autofs-5.1.5
- fix additional typing errors.
- make bind mounts propagation slave by default.
- fix browse dir not re-created on symlink expire.
+- update list.h.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/include/list.h
+++ autofs-5.1.4/include/list.h
@@ -1,6 +1,27 @@
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
+#include <stddef.h>
+
+/*
+ * Casts a member of a structure out to the containing structure
+ * @param ptr the pointer to the member.
+ * @param type the type of the container struct this is embedded in.
+ * @param member the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
/*
* Simple doubly linked list implementation.
*
@@ -25,14 +46,14 @@ struct list_head {
} while (0)
/*
- * Insert a new entry between two known consecutive entries.
+ * Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
-static __inline__ void __list_add(struct list_head * new,
- struct list_head * prev,
- struct list_head * next)
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
{
next->prev = new;
new->next = next;
@@ -48,7 +69,7 @@ static __inline__ void __list_add(struct
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
-static __inline__ void list_add(struct list_head *new, struct list_head *head)
+static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
@@ -61,7 +82,7 @@ static __inline__ void list_add(struct l
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
-static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
@@ -73,8 +94,7 @@ static __inline__ void list_add_tail(str
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
-static __inline__ void __list_del(struct list_head * prev,
- struct list_head * next)
+static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
@@ -83,50 +103,96 @@ static __inline__ void __list_del(struct
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
*/
-static __inline__ void list_del(struct list_head *entry)
+static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
-static __inline__ void list_del_init(struct list_head *entry)
+static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
+ INIT_LIST_HEAD(entry);
+}
+
+/*
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
-static __inline__ int list_empty(struct list_head *head)
+static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
+static inline void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+}
+
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
-static __inline__ void list_splice(struct list_head *list, struct list_head *head)
+static inline void list_splice(struct list_head *list, struct list_head *head)
{
- struct list_head *first = list->next;
-
- if (first != list) {
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
+ if (!list_empty(list))
+ __list_splice(list, head);
+}
- last->next = at;
- at->prev = last;
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
}
}
@@ -137,7 +203,45 @@ static __inline__ void list_splice(struc
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+ container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_last_entry - get the last element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_head within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
+/**
+ * list_next_entry - get the next element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_next_entry(pos, member) \
+ list_entry((pos)->member.next, typeof(*(pos)), member)
+
+/**
+ * list_prev_entry - get the prev element in list
+ * @pos: the type * to cursor
+ * @member: the name of the list_head within the struct.
+ */
+#define list_prev_entry(pos, member) \
+ list_entry((pos)->member.prev, typeof(*(pos)), member)
/**
* list_for_each - iterate over a list
@@ -155,4 +259,252 @@ static __inline__ void list_splice(struc
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop counter.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_next_entry(pos, member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_last_entry(head, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_prev_entry(pos, member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use as a start point in
+ * list_for_each_entry_continue
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - iterate over list of given type
+ * continuing after existing point
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_next_entry(pos, member); \
+ &pos->member != (head); \
+ pos = list_next_entry(pos, member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_first_entry(head, typeof(*pos), member), \
+ n = list_next_entry(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, member))
+
+/**
+ * list_for_each_entry_safe_continue - iterate over list of given type
+ * continuing after existing point safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_next_entry(pos, member), \
+ n = list_next_entry(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = list_next_entry(n, member))
+
+/**
+ * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against
+ * removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_last_entry(head, typeof(*pos), member), \
+ n = list_prev_entry(pos, member); \
+ &pos->member != (head); \
+ pos = n, n = list_prev_entry(n, member))
+
+
+
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
+#define HLIST_HEAD_INIT { .first = NULL }
+#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+ return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+ return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+ *pprev = next;
+ if (next)
+ next->pprev = pprev;
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+ __hlist_del(n);
+ n->next = LIST_POISON1;
+ n->pprev = LIST_POISON2;
+}
+
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+ if (n->pprev) {
+ __hlist_del(n);
+ INIT_HLIST_NODE(n);
+ }
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ n->pprev = next->pprev;
+ n->next = next;
+ next->pprev = &n->next;
+ *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ next->next = n->next;
+ n->next = next;
+ next->pprev = &n->next;
+
+ if(next->next)
+ next->next->pprev = &next->next;
+}
+
+
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+ for (pos = (head)->first; pos; pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
+ pos = n)
+
+#define hlist_entry_safe(ptr, type, member) \
+ ({ typeof(ptr) ____ptr = (ptr); \
+ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+ })
+
+/**
+ * hlist_for_each_entry - iterate over list of given type
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(pos, head, member) \
+ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
+ pos; \
+ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(pos, member) \
+ for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\
+ pos; \
+ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(pos, member) \
+ for (; pos; \
+ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @n: another &struct hlist_node to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
+ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
+ pos && ({ n = pos->next; 1; }) && \
+ pos = hlist_entry_safe(n, typeof(*pos), member))
+
#endif

View File

@ -0,0 +1,119 @@
autofs-5.1.6 - use master_list_empty() for list empty check
From: Ian Kent <raven@themaw.net>
For consistency use the master_list_empty() function for list empty
checks everywhere.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
daemon/master.c | 24 +++++++++++++++++-------
include/master.h | 1 +
4 files changed, 20 insertions(+), 8 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -134,6 +134,7 @@ xx/xx/2018 autofs-5.1.5
- only add expre alarm for active mounts.
- move submount check into conditional_alarm_add().
- move lib/master.c to daemon/master.c.
+- use master_list_empty() for list empty check.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -1596,7 +1596,7 @@ static void *statemachine(void *arg)
case SIGUSR2:
master_mutex_lock();
if (list_empty(&master_list->completed)) {
- if (list_empty(&master_list->mounts)) {
+ if (__master_list_empty(master_list)) {
master_mutex_unlock();
return NULL;
}
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -1110,7 +1110,7 @@ int master_read_master(struct master *ma
master_mount_mounts(master, age);
}
- if (list_empty(&master->mounts))
+ if (__master_list_empty(master))
warn(logopt, "no mounts in table");
master_mutex_unlock();
@@ -1625,7 +1625,7 @@ int dump_map(struct master *master, cons
{
struct list_head *p, *head;
- if (list_empty(&master->mounts)) {
+ if (__master_list_empty(master)) {
printf("no master map entries found\n");
return 1;
}
@@ -1743,7 +1743,7 @@ int master_show_mounts(struct master *ma
printf("global options %s be appended to map entries\n", append);
}
- if (list_empty(&master->mounts)) {
+ if (__master_list_empty(master)) {
printf("no master map entries found\n\n");
return 1;
}
@@ -1831,13 +1831,22 @@ int master_show_mounts(struct master *ma
return 1;
}
-int master_list_empty(struct master *master)
+int __master_list_empty(struct master *master)
{
int res = 0;
- master_mutex_lock();
if (list_empty(&master->mounts))
res = 1;
+
+ return res;
+}
+
+int master_list_empty(struct master *master)
+{
+ int res;
+
+ master_mutex_lock();
+ res = __master_list_empty(master);
master_mutex_unlock();
return res;
@@ -1859,7 +1868,8 @@ int master_done(struct master *master)
master_free_mapent_sources(entry, 1);
master_free_mapent(entry);
}
- if (list_empty(&master->mounts))
+
+ if (__master_list_empty(master))
res = 1;
return res;
@@ -1872,7 +1882,7 @@ unsigned int master_get_logopt(void)
int master_kill(struct master *master)
{
- if (!list_empty(&master->mounts))
+ if (!master_list_empty(master))
return 0;
if (master->name)
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -123,6 +123,7 @@ int master_mount_mounts(struct master *,
int dump_map(struct master *, const char *, const char *);
int master_show_mounts(struct master *);
unsigned int master_get_logopt(void);
+int __master_list_empty(struct master *);
int master_list_empty(struct master *);
int master_done(struct master *);
int master_kill(struct master *);

View File

@ -0,0 +1,547 @@
autofs-5.1.6 - use mnt_list for amdmounts
From: Ian Kent <raven@themaw.net>
Use struct mnt_list objects for the list of amd mounts instead of
struct amd_entry.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 48 ++++++++++------------
daemon/lookup.c | 18 +++++---
include/automount.h | 2
include/master.h | 2
include/mounts.h | 12 +++++
include/parse_amd.h | 1
lib/master.c | 36 +----------------
lib/mounts.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++-
modules/mount_autofs.c | 15 ++++---
modules/parse_amd.c | 43 +++++++++++++++-----
11 files changed, 193 insertions(+), 88 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -123,6 +123,7 @@ xx/xx/2018 autofs-5.1.5
- make external mounts use simpler hashtable.
- add a hash index to mnt_list.
- use mnt_list for submounts.
+- use mnt_list for amdmounts.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -595,7 +595,8 @@ static int umount_subtree_mounts(struct
* it already to ensure it's ok to remove any offset triggers.
*/
if (!is_mm_root && is_mounted(path, MNTS_REAL)) {
- struct amd_entry *entry;
+ struct mnt_list *mnt;
+
debug(ap->logopt, "unmounting dir = %s", path);
if (umount_ent(ap, path) &&
is_mounted(path, MNTS_REAL)) {
@@ -605,16 +606,12 @@ static int umount_subtree_mounts(struct
}
/* Check for an external mount and umount if possible */
- mounts_mutex_lock(ap);
- entry = __master_find_amdmount(ap, path);
- if (!entry) {
- mounts_mutex_unlock(ap);
- goto done;
+ mnt = mnts_find_amdmount(path);
+ if (mnt) {
+ umount_amd_ext_mount(ap, mnt->ext_mp);
+ mnts_remove_amdmount(path);
+ mnts_put_mount(mnt);
}
- list_del(&entry->entries);
- mounts_mutex_unlock(ap);
- umount_amd_ext_mount(ap, entry->fs);
- free_amd_entry(entry);
}
done:
return left;
@@ -639,7 +636,8 @@ int umount_multi(struct autofs_point *ap
/* if this is a symlink we can handle it now */
if (S_ISLNK(st.st_mode)) {
- struct amd_entry *entry;
+ struct mnt_list *mnt;
+
if (st.st_dev != ap->dev) {
crit(ap->logopt,
"symlink %s has the wrong device, "
@@ -671,17 +669,15 @@ int umount_multi(struct autofs_point *ap
"mkdir_path %s failed: %s", path, estr);
}
}
+
/* Check for an external mount and attempt umount if needed */
- mounts_mutex_lock(ap);
- entry = __master_find_amdmount(ap, path);
- if (!entry) {
- mounts_mutex_unlock(ap);
- return 0;
- }
- list_del(&entry->entries);
- mounts_mutex_unlock(ap);
- umount_amd_ext_mount(ap, entry->fs);
- free_amd_entry(entry);
+ mnt = mnts_find_amdmount(path);
+ if (mnt) {
+ umount_amd_ext_mount(ap, mnt->ext_mp);
+ mnts_remove_amdmount(path);
+ mnts_put_mount(mnt);
+ }
+
return 0;
}
@@ -1720,17 +1716,17 @@ static void handle_mounts_cleanup(void *
clean = 1;
if (submount) {
- struct amd_entry *am;
+ struct mnt_list *mnt;
/* We are finishing up */
ap->parent->submnt_count--;
/* Submount at ap->path belongs to parent submount list. */
mnts_remove_submount(ap->path);
- am = __master_find_amdmount(ap->parent, ap->path);
- if (am) {
- list_del_init(&am->entries);
- free_amd_entry(am);
+ mnt = mnts_find_amdmount(ap->path);
+ if (mnt) {
+ mnts_remove_amdmount(ap->path);
+ mnts_put_mount(mnt);
}
}
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -838,7 +838,7 @@ static int lookup_amd_instance(struct au
const char *name, int name_len)
{
struct map_source *instance;
- struct amd_entry *entry;
+ struct mnt_list *mnt;
const char *argv[2];
const char **pargv = NULL;
int argc = 0;
@@ -861,21 +861,23 @@ static int lookup_amd_instance(struct au
strcpy(m_key, ap->path);
strcat(m_key, "/");
strcat(m_key, me->multi->key);
- entry = master_find_amdmount(ap, m_key);
+
+ mnt = mnts_find_amdmount(m_key);
free(m_key);
- if (!entry) {
+ if (!mnt) {
error(ap->logopt, "expected amd mount entry not found");
return NSS_STATUS_UNKNOWN;
}
- if (strcmp(entry->type, "host")) {
- error(ap->logopt, "unexpected map type %s", entry->type);
+ if (strcmp(mnt->amd_type, "host")) {
+ error(ap->logopt, "unexpected map type %s", mnt->amd_type);
+ mnts_put_mount(mnt);
return NSS_STATUS_UNKNOWN;
}
- if (entry->opts && *entry->opts) {
- argv[0] = entry->opts;
+ if (mnt->amd_opts && *mnt->amd_opts) {
+ argv[0] = mnt->amd_opts;
argv[1] = NULL;
pargv = argv;
argc = 1;
@@ -894,9 +896,11 @@ static int lookup_amd_instance(struct au
}
}
if (!instance) {
+ mnts_put_mount(mnt);
error(ap->logopt, "expected hosts map instance not found");
return NSS_STATUS_UNKNOWN;
}
+ mnts_put_mount(mnt);
return do_lookup_mount(ap, instance, name, name_len);
}
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -568,10 +568,10 @@ struct autofs_point {
struct autofs_point *parent; /* Owner of mounts list for submount */
pthread_mutex_t mounts_mutex; /* Protect mount lists */
struct list_head mounts; /* List of autofs mounts at current level */
- struct list_head amdmounts; /* List of non submount amd mounts */
unsigned int submount; /* Is this a submount */
unsigned int submnt_count; /* Number of submounts */
struct list_head submounts; /* List of child submounts */
+ struct list_head amdmounts; /* List of non submount amd mounts */
unsigned int shutdown; /* Shutdown notification */
};
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -109,8 +109,6 @@ void master_source_current_wait(struct m
void master_source_current_signal(struct master_mapent *);
struct master_mapent *master_find_mapent(struct master *, const char *);
unsigned int master_partial_match_mapent(struct master *, const char *);
-struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *);
-struct amd_entry *master_find_amdmount(struct autofs_point *, const char *);
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
void master_add_mapent(struct master *, struct master_mapent *);
void master_remove_mapent(struct master_mapent *);
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -38,6 +38,7 @@
#define MNTS_INDIRECT 0x0008
#define MNTS_DIRECT 0x0010
#define MNTS_OFFSET 0x0020
+#define MNTS_AMD_MOUNT 0x0040
#define REMOUNT_SUCCESS 0x0000
#define REMOUNT_FAIL 0x0001
@@ -64,6 +65,14 @@ struct mnt_list {
struct list_head submount;
struct list_head submount_work;
+ /* List of amd-mounts of an autofs_point */
+ char *ext_mp;
+ char *amd_pref;
+ char *amd_type;
+ char *amd_opts;
+ unsigned int amd_cache_opts;
+ struct list_head amdmount;
+
/*
* List operations ie. get_mnt_list.
*/
@@ -118,6 +127,9 @@ struct mnt_list *mnts_add_submount(struc
void mnts_remove_submount(const char *mp);
void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap);
void mnts_put_submount_list(struct list_head *mnts);
+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);
struct mnt_list *get_mnt_list(const char *path, int include);
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
void free_mnt_list(struct mnt_list *list);
--- autofs-5.1.4.orig/include/parse_amd.h
+++ autofs-5.1.4/include/parse_amd.h
@@ -65,7 +65,6 @@ struct amd_entry {
char *umount;
struct selector *selector;
struct list_head list;
- struct list_head entries;
};
int amd_parse_list(struct autofs_point *,
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -152,12 +152,10 @@ void master_free_autofs_point(struct aut
head = &ap->amdmounts;
p = head->next;
while (p != head) {
- struct amd_entry *entry = list_entry(p, struct amd_entry, entries);
+ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount);
p = p->next;
- if (!list_empty(&entry->entries))
- list_del(&entry->entries);
- ext_mount_remove(entry->fs);
- free_amd_entry(entry);
+ ext_mount_remove(mnt->ext_mp);
+ mnts_remove_amdmount(mnt->mp);
}
mounts_mutex_unlock(ap);
@@ -761,34 +759,6 @@ unsigned int master_partial_match_mapent
return ret;
}
-struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path)
-{
- struct list_head *head, *p;
-
- head = &ap->amdmounts;
- list_for_each(p, head) {
- struct amd_entry *entry;
-
- entry = list_entry(p, struct amd_entry, entries);
-
- if (!strcmp(entry->path, path))
- return entry;
- }
-
- return NULL;
-}
-
-struct amd_entry *master_find_amdmount(struct autofs_point *ap, const char *path)
-{
- struct amd_entry *entry;
-
- mounts_mutex_lock(ap);
- entry = __master_find_amdmount(ap, path);
- mounts_mutex_unlock(ap);
-
- return entry;
-}
-
struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
{
struct master_mapent *entry;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -546,7 +546,6 @@ struct amd_entry *new_amd_entry(const st
memset(new, 0, sizeof(*new));
new->path = path;
INIT_LIST_HEAD(&new->list);
- INIT_LIST_HEAD(&new->entries);
return new;
}
@@ -887,6 +886,7 @@ static struct mnt_list *mnts_alloc_mount
INIT_HLIST_NODE(&this->hash);
INIT_LIST_HEAD(&this->submount);
INIT_LIST_HEAD(&this->submount_work);
+ INIT_LIST_HEAD(&this->amdmount);
done:
return this;
}
@@ -1048,6 +1048,107 @@ void mnts_put_submount_list(struct list_
mnts_hash_mutex_unlock();
}
+struct mnt_list *mnts_find_amdmount(const char *path)
+{
+ struct mnt_list *mnt;
+
+ mnt = mnts_lookup_mount(path);
+ if (mnt && mnt->flags & MNTS_AMD_MOUNT)
+ return mnt;
+ mnts_put_mount(mnt);
+ return NULL;
+}
+
+struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry)
+{
+ struct mnt_list *this;
+ char *type, *ext_mp, *pref, *opts;
+
+ ext_mp = pref = type = opts = NULL;
+
+ if (entry->fs) {
+ ext_mp = strdup(entry->fs);
+ if (!ext_mp)
+ goto fail;
+ }
+
+ if (entry->pref) {
+ pref = strdup(entry->pref);
+ if (!pref)
+ goto fail;
+ }
+
+ if (entry->type) {
+ type = strdup(entry->type);
+ if (!type)
+ goto fail;
+ }
+
+ if (entry->opts) {
+ opts = strdup(entry->opts);
+ if (!opts)
+ goto fail;
+ }
+
+ 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);
+ }
+ mnts_hash_mutex_unlock();
+
+ return this;
+fail:
+ if (ext_mp)
+ free(ext_mp);
+ if (pref)
+ free(pref);
+ if (type)
+ free(type);
+ if (opts)
+ free(opts);
+ return NULL;
+}
+
+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;
+ this->flags &= ~MNTS_AMD_MOUNT;
+ list_del_init(&this->submount);
+ if (this->ext_mp) {
+ free(this->ext_mp);
+ this->ext_mp = NULL;
+ }
+ if (this->amd_type) {
+ free(this->amd_type);
+ this->amd_type = NULL;
+ }
+ if (this->amd_pref) {
+ free(this->amd_pref);
+ this->amd_pref = NULL;
+ }
+ if (this->amd_opts) {
+ free(this->amd_opts);
+ this->amd_opts = NULL;
+ }
+ this->amd_cache_opts = 0;
+ __mnts_put_mount(this);
+done:
+ mnts_hash_mutex_unlock();
+}
+
/* 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
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -286,16 +286,19 @@ int mount_mount(struct autofs_point *ap,
mounts_mutex_lock(ap);
if (source->flags & MAP_FLAG_FORMAT_AMD) {
- struct amd_entry *am_entry = __master_find_amdmount(ap, entry->path);
+ struct mnt_list *mnt;
- if (am_entry) {
- if (am_entry->pref) {
- nap->pref = am_entry->pref;
- am_entry->pref = NULL;
+ mnt = mnts_find_amdmount(entry->path);
+ if (mnt) {
+ if (mnt->amd_pref) {
+ nap->pref = mnt->amd_pref;
+ mnt->amd_pref = NULL;
}
- if (am_entry->cache_opts & AMD_CACHE_OPTION_ALL)
+ if (mnt->amd_cache_opts & AMD_CACHE_OPTION_ALL)
nap->flags |= MOUNT_FLAG_AMD_CACHE_ALL;
+
+ mnts_put_mount(mnt);
}
}
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1300,6 +1300,7 @@ static int do_host_mount(struct autofs_p
{
struct lookup_mod *lookup;
struct map_source *instance;
+ struct mnt_list *mnt = NULL;
struct mapent *me;
const char *argv[2];
const char **pargv = NULL;
@@ -1316,7 +1317,9 @@ static int do_host_mount(struct autofs_p
*/
if (strcmp(name, entry->rhost)) {
char *target;
- size_t len = strlen(ap->path) + strlen(entry->rhost) + 2;
+ size_t len;
+
+ len = strlen(ap->path) + strlen(entry->rhost) + 2;
target = malloc(len);
if (!target) {
warn(ap->logopt, MODPREFIX
@@ -1329,6 +1332,15 @@ static int do_host_mount(struct autofs_p
if (entry->path)
free(entry->path);
entry->path = target;
+
+ /* Add an mnt_list entry for the updated path. */
+ mnt = mnts_add_amdmount(ap, entry);
+ if (!mnt) {
+ error(ap->logopt, MODPREFIX
+ "failed to update mount mnt_list entry");
+ goto out;
+ }
+
/*
* Wait for any expire before racing to mount the
* export tree or bail out if we're shutting down.
@@ -1388,6 +1400,8 @@ static int do_host_mount(struct autofs_p
warn(ap->logopt, MODPREFIX
"failed to create symlink to hosts mount base");
out:
+ if (ret && mnt)
+ mnts_remove_amdmount(mnt->mp);
return ret;
}
@@ -2204,6 +2218,7 @@ int parse_mount(struct autofs_point *ap,
struct list_head entries, *p, *head;
struct amd_entry *defaults_entry;
struct amd_entry *cur_defaults;
+ struct mnt_list *mnt;
int rv = 1;
int cur_state;
int ret;
@@ -2313,21 +2328,27 @@ int parse_mount(struct autofs_point *ap,
* add parsed entry to parent amd mount list and remove
* on mount fail.
*/
- mounts_mutex_lock(ap);
- list_add_tail(&this->entries, &ap->amdmounts);
- mounts_mutex_unlock(ap);
+ mnt = mnts_add_amdmount(ap, this);
+ if (!mnt) {
+ error(ap->logopt, MODPREFIX
+ "failed to add mount to mnt_list");
+ break;
+ }
rv = amd_mount(ap, name, this, source, sv, flags, ctxt);
- mounts_mutex_lock(ap);
if (!rv) {
- /* Mounted, remove entry from parsed list */
- list_del_init(&this->list);
- mounts_mutex_unlock(ap);
+ /*
+ * 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.
+ */
+ if (strcmp(this->path, mnt->mp))
+ mnts_remove_amdmount(this->path);
break;
}
- /* Not mounted, remove entry from the parent list */
- list_del_init(&this->entries);
- mounts_mutex_unlock(ap);
+ /* Not mounted, remove the mnt_list entry from amdmount list */
+ mnts_remove_amdmount(this->path);
}
free_amd_entry(cur_defaults);

View File

@ -0,0 +1,472 @@
autofs-5.1.6 - use mnt_list for submounts
From: Ian Kent <raven@themaw.net>
Use struct mnt_list objects for submount list entries instead of
struct autofs_point itself.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 11 ++++-
daemon/direct.c | 7 ++-
daemon/indirect.c | 5 ++
include/automount.h | 2 -
include/master.h | 2 -
include/mounts.h | 10 +++++
lib/master.c | 93 +++++++++++++++----------------------------------
lib/mounts.c | 81 ++++++++++++++++++++++++++++++++++++++++++
modules/mount_autofs.c | 17 ++++++++
10 files changed, 157 insertions(+), 72 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -122,6 +122,7 @@ xx/xx/2018 autofs-5.1.5
- make external mounts independent of amd_entry.
- make external mounts use simpler hashtable.
- add a hash index to mnt_list.
+- use mnt_list for submounts.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -624,6 +624,7 @@ done:
it also tries to umount path itself */
int umount_multi(struct autofs_point *ap, const char *path, int incl)
{
+ struct mnt_list *sbmnt;
int is_autofs_fs;
struct stat st;
int left;
@@ -685,8 +686,11 @@ int umount_multi(struct autofs_point *ap
}
is_autofs_fs = 0;
- if (master_find_submount(ap, path))
+ sbmnt = mnts_find_submount(path);
+ if (sbmnt) {
is_autofs_fs = 1;
+ mnts_put_mount(sbmnt);
+ }
left = 0;
@@ -1717,9 +1721,12 @@ static void handle_mounts_cleanup(void *
if (submount) {
struct amd_entry *am;
+
/* We are finishing up */
ap->parent->submnt_count--;
- list_del_init(&ap->mounts);
+
+ /* Submount at ap->path belongs to parent submount list. */
+ mnts_remove_submount(ap->path);
am = __master_find_amdmount(ap->parent, ap->path);
if (am) {
list_del_init(&am->entries);
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1211,14 +1211,17 @@ 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;
+ sbmnt = mnts_find_submount(mt.name);
if (statfs(mt.name, &fs) == -1 ||
- (fs.f_type == AUTOFS_SUPER_MAGIC &&
- !master_find_submount(ap, mt.name)))
+ (fs.f_type == AUTOFS_SUPER_MAGIC && !sbmnt))
close_fd = 1;
+ if (sbmnt)
+ mnts_put_mount(sbmnt);
cache_writelock(mt.mc);
if ((me = cache_lookup_distinct(mt.mc, mt.name))) {
/*
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -401,6 +401,7 @@ void *expire_proc_indirect(void *arg)
if (next->flags & MNTS_INDIRECT)
master_notify_submount(ap, next->mp, ap->state);
else if (next->flags & MNTS_OFFSET) {
+ struct mnt_list *sbmnt;
struct map_source *map;
struct mapent_cache *mc = NULL;
struct mapent *me = NULL;
@@ -413,7 +414,9 @@ void *expire_proc_indirect(void *arg)
}
/* Don't touch submounts */
- if (master_find_submount(ap, next->mp)) {
+ sbmnt = mnts_find_submount(next->mp);
+ if (sbmnt) {
+ mnts_put_mount(sbmnt);
pthread_setcancelstate(cur_state, NULL);
continue;
}
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -570,9 +570,9 @@ struct autofs_point {
struct list_head mounts; /* List of autofs mounts at current level */
struct list_head amdmounts; /* List of non submount amd mounts */
unsigned int submount; /* Is this a submount */
- unsigned int shutdown; /* Shutdown notification */
unsigned int submnt_count; /* Number of submounts */
struct list_head submounts; /* List of child submounts */
+ unsigned int shutdown; /* Shutdown notification */
};
#define UNLINK_AND_CONT 0x01
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -109,8 +109,6 @@ void master_source_current_wait(struct m
void master_source_current_signal(struct master_mapent *);
struct master_mapent *master_find_mapent(struct master *, const char *);
unsigned int master_partial_match_mapent(struct master *, const char *);
-struct autofs_point *__master_find_submount(struct autofs_point *, const char *);
-struct autofs_point *master_find_submount(struct autofs_point *, const char *);
struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *);
struct amd_entry *master_find_amdmount(struct autofs_point *, const char *);
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -59,6 +59,11 @@ struct mnt_list {
struct hlist_node hash;
unsigned int ref;
+ /* List of sub-mounts of an autofs_point */
+ struct autofs_point *ap;
+ struct list_head submount;
+ struct list_head submount_work;
+
/*
* List operations ie. get_mnt_list.
*/
@@ -108,6 +113,11 @@ int ext_mount_remove(const char *);
int ext_mount_inuse(const char *);
struct mnt_list *mnts_lookup_mount(const char *mp);
void mnts_put_mount(struct mnt_list *mnt);
+struct mnt_list *mnts_find_submount(const char *path);
+struct mnt_list *mnts_add_submount(struct autofs_point *ap);
+void mnts_remove_submount(const char *mp);
+void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap);
+void mnts_put_submount_list(struct list_head *mnts);
struct mnt_list *get_mnt_list(const char *path, int include);
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
void free_mnt_list(struct mnt_list *list);
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -761,34 +761,6 @@ unsigned int master_partial_match_mapent
return ret;
}
-struct autofs_point *__master_find_submount(struct autofs_point *ap, const char *path)
-{
- struct list_head *head, *p;
-
- head = &ap->submounts;
- list_for_each(p, head) {
- struct autofs_point *submount;
-
- submount = list_entry(p, struct autofs_point, mounts);
-
- if (!strcmp(submount->path, path))
- return submount;
- }
-
- return NULL;
-}
-
-struct autofs_point *master_find_submount(struct autofs_point *ap, const char *path)
-{
- struct autofs_point *submount;
-
- mounts_mutex_lock(ap);
- submount = __master_find_submount(ap, path);
- mounts_mutex_unlock(ap);
-
- return submount;
-}
-
struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path)
{
struct list_head *head, *p;
@@ -1190,85 +1162,80 @@ int master_submount_list_empty(struct au
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
{
- struct list_head *head, *p;
- struct autofs_point *this = NULL;
+ struct mnt_list *this, *sbmnt;
+ LIST_HEAD(sbmnts);
int ret = 1;
- mounts_mutex_lock(ap);
-
- head = &ap->submounts;
- p = head->prev;
- while (p != head) {
- this = list_entry(p, struct autofs_point, mounts);
- p = p->prev;
+ mnts_get_submount_list(&sbmnts, ap);
+ if (list_empty(&sbmnts))
+ return 1;
+
+ list_for_each_entry(this, &sbmnts, submount_work) {
+ /* Not a submount */
+ if (!(this->flags & MNTS_AUTOFS))
+ continue;
/* path not the same */
- if (strcmp(this->path, path))
+ if (strcmp(this->mp, path))
continue;
- if (!master_submount_list_empty(this)) {
- char *this_path = strdup(this->path);
- if (this_path) {
- mounts_mutex_unlock(ap);
- master_notify_submount(this, path, state);
- mounts_mutex_lock(ap);
- if (!__master_find_submount(ap, this_path)) {
- free(this_path);
- continue;
- }
- free(this_path);
- }
+ if (!master_submount_list_empty(this->ap)) {
+ struct mnt_list *sm;
+
+ master_notify_submount(this->ap, path, state);
+ sm = mnts_find_submount(path);
+ if (!sm)
+ continue;
+ mnts_put_mount(sm);
}
/* Now we have found the submount we want to expire */
st_mutex_lock();
- if (this->state == ST_SHUTDOWN) {
+ if (this->ap->state == ST_SHUTDOWN) {
this = NULL;
st_mutex_unlock();
break;
}
- this->shutdown = ap->shutdown;
+ this->ap->shutdown = ap->shutdown;
- __st_add_task(this, state);
+ __st_add_task(this->ap, state);
st_mutex_unlock();
- mounts_mutex_unlock(ap);
- st_wait_task(this, state, 0);
+ st_wait_task(this->ap, state, 0);
/*
* If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or
* ST_SHUTDOWN_FORCE we need to wait until it goes away or changes
* to ST_READY.
*/
- mounts_mutex_lock(ap);
st_mutex_lock();
- while ((this = __master_find_submount(ap, path))) {
+ while ((sbmnt = mnts_find_submount(path))) {
struct timespec t = { 0, 300000000 };
struct timespec r;
- if (this->state != ST_SHUTDOWN &&
- this->state != ST_SHUTDOWN_PENDING &&
- this->state != ST_SHUTDOWN_FORCE) {
+ if (sbmnt->ap->state != ST_SHUTDOWN &&
+ sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
+ sbmnt->ap->state != ST_SHUTDOWN_FORCE) {
ret = 0;
+ mnts_put_mount(sbmnt);
break;
}
+ mnts_put_mount(sbmnt);
st_mutex_unlock();
- mounts_mutex_unlock(ap);
while (nanosleep(&t, &r) == -1 && errno == EINTR)
memcpy(&t, &r, sizeof(struct timespec));
- mounts_mutex_lock(ap);
st_mutex_lock();
}
st_mutex_unlock();
break;
}
- mounts_mutex_unlock(ap);
+ mnts_put_submount_list(&sbmnts);
return ret;
}
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -885,6 +885,8 @@ static struct mnt_list *mnts_alloc_mount
this->ref = 1;
INIT_HLIST_NODE(&this->hash);
+ INIT_LIST_HEAD(&this->submount);
+ INIT_LIST_HEAD(&this->submount_work);
done:
return this;
}
@@ -967,6 +969,85 @@ void mnts_put_mount(struct mnt_list *mnt
mnts_hash_mutex_unlock();
}
+struct mnt_list *mnts_find_submount(const char *path)
+{
+ struct mnt_list *mnt;
+
+ mnt = mnts_lookup_mount(path);
+ if (mnt && mnt->flags & MNTS_AUTOFS)
+ return mnt;
+ mnts_put_mount(mnt);
+ return NULL;
+}
+
+struct mnt_list *mnts_add_submount(struct autofs_point *ap)
+{
+ struct mnt_list *this;
+
+ mnts_hash_mutex_lock();
+ this = mnts_get_mount(ap->path);
+ if (this) {
+ if (!this->ap)
+ this->ap = ap;
+ else if (this->ap != ap ||
+ this->ap->parent != ap->parent) {
+ __mnts_put_mount(this);
+ mnts_hash_mutex_unlock();
+ error(ap->logopt,
+ "conflict with submount owner: %s", ap->path);
+ goto fail;
+ }
+ this->flags |= MNTS_AUTOFS;
+ if (list_empty(&this->submount))
+ list_add_tail(&this->submount, &ap->parent->submounts);
+ }
+ mnts_hash_mutex_unlock();
+fail:
+ return this;
+}
+
+void mnts_remove_submount(const char *mp)
+{
+ struct mnt_list *this;
+
+ mnts_hash_mutex_lock();
+ this = mnts_lookup(mp);
+ if (this && this->flags & MNTS_AUTOFS) {
+ this->flags &= ~MNTS_AUTOFS;
+ this->ap = NULL;
+ list_del_init(&this->submount);
+ __mnts_put_mount(this);
+ }
+ mnts_hash_mutex_unlock();
+}
+
+void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap)
+{
+ struct mnt_list *mnt;
+
+ mnts_hash_mutex_lock();
+ if (list_empty(&ap->submounts))
+ goto done;
+ list_for_each_entry(mnt, &ap->submounts, submount) {
+ __mnts_get_mount(mnt);
+ list_add(&mnt->submount_work, mnts);
+ }
+done:
+ mnts_hash_mutex_unlock();
+}
+
+void mnts_put_submount_list(struct list_head *mnts)
+{
+ struct mnt_list *mnt, *tmp;
+
+ mnts_hash_mutex_lock();
+ list_for_each_entry_safe(mnt, tmp, mnts, submount_work) {
+ list_del_init(&mnt->submount_work);
+ __mnts_put_mount(mnt);
+ }
+ mnts_hash_mutex_unlock();
+}
+
/* 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
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -65,6 +65,7 @@ int mount_mount(struct autofs_point *ap,
struct master_mapent *entry;
struct map_source *source;
struct autofs_point *nap;
+ struct mnt_list *mnt;
char buf[MAX_ERR_BUF];
char *options, *p;
int len, ret;
@@ -307,6 +308,18 @@ int mount_mount(struct autofs_point *ap,
return 1;
}
+ mnt = mnts_add_submount(nap);
+ if (!mnt) {
+ crit(ap->logopt,
+ MODPREFIX "failed to allocate mount %s", realpath);
+ handle_mounts_startup_cond_destroy(&suc);
+ mounts_mutex_unlock(ap);
+ master_free_map_source(source, 1);
+ master_free_mapent(entry);
+ return 1;
+ }
+
+
suc.ap = nap;
suc.root = mountpoint;
suc.done = 0;
@@ -318,6 +331,7 @@ int mount_mount(struct autofs_point *ap,
"failed to create mount handler thread for %s",
realpath);
handle_mounts_startup_cond_destroy(&suc);
+ mnts_remove_submount(nap->path);
mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
@@ -328,6 +342,7 @@ int mount_mount(struct autofs_point *ap,
status = pthread_cond_wait(&suc.cond, &suc.mutex);
if (status) {
handle_mounts_startup_cond_destroy(&suc);
+ mnts_remove_submount(nap->path);
mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
@@ -339,6 +354,7 @@ int mount_mount(struct autofs_point *ap,
crit(ap->logopt,
MODPREFIX "failed to create submount for %s", realpath);
handle_mounts_startup_cond_destroy(&suc);
+ mnts_remove_submount(nap->path);
mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
@@ -347,7 +363,6 @@ int mount_mount(struct autofs_point *ap,
nap->thid = thid;
ap->submnt_count++;
- list_add(&nap->mounts, &ap->submounts);
handle_mounts_startup_cond_destroy(&suc);
mounts_mutex_unlock(ap);

View File

@ -0,0 +1,620 @@
autofs-5.1.6 - use struct mnt_list mounted list for expire
From: Ian Kent <raven@themaw.net>
Now we are keeping track of mounted mounts using the mnt_list struct
use it to drive the expire instead of using the system mount table.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/direct.c | 61 +++++++----------
daemon/indirect.c | 66 +++++++++----------
include/mounts.h | 5 -
lib/master.c | 36 +---------
lib/mounts.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++--------
6 files changed, 223 insertions(+), 131 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -129,6 +129,7 @@ xx/xx/2018 autofs-5.1.5
- fix remount expire.
- fix stale offset directories disable mount.
- use struct mnt_list to track mounted mounts.
+- use struct mnt_list mounted list for expire.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -77,9 +77,8 @@ static void key_mnt_params_init(void)
static void mnts_cleanup(void *arg)
{
- struct mnt_list *mnts = (struct mnt_list *) arg;
- tree_free_mnt_tree(mnts);
- return;
+ struct list_head *mnts = (struct list_head *) arg;
+ mnts_put_expire_list(mnts);
}
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
@@ -788,8 +787,8 @@ out_err:
void *expire_proc_direct(void *arg)
{
struct ioctl_ops *ops = get_ioctl_ops();
- struct mnt_list *mnts = NULL, *next;
- struct list_head list, *p;
+ struct mnt_list *mnt;
+ LIST_HEAD(mnts);
struct expire_args *ea;
struct expire_args ec;
struct autofs_point *ap;
@@ -821,31 +820,24 @@ void *expire_proc_direct(void *arg)
left = 0;
- mnts = tree_make_mnt_tree("/");
- pthread_cleanup_push(mnts_cleanup, mnts);
-
- /* Get a list of mounts select real ones and expire them if possible */
- INIT_LIST_HEAD(&list);
- if (!tree_get_mnt_list(mnts, &list, "/", 0)) {
- ec.status = 0;
- return NULL;
- }
-
- list_for_each(p, &list) {
- next = list_entry(p, struct mnt_list, list);
-
+ /* Get the list of real mounts and expire them if possible */
+ mnts_get_expire_list(&mnts, ap);
+ if (list_empty(&mnts))
+ goto done;
+ pthread_cleanup_push(mnts_cleanup, &mnts);
+ list_for_each_entry(mnt, &mnts, expire) {
/*
* All direct mounts must be present in the map
* entry cache.
*/
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
- me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT);
+ me = lookup_source_mapent(ap, mnt->mp, LKP_DISTINCT);
pthread_cleanup_pop(1);
if (!me)
continue;
- if (next->flags & MNTS_AUTOFS) {
+ if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) {
struct stat st;
int ioctlfd;
@@ -856,22 +848,17 @@ void *expire_proc_direct(void *arg)
* one of them and pass on state change.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- if (next->flags & MNTS_INDIRECT) {
- master_notify_submount(ap, next->mp, ap->state);
- pthread_setcancelstate(cur_state, NULL);
- continue;
- }
+ if (mnt->flags & MNTS_AUTOFS)
+ master_notify_submount(ap, mnt->mp, ap->state);
if (me->ioctlfd == -1) {
pthread_setcancelstate(cur_state, NULL);
continue;
}
- /* It's got a mount, deal with in the outer loop */
- if (is_mounted(me->key, MNTS_REAL)) {
- pthread_setcancelstate(cur_state, NULL);
- continue;
- }
+ /* It's got a mount, just send the expire. */
+ if (is_mounted(me->key, MNTS_REAL))
+ goto cont;
/*
* Maybe a manual umount, repair.
@@ -888,19 +875,19 @@ void *expire_proc_direct(void *arg)
cache_writelock(me->mc);
if (me->ioctlfd != -1 &&
fstat(me->ioctlfd, &st) != -1 &&
- !count_mounts(ap, next->mp, st.st_dev)) {
+ !count_mounts(ap, mnt->mp, st.st_dev)) {
ops->close(ap->logopt, me->ioctlfd);
me->ioctlfd = -1;
cache_unlock(me->mc);
- mnts_remove_mount(next->mp, MNTS_MOUNTED);
+ mnts_remove_mount(mnt->mp, MNTS_MOUNTED);
pthread_setcancelstate(cur_state, NULL);
continue;
}
cache_unlock(me->mc);
-
+cont:
ioctlfd = me->ioctlfd;
- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how);
+ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
if (ret) {
left++;
pthread_setcancelstate(cur_state, NULL);
@@ -923,10 +910,10 @@ void *expire_proc_direct(void *arg)
if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE)
pthread_testcancel();
- debug(ap->logopt, "send expire to trigger %s", next->mp);
+ debug(ap->logopt, "send expire to trigger %s", mnt->mp);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how);
+ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
if (ret)
left++;
pthread_setcancelstate(cur_state, NULL);
@@ -935,7 +922,7 @@ void *expire_proc_direct(void *arg)
if (left)
debug(ap->logopt, "%d remaining in %s", left, ap->path);
-
+done:
ec.status = left;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -343,17 +343,17 @@ force_umount:
static void mnts_cleanup(void *arg)
{
- struct mnt_list *mnts = (struct mnt_list *) arg;
- free_mnt_list(mnts);
- return;
+ struct list_head *mnts = (struct list_head *) arg;
+ mnts_put_expire_list(mnts);
}
void *expire_proc_indirect(void *arg)
{
struct ioctl_ops *ops = get_ioctl_ops();
struct autofs_point *ap;
- struct mapent *me = NULL;
- struct mnt_list *mnts = NULL, *next;
+ struct mnt_list *mnt;
+ LIST_HEAD(mnts);
+ struct mapent *me;
struct expire_args *ea;
struct expire_args ec;
unsigned int how;
@@ -385,36 +385,34 @@ void *expire_proc_indirect(void *arg)
left = 0;
- /* Get a list of real mounts and expire them if possible */
- mnts = get_mnt_list(ap->path, 0);
- pthread_cleanup_push(mnts_cleanup, mnts);
- for (next = mnts; next; next = next->next) {
+ /* Get the list of real mounts and expire them if possible */
+ mnts_get_expire_list(&mnts, ap);
+ if (list_empty(&mnts))
+ goto done;
+ pthread_cleanup_push(mnts_cleanup, &mnts);
+ list_for_each_entry(mnt, &mnts, expire) {
char *ind_key;
int ret;
- if (next->flags & MNTS_AUTOFS) {
+ if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) {
/*
* If we have submounts check if this path lives below
* one of them and pass on the state change.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- if (next->flags & MNTS_INDIRECT)
- master_notify_submount(ap, next->mp, ap->state);
- else if (next->flags & MNTS_OFFSET) {
+ if (mnt->flags & MNTS_AUTOFS)
+ master_notify_submount(ap, mnt->mp, ap->state);
+
+ /* An offset without a real mount, check for manual umount */
+ if (mnt->flags & MNTS_OFFSET &&
+ !is_mounted(mnt->mp, MNTS_REAL)) {
struct mnt_list *sbmnt;
struct map_source *map;
struct mapent_cache *mc = NULL;
- struct mapent *me = NULL;
struct stat st;
- /* It's got a mount, deal with in the outer loop */
- if (is_mounted(next->mp, MNTS_REAL)) {
- pthread_setcancelstate(cur_state, NULL);
- continue;
- }
-
/* Don't touch submounts */
- sbmnt = mnts_find_submount(next->mp);
+ sbmnt = mnts_find_submount(mnt->mp);
if (sbmnt) {
mnts_put_mount(sbmnt);
pthread_setcancelstate(cur_state, NULL);
@@ -427,7 +425,7 @@ void *expire_proc_indirect(void *arg)
while (map) {
mc = map->mc;
cache_writelock(mc);
- me = cache_lookup_distinct(mc, next->mp);
+ me = cache_lookup_distinct(mc, mnt->mp);
if (me)
break;
cache_unlock(mc);
@@ -456,10 +454,10 @@ void *expire_proc_indirect(void *arg)
cache_unlock(mc);
master_source_unlock(ap->entry);
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
}
-
pthread_setcancelstate(cur_state, NULL);
- continue;
}
if (ap->state == ST_EXPIRE || ap->state == ST_PRUNE)
@@ -469,7 +467,7 @@ void *expire_proc_indirect(void *arg)
* If the mount corresponds to an offset trigger then
* the key is the path, otherwise it's the last component.
*/
- ind_key = strrchr(next->mp, '/');
+ ind_key = strrchr(mnt->mp, '/');
if (ind_key)
ind_key++;
@@ -482,7 +480,7 @@ void *expire_proc_indirect(void *arg)
*/
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
- me = lookup_source_mapent(ap, next->mp, LKP_DISTINCT);
+ me = lookup_source_mapent(ap, mnt->mp, LKP_DISTINCT);
if (!me && ind_key)
me = lookup_source_mapent(ap, ind_key, LKP_NORMAL);
pthread_cleanup_pop(1);
@@ -494,10 +492,10 @@ void *expire_proc_indirect(void *arg)
cache_unlock(me->mc);
}
- debug(ap->logopt, "expire %s", next->mp);
+ debug(ap->logopt, "expire %s", mnt->mp);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- ret = ops->expire(ap->logopt, ioctlfd, next->mp, how);
+ ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
if (ret)
left++;
pthread_setcancelstate(cur_state, NULL);
@@ -519,14 +517,14 @@ void *expire_proc_indirect(void *arg)
pthread_cleanup_pop(1);
count = offsets = submnts = 0;
- mnts = get_mnt_list(ap->path, 0);
- pthread_cleanup_push(mnts_cleanup, mnts);
+ mnts_get_expire_list(&mnts, ap);
+ pthread_cleanup_push(mnts_cleanup, &mnts);
/* Are there any real mounts left */
- for (next = mnts; next; next = next->next) {
- if (!(next->flags & MNTS_AUTOFS))
+ list_for_each_entry(mnt, &mnts, expire) {
+ if (!(mnt->flags & MNTS_AUTOFS))
count++;
else {
- if (next->flags & MNTS_INDIRECT)
+ if (mnt->flags & MNTS_INDIRECT)
submnts++;
else
offsets++;
@@ -544,7 +542,7 @@ void *expire_proc_indirect(void *arg)
*/
if (count)
debug(ap->logopt, "%d remaining in %s", count, ap->path);
-
+done:
ec.status = left;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -63,6 +63,8 @@ struct mnt_list {
/* List of mounts of an autofs_point */
struct list_head mount;
+ /* Mounted mounts list for expire */
+ struct list_head expire;
/* List of sub-mounts of an autofs_point */
struct autofs_point *ap;
@@ -129,15 +131,12 @@ void mnts_put_mount(struct mnt_list *mnt
struct mnt_list *mnts_find_submount(const char *path);
struct mnt_list *mnts_add_submount(struct autofs_point *ap);
void mnts_remove_submount(const char *mp);
-void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap);
-void mnts_put_submount_list(struct list_head *mnts);
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);
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);
-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);
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -1133,40 +1133,17 @@ int master_submount_list_empty(struct au
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
{
struct mnt_list *this, *sbmnt;
- LIST_HEAD(sbmnts);
int ret = 1;
- mnts_get_submount_list(&sbmnts, ap);
- if (list_empty(&sbmnts))
- return 1;
-
- list_for_each_entry(this, &sbmnts, submount_work) {
- /* Not a submount */
- if (!(this->flags & MNTS_AUTOFS))
- continue;
-
- /* path not the same */
- if (strcmp(this->mp, path))
- continue;
-
- if (!master_submount_list_empty(this->ap)) {
- struct mnt_list *sm;
-
- master_notify_submount(this->ap, path, state);
- sm = mnts_find_submount(path);
- if (!sm)
- continue;
- mnts_put_mount(sm);
- }
-
- /* Now we have found the submount we want to expire */
-
+ this = mnts_find_submount(path);
+ if (this) {
+ /* We have found a submount to expire */
st_mutex_lock();
if (this->ap->state == ST_SHUTDOWN) {
this = NULL;
st_mutex_unlock();
- break;
+ goto done;
}
this->ap->shutdown = ap->shutdown;
@@ -1202,11 +1179,10 @@ int master_notify_submount(struct autofs
st_mutex_lock();
}
st_mutex_unlock();
- break;
+done:
+ mnts_put_mount(this);
}
- mnts_put_submount_list(&sbmnts);
-
return ret;
}
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -888,6 +888,7 @@ static struct mnt_list *mnts_alloc_mount
INIT_LIST_HEAD(&this->submount);
INIT_LIST_HEAD(&this->submount_work);
INIT_LIST_HEAD(&this->amdmount);
+ INIT_LIST_HEAD(&this->expire);
done:
return this;
}
@@ -1022,33 +1023,6 @@ void mnts_remove_submount(const char *mp
mnts_hash_mutex_unlock();
}
-void mnts_get_submount_list(struct list_head *mnts, struct autofs_point *ap)
-{
- struct mnt_list *mnt;
-
- mnts_hash_mutex_lock();
- if (list_empty(&ap->submounts))
- goto done;
- list_for_each_entry(mnt, &ap->submounts, submount) {
- __mnts_get_mount(mnt);
- list_add(&mnt->submount_work, mnts);
- }
-done:
- mnts_hash_mutex_unlock();
-}
-
-void mnts_put_submount_list(struct list_head *mnts)
-{
- struct mnt_list *mnt, *tmp;
-
- mnts_hash_mutex_lock();
- list_for_each_entry_safe(mnt, tmp, mnts, submount_work) {
- list_del_init(&mnt->submount_work);
- __mnts_put_mount(mnt);
- }
- mnts_hash_mutex_unlock();
-}
-
struct mnt_list *mnts_find_amdmount(const char *path)
{
struct mnt_list *mnt;
@@ -1234,6 +1208,163 @@ void mnts_set_mounted_mount(struct autof
}
}
+struct node {
+ struct mnt_list *mnt;
+ struct node *left;
+ struct node *right;
+};
+
+static struct node *new(struct mnt_list *mnt)
+{
+ struct node *n;
+
+ n = malloc(sizeof(struct node));
+ if (!n)
+ return NULL;
+ memset(n, 0, sizeof(struct node));
+ n->mnt = mnt;
+
+ return n;
+}
+
+static struct node *tree_root(struct mnt_list *mnt)
+{
+ struct node *n;
+
+ n = new(mnt);
+ if (!n) {
+ error(LOGOPT_ANY, "failed to allcate tree root");
+ return NULL;
+ }
+
+ return n;
+}
+
+static struct node *add_left(struct node *this, struct mnt_list *mnt)
+{
+ struct node *n;
+
+ n = new(mnt);
+ if (!n) {
+ error(LOGOPT_ANY, "failed to allcate tree node");
+ return NULL;
+ }
+ this->left = n;
+
+ return n;
+}
+
+static struct node *add_right(struct node *this, struct mnt_list *mnt)
+{
+ struct node *n;
+
+ n = new(mnt);
+ if (!n) {
+ error(LOGOPT_ANY, "failed to allcate tree node");
+ return NULL;
+ }
+ this->right = n;
+
+ return n;
+}
+
+static struct node *add_node(struct node *root, struct mnt_list *mnt)
+{
+ struct node *p, *q;
+ unsigned int mp_len;
+
+ mp_len = strlen(mnt->mp);
+
+ q = root;
+ p = root;
+
+ while (q && strcmp(mnt->mp, p->mnt->mp)) {
+ p = q;
+ if (mp_len < strlen(p->mnt->mp))
+ q = p->left;
+ else
+ q = p->right;
+ }
+
+ if (strcmp(mnt->mp, p->mnt->mp) == 0)
+ error(LOGOPT_ANY, "duplicate entry in mounts list");
+ else {
+ if (mp_len < strlen(p->mnt->mp))
+ return add_left(p, mnt);
+ else
+ return add_right(p, mnt);
+ }
+
+ return NULL;
+}
+
+static void tree_free(struct node *tree)
+{
+ if (tree->right)
+ tree_free(tree->right);
+ if (tree->left)
+ tree_free(tree->left);
+ free(tree);
+}
+
+static void traverse(struct node *node, struct list_head *mnts)
+{
+ if (node->right)
+ traverse(node->right, mnts);
+ list_add_tail(&node->mnt->expire, mnts);
+ if (node->left)
+ traverse(node->left, mnts);
+}
+
+void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
+{
+ struct mnt_list *mnt;
+ struct node *tree = NULL;
+
+ mnts_hash_mutex_lock();
+ if (list_empty(&ap->mounts))
+ goto done;
+
+ list_for_each_entry(mnt, &ap->mounts, mount) {
+ struct node *n;
+
+ __mnts_get_mount(mnt);
+
+ if (!tree) {
+ tree = tree_root(mnt);
+ if (!tree) {
+ error(LOGOPT_ANY, "failed to create expire tree root");
+ goto done;
+ }
+ continue;
+ }
+
+ n = add_node(tree, mnt);
+ if (!n) {
+ error(LOGOPT_ANY, "failed to add expire tree node");
+ tree_free(tree);
+ goto done;
+ }
+ }
+
+ traverse(tree, mnts);
+ tree_free(tree);
+done:
+ mnts_hash_mutex_unlock();
+}
+
+void mnts_put_expire_list(struct list_head *mnts)
+{
+ struct mnt_list *mnt, *tmp;
+
+ mnts_hash_mutex_lock();
+ list_for_each_entry_safe(mnt, tmp, mnts, expire) {
+ list_del_init(&mnt->expire);
+ __mnts_put_mount(mnt);
+ }
+ mnts_hash_mutex_unlock();
+}
+
/* 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

View File

@ -0,0 +1,360 @@
autofs-5.1.6 - use struct mnt_list to track mounted mounts
From: Ian Kent <raven@themaw.net>
Use struct mnt_list to track mounted mounts so that it's no longer
necessary to use the system mount table to get the list of mounted
mounts.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 5 ++
daemon/direct.c | 19 ++++++++
daemon/indirect.c | 3 +
include/mounts.h | 10 ++++
lib/mounts.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++----
6 files changed, 154 insertions(+), 9 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -128,6 +128,7 @@ xx/xx/2018 autofs-5.1.5
- remove force parameter from umount_all().
- fix remount expire.
- fix stale offset directories disable mount.
+- use struct mnt_list to track mounted mounts.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -677,6 +677,9 @@ int umount_multi(struct autofs_point *ap
mnts_put_mount(mnt);
}
+ /* Check for mounted mount and remove it if found */
+ mnts_remove_mount(path, MNTS_MOUNTED);
+
return 0;
}
@@ -1719,6 +1722,8 @@ static void handle_mounts_cleanup(void *
/* Submount at ap->path belongs to parent submount list. */
mnts_remove_submount(ap->path);
+ /* Also remove from parent mounted list */
+ mnts_remove_mount(ap->path, MNTS_MOUNTED);
mnt = mnts_find_amdmount(ap->path);
if (mnt) {
mnts_remove_amdmount(ap->path);
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -606,6 +606,9 @@ force_umount:
} else
info(ap->logopt, "umounted offset mount %s", me->key);
+ if (!rv)
+ mnts_remove_mount(me->key, MNTS_OFFSET);
+
return rv;
}
@@ -622,6 +625,7 @@ int mount_autofs_offset(struct autofs_po
const char *map_name = hosts_map_name;
const char *type;
char mountpoint[PATH_MAX];
+ struct mnt_list *mnt;
if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) {
ret = try_remount(ap, me, t_offset);
@@ -635,6 +639,11 @@ int mount_autofs_offset(struct autofs_po
if (ap->state != ST_READMAP)
warn(ap->logopt,
"trigger %s already mounted", me->key);
+ 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);
return MOUNT_OFFSET_OK;
}
@@ -757,6 +766,12 @@ int mount_autofs_offset(struct autofs_po
notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
+ mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET);
+ if (!mnt)
+ error(ap->logopt,
+ "failed to add offset mount %s to mounted list",
+ mountpoint);
+
debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
return MOUNT_OFFSET_OK;
@@ -877,6 +892,7 @@ void *expire_proc_direct(void *arg)
ops->close(ap->logopt, me->ioctlfd);
me->ioctlfd = -1;
cache_unlock(me->mc);
+ mnts_remove_mount(next->mp, MNTS_MOUNTED);
pthread_setcancelstate(cur_state, NULL);
continue;
}
@@ -1238,7 +1254,10 @@ static void *do_mount_direct(void *arg)
cache_unlock(mt.mc);
if (close_fd)
ops->close(ap->logopt, mt.ioctlfd);
+
info(ap->logopt, "mounted %s", mt.name);
+
+ mnts_set_mounted_mount(ap, mt.name);
} else {
/* TODO: get mount return status from lookup_nss_mount */
ops->send_fail(ap->logopt,
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -751,7 +751,10 @@ static void *do_mount_indirect(void *arg
if (status) {
ops->send_ready(ap->logopt,
ap->ioctlfd, mt.wait_queue_token);
+
info(ap->logopt, "mounted %s", buf);
+
+ mnts_set_mounted_mount(ap, mt.name);
} else {
/* TODO: get mount return status from lookup_nss_mount */
ops->send_fail(ap->logopt,
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -39,6 +39,7 @@
#define MNTS_DIRECT 0x0010
#define MNTS_OFFSET 0x0020
#define MNTS_AMD_MOUNT 0x0040
+#define MNTS_MOUNTED 0x0080
#define REMOUNT_SUCCESS 0x0000
#define REMOUNT_FAIL 0x0001
@@ -60,6 +61,9 @@ struct mnt_list {
struct hlist_node hash;
unsigned int ref;
+ /* List of mounts of an autofs_point */
+ struct list_head mount;
+
/* List of sub-mounts of an autofs_point */
struct autofs_point *ap;
struct list_head submount;
@@ -130,7 +134,13 @@ void mnts_put_submount_list(struct list_
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);
+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);
+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);
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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -884,6 +884,7 @@ static struct mnt_list *mnts_alloc_mount
this->ref = 1;
INIT_HLIST_NODE(&this->hash);
+ INIT_LIST_HEAD(&this->mount);
INIT_LIST_HEAD(&this->submount);
INIT_LIST_HEAD(&this->submount_work);
INIT_LIST_HEAD(&this->amdmount);
@@ -1149,6 +1150,90 @@ done:
mnts_hash_mutex_unlock();
}
+struct mnt_list *mnts_add_mount(struct autofs_point *ap,
+ const char *name, unsigned int flags)
+{
+ struct mnt_list *this;
+ char *mp;
+
+ if (*name == '/') {
+ mp = strdup(name);
+ if (!mp)
+ goto fail;
+ } else {
+ int len = strlen(ap->path) + strlen(name) + 2;
+
+ mp = malloc(len);
+ if (!mp)
+ goto fail;
+ strcpy(mp, ap->path);
+ strcat(mp, "/");
+ strcat(mp, name);
+ }
+
+ mnts_hash_mutex_lock();
+ this = mnts_get_mount(mp);
+ if (this) {
+ this->flags |= flags;
+ if (list_empty(&this->mount))
+ list_add(&this->mount, &ap->mounts);
+ }
+ mnts_hash_mutex_unlock();
+ free(mp);
+
+ return this;
+fail:
+ if (mp)
+ free(mp);
+ return NULL;
+}
+
+void mnts_remove_mount(const char *mp, unsigned int flags)
+{
+ struct mnt_list *this;
+
+ mnts_hash_mutex_lock();
+ this = mnts_lookup(mp);
+ if (this && this->flags & flags) {
+ this->flags &= ~flags;
+ if (!(this->flags & (MNTS_OFFSET|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)
+{
+ struct mnt_list *mnt;
+
+ mnt = mnts_add_mount(ap, name, MNTS_MOUNTED);
+ 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;
+ }
+}
+
/* 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
@@ -1962,7 +2047,8 @@ void notify_mount_result(struct autofs_p
return;
}
-static int do_remount_direct(struct autofs_point *ap, int fd, const char *path)
+static int do_remount_direct(struct autofs_point *ap,
+ const unsigned int type, int fd, const char *path)
{
struct ioctl_ops *ops = get_ioctl_ops();
int status = REMOUNT_SUCCESS;
@@ -1975,9 +2061,21 @@ static int do_remount_direct(struct auto
set_tsd_user_vars(ap->logopt, uid, gid);
ret = lookup_nss_mount(ap, NULL, path, strlen(path));
- if (ret)
+ if (ret) {
+ struct mnt_list *mnt;
+
+ /* 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);
+ }
+
+ mnts_set_mounted_mount(ap, path);
+
info(ap->logopt, "re-connected to %s", path);
- else {
+ } else {
status = REMOUNT_FAIL;
info(ap->logopt, "failed to re-connect %s", path);
}
@@ -1985,7 +2083,7 @@ static int do_remount_direct(struct auto
return status;
}
-static int do_remount_indirect(struct autofs_point *ap, int fd, const char *path)
+static int do_remount_indirect(struct autofs_point *ap, const unsigned int type, int fd, const char *path)
{
struct ioctl_ops *ops = get_ioctl_ops();
int status = REMOUNT_SUCCESS;
@@ -2046,9 +2144,11 @@ static int do_remount_indirect(struct au
len = strlen(de[n]->d_name);
ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len);
- if (ret)
+ if (ret) {
+ mnts_set_mounted_mount(ap, buf);
+
info(ap->logopt, "re-connected to %s", buf);
- else {
+ } else {
status = REMOUNT_FAIL;
info(ap->logopt, "failed to re-connect %s", buf);
}
@@ -2149,9 +2249,9 @@ static int remount_active_mount(struct a
* following will be broken?
*/
if (type == t_indirect)
- do_remount_indirect(ap, fd, path);
+ do_remount_indirect(ap, type, fd, path);
else
- do_remount_direct(ap, fd, path);
+ do_remount_direct(ap, type, fd, path);
}
debug(ap->logopt, "re-connected to mount %s", path);
@@ -2389,7 +2489,7 @@ int umount_ent(struct autofs_point *ap,
* so that we do not try to call rmdir_path on the
* directory.
*/
- if (!rv && is_mounted(path, MNTS_REAL)) {
+ if (is_mounted(path, MNTS_REAL)) {
crit(ap->logopt,
"the umount binary reported that %s was "
"unmounted, but there is still something "
@@ -2398,6 +2498,10 @@ int umount_ent(struct autofs_point *ap,
}
}
+ /* On success, check for mounted mount and remove it if found */
+ if (!rv)
+ mnts_remove_mount(path, MNTS_MOUNTED);
+
return rv;
}
@@ -2690,6 +2794,9 @@ int umount_multi_triggers(struct autofs_
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);
}
return left;

View File

@ -0,0 +1,122 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -30,6 +30,7 @@
- fix program map multi-mount lookup after mount fail.
- add some multi-mount macros.
- remove unused functions cache_dump_multi() and cache_dump_cache().
+- add a len field to struct autofs_point.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -851,7 +851,7 @@ static int lookup_amd_instance(struct au
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");
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -86,6 +86,7 @@ int master_add_autofs_point(struct maste
free(ap);
return 0;
}
+ ap->len = strlen(ap->path);
ap->pref = NULL;
ap->entry = entry;
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -547,6 +547,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 */
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1158,7 +1158,7 @@ struct mnt_list *mnts_add_mount(struct a
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)
@@ -2489,9 +2489,9 @@ static int rmdir_path_offset(struct auto
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];
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -147,7 +147,7 @@ static struct substvar *add_lookup_vars(
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_p
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
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1156,7 +1156,7 @@ static int mount_subtree(struct autofs_p
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, "/");
@@ -1479,7 +1479,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);

View File

@ -0,0 +1,100 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/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, cons
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, cons
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;
}

View File

@ -0,0 +1,38 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct
left++;
}
+ if (me->len > PATH_MAX) {
+ crit(ap->logopt, "me->key too long for buffer");
+ return 1;
+ }
+
strcpy(key, me->key);
cache_unlock(mc);

View File

@ -0,0 +1,167 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/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;
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/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(str
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);
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -546,17 +546,21 @@ int cache_add(struct mapent_cache *mc, s
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, s
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;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/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_he
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

View File

@ -0,0 +1,51 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -74,6 +74,7 @@
- fix hosts map offset order.
- fix direct mount deadlock.
- fix lookup_prune_one_cache() refactoring change.
+- add missing description of null map option.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/man/auto.master.5.in
+++ autofs-5.1.4/man/auto.master.5.in
@@ -263,6 +263,25 @@ accessing /net/myserver will mount expor
NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options
unless overridden by explicitly specifying the "suid", "dev" or "nointr" 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

View File

@ -0,0 +1,38 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -1917,6 +1917,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);
}

View File

@ -0,0 +1,304 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -39,6 +39,7 @@
- fix mount_fullpath().
- add tree_mapent_cleanup_offsets().
- add set_offset_tree_catatonic().
+- add mount and umount offsets functions.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -172,6 +172,8 @@ struct tree_node *tree_mapent_root(struc
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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1692,6 +1692,266 @@ void tree_mapent_cleanup_offsets(struct
}
}
+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

View File

@ -0,0 +1,46 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -38,6 +38,7 @@
- add tree_mapent_traverse_subtree().
- fix mount_fullpath().
- add tree_mapent_cleanup_offsets().
+- add set_offset_tree_catatonic().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2574,6 +2574,21 @@ static int set_mount_catatonic(struct au
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)) {

View File

@ -0,0 +1,522 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -28,6 +28,7 @@
- don't pass root to do_mount_autofs_offset().
- rename tree implementation functions.
- fix program map multi-mount lookup after mount fail.
+- add some multi-mount macros.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -545,27 +545,27 @@ static int umount_subtree_mounts(struct
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
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");
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -686,7 +686,7 @@ int mount_autofs_offset(struct autofs_po
* 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);
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -756,7 +756,7 @@ int lookup_ghost(struct autofs_point *ap
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;
@@ -846,12 +846,12 @@ static int lookup_amd_instance(struct au
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");
@@ -860,7 +860,7 @@ static int lookup_amd_instance(struct au
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);
@@ -1363,7 +1363,7 @@ void lookup_prune_one_cache(struct autof
* 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;
}
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/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);
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -374,7 +374,7 @@ struct mapent *cache_lookup_first(struct
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
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
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(str
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_ca
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;
@@ -784,14 +784,14 @@ int cache_set_offset_parent(struct mapen
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;
}
@@ -849,7 +849,7 @@ int cache_delete_offset(struct mapent_ca
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;
@@ -859,7 +859,7 @@ int cache_delete_offset(struct mapent_ca
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;
@@ -897,7 +897,7 @@ int cache_delete(struct mapent_cache *mc
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;
}
@@ -926,7 +926,7 @@ int cache_delete(struct mapent_cache *mc
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;
}
@@ -965,7 +965,7 @@ int cache_delete_offset_list(struct mape
return CHE_FAIL;
/* Not offset list owner */
- if (me->multi != me)
+ if (!IS_MM_ROOT(me))
return CHE_FAIL;
head = &me->multi_list;
@@ -986,13 +986,13 @@ int cache_delete_offset_list(struct mape
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++;
}
@@ -1000,7 +1000,7 @@ int cache_delete_offset_list(struct mape
if (!remain) {
list_del_init(&me->multi_list);
- me->multi = NULL;
+ MM_ROOT(me) = NULL;
}
if (remain)
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2159,7 +2159,7 @@ int try_remount(struct autofs_point *ap,
} 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;
}
}
@@ -2306,7 +2306,7 @@ void set_indirect_mount_tree_catatonic(s
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);
@@ -2326,7 +2326,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);
}
@@ -2484,12 +2484,12 @@ static int rmdir_path_offset(struct auto
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);
@@ -2684,7 +2684,7 @@ int mount_multi_triggers(struct autofs_p
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;
@@ -2718,7 +2718,7 @@ int umount_multi_triggers(struct autofs_
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
--- autofs-5.1.4.orig/modules/lookup_file.c
+++ autofs-5.1.4/modules/lookup_file.c
@@ -1217,8 +1217,8 @@ int lookup_mount(struct autofs_point *ap
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 {
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -177,7 +177,7 @@ static void update_hosts_mounts(struct a
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
--- autofs-5.1.4.orig/modules/lookup_ldap.c
+++ autofs-5.1.4/modules/lookup_ldap.c
@@ -3718,8 +3718,8 @@ int lookup_mount(struct autofs_point *ap
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 {
--- autofs-5.1.4.orig/modules/lookup_nisplus.c
+++ autofs-5.1.4/modules/lookup_nisplus.c
@@ -740,8 +740,8 @@ int lookup_mount(struct autofs_point *ap
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 {
--- autofs-5.1.4.orig/modules/lookup_program.c
+++ autofs-5.1.4/modules/lookup_program.c
@@ -664,7 +664,7 @@ int lookup_mount(struct autofs_point *ap
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"
@@ -675,7 +675,7 @@ int lookup_mount(struct autofs_point *ap
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);
}
--- autofs-5.1.4.orig/modules/lookup_sss.c
+++ autofs-5.1.4/modules/lookup_sss.c
@@ -1073,8 +1073,8 @@ int lookup_mount(struct autofs_point *ap
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);
--- autofs-5.1.4.orig/modules/lookup_yp.c
+++ autofs-5.1.4/modules/lookup_yp.c
@@ -844,8 +844,8 @@ int lookup_mount(struct autofs_point *ap
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 {
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1150,7 +1150,7 @@ static int mount_subtree(struct autofs_p
rv = 0;
- mm_key = me->multi->key;
+ mm_key = MM_ROOT(me)->key;
if (*mm_key == '/') {
mm_root = mm_key;
@@ -1164,7 +1164,7 @@ static int mount_subtree(struct autofs_p
}
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) {
@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_p
/* 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;
@@ -1352,7 +1352,7 @@ int parse_mount(struct autofs_point *ap,
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);
@@ -1507,7 +1507,7 @@ dont_expand:
}
/* So we know we're the multi-mount root */
- if (!me->multi)
+ if (!IS_MM(me))
me->multi = me;
else {
/*
@@ -1632,7 +1632,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) {

View File

@ -0,0 +1,123 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -215,6 +215,7 @@ struct mapent *cache_partial_match_wild(
int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
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);
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -169,6 +169,7 @@ void mnts_get_expire_list(struct list_he
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);
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -719,8 +719,7 @@ void cache_update_negative(struct mapent
}
-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;
@@ -766,7 +765,7 @@ int cache_set_offset_parent(struct mapen
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
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1481,6 +1481,53 @@ static void tree_mapent_free(struct tree
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

View File

@ -0,0 +1,88 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -37,6 +37,7 @@
- add tree_mapent_delete_offsets().
- add tree_mapent_traverse_subtree().
- fix mount_fullpath().
+- add tree_mapent_cleanup_offsets().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -171,6 +171,7 @@ void mnts_set_mounted_mount(struct autof
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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1647,6 +1647,51 @@ int tree_mapent_delete_offsets(struct ma
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

View File

@ -0,0 +1,113 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -34,6 +34,7 @@
- make tree implementation data independent.
- add mapent tree implementation.
- add tree_mapent_add_node().
+- add tree_mapent_delete_offsets().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -170,6 +170,7 @@ void mnts_put_expire_list(struct list_he
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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1528,6 +1528,76 @@ int tree_mapent_add_node(struct mapent_c
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

View File

@ -0,0 +1,79 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -35,6 +35,7 @@
- add mapent tree implementation.
- add tree_mapent_add_node().
- add tree_mapent_delete_offsets().
+- add tree_mapent_traverse_subtree().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_c
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);

View File

@ -0,0 +1,325 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -1,3 +1,6 @@
+
+- add xdr_exports().
+
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
- fix directory create permission.
--- autofs-5.1.4.orig/include/rpc_subs.h
+++ autofs-5.1.4/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 <nfs/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
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
--- autofs-5.1.4.orig/lib/rpc_subs.c
+++ autofs-5.1.4/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
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
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
return 1;
}
-static void rpc_export_free(exports item)
+static void rpc_export_free(struct exportinfo *export)
{
- groups grp;
- groups tmp;
+ struct hostinfo *host, *tmp;
- if (item->ex_dir)
- free(item->ex_dir);
+ if (export->dir)
+ free(export->dir);
- grp = item->ex_groups;
- while (grp) {
- if (grp->gr_name)
- free(grp->gr_name);
- tmp = grp;
- grp = grp->gr_next;
+ 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
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)
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/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_p
{
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_p
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_p
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_p
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);

View File

@ -0,0 +1,40 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_he
}
}
- 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();
}

View File

@ -0,0 +1,46 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -803,7 +803,20 @@ update_offset_entry(struct autofs_point
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);

View File

@ -0,0 +1,60 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -23,6 +23,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -887,20 +887,15 @@ int cache_delete(struct mapent_cache *mc
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;
@@ -929,7 +924,7 @@ int cache_delete(struct mapent_cache *mc
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;

View File

@ -0,0 +1,197 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -21,6 +21,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/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_po
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 {
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/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 {
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -131,7 +131,7 @@ struct mnt_list *get_mnt_list(const char
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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1172,7 +1172,7 @@ struct mnt_list *mnts_add_mount(struct a
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, u
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)
@@ -1943,17 +1924,13 @@ static int do_remount_direct(struct auto
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);
@@ -2028,7 +2005,9 @@ static int do_remount_indirect(struct au
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);

View File

@ -0,0 +1,60 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -25,6 +25,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2447,13 +2447,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)
@@ -2645,7 +2644,7 @@ static int do_umount_offset(struct autof
*/
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 */
@@ -2691,7 +2690,7 @@ int mount_multi_triggers(struct autofs_p
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

View File

@ -0,0 +1,41 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_po
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);

View File

@ -0,0 +1,107 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -1,6 +1,7 @@
- add xdr_exports().
- remove mount.x and rpcgen dependencies.
+- dont use realloc in host exports list processing.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_p
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;
+ mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
+ this = this->next;
+ }
- 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 = 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_p
}
rpc_exports_free(exp);
- if (!mapent)
- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
-
return mapent;
}

View File

@ -0,0 +1,372 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
+- eliminate cache_lookup_offset() usage.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2489,24 +2489,27 @@ int mount_multi_triggers(struct autofs_p
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;
@@ -2519,12 +2522,8 @@ int mount_multi_triggers(struct autofs_p
*/
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,
@@ -2578,6 +2577,8 @@ int umount_multi_triggers(struct autofs_
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);
@@ -2591,11 +2592,28 @@ int umount_multi_triggers(struct autofs_
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;
@@ -2680,13 +2698,14 @@ int clean_stale_multi_triggers(struct au
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)
@@ -2714,14 +2733,30 @@ int clean_stale_multi_triggers(struct au
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;
@@ -2772,14 +2807,6 @@ int clean_stale_multi_triggers(struct au
}
}
- 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)) {
@@ -2794,7 +2821,6 @@ int clean_stale_multi_triggers(struct au
if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
error(ap->logopt,
"failed to delete offset key %s", key);
- free(key);
continue;
}
@@ -2810,7 +2836,6 @@ int clean_stale_multi_triggers(struct au
left++;
/* But we did origianlly create this */
oe->flags |= MOUNT_FLAG_DIR_CREATED;
- free(key);
continue;
}
/*
@@ -2828,7 +2853,6 @@ int clean_stale_multi_triggers(struct au
error(ap->logopt,
"failed to delete offset key %s", key);
}
- free(key);
}
return left;
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1088,6 +1088,8 @@ static void cleanup_multi_triggers(struc
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;
@@ -1097,16 +1099,31 @@ static void cleanup_multi_triggers(struc
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);
@@ -1119,17 +1136,14 @@ static void cleanup_multi_triggers(struc
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;
@@ -1143,20 +1157,26 @@ static int mount_subtree(struct autofs_p
}
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;
@@ -1174,13 +1194,7 @@ static int mount_subtree(struct autofs_p
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)
@@ -1188,11 +1202,11 @@ static int mount_subtree(struct autofs_p
}
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) {
@@ -1208,24 +1222,29 @@ static int mount_subtree(struct autofs_p
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);

View File

@ -0,0 +1,285 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -11,6 +11,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2595,10 +2595,44 @@ static int do_umount_offset(struct autof
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);
@@ -2660,6 +2694,11 @@ int mount_multi_triggers(struct autofs_p
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);
@@ -2718,170 +2757,4 @@ int umount_multi_triggers(struct autofs_
}
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;
}
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1178,7 +1178,7 @@ static int mount_subtree(struct autofs_p
/* 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;
@@ -1612,14 +1612,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);

View File

@ -0,0 +1,132 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -19,6 +19,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/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);
}
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/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);
--- autofs-5.1.4.orig/lib/dev-ioctl-lib.c
+++ autofs-5.1.4/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,

View File

@ -0,0 +1,82 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -70,6 +70,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree
}
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_c
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
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1548,7 +1548,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);
}

View File

@ -0,0 +1,124 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -20,6 +20,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2534,10 +2534,12 @@ static int rmdir_path_offset(struct auto
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;
@@ -2545,12 +2547,11 @@ static int do_umount_multi_triggers(stru
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;
@@ -2586,13 +2587,14 @@ static int do_umount_multi_triggers(stru
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;
@@ -2601,8 +2603,8 @@ static int do_umount_offset(struct autof
* 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
@@ -2706,7 +2708,7 @@ int mount_multi_triggers(struct autofs_p
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;
}
@@ -2720,7 +2722,7 @@ int mount_multi_triggers(struct autofs_p
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,
@@ -2732,9 +2734,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) {
/*
@@ -2747,7 +2751,7 @@ int umount_multi_triggers(struct autofs_
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;

View File

@ -0,0 +1,48 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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 amd hosts mount expire.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap,
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 */

View File

@ -0,0 +1,120 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -882,6 +882,83 @@ struct master *master_new(const char *na
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
* 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);

View File

@ -0,0 +1,36 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_c
}
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);

View File

@ -0,0 +1,51 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct a
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 a
free(mp);
return this;
-fail:
- if (mp)
- free(mp);
- return NULL;
}
void mnts_remove_mount(const char *mp, unsigned int flags)

View File

@ -0,0 +1,129 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -72,6 +72,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/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_p
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_p
* failed umount.
*/
error = do_umount_autofs_direct(ap, me);
+ /* cache became invalid, restart */
+ if (error == -1)
+ goto restart;
if (!error)
goto done;
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -348,11 +348,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;
@@ -411,7 +412,7 @@ static void do_readmap_mount(struct auto
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;
@@ -430,14 +431,14 @@ static void do_readmap_mount(struct auto
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)
@@ -504,9 +505,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);

View File

@ -0,0 +1,35 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -976,8 +976,6 @@ static int parse_mapent(const char *ent,
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX
"concat_options: %s", estr);
- if (newopt)
- free(newopt);
free(myoptions);
return 0;
}

View File

@ -0,0 +1,33 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1528,7 +1528,6 @@ dont_expand:
if (!loc) {
free(options);
free(pmapent);
- cache_unlock(mc);
warn(ap->logopt, MODPREFIX "out of memory");
return 1;
}

View File

@ -0,0 +1,34 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -661,7 +661,7 @@ int umount_multi(struct autofs_point *ap
/* 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

View File

@ -0,0 +1,289 @@
autofs-5.1.7 - fix hosts map offset order
From: Ian Kent <raven@themaw.net>
Map entry offset paths 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 use to mount the offset during parsing since the
path length of exports can cary 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 | 71 ++++++++++++++++++++++++++++++++++++++-----------
6 files changed, 124 insertions(+), 18 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -71,6 +71,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/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"
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/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 a
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);
--- autofs-5.1.4.orig/include/rpc_subs.h
+++ autofs-5.1.4/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 {
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/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(s
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 *
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_he
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);
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma
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_p
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_p
}
*mapent = 0;
- pos = 0;
- this = exp;
- if (this) {
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
- this->dir, host, this->dir);
- pos += len;
- this = this->next;
- }
-
- while (this) {
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
- this->dir, host, this->dir);
- pos += len;
- this = this->next;
+ wi.mapent = mapent;
+ wi.host = host;
+ wi.pos = 0;
+
+ if (!tree) {
+ free(mapent);
+ mapent = NULL;
+ } else {
+ tree_traverse_inorder(tree, tree_host_work, &wi);
+ tree_free(tree);
}
rpc_exports_free(exp);

View File

@ -0,0 +1,245 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -17,6 +17,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2485,6 +2485,12 @@ static int do_mount_autofs_offset(struct
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;
}
@@ -2628,7 +2634,8 @@ static int do_umount_offset(struct autof
/*
* 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);
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -853,10 +853,12 @@ update_offset_entry(struct autofs_point
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
@@ -1130,14 +1132,22 @@ static void cleanup_multi_triggers(struc
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;
@@ -1182,9 +1192,12 @@ static int mount_subtree(struct autofs_p
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;
@@ -1201,9 +1214,10 @@ static int mount_subtree(struct autofs_p
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;
}
}
@@ -1219,9 +1233,10 @@ static int mount_subtree(struct autofs_p
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) {
@@ -1229,8 +1244,11 @@ static int mount_subtree(struct autofs_p
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;
}
@@ -1239,13 +1257,15 @@ static int mount_subtree(struct autofs_p
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)
@@ -1486,7 +1506,6 @@ dont_expand:
return 1;
}
- cache_multi_writelock(me);
/* So we know we're the multi-mount root */
if (!me->multi)
me->multi = me;
@@ -1511,14 +1530,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 {
@@ -1539,8 +1557,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);
@@ -1556,8 +1574,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);
@@ -1575,8 +1593,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);
@@ -1594,10 +1612,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);
@@ -1618,6 +1633,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);
@@ -1626,10 +1642,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);

View File

@ -0,0 +1,129 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -14,6 +14,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -527,8 +527,11 @@ static int umount_subtree_mounts(struct
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
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
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;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2730,9 +2730,6 @@ int umount_multi_triggers(struct autofs_
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
@@ -2750,11 +2747,6 @@ int umount_multi_triggers(struct autofs_
}
}
- /* 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);
}

View File

@ -0,0 +1,58 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -5,6 +5,7 @@
- use sprintf() when constructing hosts mapent.
- fix mnts_remove_amdmount() uses wrong list.
- eliminate cache_lookup_offset() usage.
+- fix is mounted check on non existent path.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/dev-ioctl-lib.c
+++ autofs-5.1.4/lib/dev-ioctl-lib.c
@@ -759,6 +759,9 @@ static int dev_ioctl_ismountpoint(unsign
int save_errno = errno;
free_dev_ioctl_path(param);
errno = save_errno;
+ /* Path doesn't exist */
+ if (errno == ENOENT)
+ return 0;
return -1;
}
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1645,8 +1645,18 @@ static int table_is_mounted(const char *
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;

View File

@ -0,0 +1,56 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -73,6 +73,7 @@
- eliminate redundant cache lookup in tree_mapent_add_node().
- fix hosts map offset order.
- fix direct mount deadlock.
+- fix lookup_prune_one_cache() refactoring change.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -1387,6 +1387,7 @@ void lookup_prune_one_cache(struct autof
if (!key || strchr(key, '*')) {
if (key)
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1394,6 +1395,7 @@ void lookup_prune_one_cache(struct autof
if (!path) {
warn(ap->logopt, "can't malloc storage for path");
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1421,9 +1423,10 @@ void lookup_prune_one_cache(struct autof
}
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)

View File

@ -0,0 +1,32 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1107,6 +1107,7 @@ static int mount_subtree(struct autofs_p
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] = '/';

View File

@ -0,0 +1,36 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -13,6 +13,7 @@
- refactor umount_multi_triggers().
- eliminate clean_stale_multi_triggers().
- simplify mount_subtree() mount check.
+- fix mnts_get_expire_list() expire list construction.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1364,6 +1364,9 @@ void mnts_get_expire_list(struct list_he
list_for_each_entry(mnt, &ap->mounts, mount) {
struct node *n;
+ if (!(mnt->flags & MNTS_MOUNTED))
+ continue;
+
__mnts_get_mount(mnt);
if (!tree) {

View File

@ -0,0 +1,34 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/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;

View File

@ -0,0 +1,61 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -36,6 +36,7 @@
- add tree_mapent_add_node().
- add tree_mapent_delete_offsets().
- add tree_mapent_traverse_subtree().
+- fix mount_fullpath().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -371,8 +371,10 @@ int mount_fullpath(char *fullpath, size_
/* 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);
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1177,7 +1177,8 @@ static int do_generic_mount(struct autof
* 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_po
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)

View File

@ -0,0 +1,54 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -76,6 +76,7 @@
- fix lookup_prune_one_cache() refactoring change.
- add missing description of null map option.
- fix empty mounts list return from unlink_mount_tree().
+- fix nonstrict offset mount fail handling.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree(
{
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);
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1183,7 +1183,7 @@ static int mount_subtree(struct autofs_p
* 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);

View File

@ -0,0 +1,199 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -68,6 +68,7 @@
- add ext_mount_hash_mutex lock helpers.
- fix amd section mounts map reload.
- fix amd hosts mount expire.
+- fix offset entries order.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/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;
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, s
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;
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -791,14 +791,15 @@ static int check_is_multi(const char *ma
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);
@@ -864,8 +865,29 @@ update_offset_entry(struct autofs_point
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) {
@@ -1211,6 +1233,25 @@ static char *do_expandsunent(const char
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] ...
@@ -1230,7 +1271,8 @@ int parse_mount(struct autofs_point *ap,
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;
@@ -1446,9 +1488,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);
@@ -1463,9 +1503,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);
@@ -1476,15 +1514,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);
@@ -1501,6 +1537,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);

View File

@ -0,0 +1,34 @@
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(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master_parse.y
+++ autofs-5.1.4/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();

View File

@ -0,0 +1,54 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struc
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;

View File

@ -0,0 +1,40 @@
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 not
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -15,6 +15,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -590,9 +590,10 @@ static int umount_subtree_mounts(struct
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 &&

View File

@ -0,0 +1,346 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/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.
*/
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -68,6 +68,17 @@ static pthread_mutex_t ext_mount_hash_mu
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
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
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)
-{
- 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)
+static inline struct tree_node *tree_root(struct tree_ops *ops, void *ptr)
{
- 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(s
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 int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
+{
+ 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 void tree_traverse(struct tree_node *n, struct list_head *mnts)
+static int tree_mnt_expire_list_work(struct tree_node *n, 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);
+ 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_he
__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_he
}
}
- tree_traverse(tree, mnts);
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
tree_free(tree);
done:
mnts_hash_mutex_unlock();

View File

@ -0,0 +1,110 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -143,22 +143,12 @@ int master_add_autofs_point(struct maste
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)
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/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);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/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();
}

View File

@ -0,0 +1,68 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -16,6 +16,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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -795,24 +795,17 @@ static int check_is_multi(const char *ma
}
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 */
@@ -1576,11 +1569,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) {

View File

@ -0,0 +1,153 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/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().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -131,7 +131,7 @@ int check_nfs_mount_version(struct nfs_m
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;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -362,11 +362,14 @@ int check_nfs_mount_version(struct nfs_m
#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
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 ma
* 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;
}
--- autofs-5.1.4.orig/modules/mount_bind.c
+++ autofs-5.1.4/modules/mount_bind.c
@@ -122,7 +122,7 @@ int mount_mount(struct autofs_point *ap,
}
}
- 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");
--- autofs-5.1.4.orig/modules/mount_changer.c
+++ autofs-5.1.4/modules/mount_changer.c
@@ -59,7 +59,7 @@ int mount_mount(struct autofs_point *ap,
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");
--- autofs-5.1.4.orig/modules/mount_ext2.c
+++ autofs-5.1.4/modules/mount_ext2.c
@@ -55,7 +55,7 @@ int mount_mount(struct autofs_point *ap,
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");
--- autofs-5.1.4.orig/modules/mount_generic.c
+++ autofs-5.1.4/modules/mount_generic.c
@@ -54,7 +54,7 @@ int mount_mount(struct autofs_point *ap,
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");
--- autofs-5.1.4.orig/modules/mount_nfs.c
+++ autofs-5.1.4/modules/mount_nfs.c
@@ -213,7 +213,7 @@ int mount_mount(struct autofs_point *ap,
}
/* 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");
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1091,7 +1091,7 @@ static int mount_subtree(struct autofs_p
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;
@@ -1361,7 +1361,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");

View File

@ -0,0 +1,75 @@
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(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -22,6 +22,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.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -150,7 +150,7 @@ int do_umount_autofs_direct(struct autof
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_p
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);
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -265,7 +265,7 @@ int umount_autofs_indirect(struct autofs
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);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/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 {

View File

@ -0,0 +1,71 @@
autofs-5.1.7 - refactor lookup_prune_one_cache() a bit
From: Ian Kent <raven@themaw.net>
Coverity: use: Using an unreliable value of "me" inside the second locked
section.
Change lookup_prune_one_cache() a little, move the location the next
key is set (before releasing the lock) and add a comment explaining
why we don't care about the side effects of the read lock release/
write lock aquire/write lock release/read lock reaquire.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 20 +++++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -63,6 +63,7 @@
- fix arg not used in error print.
- fix missing lock release in mount_subtree().
- fix double free in parse_mapent().
+- refactor lookup_prune_one_cache() a bit.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -1383,7 +1383,6 @@ void lookup_prune_one_cache(struct autof
}
key = strdup(me->key);
- me = cache_enumerate(mc, me);
/* Don't consider any entries with a wildcard */
if (!key || strchr(key, '*')) {
if (key)
@@ -1430,6 +1429,7 @@ void lookup_prune_one_cache(struct autof
if (valid)
cache_unlock(valid->mc);
+ me = cache_enumerate(mc, me);
if (me)
next_key = strdup(me->key);
@@ -1464,6 +1464,24 @@ void lookup_prune_one_cache(struct autof
next:
cache_readlock(mc);
if (next_key) {
+ /* The lock release and reaquire above can mean
+ * a number of things could happen.
+ *
+ * First, mapents could be added between the
+ * current mapent and the mapent of next_key.
+ * Don't care about that because there's no
+ * need to prune newly added entries.
+ *
+ * Second, the next mapent data could have
+ * changed. Don't care about that either since
+ * we are looking to prune stale map entries
+ * and don't care when they become stale.
+ *
+ * Finally, the mapent of next_key could have
+ * gone away. Again don't care about this either,
+ * the loop will exit prematurely so just wait
+ * until the next prune and try again.
+ */
me = cache_lookup_distinct(mc, next_key);
free(next_key);
}

View File

@ -0,0 +1,255 @@
autofs-5.1.7 - refactor umount_multi_triggers()
From: Ian Kent <raven@themaw.net>
Refactor umount_multi_triggers() to try the umount of an offset subtree
in a seperate function.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
lib/mounts.c | 187 ++++++++++++++++++++++++++++++++---------------------------
2 files changed, 104 insertions(+), 84 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -10,6 +10,7 @@
- set offset parent in update_offset_entry().
- remove redundant variables from mount_autofs_offset().
- remove unused parameter form do_mount_autofs_offset().
+- refactor umount_multi_triggers().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2490,57 +2490,6 @@ static int do_mount_autofs_offset(struct
return mounted;
}
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
- const char *root, unsigned int start, const char *base)
-{
- char path[PATH_MAX + 1];
- char *offset = path;
- struct mapent *oe;
- struct list_head *pos = NULL;
- unsigned int root_len = strlen(root);
- int mounted;
-
- mounted = 0;
- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
- while (offset) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
-
- if (key_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- goto cont;
- }
-
- /* 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;
-
- mounted += do_mount_autofs_offset(ap, oe, root);
-
- /*
- * 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))
- mount_multi_triggers(ap, oe, key, strlen(key), base);
- }
-cont:
- offset = cache_get_offset(base,
- offset, start, &me->multi_list, &pos);
- }
-
- return mounted;
-}
-
static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
{
char *dir, *path;
@@ -2576,7 +2525,10 @@ static int rmdir_path_offset(struct auto
return ret;
}
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
+
+static int do_umount_multi_triggers(struct autofs_point *ap,
+ struct mapent *me, const char *root, const char *base)
{
char path[PATH_MAX + 1];
char *offset;
@@ -2606,7 +2558,6 @@ int umount_multi_triggers(struct autofs_
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;
if (mm_base_len > 1)
key_len += mm_base_len;
@@ -2626,47 +2577,116 @@ int umount_multi_triggers(struct autofs_
if (!oe || (strlen(oe->key) - start) == 1)
continue;
+ left += do_umount_offset(ap, oe, root);
+ }
+
+ return left;
+}
+
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
+{
+ char *oe_base;
+ int left = 0;
+
+ /*
+ * 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);
+
+ if (oe->ioctlfd != -1 ||
+ is_mounted(oe->key, MNTS_REAL)) {
+ left++;
+ return left;
+ }
+
+ debug(ap->logopt, "umount offset %s", oe->key);
+
+ if (umount_autofs_offset(ap, oe)) {
+ warn(ap->logopt, "failed to umount offset");
+ left++;
+ } else {
+ struct stat st;
+ int ret;
+
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
+ return left;
+
/*
- * Check for and umount subtree offsets resulting from
- * nonstrict mount fail.
+ * An error due to partial directory removal is
+ * ok so only try and remount the offset if the
+ * actual mount point still exists.
*/
- oe_base = oe->key + strlen(root);
- left += umount_multi_triggers(ap, oe, root, oe_base);
+ 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;
+ }
+ }
+ return left;
+}
- if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL)) {
- left++;
- continue;
+int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
+ const char *root, unsigned int start, const char *base)
+{
+ char path[PATH_MAX + 1];
+ char *offset = path;
+ struct mapent *oe;
+ struct list_head *pos = NULL;
+ unsigned int root_len = strlen(root);
+ int mounted;
+
+ mounted = 0;
+ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
+ while (offset) {
+ char key[PATH_MAX + 1];
+ int key_len = root_len + strlen(offset);
+
+ if (key_len > PATH_MAX) {
+ warn(ap->logopt, "path loo long");
+ goto cont;
}
- debug(ap->logopt, "umount offset %s", oe->key);
+ /* The root offset is always mounted seperately so the
+ * offset path will always be root + offset.
+ */
+ strcpy(key, root);
+ strcat(key, offset);
- if (umount_autofs_offset(ap, oe)) {
- warn(ap->logopt, "failed to umount offset");
- left++;
- } else {
- struct stat st;
- int ret;
+ oe = cache_lookup_distinct(me->mc, key);
+ if (!oe || !oe->mapent)
+ goto cont;
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
- continue;
+ mounted += do_mount_autofs_offset(ap, oe, root);
- /*
- * 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;
- }
+ /*
+ * 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))
+ mount_multi_triggers(ap, oe, key, strlen(key), base);
}
+cont:
+ offset = cache_get_offset(base,
+ offset, start, &me->multi_list, &pos);
}
+ return mounted;
+}
+
+int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
+{
+ int left;
+
+ left = do_umount_multi_triggers(ap, me, root, base);
+
if (!left && me->multi == me) {
struct mapent_cache *mc = me->mc;
int status;
@@ -2865,4 +2885,3 @@ int clean_stale_multi_triggers(struct au
return left;
}
-

View File

@ -0,0 +1,544 @@
autofs-5.1.7 - remove mount.x and rpcgen dependencies
From: Ian Kent <raven@themaw.net>
Adding a local implementation to get the exports list from a server
means the the rpcgen generataed code is no longer needed so remove
mount.x and the build dependencies.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
Makefile.conf.in | 1
autofs.spec | 2
configure | 58 ---------
configure.in | 1
include/automount.h | 1
include/config.h.in | 3
lib/Makefile | 26 ----
lib/mount.x | 345 ---------------------------------------------------
9 files changed, 5 insertions(+), 433 deletions(-)
delete mode 100644 lib/mount.x
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -1,5 +1,6 @@
- add xdr_exports().
+- remove mount.x and rpcgen dependencies.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/Makefile.conf.in
+++ autofs-5.1.4/Makefile.conf.in
@@ -65,7 +65,6 @@ FEDFS = @ENABLE_FEDFS@
LEX = @PATH_LEX@
YACC = @PATH_YACC@
-RPCGEN = @PATH_RPCGEN@
RANLIB = @PATH_RANLIB@
# Use libtirpc if requested and available
--- autofs-5.1.4.orig/configure
+++ autofs-5.1.4/configure
@@ -651,8 +651,6 @@ XML_CONFIG
ENABLE_FEDFS
sssldir
HAVE_SSS_AUTOFS
-PATH_RPCGEN
-RPCGEN
PATH_RANLIB
RANLIB
PATH_YACC
@@ -4322,62 +4320,6 @@ else
as_fn_error $? "required program RANLIB not found" "$LINENO" 5
fi
-for ac_prog in rpcgen
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_RPCGEN+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $RPCGEN in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_RPCGEN="$RPCGEN" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $searchpath
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-RPCGEN=$ac_cv_path_RPCGEN
-if test -n "$RPCGEN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5
-$as_echo "$RPCGEN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$RPCGEN" && break
-done
-
-if test -n "$RPCGEN"; then
-
-cat >>confdefs.h <<_ACEOF
-#define PATH_RPCGEN "$RPCGEN"
-_ACEOF
-
- PATH_RPCGEN="$RPCGEN"
-else
- as_fn_error $? "required program RPCGEN not found" "$LINENO" 5
-fi
-
if test -z "$sssldir"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sssd autofs library" >&5
--- autofs-5.1.4.orig/configure.in
+++ autofs-5.1.4/configure.in
@@ -165,7 +165,6 @@ AF_PATH_INCLUDE(E4FSCK, fsck.ext4 e4fsck
AF_CHECK_PROG(LEX, flex lex, , $searchpath)
AF_CHECK_PROG(YACC, bison, , $searchpath)
AF_CHECK_PROG(RANLIB, ranlib, , $searchpath)
-AF_CHECK_PROG(RPCGEN, rpcgen, , $searchpath)
AF_CHECK_SSS_LIB(SSS_AUTOFS, libsss_autofs.so)
AC_SUBST(HAVE_SSS_AUTOFS)
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -32,7 +32,6 @@
#include "macros.h"
#include "log.h"
#include "rpc_subs.h"
-#include "mounts.h"
#include "parse_subs.h"
#include "mounts.h"
#include "dev-ioctl-lib.h"
--- autofs-5.1.4.orig/include/config.h.in
+++ autofs-5.1.4/include/config.h.in
@@ -135,9 +135,6 @@
/* define if you have RANLIB */
#undef PATH_RANLIB
-/* define if you have RPCGEN */
-#undef PATH_RPCGEN
-
/* define if you have UMOUNT */
#undef PATH_UMOUNT
--- autofs-5.1.4.orig/lib/Makefile
+++ autofs-5.1.4/lib/Makefile
@@ -8,10 +8,9 @@ include ../Makefile.rules
SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \
nss_tok.c nss_parse.tab.c args.c alarm.c macros.c defaults.c \
parse_subs.c dev-ioctl-lib.c
-RPCS = mount.h mount_clnt.c mount_xdr.c
-OBJS = cache.o mount_clnt.o mount_xdr.o cat_path.o rpc_subs.o \
- mounts.o log.o nsswitch.o nss_tok.o nss_parse.tab.o args.o \
- alarm.o macros.o defaults.o parse_subs.o dev-ioctl-lib.o
+OBJS = cache.o cat_path.o rpc_subs.o mounts.o log.o nsswitch.o \
+ nss_tok.o nss_parse.tab.o args.o alarm.o macros.o defaults.o \
+ parse_subs.o dev-ioctl-lib.o
YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h
@@ -34,23 +33,6 @@ autofs.a: $(OBJS)
$(AR) $(ARFLAGS) $(LIB) $(OBJS)
-$(RANLIB) $(LIB)
-mount.h: mount.x
- $(RPCGEN) -h -o mount.h mount.x
-
-mount_clnt.c: mount.h
- $(RPCGEN) -l -o mount_clnt.c mount.x
-
-mount_clnt.o: mount_clnt.c
- $(CC) $(CFLAGS) -o mount_clnt.o -c mount_clnt.c
- $(STRIP) mount_clnt.o
-
-mount_xdr.c: mount.h
- $(RPCGEN) -c -o mount_xdr.c mount.x
-
-mount_xdr.o: mount_xdr.c
- $(CC) $(CFLAGS) -Wno-unused-variable -o mount_xdr.o -c mount_xdr.c
- $(STRIP) mount_xdr.o
-
nss_tok.c: nss_tok.l
$(LEX) -o$@ -Pnss_ $?
@@ -61,8 +43,6 @@ nss_tok.o: nss_tok.c nss_parse.tab.h
nss_parse.tab.o: nss_parse.tab.c nss_parse.tab.h
-rpc_subs.o: mount.h
-
install: all
clean:
--- autofs-5.1.4.orig/lib/mount.x
+++ /dev/null
@@ -1,345 +0,0 @@
-%/*
-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-% * unrestricted use provided that this legend is included on all tape
-% * media and as a part of the software program in whole or part. Users
-% * may copy or modify Sun RPC without charge, but are not authorized
-% * to license or distribute it to anyone else except as part of a product or
-% * program developed by the user or with the express written consent of
-% * Sun Microsystems, Inc.
-% *
-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-% *
-% * Sun RPC is provided with no support and without any obligation on the
-% * part of Sun Microsystems, Inc. to assist in its use, correction,
-% * modification or enhancement.
-% *
-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-% * OR ANY PART THEREOF.
-% *
-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-% * or profits or other special, indirect and consequential damages, even if
-% * Sun has been advised of the possibility of such damages.
-% *
-% * Sun Microsystems, Inc.
-% * 2550 Garcia Avenue
-% * Mountain View, California 94043
-% */
-
-%/*
-% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
-% */
-%
-%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-/*
- * Protocol description for the mount program
- */
-
-#ifdef RPC_HDR
-%#ifndef _rpcsvc_mount_h
-%#define _rpcsvc_mount_h
-%#include <memory.h>
-#endif
-
-const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
-const MNTNAMLEN = 255; /* maximum bytes in a name argument */
-const FHSIZE = 32; /* size in bytes of a file handle */
-
-/*
- * The fhandle is the file handle that the server passes to the client.
- * All file operations are done using the file handles to refer to a file
- * or a directory. The file handle can contain whatever information the
- * server needs to distinguish an individual file.
- */
-typedef opaque fhandle[FHSIZE];
-
-/*
- * If a status of zero is returned, the call completed successfully, and
- * a file handle for the directory follows. A non-zero status indicates
- * some sort of error. The status corresponds with UNIX error numbers.
- */
-union fhstatus switch (unsigned fhs_status) {
-case 0:
- fhandle fhs_fhandle;
-default:
- void;
-};
-
-/*
- * The type dirpath is the pathname of a directory
- */
-typedef string dirpath<MNTPATHLEN>;
-
-/*
- * The type name is used for arbitrary names (hostnames, groupnames)
- */
-typedef string name<MNTNAMLEN>;
-
-/*
- * A list of who has what mounted
- */
-typedef struct mountbody *mountlist;
-struct mountbody {
- name ml_hostname;
- dirpath ml_directory;
- mountlist ml_next;
-};
-
-/*
- * A list of netgroups
- */
-typedef struct groupnode *groups;
-struct groupnode {
- name gr_name;
- groups gr_next;
-};
-
-/*
- * A list of what is exported and to whom
- */
-typedef struct exportnode *exports;
-struct exportnode {
- dirpath ex_dir;
- groups ex_groups;
- exports ex_next;
-};
-
-/*
- * POSIX pathconf information
- */
-struct ppathcnf {
- int pc_link_max; /* max links allowed */
- short pc_max_canon; /* max line len for a tty */
- short pc_max_input; /* input a tty can eat all at once */
- short pc_name_max; /* max file name length (dir entry) */
- short pc_path_max; /* max path name length (/x/y/x/.. ) */
- short pc_pipe_buf; /* size of a pipe (bytes) */
- u_char pc_vdisable; /* safe char to turn off c_cc[i] */
- char pc_xxx; /* alignment padding; cc_t == char */
- short pc_mask[2]; /* validity and boolean bits */
-};
-
-/*
- * NFSv3 file handle
- */
-const FHSIZE3 = 64; /* max size of NFSv3 file handle in bytes */
-typedef opaque fhandle3<FHSIZE3>;
-
-/*
- * NFSv3 mount status
- */
-enum mountstat3 {
- MNT_OK = 0, /* no error */
- MNT3ERR_PERM = 1, /* not owner */
- MNT3ERR_NOENT = 2, /* no such file or directory */
- MNT3ERR_IO = 5, /* I/O error */
- MNT3ERR_ACCES = 13, /* Permission denied */
- MNT3ERR_NOTDIR = 20, /* Not a directory */
- MNT3ERR_INVAL = 22, /* Invalid argument */
- MNT3ERR_NAMETOOLONG = 63, /* File name too long */
- MNT3ERR_NOTSUPP = 10004,/* Operation not supported */
- MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
-};
-
-/*
- * NFSv3 mount result
- */
-struct mountres3_ok {
- fhandle3 fhandle;
- int auth_flavors<>;
-};
-
-union mountres3 switch (mountstat3 fhs_status) {
-case MNT_OK:
- mountres3_ok mountinfo; /* File handle and supported flavors */
-default:
- void;
-};
-
-program MOUNTPROG {
- /*
- * Version one of the mount protocol communicates with version two
- * of the NFS protocol. The only connecting point is the fhandle
- * structure, which is the same for both protocols.
- */
- version MOUNTVERS {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- fhstatus
- MOUNTPROC_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC_EXPORT(void) = 5;
-
- /*
- * Identical to MOUNTPROC_EXPORT above
- */
- exports
- MOUNTPROC_EXPORTALL(void) = 6;
- } = 1;
-
- /*
- * Version two of the mount protocol communicates with version two
- * of the NFS protocol.
- * The only difference from version one is the addition of a POSIX
- * pathconf call.
- */
- version MOUNTVERS_POSIX {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- fhstatus
- MOUNTPROC_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC_EXPORT(void) = 5;
-
- /*
- * Identical to MOUNTPROC_EXPORT above
- */
- exports
- MOUNTPROC_EXPORTALL(void) = 6;
-
- /*
- * POSIX pathconf info (Sun hack)
- */
- ppathcnf
- MOUNTPROC_PATHCONF(dirpath) = 7;
- } = 2;
-
- /*
- * Version 3 of the protocol is for NFSv3
- */
- version MOUNTVERS_NFSV3 {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC3_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- mountres3
- MOUNTPROC3_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC3_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC3_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC3_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC3_EXPORT(void) = 5;
- } = 3;
-} = 100005;
-
-#ifdef RPC_HDR
-%#endif /*!_rpcsvc_mount_h*/
-#endif

View File

@ -0,0 +1,168 @@
autofs-5.1.7 - remove mounts_mutex
From: Ian Kent <raven@themaw.net>
The mounts_mutex is no longer used, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 8 +-------
daemon/master.c | 13 -------------
include/automount.h | 1 -
modules/mount_autofs.c | 8 --------
5 files changed, 2 insertions(+), 29 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -48,6 +48,7 @@
- remove unused function master_submount_list_empty().
- move amd mounts removal into lib/mounts.c.
- check for offset with no mount location.
+- remove mounts_mutex.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -1749,7 +1749,6 @@ static void handle_mounts_cleanup(void *
* here.
*/
if (submount) {
- mounts_mutex_unlock(ap->parent);
master_source_unlock(ap->parent->entry);
master_free_mapent_sources(ap->entry, 1);
master_free_mapent(ap->entry);
@@ -1787,13 +1786,9 @@ static int submount_source_writelock_nes
if (status)
goto done;
- mounts_mutex_lock(parent);
-
status = pthread_rwlock_trywrlock(&ap->entry->source_lock);
- if (status) {
- mounts_mutex_unlock(parent);
+ if (status)
master_source_unlock(parent->entry);
- }
done:
if (status && status != EBUSY) {
@@ -1809,7 +1804,6 @@ static void submount_source_unlock_neste
struct autofs_point *parent = ap->parent;
master_source_unlock(ap->entry);
- mounts_mutex_unlock(parent);
master_source_unlock(parent->entry);
}
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -69,7 +69,6 @@ int master_add_autofs_point(struct maste
unsigned nobind, unsigned ghost, int submount)
{
struct autofs_point *ap;
- int status;
ap = malloc(sizeof(struct autofs_point));
if (!ap)
@@ -128,12 +127,6 @@ int master_add_autofs_point(struct maste
INIT_LIST_HEAD(&ap->amdmounts);
ap->shutdown = 0;
- status = pthread_mutex_init(&ap->mounts_mutex, NULL);
- if (status) {
- free(ap->path);
- free(ap);
- return 0;
- }
ap->mode = 0;
entry->ap = ap;
@@ -143,17 +136,11 @@ int master_add_autofs_point(struct maste
void master_free_autofs_point(struct autofs_point *ap)
{
- int status;
-
if (!ap)
return;
mnts_remove_amdmounts(ap);
- status = pthread_mutex_destroy(&ap->mounts_mutex);
- if (status)
- fatal(status);
-
if (ap->pref)
free(ap->pref);
free(ap->path);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -564,7 +564,6 @@ struct autofs_point {
enum states state; /* Current state */
int state_pipe[2]; /* State change router pipe */
struct autofs_point *parent; /* Owner of mounts list for submount */
- pthread_mutex_t mounts_mutex; /* Protect mount lists */
struct list_head mounts; /* List of autofs mounts at current level */
unsigned int submount; /* Is this a submount */
unsigned int submnt_count; /* Number of submounts */
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -283,8 +283,6 @@ int mount_mount(struct autofs_point *ap,
set_exp_timeout(nap, NULL, timeout);
nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- mounts_mutex_lock(ap);
-
if (source->flags & MAP_FLAG_FORMAT_AMD) {
struct mnt_list *mnt;
@@ -305,7 +303,6 @@ int mount_mount(struct autofs_point *ap,
if (handle_mounts_startup_cond_init(&suc)) {
crit(ap->logopt, MODPREFIX
"failed to init startup cond for mount %s", entry->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -316,7 +313,6 @@ int mount_mount(struct autofs_point *ap,
crit(ap->logopt,
MODPREFIX "failed to allocate mount %s", realpath);
handle_mounts_startup_cond_destroy(&suc);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -335,7 +331,6 @@ int mount_mount(struct autofs_point *ap,
realpath);
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -346,7 +341,6 @@ int mount_mount(struct autofs_point *ap,
if (status) {
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
fatal(status);
@@ -358,7 +352,6 @@ int mount_mount(struct autofs_point *ap,
MODPREFIX "failed to create submount for %s", realpath);
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -368,7 +361,6 @@ int mount_mount(struct autofs_point *ap,
ap->submnt_count++;
handle_mounts_startup_cond_destroy(&suc);
- mounts_mutex_unlock(ap);
return 0;
}

View File

@ -0,0 +1,739 @@
autofs-5.1.7 - remove obsolete functions
From: Ian Kent <raven@themaw.net>
Remove the code that's no longer used due to the tree mapent
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 10 -
include/mounts.h | 2
lib/cache.c | 227 -------------------------------------
lib/mounts.c | 311 ----------------------------------------------------
modules/parse_sun.c | 56 ---------
6 files changed, 2 insertions(+), 605 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -41,6 +41,7 @@
- add set_offset_tree_catatonic().
- add mount and umount offsets functions.
- switch to use tree implementation for offsets.
+- remove obsolete functions.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -162,16 +162,13 @@ struct stack {
struct mapent {
struct mapent *next;
struct list_head ino_index;
- struct list_head multi_list;
struct mapent_cache *mc;
struct map_source *source;
/* Need to know owner if we're a multi-mount */
struct tree_node *mm_root;
+ /* Parent nesting point within multi-mount */
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;
@@ -209,23 +206,18 @@ struct mapent *cache_lookup_next(struct
struct mapent *cache_lookup_key_next(struct mapent *me);
struct mapent *cache_lookup(struct mapent_cache *mc, const char *key);
struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key);
-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head);
struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix);
struct mapent *cache_partial_match_wild(struct mapent_cache *mc, const char *prefix);
int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
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);
-int cache_delete_offset(struct mapent_cache *mc, const char *key);
-int cache_delete_offset_list(struct mapent_cache *mc, const char *key);
void cache_release(struct map_source *map);
void cache_clean_null_cache(struct mapent_cache *mc);
void cache_release_null_cache(struct master *master);
struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me);
-char *cache_get_offset(const char *prefix, char *offset, int start, struct list_head *head, struct list_head **pos);
/* Utility functions */
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -187,8 +187,6 @@ void set_indirect_mount_tree_catatonic(s
void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *);
int umount_ent(struct autofs_point *, const char *);
int umount_amd_ext_mount(struct autofs_point *, const char *);
-int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
-int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
#endif
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -461,30 +461,6 @@ struct mapent *cache_lookup_distinct(str
return NULL;
}
-/* Lookup an offset within a multi-mount entry */
-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head)
-{
- struct list_head *p;
- struct mapent *this;
- /* Keys for direct maps may be as long as a path name */
- char o_key[PATH_MAX];
- /* Avoid "//" at the beginning of paths */
- const char *path_prefix = strlen(prefix) > 1 ? prefix : "";
- size_t size;
-
- /* root offset duplicates "/" */
- size = snprintf(o_key, sizeof(o_key), "%s%s", path_prefix, offset);
- if (size >= sizeof(o_key))
- return NULL;
-
- list_for_each(p, head) {
- this = list_entry(p, struct mapent, multi_list);
- if (!strcmp(&this->key[start], o_key))
- return this;
- }
- return NULL;
-}
-
/* cache must be read locked by caller */
static struct mapent *__cache_partial_match(struct mapent_cache *mc,
const char *prefix,
@@ -583,9 +559,6 @@ int cache_add(struct mapent_cache *mc, s
me->mm_parent = NULL;
INIT_TREE_NODE(&me->node);
INIT_LIST_HEAD(&me->ino_index);
- INIT_LIST_HEAD(&me->multi_list);
- me->multi = NULL;
- me->parent = NULL;
me->ioctlfd = -1;
me->dev = (dev_t) -1;
me->ino = (ino_t) -1;
@@ -616,33 +589,6 @@ int cache_add(struct mapent_cache *mc, s
}
/* cache must be write locked by caller */
-static void cache_add_ordered_offset(struct mapent *me, struct list_head *head)
-{
- struct list_head *p;
- struct mapent *this;
-
- list_for_each(p, head) {
- size_t tlen;
- int eq;
-
- this = list_entry(p, struct mapent, multi_list);
- tlen = strlen(this->key);
-
- eq = strncmp(this->key, me->key, tlen);
- if (!eq && tlen == strlen(me->key))
- return;
-
- if (eq > 0) {
- list_add_tail(&me->multi_list, p);
- return;
- }
- }
- list_add_tail(&me->multi_list, p);
-
- return;
-}
-
-/* cache must be write locked by caller */
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
{
unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
@@ -747,25 +693,6 @@ struct mapent *cache_get_offset_parent(s
return NULL;
}
-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
-{
- struct mapent *this, *parent;
-
- this = cache_lookup_distinct(mc, offset);
- if (!this)
- return 0;
- if (!IS_MM(this))
- return 0;
-
- parent = cache_get_offset_parent(mc, offset);
- if (parent)
- this->parent = parent;
- else
- this->parent = MM_ROOT(this);
-
- return 1;
-}
-
/* cache must be write locked by caller */
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age)
{
@@ -807,50 +734,6 @@ int cache_update(struct mapent_cache *mc
return ret;
}
-/* cache write lock of the multi mount owner must be held by caller */
-int cache_delete_offset(struct mapent_cache *mc, const char *key)
-{
- u_int32_t hashval = hash(key, mc->size);
- struct mapent *me = NULL, *pred;
- int status;
-
- me = mc->hash[hashval];
- if (!me)
- return CHE_FAIL;
-
- if (strcmp(key, me->key) == 0) {
- if (IS_MM(me) && IS_MM_ROOT(me))
- return CHE_FAIL;
- mc->hash[hashval] = me->next;
- goto delete;
- }
-
- while (me->next != NULL) {
- pred = me;
- me = me->next;
- if (strcmp(key, me->key) == 0) {
- if (IS_MM(me) && IS_MM_ROOT(me))
- return CHE_FAIL;
- pred->next = me->next;
- goto delete;
- }
- }
-
- return CHE_FAIL;
-
-delete:
- list_del(&me->multi_list);
- ino_index_lock(mc);
- list_del(&me->ino_index);
- ino_index_unlock(mc);
- free(me->key);
- if (me->mapent)
- free(me->mapent);
- free(me);
-
- return CHE_OK;
-}
-
/* cache must be write locked by caller */
int cache_delete(struct mapent_cache *mc, const char *key)
{
@@ -1024,113 +907,3 @@ struct mapent *cache_enumerate(struct ma
return cache_lookup_next(mc, me);
}
-
-/*
- * Get each offset from list head under prefix.
- * Maintain traversal current position in pos for subsequent calls.
- * Return each offset into offset.
- */
-/* cache must be read locked by caller */
-char *cache_get_offset(const char *prefix, char *offset, int start,
- struct list_head *head, struct list_head **pos)
-{
- struct list_head *next;
- struct mapent *this;
- size_t plen = strlen(prefix);
- size_t len = 0;
-
- if (*pos == head)
- return NULL;
-
- /* Find an offset */
- *offset = '\0';
- next = *pos ? (*pos)->next : head->next;
- while (next != head) {
- char *offset_start, *pstart, *pend;
-
- this = list_entry(next, struct mapent, multi_list);
- *pos = next;
- next = next->next;
-
- offset_start = &this->key[start];
- if (strlen(offset_start) <= plen)
- continue;
-
- if (!strncmp(prefix, offset_start, plen)) {
- struct mapent *np = NULL;
- char pe[PATH_MAX + 1];
-
- /* "/" doesn't count for root offset */
- if (plen == 1)
- pstart = &offset_start[plen - 1];
- else
- pstart = &offset_start[plen];
-
- /* not part of this sub-tree */
- if (*pstart != '/')
- continue;
-
- /* get next offset */
- pend = pstart;
- while (*pend++) {
- size_t nest_pt_offset;
-
- if (*pend != '/')
- continue;
-
- nest_pt_offset = start + pend - pstart;
- if (plen > 1)
- nest_pt_offset += plen;
- strcpy(pe, this->key);
- pe[nest_pt_offset] = '\0';
-
- np = cache_lookup_distinct(this->mc, pe);
- if (np)
- break;
- }
- if (np)
- continue;
- len = pend - pstart - 1;
- strncpy(offset, pstart, len);
- offset[len] ='\0';
- break;
- }
- }
-
- /* Seek to next offset */
- while (next != head) {
- char *offset_start, *pstart;
-
- this = list_entry(next, struct mapent, multi_list);
-
- offset_start = &this->key[start];
- if (strlen(offset_start) <= plen + len)
- break;
-
- /* "/" doesn't count for root offset */
- if (plen == 1)
- pstart = &offset_start[plen - 1];
- else
- pstart = &offset_start[plen];
-
- /* not part of this sub-tree */
- if (*pstart != '/')
- break;
-
- /* new offset */
- if (!*(pstart + len + 1))
- break;
-
- /* compare offset */
- if (pstart[len] != '/' ||
- strlen(pstart) != len ||
- strncmp(offset, pstart, len))
- break;
-
- *pos = next;
- next = next->next;
- }
-
- return *offset ? offset : NULL;
-}
-
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2849,21 +2849,6 @@ static void set_offset_tree_catatonic(st
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)) {
- struct list_head *head = &me->multi_list;
- struct list_head *p;
-
- list_for_each(p, head) {
- struct mapent *this;
-
- this = list_entry(p, struct mapent, multi_list);
- set_mount_catatonic(ap, this, this->ioctlfd);
- }
- }
-}
-
void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
{
struct master_mapent *entry = ap->entry;
@@ -3028,299 +3013,3 @@ done:
out:
return rv;
}
-
-static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe)
-{
- int mounted = 0;
- int ret;
-
- debug(ap->logopt, "mount offset %s", oe->key);
-
- ret = mount_autofs_offset(ap, oe);
- if (ret >= MOUNT_OFFSET_OK)
- mounted++;
- else {
- if (ret != MOUNT_OFFSET_IGNORE)
- warn(ap->logopt, "failed to mount offset");
- 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 mounted;
-}
-
-static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
-{
- char *dir, *path;
- unsigned int split;
- int ret;
-
- if (ap->type == LKP_DIRECT)
- return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev);
-
- dir = strdup(oe->key);
-
- if (ap->flags & MOUNT_FLAG_GHOST)
- split = ap->len + strlen(MM_ROOT(oe)->key) + 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 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,
- int start, const char *base)
-{
- 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;
- unsigned int root_len;
- unsigned int mm_base_len;
-
- left = 0;
-
- 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);
-
- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
-
- 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;
-
- 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, int start)
-{
- char *oe_base;
- int left = 0;
-
- /*
- * Check for and umount subtree offsets resulting from
- * nonstrict mount fail.
- */
- 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
- * 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 ++left;
- }
- }
-
- debug(ap->logopt, "umount offset %s", oe->key);
-
- if (umount_autofs_offset(ap, oe)) {
- warn(ap->logopt, "failed to umount offset");
- left++;
- } else {
- struct stat st;
- int ret;
-
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
- return left;
-
- /*
- * 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);
- if (ret)
- left++;
- /* But we did origianlly create this */
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
- }
- }
- return left;
-}
-
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
- const char *root, unsigned int start, const char *base)
-{
- char path[PATH_MAX + 1];
- char *offset = path;
- struct mapent *oe;
- struct list_head *pos = NULL;
- unsigned int root_len = strlen(root);
- int mounted;
-
- mounted = 0;
- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
- while (offset) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
-
- if (key_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- goto cont;
- }
-
- /* 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;
- if (oe->age != MM_ROOT(me)->age) {
- /* Best effort */
- do_umount_offset(ap, oe, root, start);
- goto cont;
- }
-
- mounted += do_mount_autofs_offset(ap, oe);
-
- /*
- * 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))
- mount_multi_triggers(ap, oe, key, key_len, base);
- }
-cont:
- offset = cache_get_offset(base,
- offset, start, &me->multi_list, &pos);
- }
-
- return mounted;
-}
-
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
-{
- int left, start;
-
- start = strlen(root);
-
- left = do_umount_multi_triggers(ap, me, root, start, base);
-
- if (!left && IS_MM_ROOT(me)) {
- /*
- * 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(root, MNTS_REAL)) {
- info(ap->logopt, "unmounting dir = %s", root);
- if (umount_ent(ap, root) &&
- is_mounted(root, MNTS_REAL)) {
- if (mount_multi_triggers(ap, me, root, start, "/") < 0)
- warn(ap->logopt,
- "failed to remount offset triggers");
- return ++left;
- }
- }
-
- /* check for mounted mount entry and remove it if found */
- mnts_remove_mount(root, MNTS_MOUNTED);
- }
-
- return left;
-}
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1076,62 +1076,6 @@ next:
return (p - ent);
}
-static void cleanup_multi_triggers(struct autofs_point *ap,
- struct mapent *me, const char *root, int start,
- const char *base)
-{
- char path[PATH_MAX + 1];
- char offset[PATH_MAX + 1];
- char *poffset = offset;
- struct mapent *oe;
- 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;
-
- if (!base)
- mm_base = o_root;
- else
- 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))) {
- 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);
- }
- }
-
- return;
-}
-
static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
const char *name, char *loc, char *options, void *ctxt)
{

View File

@ -0,0 +1,36 @@
autofs-5.1.7 - remove redundant assignment in master_add_amd_mount_section_mounts()
From: Ian Kent <raven@themaw.net>
Coverity: missing_lock: Accessing "entry->current" without holding lock
"master_mapent.current_mutex".
This is initialization not clearing current source. But the field has
already been initialized in the master_new_mapent() call.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -58,6 +58,7 @@
- add length check in umount_subtree_mounts().
- fix flags check in umount_multi().
- dont try umount after stat() ENOENT fail.
+- remove redundant assignment in master_add_amd_mount_section_mounts().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -996,7 +996,6 @@ static void master_add_amd_mount_section
source->master_line = 0;
entry->age = age;
- entry->current = NULL;
master_add_mapent(master, entry);
next:

View File

@ -0,0 +1,36 @@
autofs-5.1.7 - remove redundant if check
From: Ian Kent <raven@themaw.net>
Coverity: identical code in if condition branches.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 5 +----
2 files changed, 2 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -51,6 +51,7 @@
- remove mounts_mutex.
- remove unused variable from get_exports().
- add missing free in handle_mounts().
+- remove redundant if check.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -752,10 +752,7 @@ int mount_autofs_offset(struct autofs_po
ops->timeout(ap->logopt, ioctlfd, timeout);
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
- if (ap->logopt & LOGOPT_DEBUG)
- notify_mount_result(ap, me->key, timeout, str_offset);
- else
- notify_mount_result(ap, me->key, timeout, str_offset);
+ notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
debug(ap->logopt, "mounted trigger %s", me->key);

View File

@ -0,0 +1,70 @@
autofs-5.1.7 - remove redundant local var from sun_mount()
From: Ian Kent <raven@themaw.net>
The local variable mountpoint in sun_mount() is set directly from a
passed in parameter and never changed and the source isn't changed
either, so use the variable directly.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 13 ++++---------
2 files changed, 5 insertions(+), 9 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -42,6 +42,7 @@
- add mount and umount offsets functions.
- switch to use tree implementation for offsets.
- remove obsolete functions.
+- remove redundant local var from sun_mount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -530,7 +530,6 @@ static int sun_mount(struct autofs_point
int nonstrict = 1;
int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY;
int rv, cur_state;
- char *mountpoint;
char *what;
char *type;
@@ -623,9 +622,6 @@ static int sun_mount(struct autofs_point
}
}
- mountpoint = alloca(namelen + 1);
- sprintf(mountpoint, "%.*s", namelen, name);
-
type = ap->entry->maps->type;
if (type && !strcmp(type, "hosts")) {
if (options && *options != '\0') {
@@ -700,9 +696,9 @@ static int sun_mount(struct autofs_point
debug(ap->logopt, MODPREFIX
"mounting root %s, mountpoint %s, "
"what %s, fstype %s, options %s",
- root, mountpoint, what, fstype, options);
+ root, name, what, fstype, options);
- rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint),
+ rv = mount_nfs->mount_mount(ap, root, name, namelen,
what, fstype, options, mount_nfs->context);
} else {
if (!loclen)
@@ -722,11 +718,10 @@ static int sun_mount(struct autofs_point
debug(ap->logopt, MODPREFIX
"mounting root %s, mountpoint %s, "
"what %s, fstype %s, options %s",
- root, mountpoint, what, fstype, options);
+ root, name, what, fstype, options);
/* Generic mount routine */
- rv = do_mount(ap, root, mountpoint, strlen(mountpoint), what, fstype,
- options);
+ rv = do_mount(ap, root, name, namelen, what, fstype, options);
}
pthread_setcancelstate(cur_state, NULL);

View File

@ -0,0 +1,174 @@
autofs-5.1.7 - remove redundant variables from mount_autofs_offset()
From: Ian Kent <raven@themaw.net>
The path to be mounted is the key in the passed in mapent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 42 +++++++++++++++++++-----------------------
include/automount.h | 2 +-
lib/mounts.c | 2 +-
4 files changed, 22 insertions(+), 25 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -8,6 +8,7 @@
- fix is mounted check on non existent path.
- simplify cache_get_parent().
- set offset parent in update_offset_entry().
+- remove redundant variables from mount_autofs_offset().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -611,7 +611,7 @@ force_umount:
return rv;
}
-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset)
+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
{
const char *str_offset = mount_type_str(t_offset);
struct ioctl_ops *ops = get_ioctl_ops();
@@ -623,7 +623,6 @@ int mount_autofs_offset(struct autofs_po
const char *hosts_map_name = "-hosts";
const char *map_name = hosts_map_name;
const char *type;
- char mountpoint[PATH_MAX];
struct mnt_list *mnt;
if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) {
@@ -681,11 +680,8 @@ int mount_autofs_offset(struct autofs_po
return MOUNT_OFFSET_OK;
}
- strcpy(mountpoint, root);
- strcat(mountpoint, offset);
-
/* In case the directory doesn't exist, try to mkdir it */
- if (mkdir_path(mountpoint, mp_mode) < 0) {
+ if (mkdir_path(me->key, mp_mode) < 0) {
if (errno == EEXIST) {
/*
* If the mount point directory is a real mount
@@ -694,7 +690,7 @@ int mount_autofs_offset(struct autofs_po
* the kernel NFS client.
*/
if (me->multi != me &&
- is_mounted(mountpoint, MNTS_REAL))
+ is_mounted(me->key, MNTS_REAL))
return MOUNT_OFFSET_IGNORE;
/*
@@ -714,13 +710,13 @@ int mount_autofs_offset(struct autofs_po
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
debug(ap->logopt,
"can't create mount directory: %s, %s",
- mountpoint, estr);
+ me->key, estr);
return MOUNT_OFFSET_FAIL;
} else {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
crit(ap->logopt,
"failed to create mount directory: %s, %s",
- mountpoint, estr);
+ me->key, estr);
return MOUNT_OFFSET_FAIL;
}
} else {
@@ -730,56 +726,56 @@ int mount_autofs_offset(struct autofs_po
debug(ap->logopt,
"calling mount -t autofs " SLOPPY " -o %s automount %s",
- mp->options, mountpoint);
+ mp->options, me->key);
type = ap->entry->maps->type;
if (!type || strcmp(ap->entry->maps->type, "hosts"))
map_name = me->mc->map->argv[0];
- ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options);
+ ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options);
if (ret) {
crit(ap->logopt,
"failed to mount offset trigger %s at %s",
- me->key, mountpoint);
+ me->key, me->key);
goto out_err;
}
- ret = stat(mountpoint, &st);
+ ret = stat(me->key, &st);
if (ret == -1) {
error(ap->logopt,
- "failed to stat direct mount trigger %s", mountpoint);
+ "failed to stat direct mount trigger %s", me->key);
goto out_umount;
}
- ops->open(ap->logopt, &ioctlfd, st.st_dev, mountpoint);
+ ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
if (ioctlfd < 0) {
- crit(ap->logopt, "failed to create ioctl fd for %s", mountpoint);
+ crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
goto out_umount;
}
ops->timeout(ap->logopt, ioctlfd, timeout);
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
if (ap->logopt & LOGOPT_DEBUG)
- notify_mount_result(ap, mountpoint, timeout, str_offset);
+ notify_mount_result(ap, me->key, timeout, str_offset);
else
notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
- mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET);
+ mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET);
if (!mnt)
error(ap->logopt,
"failed to add offset mount %s to mounted list",
- mountpoint);
+ me->key);
- debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
+ debug(ap->logopt, "mounted trigger %s", me->key);
return MOUNT_OFFSET_OK;
out_umount:
- umount(mountpoint);
+ umount(me->key);
out_err:
- if (stat(mountpoint, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED)
- rmdir_path(ap, mountpoint, st.st_dev);
+ if (stat(me->key, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED)
+ rmdir_path(ap, me->key, st.st_dev);
return MOUNT_OFFSET_FAIL;
}
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -595,7 +595,7 @@ int expire_offsets_direct(struct autofs_
int mount_autofs_indirect(struct autofs_point *ap, const char *root);
int do_mount_autofs_direct(struct autofs_point *ap, struct mapent *me, time_t timeout);
int mount_autofs_direct(struct autofs_point *ap);
-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset);
+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me);
void submount_signal_parent(struct autofs_point *ap, unsigned int success);
void close_mount_fds(struct autofs_point *ap);
int umount_autofs_indirect(struct autofs_point *ap, const char *root);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2475,7 +2475,7 @@ static int do_mount_autofs_offset(struct
debug(ap->logopt, "mount offset %s at %s", oe->key, root);
- ret = mount_autofs_offset(ap, oe, root, offset);
+ ret = mount_autofs_offset(ap, oe);
if (ret >= MOUNT_OFFSET_OK)
mounted++;
else {

View File

@ -0,0 +1,54 @@
autofs-5.1.7 - remove unused function master_submount_list_empty()
From: Ian Kent <raven@themaw.net>
This function is not used anywhere now, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 12 ------------
include/master.h | 1 -
3 files changed, 1 insertion(+), 13 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -45,6 +45,7 @@
- remove redundant local var from sun_mount().
- use mount_fullpath() in one spot in parse_mount().
- pass root length to mount_fullpath().
+- remove unused function master_submount_list_empty().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -1119,18 +1119,6 @@ int master_read_master(struct master *ma
return 1;
}
-int master_submount_list_empty(struct autofs_point *ap)
-{
- int res = 0;
-
- mounts_mutex_lock(ap);
- if (list_empty(&ap->submounts))
- res = 1;
- mounts_mutex_unlock(ap);
-
- return res;
-}
-
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
{
struct mnt_list *this, *sbmnt;
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -116,7 +116,6 @@ void master_free_mapent_sources(struct m
void master_free_mapent(struct master_mapent *);
struct master *master_new(const char *, unsigned int, unsigned int);
int master_read_master(struct master *, time_t);
-int master_submount_list_empty(struct autofs_point *ap);
int master_notify_submount(struct autofs_point *, const char *path, enum states);
void master_notify_state_change(struct master *, int);
int master_mount_mounts(struct master *, time_t);

View File

@ -0,0 +1,59 @@
autofs-5.1.7 - remove unused functions cache_dump_multi() and cache_dump_cache()
From: Ian Kent <raven@themaw.net>
Remove debugging functions cache_dump_multi() and cache_dump_cache()
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 28 ----------------------------
2 files changed, 1 insertion(+), 28 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -29,6 +29,7 @@
- rename tree implementation functions.
- fix program map multi-mount lookup after mount fail.
- add some multi-mount macros.
+- remove unused functions cache_dump_multi() and cache_dump_cache().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -24,34 +24,6 @@
#include "automount.h"
-void cache_dump_multi(struct list_head *list)
-{
- struct list_head *p;
- struct mapent *me;
-
- list_for_each(p, list) {
- me = list_entry(p, struct mapent, multi_list);
- logmsg("key=%s", me->key);
- }
-}
-
-void cache_dump_cache(struct mapent_cache *mc)
-{
- struct mapent *me;
- unsigned int i;
-
- for (i = 0; i < mc->size; i++) {
- me = mc->hash[i];
- if (me == NULL)
- continue;
- while (me) {
- logmsg("me->key=%s me->multi=%p dev=%ld ino=%ld",
- me->key, me->multi, me->dev, me->ino);
- me = me->next;
- }
- }
-}
-
void cache_readlock(struct mapent_cache *mc)
{
int status;

View File

@ -0,0 +1,173 @@
autofs-5.1.7 - remove unused mount offset list lock functions
From: Ian Kent <raven@themaw.net>
When fixing the locking in parse_mount() it was evident that there was
no real benefit of having an additional lock for the offset list so its
use was eliminated.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 4 --
lib/cache.c | 70 +---------------------------------------------------
3 files changed, 3 insertions(+), 72 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -18,6 +18,7 @@
- fix return from umount_subtree_mounts() on offset list delete.
- pass mapent_cache to update_offset_entry().
- fix inconsistent locking in parse_mount().
+- remove unused mount offset list lock functions.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -162,7 +162,6 @@ struct stack {
struct mapent {
struct mapent *next;
struct list_head ino_index;
- pthread_rwlock_t multi_rwlock;
struct list_head multi_list;
struct mapent_cache *mc;
struct map_source *source;
@@ -211,9 +210,6 @@ int cache_set_offset_parent(struct mapen
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);
int cache_delete_offset(struct mapent_cache *mc, const char *key);
-void cache_multi_readlock(struct mapent *me);
-void cache_multi_writelock(struct mapent *me);
-void cache_multi_unlock(struct mapent *me);
int cache_delete_offset_list(struct mapent_cache *mc, const char *key);
void cache_release(struct map_source *map);
void cache_clean_null_cache(struct mapent_cache *mc);
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -108,58 +108,6 @@ void cache_lock_cleanup(void *arg)
return;
}
-void cache_multi_readlock(struct mapent *me)
-{
- int status;
-
- if (!me)
- return;
-
- status = pthread_rwlock_rdlock(&me->multi_rwlock);
- if (status) {
- logmsg("mapent cache multi mutex lock failed");
- fatal(status);
- }
- return;
-}
-
-void cache_multi_writelock(struct mapent *me)
-{
- int status;
-
- if (!me)
- return;
-
- status = pthread_rwlock_wrlock(&me->multi_rwlock);
- if (status) {
- logmsg("mapent cache multi mutex lock failed");
- fatal(status);
- }
- return;
-}
-
-void cache_multi_unlock(struct mapent *me)
-{
- int status;
-
- if (!me)
- return;
-
- status = pthread_rwlock_unlock(&me->multi_rwlock);
- if (status) {
- logmsg("mapent cache multi mutex unlock failed");
- fatal(status);
- }
- return;
-}
-
-void cache_multi_lock_cleanup(void *arg)
-{
- struct mapent *me = (struct mapent *) arg;
- cache_multi_unlock(me);
- return;
-}
-
static inline void ino_index_lock(struct mapent_cache *mc)
{
int status = pthread_mutex_lock(&mc->ino_index_mutex);
@@ -626,7 +574,6 @@ int cache_add(struct mapent_cache *mc, s
struct mapent *me, *existing = NULL;
char *pkey, *pent;
u_int32_t hashval = hash(key, mc->size);
- int status;
me = (struct mapent *) malloc(sizeof(struct mapent));
if (!me)
@@ -665,10 +612,6 @@ int cache_add(struct mapent_cache *mc, s
me->ino = (ino_t) -1;
me->flags = 0;
- status = pthread_rwlock_init(&me->multi_rwlock, NULL);
- if (status)
- fatal(status);
-
/*
* We need to add to the end if values exist in order to
* preserve the order in which the map was read on lookup.
@@ -894,7 +837,7 @@ int cache_update(struct mapent_cache *mc
return ret;
}
-/* cache_multi_lock of the multi mount owner must be held by caller */
+/* cache write lock of the multi mount owner must be held by caller */
int cache_delete_offset(struct mapent_cache *mc, const char *key)
{
u_int32_t hashval = hash(key, mc->size);
@@ -926,9 +869,6 @@ int cache_delete_offset(struct mapent_ca
return CHE_FAIL;
delete:
- status = pthread_rwlock_destroy(&me->multi_rwlock);
- if (status)
- fatal(status);
list_del(&me->multi_list);
ino_index_lock(mc);
list_del(&me->ino_index);
@@ -946,7 +886,7 @@ int cache_delete(struct mapent_cache *mc
{
struct mapent *me = NULL, *pred;
u_int32_t hashval = hash(key, mc->size);
- int status, ret = CHE_OK;
+ int ret = CHE_OK;
char this[PATH_MAX];
strcpy(this, key);
@@ -967,9 +907,6 @@ int cache_delete(struct mapent_cache *mc
goto done;
}
pred->next = me->next;
- status = pthread_rwlock_destroy(&me->multi_rwlock);
- if (status)
- fatal(status);
ino_index_lock(mc);
list_del(&me->ino_index);
ino_index_unlock(mc);
@@ -999,9 +936,6 @@ int cache_delete(struct mapent_cache *mc
goto done;
}
mc->hash[hashval] = me->next;
- status = pthread_rwlock_destroy(&me->multi_rwlock);
- if (status)
- fatal(status);
ino_index_lock(mc);
list_del(&me->ino_index);
ino_index_unlock(mc);

View File

@ -0,0 +1,62 @@
autofs-5.1.7 - remove unused parameter form do_mount_autofs_offset()
From: Ian Kent <raven@themaw.net>
The offset parameter of do_mount_autofs_offset() isn't used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -9,6 +9,7 @@
- simplify cache_get_parent().
- set offset parent in update_offset_entry().
- remove redundant variables from mount_autofs_offset().
+- remove unused parameter form do_mount_autofs_offset().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2466,9 +2466,7 @@ out:
}
static int do_mount_autofs_offset(struct autofs_point *ap,
- struct mapent *oe, const char *root,
- char *offset)
-
+ struct mapent *oe, const char *root)
{
int mounted = 0;
int ret;
@@ -2523,7 +2521,7 @@ int mount_multi_triggers(struct autofs_p
if (!oe || !oe->mapent)
goto cont;
- mounted += do_mount_autofs_offset(ap, oe, root, offset);
+ mounted += do_mount_autofs_offset(ap, oe, root);
/*
* If re-constructing a multi-mount it's necessary to walk
@@ -2660,7 +2658,7 @@ int umount_multi_triggers(struct autofs_
*/
ret = rmdir_path_offset(ap, oe);
if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root, offset);
+ ret = do_mount_autofs_offset(ap, oe, root);
if (ret)
left++;
/* But we did origianlly create this */
@@ -2841,7 +2839,7 @@ int clean_stale_multi_triggers(struct au
*/
ret = rmdir_path_offset(ap, oe);
if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root, offset);
+ ret = do_mount_autofs_offset(ap, oe, root);
if (ret) {
left++;
/* But we did origianlly create this */

View File

@ -0,0 +1,32 @@
autofs-5.1.7 - remove unused variable from get_exports()
From: Ian Kent <raven@themaw.net>
Fix complier warning about unused variable entry in get_exports().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -49,6 +49,7 @@
- move amd mounts removal into lib/mounts.c.
- check for offset with no mount location.
- remove mounts_mutex.
+- remove unused variable from get_exports().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -87,7 +87,6 @@ int lookup_read_master(struct master *ma
static char *get_exports(struct autofs_point *ap, const char *host)
{
char buf[MAX_ERR_BUF];
- char entry[PATH_MAX + 1];
char *mapent;
struct exportinfo *exp, *this;
size_t hostlen = strlen(host);

View File

@ -0,0 +1,155 @@
autofs-5.1.7 - rename path to m_offset in update_offset_entry()
From: Ian Kent <raven@themaw.net>
Rename local variable from path to m_offset in update_offset_entry() to
make the meaning of this variable clear.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 46 +++++++++++++++++++++++-----------------------
2 files changed, 24 insertions(+), 23 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -24,6 +24,7 @@
- don't add offset mounts to mounted mounts table.
- reduce umount EBUSY check delay.
- cleanup cache_delete() a little.
+- rename path to m_offset in update_offset_entry().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -798,36 +798,36 @@ static int
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 *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 p_len, m_key_len, m_options_len, m_mapent_len;
+ int o_len, m_key_len, m_options_len, m_mapent_len;
int ret;
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
/* Internal hosts map may have loc == NULL */
- if (!*path) {
+ if (!*m_offset) {
error(ap->logopt,
- MODPREFIX "syntax error in offset %s -> %s", path, loc);
+ MODPREFIX "syntax error in offset %s -> %s", m_offset, loc);
return CHE_FAIL;
}
- p_len = strlen(path);
+ o_len = strlen(m_offset);
/* Trailing '/' causes us pain */
- if (p_len > 1) {
- while (p_len > 1 && path[p_len - 1] == '/')
- p_len--;
+ if (o_len > 1) {
+ while (o_len > 1 && m_offset[o_len - 1] == '/')
+ o_len--;
}
- m_key_len = m_root_len + p_len;
+ m_key_len = m_root_len + o_len;
if (m_key_len > PATH_MAX) {
error(ap->logopt, MODPREFIX "multi mount key too long");
return CHE_FAIL;
}
strcpy(m_key, m_root);
- strncat(m_key, path, p_len);
+ strncat(m_key, m_offset, o_len);
m_key[m_key_len] = '\0';
m_options_len = 0;
@@ -862,15 +862,15 @@ update_offset_entry(struct autofs_point
if (ret == CHE_DUPLICATE) {
warn(ap->logopt, MODPREFIX
- "syntax error or duplicate offset %s -> %s", path, loc);
+ "syntax error or duplicate offset %s -> %s", m_offset, loc);
ret = CHE_OK;
} else if (ret == CHE_FAIL)
debug(ap->logopt, MODPREFIX
- "failed to update multi-mount offset %s -> %s", path, m_mapent);
+ "failed to update multi-mount offset %s -> %s", m_offset, m_mapent);
else {
ret = CHE_OK;
debug(ap->logopt, MODPREFIX
- "updated multi-mount offset %s -> %s", path, m_mapent);
+ "updated multi-mount offset %s -> %s", m_offset, m_mapent);
}
return ret;
@@ -1540,22 +1540,22 @@ dont_expand:
/* It's a multi-mount; deal with it */
do {
- char *path, *myoptions, *loc;
+ char *m_offset, *myoptions, *loc;
int status;
if ((*p == '"' && *(p + 1) != '/') || (*p != '"' && *p != '/')) {
l = 0;
- path = dequote("/", 1, ap->logopt);
+ m_offset = dequote("/", 1, ap->logopt);
debug(ap->logopt,
- MODPREFIX "dequote(\"/\") -> %s", path);
+ MODPREFIX "dequote(\"/\") -> %s", m_offset);
} else {
l = span_space(p, mapent_len - (p - pmapent));
- path = sanitize_path(p, l, LKP_MULTI, ap->logopt);
+ m_offset = sanitize_path(p, l, LKP_MULTI, ap->logopt);
debug(ap->logopt, MODPREFIX
- "dequote(\"%.*s\") -> %s", l, p, path);
+ "dequote(\"%.*s\") -> %s", l, p, m_offset);
}
- if (!path) {
+ if (!m_offset) {
warn(ap->logopt, MODPREFIX "null path or out of memory");
cache_writelock(mc);
cache_delete_offset_list(mc, name);
@@ -1577,7 +1577,7 @@ dont_expand:
cache_writelock(mc);
cache_delete_offset_list(mc, name);
cache_unlock(mc);
- free(path);
+ free(m_offset);
free(options);
free(pmapent);
pthread_setcancelstate(cur_state, NULL);
@@ -1589,14 +1589,14 @@ dont_expand:
status = update_offset_entry(ap, mc,
name, m_root, m_root_len,
- path, myoptions, loc, age);
+ m_offset, myoptions, loc, age);
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");
cache_writelock(mc);
cache_delete_offset_list(mc, name);
cache_unlock(mc);
- free(path);
+ free(m_offset);
free(options);
free(pmapent);
free(myoptions);
@@ -1608,7 +1608,7 @@ dont_expand:
if (loc)
free(loc);
- free(path);
+ free(m_offset);
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));

View File

@ -0,0 +1,196 @@
autofs-5.1.7 - rename tree implementation functions
From: Ian Kent <raven@themaw.net>
Rename the tree struct and functions to make them consistent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
lib/mounts.c | 86 +++++++++++++++++++++++++++++------------------------------
2 files changed, 44 insertions(+), 43 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -26,6 +26,7 @@
- cleanup cache_delete() a little.
- rename path to m_offset in update_offset_entry().
- don't pass root to do_mount_autofs_offset().
+- rename tree implementation functions.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1225,30 +1225,30 @@ done:
return has_mounted_mounts;
}
-struct node {
+struct tree_node {
struct mnt_list *mnt;
- struct node *left;
- struct node *right;
+ struct tree_node *left;
+ struct tree_node *right;
};
-static struct node *new(struct mnt_list *mnt)
+static struct tree_node *tree_new(struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *n;
- n = malloc(sizeof(struct node));
+ n = malloc(sizeof(struct tree_node));
if (!n)
return NULL;
- memset(n, 0, sizeof(struct node));
+ memset(n, 0, sizeof(struct tree_node));
n->mnt = mnt;
return n;
}
-static struct node *tree_root(struct mnt_list *mnt)
+static struct tree_node *tree_root(struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *n;
- n = new(mnt);
+ n = tree_new(mnt);
if (!n) {
error(LOGOPT_ANY, "failed to allcate tree root");
return NULL;
@@ -1257,37 +1257,37 @@ static struct node *tree_root(struct mnt
return n;
}
-static struct node *add_left(struct node *this, struct mnt_list *mnt)
+static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *new;
- n = new(mnt);
- if (!n) {
+ new = tree_new(mnt);
+ if (!new) {
error(LOGOPT_ANY, "failed to allcate tree node");
return NULL;
}
- this->left = n;
+ n->left = new;
return n;
}
-static struct node *add_right(struct node *this, struct mnt_list *mnt)
+static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *new;
- n = new(mnt);
- if (!n) {
+ new = tree_new(mnt);
+ if (!new) {
error(LOGOPT_ANY, "failed to allcate tree node");
return NULL;
}
- this->right = n;
+ n->right = new;
return n;
}
-static struct node *add_node(struct node *root, struct mnt_list *mnt)
+static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt)
{
- struct node *p, *q;
+ struct tree_node *p, *q;
unsigned int mp_len;
mp_len = strlen(mnt->mp);
@@ -1307,43 +1307,43 @@ static struct node *add_node(struct node
error(LOGOPT_ANY, "duplicate entry in mounts list");
else {
if (mp_len < strlen(p->mnt->mp))
- return add_left(p, mnt);
+ return tree_add_left(p, mnt);
else
- return add_right(p, mnt);
+ return tree_add_right(p, mnt);
}
return NULL;
}
-static void tree_free(struct node *tree)
+static void tree_free(struct tree_node *root)
{
- if (tree->right)
- tree_free(tree->right);
- if (tree->left)
- tree_free(tree->left);
- free(tree);
-}
-
-static void traverse(struct node *node, struct list_head *mnts)
-{
- if (node->right)
- traverse(node->right, mnts);
- list_add_tail(&node->mnt->expire, mnts);
- if (node->left)
- traverse(node->left, mnts);
+ if (root->right)
+ tree_free(root->right);
+ if (root->left)
+ tree_free(root->left);
+ free(root);
+}
+
+static void tree_traverse(struct tree_node *n, struct list_head *mnts)
+{
+ if (n->right)
+ tree_traverse(n->right, mnts);
+ list_add_tail(&n->mnt->expire, mnts);
+ if (n->left)
+ tree_traverse(n->left, mnts);
}
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
{
struct mnt_list *mnt;
- struct node *tree = NULL;
+ struct tree_node *tree = NULL;
mnts_hash_mutex_lock();
if (list_empty(&ap->mounts))
goto done;
list_for_each_entry(mnt, &ap->mounts, mount) {
- struct node *n;
+ struct tree_node *n;
if (!(mnt->flags & MNTS_MOUNTED))
continue;
@@ -1359,7 +1359,7 @@ void mnts_get_expire_list(struct list_he
continue;
}
- n = add_node(tree, mnt);
+ n = tree_add_node(tree, mnt);
if (!n) {
error(LOGOPT_ANY, "failed to add expire tree node");
tree_free(tree);
@@ -1367,7 +1367,7 @@ void mnts_get_expire_list(struct list_he
}
}
- traverse(tree, mnts);
+ tree_traverse(tree, mnts);
tree_free(tree);
done:
mnts_hash_mutex_unlock();

View File

@ -0,0 +1,96 @@
autofs-5.1.7 - set offset parent in update_offset_entry()
From: Ian Kent <raven@themaw.net>
Avoid the list traversal in cache_set_parents() by setting the
offset parent when updating the offset.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 2 +-
lib/cache.c | 26 +++++++++++---------------
modules/parse_sun.c | 5 ++++-
4 files changed, 17 insertions(+), 17 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -7,6 +7,7 @@
- eliminate cache_lookup_offset() usage.
- fix is mounted check on non existent path.
- simplify cache_get_parent().
+- set offset parent in update_offset_entry().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -207,7 +207,7 @@ struct mapent *cache_partial_match_wild(
int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout);
-int cache_set_parents(struct mapent *mm);
+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);
int cache_delete_offset(struct mapent_cache *mc, const char *key);
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -834,25 +834,21 @@ static struct mapent *get_offset_parent(
return NULL;
}
-int cache_set_parents(struct mapent *mm)
+int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
{
- struct list_head *multi_head, *p;
- struct mapent *this;
+ struct mapent *this, *parent;
- if (!mm->multi)
+ this = cache_lookup_distinct(mc, offset);
+ if (!this)
+ return 0;
+ if (!this->multi)
return 0;
- multi_head = &mm->multi->multi_list;
-
- list_for_each(p, multi_head) {
- struct mapent *parent;
- this = list_entry(p, struct mapent, multi_list);
- parent = get_offset_parent(mm->mc, this->key);
- if (parent)
- this->parent = parent;
- else
- this->parent = mm->multi;
- }
+ parent = get_offset_parent(mc, offset);
+ if (parent)
+ this->parent = parent;
+ else
+ this->parent = this->multi;
return 1;
}
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -861,6 +861,10 @@ update_offset_entry(struct autofs_point
}
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");
+
if (ret == CHE_DUPLICATE) {
warn(ap->logopt, MODPREFIX
"syntax error or duplicate offset %s -> %s", path, loc);
@@ -1615,7 +1619,6 @@ dont_expand:
*/
if (me == me->multi)
clean_stale_multi_triggers(ap, me, NULL, NULL);
- cache_set_parents(me);
rv = mount_subtree(ap, me, name, NULL, options, ctxt);

View File

@ -0,0 +1,101 @@
autofs-5.1.7 - simplify cache_get_parent()
From: Ian Kent <raven@themaw.net>
Eliminate the list traversal from get_parent() and rename it to
get_offset_parent() to better describe it's usage.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 46 ++++++++++++++++++++++++++++------------------
2 files changed, 29 insertions(+), 18 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -6,6 +6,7 @@
- fix mnts_remove_amdmount() uses wrong list.
- eliminate cache_lookup_offset() usage.
- fix is mounted check on non existent path.
+- simplify cache_get_parent().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -797,47 +797,57 @@ void cache_update_negative(struct mapent
}
-static struct mapent *get_parent(const char *key, struct list_head *head, struct list_head **pos)
+static struct mapent *get_offset_parent(struct mapent_cache *mc,
+ const char *key)
{
- struct list_head *next;
- struct mapent *this, *last;
- int eq;
+ struct mapent *me;
+ char *parent, *tail;
+ int key_len;
- last = NULL;
- next = *pos ? (*pos)->next : head->next;
+ key_len = strlen(key);
- list_for_each(next, head) {
- this = list_entry(next, struct mapent, multi_list);
+ /* Check if this is the root offset */
+ if (key[key_len - 1] == '/')
+ return NULL;
- if (!strcmp(this->key, key))
+ parent = strdup(key);
+ tail = &parent[key_len - 1];
+
+ while (*tail) {
+ while (*tail != '/')
+ tail--;
+
+ *tail = 0;
+
+ tail--;
+ if (tail == parent)
break;
- eq = strncmp(this->key, key, strlen(this->key));
- if (eq == 0) {
- *pos = next;
- last = this;
- continue;
+ me = cache_lookup_distinct(mc, parent);
+ if (me) {
+ free(parent);
+ return me;
}
}
+ free(parent);
- return last;
+ return NULL;
}
int cache_set_parents(struct mapent *mm)
{
- struct list_head *multi_head, *p, *pos;
+ struct list_head *multi_head, *p;
struct mapent *this;
if (!mm->multi)
return 0;
- pos = NULL;
multi_head = &mm->multi->multi_list;
list_for_each(p, multi_head) {
struct mapent *parent;
this = list_entry(p, struct mapent, multi_list);
- parent = get_parent(this->key, multi_head, &pos);
+ parent = get_offset_parent(mm->mc, this->key);
if (parent)
this->parent = parent;
else

View File

@ -0,0 +1,42 @@
autofs-5.1.7 - simplify mount_subtree() mount check
From: Ian Kent <raven@themaw.net>
The check of the return from sun_mount() following the possible mount
of the root offset in mount_subtree() can be simpler.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 10 +---------
2 files changed, 2 insertions(+), 9 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -12,6 +12,7 @@
- remove unused parameter form do_mount_autofs_offset().
- refactor umount_multi_triggers().
- eliminate clean_stale_multi_triggers().
+- simplify mount_subtree() mount check.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1205,15 +1205,7 @@ static int mount_subtree(struct autofs_p
free(ro_loc);
}
- if (ro && rv == 0) {
- 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, mm_root, start, mm_base);
- return 1;
- }
- } else if (rv <= 0) {
+ if ((ro && rv == 0) || rv <= 0) {
ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX

Some files were not shown because too many files have changed in this diff Show More