Ian Kent 3685ec
autofs-5.0.3 - refactor mount request vars
Ian Kent 3685ec
Ian Kent 3685ec
From: Ian Kent <raven@themaw.net>
Ian Kent 3685ec
Ian Kent 3685ec
There is code duplication between the direct and indirect mount
Ian Kent 3685ec
modules that sets up the variables available to maps. This patch
Ian Kent 3685ec
reorganizes and moves that code to a common location.
Ian Kent 3685ec
Ian Kent 3685ec
Signed-off-by: Ian Kent <raven@themaw.net>
Ian Kent 3685ec
---
Ian Kent 3685ec
Ian Kent 3685ec
 daemon/direct.c      |  131 ----------------
Ian Kent 3685ec
 daemon/indirect.c    |  131 ----------------
Ian Kent 3685ec
 include/automount.h  |   56 -------
Ian Kent 3685ec
 include/mounts.h     |   91 +++++++++++
Ian Kent 3685ec
 include/parse_subs.h |    3 
Ian Kent 3685ec
 lib/mounts.c         |  410 ++++++++++++++++++++++++++++++++++++++++++++------
Ian Kent 3685ec
 lib/parse_subs.c     |  230 ----------------------------
Ian Kent 3685ec
 7 files changed, 458 insertions(+), 594 deletions(-)
Ian Kent 3685ec
 create mode 100644 include/mounts.h
Ian Kent 3685ec
Ian Kent 3685ec
Ian Kent 3685ec
diff --git a/daemon/direct.c b/daemon/direct.c
Ian Kent 3685ec
index 072ef97..a3869a5 100644
Ian Kent 3685ec
--- a/daemon/direct.c
Ian Kent 3685ec
+++ b/daemon/direct.c
Ian Kent 3685ec
@@ -35,8 +35,6 @@
Ian Kent 3685ec
 #include <sys/mount.h>
Ian Kent 3685ec
 #include <sys/vfs.h>
Ian Kent 3685ec
 #include <sched.h>
Ian Kent 3685ec
-#include <pwd.h>
Ian Kent 3685ec
-#include <grp.h>
Ian Kent 3685ec
 
Ian Kent 3685ec
 #include "automount.h"
Ian Kent 3685ec
 
Ian Kent 3685ec
@@ -1237,15 +1235,6 @@ static void *do_mount_direct(void *arg)
Ian Kent 3685ec
 {
Ian Kent 3685ec
 	struct pending_args *args, mt;
Ian Kent 3685ec
 	struct autofs_point *ap;
Ian Kent 3685ec
-	struct passwd pw;
Ian Kent 3685ec
-	struct passwd *ppw = &pw;
Ian Kent 3685ec
-	struct passwd **pppw = &pp;;
Ian Kent 3685ec
-	struct group gr;
Ian Kent 3685ec
-	struct group *pgr;
Ian Kent 3685ec
-	struct group **ppgr;
Ian Kent 3685ec
-	char *pw_tmp, *gr_tmp;
Ian Kent 3685ec
-	struct thread_stdenv_vars *tsv;
Ian Kent 3685ec
-	int tmplen, grplen;
Ian Kent 3685ec
 	struct stat st;
Ian Kent 3685ec
 	int status, state;
Ian Kent 3685ec
 
Ian Kent 3685ec
@@ -1291,126 +1280,8 @@ static void *do_mount_direct(void *arg)
Ian Kent 3685ec
 
Ian Kent 3685ec
 	info(ap->logopt, "attempting to mount entry %s", mt.name);
Ian Kent 3685ec
 
Ian Kent 3685ec
-	/*
Ian Kent 3685ec
-	 * Setup thread specific data values for macro
Ian Kent 3685ec
-	 * substution in map entries during the mount.
Ian Kent 3685ec
-	 * Best effort only as it must go ahead.
Ian Kent 3685ec
-	 */
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv = malloc(sizeof(struct thread_stdenv_vars));
Ian Kent 3685ec
-	if (!tsv) 
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->uid = mt.uid;
Ian Kent 3685ec
-	tsv->gid = mt.gid;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* Try to get passwd info */
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
Ian Kent 3685ec
-	if (tmplen < 0) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get buffer size for getpwuid_r");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	pw_tmp = malloc(tmplen + 1);
Ian Kent 3685ec
-	if (!pw_tmp) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for getpwuid_r");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	status = getpwuid_r(tsv->uid, ppw, pw_tmp, tmplen, pppw);
Ian Kent 3685ec
-	if (status || !ppw) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get passwd info from getpwuid_r");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(pw_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->user = strdup(pw.pw_name);
Ian Kent 3685ec
-	if (!tsv->user) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for user");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(pw_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->home = strdup(pw.pw_dir);
Ian Kent 3685ec
-	if (!tsv->home) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for home");
Ian Kent 3685ec
-		free(pw_tmp);
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	free(pw_tmp);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* Try to get group info */
Ian Kent 3685ec
-
Ian Kent 3685ec
-	grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
Ian Kent 3685ec
-	if (tmplen < 0) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get buffer size for getgrgid_r");
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	gr_tmp = NULL;
Ian Kent 3685ec
-	tmplen = grplen;
Ian Kent 3685ec
-	while (1) {
Ian Kent 3685ec
-		char *tmp = realloc(gr_tmp, tmplen + 1);
Ian Kent 3685ec
-		if (!tmp) {
Ian Kent 3685ec
-			error(ap->logopt, "failed to malloc buffer for getgrgid_r");
Ian Kent 3685ec
-			if (gr_tmp)
Ian Kent 3685ec
-				free(gr_tmp);
Ian Kent 3685ec
-			free(tsv->user);
Ian Kent 3685ec
-			free(tsv->home);
Ian Kent 3685ec
-			free(tsv);
Ian Kent 3685ec
-			goto cont;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-		gr_tmp = tmp;
Ian Kent 3685ec
-		pgr = &gr;
Ian Kent 3685ec
-		ppgr = &pg;;
Ian Kent 3685ec
-		status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr);
Ian Kent 3685ec
-		if (status != ERANGE)
Ian Kent 3685ec
-			break;
Ian Kent 3685ec
-		tmplen += grplen;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	if (status || !pgr) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get group info from getgrgid_r");
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(gr_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->group = strdup(gr.gr_name);
Ian Kent 3685ec
-	if (!tsv->group) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for group");
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(gr_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	free(gr_tmp);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	status = pthread_setspecific(key_thread_stdenv_vars, tsv);
Ian Kent 3685ec
-	if (status) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to set stdenv thread var");
Ian Kent 3685ec
-		free(tsv->group);
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-	}
Ian Kent 3685ec
+	set_tsd_user_vars(ap->logopt, mt.uid, mt.gid);
Ian Kent 3685ec
 
Ian Kent 3685ec
-cont:
Ian Kent 3685ec
 	status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
Ian Kent 3685ec
 	/*
Ian Kent 3685ec
 	 * Direct mounts are always a single mount. If it fails there's
Ian Kent 3685ec
diff --git a/daemon/indirect.c b/daemon/indirect.c
Ian Kent 3685ec
index ccdd8bf..3922f3f 100644
Ian Kent 3685ec
--- a/daemon/indirect.c
Ian Kent 3685ec
+++ b/daemon/indirect.c
Ian Kent 3685ec
@@ -33,8 +33,6 @@
Ian Kent 3685ec
 #include <sys/time.h>
Ian Kent 3685ec
 #include <sys/mount.h>
Ian Kent 3685ec
 #include <sched.h>
Ian Kent 3685ec
-#include <pwd.h>
Ian Kent 3685ec
-#include <grp.h>
Ian Kent 3685ec
 
Ian Kent 3685ec
 #include "automount.h"
Ian Kent 3685ec
 
Ian Kent 3685ec
@@ -672,15 +670,7 @@ static void *do_mount_indirect(void *arg)
Ian Kent 3685ec
 	struct autofs_point *ap;
Ian Kent 3685ec
 	char buf[PATH_MAX + 1];
Ian Kent 3685ec
 	struct stat st;
Ian Kent 3685ec
-	struct passwd pw;
Ian Kent 3685ec
-	struct passwd *ppw = &pw;
Ian Kent 3685ec
-	struct passwd **pppw = &pp;;
Ian Kent 3685ec
-	struct group gr;
Ian Kent 3685ec
-	struct group *pgr;
Ian Kent 3685ec
-	struct group **ppgr;
Ian Kent 3685ec
-	char *pw_tmp, *gr_tmp;
Ian Kent 3685ec
-	struct thread_stdenv_vars *tsv;
Ian Kent 3685ec
-	int len, tmplen, grplen, status, state;
Ian Kent 3685ec
+	int len, status, state;
Ian Kent 3685ec
 
Ian Kent 3685ec
 	args = (struct pending_args *) arg;
Ian Kent 3685ec
 
Ian Kent 3685ec
@@ -722,125 +712,8 @@ static void *do_mount_indirect(void *arg)
Ian Kent 3685ec
 
Ian Kent 3685ec
 	info(ap->logopt, "attempting to mount entry %s", buf);
Ian Kent 3685ec
 
Ian Kent 3685ec
-	/*
Ian Kent 3685ec
-	 * Setup thread specific data values for macro
Ian Kent 3685ec
-	 * substution in map entries during the mount.
Ian Kent 3685ec
-	 * Best effort only as it must go ahead.
Ian Kent 3685ec
-	 */
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv = malloc(sizeof(struct thread_stdenv_vars));
Ian Kent 3685ec
-	if (!tsv) 
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->uid = mt.uid;
Ian Kent 3685ec
-	tsv->gid = mt.gid;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* Try to get passwd info */
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
Ian Kent 3685ec
-	if (tmplen < 0) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get buffer size for getpwuid_r");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	pw_tmp = malloc(tmplen + 1);
Ian Kent 3685ec
-	if (!pw_tmp) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for getpwuid_r");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	status = getpwuid_r(tsv->uid, ppw, pw_tmp, tmplen, pppw);
Ian Kent 3685ec
-	if (status || !ppw) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get passwd info from getpwuid_r");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(pw_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->user = strdup(pw.pw_name);
Ian Kent 3685ec
-	if (!tsv->user) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for user");
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(pw_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->home = strdup(pw.pw_dir);
Ian Kent 3685ec
-	if (!tsv->home) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for home");
Ian Kent 3685ec
-		free(pw_tmp);
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
+	set_tsd_user_vars(ap->logopt, mt.uid, mt.gid);
Ian Kent 3685ec
 
Ian Kent 3685ec
-	free(pw_tmp);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* Try to get group info */
Ian Kent 3685ec
-
Ian Kent 3685ec
-	grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
Ian Kent 3685ec
-	if (tmplen < 0) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get buffer size for getgrgid_r");
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	gr_tmp = NULL;
Ian Kent 3685ec
-	tmplen = grplen;
Ian Kent 3685ec
-	while (1) {
Ian Kent 3685ec
-		char *tmp = realloc(gr_tmp, tmplen + 1);
Ian Kent 3685ec
-		if (!tmp) {
Ian Kent 3685ec
-			error(ap->logopt, "failed to malloc buffer for getgrgid_r");
Ian Kent 3685ec
-			if (gr_tmp)
Ian Kent 3685ec
-				free(gr_tmp);
Ian Kent 3685ec
-			free(tsv->user);
Ian Kent 3685ec
-			free(tsv->home);
Ian Kent 3685ec
-			free(tsv);
Ian Kent 3685ec
-			goto cont;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-		gr_tmp = tmp;
Ian Kent 3685ec
-		pgr = &gr;
Ian Kent 3685ec
-		ppgr = &pg;;
Ian Kent 3685ec
-		status = getgrgid_r(tsv->gid, pgr, gr_tmp, tmplen, ppgr);
Ian Kent 3685ec
-		if (status != ERANGE)
Ian Kent 3685ec
-			break;
Ian Kent 3685ec
-		tmplen += grplen;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	if (status || !pgr) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to get group info from getgrgid_r");
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(gr_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tsv->group = strdup(gr.gr_name);
Ian Kent 3685ec
-	if (!tsv->group) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to malloc buffer for group");
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-		free(gr_tmp);
Ian Kent 3685ec
-		goto cont;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	free(gr_tmp);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	status = pthread_setspecific(key_thread_stdenv_vars, tsv);
Ian Kent 3685ec
-	if (status) {
Ian Kent 3685ec
-		error(ap->logopt, "failed to set stdenv thread var");
Ian Kent 3685ec
-		free(tsv->group);
Ian Kent 3685ec
-		free(tsv->user);
Ian Kent 3685ec
-		free(tsv->home);
Ian Kent 3685ec
-		free(tsv);
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-cont:
Ian Kent 3685ec
 	status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
Ian Kent 3685ec
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
Ian Kent 3685ec
 	if (status) {
Ian Kent 3685ec
diff --git a/include/automount.h b/include/automount.h
Ian Kent 3685ec
index 72e2457..da1bf8f 100644
Ian Kent 3685ec
--- a/include/automount.h
Ian Kent 3685ec
+++ b/include/automount.h
Ian Kent 3685ec
@@ -28,6 +28,7 @@
Ian Kent 3685ec
 #include "macros.h"
Ian Kent 3685ec
 #include "log.h"
Ian Kent 3685ec
 #include "rpc_subs.h"
Ian Kent 3685ec
+#include "mounts.h"
Ian Kent 3685ec
 #include "parse_subs.h"
Ian Kent 3685ec
 
Ian Kent 3685ec
 #ifdef WITH_DMALLOC
Ian Kent 3685ec
@@ -323,61 +324,6 @@ int cat_path(char *buf, size_t len, const char *dir, const char *base);
Ian Kent 3685ec
 int ncat_path(char *buf, size_t len,
Ian Kent 3685ec
               const char *dir, const char *base, size_t blen);
Ian Kent 3685ec
 
Ian Kent 3685ec
-/* mount table utilities */
Ian Kent 3685ec
-
Ian Kent 3685ec
-#define MNTS_ALL	0x0001
Ian Kent 3685ec
-#define MNTS_REAL	0x0002
Ian Kent 3685ec
-#define MNTS_AUTOFS	0x0004
Ian Kent 3685ec
-
Ian Kent 3685ec
-struct mnt_list {
Ian Kent 3685ec
-	char *path;
Ian Kent 3685ec
-	char *fs_name;
Ian Kent 3685ec
-	char *fs_type;
Ian Kent 3685ec
-	char *opts;
Ian Kent 3685ec
-	pid_t owner;
Ian Kent 3685ec
-	/*
Ian Kent 3685ec
-	 * List operations ie. get_mnt_list.
Ian Kent 3685ec
-	 */
Ian Kent 3685ec
-	struct mnt_list *next;
Ian Kent 3685ec
-	/*
Ian Kent 3685ec
-	 * Tree operations ie. tree_make_tree,
Ian Kent 3685ec
-	 * tree_get_mnt_list etc.
Ian Kent 3685ec
-	 */
Ian Kent 3685ec
-	struct mnt_list *left;
Ian Kent 3685ec
-	struct mnt_list *right;
Ian Kent 3685ec
-	struct list_head self;
Ian Kent 3685ec
-	struct list_head list;
Ian Kent 3685ec
-	struct list_head entries;
Ian Kent 3685ec
-	struct list_head sublist;
Ian Kent 3685ec
-	/*
Ian Kent 3685ec
-	 * Offset mount handling ie. add_ordered_list
Ian Kent 3685ec
-	 * and get_offset.
Ian Kent 3685ec
-	 */
Ian Kent 3685ec
-	struct list_head ordered;
Ian Kent 3685ec
-};
Ian Kent 3685ec
-
Ian Kent 3685ec
-unsigned int query_kproto_ver(void);
Ian Kent 3685ec
-unsigned int get_kver_major(void);
Ian Kent 3685ec
-unsigned int get_kver_minor(void);
Ian Kent 3685ec
-char *make_options_string(char *path, int kernel_pipefd, char *extra);
Ian Kent 3685ec
-char *make_mnt_name_string(char *path);
Ian Kent 3685ec
-struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
Ian Kent 3685ec
-struct mnt_list *reverse_mnt_list(struct mnt_list *list);
Ian Kent 3685ec
-void free_mnt_list(struct mnt_list *list);
Ian Kent 3685ec
-int contained_in_local_fs(const char *path);
Ian Kent 3685ec
-int is_mounted(const char *table, const char *path, unsigned int type);
Ian Kent 3685ec
-int has_fstab_option(const char *opt);
Ian Kent 3685ec
-char *find_mnt_ino(const char *table, dev_t dev, ino_t ino);
Ian Kent 3685ec
-char *get_offset(const char *prefix, char *offset,
Ian Kent 3685ec
-                 struct list_head *head, struct list_head **pos);
Ian Kent 3685ec
-void add_ordered_list(struct mnt_list *ent, struct list_head *head);
Ian Kent 3685ec
-void tree_free_mnt_tree(struct mnt_list *tree);
Ian Kent 3685ec
-struct mnt_list *tree_make_mnt_tree(const char *table, const char *path);
Ian Kent 3685ec
-int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
Ian Kent 3685ec
-int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
Ian Kent 3685ec
-int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
Ian Kent 3685ec
-int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
Ian Kent 3685ec
-
Ian Kent 3685ec
 /* Core automount definitions */
Ian Kent 3685ec
 
Ian Kent 3685ec
 #define MNT_DETACH	0x00000002	/* Just detach from the tree */
Ian Kent 3685ec
diff --git a/include/mounts.h b/include/mounts.h
Ian Kent 3685ec
new file mode 100644
Ian Kent 3685ec
index 0000000..7120351
Ian Kent 3685ec
--- /dev/null
Ian Kent 3685ec
+++ b/include/mounts.h
Ian Kent 3685ec
@@ -0,0 +1,91 @@
Ian Kent 3685ec
+/* ----------------------------------------------------------------------- *
Ian Kent 3685ec
+ *
Ian Kent 3685ec
+ *  mounts.h - header file for mount utilities module.
Ian Kent 3685ec
+ *
Ian Kent 3685ec
+ *   Copyright 2008 Red Hat, Inc. All rights reserved.
Ian Kent 3685ec
+ *   Copyright 2004-2006 Ian Kent <raven@themaw.net> - All Rights Reserved.
Ian Kent 3685ec
+ *
Ian Kent 3685ec
+ *   This program is free software; you can redistribute it and/or modify
Ian Kent 3685ec
+ *   it under the terms of the GNU General Public License as published by
Ian Kent 3685ec
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
Ian Kent 3685ec
+ *   USA; either version 2 of the License, or (at your option) any later
Ian Kent 3685ec
+ *   version; incorporated herein by reference.
Ian Kent 3685ec
+ *
Ian Kent 3685ec
+ * ----------------------------------------------------------------------- */
Ian Kent 3685ec
+
Ian Kent 3685ec
+#ifndef MOUNTS_H
Ian Kent 3685ec
+#define MOUNTS_H
Ian Kent 3685ec
+
Ian Kent 3685ec
+#define AUTOFS_TYPE_ANY		0x0000
Ian Kent 3685ec
+#define AUTOFS_TYPE_INDIRECT	0x0001
Ian Kent 3685ec
+#define AUTOFS_TYPE_DIRECT	0x0002
Ian Kent 3685ec
+#define AUTOFS_TYPE_OFFSET	0x0004
Ian Kent 3685ec
+
Ian Kent 3685ec
+#define MNTS_ALL	0x0001
Ian Kent 3685ec
+#define MNTS_REAL	0x0002
Ian Kent 3685ec
+#define MNTS_AUTOFS	0x0004
Ian Kent 3685ec
+
Ian Kent 3685ec
+#define REMOUNT_SUCCESS		0x0000
Ian Kent 3685ec
+#define REMOUNT_OPEN_FAIL	0x0001
Ian Kent 3685ec
+#define REMOUNT_STAT_FAIL	0x0002
Ian Kent 3685ec
+#define REMOUNT_READ_MAP	0x0004
Ian Kent 3685ec
+
Ian Kent 3685ec
+extern const unsigned int indirect;
Ian Kent 3685ec
+extern const unsigned int direct;
Ian Kent 3685ec
+extern const unsigned int offset;
Ian Kent 3685ec
+
Ian Kent 3685ec
+struct mapent;
Ian Kent 3685ec
+
Ian Kent 3685ec
+struct mnt_list {
Ian Kent 3685ec
+	char *path;
Ian Kent 3685ec
+	char *fs_name;
Ian Kent 3685ec
+	char *fs_type;
Ian Kent 3685ec
+	char *opts;
Ian Kent 3685ec
+	pid_t owner;
Ian Kent 3685ec
+	/*
Ian Kent 3685ec
+	 * List operations ie. get_mnt_list.
Ian Kent 3685ec
+	 */
Ian Kent 3685ec
+	struct mnt_list *next;
Ian Kent 3685ec
+	/*
Ian Kent 3685ec
+	 * Tree operations ie. tree_make_tree,
Ian Kent 3685ec
+	 * tree_get_mnt_list etc.
Ian Kent 3685ec
+	 */
Ian Kent 3685ec
+	struct mnt_list *left;
Ian Kent 3685ec
+	struct mnt_list *right;
Ian Kent 3685ec
+	struct list_head self;
Ian Kent 3685ec
+	struct list_head list;
Ian Kent 3685ec
+	struct list_head entries;
Ian Kent 3685ec
+	struct list_head sublist;
Ian Kent 3685ec
+	/*
Ian Kent 3685ec
+	 * Offset mount handling ie. add_ordered_list
Ian Kent 3685ec
+	 * and get_offset.
Ian Kent 3685ec
+	 */
Ian Kent 3685ec
+	struct list_head ordered;
Ian Kent 3685ec
+};
Ian Kent 3685ec
+
Ian Kent 3685ec
+unsigned int query_kproto_ver(void);
Ian Kent 3685ec
+unsigned int get_kver_major(void);
Ian Kent 3685ec
+unsigned int get_kver_minor(void);
Ian Kent 3685ec
+char *make_options_string(char *path, int kernel_pipefd, const char *extra);
Ian Kent 3685ec
+char *make_mnt_name_string(char *path);
Ian Kent 3685ec
+struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
Ian Kent 3685ec
+struct mnt_list *reverse_mnt_list(struct mnt_list *list);
Ian Kent 3685ec
+void free_mnt_list(struct mnt_list *list);
Ian Kent 3685ec
+int contained_in_local_fs(const char *path);
Ian Kent 3685ec
+int is_mounted(const char *table, const char *path, unsigned int type);
Ian Kent 3685ec
+int has_fstab_option(const char *opt);
Ian Kent 3685ec
+char *get_offset(const char *prefix, char *offset,
Ian Kent 3685ec
+                 struct list_head *head, struct list_head **pos);
Ian Kent 3685ec
+void add_ordered_list(struct mnt_list *ent, struct list_head *head);
Ian Kent 3685ec
+void tree_free_mnt_tree(struct mnt_list *tree);
Ian Kent 3685ec
+struct mnt_list *tree_make_mnt_tree(const char *table, const char *path);
Ian Kent 3685ec
+int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
Ian Kent 3685ec
+int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
Ian Kent 3685ec
+int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
Ian Kent 3685ec
+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
Ian Kent 3685ec
+void set_tsd_user_vars(unsigned int, uid_t, gid_t);
Ian Kent 3685ec
+int umount_ent(struct autofs_point *, const char *);
Ian Kent 3685ec
+int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
Ian Kent 3685ec
+int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
Ian Kent 3685ec
+
Ian Kent 3685ec
+#endif
Ian Kent 3685ec
diff --git a/include/parse_subs.h b/include/parse_subs.h
Ian Kent 3685ec
index 10c6083..643ad68 100644
Ian Kent 3685ec
--- a/include/parse_subs.h
Ian Kent 3685ec
+++ b/include/parse_subs.h
Ian Kent 3685ec
@@ -27,8 +27,5 @@ int strmcmp(const char *, const char *, int);
Ian Kent 3685ec
 char *dequote(const char *, int, unsigned int);
Ian Kent 3685ec
 int span_space(const char *, unsigned int);
Ian Kent 3685ec
 char *sanitize_path(const char *, int, unsigned int, unsigned int);
Ian Kent 3685ec
-int umount_ent(struct autofs_point *, const char *);
Ian Kent 3685ec
-int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
Ian Kent 3685ec
-int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
Ian Kent 3685ec
 
Ian Kent 3685ec
 #endif
Ian Kent 3685ec
diff --git a/lib/mounts.c b/lib/mounts.c
Ian Kent 3685ec
index b987fbb..a4bf86c 100644
Ian Kent 3685ec
--- a/lib/mounts.c
Ian Kent 3685ec
+++ b/lib/mounts.c
Ian Kent 3685ec
@@ -1,6 +1,6 @@
Ian Kent 3685ec
 /* ----------------------------------------------------------------------- *
Ian Kent 3685ec
  *   
Ian Kent 3685ec
- *  mounts.c - module for Linux automount mount table lookup functions
Ian Kent 3685ec
+ *  mounts.c - module for mount utilities.
Ian Kent 3685ec
  *
Ian Kent 3685ec
  *   Copyright 2002-2005 Ian Kent <raven@themaw.net> - All Rights Reserved
Ian Kent 3685ec
  *
Ian Kent 3685ec
@@ -23,12 +23,21 @@
Ian Kent 3685ec
 #include <fcntl.h>
Ian Kent 3685ec
 #include <sys/mount.h>
Ian Kent 3685ec
 #include <stdio.h>
Ian Kent 3685ec
+#include <dirent.h>
Ian Kent 3685ec
+#include <sys/vfs.h>
Ian Kent 3685ec
+#include <pwd.h>
Ian Kent 3685ec
+#include <grp.h>
Ian Kent 3685ec
 
Ian Kent 3685ec
 #include "automount.h"
Ian Kent 3685ec
 
Ian Kent 3685ec
 #define MAX_OPTIONS_LEN		80
Ian Kent 3685ec
 #define MAX_MNT_NAME_LEN	30
Ian Kent 3685ec
 
Ian Kent 3685ec
+const unsigned int indirect = AUTOFS_TYPE_INDIRECT;
Ian Kent 3685ec
+const unsigned int direct = AUTOFS_TYPE_DIRECT;
Ian Kent 3685ec
+const unsigned int offset = AUTOFS_TYPE_OFFSET;
Ian Kent 3685ec
+const unsigned int type_count = 3;
Ian Kent 3685ec
+
Ian Kent 3685ec
 static const char options_template[]       = "fd=%d,pgrp=%u,minproto=5,maxproto=%d";
Ian Kent 3685ec
 static const char options_template_extra[] = "fd=%d,pgrp=%u,minproto=5,maxproto=%d,%s";
Ian Kent 3685ec
 static const char mnt_name_template[]      = "automount(pid%u)";
Ian Kent 3685ec
@@ -119,7 +128,7 @@ unsigned int get_kver_minor(void)
Ian Kent 3685ec
 /*
Ian Kent 3685ec
  * Make common autofs mount options string
Ian Kent 3685ec
  */
Ian Kent 3685ec
-char *make_options_string(char *path, int pipefd, char *extra)
Ian Kent 3685ec
+char *make_options_string(char *path, int pipefd, const char *extra)
Ian Kent 3685ec
 {
Ian Kent 3685ec
 	char *options;
Ian Kent 3685ec
 	int len;
Ian Kent 3685ec
@@ -462,51 +471,6 @@ int has_fstab_option(const char *opt)
Ian Kent 3685ec
 	return ret;
Ian Kent 3685ec
 }
Ian Kent 3685ec
 
Ian Kent 3685ec
-char *find_mnt_ino(const char *table, dev_t dev, ino_t ino)
Ian Kent 3685ec
-{
Ian Kent 3685ec
-	struct mntent mnt_wrk;
Ian Kent 3685ec
-	struct mntent *mnt;
Ian Kent 3685ec
-	char buf[PATH_MAX * 3];
Ian Kent 3685ec
-	char *path = NULL;
Ian Kent 3685ec
-	unsigned long l_dev = (unsigned long) dev;
Ian Kent 3685ec
-	unsigned long l_ino = (unsigned long) ino;
Ian Kent 3685ec
-	FILE *tab;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	tab = setmntent(table, "r");
Ian Kent 3685ec
-	if (!tab) {
Ian Kent 3685ec
-		char *estr = strerror_r(errno, buf, (size_t) PATH_MAX - 1);
Ian Kent 3685ec
-		logerr("setmntent: %s", estr);
Ian Kent 3685ec
-		return 0;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
Ian Kent 3685ec
-		char *p_dev, *p_ino;
Ian Kent 3685ec
-		unsigned long m_dev, m_ino;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		if (strcmp(mnt->mnt_type, "autofs"))
Ian Kent 3685ec
-			continue;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		p_dev = strstr(mnt->mnt_opts, "dev=");
Ian Kent 3685ec
-		if (!p_dev)
Ian Kent 3685ec
-			continue;
Ian Kent 3685ec
-		sscanf(p_dev, "dev=%lu", &m_dev);
Ian Kent 3685ec
-		if (m_dev != l_dev)
Ian Kent 3685ec
-			continue;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		p_ino = strstr(mnt->mnt_opts, "ino=");
Ian Kent 3685ec
-		if (!p_ino)
Ian Kent 3685ec
-			continue;
Ian Kent 3685ec
-		sscanf(p_ino, "ino=%lu", &m_ino);
Ian Kent 3685ec
-		if (m_ino == l_ino) {
Ian Kent 3685ec
-			path = strdup(mnt->mnt_dir);
Ian Kent 3685ec
-			break;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-	endmntent(tab);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	return path;
Ian Kent 3685ec
-}
Ian Kent 3685ec
-
Ian Kent 3685ec
 char *get_offset(const char *prefix, char *offset,
Ian Kent 3685ec
 		 struct list_head *head, struct list_head **pos)
Ian Kent 3685ec
 {
Ian Kent 3685ec
@@ -982,3 +946,355 @@ int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type)
Ian Kent 3685ec
 	return mounted;
Ian Kent 3685ec
 }
Ian Kent 3685ec
 
Ian Kent 3685ec
+void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid)
Ian Kent 3685ec
+{
Ian Kent 3685ec
+	struct thread_stdenv_vars *tsv;
Ian Kent 3685ec
+	struct passwd pw;
Ian Kent 3685ec
+	struct passwd *ppw = &pw;
Ian Kent 3685ec
+	struct passwd **pppw = &pp;;
Ian Kent 3685ec
+	struct group gr;
Ian Kent 3685ec
+	struct group *pgr;
Ian Kent 3685ec
+	struct group **ppgr;
Ian Kent 3685ec
+	char *pw_tmp, *gr_tmp;
Ian Kent 3685ec
+	int status, tmplen, grplen;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/*
Ian Kent 3685ec
+	 * Setup thread specific data values for macro
Ian Kent 3685ec
+	 * substution in map entries during the mount.
Ian Kent 3685ec
+	 * Best effort only as it must go ahead.
Ian Kent 3685ec
+	 */
Ian Kent 3685ec
+
Ian Kent 3685ec
+	tsv = malloc(sizeof(struct thread_stdenv_vars));
Ian Kent 3685ec
+	if (!tsv) {
Ian Kent 3685ec
+		error(logopt, "failed alloc tsv storage");
Ian Kent 3685ec
+		return;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	tsv->uid = uid;
Ian Kent 3685ec
+	tsv->gid = gid;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/* Try to get passwd info */
Ian Kent 3685ec
+
Ian Kent 3685ec
+	tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
Ian Kent 3685ec
+	if (tmplen < 0) {
Ian Kent 3685ec
+		error(logopt, "failed to get buffer size for getpwuid_r");
Ian Kent 3685ec
+		goto free_tsv;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	pw_tmp = malloc(tmplen + 1);
Ian Kent 3685ec
+	if (!pw_tmp) {
Ian Kent 3685ec
+		error(logopt, "failed to malloc buffer for getpwuid_r");
Ian Kent 3685ec
+		goto free_tsv;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	status = getpwuid_r(uid, ppw, pw_tmp, tmplen, pppw);
Ian Kent 3685ec
+	if (status || !ppw) {
Ian Kent 3685ec
+		error(logopt, "failed to get passwd info from getpwuid_r");
Ian Kent 3685ec
+		free(pw_tmp);
Ian Kent 3685ec
+		goto free_tsv;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	tsv->user = strdup(pw.pw_name);
Ian Kent 3685ec
+	if (!tsv->user) {
Ian Kent 3685ec
+		error(logopt, "failed to malloc buffer for user");
Ian Kent 3685ec
+		free(pw_tmp);
Ian Kent 3685ec
+		goto free_tsv;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	tsv->home = strdup(pw.pw_dir);
Ian Kent 3685ec
+	if (!tsv->home) {
Ian Kent 3685ec
+		error(logopt, "failed to malloc buffer for home");
Ian Kent 3685ec
+		free(pw_tmp);
Ian Kent 3685ec
+		goto free_tsv_user;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	free(pw_tmp);
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/* Try to get group info */
Ian Kent 3685ec
+
Ian Kent 3685ec
+	grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
Ian Kent 3685ec
+	if (tmplen < 0) {
Ian Kent 3685ec
+		error(logopt, "failed to get buffer size for getgrgid_r");
Ian Kent 3685ec
+		goto free_tsv_home;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	gr_tmp = NULL;
Ian Kent 3685ec
+	tmplen = grplen;
Ian Kent 3685ec
+	while (1) {
Ian Kent 3685ec
+		char *tmp = realloc(gr_tmp, tmplen + 1);
Ian Kent 3685ec
+		if (!tmp) {
Ian Kent 3685ec
+			error(logopt, "failed to malloc buffer for getgrgid_r");
Ian Kent 3685ec
+			if (gr_tmp)
Ian Kent 3685ec
+				free(gr_tmp);
Ian Kent 3685ec
+			goto free_tsv_home;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+		gr_tmp = tmp;
Ian Kent 3685ec
+		pgr = &gr;
Ian Kent 3685ec
+		ppgr = &pg;;
Ian Kent 3685ec
+		status = getgrgid_r(gid, pgr, gr_tmp, tmplen, ppgr);
Ian Kent 3685ec
+		if (status != ERANGE)
Ian Kent 3685ec
+			break;
Ian Kent 3685ec
+		tmplen += grplen;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	if (status || !pgr) {
Ian Kent 3685ec
+		error(logopt, "failed to get group info from getgrgid_r");
Ian Kent 3685ec
+		free(gr_tmp);
Ian Kent 3685ec
+		goto free_tsv_home;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	tsv->group = strdup(gr.gr_name);
Ian Kent 3685ec
+	if (!tsv->group) {
Ian Kent 3685ec
+		error(logopt, "failed to malloc buffer for group");
Ian Kent 3685ec
+		free(gr_tmp);
Ian Kent 3685ec
+		goto free_tsv_home;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	free(gr_tmp);
Ian Kent 3685ec
+
Ian Kent 3685ec
+	status = pthread_setspecific(key_thread_stdenv_vars, tsv);
Ian Kent 3685ec
+	if (status) {
Ian Kent 3685ec
+		error(logopt, "failed to set stdenv thread var");
Ian Kent 3685ec
+		goto free_tsv_group;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	return;
Ian Kent 3685ec
+
Ian Kent 3685ec
+free_tsv_group:
Ian Kent 3685ec
+	free(tsv->group);
Ian Kent 3685ec
+free_tsv_home:
Ian Kent 3685ec
+	free(tsv->home);
Ian Kent 3685ec
+free_tsv_user:
Ian Kent 3685ec
+	free(tsv->user);
Ian Kent 3685ec
+free_tsv:
Ian Kent 3685ec
+	free(tsv);
Ian Kent 3685ec
+	return;
Ian Kent 3685ec
+}
Ian Kent 3685ec
+
Ian Kent 3685ec
+int umount_ent(struct autofs_point *ap, const char *path)
Ian Kent 3685ec
+{
Ian Kent 3685ec
+	struct stat st;
Ian Kent 3685ec
+	struct statfs fs;
Ian Kent 3685ec
+	int sav_errno;
Ian Kent 3685ec
+	int status, is_smbfs = 0;
Ian Kent 3685ec
+	int ret, rv = 1;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	ret = statfs(path, &fs);
Ian Kent 3685ec
+	if (ret == -1) {
Ian Kent 3685ec
+		warn(ap->logopt, "could not stat fs of %s", path);
Ian Kent 3685ec
+		is_smbfs = 0;
Ian Kent 3685ec
+	} else {
Ian Kent 3685ec
+		int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER;
Ian Kent 3685ec
+		int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC;
Ian Kent 3685ec
+		is_smbfs = (cifsfs | smbfs) ? 1 : 0;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	status = lstat(path, &st);
Ian Kent 3685ec
+	sav_errno = errno;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	if (status < 0)
Ian Kent 3685ec
+		warn(ap->logopt, "lstat of %s failed with %d", path, status);
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/*
Ian Kent 3685ec
+	 * lstat failed and we're an smbfs fs returning an error that is not
Ian Kent 3685ec
+	 * EIO or EBADSLT or the lstat failed so it's a bad path. Return
Ian Kent 3685ec
+	 * a fail.
Ian Kent 3685ec
+	 *
Ian Kent 3685ec
+	 * EIO appears to correspond to an smb mount that has gone away
Ian Kent 3685ec
+	 * and EBADSLT relates to CD changer not responding.
Ian Kent 3685ec
+	 */
Ian Kent 3685ec
+	if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
Ian Kent 3685ec
+		rv = spawn_umount(ap->logopt, path, NULL);
Ian Kent 3685ec
+	} else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
Ian Kent 3685ec
+		rv = spawn_umount(ap->logopt, path, NULL);
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/* We are doing a forced shutcwdown down so unlink busy mounts */
Ian Kent 3685ec
+	if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
Ian Kent 3685ec
+		ret = stat(path, &st);
Ian Kent 3685ec
+		if (ret == -1 && errno == ENOENT) {
Ian Kent 3685ec
+			warn(ap->logopt, "mount point does not exist");
Ian Kent 3685ec
+			return 0;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		if (ret == 0 && !S_ISDIR(st.st_mode)) {
Ian Kent 3685ec
+			warn(ap->logopt, "mount point is not a directory");
Ian Kent 3685ec
+			return 0;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		if (ap->state == ST_SHUTDOWN_FORCE) {
Ian Kent 3685ec
+			info(ap->logopt, "forcing umount of %s", path);
Ian Kent 3685ec
+			rv = spawn_umount(ap->logopt, "-l", path, NULL);
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		/*
Ian Kent 3685ec
+		 * Verify that we actually unmounted the thing.  This is a
Ian Kent 3685ec
+		 * belt and suspenders approach to not eating user data.
Ian Kent 3685ec
+		 * We have seen cases where umount succeeds, but there is
Ian Kent 3685ec
+		 * still a file system mounted on the mount point.  How
Ian Kent 3685ec
+		 * this happens has not yet been determined, but we want to
Ian Kent 3685ec
+		 * make sure to return failure here, if that is the case,
Ian Kent 3685ec
+		 * so that we do not try to call rmdir_path on the
Ian Kent 3685ec
+		 * directory.
Ian Kent 3685ec
+		 */
Ian Kent 3685ec
+		if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
Ian Kent 3685ec
+			crit(ap->logopt,
Ian Kent 3685ec
+			     "the umount binary reported that %s was "
Ian Kent 3685ec
+			     "unmounted, but there is still something "
Ian Kent 3685ec
+			     "mounted on this path.", path);
Ian Kent 3685ec
+			rv = -1;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	return rv;
Ian Kent 3685ec
+}
Ian Kent 3685ec
+
Ian Kent 3685ec
+int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
Ian Kent 3685ec
+{
Ian Kent 3685ec
+	char path[PATH_MAX + 1];
Ian Kent 3685ec
+	char *offset = path;
Ian Kent 3685ec
+	struct mapent *oe;
Ian Kent 3685ec
+	struct list_head *pos = NULL;
Ian Kent 3685ec
+	unsigned int fs_path_len;
Ian Kent 3685ec
+	unsigned int mounted;
Ian Kent 3685ec
+	int ret, start;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	fs_path_len = strlen(root) + strlen(base);
Ian Kent 3685ec
+	if (fs_path_len > PATH_MAX)
Ian Kent 3685ec
+		return -1;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	strcpy(path, root);
Ian Kent 3685ec
+	strcat(path, base);
Ian Kent 3685ec
+
Ian Kent 3685ec
+	mounted = 0;
Ian Kent 3685ec
+	start = strlen(root);
Ian Kent 3685ec
+	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos;;
Ian Kent 3685ec
+	while (offset) {
Ian Kent 3685ec
+		int plen = fs_path_len + strlen(offset);
Ian Kent 3685ec
+
Ian Kent 3685ec
+		if (plen > PATH_MAX) {
Ian Kent 3685ec
+			warn(ap->logopt, "path loo long");
Ian Kent 3685ec
+			goto cont;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		oe = cache_lookup_offset(base, offset, start, &me->multi_list);
Ian Kent 3685ec
+		if (!oe || !oe->mapent)
Ian Kent 3685ec
+			goto cont;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		debug(ap->logopt, "mount offset %s", oe->key);
Ian Kent 3685ec
+
Ian Kent 3685ec
+		ret = mount_autofs_offset(ap, oe);
Ian Kent 3685ec
+		if (ret >= MOUNT_OFFSET_OK)
Ian Kent 3685ec
+			mounted++;
Ian Kent 3685ec
+		else {
Ian Kent 3685ec
+			if (ret != MOUNT_OFFSET_IGNORE)
Ian Kent 3685ec
+				warn(ap->logopt, "failed to mount offset");
Ian Kent 3685ec
+			else {
Ian Kent 3685ec
+				debug(ap->logopt,
Ian Kent 3685ec
+				      "ignoring \"nohide\" trigger %s",
Ian Kent 3685ec
+				      oe->key);
Ian Kent 3685ec
+				free(oe->mapent);
Ian Kent 3685ec
+				oe->mapent = NULL;
Ian Kent 3685ec
+			}
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+cont:
Ian Kent 3685ec
+		offset = cache_get_offset(base,
Ian Kent 3685ec
+				offset, start, &me->multi_list, &pos;;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	return mounted;
Ian Kent 3685ec
+}
Ian Kent 3685ec
+
Ian Kent 3685ec
+int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
Ian Kent 3685ec
+{
Ian Kent 3685ec
+	char path[PATH_MAX + 1];
Ian Kent 3685ec
+	char *offset;
Ian Kent 3685ec
+	struct mapent *oe;
Ian Kent 3685ec
+	struct list_head *mm_root, *pos;
Ian Kent 3685ec
+	const char o_root[] = "/";
Ian Kent 3685ec
+	const char *mm_base;
Ian Kent 3685ec
+	int left, start;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	left = 0;
Ian Kent 3685ec
+	start = strlen(root);
Ian Kent 3685ec
+
Ian Kent 3685ec
+	mm_root = &me->multi->multi_list;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	if (!base)
Ian Kent 3685ec
+		mm_base = o_root;
Ian Kent 3685ec
+	else
Ian Kent 3685ec
+		mm_base = base;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	pos = NULL;
Ian Kent 3685ec
+	offset = path;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/* Make sure "none" of the offsets have an active mount. */
Ian Kent 3685ec
+	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
Ian Kent 3685ec
+		char *oe_base;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
Ian Kent 3685ec
+		/* root offset is a special case */
Ian Kent 3685ec
+		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
Ian Kent 3685ec
+			continue;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		/*
Ian Kent 3685ec
+		 * Check for and umount subtree offsets resulting from
Ian Kent 3685ec
+		 * nonstrict mount fail.
Ian Kent 3685ec
+		 */
Ian Kent 3685ec
+		oe_base = oe->key + strlen(root);
Ian Kent 3685ec
+		left += umount_multi_triggers(ap, root, oe, oe_base);
Ian Kent 3685ec
+
Ian Kent 3685ec
+		if (oe->ioctlfd != -1)
Ian Kent 3685ec
+			left++;
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	if (left)
Ian Kent 3685ec
+		return left;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	pos = NULL;
Ian Kent 3685ec
+	offset = path;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	/* Make sure "none" of the offsets have an active mount. */
Ian Kent 3685ec
+	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
Ian Kent 3685ec
+		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
Ian Kent 3685ec
+		/* root offset is a special case */
Ian Kent 3685ec
+		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
Ian Kent 3685ec
+			continue;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		debug(ap->logopt, "umount offset %s", oe->key);
Ian Kent 3685ec
+
Ian Kent 3685ec
+		if (umount_autofs_offset(ap, oe)) {
Ian Kent 3685ec
+			warn(ap->logopt, "failed to umount offset");
Ian Kent 3685ec
+			left++;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	if (!left && me->multi == me) {
Ian Kent 3685ec
+		struct mapent_cache *mc = me->mc;
Ian Kent 3685ec
+		int status;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		/*
Ian Kent 3685ec
+		 * Special case.
Ian Kent 3685ec
+		 * If we can't umount the root container then we can't
Ian Kent 3685ec
+		 * delete the offsets from the cache and we need to put
Ian Kent 3685ec
+		 * the offset triggers back.
Ian Kent 3685ec
+		 */
Ian Kent 3685ec
+		if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
Ian Kent 3685ec
+			info(ap->logopt, "unmounting dir = %s", root);
Ian Kent 3685ec
+			if (umount_ent(ap, root)) {
Ian Kent 3685ec
+				if (mount_multi_triggers(ap, root, me, "/") < 0)
Ian Kent 3685ec
+					warn(ap->logopt,
Ian Kent 3685ec
+					     "failed to remount offset triggers");
Ian Kent 3685ec
+				return left++;
Ian Kent 3685ec
+			}
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		/* We're done - clean out the offsets */
Ian Kent 3685ec
+		status = cache_delete_offset_list(mc, me->key);
Ian Kent 3685ec
+		if (status != CHE_OK)
Ian Kent 3685ec
+			warn(ap->logopt, "couldn't delete offset list");
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	return left;
Ian Kent 3685ec
+}
Ian Kent 3685ec
+
Ian Kent 3685ec
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
Ian Kent 3685ec
index 27cb0fc..3a04dd6 100644
Ian Kent 3685ec
--- a/lib/parse_subs.c
Ian Kent 3685ec
+++ b/lib/parse_subs.c
Ian Kent 3685ec
@@ -18,10 +18,7 @@
Ian Kent 3685ec
 #include <stdlib.h>
Ian Kent 3685ec
 #include <string.h>
Ian Kent 3685ec
 #include <ctype.h>
Ian Kent 3685ec
-#include <sys/types.h>
Ian Kent 3685ec
-#include <sys/stat.h>
Ian Kent 3685ec
 #include <unistd.h>
Ian Kent 3685ec
-#include <sys/vfs.h>
Ian Kent 3685ec
 #include "automount.h"
Ian Kent 3685ec
 
Ian Kent 3685ec
 /*
Ian Kent 3685ec
@@ -304,230 +301,3 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i
Ian Kent 3685ec
 	return s_path;
Ian Kent 3685ec
 }
Ian Kent 3685ec
 
Ian Kent 3685ec
-int umount_ent(struct autofs_point *ap, const char *path)
Ian Kent 3685ec
-{
Ian Kent 3685ec
-	struct stat st;
Ian Kent 3685ec
-	struct statfs fs;
Ian Kent 3685ec
-	int sav_errno;
Ian Kent 3685ec
-	int status, is_smbfs = 0;
Ian Kent 3685ec
-	int ret, rv = 1;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	ret = statfs(path, &fs);
Ian Kent 3685ec
-	if (ret == -1) {
Ian Kent 3685ec
-		warn(ap->logopt, "could not stat fs of %s", path);
Ian Kent 3685ec
-		is_smbfs = 0;
Ian Kent 3685ec
-	} else {
Ian Kent 3685ec
-		int cifsfs = fs.f_type == (__SWORD_TYPE) CIFS_MAGIC_NUMBER;
Ian Kent 3685ec
-		int smbfs = fs.f_type == (__SWORD_TYPE) SMB_SUPER_MAGIC;
Ian Kent 3685ec
-		is_smbfs = (cifsfs | smbfs) ? 1 : 0;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	status = lstat(path, &st);
Ian Kent 3685ec
-	sav_errno = errno;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	if (status < 0)
Ian Kent 3685ec
-		warn(ap->logopt, "lstat of %s failed with %d", path, status);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/*
Ian Kent 3685ec
-	 * lstat failed and we're an smbfs fs returning an error that is not
Ian Kent 3685ec
-	 * EIO or EBADSLT or the lstat failed so it's a bad path. Return
Ian Kent 3685ec
-	 * a fail.
Ian Kent 3685ec
-	 *
Ian Kent 3685ec
-	 * EIO appears to correspond to an smb mount that has gone away
Ian Kent 3685ec
-	 * and EBADSLT relates to CD changer not responding.
Ian Kent 3685ec
-	 */
Ian Kent 3685ec
-	if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
Ian Kent 3685ec
-		rv = spawn_umount(ap->logopt, path, NULL);
Ian Kent 3685ec
-	} else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
Ian Kent 3685ec
-		rv = spawn_umount(ap->logopt, path, NULL);
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* We are doing a forced shutcwdown down so unlink busy mounts */
Ian Kent 3685ec
-	if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
Ian Kent 3685ec
-		ret = stat(path, &st);
Ian Kent 3685ec
-		if (ret == -1 && errno == ENOENT) {
Ian Kent 3685ec
-			warn(ap->logopt, "mount point does not exist");
Ian Kent 3685ec
-			return 0;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-
Ian Kent 3685ec
-		if (ret == 0 && !S_ISDIR(st.st_mode)) {
Ian Kent 3685ec
-			warn(ap->logopt, "mount point is not a directory");
Ian Kent 3685ec
-			return 0;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-
Ian Kent 3685ec
-		if (ap->state == ST_SHUTDOWN_FORCE) {
Ian Kent 3685ec
-			info(ap->logopt, "forcing umount of %s", path);
Ian Kent 3685ec
-			rv = spawn_umount(ap->logopt, "-l", path, NULL);
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-
Ian Kent 3685ec
-		/*
Ian Kent 3685ec
-		 * Verify that we actually unmounted the thing.  This is a
Ian Kent 3685ec
-		 * belt and suspenders approach to not eating user data.
Ian Kent 3685ec
-		 * We have seen cases where umount succeeds, but there is
Ian Kent 3685ec
-		 * still a file system mounted on the mount point.  How
Ian Kent 3685ec
-		 * this happens has not yet been determined, but we want to
Ian Kent 3685ec
-		 * make sure to return failure here, if that is the case,
Ian Kent 3685ec
-		 * so that we do not try to call rmdir_path on the
Ian Kent 3685ec
-		 * directory.
Ian Kent 3685ec
-		 */
Ian Kent 3685ec
-		if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
Ian Kent 3685ec
-			crit(ap->logopt,
Ian Kent 3685ec
-			     "the umount binary reported that %s was "
Ian Kent 3685ec
-			     "unmounted, but there is still something "
Ian Kent 3685ec
-			     "mounted on this path.", path);
Ian Kent 3685ec
-			rv = -1;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	return rv;
Ian Kent 3685ec
-}
Ian Kent 3685ec
-
Ian Kent 3685ec
-int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
Ian Kent 3685ec
-{
Ian Kent 3685ec
-	char path[PATH_MAX + 1];
Ian Kent 3685ec
-	char *offset = path;
Ian Kent 3685ec
-	struct mapent *oe;
Ian Kent 3685ec
-	struct list_head *pos = NULL;
Ian Kent 3685ec
-	unsigned int fs_path_len;
Ian Kent 3685ec
-	unsigned int mounted;
Ian Kent 3685ec
-	int ret, start;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	fs_path_len = strlen(root) + strlen(base);
Ian Kent 3685ec
-	if (fs_path_len > PATH_MAX)
Ian Kent 3685ec
-		return -1;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	strcpy(path, root);
Ian Kent 3685ec
-	strcat(path, base);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	mounted = 0;
Ian Kent 3685ec
-	start = strlen(root);
Ian Kent 3685ec
-	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos;;
Ian Kent 3685ec
-	while (offset) {
Ian Kent 3685ec
-		int plen = fs_path_len + strlen(offset);
Ian Kent 3685ec
-
Ian Kent 3685ec
-		if (plen > PATH_MAX) {
Ian Kent 3685ec
-			warn(ap->logopt, "path loo long");
Ian Kent 3685ec
-			goto cont;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-
Ian Kent 3685ec
-		oe = cache_lookup_offset(base, offset, start, &me->multi_list);
Ian Kent 3685ec
-		if (!oe || !oe->mapent)
Ian Kent 3685ec
-			goto cont;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		debug(ap->logopt, "mount offset %s", oe->key);
Ian Kent 3685ec
-
Ian Kent 3685ec
-		ret = mount_autofs_offset(ap, oe);
Ian Kent 3685ec
-		if (ret >= MOUNT_OFFSET_OK)
Ian Kent 3685ec
-			mounted++;
Ian Kent 3685ec
-		else {
Ian Kent 3685ec
-			if (ret != MOUNT_OFFSET_IGNORE)
Ian Kent 3685ec
-				warn(ap->logopt, "failed to mount offset");
Ian Kent 3685ec
-			else {
Ian Kent 3685ec
-				debug(ap->logopt,
Ian Kent 3685ec
-				      "ignoring \"nohide\" trigger %s",
Ian Kent 3685ec
-				      oe->key);
Ian Kent 3685ec
-				free(oe->mapent);
Ian Kent 3685ec
-				oe->mapent = NULL;
Ian Kent 3685ec
-			}
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-cont:
Ian Kent 3685ec
-		offset = cache_get_offset(base,
Ian Kent 3685ec
-				offset, start, &me->multi_list, &pos;;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	return mounted;
Ian Kent 3685ec
-}
Ian Kent 3685ec
-
Ian Kent 3685ec
-int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
Ian Kent 3685ec
-{
Ian Kent 3685ec
-	char path[PATH_MAX + 1];
Ian Kent 3685ec
-	char *offset;
Ian Kent 3685ec
-	struct mapent *oe;
Ian Kent 3685ec
-	struct list_head *mm_root, *pos;
Ian Kent 3685ec
-	const char o_root[] = "/";
Ian Kent 3685ec
-	const char *mm_base;
Ian Kent 3685ec
-	int left, start;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	left = 0;
Ian Kent 3685ec
-	start = strlen(root);
Ian Kent 3685ec
-
Ian Kent 3685ec
-	mm_root = &me->multi->multi_list;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	if (!base)
Ian Kent 3685ec
-		mm_base = o_root;
Ian Kent 3685ec
-	else
Ian Kent 3685ec
-		mm_base = base;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	pos = NULL;
Ian Kent 3685ec
-	offset = path;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* Make sure "none" of the offsets have an active mount. */
Ian Kent 3685ec
-	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
Ian Kent 3685ec
-		char *oe_base;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
Ian Kent 3685ec
-		/* root offset is a special case */
Ian Kent 3685ec
-		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
Ian Kent 3685ec
-			continue;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		/*
Ian Kent 3685ec
-		 * Check for and umount subtree offsets resulting from
Ian Kent 3685ec
-		 * nonstrict mount fail.
Ian Kent 3685ec
-		 */
Ian Kent 3685ec
-		oe_base = oe->key + strlen(root);
Ian Kent 3685ec
-		left += umount_multi_triggers(ap, root, oe, oe_base);
Ian Kent 3685ec
-
Ian Kent 3685ec
-		if (oe->ioctlfd != -1)
Ian Kent 3685ec
-			left++;
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	if (left)
Ian Kent 3685ec
-		return left;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	pos = NULL;
Ian Kent 3685ec
-	offset = path;
Ian Kent 3685ec
-
Ian Kent 3685ec
-	/* Make sure "none" of the offsets have an active mount. */
Ian Kent 3685ec
-	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
Ian Kent 3685ec
-		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
Ian Kent 3685ec
-		/* root offset is a special case */
Ian Kent 3685ec
-		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
Ian Kent 3685ec
-			continue;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		debug(ap->logopt, "umount offset %s", oe->key);
Ian Kent 3685ec
-
Ian Kent 3685ec
-		if (umount_autofs_offset(ap, oe)) {
Ian Kent 3685ec
-			warn(ap->logopt, "failed to umount offset");
Ian Kent 3685ec
-			left++;
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	if (!left && me->multi == me) {
Ian Kent 3685ec
-		struct mapent_cache *mc = me->mc;
Ian Kent 3685ec
-		int status;
Ian Kent 3685ec
-
Ian Kent 3685ec
-		/*
Ian Kent 3685ec
-		 * Special case.
Ian Kent 3685ec
-		 * If we can't umount the root container then we can't
Ian Kent 3685ec
-		 * delete the offsets from the cache and we need to put
Ian Kent 3685ec
-		 * the offset triggers back.
Ian Kent 3685ec
-		 */
Ian Kent 3685ec
-		if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) {
Ian Kent 3685ec
-			info(ap->logopt, "unmounting dir = %s", root);
Ian Kent 3685ec
-			if (umount_ent(ap, root)) {
Ian Kent 3685ec
-				if (mount_multi_triggers(ap, root, me, "/") < 0)
Ian Kent 3685ec
-					warn(ap->logopt,
Ian Kent 3685ec
-					     "failed to remount offset triggers");
Ian Kent 3685ec
-				return left++;
Ian Kent 3685ec
-			}
Ian Kent 3685ec
-		}
Ian Kent 3685ec
-
Ian Kent 3685ec
-		/* We're done - clean out the offsets */
Ian Kent 3685ec
-		status = cache_delete_offset_list(mc, me->key);
Ian Kent 3685ec
-		if (status != CHE_OK)
Ian Kent 3685ec
-			warn(ap->logopt, "couldn't delete offset list");
Ian Kent 3685ec
-	}
Ian Kent 3685ec
-
Ian Kent 3685ec
-	return left;
Ian Kent 3685ec
-}
Ian Kent 3685ec
-