summaryrefslogtreecommitdiff
path: root/src/starter/invokecharon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/starter/invokecharon.c')
-rw-r--r--src/starter/invokecharon.c317
1 files changed, 161 insertions, 156 deletions
diff --git a/src/starter/invokecharon.c b/src/starter/invokecharon.c
index dd3f5f018..804467cea 100644
--- a/src/starter/invokecharon.c
+++ b/src/starter/invokecharon.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: invokecharon.c 5050 2009-03-27 16:14:59Z andreas $
*/
#include <sys/types.h>
@@ -41,190 +39,197 @@ static int _stop_requested;
pid_t
starter_charon_pid(void)
{
- return _charon_pid;
+ return _charon_pid;
}
void
starter_charon_sigchild(pid_t pid)
{
- if (pid == _charon_pid)
- {
- _charon_pid = 0;
- if (!_stop_requested)
+ if (pid == _charon_pid)
{
- plog("charon has died -- restart scheduled (%dsec)"
- , CHARON_RESTART_DELAY);
- alarm(CHARON_RESTART_DELAY); // restart in 5 sec
+ _charon_pid = 0;
+ if (!_stop_requested)
+ {
+ plog("charon has died -- restart scheduled (%dsec)"
+ , CHARON_RESTART_DELAY);
+ alarm(CHARON_RESTART_DELAY); // restart in 5 sec
+ }
+ unlink(CHARON_PID_FILE);
}
- unlink(CHARON_PID_FILE);
- }
}
int
starter_stop_charon (void)
{
- int i;
- pid_t pid = _charon_pid;
+ int i;
+ pid_t pid = _charon_pid;
- if (pid)
- {
- _stop_requested = 1;
-
- /* be more and more aggressive */
- for (i = 0; i < 50 && (pid = _charon_pid) != 0; i++)
+ if (pid)
{
- if (i == 0)
- {
- kill(pid, SIGINT);
- }
- else if (i < 40)
- {
- kill(pid, SIGTERM);
- }
- else if (i == 40)
- {
- kill(pid, SIGKILL);
- plog("starter_stop_charon(): charon does not respond, sending KILL");
- }
- else
- {
- kill(pid, SIGKILL);
- }
- usleep(200000); /* sleep for 200 ms */
+ _stop_requested = 1;
+
+ /* be more and more aggressive */
+ for (i = 0; i < 50 && (pid = _charon_pid) != 0; i++)
+ {
+ if (i == 0)
+ {
+ kill(pid, SIGINT);
+ }
+ else if (i < 40)
+ {
+ kill(pid, SIGTERM);
+ }
+ else if (i == 40)
+ {
+ kill(pid, SIGKILL);
+ plog("starter_stop_charon(): charon does not respond, sending KILL");
+ }
+ else
+ {
+ kill(pid, SIGKILL);
+ }
+ usleep(200000); /* sleep for 200 ms */
+ }
+ if (_charon_pid == 0)
+ {
+ plog("charon stopped after %d ms", 200*i);
+ return 0;
+ }
+ plog("starter_stop_charon(): can't stop charon !!!");
+ return -1;
}
- if (_charon_pid == 0)
+ else
{
- plog("charon stopped after %d ms", 200*i);
- return 0;
+ plog("stater_stop_charon(): charon was not started...");
}
- plog("starter_stop_charon(): can't stop charon !!!");
return -1;
- }
- else
- {
- plog("stater_stop_charon(): charon was not started...");
- }
- return -1;
}
int
-starter_start_charon (starter_config_t *cfg, bool no_fork)
+starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
{
- struct stat stb;
- int pid, i;
- char buffer[BUF_LEN];
- int argc = 1;
- char *arg[] = {
- CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- };
-
- if (!no_fork)
- {
- arg[argc++] = "--use-syslog";
- }
-
- /* parse debug string */
- {
- int level;
- char type[4];
- char *pos = cfg->setup.charondebug;
- char *buf_pos = buffer;
-
- while (pos && sscanf(pos, "%4s %d,", type, &level) == 2)
- {
- snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "--debug-%s", type);
- arg[argc++] = buf_pos;
- buf_pos += strlen(buf_pos) + 1;
- if (buf_pos >= buffer + sizeof(buffer))
- {
- break;
- }
- snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "%d", level);
- arg[argc++] = buf_pos;
- buf_pos += strlen(buf_pos) + 1;
- if (buf_pos >= buffer + sizeof(buffer))
- {
- break;
- }
+ struct stat stb;
+ int pid, i;
+ char buffer[BUF_LEN];
+ int argc = 1;
+ char *arg[] = {
+ CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ };
- /* get next */
- pos = strchr(pos, ',');
- if (pos)
- {
- pos++;
- }
+ if (attach_gdb)
+ {
+ argc = 0;
+ arg[argc++] = "/usr/bin/gdb";
+ arg[argc++] = "--args";
+ arg[argc++] = CHARON_CMD;
+ }
+ if (!no_fork)
+ {
+ arg[argc++] = "--use-syslog";
}
- }
- if (_charon_pid)
- {
- plog("starter_start_charon(): charon already started...");
- return -1;
- }
- else
- {
- unlink(CHARON_CTL_FILE);
- _stop_requested = 0;
-
- pid = fork();
- switch (pid)
+ /* parse debug string */
{
- case -1:
- plog("can't fork(): %s", strerror(errno));
- return -1;
- case 0:
- /* child */
- setsid();
- sigprocmask(SIG_SETMASK, 0, NULL);
- /* disable glibc's malloc checker, conflicts with leak detective */
- setenv("MALLOC_CHECK_", "0", 1);
- execv(arg[0], arg);
- plog("can't execv(%s,...): %s", arg[0], strerror(errno));
- exit(1);
- default:
- /* father */
- _charon_pid = pid;
- for (i = 0; i < 500 && _charon_pid; i++)
- {
- /* wait for charon for a maximum of 500 x 20 ms = 10 s */
- usleep(20000);
- if (stat(CHARON_PID_FILE, &stb) == 0)
+ int level;
+ char type[4];
+ char *pos = cfg->setup.charondebug;
+ char *buf_pos = buffer;
+
+ while (pos && sscanf(pos, "%4s %d,", type, &level) == 2)
{
- plog("charon (%d) started after %d ms", _charon_pid, 20*(i+1));
- return 0;
+ snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "--debug-%s", type);
+ arg[argc++] = buf_pos;
+ buf_pos += strlen(buf_pos) + 1;
+ if (buf_pos >= buffer + sizeof(buffer))
+ {
+ break;
+ }
+ snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "%d", level);
+ arg[argc++] = buf_pos;
+ buf_pos += strlen(buf_pos) + 1;
+ if (buf_pos >= buffer + sizeof(buffer))
+ {
+ break;
+ }
+
+ /* get next */
+ pos = strchr(pos, ',');
+ if (pos)
+ {
+ pos++;
+ }
}
- }
- if (_charon_pid)
- {
- /* If charon is started but with no ctl file, stop it */
- plog("charon too long to start... - kill kill");
- for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
+ }
+
+ if (_charon_pid)
+ {
+ plog("starter_start_charon(): charon already started...");
+ return -1;
+ }
+ else
+ {
+ unlink(CHARON_CTL_FILE);
+ _stop_requested = 0;
+
+ pid = fork();
+ switch (pid)
{
- if (i == 0)
- {
- kill(pid, SIGINT);
- }
- else if (i < 10)
- {
- kill(pid, SIGTERM);
- }
- else
- {
- kill(pid, SIGKILL);
- }
- usleep(20000); /* sleep for 20 ms */
+ case -1:
+ plog("can't fork(): %s", strerror(errno));
+ return -1;
+ case 0:
+ /* child */
+ setsid();
+ sigprocmask(SIG_SETMASK, 0, NULL);
+ /* disable glibc's malloc checker, conflicts with leak detective */
+ setenv("MALLOC_CHECK_", "0", 1);
+ execv(arg[0], arg);
+ plog("can't execv(%s,...): %s", arg[0], strerror(errno));
+ exit(1);
+ default:
+ /* father */
+ _charon_pid = pid;
+ for (i = 0; i < 500 && _charon_pid; i++)
+ {
+ /* wait for charon for a maximum of 500 x 20 ms = 10 s */
+ usleep(20000);
+ if (stat(CHARON_PID_FILE, &stb) == 0)
+ {
+ plog("charon (%d) started after %d ms", _charon_pid, 20*(i+1));
+ return 0;
+ }
+ }
+ if (_charon_pid)
+ {
+ /* If charon is started but with no ctl file, stop it */
+ plog("charon too long to start... - kill kill");
+ for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
+ {
+ if (i == 0)
+ {
+ kill(pid, SIGINT);
+ }
+ else if (i < 10)
+ {
+ kill(pid, SIGTERM);
+ }
+ else
+ {
+ kill(pid, SIGKILL);
+ }
+ usleep(20000); /* sleep for 20 ms */
+ }
+ }
+ else
+ {
+ plog("charon refused to be started");
+ }
+ return -1;
}
- }
- else
- {
- plog("charon refused to be started");
- }
- return -1;
}
- }
- return -1;
+ return -1;
}