diff --git a/daemon/spawn.c b/daemon/spawn.c index 0ed873e..78d69c6 100644 --- a/daemon/spawn.c +++ b/daemon/spawn.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "automount.h" @@ -308,6 +309,8 @@ int spawn_mount(unsigned logopt, ...) while (retries--) { ret = do_spawn(logopt, options, prog, (const char **) argv); if (ret & MTAB_NOTUPDATED) { + struct timespec tm = {3, 0}; + /* * If the mount succeeded but the mtab was not * updated, then retry the mount with the -f (fake) @@ -329,6 +332,9 @@ int spawn_mount(unsigned logopt, ...) argv[argc - 1] = argv[argc - 2]; argv[argc - 2] = arg_fake; } + + nanosleep(&tm, NULL); + continue; } break; @@ -336,9 +342,16 @@ int spawn_mount(unsigned logopt, ...) /* This is not a fatal error */ if (ret == MTAB_NOTUPDATED) { - warn(logopt, "Unable to update the mtab file, /proc/mounts " - "and /etc/mtab will differ"); - ret = 0; + /* + * Version 5 requires that /etc/mtab be in sync with + * /proc/mounts. If we're unable to update matb after + * retrying then we have no choice but umount the mount + * and return a fail. + */ + warn(logopt, + "Unable to update the mtab file, forcing mount fail!"); + umount(argv[argc]); + ret = MNT_FORCE_FAIL; } return ret; @@ -395,6 +408,8 @@ int spawn_bind_mount(unsigned logopt, ...) while (retries--) { ret = do_spawn(logopt, options, prog, (const char **) argv); if (ret & MTAB_NOTUPDATED) { + struct timespec tm = {3, 0}; + /* * If the mount succeeded but the mtab was not * updated, then retry the mount with the -f (fake) @@ -416,6 +431,9 @@ int spawn_bind_mount(unsigned logopt, ...) argv[argc - 1] = argv[argc - 2]; argv[argc - 2] = arg_fake; } + + nanosleep(&tm, NULL); + continue; } break; @@ -423,9 +441,16 @@ int spawn_bind_mount(unsigned logopt, ...) /* This is not a fatal error */ if (ret == MTAB_NOTUPDATED) { - warn(logopt, "Unable to update the mtab file, /proc/mounts " - "and /etc/mtab will differ"); - ret = 0; + /* + * Version 5 requires that /etc/mtab be in sync with + * /proc/mounts. If we're unable to update matb after + * retrying then we have no choice but umount the mount + * and return a fail. + */ + warn(logopt, + "Unable to update the mtab file, forcing mount fail!"); + umount(argv[argc]); + ret = MNT_FORCE_FAIL; } return ret; diff --git a/include/automount.h b/include/automount.h index 4887da6..fa5cd97 100644 --- a/include/automount.h +++ b/include/automount.h @@ -78,6 +78,7 @@ int load_autofs4_module(void); #define MOUNTED_LOCK _PATH_MOUNTED "~" /* mounts' lock file */ #define MTAB_NOTUPDATED 0x1000 /* mtab succeded but not updated */ #define NOT_MOUNTED 0x0100 /* path notmounted */ +#define MNT_FORCE_FAIL -1 #define _PROC_MOUNTS "/proc/mounts" /* Constants for lookup modules */ diff --git a/modules/mount_bind.c b/modules/mount_bind.c index 04284f5..ef973e1 100644 --- a/modules/mount_bind.c +++ b/modules/mount_bind.c @@ -147,7 +147,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int if ((!ap->ghost && name_len) || !existed) rmdir_path(ap, fullpath, ap->dev); - return 1; + return err; } else { debug(ap->logopt, MODPREFIX "mounted %s type %s on %s", diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c index bad21fc..0e7aebe 100644 --- a/modules/mount_nfs.c +++ b/modules/mount_nfs.c @@ -233,6 +233,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int return 0; } + /* Failed to update mtab, don't try any more */ + if (err == MNT_FORCE_FAIL) + goto forced_fail; + /* No hostname, can't be NFS */ if (!this->name) { this = this->next; @@ -275,6 +279,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int this = this->next; } +forced_fail: free_host_list(&hosts); ap->ghost = save_ghost;