runsvdir: fx a recent vda's buglet (was pausing even if not signaled).
stop spawning children immediately if signaled. Kill one global.
This commit is contained in:
parent
e7368f16fa
commit
6a2c2cf6f3
@ -58,7 +58,6 @@ struct globals {
|
|||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
unsigned stamplog;
|
unsigned stamplog;
|
||||||
#endif
|
#endif
|
||||||
smallint need_rescan; /* = 1; */
|
|
||||||
smallint set_pgrp;
|
smallint set_pgrp;
|
||||||
};
|
};
|
||||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||||
@ -70,10 +69,8 @@ struct globals {
|
|||||||
#define logpipe (G.logpipe )
|
#define logpipe (G.logpipe )
|
||||||
#define pfd (G.pfd )
|
#define pfd (G.pfd )
|
||||||
#define stamplog (G.stamplog )
|
#define stamplog (G.stamplog )
|
||||||
#define need_rescan (G.need_rescan )
|
|
||||||
#define set_pgrp (G.set_pgrp )
|
#define set_pgrp (G.set_pgrp )
|
||||||
#define INIT_G() do { \
|
#define INIT_G() do { \
|
||||||
need_rescan = 1; \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void fatal2_cannot(const char *m1, const char *m2)
|
static void fatal2_cannot(const char *m1, const char *m2)
|
||||||
@ -96,21 +93,27 @@ static void warnx(const char *m1)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void runsv(int no, const char *name)
|
/* inlining + vfork -> bigger code */
|
||||||
|
static NOINLINE pid_t runsv(const char *name)
|
||||||
{
|
{
|
||||||
pid_t pid = vfork();
|
pid_t pid;
|
||||||
|
|
||||||
|
/* If we got signaled, stop spawning children at once! */
|
||||||
|
if (bb_got_signal)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pid = vfork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
warn2_cannot("vfork", "");
|
warn2_cannot("vfork", "");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
/* child */
|
/* child */
|
||||||
if (set_pgrp)
|
if (set_pgrp)
|
||||||
setsid();
|
setsid();
|
||||||
/* man execv:
|
/* man execv:
|
||||||
* Signals set to be caught by the calling process image
|
* "Signals set to be caught by the calling process image
|
||||||
* shall be set to the default action in the new process image.
|
* shall be set to the default action in the new process image."
|
||||||
* Therefore, we do not need this: */
|
* Therefore, we do not need this: */
|
||||||
#if 0
|
#if 0
|
||||||
bb_signals(0
|
bb_signals(0
|
||||||
@ -121,20 +124,22 @@ static void runsv(int no, const char *name)
|
|||||||
execlp("runsv", "runsv", name, NULL);
|
execlp("runsv", "runsv", name, NULL);
|
||||||
fatal2_cannot("start runsv ", name);
|
fatal2_cannot("start runsv ", name);
|
||||||
}
|
}
|
||||||
sv[no].pid = pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_rescan(void)
|
/* gcc 4.3.0 does better with NOINLINE */
|
||||||
|
static NOINLINE int do_rescan(void)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
direntry *d;
|
direntry *d;
|
||||||
int i;
|
int i;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
|
int need_rescan = 0;
|
||||||
|
|
||||||
dir = opendir(".");
|
dir = opendir(".");
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
warn2_cannot("open directory ", svdir);
|
warn2_cannot("open directory ", svdir);
|
||||||
return;
|
return 1; /* need to rescan again soon */
|
||||||
}
|
}
|
||||||
for (i = 0; i < svnum; i++)
|
for (i = 0; i < svnum; i++)
|
||||||
sv[i].isgone = 1;
|
sv[i].isgone = 1;
|
||||||
@ -152,47 +157,47 @@ static void do_rescan(void)
|
|||||||
}
|
}
|
||||||
if (!S_ISDIR(s.st_mode))
|
if (!S_ISDIR(s.st_mode))
|
||||||
continue;
|
continue;
|
||||||
|
/* Do we have this service listed already? */
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
if ((sv[i].ino == s.st_ino)
|
if ((sv[i].ino == s.st_ino)
|
||||||
#if CHECK_DEVNO_TOO
|
#if CHECK_DEVNO_TOO
|
||||||
&& (sv[i].dev == s.st_dev)
|
&& (sv[i].dev == s.st_dev)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
sv[i].isgone = 0;
|
if (sv[i].pid == 0) /* restart if it has died */
|
||||||
if (!sv[i].pid)
|
goto run_ith_sv;
|
||||||
runsv(i, d->d_name);
|
sv[i].isgone = 0; /* "we still see you" */
|
||||||
break;
|
goto next_dentry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == svnum) {
|
{ /* Not found, make new service */
|
||||||
/* new service */
|
|
||||||
struct service *svnew = realloc(sv, (i+1) * sizeof(*sv));
|
struct service *svnew = realloc(sv, (i+1) * sizeof(*sv));
|
||||||
if (!svnew) {
|
if (!svnew) {
|
||||||
warn2_cannot("start runsv ", d->d_name);
|
warn2_cannot("start runsv ", d->d_name);
|
||||||
|
need_rescan = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sv = svnew;
|
sv = svnew;
|
||||||
svnum++;
|
svnum++;
|
||||||
memset(&sv[i], 0, sizeof(sv[i]));
|
|
||||||
sv[i].ino = s.st_ino;
|
|
||||||
#if CHECK_DEVNO_TOO
|
#if CHECK_DEVNO_TOO
|
||||||
sv[i].dev = s.st_dev;
|
sv[i].dev = s.st_dev;
|
||||||
#endif
|
#endif
|
||||||
/*sv[i].pid = 0;*/
|
sv[i].ino = s.st_ino;
|
||||||
/*sv[i].isgone = 0;*/
|
run_ith_sv:
|
||||||
runsv(i, d->d_name);
|
sv[i].pid = runsv(d->d_name);
|
||||||
need_rescan = 1;
|
sv[i].isgone = 0;
|
||||||
}
|
}
|
||||||
|
next_dentry: ;
|
||||||
}
|
}
|
||||||
i = errno;
|
i = errno;
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
if (i) {
|
if (i) { /* readdir failed */
|
||||||
warn2_cannot("read directory ", svdir);
|
warn2_cannot("read directory ", svdir);
|
||||||
need_rescan = 1;
|
return 1; /* need to rescan again soon */
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send SIGTERM to runsv whose directories were not found (removed) */
|
/* Send SIGTERM to runsv whose directories
|
||||||
|
* were no longer found (-> must have been removed) */
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
if (!sv[i].isgone)
|
if (!sv[i].isgone)
|
||||||
continue;
|
continue;
|
||||||
@ -201,8 +206,8 @@ static void do_rescan(void)
|
|||||||
svnum--;
|
svnum--;
|
||||||
sv[i] = sv[svnum];
|
sv[i] = sv[svnum];
|
||||||
i--; /* so that we don't skip new sv[i] (bug was here!) */
|
i--; /* so that we don't skip new sv[i] (bug was here!) */
|
||||||
need_rescan = 1;
|
|
||||||
}
|
}
|
||||||
|
return need_rescan;
|
||||||
}
|
}
|
||||||
|
|
||||||
int runsvdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int runsvdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
@ -219,6 +224,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
unsigned now;
|
unsigned now;
|
||||||
unsigned stampcheck;
|
unsigned stampcheck;
|
||||||
int i;
|
int i;
|
||||||
|
int need_rescan = 1;
|
||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
|
||||||
@ -284,10 +290,9 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
break;
|
break;
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
if (pid == sv[i].pid) {
|
if (pid == sv[i].pid) {
|
||||||
/* runsv has gone */
|
/* runsv has died */
|
||||||
sv[i].pid = 0;
|
sv[i].pid = 0;
|
||||||
need_rescan = 1;
|
need_rescan = 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,19 +311,20 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
last_mtime = s.st_mtime;
|
last_mtime = s.st_mtime;
|
||||||
last_dev = s.st_dev;
|
last_dev = s.st_dev;
|
||||||
last_ino = s.st_ino;
|
last_ino = s.st_ino;
|
||||||
need_rescan = 0;
|
|
||||||
//if (now <= mtime)
|
//if (now <= mtime)
|
||||||
// sleep(1);
|
// sleep(1);
|
||||||
do_rescan();
|
need_rescan = do_rescan();
|
||||||
while (fchdir(curdir) == -1) {
|
while (fchdir(curdir) == -1) {
|
||||||
warn2_cannot("change directory, pausing", "");
|
warn2_cannot("change directory, pausing", "");
|
||||||
sleep(5);
|
sleep(5);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
warn2_cannot("change directory to ", svdir);
|
warn2_cannot("change directory to ", svdir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
warn2_cannot("stat ", svdir);
|
warn2_cannot("stat ", svdir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
#if ENABLE_FEATURE_RUNSVDIR_LOG
|
||||||
@ -354,6 +360,8 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
switch (bb_got_signal) {
|
switch (bb_got_signal) {
|
||||||
|
case 0: /* we are not signaled, business as usual */
|
||||||
|
break;
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
for (i = 0; i < svnum; i++)
|
for (i = 0; i < svnum; i++)
|
||||||
if (sv[i].pid)
|
if (sv[i].pid)
|
||||||
|
Loading…
Reference in New Issue
Block a user