aboutsummaryrefslogtreecommitdiffstats
path: root/modules/mount_autofs.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mount_autofs.c')
-rw-r--r--modules/mount_autofs.c57
1 files changed, 23 insertions, 34 deletions
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 6ab439c..ed9f2e9 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -36,11 +36,10 @@ int mount_mount(const char *root, const char *name, int name_len,
const char *what, const char *fstype, const char *c_options,
void *context)
{
- char *fullpath;
- const char **argv;
+ char *fullpath, **argv;
int argc, status;
- struct stat sb, cb;
char *options, *p;
+ pid_t slave, wp;
fullpath = alloca(strlen(root)+name_len+2);
if ( !fullpath ) {
@@ -74,7 +73,7 @@ int mount_mount(const char *root, const char *name, int name_len,
argc++;
} while ((p = strchr(p,',')) != NULL);
}
- argv = (const char **) alloca((argc+1) * sizeof(char *));
+ argv = (char **) alloca((argc+1) * sizeof(char *));
argc = 0;
argv[argc++] = _PATH_AUTOMOUNT;
@@ -96,42 +95,32 @@ int mount_mount(const char *root, const char *name, int name_len,
}
argv[argc] = NULL;
- /* Spawn a new daemon. */
- status = spawnv(LOG_DEBUG, _PATH_AUTOMOUNT, argv);
- if (!WIFEXITED(status) || WEXITSTATUS(status)) {
- syslog(LOG_NOTICE, MODPREFIX "sub automount returned status %d", status);
+ /* Spawn a new daemon. If initialization is successful, the daemon will send
+ itself SIGSTOP, which we detect and let it go on its merry way. */
+
+ slave = fork();
+ if ( slave < 0 ) {
+ syslog(LOG_ERR, MODPREFIX "fork: %m");
goto error;
+ } else if ( slave == 0 ) {
+ /* Slave process */
+ execv(_PATH_AUTOMOUNT, argv);
+ _exit(255);
}
- /* We must wait a bit for it to get registered. We try three times, and
- if it isn't ready after that, assume it has failed. This is a real
- hack; we really should make --submount make the subprocess notify us. */
-
- stat(root, &cb);
- usleep(10000);
-
- stat(fullpath, &sb);
- if (cb.st_dev == sb.st_dev) {
- int i;
- /* First, to one second by tenths. */
- for (i = 0; i < 10; ++i) {
- usleep(100000);
- stat(fullpath, &sb);
- if (cb.st_dev != sb.st_dev)
- goto ok;
- }
- /* Then to one minute by seconds. */
- for (i = 1; i < 60; ++i) {
- sleep(1);
- stat(fullpath, &sb);
- if (cb.st_dev != sb.st_dev)
- goto ok;
- }
- syslog(LOG_NOTICE, MODPREFIX "timeout waiting for submount");
+ while ( (wp = waitpid(slave, &status, WUNTRACED)) == -1 && errno == EINTR );
+ if ( wp != slave ) {
+ syslog(LOG_NOTICE, MODPREFIX "waitpid: %m");
goto error;
}
-ok:
+ if ( !WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP ) {
+ syslog(LOG_NOTICE, MODPREFIX "sub automount returned status 0x%x", status);
+ goto error;
+ }
+
+ kill(slave, SIGCONT); /* Carry on, private */
+
syslog(LOG_DEBUG, MODPREFIX "mounted %s on %s", what, fullpath);
return 0;