From: Kern Sibbald Date: Sat, 9 Nov 2002 15:55:28 +0000 (+0000) Subject: Manual rework + new website see kes08Nov02 X-Git-Tag: Release-1.27~33 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=40b3afb988ac3acbba09fbe633af7c103d61b915;p=bacula%2Fbacula Manual rework + new website see kes08Nov02 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@185 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/Makefile.in b/bacula/Makefile.in index eff60474a4..48467ac468 100755 --- a/bacula/Makefile.in +++ b/bacula/Makefile.in @@ -15,7 +15,7 @@ thisdir = . first_rule: all dummy: -subdirs = src doc src/lib src/findlib src/cats \ +subdirs = src scripts doc src/lib src/findlib src/cats \ @READLINE_SRC@ src/console src/dird src/filed \ src/stored @GNOME_DIR@ src/tools @@ -73,25 +73,9 @@ installdirs: # $(MKDIR) $(DESTDIR)$(mandir) install: installdirs - $(INSTALL_SCRIPT) startmysql $(DESTDIR)$(sysconfdir)/startmysql - $(INSTALL_SCRIPT) stopmysql $(DESTDIR)$(sysconfdir)/stopmysql - $(INSTALL_SCRIPT) console $(DESTDIR)$(sysconfdir)/console - $(INSTALL_SCRIPT) bacula $(DESTDIR)$(sysconfdir)/bacula - $(INSTALL_SCRIPT) fd $(DESTDIR)$(sysconfdir)/fd - $(INSTALL_SCRIPT) mtx-changer $(DESTDIR)$(sysconfdir)/mtx-changer - $(INSTALL_SCRIPT) btraceback $(DESTDIR)$(sysconfdir)/btraceback - $(INSTALL_DATA) btraceback.gdb $(DESTDIR)$(sysconfdir)/btraceback.gdb @for I in $(subdirs); do (cd $$I; $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1); done uninstall: - (cd $(DESTDIR)$(sysconfdir); $(RMF) startmysql) - (cd $(DESTDIR)$(sysconfdir); $(RMF) stopmysql) - (cd $(DESTDIR)$(sysconfdir); $(RMF) console) - (cd $(DESTDIR)$(sysconfdir); $(RMF) bacula) - (cd $(DESTDIR)$(sysconfdir); $(RMF) fd) - (cd $(DESTDIR)$(sysconfdir); $(RMF) mtx-changer) - (cd $(DESTDIR)$(sysconfdir); $(RMF) btraceback) - (cd $(DESTDIR)$(sysconfdir); $(RMF) btraceback.gdb) @for I in $(subdirs); do (cd $$I; $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1); done install-autostart: install-autostart-dir install-autostart-fd install-autostart-sd @@ -122,8 +106,9 @@ Makefile: Makefile.in Makefiles: $(SHELL) config.status - chmod 755 startmysql stopmysql bacula fd startit stopit btraceback - chmod 755 mtx-changer console gconsole + (cd scripts; \ + chmod 755 startmysql stopmysql bacula fd startit stopit btraceback; \ + chmod 755 mtx-changer console gconsole) chmod 755 src/console/btraceback src/lib/btraceback chmod 755 src/dird/btraceback src/filed/btraceback chmod 755 src/stored/btraceback diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index 95ec062a70..e31314400d 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -590,7 +590,7 @@ AC_ARG_WITH(dir-password, if test "x$dir_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then # key=`date | uuencode /dev/stdout | tr "\"@\\\`\\ \\=\\,\\(\\)\\#\\.\\!\\-$'" abcdefghijklmnopqrst | awk '{getline} {print} {exit}'` - key=`./randpass 33` + key=`autoconf/randpass 33` else key=`openssl rand -base64 33` fi @@ -610,7 +610,7 @@ AC_ARG_WITH(fd-password, if test "x$fd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then # key=`date | uuencode /dev/stdout | tr "\"@\\\`\\ \\=\\,\\(\\)\\#\\.\\!\\-$'" tsrqponmlkjihgfedcba | awk '{getline} {print} {exit}'` - key=`./randpass 37` + key=`autoconf/randpass 37` else key=`openssl rand -base64 33` fi @@ -630,7 +630,7 @@ AC_ARG_WITH(sd-password, if test "x$sd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then # key=`date | uuencode /dev/stdout | tr "\"@\\\`\\ \\=\\,\\(\\)\\#\\.\\!\\-$'" 123456789uvwxyzabcdef | awk '{getline} {print} {exit}'` - key=`./randpass 41` + key=`autocnf/randpass 41` else key=`openssl rand -base64 33` fi @@ -1207,15 +1207,16 @@ AC_SUBST_FILE(MCOMMON) AC_OUTPUT([autoconf/Make.common \ Makefile \ - startmysql \ - stopmysql \ - btraceback \ - startit \ - stopit \ - console \ - gconsole \ - bacula \ - fd \ + scripts/startmysql \ + scripts/stopmysql \ + scripts/btraceback \ + scripts/startit \ + scripts/stopit \ + scripts/console \ + scripts/gconsole \ + scripts/bacula \ + scripts/fd \ + scripts/Makefile \ doc/Makefile \ src/Makefile \ src/console/Makefile \ @@ -1254,13 +1255,10 @@ AC_OUTPUT([autoconf/Make.common \ [(echo "Doing make of dependencies"; make depend;) ] ) +cd scripts chmod 755 startmysql stopmysql bacula startit stopit btraceback mtx-changer chmod 755 console gconsole -cp -f startit stopit btraceback btraceback.gdb src/console -cp -f startit stopit btraceback btraceback.gdb src/dird -cp -f startit stopit btraceback btraceback.gdb src/filed -cp -f startit stopit btraceback btraceback.gdb src/lib -cp -f startit stopit btraceback btraceback.gdb src/stored +cd .. chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables chmod 755 src/cats/make_test_tables src/cats/drop_test_tables chmod 755 src/cats/create_mysql_database diff --git a/bacula/autoconf/randpass b/bacula/autoconf/randpass new file mode 100755 index 0000000000..b233e24efc --- /dev/null +++ b/bacula/autoconf/randpass @@ -0,0 +1,19 @@ +#! /bin/sh +# +# Generate a random password, written to standard output +# By John Walker +# +if test "x$1" = "x" ; then + PWL=48 # Password length in characters +else + PWL=$1 +fi +tmp=/tmp/p.tmp.$$ +cp autoconf/randpass.bc $tmp +ps | sum | tr -d ':[:alpha:] ' | sed 's/^/k=/' >>$tmp +date | tr -d ':[:alpha:] ' | sed 's/^/k=k*/' >>$tmp +ls -l /tmp | sum | tr -d ':[:alpha:] ' | sed 's/^/k=k*/' >>$tmp +echo "j=s(k); for (i = 0; i < $PWL; i++) r()" >>$tmp +echo "quit" >>$tmp +bc $tmp | awk -f autoconf/randpass.awk +rm $tmp diff --git a/bacula/autoconf/randpass.awk b/bacula/autoconf/randpass.awk new file mode 100644 index 0000000000..04cfd13b2e --- /dev/null +++ b/bacula/autoconf/randpass.awk @@ -0,0 +1,14 @@ + +# Dumb little AWK program to convert random decimal +# values generated by rand.bc into passwords from the +# character set defined below as "charset". + +BEGIN { + charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + for (i = 0; i < length(charset); i++) { + set[i] = substr(charset, i, 1) + } +} + { printf "%s", set[$1 % length(charset)] } + +END { printf "\n" } diff --git a/bacula/autoconf/randpass.bc b/bacula/autoconf/randpass.bc new file mode 100644 index 0000000000..8a35df67a4 --- /dev/null +++ b/bacula/autoconf/randpass.bc @@ -0,0 +1,44 @@ + /* + "bc" implementation of the "Minimal Standard" + multiplicative congruential generator of Park and Miller. + [Park, S.K. and K.W. Miller, Communications of the ACM 31, + 1192-1201 (1988).] + + The generation algorithm is: + + I[j+1] = (I[j] × 16807) & 0x7FFFFFFF + + Note that the intermediate value of the multiplication by 16807 + (7^5) exceeds that representable in 32 bits; this has + deterred use of this generator in most portable languages. + Fortunately, bc computes with arbitrary precision so this + poses no problem. + + Designed and implemented in September 2002 by John Walker, + http://www.fourmilab.ch/. + */ + + /* Initialise state to default value of 1. */ + + t = 1 + + /* Generate and return the next random byte, updating + the state t. */ + + define r() { + t = (t * 16807) % (2^31) + return ((t / 2048) % (2^8)) + } + + /* Set the seed to the x argument. The state t is + set from the seed, after an initial shuffle. If + you don't want 0 printed when setting the seed, + assign s(x) to a junk variable. */ + + define s(x) { + auto i, j + if (x == 0) { "Seed must be nonzero"; return } + t = x % (2^32) + /* Perform initial shuffle of state. */ + for (i = 0; i < 11; i++) j = r() + } diff --git a/bacula/configure b/bacula/configure index 294fddec3e..edb1576258 100755 --- a/bacula/configure +++ b/bacula/configure @@ -3762,7 +3762,7 @@ fi if test "x$dir_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then # key=`date | uuencode /dev/stdout | tr "\"@\\\`\\ \\=\\,\\(\\)\\#\\.\\!\\-$'" abcdefghijklmnopqrst | awk '{getline} {print} {exit}'` - key=`./randpass 33` + key=`autoconf/randpass 33` else key=`openssl rand -base64 33` fi @@ -3785,7 +3785,7 @@ fi if test "x$fd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then # key=`date | uuencode /dev/stdout | tr "\"@\\\`\\ \\=\\,\\(\\)\\#\\.\\!\\-$'" tsrqponmlkjihgfedcba | awk '{getline} {print} {exit}'` - key=`./randpass 37` + key=`autoconf/randpass 37` else key=`openssl rand -base64 33` fi @@ -3808,7 +3808,7 @@ fi if test "x$sd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then # key=`date | uuencode /dev/stdout | tr "\"@\\\`\\ \\=\\,\\(\\)\\#\\.\\!\\-$'" 123456789uvwxyzabcdef | awk '{getline} {print} {exit}'` - key=`./randpass 41` + key=`autocnf/randpass 41` else key=`openssl rand -base64 33` fi @@ -9503,15 +9503,16 @@ ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "autoconf/Make.common \ Makefile \ - startmysql \ - stopmysql \ - btraceback \ - startit \ - stopit \ - console \ - gconsole \ - bacula \ - fd \ + scripts/startmysql \ + scripts/stopmysql \ + scripts/btraceback \ + scripts/startit \ + scripts/stopit \ + scripts/console \ + scripts/gconsole \ + scripts/bacula \ + scripts/fd \ + scripts/Makefile \ doc/Makefile \ src/Makefile \ src/console/Makefile \ @@ -9761,15 +9762,16 @@ cat >> $CONFIG_STATUS </dev/null 2>&1; then + # TERM first, then KILL if not dead + kill -TERM $pid 2>/dev/null + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 1 + if ps -p $pid >/dev/null 2>&1 ; then + sleep 3 + if ps -p $pid >/dev/null 2>&1 ; then + kill -KILL $pid 2>/dev/null + fi + fi + fi + fi + ps -p $pid >/dev/null 2>&1 + RC=$? + [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" + # RC=$((! $RC)) + # use specified level only + else + if ps -p $pid >/dev/null 2>&1; then + kill $killlevel $pid 2>/dev/null + RC=$? + [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" + fi + fi + else + failure "$base shutdown" + fi + # Remove pid file if any. + if [ "$notset" = "1" ]; then + rm -f @piddir@/$base.$2.pid + fi + return $RC +} + +# A function to find the pid of a program. +pidofproc() { + pid="" + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: pidofproc {program}" + return 1 + fi + + # Get base program name + base=`basename $1` + + # First try PID file + if [ -f @piddir@/$base.$2.pid ] ; then + pid=`head -1 @piddir@/$base.$2.pid` + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + fi + + # Next try "pidof" + if [ -x /sbin/pidof ] ; then + pid=`/sbin/pidof $1` + fi + if [ "$pid" != "" ] ; then + echo $pid + return 0 + fi + + # Finally try to extract it from ps + ${PSCMD} | grep $1 | awk '{ print $1 }' | tr '\n' ' ' + return 0 +} + +status() { + # Test syntax. + if [ $# = 0 ] ; then + echo "Usage: status {program}" + return 1 + fi + + # Get base program name + base=`basename $1` + + # First try "pidof" + if [ -x /sbin/pidof ] ; then + pid=`/sbin/pidof $1` + fi + if [ "$pid" != "" ] ; then + echo "$base (pid $pid) is running..." + return 0 + else + pid=`${PSCMD} | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } + { if ((prog == $2) || (("(" prog ")") == $2) || + (("[" prog "]") == $2) || + ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` + if [ "$pid" != "" ] ; then + echo "$base (pid $pid) is running..." + return 0 + fi + fi + + # Next try the PID files + if [ -f @piddir@/$base.$2.pid ] ; then + pid=`head -1 @piddir@/$base.$2.pid` + if [ "$pid" != "" ] ; then + echo "$base dead but pid file exists" + return 1 + fi + fi + # See if the subsys lock exists + if [ -f @subsysdir@/$base ] ; then + echo "$base dead but subsys locked" + return 2 + fi + echo "$base is stopped" + return 3 +} + +success() { + return 0 +} + +failure() { + rc=$? + return $rc +} + +case "$1" in + start) + echo "Starting the Storage daemon" + @sbindir@/bacula-sd $2 -c @sysconfdir@/bacula-sd.conf + echo "Starting the File daemon" + @sbindir@/bacula-fd $2 -c @sysconfdir@/bacula-fd.conf + sleep 2 + echo "Starting the Director daemon" + @sbindir@/bacula-dir $2 -c @sysconfdir@/bacula-dir.conf + ;; + stop) + echo "Stopping the File daemon" + killproc @sbindir@/bacula-fd @fd_port@ + echo "Stopping the Storage daemon" + killproc @sbindir@/bacula-sd @sd_port@ + echo "Stopping the Director daemon" + killproc @sbindir@/bacula-dir @dir_port@ + echo + ;; + restart) + $0 stop + sleep 5 + $0 start + ;; + status) + status @sbindir@/bacula-sd @sd_port@ + status @sbindir@/bacula-fd @fd_port@ + status @sbindir@/bacula-dir @dir_port@ + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac +exit 0 diff --git a/bacula/scripts/btraceback.in b/bacula/scripts/btraceback.in new file mode 100755 index 0000000000..8d29d9469e --- /dev/null +++ b/bacula/scripts/btraceback.in @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Script to do a stackdump of a Bacula daemon/program. +# +# We attempt to attach to running program +# +# Arguments to this script are +# $1 = path to executable +# $2 = main pid of running program to be traced back. +# + +gdb -quiet -batch -x @sbindir@/btraceback.gdb $1 $2 2>&1 | mail -s "Bacula traceback" @dump_email@ + +# Below is some old code that did the traceback from a core +# dump. However, for some odd reason, core dumps are not +# always produced. +#i=0 +#core= +#echo "In modified btraceback" +#echo "$1 $2" +#pwd +#while [ "$i" -lt 60 ] ; do +# if [ -f core ] ; then +# break; +# fi +# if [ -f core.$2 ] ; then +# core=core.$2 +# break +# fi +# sleep 1 +# i=`expr $i + 1` +#done + +#if test x$core != x; then +# gdb -quiet -batch -x @sbindir@/btraceback.gdb $1 $core 2>&1 | mail -s "Bacula traceback" @dump_email@ +#else +# gdb -quiet -batch -x @sbindir@/btraceback.gdb $1 $2 2>&1 | mail -s "Bacula traceback" @dump_email@ +#fi diff --git a/bacula/scripts/defaultconfig b/bacula/scripts/defaultconfig new file mode 100755 index 0000000000..ec218deab0 --- /dev/null +++ b/bacula/scripts/defaultconfig @@ -0,0 +1,24 @@ +#!/bin/sh +# +# This is a default configuration file for Bacula that +# sets reasonable defaults, and assumes that you do not +# have MySQL running. It will "install" Bacula into +# bin and etc in the current directory. +# + +CFLAGS="-g -Wall" \ + ./configure \ + --sbindir=$HOME/bacula/bin \ + --sysconfdir=$HOME/bacula/bin \ + --with-pid-dir=$HOME/bacula/bin \ + --with-subsys-dir=$HOME/bacula/bin \ + --enable-smartalloc \ + --enable-gnome \ + --with-mysql=$HOME/mysql \ + --with-working-dir=$HOME/bacula/bin/working \ + --with-dump-email=root@localhost \ + --with-job-email=root@localhost \ + --with-smtp-host=localhost \ + --with-baseport=9101 + +exit 0 diff --git a/bacula/scripts/gconsole.in b/bacula/scripts/gconsole.in new file mode 100755 index 0000000000..0197d8da3b --- /dev/null +++ b/bacula/scripts/gconsole.in @@ -0,0 +1,8 @@ +#!/bin/sh +cd @BUILD_DIR@/src/gnome-console +if [ $# = 1 ] ; then + echo "doing gnome-console $1.conf" + ./gnome-console -c $1.conf +else + ./gnome-console +fi diff --git a/bacula/scripts/startit.in b/bacula/scripts/startit.in new file mode 100755 index 0000000000..da7ce84589 --- /dev/null +++ b/bacula/scripts/startit.in @@ -0,0 +1,2 @@ +#!/bin/sh +@BUILD_DIR@/scripts/devel_bacula start $1 diff --git a/bacula/scripts/startmysql.in b/bacula/scripts/startmysql.in new file mode 100755 index 0000000000..ee60a5b865 --- /dev/null +++ b/bacula/scripts/startmysql.in @@ -0,0 +1,12 @@ +#!/bin/sh +cd @SQL_BINDIR@ +if [ -x ./safe_mysqld ]; then + ./safe_mysqld & + exit $? +fi +if [ -x ./mysqld_safe ]; then + ./mysqld_safe & + exit $? +fi +echo "Neither safe_mysqld nor mysqld_safe found!" +exit 1 diff --git a/bacula/scripts/stopit.in b/bacula/scripts/stopit.in new file mode 100755 index 0000000000..80503eede4 --- /dev/null +++ b/bacula/scripts/stopit.in @@ -0,0 +1,2 @@ +#!/bin/sh +@BUILD_DIR@/scripts/bacula stop diff --git a/bacula/scripts/stopmysql.in b/bacula/scripts/stopmysql.in new file mode 100755 index 0000000000..9bf117be33 --- /dev/null +++ b/bacula/scripts/stopmysql.in @@ -0,0 +1,2 @@ +#!/bin/sh +@SQL_BINDIR@/mysqladmin shutdown diff --git a/bacula/src/cats/Makefile.in b/bacula/src/cats/Makefile.in index fbdf8801c5..348cd8e0be 100644 --- a/bacula/src/cats/Makefile.in +++ b/bacula/src/cats/Makefile.in @@ -72,11 +72,15 @@ install: $(INSTALL_SCRIPT) create_@DB_NAME@_database $(DESTDIR)$(sysconfdir)/create_@DB_NAME@_database $(INSTALL_SCRIPT) drop_@DB_NAME@_tables $(DESTDIR)$(sysconfdir)/drop_@DB_NAME@_tables $(INSTALL_SCRIPT) make_@DB_NAME@_tables $(DESTDIR)$(sysconfdir)/make_@DB_NAME@_tables + $(INSTALL_SCRIPT) drop_bacula_tables $(DESTDIR)$(sysconfdir)/drop_bacula_tables + $(INSTALL_SCRIPT) make_bacula_tables $(DESTDIR)$(sysconfdir)/make_bacula_tables uninstall: (cd $(DESTDIR)$(sysconfdir); $(RMF) create_@DB_NAME@_database) (cd $(DESTDIR)$(sysconfdir); $(RMF) drop_@DB_NAME@_tables) (cd $(DESTDIR)$(sysconfdir); $(RMF) make_@DB_NAME@_tables) + (cd $(DESTDIR)$(sysconfdir); $(RMF) drop_bacula_tables) + (cd $(DESTDIR)$(sysconfdir); $(RMF) make_bacula_tables) # Semi-automatic generation of dependencies: diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 851e3b2b19..a9d805cb4b 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -49,6 +49,7 @@ int win32_client = 0; static char *configfile = NULL; static int foreground = 0; +static int inetd_request = 0; static workq_t dir_workq; /* queue of work from Director */ CLIENT *me; /* my resource */ @@ -61,6 +62,7 @@ static void usage() " -c use as configuration file\n" " -dnn set debug level to nn\n" " -f run in foreground (for debugging)\n" +" -i inetd request\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -? print this message.\n" @@ -91,7 +93,7 @@ int main (int argc, char *argv[]) memset(&last_job, 0, sizeof(last_job)); - while ((ch = getopt(argc, argv, "c:d:fst?")) != -1) { + while ((ch = getopt(argc, argv, "c:d:fist?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { @@ -111,6 +113,9 @@ int main (int argc, char *argv[]) foreground = TRUE; break; + case 'i': + inetd_request = TRUE; + break; case 's': no_signals = TRUE; break; @@ -182,12 +187,14 @@ Without that I don't know who I am :-(\n"), configfile); terminate_filed(0); } - if (!foreground) { + if (!foreground &&!inetd_request) { daemon_start(); init_stack_dump(); /* set new pid */ } - create_pid_file(me->pid_directory, "bacula-fd", me->FDport); + if (!inetd_request) { + create_pid_file(me->pid_directory, "bacula-fd", me->FDport); + } #ifdef BOMB me += 1000000; @@ -197,11 +204,17 @@ Without that I don't know who I am :-(\n"), configfile); start_watchdog(); /* start watchdog thread */ - /* Become server, and handle requests */ - Dmsg1(10, "filed: listening on port %d\n", me->FDport); - bnet_thread_server(me->FDaddr, me->FDport, me->MaxConcurrentJobs, + if (inetd_request) { + BSOCK *bs = init_bsock(NULL, 0, "client", "unknown client", me->FDport); + handle_client_request((void *)bs); + } else { + /* Become server, and handle requests */ + Dmsg1(10, "filed: listening on port %d\n", me->FDport); + bnet_thread_server(me->FDaddr, me->FDport, me->MaxConcurrentJobs, &dir_workq, handle_client_request); + } + term_msg(); exit(0); /* should never get here */ } diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 3833c2ea5e..5fd610fa34 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -611,7 +611,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) if (bit_is_set(type, d->msg_types)) { switch (d->dest_code) { case MD_CONSOLE: - Dmsg1(200, "CONSOLE for following err: %s\n", msg); + Dmsg1(400, "CONSOLE for following msg: %s", msg); if (!con_fd) { con_fd = fopen(con_fname, "a+"); Dmsg0(200, "Console file not open.\n"); @@ -635,12 +635,12 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) } break; case MD_SYSLOG: - Dmsg1(200, "SYSLOG for following err: %s\n", msg); + Dmsg1(400, "SYSLOG for collowing msg: %s\n", msg); /* We really should do an openlog() here */ syslog(LOG_DAEMON|LOG_ERR, msg); break; case MD_OPERATOR: - Dmsg1(200, "OPERATOR for following err: %s\n", msg); + Dmsg1(400, "OPERATOR for collowing msg: %s\n", msg); mcmd = get_pool_memory(PM_MESSAGE); d->fd = open_mail_pipe(jcr, &mcmd, d); if (d->fd) { @@ -658,7 +658,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) break; case MD_MAIL: case MD_MAIL_ON_ERROR: - Dmsg1(200, "MAIL for following err: %s\n", msg); + Dmsg1(400, "MAIL for following msg: %s", msg); if (!d->fd) { POOLMEM *name = get_pool_memory(PM_MESSAGE); make_unique_mail_filename(jcr, &name, d); @@ -679,7 +679,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) fputs(msg, d->fd); break; case MD_FILE: - Dmsg1(200, "FILE for following err: %s\n", msg); + Dmsg1(400, "FILE for following msg: %s", msg); if (!d->fd) { d->fd = fopen(d->where, "w+"); if (!d->fd) { @@ -692,7 +692,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) fputs(msg, d->fd); break; case MD_APPEND: - Dmsg1(200, "APPEND for following err: %s\n", msg); + Dmsg1(400, "APPEND for following msg: %s", msg); if (!d->fd) { d->fd = fopen(d->where, "a"); if (!d->fd) { @@ -705,7 +705,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) fputs(msg, d->fd); break; case MD_DIRECTOR: - Dmsg1(200, "DIRECTOR for following err: %s\n", msg); + Dmsg1(400, "DIRECTOR for following msg: %s", msg); if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) { jcr->dir_bsock->msglen = Mmsg(&(jcr->dir_bsock->msg), @@ -715,12 +715,12 @@ void dispatch_message(void *vjcr, int type, int level, char *msg) } break; case MD_STDOUT: - Dmsg1(200, "STDOUT for following err: %s\n", msg); + Dmsg1(400, "STDOUT for following msg: %s", msg); if (type != M_ABORT && type != M_ERROR_TERM) /* already printed */ fprintf(stdout, msg); break; case MD_STDERR: - Dmsg1(200, "STDERR for following err: %s\n", msg); + Dmsg1(400, "STDERR for following msg: %s", msg); fprintf(stderr, msg); break; default: diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index 58cec0eb69..9da6927c02 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -72,9 +72,6 @@ int main (int argc, char *argv[]) my_name_is(argc, argv, "bscan"); init_msg(NULL, NULL); - fprintf(stderr, "\n\nPlease don't use this program.\n\ -It is currently under development and does not work.\n\n"); - while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vw:?")) != -1) { switch (ch) { case 'b': diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 8e1b01caaa..5e653f9f15 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -107,6 +107,7 @@ DEV_BLOCK *new_block(DEVICE *dev) memset(block, 0, sizeof(DEV_BLOCK)); + /* If the user has specified a max_block_size, use it as the default */ if (dev->max_block_size == 0) { block->buf_len = DEFAULT_BLOCK_SIZE; } else { @@ -205,12 +206,12 @@ static int unser_block_header(DEVICE *dev, DEV_BLOCK *block) block->BlockVer = 1; block->bufp = block->buf + bhl; if (strncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH) != 0) { - Mmsg2(&dev->errmsg, _("Buffer ID error. Wanted: %s, got %s. Buffer discarded.\n"), + Mmsg2(&dev->errmsg, _("Buffer ID error. Wanted: %s, got %s. Buffer discarded.\n"), BLKHDR1_ID, Id); - Emsg0(M_ERROR, 0, dev->errmsg); - return 0; - } - } else { + Emsg0(M_ERROR, 0, dev->errmsg); + return 0; + } + } else if (Id[3] == '2') { unser_uint32(block->VolSessionId); unser_uint32(block->VolSessionTime); bhl = BLKHDR2_LENGTH; @@ -222,9 +223,19 @@ static int unser_block_header(DEVICE *dev, DEV_BLOCK *block) Emsg0(M_ERROR, 0, dev->errmsg); return 0; } + } else { + Mmsg1(&dev->errmsg, _("Expected block-id BB01 or BB02, got %s. Buffer discarded.\n"), Id); + Emsg0(M_ERROR, 0, dev->errmsg); + return 0; } - ASSERT(block_len < MAX_BLOCK_LENGTH); /* temp sanity check */ + /* Sanity check */ + if (block_len > MAX_BLOCK_LENGTH) { + Mmsg1(&dev->errmsg, _("Block length %u is insane (too large), probably due to a bad archive.\n"), + block_len); + Emsg0(M_ERROR, 0, dev->errmsg); + return 0; + } Dmsg1(190, "unser_block_header block_len=%d\n", block_len); /* Find end of block or end of buffer whichever is smaller */ @@ -238,12 +249,6 @@ static int unser_block_header(DEVICE *dev, DEV_BLOCK *block) block->BlockNumber = BlockNumber; Dmsg3(190, "Read binbuf = %d %d block_len=%d\n", block->binbuf, bhl, block_len); - if (block_len > block->buf_len) { - Mmsg2(&dev->errmsg, _("Block length %u is greater than buffer %u\n"), - block_len, block->buf_len); - Emsg0(M_ERROR, 0, dev->errmsg); - return 0; - } if (block_len <= block->read_len) { BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH, block_len-BLKHDR_CS_LENGTH); @@ -372,7 +377,6 @@ int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block) weof_dev(dev, 1); /* write second eof */ return 0; } -// Dmsg1(000, "Pos after write=%lld\n", lseek(dev->fd, (off_t)0, SEEK_CUR)); dev->VolCatInfo.VolCatBytes += block->binbuf; dev->VolCatInfo.VolCatBlocks++; dev->file_addr += wlen; @@ -415,17 +419,19 @@ int read_block_from_device(DEVICE *dev, DEV_BLOCK *block) int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block) { size_t stat; + int looping; + looping = 0; Dmsg1(100, "Full read() in read_block_from_device() len=%d\n", block->buf_len); -// Dmsg1(000, "Pos before read=%lld\n", lseek(dev->fd, (off_t)0, SEEK_CUR)); +reread: + if (looping > 1) { + Mmsg1(&dev->errmsg, _("Block buffer size looping problem on device %s\n"), + dev->dev_name); + block->read_len = 0; + return 0; + } if ((stat=read(dev->fd, block->buf, (size_t)block->buf_len)) < 0) { - -/* ***FIXME**** add code to detect buffer too small, and - reallocate buffer, backspace, and reread. - ENOMEM - */ - Dmsg1(90, "Read device got: ERR=%s\n", strerror(errno)); clrerror_dev(dev, -1); block->read_len = 0; @@ -433,7 +439,6 @@ int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block) dev->dev_name, strerror(dev->dev_errno)); return 0; } -// Dmsg1(000, "Pos after read=%lld\n", lseek(dev->fd, (off_t)0, SEEK_CUR)); Dmsg1(90, "Read device got %d bytes\n", stat); if (stat == 0) { /* Got EOF ! */ dev->block_num = block->read_len = 0; @@ -455,10 +460,47 @@ int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block) block->read_len = block->binbuf = 0; return 0; /* return error */ } + if (!unser_block_header(dev, block)) { return 0; } + /* + * If the block is bigger than the buffer, we reposition for + * re-reading the block, allocate a buffer of the correct size, + * and go re-read. + */ + if (block->block_len > block->buf_len) { + Mmsg2(&dev->errmsg, _("Block length %u is greater than buffer %u. Attempting recovery.\n"), + block->block_len, block->buf_len); + Emsg0(M_WARNING, 0, dev->errmsg); + Dmsg1(000, "%s", dev->errmsg); + /* Attempt to reposition to re-read the block */ + if (dev->state & ST_TAPE) { + Dmsg0(000, "Backspace record for reread.\n"); + if (bsf_dev(dev, 1) != 0) { + Emsg0(M_ERROR, 0, dev->errmsg); + return 0; + } + } else { + Dmsg0(000, "Seek to beginning of block for reread.\n"); + off_t pos = lseek(dev->fd, (off_t)0, SEEK_CUR); /* get curr pos */ + pos -= block->read_len; + lseek(dev->fd, pos, SEEK_SET); + } + Mmsg1(&dev->errmsg, _("Resetting buffer size to %u bytes.\n"), block->block_len); + Emsg0(M_WARNING, 0, dev->errmsg); + Dmsg1(000, "%s", dev->errmsg); + /* Set new block length */ + dev->max_block_size = block->block_len; + block->buf_len = block->block_len; + free_memory(block->buf); + block->buf = get_memory(block->buf_len); + empty_block(block); + looping++; + goto reread; /* re-read block with correct block size */ + } + if (block->block_len > block->read_len) { Mmsg2(&dev->errmsg, _("Short block of %d bytes on device %s discarded.\n"), block->read_len, dev->dev_name); @@ -467,11 +509,6 @@ int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block) return 0; /* return error */ } - /* Make sure block size is not too big (temporary - * sanity check) and that we read the full block. - */ - ASSERT(block->block_len < MAX_BLOCK_LENGTH); - dev->state &= ~(ST_EOF|ST_SHORT); /* clear EOF and short block */ dev->block_num++; diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index f1b62ab247..4e0e093da4 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -819,6 +819,8 @@ fsr_dev(DEVICE *dev, int num) /* * Backward space a record + * Returns: 0 on success + * -1 on failure */ int bsr_dev(DEVICE *dev, int num) diff --git a/bacula/src/version.h b/bacula/src/version.h index 1478f619a7..1b1094e6d0 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.27" #define VSTRING "1" -#define DATE "02 November 2002" -#define LSMDATE "02Nov02" +#define DATE "08 November 2002" +#define LSMDATE "08Nov02" /* Debug flags */ #define DEBUG 1