]>
Commit | Line | Data |
---|---|---|
3d551623 PG |
1 | diff --git a/CHANGELOG b/CHANGELOG |
2 | index 5e3a9ec..795ec30 100644 | |
3 | --- a/CHANGELOG | |
4 | +++ b/CHANGELOG | |
5 | @@ -39,6 +39,7 @@ | |
6 | - fix recursive loopback mounts (Matthias Koenig). | |
7 | - add map re-load to verbose logging. | |
8 | - fix handling of LDAP base dns with spaces. | |
9 | +- handle MTAB_NOTUPDATED status return from mount. | |
10 | ||
11 | 18/06/2007 autofs-5.0.2 | |
12 | ----------------------- | |
13 | diff --git a/daemon/spawn.c b/daemon/spawn.c | |
14 | index ab3274c..0ed873e 100644 | |
15 | --- a/daemon/spawn.c | |
16 | +++ b/daemon/spawn.c | |
17 | @@ -268,9 +268,11 @@ int spawn_mount(unsigned logopt, ...) | |
18 | char **argv, **p; | |
19 | char prog[] = PATH_MOUNT; | |
20 | char arg0[] = PATH_MOUNT; | |
21 | + /* In case we need to use the fake option to mount */ | |
22 | + char arg_fake[] = "-f"; | |
23 | unsigned int options; | |
24 | unsigned int retries = MTAB_LOCK_RETRIES; | |
25 | - int ret; | |
26 | + int ret, printed = 0; | |
27 | ||
28 | /* If we use mount locking we can't validate the location */ | |
29 | #ifdef ENABLE_MOUNT_LOCKING | |
30 | @@ -283,7 +285,8 @@ int spawn_mount(unsigned logopt, ...) | |
31 | for (argc = 1; va_arg(arg, char *); argc++); | |
32 | va_end(arg); | |
33 | ||
34 | - if (!(argv = alloca(sizeof(char *) * argc + 1))) | |
35 | + /* Alloc 1 extra slot in case we need to use the "-f" option */ | |
36 | + if (!(argv = alloca(sizeof(char *) * argc + 2))) | |
37 | return -1; | |
38 | ||
39 | argv[0] = arg0; | |
40 | @@ -304,11 +307,40 @@ int spawn_mount(unsigned logopt, ...) | |
41 | ||
42 | while (retries--) { | |
43 | ret = do_spawn(logopt, options, prog, (const char **) argv); | |
44 | - if (ret & MTAB_NOTUPDATED) | |
45 | + if (ret & MTAB_NOTUPDATED) { | |
46 | + /* | |
47 | + * If the mount succeeded but the mtab was not | |
48 | + * updated, then retry the mount with the -f (fake) | |
49 | + * option to just update the mtab. | |
50 | + */ | |
51 | + if (!printed) { | |
52 | + debug(logopt, "mount failed with error code 16" | |
53 | + ", retrying with the -f option"); | |
54 | + printed = 1; | |
55 | + } | |
56 | + | |
57 | + /* | |
58 | + * Move the last two args so do_spawn() can find the | |
59 | + * mount target. | |
60 | + */ | |
61 | + if (!argv[argc]) { | |
62 | + argv[argc + 1] = NULL; | |
63 | + argv[argc] = argv[argc - 1]; | |
64 | + argv[argc - 1] = argv[argc - 2]; | |
65 | + argv[argc - 2] = arg_fake; | |
66 | + } | |
67 | continue; | |
68 | + } | |
69 | break; | |
70 | } | |
71 | ||
72 | + /* This is not a fatal error */ | |
73 | + if (ret == MTAB_NOTUPDATED) { | |
74 | + warn(logopt, "Unable to update the mtab file, /proc/mounts " | |
75 | + "and /etc/mtab will differ"); | |
76 | + ret = 0; | |
77 | + } | |
78 | + | |
79 | return ret; | |
80 | } | |
81 | ||
82 | @@ -328,9 +360,11 @@ int spawn_bind_mount(unsigned logopt, ...) | |
83 | char prog[] = PATH_MOUNT; | |
84 | char arg0[] = PATH_MOUNT; | |
85 | char bind[] = "--bind"; | |
86 | + /* In case we need to use the fake option to mount */ | |
87 | + char arg_fake[] = "-f"; | |
88 | unsigned int options; | |
89 | unsigned int retries = MTAB_LOCK_RETRIES; | |
90 | - int ret; | |
91 | + int ret, printed = 0; | |
92 | ||
93 | /* If we use mount locking we can't validate the location */ | |
94 | #ifdef ENABLE_MOUNT_LOCKING | |
95 | @@ -339,8 +373,12 @@ int spawn_bind_mount(unsigned logopt, ...) | |
96 | options = SPAWN_OPT_ACCESS; | |
97 | #endif | |
98 | ||
99 | + /* | |
100 | + * Alloc 2 extra slots, one for the bind option and one in case | |
101 | + * we need to use the "-f" option | |
102 | + */ | |
103 | va_start(arg, logopt); | |
104 | - for (argc = 1; va_arg(arg, char *); argc++); | |
105 | + for (argc = 2; va_arg(arg, char *); argc++); | |
106 | va_end(arg); | |
107 | ||
108 | if (!(argv = alloca(sizeof(char *) * argc + 2))) | |
109 | @@ -356,11 +394,40 @@ int spawn_bind_mount(unsigned logopt, ...) | |
110 | ||
111 | while (retries--) { | |
112 | ret = do_spawn(logopt, options, prog, (const char **) argv); | |
113 | - if (ret & MTAB_NOTUPDATED) | |
114 | + if (ret & MTAB_NOTUPDATED) { | |
115 | + /* | |
116 | + * If the mount succeeded but the mtab was not | |
117 | + * updated, then retry the mount with the -f (fake) | |
118 | + * option to just update the mtab. | |
119 | + */ | |
120 | + if (!printed) { | |
121 | + debug(logopt, "mount failed with error code 16" | |
122 | + ", retrying with the -f option"); | |
123 | + printed = 1; | |
124 | + } | |
125 | + | |
126 | + /* | |
127 | + * Move the last two args so do_spawn() can find the | |
128 | + * mount target. | |
129 | + */ | |
130 | + if (!argv[argc]) { | |
131 | + argv[argc + 1] = NULL; | |
132 | + argv[argc] = argv[argc - 1]; | |
133 | + argv[argc - 1] = argv[argc - 2]; | |
134 | + argv[argc - 2] = arg_fake; | |
135 | + } | |
136 | continue; | |
137 | + } | |
138 | break; | |
139 | } | |
140 | ||
141 | + /* This is not a fatal error */ | |
142 | + if (ret == MTAB_NOTUPDATED) { | |
143 | + warn(logopt, "Unable to update the mtab file, /proc/mounts " | |
144 | + "and /etc/mtab will differ"); | |
145 | + ret = 0; | |
146 | + } | |
147 | + | |
148 | return ret; | |
149 | } | |
150 | ||
151 | @@ -373,7 +440,7 @@ int spawn_umount(unsigned logopt, ...) | |
152 | char arg0[] = PATH_UMOUNT; | |
153 | unsigned int options; | |
154 | unsigned int retries = MTAB_LOCK_RETRIES; | |
155 | - int ret; | |
156 | + int ret, printed = 0; | |
157 | ||
158 | #ifdef ENABLE_MOUNT_LOCKING | |
159 | options = SPAWN_OPT_LOCK; | |
160 | @@ -397,9 +464,37 @@ int spawn_umount(unsigned logopt, ...) | |
161 | ||
162 | while (retries--) { | |
163 | ret = do_spawn(logopt, options, prog, (const char **) argv); | |
164 | - if (ret & MTAB_NOTUPDATED) | |
165 | - continue; | |
166 | - break; | |
167 | + if (ret & MTAB_NOTUPDATED) { | |
168 | + /* | |
169 | + * If the mount succeeded but the mtab was not | |
170 | + * updated, then retry the umount just to update | |
171 | + * the mtab. | |
172 | + */ | |
173 | + if (!printed) { | |
174 | + debug(logopt, "mount failed with error code 16" | |
175 | + ", retrying with the -f option"); | |
176 | + printed = 1; | |
177 | + } | |
178 | + } else { | |
179 | + /* | |
180 | + * umount does not support the "fake" option. Thus, | |
181 | + * if we got a return value of MTAB_NOTUPDATED the | |
182 | + * first time, that means the umount actually | |
183 | + * succeeded. Then, a following umount will fail | |
184 | + * due to the fact that nothing was mounted on the | |
185 | + * mount point. So, report this as success. | |
186 | + */ | |
187 | + if (retries < MTAB_LOCK_RETRIES - 1) | |
188 | + ret = 0; | |
189 | + break; | |
190 | + } | |
191 | + } | |
192 | + | |
193 | + /* This is not a fatal error */ | |
194 | + if (ret == MTAB_NOTUPDATED) { | |
195 | + warn(logopt, "Unable to update the mtab file, /proc/mounts " | |
196 | + "and /etc/mtab will differ"); | |
197 | + ret = 0; | |
198 | } | |
199 | ||
200 | return ret; |