|
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 |
-
|