From c61c6525d92d0324770fa76f2a802f55235ac752 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 2 Nov 2009 18:04:19 +0100 Subject: [PATCH] Add -m option to DIR,FD,SD to dump kaboom output --- bacula/scripts/bacula-ctl-dir.in | 4 +- bacula/scripts/bacula-ctl-fd.in | 2 +- bacula/scripts/bacula-ctl-sd.in | 2 +- bacula/scripts/btraceback.in | 11 +++-- bacula/src/dird/dird.c | 14 ++++-- bacula/src/filed/filed.c | 11 +++-- bacula/src/lib/jcr.c | 15 +++--- bacula/src/lib/message.c | 1 + bacula/src/lib/message.h | 16 +++--- bacula/src/lib/plugins.c | 2 +- bacula/src/lib/signal.c | 85 +++++++++++++++++++++++--------- bacula/src/stored/stored.c | 11 +++-- regress/scripts/functions | 6 +-- 13 files changed, 115 insertions(+), 65 deletions(-) diff --git a/bacula/scripts/bacula-ctl-dir.in b/bacula/scripts/bacula-ctl-dir.in index 693e59aba9..4282eb7bdf 100644 --- a/bacula/scripts/bacula-ctl-dir.in +++ b/bacula/scripts/bacula-ctl-dir.in @@ -209,9 +209,9 @@ case "$1" in fi if [ "x${VALGRIND}" = "x1" ]; then - valgrind --leak-check=full ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf + valgrind --leak-check=full ${BACDIRBIN}/bacula-dir $2 $3 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf else - ${BACDIRBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf + ${BACDIRBIN}/bacula-dir $2 $3 ${OPTIONS} -v -c ${BACDIRCFG}/bacula-dir.conf fi } ;; diff --git a/bacula/scripts/bacula-ctl-fd.in b/bacula/scripts/bacula-ctl-fd.in index a5deeadf66..093797eb74 100644 --- a/bacula/scripts/bacula-ctl-fd.in +++ b/bacula/scripts/bacula-ctl-fd.in @@ -207,7 +207,7 @@ case "$1" in OPTIONS="${OPTIONS} -g ${FD_GROUP}" fi - ${BACFDBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/bacula-fd.conf + ${BACFDBIN}/bacula-fd $2 $3 ${OPTIONS} -v -c ${BACFDCFG}/bacula-fd.conf } ;; diff --git a/bacula/scripts/bacula-ctl-sd.in b/bacula/scripts/bacula-ctl-sd.in index b1bbbf78dc..9046f5b8fb 100644 --- a/bacula/scripts/bacula-ctl-sd.in +++ b/bacula/scripts/bacula-ctl-sd.in @@ -207,7 +207,7 @@ case "$1" in OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi - ${BACSDBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/bacula-sd.conf + ${BACSDBIN}/bacula-sd $2 $3 ${OPTIONS} -v -c ${BACSDCFG}/bacula-sd.conf } ;; diff --git a/bacula/scripts/btraceback.in b/bacula/scripts/btraceback.in index d4271c34ce..1e7ae9e988 100755 --- a/bacula/scripts/btraceback.in +++ b/bacula/scripts/btraceback.in @@ -7,17 +7,18 @@ # Arguments to this script are # $1 = path to executable # $2 = main pid of running program to be traced back. +# $3 = working directory # PNAME=`basename $1` PNAME="${PNAME} on `hostname`" -WD="@working_dir@" +WD="$3" if test `uname -s` = SunOS ; then gcore -o ${WD}/${PNAME} $2 - dbx $1 $2 <@scriptdir@/btraceback.dbx >${WD}/bacula.$$.traceback 2>&1 - cat ${WD}/bacula.$$.traceback \ + dbx $1 $2 <@scriptdir@/btraceback.dbx >${WD}/bacula.$2.traceback 2>&1 + cat ${WD}/bacula.$2.traceback \ | @sbindir@/bsmtp -h @smtp_host@ -f @dump_email@ -s "Bacula DBX traceback of ${PNAME}" @dump_email@ else - gdb -quiet -batch -x @scriptdir@/btraceback.gdb $1 $2 >${WD}/bacula.$$.traceback 2>&1 - cat ${WD}/bacula.$$.traceback \ + gdb -quiet -batch -x @scriptdir@/btraceback.gdb $1 $2 >${WD}/bacula.$2.traceback 2>&1 + cat ${WD}/bacula.$2.traceback \ | @sbindir@/bsmtp -h @smtp_host@ -f @dump_email@ -s "Bacula GDB traceback of ${PNAME}" @dump_email@ fi diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 3975d50b41..a431721461 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -31,7 +31,6 @@ * * Kern Sibbald, March MM * - * Version $Id$ */ #include "bacula.h" @@ -74,7 +73,7 @@ void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass); void init_device_resources(); static char *runjob = NULL; -static int background = 1; +static bool background = true; static void init_reload(void); static CONFIG *config; @@ -116,6 +115,7 @@ PROG_COPYRIGHT " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" +" -m print kaboom output for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" @@ -130,7 +130,7 @@ PROG_COPYRIGHT /********************************************************************* * - * Main Bacula Server program + * Main Bacula Director Server program * */ #if defined(HAVE_WIN32) @@ -163,7 +163,7 @@ int main (int argc, char *argv[]) console_command = run_console_command; - while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) { + while ((ch = getopt(argc, argv, "c:d:fg:mr:stu:v?")) != -1) { switch (ch) { case 'c': /* specify config file */ if (configfile != NULL) { @@ -185,13 +185,17 @@ int main (int argc, char *argv[]) break; case 'f': /* run in foreground */ - background = FALSE; + background = false; break; case 'g': /* set group id */ gid = optarg; break; + case 'm': /* print kaboom output */ + prt_kaboom = true; + break; + case 'r': /* run job */ if (runjob != NULL) { free(runjob); diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index aa4ea35ace..9a893f929f 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + Copyright (C) 2000-2009 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. @@ -30,8 +30,6 @@ * * Kern Sibbald, March MM * - * Version $Id$ - * */ #include "bacula.h" @@ -83,6 +81,7 @@ PROG_COPYRIGHT " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" +" -m print kaboom output (for debugging)\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" @@ -123,7 +122,7 @@ int main (int argc, char *argv[]) init_msg(NULL, NULL); daemon_start_time = time(NULL); - while ((ch = getopt(argc, argv, "c:d:fg:kstu:v?")) != -1) { + while ((ch = getopt(argc, argv, "c:d:fg:kmstu:v?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { @@ -155,6 +154,10 @@ int main (int argc, char *argv[]) keep_readall_caps = true; break; + case 'm': /* print kaboom output */ + prt_kaboom = true; + break; + case 's': no_signals = true; break; diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 887aa439f1..f2240c2389 100644 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -1100,10 +1100,10 @@ extern "C" void timeout_handler(int sig) static dbg_jcr_hook_t *dbg_jcr_hooks[MAX_DBG_HOOK]; static int dbg_jcr_handler_count; -void dbg_jcr_add_hook(dbg_jcr_hook_t *fct) +void dbg_jcr_add_hook(dbg_jcr_hook_t *hook) { ASSERT(dbg_jcr_handler_count < MAX_DBG_HOOK); - dbg_jcr_hooks[dbg_jcr_handler_count++] = fct; + dbg_jcr_hooks[dbg_jcr_handler_count++] = hook; } /* @@ -1112,7 +1112,7 @@ void dbg_jcr_add_hook(dbg_jcr_hook_t *fct) * This function should be used ONLY after a fatal signal. We walk through the * JCR chain without doing any lock, Bacula should not be running. */ -void _dbg_print_jcr(FILE *fp) +void dbg_print_jcr(FILE *fp) { char buf1[128], buf2[128], buf3[128], buf4[128]; if (!jcrs) { @@ -1122,9 +1122,8 @@ void _dbg_print_jcr(FILE *fp) fprintf(fp, "Attempt to dump current JCRs\n"); for (JCR *jcr = (JCR *)jcrs->first(); jcr ; jcr = (JCR *)jcrs->next(jcr)) { - - fprintf(fp, "JCR=%p JobId=%i name=%s JobStatus=%c\n", - jcr, jcr->JobId, jcr->Job, jcr->JobStatus); + fprintf(fp, "JCR=%p JobId=%d name=%s JobStatus=%c\n", + jcr, (int)jcr->JobId, jcr->Job, jcr->JobStatus); fprintf(fp, "\tuse_count=%i\n", jcr->use_count()); fprintf(fp, "\tJobType=%c JobLevel=%c\n", jcr->get_JobType(), jcr->get_JobLevel()); @@ -1141,8 +1140,8 @@ void _dbg_print_jcr(FILE *fp) * Call all the jcr debug hooks */ for(int i=0; i < dbg_jcr_handler_count; i++) { - dbg_jcr_hook_t *fct = dbg_jcr_hooks[i]; - fct(jcr, fp); + dbg_jcr_hook_t *hook = dbg_jcr_hooks[i]; + hook(jcr, fp); } } } diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 9b5e2d5ff5..5791f6b51b 100644 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -48,6 +48,7 @@ const char *working_directory = NULL; /* working directory path stored her int verbose = 0; /* increase User messages */ int debug_level = 0; /* debug level */ bool dbg_timestamp = false; /* print timestamp in debug output */ +bool prt_kaboom = false; /* Print kaboom output */ utime_t daemon_start_time = 0; /* Daemon start time */ const char *version = VERSION " (" BDATE ")"; char my_name[30]; /* daemon name is stored here */ diff --git a/bacula/src/lib/message.h b/bacula/src/lib/message.h index 923075ff2a..def98670cd 100644 --- a/bacula/src/lib/message.h +++ b/bacula/src/lib/message.h @@ -1,13 +1,7 @@ -/* - * Define Message Types for Bacula - * Kern Sibbald, 2000 - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-2009 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. @@ -31,6 +25,12 @@ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Define Message Types for Bacula + * Kern Sibbald, 2000 + * + */ + #include "bits.h" @@ -155,6 +155,7 @@ extern DLL_IMP_EXP sql_escape p_sql_escape; extern DLL_IMP_EXP int debug_level; extern DLL_IMP_EXP bool dbg_timestamp; /* print timestamp in debug output */ +extern DLL_IMP_EXP bool prt_kaboom; /* Print kaboom output */ extern DLL_IMP_EXP int verbose; extern DLL_IMP_EXP char my_name[]; extern DLL_IMP_EXP const char * working_directory; @@ -163,4 +164,3 @@ extern DLL_IMP_EXP utime_t daemon_start_time; extern DLL_IMP_EXP int console_msg_pending; extern DLL_IMP_EXP FILE * con_fd; /* Console file descriptor */ extern DLL_IMP_EXP brwlock_t con_lock; /* Console lock structure */ - diff --git a/bacula/src/lib/plugins.c b/bacula/src/lib/plugins.c index 739a504899..26028534d5 100644 --- a/bacula/src/lib/plugins.c +++ b/bacula/src/lib/plugins.c @@ -241,7 +241,7 @@ void dbg_plugin_add_hook(dbg_plugin_hook_t *fct) dbg_plugin_hooks[dbg_plugin_hook_count++] = fct; } -void _dbg_print_plugin(FILE *fp) +void dbg_print_plugin(FILE *fp) { Plugin *plugin; fprintf(fp, "Attempt to dump plugins\n"); diff --git a/bacula/src/lib/signal.c b/bacula/src/lib/signal.c index 94500d8e06..88df609358 100644 --- a/bacula/src/lib/signal.c +++ b/bacula/src/lib/signal.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + Copyright (C) 2000-2009 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. @@ -30,8 +30,6 @@ * * Kern Sibbald, April 2000 * - * Version $Id$ - * * Note, we probably should do a core dump for the serious * signals such as SIGBUS, SIGPFE, ... * Also, for SIGHUP and SIGUSR1, we should re-read the @@ -53,7 +51,7 @@ extern char my_name[]; extern char *exepath; extern char *exename; -extern void print_jcr_dbg(); +extern bool prt_kaboom; static const char *sig_names[BA_NSIG+1]; @@ -73,9 +71,9 @@ const char *get_signal_name(int sig) } /* defined in jcr.c */ -extern void _dbg_print_jcr(FILE *fp); -/* defined in plugin.c */ -extern void _dbg_print_plugin(FILE *fp); +extern void dbg_print_jcr(FILE *fp); +/* defined in plugins.c */ +extern void dbg_print_plugin(FILE *fp); /* defined in lockmgr.c */ extern void dbg_print_lock(FILE *fp); @@ -91,7 +89,7 @@ static void dbg_print_bacula() snprintf(buf, sizeof(buf), "%s/%s.%d.bactrace", working_directory, my_name, (int)getpid()); - FILE *fp = fopen(buf, "ab") ; + FILE *fp = fopen(buf, "a+") ; if (!fp) { fp = stderr; } @@ -102,10 +100,29 @@ static void dbg_print_bacula() * Can add more info about JCR with dbg_jcr_add_hook() */ dbg_print_lock(fp); - _dbg_print_jcr(fp); - _dbg_print_plugin(fp); + dbg_print_jcr(fp); + dbg_print_plugin(fp); if (fp != stderr) { +#define direct_print +#ifdef direct_print + if (prt_kaboom) { + rewind(fp); + printf("\n\n ==== bactrace output ====\n\n"); + while (fgets(buf, (int)sizeof(buf), fp) != NULL) { + printf("%s", buf); + } + printf(" ==== End baktrace output ====\n\n"); + } +#else + if (prt_kaboom) { + char buf1[512]; + printf("\n\n ==== bactrace output ====\n\n"); + snprintf(buf1, sizeof(buf1), "/bin/cat %s", buf); + system(buf1); + printf(" ==== End baktrace output ====\n\n"); + } +#endif fclose(fp); } } @@ -127,22 +144,22 @@ extern "C" void signal_handler(int sig) return; } already_dead++; + /* Don't use Emsg here as it may lock and thus block us */ if (sig == SIGTERM) { -// Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name); + syslog(LOG_DAEMON|LOG_ERR, "Shutting down Bacula service: %s ...\n", my_name); } else { -/* ***FIXME*** Display a message without locking - * Emsg2(M_FATAL, -1, _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig)); - */ fprintf(stderr, _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig)); + syslog(LOG_DAEMON|LOG_ERR, + _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig)); } #ifdef TRACEBACK if (sig != SIGTERM) { struct sigaction sigdefault; - static char *argv[4]; + static char *argv[5]; static char pid_buf[20]; static char btpath[400]; - char buf[100]; + char buf[400]; pid_t pid; int exelen = strlen(exepath); @@ -188,8 +205,10 @@ extern "C" void signal_handler(int sig) argv[0] = btpath; /* path to btraceback */ argv[1] = exepath; /* path to exe */ argv[2] = pid_buf; - argv[3] = (char *)NULL; - fprintf(stderr, _("Calling: %s %s %s\n"), btpath, exepath, pid_buf); + argv[3] = (char *)working_directory; + argv[4] = (char *)NULL; + fprintf(stderr, _("Calling: %s %s %s %s\n"), btpath, exepath, pid_buf, + working_directory); if (execv(btpath, argv) != 0) { berrno be; printf(_("execv: %s failed: ERR=%s\n"), btpath, be.bstrerror()); @@ -209,20 +228,40 @@ extern "C" void signal_handler(int sig) Dmsg0(500, "Doing waitpid\n"); waitpid(pid, NULL, 0); /* wait for child to produce dump */ Dmsg0(500, "Done waitpid\n"); - fprintf(stderr, _("Traceback complete, attempting cleanup ...\n")); - /* print information about the current state into working/.bactrace */ - dbg_print_bacula(); - exit_handler(sig); /* clean up if possible */ - Dmsg0(500, "Done exit_handler\n"); } else { Dmsg0(500, "Doing sleep\n"); bmicrosleep(30, 0); } fprintf(stderr, _("It looks like the traceback worked ...\n")); + /* If we want it printed, do so */ +#ifdef direct_print + if (prt_kaboom) { + FILE *fd; + snprintf(buf, sizeof(buf), "%s/bacula.%s.traceback", working_directory, pid_buf); + fd = fopen(buf, "r"); + if (fd != NULL) { + printf("\n\n ==== Traceback output ====\n\n"); + while (fgets(buf, (int)sizeof(buf), fd) != NULL) { + printf("%s", buf); + } + fclose(fd); + printf(" ==== End traceback output ====\n\n"); + } + } +#else + if (prt_kaboom) { + snprintf(buf, sizeof(buf), "/bin/cat %s/bacula.%s.traceback", working_directory, pid_buf); + fprintf(stderr, "\n\n ==== Traceback output ====\n\n"); + system(buf); + fprintf(stderr, " ==== End traceback output ====\n\n"); + } +#endif + /* print information about the current state into working/.bactrace */ dbg_print_bacula(); } #endif exit_handler(sig); + Dmsg0(500, "Done exit_handler\n"); } /* diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index 8c0bd6f416..93735c76b4 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + Copyright (C) 2000-2009 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. @@ -35,8 +35,6 @@ * it opens a data channel and accepts data from the * File daemon. * - * Version $Id$ - * */ #include "bacula.h" @@ -106,6 +104,7 @@ PROG_COPYRIGHT " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" +" -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" @@ -156,7 +155,7 @@ int main (int argc, char *argv[]) Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE); } - while ((ch = getopt(argc, argv, "c:d:fg:pstu:v?")) != -1) { + while ((ch = getopt(argc, argv, "c:d:fg:mpstu:v?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { @@ -184,6 +183,10 @@ int main (int argc, char *argv[]) gid = optarg; break; + case 'm': /* print kaboom output */ + prt_kaboom = true; + break; + case 'p': /* proceed in spite of I/O errors */ forge_on = true; break; diff --git a/regress/scripts/functions b/regress/scripts/functions index db2b58bf3b..df9f1319d0 100644 --- a/regress/scripts/functions +++ b/regress/scripts/functions @@ -158,9 +158,9 @@ run_bacula() debug_wait zstat=0 if test "$debug" -eq 1 ; then - ${scripts}/bacula-ctl-sd start - ${scripts}/bacula-ctl-fd start $1 - ${scripts}/bacula-ctl-dir start + ${scripts}/bacula-ctl-sd start -m + ${scripts}/bacula-ctl-fd start -m $1 + ${scripts}/bacula-ctl-dir start -m cat ${tmp}/bconcmds | ${bin}/bconsole -c ${conf}/bconsole.conf return $? else -- 2.39.5