diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c index 8793075..04f25b1 100644 --- a/src/librc/librc-daemon.c +++ b/src/librc/librc-daemon.c @@ -553,16 +553,28 @@ rc_service_daemons_crashed(const char *service) } fclose(fp); + char *ch_root = rc_service_value_get(basename_c(service), "chroot"); + char *spidfile = pidfile; + if (ch_root) { + spidfile = malloc(strlen(ch_root) + strlen(pidfile)); + strcpy(spidfile, ch_root); + strcat(spidfile, pidfile); + } + pid = 0; - if (pidfile) { + if (spidfile) { retval = true; - if ((fp = fopen(pidfile, "r"))) { + if ((fp = fopen(spidfile, "r"))) { if (fscanf(fp, "%d", &pid) == 1) retval = false; fclose(fp); } - free(pidfile); - pidfile = NULL; + free(spidfile); + spidfile = NULL; + if (ch_root) { + free(pidfile); + pidfile = NULL; + } /* We have the pid, so no need to match on exec or name */ diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index cc47c0b..c62e521 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -673,6 +673,7 @@ start_stop_daemon(int argc, char **argv) char *startas = NULL; char *name = NULL; char *pidfile = NULL; + char *spidfile = NULL; //chroot aware pidfile char *retry = NULL; int sig = -1; int nicelevel = 0, ionicec = -1, ioniced = 0; @@ -1001,10 +1002,27 @@ start_stop_daemon(int argc, char **argv) exit(EXIT_FAILURE); } + if (stop && !ch_root) { + ch_root = rc_service_value_get(svcname, "chroot"); + } + + /* if we are chrooting our service then pidfile will be created + * in the chroot folder, and it can't be controled in a natural way. + * in order to workaround this problem we introducing a chroot aware + * version of a pidfile variable. + */ + if (ch_root && pidfile) { + spidfile = malloc(strlen(ch_root) + strlen(pidfile)); + strcpy(spidfile, ch_root); + strcat(spidfile, pidfile); + } else { + spidfile = pidfile; + } + /* If we don't have a pidfile we should check if it's interpreted * or not. If it we, we need to pass the interpreter through * to our daemon calls to find it correctly. */ - if (interpreted && !pidfile) { + if (interpreted && !spidfile) { fp = fopen(exec_file, "r"); if (fp) { p = fgets(line, sizeof(line), fp); @@ -1048,7 +1066,7 @@ start_stop_daemon(int argc, char **argv) else parse_schedule(NULL, sig); i = run_stop_schedule(exec, (const char *const *)margv, - pidfile, uid, test, progress); + spidfile, uid, test, progress); if (i < 0) /* We failed to stop something */ @@ -1060,8 +1078,8 @@ start_stop_daemon(int argc, char **argv) * remove information about it as it may have unexpectedly * crashed out. We should also return success as the end * result would be the same. */ - if (pidfile && exists(pidfile)) - unlink(pidfile); + if (spidfile && exists(spidfile)) + unlink(spidfile); if (svcname) rc_service_daemon_set(svcname, exec, (const char *const *)argv, @@ -1069,8 +1087,8 @@ start_stop_daemon(int argc, char **argv) exit(EXIT_SUCCESS); } - if (pidfile) - pid = get_pid(pidfile); + if (spidfile) + pid = get_pid(spidfile); else pid = 0; @@ -1107,8 +1125,8 @@ start_stop_daemon(int argc, char **argv) eindentv(); /* Remove existing pidfile */ - if (pidfile) - unlink(pidfile); + if (spidfile) + unlink(spidfile); if (background) signal_setup(SIGCHLD, handle_signal); @@ -1341,13 +1359,13 @@ start_stop_daemon(int argc, char **argv) if (kill(pid, 0) == 0) alive = true; } else { - if (pidfile) { - pid = get_pid(pidfile); + if (spidfile) { + pid = get_pid(spidfile); if (pid == -1) { eerrorx("%s: did not " "create a valid" " pid in `%s'", - applet, pidfile); + applet, spidfile); } } else pid = 0; @@ -1359,10 +1377,12 @@ start_stop_daemon(int argc, char **argv) if (!alive) eerrorx("%s: %s died", applet, exec); } - - if (svcname) + if (svcname) { rc_service_daemon_set(svcname, exec, (const char *const *)margv, pidfile, true); + if (ch_root) + rc_service_value_set(svcname, "chroot", ch_root); + } exit(EXIT_SUCCESS); /* NOTREACHED */