|
|
4d476f |
autofs-5.0.9 - amd lookup add handling of amd maps in the master map
|
|
|
4d476f |
|
|
|
4d476f |
From: Ian Kent <raven@themaw.net>
|
|
|
4d476f |
|
|
|
4d476f |
|
|
|
4d476f |
---
|
|
|
4d476f |
daemon/automount.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
4d476f |
include/automount.h | 1 +
|
|
|
4d476f |
include/master.h | 2 +
|
|
|
4d476f |
lib/master.c | 44 +++++++++++++++++++++++++++
|
|
|
4d476f |
lib/master_parse.y | 23 ++++++++++++--
|
|
|
4d476f |
lib/master_tok.l | 2 +
|
|
|
4d476f |
lib/parse_subs.c | 1 +
|
|
|
4d476f |
modules/mount_autofs.c | 24 +++++++++++++++
|
|
|
4d476f |
modules/parse_amd.c | 12 +++++++
|
|
|
4d476f |
9 files changed, 182 insertions(+), 6 deletions(-)
|
|
|
4d476f |
|
|
|
4d476f |
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
|
4d476f |
index fd5a19b..0ba3580 100644
|
|
|
4d476f |
--- a/daemon/automount.c
|
|
|
4d476f |
+++ b/daemon/automount.c
|
|
|
4d476f |
@@ -512,6 +512,9 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|
|
4d476f |
left++;
|
|
|
4d476f |
}
|
|
|
4d476f |
cache_multi_unlock(me->parent);
|
|
|
4d476f |
+ if (ap->entry->maps &&
|
|
|
4d476f |
+ (ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD))
|
|
|
4d476f |
+ cache_pop_mapent(me);
|
|
|
4d476f |
pthread_setcancelstate(cur_state, NULL);
|
|
|
4d476f |
}
|
|
|
4d476f |
|
|
|
4d476f |
@@ -525,13 +528,36 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|
|
4d476f |
* it already to ensure it's ok to remove any offset triggers.
|
|
|
4d476f |
*/
|
|
|
4d476f |
if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
|
|
|
4d476f |
+ struct amd_entry *entry;
|
|
|
4d476f |
debug(ap->logopt, "unmounting dir = %s", path);
|
|
|
4d476f |
if (umount_ent(ap, path)) {
|
|
|
4d476f |
warn(ap->logopt, "could not umount dir %s", path);
|
|
|
4d476f |
left++;
|
|
|
4d476f |
+ goto done;
|
|
|
4d476f |
}
|
|
|
4d476f |
- }
|
|
|
4d476f |
|
|
|
4d476f |
+ /* Check for an external mount and umount if possible */
|
|
|
4d476f |
+ mounts_mutex_lock(ap);
|
|
|
4d476f |
+ entry = __master_find_amdmount(ap, path);
|
|
|
4d476f |
+ if (!entry) {
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
+ goto done;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ list_del(&entry->entries);
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
+ if (ext_mount_remove(&entry->ext_mount, entry->fs)) {
|
|
|
4d476f |
+ if (umount_ent(ap, entry->fs))
|
|
|
4d476f |
+ debug(ap->logopt,
|
|
|
4d476f |
+ "failed to umount external mount %s",
|
|
|
4d476f |
+ entry->fs);
|
|
|
4d476f |
+ else
|
|
|
4d476f |
+ debug(ap->logopt,
|
|
|
4d476f |
+ "umounted external mount %s",
|
|
|
4d476f |
+ entry->fs);
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ free_amd_entry(entry);
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+done:
|
|
|
4d476f |
return left;
|
|
|
4d476f |
}
|
|
|
4d476f |
|
|
|
4d476f |
@@ -540,10 +566,55 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|
|
4d476f |
int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
|
|
4d476f |
{
|
|
|
4d476f |
int is_autofs_fs;
|
|
|
4d476f |
+ struct stat st;
|
|
|
4d476f |
int left;
|
|
|
4d476f |
|
|
|
4d476f |
debug(ap->logopt, "path %s incl %d", path, incl);
|
|
|
4d476f |
|
|
|
4d476f |
+ if (lstat(path, &st)) {
|
|
|
4d476f |
+ warn(ap->logopt,
|
|
|
4d476f |
+ "failed to stat mount point directory %s", path);
|
|
|
4d476f |
+ return 1;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+
|
|
|
4d476f |
+ /* if this is a symlink we can handle it now */
|
|
|
4d476f |
+ if (S_ISLNK(st.st_mode)) {
|
|
|
4d476f |
+ struct amd_entry *entry;
|
|
|
4d476f |
+ if (st.st_dev != ap->dev) {
|
|
|
4d476f |
+ crit(ap->logopt,
|
|
|
4d476f |
+ "symlink %s has the wrong device, "
|
|
|
4d476f |
+ "possible race condition", path);
|
|
|
4d476f |
+ return 1;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ debug(ap->logopt, "removing symlink %s", path);
|
|
|
4d476f |
+ if (unlink(path)) {
|
|
|
4d476f |
+ error(ap->logopt,
|
|
|
4d476f |
+ "failed to remove symlink %s", path);
|
|
|
4d476f |
+ return 1;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ /* Check for an external mount and attempt umount if needed */
|
|
|
4d476f |
+ mounts_mutex_lock(ap);
|
|
|
4d476f |
+ entry = __master_find_amdmount(ap, path);
|
|
|
4d476f |
+ if (!entry) {
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
+ return 0;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ list_del(&entry->entries);
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
+ if (ext_mount_remove(&entry->ext_mount, entry->fs)) {
|
|
|
4d476f |
+ if (umount_ent(ap, entry->fs))
|
|
|
4d476f |
+ debug(ap->logopt,
|
|
|
4d476f |
+ "failed to umount external mount %s",
|
|
|
4d476f |
+ entry->fs);
|
|
|
4d476f |
+ else
|
|
|
4d476f |
+ debug(ap->logopt,
|
|
|
4d476f |
+ "umounted external mount %s",
|
|
|
4d476f |
+ entry->fs);
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ free_amd_entry(entry);
|
|
|
4d476f |
+ return 0;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+
|
|
|
4d476f |
is_autofs_fs = 0;
|
|
|
4d476f |
if (master_find_submount(ap, path))
|
|
|
4d476f |
is_autofs_fs = 1;
|
|
|
4d476f |
@@ -1475,9 +1546,15 @@ static void handle_mounts_cleanup(void *arg)
|
|
|
4d476f |
clean = 1;
|
|
|
4d476f |
|
|
|
4d476f |
if (submount) {
|
|
|
4d476f |
+ struct amd_entry *am;
|
|
|
4d476f |
/* We are finishing up */
|
|
|
4d476f |
ap->parent->submnt_count--;
|
|
|
4d476f |
list_del_init(&ap->mounts);
|
|
|
4d476f |
+ am = __master_find_amdmount(ap->parent, ap->path);
|
|
|
4d476f |
+ if (am) {
|
|
|
4d476f |
+ list_del_init(&am->entries);
|
|
|
4d476f |
+ free_amd_entry(am);
|
|
|
4d476f |
+ }
|
|
|
4d476f |
}
|
|
|
4d476f |
|
|
|
4d476f |
/* Don't signal the handler if we have already done so */
|
|
|
4d476f |
diff --git a/include/automount.h b/include/automount.h
|
|
|
4d476f |
index 615efcc..37133fe 100644
|
|
|
4d476f |
--- a/include/automount.h
|
|
|
4d476f |
+++ b/include/automount.h
|
|
|
4d476f |
@@ -510,6 +510,7 @@ struct autofs_point {
|
|
|
4d476f |
struct autofs_point *parent; /* Owner of mounts list for submount */
|
|
|
4d476f |
pthread_mutex_t mounts_mutex; /* Protect mount lists */
|
|
|
4d476f |
struct list_head mounts; /* List of autofs mounts at current level */
|
|
|
4d476f |
+ struct list_head amdmounts; /* List of non submount amd mounts */
|
|
|
4d476f |
unsigned int submount; /* Is this a submount */
|
|
|
4d476f |
unsigned int shutdown; /* Shutdown notification */
|
|
|
4d476f |
unsigned int submnt_count; /* Number of submounts */
|
|
|
4d476f |
diff --git a/include/master.h b/include/master.h
|
|
|
4d476f |
index 8833ddf..bcc8eeb 100644
|
|
|
4d476f |
--- a/include/master.h
|
|
|
4d476f |
+++ b/include/master.h
|
|
|
4d476f |
@@ -104,6 +104,8 @@ void master_source_current_signal(struct master_mapent *);
|
|
|
4d476f |
struct master_mapent *master_find_mapent(struct master *, const char *);
|
|
|
4d476f |
struct autofs_point *__master_find_submount(struct autofs_point *, const char *);
|
|
|
4d476f |
struct autofs_point *master_find_submount(struct autofs_point *, const char *);
|
|
|
4d476f |
+struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *);
|
|
|
4d476f |
+struct amd_entry *master_find_amdmount(struct autofs_point *, const char *);
|
|
|
4d476f |
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
|
|
|
4d476f |
void master_add_mapent(struct master *, struct master_mapent *);
|
|
|
4d476f |
void master_remove_mapent(struct master_mapent *);
|
|
|
4d476f |
diff --git a/lib/master.c b/lib/master.c
|
|
|
4d476f |
index df4aef6..5e4ab51 100644
|
|
|
4d476f |
--- a/lib/master.c
|
|
|
4d476f |
+++ b/lib/master.c
|
|
|
4d476f |
@@ -120,6 +120,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
|
|
|
4d476f |
ap->submount = submount;
|
|
|
4d476f |
INIT_LIST_HEAD(&ap->mounts);
|
|
|
4d476f |
INIT_LIST_HEAD(&ap->submounts);
|
|
|
4d476f |
+ INIT_LIST_HEAD(&ap->amdmounts);
|
|
|
4d476f |
ap->shutdown = 0;
|
|
|
4d476f |
|
|
|
4d476f |
status = pthread_mutex_init(&ap->mounts_mutex, NULL);
|
|
|
4d476f |
@@ -136,11 +137,26 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
|
|
|
4d476f |
|
|
|
4d476f |
void master_free_autofs_point(struct autofs_point *ap)
|
|
|
4d476f |
{
|
|
|
4d476f |
+ struct list_head *p, *head;
|
|
|
4d476f |
int status;
|
|
|
4d476f |
|
|
|
4d476f |
if (!ap)
|
|
|
4d476f |
return;
|
|
|
4d476f |
|
|
|
4d476f |
+ mounts_mutex_lock(ap);
|
|
|
4d476f |
+ head = &ap->amdmounts;
|
|
|
4d476f |
+ p = head->next;
|
|
|
4d476f |
+ while (p != head) {
|
|
|
4d476f |
+ struct amd_entry *entry = list_entry(p, struct amd_entry, entries);
|
|
|
4d476f |
+ p = p->next;
|
|
|
4d476f |
+ if (!list_empty(&entry->ext_mount))
|
|
|
4d476f |
+ ext_mount_remove(&entry->ext_mount, entry->fs);
|
|
|
4d476f |
+ if (!list_empty(&entry->entries))
|
|
|
4d476f |
+ list_del(&entry->entries);
|
|
|
4d476f |
+ free(entry);
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
+
|
|
|
4d476f |
status = pthread_mutex_destroy(&ap->mounts_mutex);
|
|
|
4d476f |
if (status)
|
|
|
4d476f |
fatal(status);
|
|
|
4d476f |
@@ -694,6 +710,34 @@ struct autofs_point *master_find_submount(struct autofs_point *ap, const char *p
|
|
|
4d476f |
return submount;
|
|
|
4d476f |
}
|
|
|
4d476f |
|
|
|
4d476f |
+struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path)
|
|
|
4d476f |
+{
|
|
|
4d476f |
+ struct list_head *head, *p;
|
|
|
4d476f |
+
|
|
|
4d476f |
+ head = &ap->amdmounts;
|
|
|
4d476f |
+ list_for_each(p, head) {
|
|
|
4d476f |
+ struct amd_entry *entry;
|
|
|
4d476f |
+
|
|
|
4d476f |
+ entry = list_entry(p, struct amd_entry, entries);
|
|
|
4d476f |
+
|
|
|
4d476f |
+ if (!strcmp(entry->path, path))
|
|
|
4d476f |
+ return entry;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+
|
|
|
4d476f |
+ return NULL;
|
|
|
4d476f |
+}
|
|
|
4d476f |
+
|
|
|
4d476f |
+struct amd_entry *master_find_amdmount(struct autofs_point *ap, const char *path)
|
|
|
4d476f |
+{
|
|
|
4d476f |
+ struct amd_entry *entry;
|
|
|
4d476f |
+
|
|
|
4d476f |
+ mounts_mutex_lock(ap);
|
|
|
4d476f |
+ entry = __master_find_amdmount(ap, path);
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
+
|
|
|
4d476f |
+ return entry;
|
|
|
4d476f |
+}
|
|
|
4d476f |
+
|
|
|
4d476f |
struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
|
|
|
4d476f |
{
|
|
|
4d476f |
struct master_mapent *entry;
|
|
|
4d476f |
diff --git a/lib/master_parse.y b/lib/master_parse.y
|
|
|
4d476f |
index 11caf5b..03aedf7 100644
|
|
|
4d476f |
--- a/lib/master_parse.y
|
|
|
4d476f |
+++ b/lib/master_parse.y
|
|
|
4d476f |
@@ -790,12 +790,29 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
|
|
|
4d476f |
}
|
|
|
4d476f |
}
|
|
|
4d476f |
|
|
|
4d476f |
+ if (!format) {
|
|
|
4d476f |
+ if (conf_amd_mount_section_exists(path))
|
|
|
4d476f |
+ format = strdup("amd");
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+
|
|
|
4d476f |
+ if (format && !strcmp(format, "amd")) {
|
|
|
4d476f |
+ unsigned int loglevel = conf_amd_get_log_options();
|
|
|
4d476f |
+ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO)
|
|
|
4d476f |
+ logopt = LOGOPT_DEBUG;
|
|
|
4d476f |
+ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR)
|
|
|
4d476f |
+ logopt = LOGOPT_VERBOSE;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+
|
|
|
4d476f |
+
|
|
|
4d476f |
if (timeout < 0) {
|
|
|
4d476f |
/*
|
|
|
4d476f |
- * If no timeout is given get the timout from first
|
|
|
4d476f |
- * map (if it exists).
|
|
|
4d476f |
+ * If no timeout is given get the timout from the
|
|
|
4d476f |
+ * first map (if it exists) or the config for amd
|
|
|
4d476f |
+ * maps.
|
|
|
4d476f |
*/
|
|
|
4d476f |
- if (entry->maps)
|
|
|
4d476f |
+ if (format && !strcmp(format, "amd"))
|
|
|
4d476f |
+ timeout = conf_amd_get_dismount_interval(path);
|
|
|
4d476f |
+ else if (entry->maps)
|
|
|
4d476f |
timeout = entry->maps->exp_timeout;
|
|
|
4d476f |
else
|
|
|
4d476f |
timeout = default_timeout;
|
|
|
4d476f |
diff --git a/lib/master_tok.l b/lib/master_tok.l
|
|
|
4d476f |
index a55cc76..d43c1dd 100644
|
|
|
4d476f |
--- a/lib/master_tok.l
|
|
|
4d476f |
+++ b/lib/master_tok.l
|
|
|
4d476f |
@@ -119,7 +119,7 @@ DNNAMESTR2 ([[:alnum:]_.\-]+)
|
|
|
4d476f |
INTMAP (-hosts|-null)
|
|
|
4d476f |
MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
|
|
|
4d476f |
MULTISEP ([\-]{2}[[:blank:]]+)
|
|
|
4d476f |
-MTYPE ((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(:{OPTWS}|{WS}))
|
|
|
4d476f |
+MTYPE ((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS}))
|
|
|
4d476f |
|
|
|
4d476f |
|
|
|
4d476f |
OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
|
|
|
4d476f |
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
|
|
|
4d476f |
index de5319f..421d18c 100644
|
|
|
4d476f |
--- a/lib/parse_subs.c
|
|
|
4d476f |
+++ b/lib/parse_subs.c
|
|
|
4d476f |
@@ -109,6 +109,7 @@ static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types);
|
|
|
4d476f |
static struct types format_type[] = {
|
|
|
4d476f |
{ "sun", 3 },
|
|
|
4d476f |
{ "hesiod", 6 },
|
|
|
4d476f |
+ { "amd", 3},
|
|
|
4d476f |
};
|
|
|
4d476f |
static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types);
|
|
|
4d476f |
|
|
|
4d476f |
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
|
|
|
4d476f |
index 61aec70..ab5a8e3 100644
|
|
|
4d476f |
--- a/modules/mount_autofs.c
|
|
|
4d476f |
+++ b/modules/mount_autofs.c
|
|
|
4d476f |
@@ -203,6 +203,30 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
|
4d476f |
}
|
|
|
4d476f |
if (info->map)
|
|
|
4d476f |
argv[0] = info->map;
|
|
|
4d476f |
+ /*
|
|
|
4d476f |
+ * If the parent map format is amd and the format isn't
|
|
|
4d476f |
+ * specified in the map entry set it from the parent map
|
|
|
4d476f |
+ * source.
|
|
|
4d476f |
+ */
|
|
|
4d476f |
+ if (!info->format && ap->entry->maps) {
|
|
|
4d476f |
+ struct map_source *s = ap->entry->maps;
|
|
|
4d476f |
+ /*
|
|
|
4d476f |
+ * For amd maps, if the format and source type aren't
|
|
|
4d476f |
+ * specified try and set them from the parent.
|
|
|
4d476f |
+ */
|
|
|
4d476f |
+ if (s->flags & MAP_FLAG_FORMAT_AMD) {
|
|
|
4d476f |
+ info->format = strdup("amd");
|
|
|
4d476f |
+ if (!info->format)
|
|
|
4d476f |
+ warn(ap->logopt, MODPREFIX
|
|
|
4d476f |
+ "failed to set amd map format");
|
|
|
4d476f |
+ if (!info->type && s->type) {
|
|
|
4d476f |
+ info->type = strdup(s->type);
|
|
|
4d476f |
+ if (!info->type)
|
|
|
4d476f |
+ warn(ap->logopt, MODPREFIX
|
|
|
4d476f |
+ "failed to set amd map type");
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ }
|
|
|
4d476f |
|
|
|
4d476f |
if (options) {
|
|
|
4d476f |
p = options;
|
|
|
4d476f |
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
|
|
|
4d476f |
index 5d8617e..4322479 100644
|
|
|
4d476f |
--- a/modules/parse_amd.c
|
|
|
4d476f |
+++ b/modules/parse_amd.c
|
|
|
4d476f |
@@ -1563,8 +1563,18 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
|
|
4d476f |
dequote_entry(ap, this);
|
|
|
4d476f |
|
|
|
4d476f |
rv = amd_mount(ap, name, this, source, sv, flags, ctxt);
|
|
|
4d476f |
- if (!rv)
|
|
|
4d476f |
+ mounts_mutex_lock(ap);
|
|
|
4d476f |
+ if (!rv) {
|
|
|
4d476f |
+ /* Add to the parent list of mounts */
|
|
|
4d476f |
+ list_add_tail(&this->entries, &ap->amdmounts);
|
|
|
4d476f |
+ /* Mounted, leave it on the parent list */
|
|
|
4d476f |
+ list_del_init(&this->list);
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
break;
|
|
|
4d476f |
+ }
|
|
|
4d476f |
+ /* Not mounted, remove it from the parent list */
|
|
|
4d476f |
+ list_del_init(&this->entries);
|
|
|
4d476f |
+ mounts_mutex_unlock(ap);
|
|
|
4d476f |
}
|
|
|
4d476f |
free_amd_entry(cur_defaults);
|
|
|
4d476f |
|