From 5c51386a679a8b2a15f6f4ab343c5eb2cb53c125 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 15 Jul 2002 07:58:43 +0000 Subject: [PATCH] Cleanups and AutoChanger code -- kes15Jul02 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@57 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/autoconf/acconfig.h | 10 +- bacula/autoconf/config.h.in | 10 +- bacula/autoconf/configure.in | 18 +- bacula/configure | 415 ++++++++++++++------------------ bacula/src/dird/catreq.c | 45 ++-- bacula/src/dird/ua_select.c | 1 + bacula/src/dird/ua_server.c | 5 +- bacula/src/dird/ua_status.c | 16 +- bacula/src/filed/status.c | 18 +- bacula/src/lib/bnet.c | 2 +- bacula/src/lib/message.c | 26 +- bacula/src/lib/protos.h | 6 + bacula/src/lib/util.c | 55 +++++ bacula/src/stored/askdir.c | 38 ++- bacula/src/stored/bextract.c | 1 + bacula/src/stored/bls.c | 1 + bacula/src/stored/dev.c | 1 + bacula/src/stored/device.c | 359 ++++++++++++++++----------- bacula/src/stored/dircmd.c | 18 +- bacula/src/stored/protos.h | 1 + bacula/src/stored/stored_conf.c | 221 ++++++++--------- bacula/src/stored/stored_conf.h | 9 +- bacula/src/version.h | 4 +- 23 files changed, 684 insertions(+), 596 deletions(-) diff --git a/bacula/autoconf/acconfig.h b/bacula/autoconf/acconfig.h index f442ee25ef..1db4e9353b 100644 --- a/bacula/autoconf/acconfig.h +++ b/bacula/autoconf/acconfig.h @@ -181,10 +181,12 @@ #undef HAVE_FCHDIR -#undef HAVE_LOCALTIME_R - -#undef HAVE_READDIR_R - #undef HAVE_GETOPT_LONG #undef HAVE_LIBSM + +/* Check for thread safe routines */ +#undef HAVE_LOCALTIME_R +#undef HAVE_READDIR_R +#undef HAVE_STRERROR_R +#undef HAVE_GETHOSTBYNAME_R diff --git a/bacula/autoconf/config.h.in b/bacula/autoconf/config.h.in index 4959b611c4..2ce72cd3e2 100644 --- a/bacula/autoconf/config.h.in +++ b/bacula/autoconf/config.h.in @@ -270,10 +270,6 @@ #undef HAVE_FCHDIR -#undef HAVE_LOCALTIME_R - -#undef HAVE_READDIR_R - #undef HAVE_GETOPT_LONG /* The number of bytes in a char. */ @@ -303,6 +299,9 @@ /* Define if you have the getcwd function. */ #undef HAVE_GETCWD +/* Define if you have the gethostbyname_r function. */ +#undef HAVE_GETHOSTBYNAME_R + /* Define if you have the gethostname function. */ #undef HAVE_GETHOSTNAME @@ -354,6 +353,9 @@ /* Define if you have the strerror function. */ #undef HAVE_STRERROR +/* Define if you have the strerror_r function. */ +#undef HAVE_STRERROR_R + /* Define if you have the strncmp function. */ #undef HAVE_STRNCMP diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index bf84950b79..4efb8b3b22 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -933,9 +933,17 @@ AC_CHECK_FUNCS(fchdir, [AC_DEFINE(HAVE_FCHDIR)]) AC_CHECK_FUNCS(snprintf vsnprintf) -AC_CHECK_FUNCS(localtime_r, [AC_DEFINE(HAVE_LOCALTIME_R)]) +dnl# -------------------------------------------------------------------------- +dnl# CHECKING FOR THREAD SAFE FUNCTIONS +dnl# -------------------------------------------------------------------------- +AC_CHECK_FUNCS(localtime_r readdir_r strerror_r gethostbyname_r) + +# If resolver functions are not in libc check for -lnsl or -lresolv. +AC_CHECK_FUNC(gethostbyname_r, + AC_MSG_RESULT(using libc's resolver), + AC_CHECK_LIB(nsl,gethostbyname_r) + AC_CHECK_LIB(resolv,gethostbyname_r)) -AC_CHECK_FUNCS(readdir_r, [AC_DEFINE(HAVE_READDIR_R)]) # Find where sockets are (especially for Solaris) AC_CHECK_FUNC(socket, @@ -944,12 +952,6 @@ AC_CHECK_FUNC(socket, AC_CHECK_LIB(socket,socket) AC_CHECK_LIB(inet,socket)) -# If resolver functions are not in libc check for -lnsl or -lresolv. -AC_CHECK_FUNC(gethostbyname, - AC_MSG_RESULT(using libc's resolver), - AC_CHECK_LIB(nsl,gethostbyname) - AC_CHECK_LIB(resolv,gethostbyname)) - AC_FUNC_STRFTIME AC_FUNC_VPRINTF diff --git a/bacula/configure b/bacula/configure index d2d0104244..f25b9bf983 100755 --- a/bacula/configure +++ b/bacula/configure @@ -7260,7 +7260,7 @@ fi done -for ac_func in localtime_r +for ac_func in localtime_r readdir_r strerror_r gethostbyname_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:7267: checking for $ac_func" >&5 @@ -7309,143 +7309,128 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then cat >> confdefs.h <> confdefs.h <<\EOF -#define HAVE_LOCALTIME_R 1 -EOF - + else echo "$ac_t""no" 1>&6 fi done -for ac_func in readdir_r -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7326: checking for $ac_func" >&5 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then +# If resolver functions are not in libc check for -lnsl or -lresolv. +echo $ac_n "checking for gethostbyname_r""... $ac_c" 1>&6 +echo "configure:7322: checking for gethostbyname_r" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname_r'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char $ac_func(); +char gethostbyname_r(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +#if defined (__stub_gethostbyname_r) || defined (__stub___gethostbyname_r) choke me #else -$ac_func(); +gethostbyname_r(); #endif ; return 0; } EOF -if { (eval echo configure:7354: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7350: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" + eval "ac_cv_func_gethostbyname_r=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_$ac_func=no" + eval "ac_cv_func_gethostbyname_r=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'gethostbyname_r`\" = yes"; then echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <> confdefs.h <<\EOF -#define HAVE_READDIR_R 1 -EOF - + echo "$ac_t""using libc's resolver" 1>&6 else echo "$ac_t""no" 1>&6 -fi -done - - -# Find where sockets are (especially for Solaris) -echo $ac_n "checking for socket""... $ac_c" 1>&6 -echo "configure:7384: checking for socket" >&5 -if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then +echo $ac_n "checking for gethostbyname_r in -lnsl""... $ac_c" 1>&6 +echo "configure:7368: checking for gethostbyname_r in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname_r | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - cat > conftest.$ac_ext < conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char socket(); +char gethostbyname_r(); int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_socket) || defined (__stub___socket) -choke me -#else -socket(); -#endif - +gethostbyname_r() ; return 0; } EOF -if { (eval echo configure:7412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_socket=yes" + eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_socket=no" + eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* -fi +LIBS="$ac_save_LIBS" -if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - echo "$ac_t""using libc's socket" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 -echo $ac_n "checking for socket in -lxnet""... $ac_c" 1>&6 -echo "configure:7430: checking for socket in -lxnet" >&5 -ac_lib_var=`echo xnet'_'socket | sed 'y%./+-%__p_%'` +fi + + echo $ac_n "checking for gethostbyname_r in -lresolv""... $ac_c" 1>&6 +echo "configure:7415: checking for gethostbyname_r in -lresolv" >&5 +ac_lib_var=`echo resolv'_'gethostbyname_r | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" -LIBS="-lxnet $LIBS" +LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7460,75 +7445,79 @@ LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo xnet | sed -e 's/^a-zA-Z0-9_/_/g' \ + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi - echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 -echo "configure:7477: checking for socket in -lsocket" >&5 -ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then +fi + + + +# Find where sockets are (especially for Solaris) +echo $ac_n "checking for socket""... $ac_c" 1>&6 +echo "configure:7467: checking for socket" >&5 +if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - ac_save_LIBS="$LIBS" -LIBS="-lsocket $LIBS" -cat > conftest.$ac_ext < conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { -socket() + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_socket) || defined (__stub___socket) +choke me +#else +socket(); +#endif + ; return 0; } EOF -if { (eval echo configure:7496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" + eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" + eval "ac_cv_func_socket=no" fi rm -f conftest* -LIBS="$ac_save_LIBS" - fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ - -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` - cat >> confdefs.h <&6 + echo "$ac_t""using libc's socket" 1>&6 else echo "$ac_t""no" 1>&6 -fi - - echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 -echo "configure:7524: checking for socket in -linet" >&5 -ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` +echo $ac_n "checking for socket in -lxnet""... $ac_c" 1>&6 +echo "configure:7513: checking for socket in -lxnet" >&5 +ac_lib_var=`echo xnet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" -LIBS="-linet $LIBS" +LIBS="-lxnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7554,89 +7543,39 @@ LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/^a-zA-Z0-9_/_/g' \ + ac_tr_lib=HAVE_LIB`echo xnet | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi -fi - - -# If resolver functions are not in libc check for -lnsl or -lresolv. -echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:7575: checking for gethostbyname" >&5 -if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gethostbyname(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) -choke me -#else -gethostbyname(); -#endif - -; return 0; } -EOF -if { (eval echo configure:7603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_gethostbyname=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_gethostbyname=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then - echo "$ac_t""yes" 1>&6 - echo "$ac_t""using libc's resolver" 1>&6 -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 -echo "configure:7621: checking for gethostbyname in -lnsl" >&5 -ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` + echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:7560: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" -LIBS="-lnsl $LIBS" +LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7651,39 +7590,39 @@ LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \ + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi - echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6 -echo "configure:7668: checking for gethostbyname in -lresolv" >&5 -ac_lib_var=`echo resolv'_'gethostbyname | sed 'y%./+-%__p_%'` + echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 +echo "configure:7607: checking for socket in -linet" >&5 +ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" -LIBS="-lresolv $LIBS" +LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7698,13 +7637,13 @@ LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/^a-zA-Z0-9_/_/g' \ + ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 @@ -7715,12 +7654,12 @@ fi echo $ac_n "checking for strftime""... $ac_c" 1>&6 -echo "configure:7719: checking for strftime" >&5 +echo "configure:7658: checking for strftime" >&5 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7686: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strftime=yes" else @@ -7765,7 +7704,7 @@ else echo "$ac_t""no" 1>&6 # strftime is in -lintl on SCO UNIX. echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 -echo "configure:7769: checking for strftime in -lintl" >&5 +echo "configure:7708: checking for strftime in -lintl" >&5 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7773,7 +7712,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7811,12 +7750,12 @@ fi fi echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:7815: checking for vprintf" >&5 +echo "configure:7754: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -7863,12 +7802,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:7867: checking for _doprnt" >&5 +echo "configure:7806: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -7918,19 +7857,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:7922: checking for working alloca.h" >&5 +echo "configure:7861: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:7934: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -7951,12 +7890,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:7955: checking for alloca" >&5 +echo "configure:7894: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -8016,12 +7955,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:8020: checking whether alloca needs Cray hooks" >&5 +echo "configure:7959: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8050: checking for $ac_func" >&5 +echo "configure:7989: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8101,7 +8040,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:8105: checking stack direction for C alloca" >&5 +echo "configure:8044: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8109,7 +8048,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8071: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -8151,7 +8090,7 @@ fi # getmntent is in -lsun on Irix 4, -lseq on Dynix/PTX, -lgen on Unixware. echo $ac_n "checking for getmntent in -lsun""... $ac_c" 1>&6 -echo "configure:8155: checking for getmntent in -lsun" >&5 +echo "configure:8094: checking for getmntent in -lsun" >&5 ac_lib_var=`echo sun'_'getmntent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8159,7 +8098,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsun $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8189,7 +8128,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getmntent in -lseq""... $ac_c" 1>&6 -echo "configure:8193: checking for getmntent in -lseq" >&5 +echo "configure:8132: checking for getmntent in -lseq" >&5 ac_lib_var=`echo seq'_'getmntent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8197,7 +8136,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8227,7 +8166,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for getmntent in -lgen""... $ac_c" 1>&6 -echo "configure:8231: checking for getmntent in -lgen" >&5 +echo "configure:8170: checking for getmntent in -lgen" >&5 ac_lib_var=`echo gen'_'getmntent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8235,7 +8174,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgen $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8271,12 +8210,12 @@ fi fi echo $ac_n "checking for getmntent""... $ac_c" 1>&6 -echo "configure:8275: checking for getmntent" >&5 +echo "configure:8214: checking for getmntent" >&5 if eval "test \"`echo '$''{'ac_cv_func_getmntent'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getmntent=yes" else @@ -8322,7 +8261,7 @@ else fi echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6 -echo "configure:8326: checking whether closedir returns void" >&5 +echo "configure:8265: checking whether closedir returns void" >&5 if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8330,13 +8269,13 @@ else ac_cv_func_closedir_void=yes else cat > conftest.$ac_ext < #include <$ac_header_dirent> int closedir(); main() { exit(closedir(opendir(".")) != 0); } EOF -if { (eval echo configure:8340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_closedir_void=no else @@ -8359,7 +8298,7 @@ EOF fi echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6 -echo "configure:8363: checking whether setpgrp takes no argument" >&5 +echo "configure:8302: checking whether setpgrp takes no argument" >&5 if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8367,7 +8306,7 @@ else { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_setpgrp_void=no else @@ -8410,7 +8349,7 @@ EOF fi echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6 -echo "configure:8414: checking for working fnmatch" >&5 +echo "configure:8353: checking for working fnmatch" >&5 if eval "test \"`echo '$''{'ac_cv_func_fnmatch_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8421,11 +8360,11 @@ if test "$cross_compiling" = yes; then ac_cv_func_fnmatch_works=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_fnmatch_works=yes else @@ -8450,7 +8389,7 @@ fi echo $ac_n "checking for setlocale in -lxpg4""... $ac_c" 1>&6 -echo "configure:8454: checking for setlocale in -lxpg4" >&5 +echo "configure:8393: checking for setlocale in -lxpg4" >&5 ac_lib_var=`echo xpg4'_'setlocale | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8458,7 +8397,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lxpg4 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8492,7 +8431,7 @@ fi echo $ac_n "checking for getpwnam in -lsun""... $ac_c" 1>&6 -echo "configure:8496: checking for getpwnam in -lsun" >&5 +echo "configure:8435: checking for getpwnam in -lsun" >&5 ac_lib_var=`echo sun'_'getpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8500,7 +8439,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsun $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8454: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8539,7 +8478,7 @@ else fi echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 -echo "configure:8543: checking for deflate in -lz" >&5 +echo "configure:8482: checking for deflate in -lz" >&5 ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8547,7 +8486,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lz $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8501: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8589,7 +8528,7 @@ fi PTHREAD_LIB="" echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 -echo "configure:8593: checking for pthread_create in -lpthread" >&5 +echo "configure:8532: checking for pthread_create in -lpthread" >&5 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8597,7 +8536,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8627,7 +8566,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6 -echo "configure:8631: checking for pthread_create in -lpthreads" >&5 +echo "configure:8570: checking for pthread_create in -lpthreads" >&5 ac_lib_var=`echo pthreads'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8635,7 +8574,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthreads $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8665,7 +8604,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6 -echo "configure:8669: checking for pthread_create in -lc_r" >&5 +echo "configure:8608: checking for pthread_create in -lc_r" >&5 ac_lib_var=`echo c_r'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8673,7 +8612,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc_r $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8703,12 +8642,12 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for pthread_create""... $ac_c" 1>&6 -echo "configure:8707: checking for pthread_create" >&5 +echo "configure:8646: checking for pthread_create" >&5 if eval "test \"`echo '$''{'ac_cv_func_pthread_create'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_pthread_create=yes" else diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 6aae9dbabc..2a249361e1 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -50,6 +50,11 @@ static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s\ FirstIndex=%d LastIndex=%d StartFile=%d EndFile=%d \ StartBlock=%d EndBlock=%d relabel=%d Slot=%d\n"; +static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia \ + FirstIndex=%d LastIndex=%d StartFile=%d EndFile=%d \ + StartBlock=%d EndBlock=%d\n"; + + /* Responses sent to Storage daemon */ static char OK_media[] = "1000 OK VolName=%s VolJobs=%d VolFiles=%d\ VolBlocks=%d VolBytes=%" lld " VolMounts=%d VolErrors=%d VolWrites=%d\ @@ -172,25 +177,6 @@ MediaType=%s\n", mr.PoolId, jcr->PoolId, mr.VolStatus, mr.MediaType); strcpy(mr.VolStatus, "Full"); } - jm.JobId = jcr->JobId; - jm.MediaId = jcr->MediaId; - /* - * If relabel is set, it means we just labeled the tape, - * so no need to create a jobmedia record. - * Otherwise, record the fact that this job used this Volume - */ - if (!relabel) { - Dmsg6(100, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n", - jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); - if(!db_create_jobmedia_record(jcr->db, &jm)) { - Jmsg(jcr, M_ERROR, 0, _("Catalog error creating JobMedia record. %s"), - db_strerror(jcr->db)); - bnet_fsend(bs, "1991 Update JobMedia error\n"); - } else { - Dmsg0(20, "JobMedia record created\n"); - } - } - Dmsg0(20, "db_update_media_record\n"); if (db_update_media_record(jcr->db, &mr)) { bnet_fsend(bs, OK_update); @@ -201,6 +187,27 @@ MediaType=%s\n", mr.PoolId, jcr->PoolId, mr.VolStatus, mr.MediaType); bnet_fsend(bs, "1992 Update Media error\n"); Dmsg0(90, "send error\n"); } + + /* + * Request to create a JobMedia record + */ + } else if (sscanf(bs->msg, Create_job_media, &Job, + &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile, + &jm.StartBlock, &jm.EndBlock) == 7) { + + jm.JobId = jcr->JobId; + jm.MediaId = jcr->MediaId; + Dmsg6(100, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n", + jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); + if(!db_create_jobmedia_record(jcr->db, &jm)) { + Jmsg(jcr, M_ERROR, 0, _("Catalog error creating JobMedia record. %s"), + db_strerror(jcr->db)); + bnet_fsend(bs, "1991 Update JobMedia error\n"); + } else { + Dmsg0(20, "JobMedia record created\n"); + bnet_fsend(bs, OK_update); + } + } else { omsg = (char *) get_memory(bs->msglen+1); strcpy(omsg, bs->msg); diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 12ac318d3d..db1477e802 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -524,6 +524,7 @@ int do_prompt(UAContext *ua, char *msg, char *prompt) /* Either a . or an @ will get you out of the loop */ if (!get_cmd(ua, pmsg) || *ua->cmd == '.' || *ua->cmd == '@') { item = -1; /* error */ + bsendmsg(ua, _("Selection aborted, nothing done.\n")); break; } item = atoi(ua->cmd); diff --git a/bacula/src/dird/ua_server.c b/bacula/src/dird/ua_server.c index 5e67d27923..861b92024d 100644 --- a/bacula/src/dird/ua_server.c +++ b/bacula/src/dird/ua_server.c @@ -117,6 +117,7 @@ static void handle_UA_client_request(void *arg) while (!ua.quit) { stat = bnet_recv(ua.UA_sock); + Dmsg1(500, "stat=%d\n", stat); if (stat > 0) { strncpy(cmd, ua.UA_sock->msg, sizeof(cmd)); cmd[sizeof(cmd)-1] = 0; /* ensure it is terminated/trucated */ @@ -138,10 +139,12 @@ static void handle_UA_client_request(void *arg) bnet_sig(ua.UA_sock, BNET_EOD); /* send end of command */ } } else if (stat == 0) { - if (ua.UA_sock->msglen == BNET_TERMINATE) { + if (ua.UA_sock->msglen == BNET_TERMINATE || + ua.UA_sock->msglen == BNET_EOF) { ua.quit = TRUE; break; } + Dmsg1(000, "stat=0 msglen=%d\n", ua.UA_sock->msglen); bnet_sig(ua.UA_sock, BNET_POLL); } else { break; /* error, exit */ diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 6d287c9d04..9e5aece000 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -203,23 +203,11 @@ static void do_director_status(UAContext *ua, char *cmd) bsendmsg(ua, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs, last_job.NumJobs == 1 ? "" : "s"); if (last_job.NumJobs > 0) { - char *termstat, jstat[2]; + char termstat[30]; bstrftime(dt, sizeof(dt), last_job.end_time); bsendmsg(ua, _("Last Job %s finished at %s\n"), last_job.Job, dt); - switch (last_job.JobStatus) { - case JS_Terminated: - termstat = _("OK"); - break; - case JS_ErrorTerminated: - termstat = _("Error"); - break; - default: - jstat[0] = last_job.JobStatus; - jstat[1] = 0; - termstat = jstat; - break; - } + jobstatus_to_ascii(last_job.JobStatus, termstat, sizeof(termstat)); bsendmsg(ua, _(" Files=%s Bytes=%s Termination Status=%s\n"), edit_uint64_with_commas(last_job.JobFiles, b1), diff --git a/bacula/src/filed/status.c b/bacula/src/filed/status.c index 91e6e92876..b14c7d8403 100755 --- a/bacula/src/filed/status.c +++ b/bacula/src/filed/status.c @@ -53,25 +53,13 @@ static void do_status(void sendit(char *msg, int len, void *sarg), void *arg) last_job.NumJobs == 1 ? "" : "s"); sendit(msg, len, arg); if (last_job.NumJobs > 0) { - char *termstat, jstat[2]; + char termstat[30]; bstrftime(dt, sizeof(dt), last_job.end_time); len = Mmsg(&msg, _("Last Job %s finished at %s\n"), last_job.Job, dt); sendit(msg, len, arg); - switch (last_job.JobStatus) { - case JS_Terminated: - termstat = "OK"; - break; - case JS_ErrorTerminated: - termstat = "Error"; - break; - default: - jstat[0] = last_job.JobStatus; - jstat[1] = 0; - termstat = jstat; - break; - } - + + jobstatus_to_ascii(last_job.JobStatus, termstat, sizeof(termstat)); len = Mmsg(&msg, _(" Files=%s Bytes=%s Termination Status=%s\n"), edit_uint64_with_commas(last_job.JobFiles, b1), edit_uint64_with_commas(last_job.JobBytes, b2), diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 8a9e398b40..8915ccecc1 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -616,7 +616,7 @@ bnet_close(BSOCK *bsock) for ( ; bsock != NULL; bsock = next) { next = bsock->next; if (!bsock->duped) { - shutdown(bsock->fd, SHUT_RDWR); +// shutdown(bsock->fd, SHUT_RDWR); close(bsock->fd); term_bsock(bsock); } else { diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 177aadb799..1408e31b47 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -156,7 +156,7 @@ init_msg(void *vjcr, MSGS *msg) /* * Walk down the message resource chain duplicating it - * for the current Job. + * for the current Job. ****FIXME***** segfault on memcpy */ for (d=msg->dest_chain; d; d=d->next) { dnew = (DEST *)malloc(sizeof(DEST)); @@ -278,23 +278,6 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where) } } -/* - * Concatenate a string (str) onto a message (msg) - * return new message pointer - */ -static void add_str(POOLMEM **base, char **msg, char *str) -{ - int len = strlen(str) + 1; - char *b, *m; - - b = *base; - *base = check_pool_memory_size(*base, len); - m = *base - b + *msg; - while (*str) { - *m++ = *str++; - } - *msg = m; -} /* * Convert Job Termination Status into a string @@ -405,6 +388,11 @@ static char *job_level_to_str(int level) * %c = Client's name * %r = Recipients * %d = Director's name + * + * omsg = edited output message + * imsg = input string containing edit codes (%x) + * to = recepients list + * */ static char *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to) { @@ -458,7 +446,7 @@ static char *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to) str = add; } Dmsg1(200, "add_str %s\n", str); - add_str(&omsg, &o, str); + add_str_to_pool_mem(&omsg, &o, str); *o = 0; Dmsg1(200, "omsg=%s\n", omsg); } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 37c0f188df..65b2d8247e 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -43,6 +43,10 @@ int bvsnprintf (char *str, size_t size, const char *format, v int pool_sprintf (char *pool_buf, char *fmt, ...); void create_pid_file (char *dir, char *progname, int port); int delete_pid_file (char *dir, char *progname, int port); +#ifndef HAVE_STRERROR_R +int strerror_r (int errnum, char *buf, size_t bufsiz); +#endif + /* bnet.c */ int32_t bnet_recv (BSOCK *bsock); @@ -145,6 +149,8 @@ int do_shell_expansion (char *name); int is_a_number (const char *num); int string_to_btime (char *str, btime_t *value); char *edit_btime (btime_t val, char *buf); +void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); +void add_str_to_pool_mem (POOLMEM **base, char **msg, char *str); /* diff --git a/bacula/src/lib/util.c b/bacula/src/lib/util.c index 611903dcd2..0d467d7c54 100644 --- a/bacula/src/lib/util.c +++ b/bacula/src/lib/util.c @@ -27,6 +27,7 @@ */ #include "bacula.h" +#include "jcr.h" #include "findlib/find.h" /* @@ -321,6 +322,60 @@ char *encode_time(time_t time, char *buf) return buf+n; } +/* + * Concatenate a string (str) onto a poolmem message (msg) + * return new message pointer. The base of the pool memory + * is base. + */ +void add_str_to_pool_mem(POOLMEM **base, char **msg, char *str) +{ + int len = strlen(str) + 1; + char *b, *m; + + b = *base; + *base = check_pool_memory_size(*base, len); + m = *base - b + *msg; + while (*str) { + *m++ = *str++; + } + *msg = m; +} + + +/* + * Convert a JobStatus code into a human readable form + */ +void jobstatus_to_ascii(int JobStatus, char *msg, int maxlen) +{ + char *termstat, jstat[2]; + + switch (JobStatus) { + case JS_Terminated: + termstat = _("OK"); + break; + case JS_FatalError: + case JS_ErrorTerminated: + termstat = _("Error"); + break; + case JS_Error: + termstat = _("Non-fatal error"); + break; + case JS_Cancelled: + termstat = _("Cancelled"); + break; + case JS_Differences: + termstat = _("Verify differences"); + break; + default: + jstat[0] = last_job.JobStatus; + jstat[1] = 0; + termstat = jstat; + break; + } + strncpy(msg, termstat, maxlen); + msg[maxlen-1] = 0; +} + /*********************************************************************** * Encode the mode bits into a 10 character string like LS does ***********************************************************************/ diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 2d88d1e367..78f7f1840d 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -39,6 +39,11 @@ static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s\ FirstIndex=%d LastIndex=%d StartFile=%d EndFile=%d \ StartBlock=%d EndBlock=%d relabel=%d Slot=%d\n"; +static char Create_job_media[] = "CatReq Job=%s CreateJobMedia \ + FirstIndex=%d LastIndex=%d StartFile=%d EndFile=%d \ + StartBlock=%d EndBlock=%d\n"; + + static char FileAttributes[] = "UpdCat Job=%s FileAttributes "; static char Job_status[] = "3012 Job %s jobstatus %d\n"; @@ -173,6 +178,32 @@ int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) return 1; } +/* + * After writing a Volume, create the JobMedia record. + */ +int dir_create_job_media_record(JCR *jcr) +{ + BSOCK *dir = jcr->dir_bsock; + + bnet_fsend(dir, Create_job_media, jcr->Job, + jcr->VolFirstFile, jcr->JobFiles, + jcr->start_file, jcr->end_file, + jcr->start_block, jcr->end_block); + Dmsg1(20, "create_job_media(): %s", dir->msg); + if (bnet_recv(dir) <= 0) { + Dmsg0(90, "create_jobmedia error bnet_recv\n"); + return 0; + } + Dmsg1(20, "Create_jobmedia: %s", dir->msg); + if (strcmp(dir->msg, OK_update) != 0) { + Dmsg1(30, "Bad response from Dir: %s\n", dir->msg); + Jmsg(jcr, M_ERROR, 0, _("Error creating JobMedia record: %s\n"), dir->msg); + return 0; + } + return 1; +} + + /* * Update File Attribute data */ @@ -208,6 +239,10 @@ int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) * On success, jcr->VolumeName and jcr->VolCatInfo contain * information on suggested volume, but this may not be the * same as what is actually mounted. + * + * When we return with success, the correct tape may or may not + * actually be mounted. The calling routine must read it and + * verify the label. */ int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { @@ -232,6 +267,7 @@ int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) if (job_cancelled(jcr)) { Mmsg(&dev->errmsg, _("Job %s cancelled while waiting for mount on Storage Device \"%s\".\n"), jcr->Job, jcr->dev_name); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); return 0; } if (dir_find_next_appendable_volume(jcr)) { /* get suggested volume */ @@ -317,7 +353,7 @@ Use \"mount\" to resume the job.\n"), return 0; } if (stat != 0) { - Jmsg(jcr, M_ERROR, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat, + Jmsg(jcr, M_WARNING, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat, strerror(stat)); } Dmsg1(90, "Someone woke me for device %s\n", dev->dev_name); diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index d6a4e5d907..c7e8206ab7 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -549,6 +549,7 @@ static void print_ls_output(char *fname, char *link, int type, struct stat *stat int dir_get_volume_info(JCR *jcr) { return 1;} int dir_find_next_appendable_volume(JCR *jcr) { return 1;} int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; } +int dir_create_job_media_record(JCR *jcr) { return 1; } int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; } int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;} int dir_send_job_status(JCR *jcr) {return 1;} diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 26bd627065..9d5f498ba3 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -535,6 +535,7 @@ static void print_ls_output(char *fname, char *link, int type, struct stat *stat int dir_get_volume_info(JCR *jcr) { return 1;} int dir_find_next_appendable_volume(JCR *jcr) { return 1;} int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; } +int dir_create_job_media_record(JCR *jcr) { return 1; } int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; } int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;} int dir_send_job_status(JCR *jcr) {return 1;} diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 6dafcc8973..207637983a 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -579,6 +579,7 @@ int offline_dev(DEVICE *dev) dev->dev_name, strerror(dev->dev_errno)); return 0; } + Dmsg1(000, "Offlined device %s\n", dev->dev_name); return 1; } diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 80e55fb1b4..20abc6c493 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -52,8 +52,7 @@ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ -static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -static int mount_next_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *label_blk); +static int mount_next_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *label_blk, int release); extern char my_name[]; extern int debug_level; @@ -96,36 +95,14 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) */ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { + int release = 0; + int do_mount = 0; lock_device(dev); Dmsg1(90, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk"); - if (!(dev->state & ST_APPEND)) { - if (dev->state & ST_READ) { - Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev)); - unlock_device(dev); - return 0; - } - ASSERT(dev->num_writers == 0); - block_device(dev, BST_DOING_ACQUIRE); - unlock_device(dev); - if (!ready_dev_for_append(jcr, dev, block)) { - Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"), - dev_name(dev)); - P(dev->mutex); - unblock_device(dev); - V(dev->mutex); - return 0; - } - P(dev->mutex); - dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on this media */ - dev->num_writers = 1; - if (jcr->NumVolumes == 0) { - jcr->NumVolumes = 1; - } - unblock_device(dev); - V(dev->mutex); - return 1; - } else { + + + if (dev->state & ST_APPEND) { /* * Device already in append mode * @@ -145,21 +122,36 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) unlock_device(dev); return 0; } - /* Wrong tape currently mounted */ - block_device(dev, BST_DOING_ACQUIRE); + /* Wrong tape mounted, release it, then fall through to get correct one */ + release = 1; + do_mount = 1; + } + } else { + /* Not already in append mode, so mount the device */ + if (dev->state & ST_READ) { + Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev)); unlock_device(dev); - if (!mount_next_volume(jcr, dev, block)) { - Jmsg(jcr, M_FATAL, 0, _("Unable to mount desired volume.\n")); - P(dev->mutex); - unblock_device(dev); - V(dev->mutex); - return 0; - } + return 0; + } + ASSERT(dev->num_writers == 0); + do_mount = 1; + } + + if (do_mount) { + block_device(dev, BST_DOING_ACQUIRE); + unlock_device(dev); + if (!mount_next_volume(jcr, dev, block, release)) { + Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"), + dev_name(dev)); P(dev->mutex); unblock_device(dev); + unlock_device(dev); + return 0; } + P(dev->mutex); + unblock_device(dev); } - dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on this media */ + dev->num_writers++; if (dev->num_writers > 1) { Dmsg2(0, "Hey!!!! There are %d writers on device %s\n", dev->num_writers, @@ -193,6 +185,7 @@ int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Dmsg1(90, "There are %d writers in release_device\n", dev->num_writers); if (dev->num_writers == 0) { weof_dev(dev, 1); + dir_create_job_media_record(jcr); dev->VolCatInfo.VolCatFiles++; /* increment number of files */ /* Note! do volume update before close, which zaps VolCatInfo */ dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */ @@ -202,6 +195,7 @@ int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Dmsg0(90, "Device is tape leave open in release_device\n"); } } else { + dir_create_job_media_record(jcr); dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */ } } else { @@ -214,101 +208,87 @@ int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) /* - * We rewind the current volume, which we no longer want, and - * ask the user (console) to mount the next volume. + * If release is set, we rewind the current volume, + * which we no longer want, and ask the user (console) + * to mount the next volume. * - * Continue trying until we get it, and we call - * ready_dev_for_append() so that we can write on it. + * Continue trying until we get it, and then ensure + * that we can write on it. * - * This routine retuns a 0 only if it is REALLY + * This routine returns a 0 only if it is REALLY * impossible to get the requested Volume. */ -static int mount_next_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *label_blk) +static int mount_next_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release) { - Dmsg0(90, "Enter mount_next_volume()\n"); - - /* - * First erase all memory of the current volume - */ - dev->block_num = 0; - dev->file = 0; - dev->LastBlockNumWritten = 0; - memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); - memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); + int recycle, ask; - /* Keep trying until we get something good mounted */ - for ( ;; ) { - if (job_cancelled(jcr)) { - Mmsg0(&dev->errmsg, "Job cancelled.\n"); - return 0; - } - - if (dev->state & ST_OPENED && !rewind_dev(dev)) { - Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - } + Dmsg0(90, "Enter mount_next_volume()\n"); - /* - * Ask to mount and wait if necessary +mount_next_vol: + if (job_cancelled(jcr)) { + Mmsg0(&dev->errmsg, _("Job cancelled.\n")); + return 0; + } + recycle = 0; + ask = 0; + if (release) { + Dmsg0(500, "mount_next_volume release=1\n"); + /* + * First erase all memory of the current volume */ - if (!dir_ask_sysop_to_mount_next_volume(jcr, dev)) { - Jmsg(jcr, M_FATAL, 0, _("Unable to mount next Volume on device %s\n"), - dev_name(dev)); - return 0; + dev->block_num = 0; + dev->file = 0; + dev->LastBlockNumWritten = 0; + memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); + memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); + dev->state &= ~ST_LABEL; /* label not yet read */ + + /* Rewind device */ + if (dev->state & ST_OPENED) { + if (!rewind_dev(dev)) { + Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + } } - + ask = 1; /* ask operator to mount tape */ + } else { /* - * Ready output device for writing + * Get Director's idea of what tape we should have mounted. */ - Dmsg1(120, "just before ready_dev_for_append dev=%x\n", dev); - if (!ready_dev_for_append(jcr, dev, label_blk)) { - continue; + if (!dir_find_next_appendable_volume(jcr)) { + ask = 1; /* we must ask */ } - dev->VolCatInfo.VolCatMounts++; - jcr->VolFirstFile = 0; - break; /* Got new volume, continue */ } - return 1; -} + release = 1; /* release if we "recurse" */ - -/* - * This routine ensures that the device is ready for - * writing. We start from the assumption that there - * may not be a tape mounted. - * - * If the device is a file, we create the output - * file. If it is a tape, we check the volume name - * and move the tape to the end of data. - * - * It assumes that the device is not already in use! - * - * Returns 0 on failure - * Returns 1 on success - */ -static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) -{ - int mounted = 0; - int recycle = 0; + /* + * Get next volume and ready it for append + * This code ensures that the device is ready for + * writing. We start from the assumption that there + * may not be a tape mounted. + * + * If the device is a file, we create the output + * file. If it is a tape, we check the volume name + * and move the tape to the end of data. + * + * It assumes that the device is not already in use! + * + */ Dmsg0(100, "Enter ready_dev_for_append\n"); - dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF); - + dev->state &= ~(ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF); + jcr->VolFirstFile = 0; /* first update of Vol FileIndex */ for ( ;; ) { - if (job_cancelled(jcr)) { - Mmsg(&dev->errmsg, "Job %s cancelled.\n", jcr->Job); - return 0; - } - /* - * Ask Director for Volume Info (Name, attributes) to use. - */ - if (!dir_find_next_appendable_volume(jcr)) { + Dmsg1(000, "Have changer. Dev=%s\n", NPRT(jcr->device->changer_name)); + if (ask) { + if (dev->capabilities && CAP_AUTOCHANGER) { + Dmsg1(000, "Have changer. Dev=%s\n", NPRT(jcr->device->changer_name)); + /*** ****FIXME**** add changer code here */ + } if (!dir_ask_sysop_to_mount_next_volume(jcr, dev)) { - Jmsg1(jcr, M_FATAL, 0, _("Unable to mount desired Volume for device %s.\n"), - dev_name(dev)); return 0; /* error return */ } } @@ -320,7 +300,7 @@ static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (dev->dev_errno == EAGAIN || dev->dev_errno == EBUSY) { sleep(30); } - Jmsg2(jcr, M_ERROR, 0, _("Unable to open device %s. ERR=%s\n"), + Jmsg2(jcr, M_FATAL, 0, _("Unable to open device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); return 0; } @@ -329,19 +309,20 @@ static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) /* * Now make sure we have the right tape mounted */ +read_volume: switch (read_dev_volume_label(jcr, dev, block)) { case VOL_OK: - Dmsg1(200, "Vol OK name=%s\n", jcr->VolumeName); + Dmsg1(500, "Vol OK name=%s\n", jcr->VolumeName); memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); if (strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0) { recycle = 1; } break; /* got it */ case VOL_NAME_ERROR: + Dmsg1(500, "Vol NAME Error Name=%s\n", jcr->VolumeName); /* Check if we can accept this as an anonymous volume */ strcpy(jcr->VolumeName, dev->VolHdr.VolName); - if (!dev->capabilities & CAP_ANONVOLS || - !dir_get_volume_info(jcr)) { + if (!dev->capabilities & CAP_ANONVOLS || !dir_get_volume_info(jcr)) { goto mount_next_vol; } Dmsg1(200, "want new name=%s\n", jcr->VolumeName); @@ -350,37 +331,26 @@ static int ready_dev_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) case VOL_NO_LABEL: case VOL_IO_ERROR: + Dmsg1(500, "Vol NO_LABEL or IO_ERROR name=%s\n", jcr->VolumeName); /* If permitted, create a label */ if (dev->capabilities & CAP_LABEL) { Dmsg0(90, "Create volume label\n"); if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName, jcr->pool_name)) { - return 0; + goto mount_next_vol; } Jmsg(jcr, M_INFO, 0, _("Created Volume label %s on device %s.\n"), jcr->VolumeName, dev_name(dev)); - mounted = 1; - continue; /* read label we just wrote */ + goto read_volume; /* read label we just wrote */ } /* NOTE! Fall-through wanted. */ default: -mount_next_vol: - /* Send error message generated by read_dev_volume_label() */ + /* Send error message */ Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); - rewind_dev(dev); - if (!dir_ask_sysop_to_mount_next_volume(jcr, dev)) { - Jmsg1(jcr, M_FATAL, 0, _("Unable to mount desired Volume for device %s.\n"), - dev_name(dev)); - return 0; /* error return */ - } - mounted = 1; - continue; /* try reading again */ + goto mount_next_vol; } break; } - if (mounted) { - dev->VolCatInfo.VolCatMounts++; - } /* * See if we have a fresh tape or tape with data. @@ -417,12 +387,12 @@ mount_next_vol: if (!write_block_to_dev(dev, block)) { Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); - return 0; + goto mount_next_vol; } if (!rewind_dev(dev)) { Jmsg2(jcr, M_ERROR, 0, _("Unable to rewind device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); - return 0; + goto mount_next_vol; } /* Recreate a correct volume label and return it in the block */ write_volume_label_to_block(jcr, dev, block); @@ -450,8 +420,10 @@ mount_next_vol: } } else { - /* OK, at this point, we have a valid Bacula label, but - * we need to position to the end of the volume. + /* + * OK, at this point, we have a valid Bacula label, but + * we need to position to the end of the volume, since we are + * just now putting it into append mode. */ Dmsg0(20, "Device previously written, moving to end of data\n"); Jmsg(jcr, M_INFO, 0, _("Volume %s previously written, moving to end of data.\n"), @@ -463,16 +435,24 @@ mount_next_vol: jcr->VolumeName); strcpy(dev->VolCatInfo.VolCatStatus, "Error"); dir_update_volume_info(jcr, &dev->VolCatInfo, 0); - return 0; + goto mount_next_vol; } - /* *****FIXME**** we might do some checking for files too */ + /* *****FIXME**** we should do some checking for files too */ if (dev_is_tape(dev)) { Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume at file=%d.\n"), dev_file(dev)); + /* + * Check if we are positioned on the tape at the same place + * that the database says we should be. + */ if (dev->VolCatInfo.VolCatFiles != dev_file(dev) + 1) { /* ****FIXME**** this should refuse to write on tape */ - Jmsg(jcr, M_INFO, 0, _("Hey! Num files mismatch! Catalog Files=%d\n"), dev->VolCatInfo.VolCatFiles); + Jmsg(jcr, M_ERROR, 0, _("Hey! Num files mismatch! Volume=%d Catalog=%d\n"), + dev_file(dev)+1, dev->VolCatInfo.VolCatFiles); } } + /* Update Volume Info -- will be written at end of Job */ + dev->VolCatInfo.VolCatMounts++; /* Update mounts */ + dev->VolCatInfo.VolCatJobs++; /* Return an empty block */ empty_block(block); /* we used it for reading so set for write */ } @@ -520,6 +500,7 @@ int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); } + /* Mount a specific volume and no other */ if (!dir_ask_sysop_to_mount_volume(jcr, dev)) { return 0; /* error return */ } @@ -565,7 +546,12 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) /* Update position counters */ jcr->end_block = dev->block_num; jcr->end_file = dev->file; - if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) { /* send Volume info to Director */ + /* + * ****FIXME**** update JobMedia record of every job using + * this device + */ + if (!dir_create_job_media_record(jcr) || + !dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) { /* send Volume info to Director */ Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"), dev->VolCatInfo.VolCatName, jcr->Job); return 0; /* device locked */ @@ -588,7 +574,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) /* Unlock, but leave BLOCKED */ unlock_device(dev); - if (!mount_next_volume(jcr, dev, label_blk)) { + if (!mount_next_volume(jcr, dev, label_blk, 1)) { P(dev->mutex); unblock_device(dev); return 0; /* device locked */ @@ -742,3 +728,92 @@ void unblock_device(DEVICE *dev) pthread_cond_broadcast(&dev->wait); /* wake them up */ } } + + + +/* + * Edit codes into ChangerDevice + * %% = % + * %a = archive device name + * %c = changer device name + * %f = Client's name + * %j = Job name + * %o = command + * %s = Slot base 0 + * %S = Slot base 1 + * %v = Volume name + * + * + * omsg = edited output message + * imsg = input string containing edit codes (%x) + * cmd = command string (load, unload, ...) + * + */ +char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd) +{ + char *p, *o, *str; + char add[20]; + + Dmsg1(200, "edit_job_codes: %s\n", imsg); + add[2] = 0; + o = omsg; + for (p=imsg; *p; p++) { + if (*p == '%') { + switch (*++p) { + case '%': + add[0] = '%'; + add[1] = 0; + str = add; + break; + case 'a': + str = jcr->device->dev->dev_name; + break; + case 'c': + str = jcr->device->changer_name; + break; + case 'o': + str = cmd; + break; + case 's': + sprintf(add, "%d", jcr->device->dev->VolCatInfo.Slot - 1); + str = add; + break; + case 'S': + sprintf(add, "%d", jcr->device->dev->VolCatInfo.Slot); + str = add; + break; + case 'j': /* Job name */ + str = jcr->Job; + break; + case 'v': + str = jcr->VolumeName; + if (!str) { + str = ""; + } + break; + case 'f': + str = jcr->client_name; + if (!str) { + str = ""; + } + break; + + default: + add[0] = '%'; + add[1] = *p; + str = add; + break; + } + } else { + add[0] = *p; + add[1] = 0; + str = add; + } + Dmsg1(200, "add_str %s\n", str); + add_str_to_pool_mem(&omsg, &o, str); + *o = 0; + Dmsg1(200, "omsg=%s\n", omsg); + } + *o = 0; + return omsg; +} diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index a7511945cc..0d81c1b683 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -609,24 +609,12 @@ static int status_cmd(JCR *jcr) bnet_fsend(user, _("Daemon started %s, %d Job%s run.\n"), dt, last_job.NumJobs, last_job.NumJobs == 1 ? "" : "s"); if (last_job.NumJobs > 0) { - char *termstat, jstat[2]; + char termstat[30]; bstrftime(dt, sizeof(dt), last_job.end_time); bnet_fsend(user, _("Last Job %s finished at %s\n"), last_job.Job, dt); - switch (last_job.JobStatus) { - case JS_Terminated: - termstat = _("OK"); - break; - case JS_ErrorTerminated: - termstat = _("Error"); - break; - default: - jstat[0] = last_job.JobStatus; - jstat[1] = 0; - termstat = jstat; - break; - } - + + jobstatus_to_ascii(last_job.JobStatus, termstat, sizeof(termstat)); bnet_fsend(user, _(" Files=%s Bytes=%s Termination Status=%s\n"), edit_uint64_with_commas(last_job.JobFiles, b1), edit_uint64_with_commas(last_job.JobBytes, b2), diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index ec564adc6a..2ec6d357e5 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -35,6 +35,7 @@ int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); int dir_send_job_status(JCR *jcr); +int dir_create_job_media_record(JCR *jcr); /* authenticate.c */ int authenticate_director(JCR *jcr); diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index 3020ea4f76..36acfce9bb 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -94,6 +94,7 @@ static struct res_items dev_items[] = { {"mountanonymousvolumes", store_yesno, ITEM(res_dev.cap_bits), CAP_ANONVOLS, ITEM_DEFAULT, 0}, {"alwaysopen", store_yesno, ITEM(res_dev.cap_bits), CAP_ALWAYSOPEN, ITEM_DEFAULT, 1}, {"autochanger", store_yesno, ITEM(res_dev.cap_bits), CAP_AUTOCHANGER, ITEM_DEFAULT, 0}, + {"changerdevice", store_strname,ITEM(res_dev.changer_name), 0, 0, 0}, {"offlineonunmount", store_yesno, ITEM(res_dev.cap_bits), CAP_OFFLINEUNMOUNT, ITEM_DEFAULT, 1}, {"maximumrewindwait", store_pint, ITEM(res_dev.max_rewind_wait), 0, ITEM_DEFAULT, 5 * 60}, {"minimumblocksize", store_pint, ITEM(res_dev.min_block_size), 0, 0, 0}, @@ -116,7 +117,7 @@ struct s_res resources[] = { {"storage", store_items, R_STORAGE, NULL}, {"device", dev_items, R_DEVICE, NULL}, {"messages", msgs_items, R_MSGS, NULL}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; @@ -132,81 +133,81 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... return; } sendit(sock, "dump_resource type=%d\n", type); - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_DIRECTOR: sendit(sock, "Director: name=%s\n", res->res_dir.hdr.name); - break; + break; case R_STORAGE: sendit(sock, "Storage: name=%s address=%s SDport=%d SDDport=%d\n", - res->res_store.hdr.name, res->res_store.address, - res->res_store.SDport, res->res_store.SDDport); - break; + res->res_store.hdr.name, res->res_store.address, + res->res_store.SDport, res->res_store.SDDport); + break; case R_DEVICE: sendit(sock, "Device: name=%s MediaType=%s Device=%s\n", - res->res_dev.hdr.name, - res->res_dev.media_type, res->res_dev.device_name); + res->res_dev.hdr.name, + res->res_dev.media_type, res->res_dev.device_name); sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n", - res->res_dev.max_rewind_wait, res->res_dev.min_block_size, - res->res_dev.max_block_size); + res->res_dev.max_rewind_wait, res->res_dev.min_block_size, + res->res_dev.max_block_size); sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n", - res->res_dev.max_volume_jobs, res->res_dev.max_volume_files, - res->res_dev.max_volume_size); + res->res_dev.max_volume_jobs, res->res_dev.max_volume_files, + res->res_dev.max_volume_size); sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n", - res->res_dev.max_file_size, res->res_dev.volume_capacity); + res->res_dev.max_file_size, res->res_dev.volume_capacity); strcpy(buf, " "); - if (res->res_dev.cap_bits & CAP_EOF) { + if (res->res_dev.cap_bits & CAP_EOF) { strcat(buf, "CAP_EOF "); - } - if (res->res_dev.cap_bits & CAP_BSR) { + } + if (res->res_dev.cap_bits & CAP_BSR) { strcat(buf, "CAP_BSR "); - } - if (res->res_dev.cap_bits & CAP_BSF) { + } + if (res->res_dev.cap_bits & CAP_BSF) { strcat(buf, "CAP_BSF "); - } - if (res->res_dev.cap_bits & CAP_FSR) { + } + if (res->res_dev.cap_bits & CAP_FSR) { strcat(buf, "CAP_FSR "); - } - if (res->res_dev.cap_bits & CAP_FSF) { + } + if (res->res_dev.cap_bits & CAP_FSF) { strcat(buf, "CAP_FSF "); - } - if (res->res_dev.cap_bits & CAP_EOM) { + } + if (res->res_dev.cap_bits & CAP_EOM) { strcat(buf, "CAP_EOM "); - } - if (res->res_dev.cap_bits & CAP_REM) { + } + if (res->res_dev.cap_bits & CAP_REM) { strcat(buf, "CAP_REM "); - } - if (res->res_dev.cap_bits & CAP_RACCESS) { + } + if (res->res_dev.cap_bits & CAP_RACCESS) { strcat(buf, "CAP_RACCESS "); - } - if (res->res_dev.cap_bits & CAP_AUTOMOUNT) { + } + if (res->res_dev.cap_bits & CAP_AUTOMOUNT) { strcat(buf, "CAP_AUTOMOUNT "); - } - if (res->res_dev.cap_bits & CAP_LABEL) { + } + if (res->res_dev.cap_bits & CAP_LABEL) { strcat(buf, "CAP_LABEL "); - } - if (res->res_dev.cap_bits & CAP_ANONVOLS) { + } + if (res->res_dev.cap_bits & CAP_ANONVOLS) { strcat(buf, "CAP_ANONVOLS "); - } - if (res->res_dev.cap_bits & CAP_ALWAYSOPEN) { + } + if (res->res_dev.cap_bits & CAP_ALWAYSOPEN) { strcat(buf, "CAP_ALWAYSOPEN "); - } + } strcat(buf, "\n"); - sendit(sock, buf); - break; + sendit(sock, buf); + break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); - if (res->res_msgs.mail_cmd) + if (res->res_msgs.mail_cmd) sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); - if (res->res_msgs.operator_cmd) + if (res->res_msgs.operator_cmd) sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); - break; + break; default: sendit(sock, _("Warning: unknown resource type %d\n"), type); - break; + break; } if (recurse && res->res_dir.hdr.next) dump_resource(type, (RES *)res->res_dir.hdr.next, sendit, sock); @@ -236,38 +237,40 @@ void free_resource(int type) switch (type) { case R_DIRECTOR: - if (res->res_dir.password) - free(res->res_dir.password); - if (res->res_dir.address) - free(res->res_dir.address); - break; + if (res->res_dir.password) + free(res->res_dir.password); + if (res->res_dir.address) + free(res->res_dir.address); + break; case R_STORAGE: - if (res->res_store.address) - free(res->res_store.address); - if (res->res_store.working_directory) - free(res->res_store.working_directory); - if (res->res_store.pid_directory) - free(res->res_store.pid_directory); - if (res->res_store.subsys_directory) - free(res->res_store.subsys_directory); - break; + if (res->res_store.address) + free(res->res_store.address); + if (res->res_store.working_directory) + free(res->res_store.working_directory); + if (res->res_store.pid_directory) + free(res->res_store.pid_directory); + if (res->res_store.subsys_directory) + free(res->res_store.subsys_directory); + break; case R_DEVICE: - if (res->res_dev.media_type) - free(res->res_dev.media_type); - if (res->res_dev.device_name) - free(res->res_dev.device_name); - break; + if (res->res_dev.media_type) + free(res->res_dev.media_type); + if (res->res_dev.device_name) + free(res->res_dev.device_name); + if (res->res_dev.changer_name) + free(res->res_dev.changer_name); + break; case R_MSGS: - if (res->res_msgs.mail_cmd) - free(res->res_msgs.mail_cmd); - if (res->res_msgs.operator_cmd) - free(res->res_msgs.operator_cmd); - free_msgs_res((MSGS *)res); /* free message resource */ - res = NULL; - break; + if (res->res_msgs.mail_cmd) + free(res->res_msgs.mail_cmd); + if (res->res_msgs.operator_cmd) + free(res->res_msgs.operator_cmd); + free_msgs_res((MSGS *)res); /* free message resource */ + res = NULL; + break; default: Dmsg1(0, "Unknown resource type %d\n", type); - break; + break; } /* Common stuff again -- free the resource, recurse to next one */ if (res) { @@ -295,10 +298,10 @@ void save_resource(int type, struct res_items *items, int pass) */ for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"), - items[i].name, resources[rindex]); - } + items[i].name, resources[rindex]); + } } /* If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { @@ -313,33 +316,33 @@ void save_resource(int type, struct res_items *items, int pass) */ if (pass == 2) { switch (type) { - /* Resources not containing a resource */ - case R_DIRECTOR: - case R_DEVICE: - case R_MSGS: - break; - - /* Resources containing a resource */ - case R_STORAGE: - if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) { + /* Resources not containing a resource */ + case R_DIRECTOR: + case R_DEVICE: + case R_MSGS: + break; + + /* Resources containing a resource */ + case R_STORAGE: + if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ABORT, 0, "Cannot find Storage resource %s\n", res_all.res_dir.hdr.name); - } - res->res_store.messages = res_all.res_store.messages; - break; - default: + } + res->res_store.messages = res_all.res_store.messages; + break; + default: printf("Unknown resource type %d\n", type); - error = 1; - break; + error = 1; + break; } if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } @@ -347,36 +350,36 @@ void save_resource(int type, struct res_items *items, int pass) /* The following code is only executed on pass 1 */ switch (type) { case R_DIRECTOR: - size = sizeof(DIRRES); - break; + size = sizeof(DIRRES); + break; case R_STORAGE: - size = sizeof(STORES); - break; + size = sizeof(STORES); + break; case R_DEVICE: - size = sizeof(DEVRES); - break; + size = sizeof(DEVRES); + break; case R_MSGS: - size = sizeof(MSGS); - break; + size = sizeof(MSGS); + break; default: printf("Unknown resource type %d\n", type); - error = 1; - break; + error = 1; + break; } /* Common */ if (!error) { res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!resources[rindex].res_head) { - resources[rindex].res_head = (RES *)res; /* store first entry */ + resources[rindex].res_head = (RES *)res; /* store first entry */ } else { - RES *next; - /* Add new res to end of chain */ - for (next=resources[rindex].res_head; next->next; next=next->next) - { } - next->next = (RES *)res; + RES *next; + /* Add new res to end of chain */ + for (next=resources[rindex].res_head; next->next; next=next->next) + { } + next->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), - res->res_dir.hdr.name); + res->res_dir.hdr.name); } } } diff --git a/bacula/src/stored/stored_conf.h b/bacula/src/stored/stored_conf.h index 6c2f946107..8983a82036 100644 --- a/bacula/src/stored/stored_conf.h +++ b/bacula/src/stored/stored_conf.h @@ -70,9 +70,10 @@ typedef struct s_res_store STORES; struct s_res_dev { RES hdr; - char *media_type; - char *device_name; - int cap_bits; + char *media_type; /* User assigned media type */ + char *device_name; /* Archive device name */ + char *changer_name; /* Changer device name */ + int cap_bits; /* Capabilities of this device */ uint32_t max_rewind_wait; /* maximum secs to wait for rewind */ uint32_t min_block_size; /* min block size */ uint32_t max_block_size; /* max block size */ @@ -81,7 +82,7 @@ struct s_res_dev { int64_t max_volume_size; /* max bytes to put on one volume */ int64_t max_file_size; /* max file size in bytes */ int64_t volume_capacity; /* advisory capacity */ - DEVICE *dev; + DEVICE *dev; /* Pointer to phyical dev -- set at runtime */ }; typedef struct s_res_dev DEVRES; diff --git a/bacula/src/version.h b/bacula/src/version.h index 8e6dd7e97d..f2cb7d0f1b 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.23" #define VSTRING "1" -#define DATE "12 July 2002" -#define LSMDATE "12Jul02" +#define DATE "15 July 2002" +#define LSMDATE "15Jul02" /* Debug flags */ #define DEBUG 1 -- 2.39.5