From 7dd370e12840c4fbd98e486cbe90cb94ee556a47 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 10 Jul 2010 14:21:46 +0200 Subject: [PATCH] Add .dump and .exit commands for daemons --- bacula/src/dird/ua_dotcmds.c | 37 +++++++++++++++++++++++------------- bacula/src/filed/filed.c | 1 - bacula/src/filed/filed.h | 3 +++ bacula/src/filed/job.c | 17 +++++++++++++++-- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index afe4be6a9e..945d9a0958 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2002-2009 Free Software Foundation Europe e.V. + Copyright (C) 2002-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -52,7 +52,7 @@ extern bool dot_status_cmd(UAContext *ua, const char *cmd); /* Forward referenced functions */ -static bool die_or_dump_cmd(UAContext *ua, const char *cmd); +static bool admin_cmds(UAContext *ua, const char *cmd); static bool jobscmd(UAContext *ua, const char *cmd); static bool filesetscmd(UAContext *ua, const char *cmd); static bool clientscmd(UAContext *ua, const char *cmd); @@ -85,9 +85,9 @@ static struct cmdstruct commands[] = { /* help */ /* can be used in runscript * { NT_(".backups"), backupscmd, NULL, false}, { NT_(".clients"), clientscmd, NULL, true}, { NT_(".defaults"), defaultscmd, NULL, false}, - { NT_(".die"), die_or_dump_cmd, NULL, false}, - { NT_(".dump"), die_or_dump_cmd, NULL, false}, - { NT_(".exit"), dot_quit_cmd, NULL, false}, + { NT_(".die"), admin_cmds, NULL, false}, + { NT_(".dump"), admin_cmds, NULL, false}, + { NT_(".exit"), admin_cmds, NULL, false}, { NT_(".filesets"), filesetscmd, NULL, false}, { NT_(".help"), dot_help_cmd, NULL, false}, { NT_(".jobs"), jobscmd, NULL, true}, @@ -419,32 +419,41 @@ static void do_client_cmd(UAContext *ua, CLIENT *client, const char *cmd) } /* - * Create segmentation fault or dump memory + * .die (seg fault) + * .dump (sm_dump) + * .exit (no arg => .quit) */ -static bool die_or_dump_cmd(UAContext *ua, const char *cmd) +static bool admin_cmds(UAContext *ua, const char *cmd) { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; STORE *store=NULL; CLIENT *client=NULL; bool dir=false; bool do_deadlock=false; - const char *remote_cmd="sm_dump"; + const char *remote_cmd; int i; JCR *jcr = NULL; int a; - if (!strncmp(ua->argk[0], ".die", 4)) { + if (strncmp(ua->argk[0], ".die", 4) == 0) { if (find_arg(ua, "deadlock") > 0) { - do_deadlock=true; + do_deadlock = true; remote_cmd = ".die deadlock"; } else { remote_cmd = ".die"; } + } else if (strncmp(ua->argk[0], ".dump", 5) == 0) { + remote_cmd = "sm_dump"; + } else if (strncmp(ua->argk[0], ".exit", 5) == 0) { + remote_cmd = "exit"; + } else { + ua->error_msg(_("Unknown command: %s\n"), ua->argk[0]); + return true; } /* General debug? */ for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], "dir") == 0 || strcasecmp(ua->argk[i], "director") == 0) { - dir=true; + dir = true; } if (strcasecmp(ua->argk[i], "client") == 0 || strcasecmp(ua->argk[i], "fd") == 0) { @@ -503,7 +512,7 @@ static bool die_or_dump_cmd(UAContext *ua, const char *cmd) } if (dir) { - if (!strncmp(remote_cmd, ".die", 4)) { + if (strncmp(remote_cmd, ".die", 4) == 0) { if (do_deadlock) { ua->send_msg(_("The Director will generate a deadlock.\n")); P(mutex); @@ -513,8 +522,10 @@ static bool die_or_dump_cmd(UAContext *ua, const char *cmd) a = jcr->JobId; /* ref NULL pointer */ jcr->JobId = 1000; /* another ref NULL pointer */ - } else { /* .dump */ + } else if (strncmp(remote_cmd, ".dump", 5) == 0) { sm_dump(false, true); + } else if (strncmp(remote_cmd, ".exit", 5) == 0) { + dot_quit_cmd(ua, cmd); } } diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 50708d3d48..7ef7c6ece8 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -53,7 +53,6 @@ extern void *handle_client_request(void *dir_sock); extern bool parse_fd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ -void terminate_filed(int sig); static bool check_resources(); /* Exported variables */ diff --git a/bacula/src/filed/filed.h b/bacula/src/filed/filed.h index 6aac8f5218..7a820e1db1 100644 --- a/bacula/src/filed/filed.h +++ b/bacula/src/filed/filed.h @@ -78,3 +78,6 @@ typedef enum { #endif extern CLIENT *me; /* "Global" Client resource */ + +void terminate_filed(int sig); + diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 0a2b8e2dcd..9059314a7a 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -92,6 +92,7 @@ static int restore_object_cmd(JCR *jcr); static int set_options(findFOPTS *fo, const char *opts); static void set_storage_auth_key(JCR *jcr, char *key); static int sm_dump_cmd(JCR *jcr); +static int exit_cmd(JCR *jcr); /* Exported functions */ @@ -128,6 +129,9 @@ static struct s_cmds cmds[] = { {"accurate", accurate_cmd, 0}, {"restoreobject", restore_object_cmd, 0}, {"sm_dump", sm_dump_cmd, 0}, +#ifdef DEVELOPER + {"exit", exit_cmd, 0}, +#endif {NULL, NULL} /* list terminator */ }; @@ -401,12 +405,21 @@ void *handle_client_request(void *dirp) static int sm_dump_cmd(JCR *jcr) { - BSOCK *dir = jcr->dir_bsock; sm_dump(false, true); - dir->fsend("2000 sm_dump OK\n"); + jcr->dir_bsock->fsend("2000 sm_dump OK\n"); return 1; } +#ifdef DEVELOPER +static int exit_cmd(JCR *jcr) +{ + jcr->dir_bsock->fsend("2000 exit OK\n"); + terminate_filed(0); + return 0; +} +#endif + + /** * Hello from Director he must identify himself and provide his * password. -- 2.39.5