- Release Notes for Bacula 1.37.2
+ Release Notes for Bacula 1.37.3
- Bacula code: Total files = 398 Total lines = 117,151 (*.h *.c *.in)
+ Bacula code: Total files = 411 Total lines = 121,855 (*.h *.c *.in)
Major Changes:
+- This version has a new database format that is not compatible
+ with previous databases. There are NO upgrade scripts yet.
+- Due to the massive changes made during the last two weeks,
+ version 1.37.3 should be considered unstable. It does, however,
+ pass the regression tests.
+- SQLite3 support.
+- First cut at ANSI labels.
+- New communications protocol between DIR and SD to reserve
+ drives.
+
+
- Preliminary Python Event support has been added. See below for
configuration.
A Python script will be called at particular points or conditions
/* Define if you want to use SQLite */
#undef HAVE_SQLITE
+/* Define if you want to use SQLite3 */
+#undef HAVE_SQLITE3
+
/* Define if you want to use Berkeley DB */
#undef HAVE_BERKELEY_DB
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_PGSQL
-
/* Define if you want to use mSQL */
#undef HAVE_MSQL
])
+AC_DEFUN(BA_CHECK_SQLITE3_DB,
+[
+db_found=no
+AC_MSG_CHECKING(for SQLite3 support)
+AC_ARG_WITH(sqlite3,
+[
+ --with-sqlite3[=DIR] Include SQLite3 support. DIR is the SQLite3 base
+ install directory, default is to search through
+ a number of common places for the SQLite3 files.],
+[
+ if test "$withval" != "no"; then
+ if test "$withval" = "yes"; then
+ if test -f /usr/local/include/sqlite3.h; then
+ SQLITE_INCDIR=/usr/local/include
+ SQLITE_LIBDIR=/usr/local/lib
+ SQLITE_BINDIR=/usr/local/bin
+ elif test -f /usr/include/sqlite3.h; then
+ SQLITE_INCDIR=/usr/include
+ SQLITE_LIBDIR=/usr/lib
+ SQLITE_BINDIR=/usr/bin
+ elif test -f $prefix/include/sqlite3.h; then
+ SQLITE_INCDIR=$prefix/include
+ SQLITE_LIBDIR=$prefix/lib
+ SQLITE_BINDIR=$prefix/bin
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(Unable to find sqlite3.h in standard locations)
+ fi
+ else
+ if test -f $withval/sqlite3.h; then
+ SQLITE_INCDIR=$withval
+ SQLITE_LIBDIR=$withval
+ SQLITE_BINDIR=$withval
+ elif test -f $withval/include/sqlite3.h; then
+ SQLITE_INCDIR=$withval/include
+ SQLITE_LIBDIR=$withval/lib
+ SQLITE_BINDIR=$withval/bin
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval)
+ fi
+ fi
+ SQL_INCLUDE=-I$SQLITE_INCDIR
+ SQL_LFLAGS="-L$SQLITE_LIBDIR -lsqlite3"
+ SQL_BINDIR=$SQLITE_BINDIR
+
+ AC_DEFINE(HAVE_SQLITE3)
+ AC_MSG_RESULT(yes)
+ db_found=yes
+ support_sqlite3=yes
+ db_name=SQLite3
+ DB_NAME=sqlite3
+
+ else
+ AC_MSG_RESULT(no)
+ fi
+],[
+ AC_MSG_RESULT(no)
+])
+AC_SUBST(SQL_LFLAGS)
+AC_SUBST(SQL_INCLUDE)
+AC_SUBST(SQL_BINDIR)
+
+])
+
+
AC_DEFUN(BA_CHECK_POSTGRESQL_DB,
[
/* Define if you want to use SQLite */
#undef HAVE_SQLITE
+/* Define if you want to use SQLite3 */
+#undef HAVE_SQLITE3
+
/* Define if you want to use Berkeley DB */
#undef HAVE_BERKELEY_DB
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_PGSQL
-
/* Define if you want to use mSQL */
#undef HAVE_MSQL
/* Define if you want to use SQLite */
#undef HAVE_SQLITE
+/* Define if you want to use SQLite3 */
+#undef HAVE_SQLITE3
+
/* Define if you want to use Berkeley DB */
#undef HAVE_BERKELEY_DB
-
-/* Define if you want to use PostgreSQL */
-#undef HAVE_PGSQL
-
/* Define if you want to use mSQL */
#undef HAVE_MSQL
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
support_mysql=no
support_sqlite=no
+support_sqlite3=no
support_postgresql=no
support_smartalloc=yes
support_readline=yes
if test x${CDSTL} = x ; then
CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD+RW | ${AWK} '{print $1}'`
fi
+ if test x${CDSTL} = x ; then
+ CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD+RW | ${AWK} '{print $1}'`
+ fi
+ if test x${CDSTL} = x ; then
+ CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD-RW | ${AWK} '{print $1}'`
+ fi
if test x${CDSTL} = x ; then
CDSTL="3,0,0"
fi
BA_CHECK_MYSQL_DB
+BA_CHECK_SQLITE3_DB
+
BA_CHECK_SQLITE_DB
AC_SUBST(cats)
scripts/dvd-writepart \
scripts/dvd-freespace \
scripts/bacula-tray-monitor.desktop \
- scripts/logwatch/Makefile \
- scripts/logwatch/logfile.bacula.conf \
+ scripts/logwatch/Makefile \
+ scripts/logwatch/logfile.bacula.conf \
doc/Makefile \
src/Makefile \
src/host.h \
src/cats/grant_sqlite_privileges \
src/cats/drop_sqlite_tables \
src/cats/drop_sqlite_database \
+ src/cats/create_sqlite3_database \
+ src/cats/update_sqlite3_tables \
+ src/cats/make_sqlite3_tables \
+ src/cats/grant_sqlite3_privileges \
+ src/cats/drop_sqlite3_tables \
+ src/cats/drop_sqlite3_database \
src/cats/sqlite \
src/cats/mysql \
src/cats/create_bdb_database \
echo " "
echo " "
echo "You have not specified either --enable-client-only or one of the"
- echo " supported databases: MySQL, PostgreSQL, or SQLite".
+ echo " supported databases: MySQL, PostgreSQL, SQLite3 or SQLite."
echo " This is not permitted. Please reconfigure."
echo " "
echo "Aborting the configuration ..."
install directory, default is to search through
a number of common places for the MySQL files.
+ --with-sqlite3=DIR Include SQLite3 support. DIR is the SQLite3 base
+ install directory, default is to search through
+ a number of common places for the SQLite3 files.
+
--with-sqlite=DIR Include SQLite support. DIR is the SQLite base
install directory, default is to search through
a number of common places for the SQLite files.
support_mysql=no
support_sqlite=no
+support_sqlite3=no
support_postgresql=no
support_smartalloc=yes
support_readline=yes
if test x${CDSTL} = x ; then
CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD+RW | ${AWK} '{print $1}'`
fi
+ if test x${CDSTL} = x ; then
+ CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD+RW | ${AWK} '{print $1}'`
+ fi
+ if test x${CDSTL} = x ; then
+ CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep DVD-RW | ${AWK} '{print $1}'`
+ fi
if test x${CDSTL} = x ; then
CDSTL="3,0,0"
fi
+db_found=no
+echo "$as_me:$LINENO: checking for SQLite3 support" >&5
+echo $ECHO_N "checking for SQLite3 support... $ECHO_C" >&6
+
+# Check whether --with-sqlite3 or --without-sqlite3 was given.
+if test "${with_sqlite3+set}" = set; then
+ withval="$with_sqlite3"
+
+ if test "$withval" != "no"; then
+ if test "$withval" = "yes"; then
+ if test -f /usr/local/include/sqlite3.h; then
+ SQLITE_INCDIR=/usr/local/include
+ SQLITE_LIBDIR=/usr/local/lib
+ SQLITE_BINDIR=/usr/local/bin
+ elif test -f /usr/include/sqlite3.h; then
+ SQLITE_INCDIR=/usr/include
+ SQLITE_LIBDIR=/usr/lib
+ SQLITE_BINDIR=/usr/bin
+ elif test -f $prefix/include/sqlite3.h; then
+ SQLITE_INCDIR=$prefix/include
+ SQLITE_LIBDIR=$prefix/lib
+ SQLITE_BINDIR=$prefix/bin
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ { { echo "$as_me:$LINENO: error: Unable to find sqlite3.h in standard locations" >&5
+echo "$as_me: error: Unable to find sqlite3.h in standard locations" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ else
+ if test -f $withval/sqlite3.h; then
+ SQLITE_INCDIR=$withval
+ SQLITE_LIBDIR=$withval
+ SQLITE_BINDIR=$withval
+ elif test -f $withval/include/sqlite3.h; then
+ SQLITE_INCDIR=$withval/include
+ SQLITE_LIBDIR=$withval/lib
+ SQLITE_BINDIR=$withval/bin
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ { { echo "$as_me:$LINENO: error: Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval" >&5
+echo "$as_me: error: Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+ SQL_INCLUDE=-I$SQLITE_INCDIR
+ SQL_LFLAGS="-L$SQLITE_LIBDIR -lsqlite3"
+ SQL_BINDIR=$SQLITE_BINDIR
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SQLITE3 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ db_found=yes
+ support_sqlite3=yes
+ db_name=SQLite3
+ DB_NAME=sqlite3
+
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+
+else
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi;
+
+
+
+
+
+
+
db_found=no
echo "$as_me:$LINENO: checking for SQLite support" >&5
echo $ECHO_N "checking for SQLite support... $ECHO_C" >&6
exit 1
fi
- ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/linux/floppy/Makefile rescue/linux/cdrom/Makefile rescue/linux/cdrom/bacula/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/devel_bacula scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/bacula.desktop.gnome1.consolehelper scripts/bacula.desktop.gnome2.consolehelper scripts/bacula.desktop.gnome1.xsu scripts/bacula.desktop.gnome2.xsu scripts/gnome-console.console_apps scripts/mtx-changer scripts/dvd-writepart scripts/dvd-freespace scripts/bacula-tray-monitor.desktop scripts/logwatch/Makefile scripts/logwatch/logfile.bacula.conf doc/Makefile src/Makefile src/host.h src/console/Makefile src/console/bconsole.conf src/gnome-console/Makefile src/gnome-console/gnome-console.conf src/gnome2-console/Makefile src/gnome2-console/gnome-console.conf src/wx-console/Makefile src/wx-console/wx-console.conf src/tray-monitor/Makefile src/tray-monitor/tray-monitor.conf src/dird/Makefile src/dird/bacula-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bacula-sd.conf src/filed/Makefile src/filed/bacula-fd.conf src/filed/win32/Makefile src/cats/Makefile src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_postgresql_database src/cats/update_postgresql_tables src/cats/make_postgresql_tables src/cats/grant_postgresql_privileges src/cats/drop_postgresql_tables src/cats/drop_postgresql_database src/cats/create_mysql_database src/cats/update_mysql_tables src/cats/make_mysql_tables src/cats/grant_mysql_privileges src/cats/drop_mysql_tables src/cats/drop_mysql_database src/cats/create_sqlite_database src/cats/update_sqlite_tables src/cats/make_sqlite_tables src/cats/grant_sqlite_privileges src/cats/drop_sqlite_tables src/cats/drop_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/update_bdb_tables src/cats/make_bdb_tables src/cats/grant_bdb_privileges src/cats/drop_bdb_tables src/cats/drop_bdb_database src/cats/create_bacula_database src/cats/update_bacula_tables src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/drop_bacula_database src/findlib/Makefile src/tools/Makefile src/win32/winbacula.nsi src/win32/baculafd/bacula-fd.conf src/win32/Makefile src/win32/console/bconsole.conf src/win32/wx-console/wx-console.conf src/win32/pebuilder/Makefile src/bimagemgr/Makefile src/bimagemgr/bacula-bimagemgr.spec $PFILES"
+ ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/linux/floppy/Makefile rescue/linux/cdrom/Makefile rescue/linux/cdrom/bacula/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/devel_bacula scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/bacula.desktop.gnome1.consolehelper scripts/bacula.desktop.gnome2.consolehelper scripts/bacula.desktop.gnome1.xsu scripts/bacula.desktop.gnome2.xsu scripts/gnome-console.console_apps scripts/mtx-changer scripts/dvd-writepart scripts/dvd-freespace scripts/bacula-tray-monitor.desktop scripts/logwatch/Makefile scripts/logwatch/logfile.bacula.conf doc/Makefile src/Makefile src/host.h src/console/Makefile src/console/bconsole.conf src/gnome-console/Makefile src/gnome-console/gnome-console.conf src/gnome2-console/Makefile src/gnome2-console/gnome-console.conf src/wx-console/Makefile src/wx-console/wx-console.conf src/tray-monitor/Makefile src/tray-monitor/tray-monitor.conf src/dird/Makefile src/dird/bacula-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bacula-sd.conf src/filed/Makefile src/filed/bacula-fd.conf src/filed/win32/Makefile src/cats/Makefile src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_postgresql_database src/cats/update_postgresql_tables src/cats/make_postgresql_tables src/cats/grant_postgresql_privileges src/cats/drop_postgresql_tables src/cats/drop_postgresql_database src/cats/create_mysql_database src/cats/update_mysql_tables src/cats/make_mysql_tables src/cats/grant_mysql_privileges src/cats/drop_mysql_tables src/cats/drop_mysql_database src/cats/create_sqlite_database src/cats/update_sqlite_tables src/cats/make_sqlite_tables src/cats/grant_sqlite_privileges src/cats/drop_sqlite_tables src/cats/drop_sqlite_database src/cats/create_sqlite3_database src/cats/update_sqlite3_tables src/cats/make_sqlite3_tables src/cats/grant_sqlite3_privileges src/cats/drop_sqlite3_tables src/cats/drop_sqlite3_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/update_bdb_tables src/cats/make_bdb_tables src/cats/grant_bdb_privileges src/cats/drop_bdb_tables src/cats/drop_bdb_database src/cats/create_bacula_database src/cats/update_bacula_tables src/cats/grant_bacula_privileges src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/drop_bacula_database src/findlib/Makefile src/tools/Makefile src/win32/winbacula.nsi src/win32/baculafd/bacula-fd.conf src/win32/Makefile src/win32/console/bconsole.conf src/win32/wx-console/wx-console.conf src/win32/pebuilder/Makefile src/bimagemgr/Makefile src/bimagemgr/bacula-bimagemgr.spec $PFILES"
ac_config_commands="$ac_config_commands default"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
"src/cats/grant_sqlite_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_sqlite_privileges" ;;
"src/cats/drop_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite_tables" ;;
"src/cats/drop_sqlite_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite_database" ;;
+ "src/cats/create_sqlite3_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_sqlite3_database" ;;
+ "src/cats/update_sqlite3_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_sqlite3_tables" ;;
+ "src/cats/make_sqlite3_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_sqlite3_tables" ;;
+ "src/cats/grant_sqlite3_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_sqlite3_privileges" ;;
+ "src/cats/drop_sqlite3_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite3_tables" ;;
+ "src/cats/drop_sqlite3_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite3_database" ;;
"src/cats/sqlite" ) CONFIG_FILES="$CONFIG_FILES src/cats/sqlite" ;;
"src/cats/mysql" ) CONFIG_FILES="$CONFIG_FILES src/cats/mysql" ;;
"src/cats/create_bdb_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_bdb_database" ;;
echo " "
echo " "
echo "You have not specified either --enable-client-only or one of the"
- echo " supported databases: MySQL, PostgreSQL, or SQLite".
+ echo " supported databases: MySQL, PostgreSQL, SQLite3 or SQLite."
echo " This is not permitted. Please reconfigure."
echo " "
echo "Aborting the configuration ..."
def EndJob(j):
jobid = bacula.get(j, "JobId")
client = bacula.get(j, "Client")
- bacula.set(jcr=j, JobReport="Python JodJob output: JobId=%d Client=%s.\n" % (jobid, client))
+ bacula.set(jcr=j, JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
if (jobid < 5) :
startid = bacula.run(j, "run kernsave")
- print "Python started jobid=", startid
+ print "Python started new Job: jobid=", startid
return 1
Kern's ToDo List
- 31 December 2004
+ 23 January 2005
Major development:
Project Developer
1.37 Major Projects:
#3 Migration (Move, Copy, Archive Jobs)
-#4 Embedded Python Scripting (implemented in Dir)
-#5 Events that call a Python program (Implemented in Dir)
+#4 Embedded Python Scripting
+ (Implemented in Dir/SD)
+#5 Events that call a Python program
+ (Implemented in Dir/SD)
#6 Select one from among Multiple Storage Devices for Job
#7 Single Job Writing to Multiple Storage Devices
- Look at Preben's acl.c error handling code.
- See multiple-store.txt for Multiple Storage implementation
design.
-- Add Set Error from Python.
- Create a new GUI chapter explaining all the GUI programs.
- Tell the "restore" user when browsing is no longer possible.
- Add disk seeking on restore.
get the bootstrap file.
- Add dump of VolSessionId/Time and FileIndex with bls.
- Make bootstrap file handle multiple MediaTypes (SD)
-- Add offline command to Bacula console.
+- Add offline tape command to Bacula console.
- Add performance testing hooks
-- Add Python writable variable for changing the Priority.
+- Add Python writable variable for changing the Priority,
+ Client, Storage, JobStatus (error), ...
- Document that Bootstrap files can be written with cataloging
turned off.
- Look at adding full Volume and Pool information to a Volume
;;
stop)
echo "Stopping the Director daemon: "
-# killproc @sbindir@/bacula-dir
+ pkill -x bacula-dir
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f @subsysdir@/bacula-dir
;;
stop)
echo "Stopping the Bacula File daemon: "
-# killproc @sbindir@/bacula-fd
+ pkill -x bacula-fd
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f @subsysdir@/bacula-fd
;;
stop)
echo "Stopping the Bacula Storage daemon: "
-# killproc @sbindir@/bacula-sd
+ pkill -x bacula-sd
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f @subsysdir@/bacula-sd
* Version $Id$
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#define MD5_SIG 1
#define SHA1_SIG 2
+/*
+ * Tape label types -- stored in catalog
+ */
+#define B_BACULA_LABEL 0
+#define B_ANSI_LABEL 1
+#define B_IBM_LABEL 2
+
/* Size of File Address stored in STREAM_SPARSE_DATA. Do NOT change! */
#define SPARSE_FADDR_SIZE (sizeof(uint64_t))
#define P(x) \
do { int errstat; if ((errstat=pthread_mutex_lock(&(x)))) \
e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex lock failure. ERR=%s\n",\
- strerror(errstat)); \
+ strerror(errstat)); \
} while(0)
#define V(x) \
do { int errstat; if ((errstat=pthread_mutex_unlock(&(x)))) \
- e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex unlock failure. ERR=%s\n",\
- strerror(errstat)); \
+ e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex unlock failure. ERR=%s\n",\
+ strerror(errstat)); \
} while(0)
#endif /* DEBUG_MUTEX */
#define Pw(x) \
do { int errstat; if ((errstat=rwl_writelock(&(x)))) \
e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock lock failure. ERR=%s\n",\
- strerror(errstat)); \
+ strerror(errstat)); \
} while(0)
#define Vw(x) \
do { int errstat; if ((errstat=rwl_writeunlock(&(x)))) \
- e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock unlock failure. ERR=%s\n",\
- strerror(errstat)); \
+ e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock unlock failure. ERR=%s\n",\
+ strerror(errstat)); \
} while(0)
#define LockRes() b_LockRes(__FILE__, __LINE__)
#ifdef HAVE_BACULA_DB
/* Forward referenced functions */
-int db_create_pool_record(B_DB *mdb, POOL_DBR *pr);
+bool db_create_pool_record(B_DB *mdb, POOL_DBR *pr);
/* -----------------------------------------------------------------------
*
* Returns: 0 on failure
* 1 on success
*/
-int db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
+bool db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
{
int len;
POOL_DBR mpr;
return 1;
}
+bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
+{ return false; }
+
+bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *dr)
+{ return false; }
+
+bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *dr)
+{ return false; }
+
/*
* Create Unique Media record. This record
* Returns: 0 on failure
* 1 on success
*/
-int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
+bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
{
int len;
FILESET_DBR lfsr;
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#ifdef HAVE_SQLITE
-#ifdef HAVE_SQLITE3
-#define sqlite_last_insert_rowid sqlite3_last_insert_rowid
-#define sqlite_open sqlite3_open
-#define sqlite_close sqlite3_close
-#define sqlite_result sqlite3_result
-#define sqlite_exec sqlite3_exec
-#define sqlite_get_table sqlite3_get_table
-#define sqlite_free_table sqlite3_free_table
-#endif
-
#define BDB_VERSION 8
#include <sqlite.h>
+/* In cats/sqlite.c */
+void my_sqlite_free_table(B_DB *mdb);
+SQL_ROW my_sqlite_fetch_row(B_DB *mdb);
+int my_sqlite_query(B_DB *mdb, char *cmd);
+void my_sqlite_field_seek(B_DB *mdb, int field);
+SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb);
+
+
+#else
+
+/* S Q L I T E 3 */
+
+
+#ifdef HAVE_SQLITE3
+
+
+#define BDB_VERSION 8
+
+#include <sqlite3.h>
+
+/* Define opaque structure for sqlite */
+struct sqlite3 {
+ char dummy;
+};
+
+#define IS_NUM(x) ((x) == 1)
+#define IS_NOT_NULL(x) ((x) == 1)
+
+typedef struct s_sql_field {
+ char *name; /* name of column */
+ int length; /* length */
+ int max_length; /* max length */
+ uint32_t type; /* type */
+ uint32_t flags; /* flags */
+} SQL_FIELD;
+
+/*
+ * This is the "real" definition that should only be
+ * used inside sql.c and associated database interface
+ * subroutines.
+ * S Q L I T E
+ */
+typedef struct s_db {
+ BQUEUE bq; /* queue control */
+ brwlock_t lock; /* transaction lock */
+ struct sqlite3 *db;
+ char **result;
+ int status;
+ int nrow; /* nrow returned from sqlite */
+ int ncolumn; /* ncolum returned from sqlite */
+ int num_rows; /* used by code */
+ int row; /* seek row */
+ int field; /* seek field */
+ SQL_FIELD **fields; /* defined fields */
+ int ref_count;
+ char *db_name;
+ char *db_user;
+ char *db_address; /* host name address */
+ char *db_socket; /* socket for local access */
+ char *db_password;
+ int db_port; /* port for host name address */
+ bool connected; /* connection made to db */
+ bool have_insert_id; /* do not have insert id */
+ bool fields_defined; /* set when fields defined */
+ char *sqlite_errmsg; /* error message returned by sqlite */
+ POOLMEM *errmsg; /* nicely edited error message */
+ POOLMEM *cmd; /* SQL command string */
+ POOLMEM *cached_path; /* cached path name */
+ int cached_path_len; /* length of cached path */
+ uint32_t cached_path_id; /* cached path id */
+ bool allow_transactions; /* transactions allowed */
+ bool transaction; /* transaction started */
+ int changes; /* changes during transaction */
+ POOLMEM *fname; /* Filename only */
+ POOLMEM *path; /* Path only */
+ POOLMEM *esc_name; /* Escaped file/path name */
+ int fnl; /* file name length */
+ int pnl; /* path name length */
+} B_DB;
+
+/*
+ * Conversion of sqlite 2 names to sqlite3
+ */
+#define sqlite_last_insert_rowid sqlite3_last_insert_rowid
+#define sqlite_open sqlite3_open
+#define sqlite_close sqlite3_close
+#define sqlite_result sqlite3_result
+#define sqlite_exec sqlite3_exec
+#define sqlite_get_table sqlite3_get_table
+#define sqlite_free_table sqlite3_free_table
+
+
+/*
+ * "Generic" names for easier conversion
+ *
+ * S Q L I T E 3
+ */
+#define sql_store_result(x) (x)->result
+#define sql_free_result(x) my_sqlite_free_table(x)
+#define sql_fetch_row(x) my_sqlite_fetch_row(x)
+#define sql_query(x, y) my_sqlite_query((x), (y))
+#ifdef HAVE_SQLITE3
+#define sql_insert_id(x,y) sqlite3_last_insert_rowid((x)->db)
+#define sql_close(x) sqlite3_close((x)->db)
+#else
+#define sql_insert_id(x,y) sqlite_last_insert_rowid((x)->db)
+#define sql_close(x) sqlite_close((x)->db)
+#endif
+#define sql_strerror(x) (x)->sqlite_errmsg?(x)->sqlite_errmsg:"unknown"
+#define sql_num_rows(x) (x)->nrow
+#define sql_data_seek(x, i) (x)->row = (i)
+#define sql_affected_rows(x) 1
+#define sql_field_seek(x, y) my_sqlite_field_seek((x), (y))
+#define sql_fetch_field(x) my_sqlite_fetch_field(x)
+#define sql_num_fields(x) ((x)->ncolumn)
+#define SQL_ROW char**
+
+
+
/* In cats/sqlite.c */
void my_sqlite_free_table(B_DB *mdb);
SQL_ROW my_sqlite_fetch_row(B_DB *mdb);
uint32_t cached_path_id;
} B_DB;
+#endif /* HAVE_SQLITE3 */
#endif /* HAVE_MYSQL */
#endif /* HAVE_SQLITE */
#endif /* HAVE_POSTGRESQL */
/* Volume Parameter structure */
struct VOL_PARAMS {
char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
+ char MediaType[MAX_NAME_LENGTH]; /* Media Type */
uint32_t VolIndex; /* Volume seqence no. */
uint32_t FirstIndex; /* First index this Volume */
uint32_t LastIndex; /* Last index this Volume */
DBId_t PathId;
JobId_t MarkId;
char LStat[256];
-/* int Status; */
char SIG[50];
int SigType; /* NO_SIG/MD5_SIG/SHA1_SIG */
};
char Name[MAX_NAME_LENGTH]; /* Pool name */
uint32_t NumVols; /* total number of volumes */
uint32_t MaxVols; /* max allowed volumes */
+ int32_t LabelType; /* Bacula/ANSI/IBM */
int32_t UseOnce; /* set to use once only */
int32_t UseCatalog; /* set to use catalog */
int32_t AcceptAnyVolume; /* set to accept any volume sequence */
faddr_t rec_addr;
};
+class DEVICE_DBR {
+public:
+ DBId_t DeviceId;
+ char Name[MAX_NAME_LENGTH]; /* Device name */
+ DBId_t MediaTypeId; /* MediaType */
+ DBId_t StorageId; /* Storage id if autochanger */
+ uint32_t DevMounts; /* Number of times mounted */
+ uint32_t DevErrors; /* Number of read/write errors */
+ uint64_t DevReadBytes; /* Number of bytes read */
+ uint64_t DevWriteBytes; /* Number of bytew written */
+ uint64_t DevReadTime; /* time spent reading volume */
+ uint64_t DevWriteTime; /* time spent writing volume */
+ uint64_t DevReadTimeSincCleaning; /* read time since cleaning */
+ uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
+ time_t CleaningDate; /* time last cleaned */
+ utime_t CleaningPeriod; /* time between cleanings */
+};
+
+class STORAGE_DBR {
+public:
+ DBId_t StorageId;
+ char Name[MAX_NAME_LENGTH]; /* Device name */
+ DBId_t MediaTypeId; /* MediaType */
+ int AutoChanger; /* Set if autochanger */
+};
+
+class MEDIATYPE_DBR {
+public:
+ DBId_t MediaTypeId;
+ char MediaType[MAX_NAME_LENGTH]; /* MediaType string */
+ int ReadOnly; /* Set if read-only */
+};
+
+
/* Media record -- same as the database */
struct MEDIA_DBR {
DBId_t MediaId; /* Unique volume id */
time_t FirstWritten; /* Time Volume first written */
time_t LastWritten; /* Time Volume last written */
time_t LabelDate; /* Date/Time Volume labeled */
+ int32_t LabelType; /* Label (Bacula/ANSI/IBM) */
uint32_t VolJobs; /* number of jobs on this medium */
uint32_t VolFiles; /* Number of files */
uint32_t VolBlocks; /* Number of blocks */
# This routine creates the Bacula database
# using PostgreSQL, MySQL, or SQLite.
#
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
echo "Creating SQLite database"
- @scriptdir@/create_sqlite_database $*
+ @scriptdir@/create_@DB_NAME@_database $*
else
if test xmysql = x@DB_NAME@ ; then
echo "Creating MySQL database"
bindir=@SQL_BINDIR@
cd @working_dir@
+sqlite=@DB_NAME@
-$bindir/sqlite $* bacula.db <<END-OF-DATA
+${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
END-OF-DATA
exit 0
# Drop Bacula database -- works for whatever is configured,
# MySQL, SQLite, PostgreSQL
#
-if test xsqlite = x@DB_NAME@ ; then
- @scriptdir@/drop_sqlite_database $*
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
+ @scriptdir@/drop_@DB_NAME@_database $*
else
if test xmysql = x@DB_NAME@ ; then
echo "Making MySQL database"
# Drop Bacula tables -- works for whatever is configured,
# MySQL, SQLite, or PostgreSQL
#
-if test xsqlite = x@DB_NAME@ ; then
- @scriptdir@/drop_sqlite_tables $*
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
+ @scriptdir@/drop_@DB_NAME@_tables $*
echo "Dropped SQLite tables"
else
if test xmysql = x@DB_NAME@ ; then
#
# shell script to drop Bacula SQLite tables
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
cd @working_dir@
rm -rf bacula.db
echo "SQLite database dropped."
echo "Granting PostgreSQL privileges"
@scriptdir@/grant_postgresql_privileges $*
else
- if test xsqlite = x@DB_NAME@ ; then
+ if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
echo "Granting SQLite privileges"
- @scriptdir@/grant_sqlite_privileges $*
+ @scriptdir@/grant_@DB_NAME@_privileges $*
fi
fi
fi
# This routine makes the appropriately configured
# Bacula tables for PostgreSQL, MySQL, or SQLite.
#
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
echo "Making SQLite tables"
- @scriptdir@/make_sqlite_tables $*
+ @scriptdir@/make_@DB_NAME@_tables $*
else
if test xmysql = x@DB_NAME@ ; then
echo "Making MySQL tables"
Slot INTEGER NOT NULL DEFAULT 0,
PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
MediaType TINYBLOB NOT NULL,
+ LabelType TINYINT NOT NULL DEFAULT 0,
FirstWritten DATETIME NOT NULL,
LastWritten DATETIME NOT NULL,
LabelDate DATETIME NOT NULL,
INDEX (PoolId)
);
+CREATE INDEX inx8 ON Media (PoolId);
+
+CREATE TABLE MediaType (
+ MediaTypeId INTERGER UNSIGNED NOT NULL AUTO_INCREMENT,
+ MediaType VARCHAR(128) NOT NULL,
+ ReadOnly TINYINT DEFAULT 0,
+ PRIMARY KEY(MediaTypeId)
+ );
+
+CREATE TABLE Device (
+ DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+ Name VARCHAR(128) NOT NULL,
+ MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
+ StorageId INTEGER UNSIGNED REFERENCES Storage,
+ DevMounts INTEGER UNSIGNED DEFAULT 0,
+ DevReadBytes BIGINT UNSIGNED DEFAULT 0,
+ DevWriteBytes BIGINT UNSIGNED DEFAULT 0,
+ DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ DevReadTime BIGINT UNSIGNED DEFAULT 0,
+ DevWriteTime BIGINT UNSIGNED DEFAULT 0,
+ DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ CleaningDate DATETIME DEFAULT 0,
+ CleaningPeriod BIGINT UNSIGNED DEFAULT 0,
+ PRIMARY KEY(DeviceId)
+ );
+
+CREATE TABLE Storage (
+ StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+ Name VARCHAR(128) NOT NULL,
+ AutoChanger TINYINT DEFAULT 0,
+ PRIMARY KEY(StorageId)
+ );
+
CREATE TABLE Pool (
PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Name TINYBLOB NOT NULL,
if $bindir/psql $* bacula -f - <<END-OF-DATA
-create table version
+CREATE TABLE filename
(
- versionid integer not null
+ filenameid serial not null,
+ name text not null,
+ primary key (filenameid)
);
-INSERT INTO Version (VersionId) VALUES (8);
+CREATE INDEX filename_name_idx on filename (name);
-create table counters
+CREATE TABLE path
(
- counter text not null,
- minvalue integer ,
- maxvalue integer ,
- currentvalue integer ,
- wrapcounter text not null,
- primary key (counter)
+ pathid serial not null,
+ path text not null,
+ primary key (pathid)
);
-create table filename
+CREATE INDEX path_name_idx on path (path);
+
+CREATE TABLE file
(
- filenameid serial not null,
- name text not null,
- primary key (filenameid)
+ fileid serial not null,
+ fileindex integer not null default 0,
+ jobid integer not null,
+ pathid integer not null,
+ filenameid integer not null,
+ markid integer not null default 0,
+ lstat text not null,
+ md5 text not null,
+ primary key (fileid)
);
-create index filename_name_idx on filename (name);
+CREATE INDEX file_jobid_idx on file (jobid);
+CREATE INDEX file_fp_idx on file (filenameid, pathid);
-create table path
+--
+-- Possibly add one or more of the following indexes
+-- if your Verifies are too slow.
+--
+-- CREATE INDEX file_pathid_idx on file(pathid);
+-- CREATE INDEX file_filenameid_idx on file(filenameid);
+-- CREATE INDEX file_jpfid_idx on file (jobid, pathid, filenameid);
+
+CREATE TABLE job
(
- pathid serial not null,
- path text not null,
- primary key (pathid)
+ jobid serial not null,
+ job text not null,
+ name text not null,
+ type char(1) not null,
+ level char(1) not null,
+ clientid integer,
+ jobstatus char(1) not null,
+ schedtime timestamp without time zone not null,
+ starttime timestamp without time zone,
+ endtime timestamp without time zone,
+ jobtdate bigint not null,
+ volsessionid integer not null default 0,
+ volsessiontime integer not null default 0,
+ jobfiles integer not null default 0,
+ jobbytes bigint not null default 0,
+ joberrors integer not null default 0,
+ jobmissingfiles integer not null default 0,
+ poolid integer,
+ filesetid integer,
+ purgedfiles smallint not null default 0,
+ hasbase smallint not null default 0,
+ primary key (jobid)
);
-create index path_name_idx on path (path);
+CREATE INDEX job_name_idx on job (name);
-create table fileset
+CREATE TABLE fileset
(
- filesetid serial not null,
- fileset text not null,
- md5 text not null,
+ filesetid serial not null,
+ fileset text not null,
+ md5 text not null,
createtime timestamp without time zone not null,
primary key (filesetid)
);
-create index fileset_name_idx on fileset (fileset);
+CREATE INDEX fileset_name_idx on fileset (fileset);
-create table pool
+CREATE TABLE jobmedia
(
- poolid serial not null,
- name text not null,
- numvols integer not null
- default 0,
- maxvols integer not null
- default 0,
- useonce smallint not null,
- usecatalog smallint not null,
- acceptanyvolume smallint
- default 0,
- volretention bigint not null,
- voluseduration bigint not null,
- maxvoljobs integer not null
- default 0,
- maxvolfiles integer not null
- default 0,
- maxvolbytes bigint not null,
- autoprune smallint not null
- default 0,
- recycle smallint
- default 0,
- pooltype text
- check (pooltype is null or (pooltype in ('Backup','Copy','Cloned','Archive','Migration'))),
- labelformat text not null,
- enabled smallint not null
- default 1,
- scratchpoolid integer ,
- recyclepoolid integer ,
- primary key (poolid)
-);
-
-create index pool_name_idx on pool (name);
-
-create table client
-(
- clientid serial not null,
- name text not null,
- uname text not null,
- autoprune smallint
- default 0,
- fileretention bigint not null,
- jobretention bigint not null,
- primary key (clientid)
+ jobmediaid serial not null,
+ jobid integer not null,
+ mediaid integer not null,
+ firstindex integer not null default 0,
+ lastindex integer not null default 0,
+ startfile integer not null default 0,
+ endfile integer not null default 0,
+ startblock bigint not null default 0,
+ endblock bigint not null default 0,
+ volindex integer not null default 0,
+ primary key (jobmediaid)
);
-create unique index client_name_idx on client (name);
+CREATE INDEX job_media_job_id_media_id_idx on jobmedia (jobid, mediaid);
-create table media
+CREATE TABLE media
(
- mediaid serial not null,
- volumename text not null,
- slot integer not null
- default 0,
- poolid integer not null,
- mediatype text not null,
- firstwritten timestamp without time zone,
- lastwritten timestamp without time zone,
- labeldate timestamp without time zone,
- voljobs integer not null
- default 0,
- volfiles integer not null
- default 0,
- volblocks integer not null
- default 0,
- volmounts integer not null
- default 0,
- volbytes bigint not null
- default 0,
- volparts integer not null
- default 0,
- volerrors integer not null
- default 0,
- volwrites integer not null
- default 0,
- volcapacitybytes bigint not null,
- volstatus text not null
- check (volstatus in ('Full','Archive','Append','Recycle','Purged','Read-Only','Disabled','Error','Busy',
- 'Used','Cleaning')),
- recycle smallint not null
- default 0,
- volretention bigint not null
- default 0,
- voluseduration bigint not null
- default 0,
- maxvoljobs integer not null
- default 0,
- maxvolfiles integer not null
- default 0,
- maxvolbytes bigint not null
- default 0,
- inchanger smallint not null
- default 0,
- mediaaddressing smallint not null
- default 0,
- volreadtime bigint not null
- default 0,
- volwritetime bigint not null
- default 0,
- endfile integer not null
- default 0,
- endblock bigint not null
- default 0,
+ mediaid serial not null,
+ volumename text not null,
+ slot integer not null default 0,
+ poolid integer not null,
+ mediatype text not null,
+ labeltype integer not null default 0,
+ firstwritten timestamp without time zone,
+ lastwritten timestamp without time zone,
+ labeldate timestamp without time zone,
+ voljobs integer not null default 0,
+ volfiles integer not null default 0,
+ volblocks integer not null default 0,
+ volmounts integer not null default 0,
+ volbytes bigint not null default 0,
+ volparts integer not null default 0,
+ volerrors integer not null default 0,
+ volwrites integer not null default 0,
+ volcapacitybytes bigint not null default 0,
+ volstatus text not null
+ check (volstatus in ('Full','Archive','Append',
+ 'Recycle','Purged','Read-Only','Disabled',
+ 'Error','Busy','Used','Cleaning')),
+ recycle smallint not null default 0,
+ volretention bigint not null default 0,
+ voluseduration bigint not null default 0,
+ maxvoljobs integer not null default 0,
+ maxvolfiles integer not null default 0,
+ maxvolbytes bigint not null default 0,
+ inchanger smallint not null default 0,
+ mediaaddressing smallint not null default 0,
+ volreadtime bigint not null default 0,
+ volwritetime bigint not null default 0,
+ endfile integer not null default 0,
+ endblock bigint not null default 0,
primary key (mediaid)
);
create unique index media_volumename_id on media (volumename);
-create table job
+
+CREATE TABLE MediaType (
+ MediaTypeId SERIAL,
+ MediaType TEXT NOT NULL,
+ ReadOnly INTEGER DEFAULT 0,
+ PRIMARY KEY(MediaTypeId)
+ );
+
+CREATE TABLE Device (
+ DeviceId SERIAL,
+ Name TEXT NOT NULL,
+ MediaTypeId INTEGER NOT NULL,
+ StorageId INTEGER UNSIGNED,
+ DevMounts INTEGER NOT NULL DEFAULT 0,
+ DevReadBytes BIGINT NOT NULL DEFAULT 0,
+ DevWriteBytes BIGINT NOT NULL DEFAULT 0,
+ DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0,
+ DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0,
+ DevReadTime BIGINT NOT NULL DEFAULT 0,
+ DevWriteTime BIGINT NOT NULL DEFAULT 0,
+ DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0,
+ DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ CleaningDate TIMESTAMP WITHOUT TIME ZONE,
+ CleaningPeriod BIGINT NOT NULL DEFAULT 0,
+ PRIMARY KEY(DeviceId)
+ );
+
+CREATE TABLE Storage (
+ StorageId SERIAL,
+ Name TEXT NOT NULL,
+ AutoChanger INTEGER DEFAULT 0,
+ PRIMARY KEY(StorageId)
+ );
+
+CREATE TABLE pool
(
- jobid serial not null,
- job text not null,
- name text not null,
- type char(1) not null,
- level char(1) not null,
- clientid integer ,
- jobstatus char(1) not null,
- schedtime timestamp without time zone not null,
- starttime timestamp without time zone ,
- endtime timestamp without time zone ,
- jobtdate bigint not null,
- volsessionid integer not null
- default 0,
- volsessiontime integer not null
- default 0,
- jobfiles integer not null
- default 0,
- jobbytes bigint not null
- default 0,
- joberrors integer not null
- default 0,
- jobmissingfiles integer not null
- default 0,
- poolid integer ,
- filesetid integer ,
- purgedfiles smallint not null
- default 0,
- hasbase smallint not null
- default 0,
- primary key (jobid)
+ poolid serial not null,
+ name text not null,
+ numvols integer not null default 0,
+ maxvols integer not null default 0,
+ useonce smallint not null default 0,
+ usecatalog smallint not null default 0,
+ acceptanyvolume smallint not null default 0,
+ volretention bigint not null default 0,
+ voluseduration bigint not null default 0,
+ maxvoljobs integer not null default 0,
+ maxvolfiles integer not null default 0,
+ maxvolbytes bigint not null default 0,
+ autoprune smallint not null default 0,
+ recycle smallint not null default 0,
+ pooltype text
+ check (pooltype is null or (pooltype in ('Backup','Copy','Cloned','Archive','Migration'))),
+ labelformat text not null,
+ enabled smallint not null default 1,
+ scratchpoolid integer,
+ recyclepoolid integer,
+ primary key (poolid)
);
-create index job_name_idx on job (name);
+CREATE INDEX pool_name_idx on pool (name);
-create table file
+CREATE TABLE client
(
- fileid serial not null,
- fileindex integer not null
- default 0,
- jobid integer not null,
- pathid integer not null,
- filenameid integer not null,
- markid integer not null
- default 0,
- lstat text not null,
- md5 text not null,
- primary key (fileid)
+ clientid serial not null,
+ name text not null,
+ uname text not null,
+ autoprune smallint default 0,
+ fileretention bigint not null,
+ jobretention bigint not null,
+ primary key (clientid)
);
-create index file_jobid_idx on file (jobid);
-create index file_fp_idx on file (filenameid, pathid);
+create unique index client_name_idx on client (name);
+
---
--- Possibly add one or more of the following indexes
--- if your Verifies are too slow.
---
--- create index file_pathid_idx on file(pathid);
--- create index file_filenameid_idx on file(filenameid);
--- create index file_jpfid_idx on file (jobid, pathid, filenameid);
+CREATE TABLE counters
+(
+ counter text not null,
+ minvalue integer,
+ maxvalue integer,
+ currentvalue integer,
+ wrapcounter text not null,
+ primary key (counter)
+);
-create table jobmedia
+CREATE TABLE version
(
- jobmediaid serial not null,
- jobid integer not null,
- mediaid integer not null,
- firstindex integer not null
- default 0,
- lastindex integer not null
- default 0,
- startfile integer not null
- default 0,
- endfile integer not null
- default 0,
- startblock bigint not null
- default 0,
- endblock bigint not null
- default 0,
- volindex integer not null
- default 0,
- primary key (jobmediaid)
+ versionid integer not null
);
-create index job_media_job_id_media_id_idx on jobmedia (jobid, mediaid);
+INSERT INTO Version (VersionId) VALUES (8);
+
-create table basefiles
+CREATE TABLE basefiles
(
baseid serial not null,
jobid integer not null,
primary key (baseid)
);
-create table unsavedfiles
+CREATE TABLE unsavedfiles
(
UnsavedId integer not null,
jobid integer not null,
primary key (UnsavedId)
);
-create table CDImages
+CREATE TABLE CDImages
(
MediaId integer not null,
LastBurn timestamp without time zone not null,
bindir=@SQL_BINDIR@
cd @working_dir@
+sqlite=@DB_NAME@
-$bindir/sqlite $* bacula.db <<END-OF-DATA
+${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
CREATE TABLE Filename (
- FilenameId INTEGER UNSIGNED AUTOINCREMENT,
+ FilenameId INTEGER,
Name TEXT DEFAULT "",
PRIMARY KEY(FilenameId)
);
CREATE INDEX inx1 ON Filename (Name);
CREATE TABLE Path (
- PathId INTEGER UNSIGNED AUTOINCREMENT,
+ PathId INTEGER,
Path TEXT DEFAULT "",
PRIMARY KEY(PathId)
);
CREATE TABLE File (
- FileId INTEGER UNSIGNED AUTOINCREMENT,
+ FileId INTEGER,
FileIndex INTEGER UNSIGNED NOT NULL,
JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
PathId INTEGER UNSIGNED REFERENCES Path NOT NULL,
-- CREATE INDEX inx9 ON File (JobId, PathId, FilenameId);
CREATE TABLE Job (
- JobId INTEGER UNSIGNED NOT NULL,
+ JobId INTEGER,
Job VARCHAR(128) NOT NULL,
Name VARCHAR(128) NOT NULL,
Type CHAR NOT NULL,
CREATE INDEX inx6 ON Job (Name);
CREATE TABLE FileSet (
- FileSetId INTEGER UNSIGNED AUTOINCREMENT,
+ FileSetId INTEGER,
FileSet VARCHAR(128) NOT NULL,
MD5 VARCHAR(25) NOT NULL,
CreateTime DATETIME DEFAULT 0,
);
CREATE TABLE JobMedia (
- JobMediaId INTEGER UNSIGNED AUTOINCREMENT,
+ JobMediaId INTEGER,
JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
FirstIndex INTEGER UNSIGNED NOT NULL,
CREATE TABLE Media (
- MediaId INTEGER UNSIGNED AUTOINCREMENT,
+ MediaId INTEGER,
VolumeName VARCHAR(128) NOT NULL,
Slot INTEGER DEFAULT 0,
PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
MediaType VARCHAR(128) NOT NULL,
+ LabelType TINYINT DEFAULT 0,
FirstWritten DATETIME DEFAULT 0,
LastWritten DATETIME DEFAULT 0,
LabelDate DATETIME DEFAULT 0,
MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
InChanger TINYINT DEFAULT 0,
+ StorageId INTEGER UNSIGNED REFERENCES Storage,
MediaAddressing TINYINT DEFAULT 0,
VolReadTime BIGINT UNSIGNED DEFAULT 0,
VolWriteTime BIGINT UNSIGNED DEFAULT 0,
CREATE INDEX inx8 ON Media (PoolId);
+CREATE TABLE MediaType (
+ MediaTypeId INTERGER,
+ MediaType VARCHAR(128) NOT NULL,
+ ReadOnly TINYINT DEFAULT 0,
+ PRIMARY KEY(MediaTypeId)
+ );
+
+CREATE TABLE Device (
+ DeviceId INTEGER,
+ Name VARCHAR(128) NOT NULL,
+ MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
+ StorageId INTEGER UNSIGNED REFERENCES Storage,
+ DevMounts INTEGER UNSIGNED DEFAULT 0,
+ DevReadBytes BIGINT UNSIGNED DEFAULT 0,
+ DevWriteBytes BIGINT UNSIGNED DEFAULT 0,
+ DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ DevReadTime BIGINT UNSIGNED DEFAULT 0,
+ DevWriteTime BIGINT UNSIGNED DEFAULT 0,
+ DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+ CleaningDate DATETIME DEFAULT 0,
+ CleaningPeriod BIGINT UNSIGNED DEFAULT 0,
+ PRIMARY KEY(DeviceId)
+ );
+
+CREATE TABLE Storage (
+ StorageId INTEGER,
+ Name VARCHAR(128) NOT NULL,
+ AutoChanger TINYINT DEFAULT 0,
+ PRIMARY KEY(StorageId)
+ );
+
+
CREATE TABLE Pool (
- PoolId INTEGER UNSIGNED AUTOINCREMENT,
+ PoolId INTEGER,
Name VARCHAR(128) NOT NULL,
NumVols INTEGER UNSIGNED DEFAULT 0,
MaxVols INTEGER UNSIGNED DEFAULT 0,
CREATE TABLE Client (
- ClientId INTEGER UNSIGNED AUTOINCREMENT,
+ ClientId INTEGER,
Name VARCHAR(128) NOT NULL,
Uname VARCHAR(255) NOT NULL, -- uname -a field
AutoPrune TINYINT DEFAULT 0,
);
CREATE TABLE BaseFiles (
- BaseId INTEGER UNSIGNED AUTOINCREMENT,
+ BaseId INTEGER,
BaseJobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
FileId INTEGER UNSIGNED REFERENCES File NOT NULL,
);
CREATE TABLE UnsavedFiles (
- UnsavedId INTEGER UNSIGNED AUTOINCREMENT,
+ UnsavedId INTEGER,
JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
PathId INTEGER UNSIGNED REFERENCES Path NOT NULL,
FilenameId INTEGER UNSIGNED REFERENCES Filename NOT NULL,
int db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
int db_create_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *media_dbr);
int db_create_client_record(JCR *jcr, B_DB *db, CLIENT_DBR *cr);
-int db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr);
-int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);
+bool db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr);
+bool db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);
bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jr);
int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
+bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr);
+bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr);
+bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr);
/* delete.c */
int db_delete_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);
int db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
-int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames);
+int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames);
int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr);
int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr);
int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
int db_get_num_media_records(JCR *jcr, B_DB *mdb);
int db_get_num_pool_records(JCR *jcr, B_DB *mdb);
-int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t **ids);
-int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t **ids);
-int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t **ids);
-int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams);
+int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, DBId_t **ids);
+int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, DBId_t **ids);
+int db_get_media_ids(JCR *jcr, B_DB *mdb, DBId_t PoolId, int *num_ids, uint32_t **ids);
+int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS **VolParams);
int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr);
int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
void db_list_job_totals(JCR *jcr, B_DB *db, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx);
void db_list_files_for_job(JCR *jcr, B_DB *db, uint32_t jobid, DB_LIST_HANDLER sendit, void *ctx);
void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
+void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
int db_list_sql_query(JCR *jcr, B_DB *mdb, char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
uint32_t bacula_db_version = 0;
m_msg(file, line, &mdb->errmsg, _("query %s failed:\n%s\n"), cmd, sql_strerror(mdb));
j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg);
if (verbose) {
- j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+ j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
return 0;
}
m_msg(file, line, &mdb->errmsg, _("insert %s failed:\n%s\n"), cmd, sql_strerror(mdb));
j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg);
if (verbose) {
- j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+ j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
return 0;
}
m_msg(file, line, &mdb->errmsg, _("Insertion problem: affected_rows=%s\n"),
edit_uint64(mdb->num_rows, ed1));
if (verbose) {
- j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+ j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
return 0;
}
m_msg(file, line, &mdb->errmsg, _("update %s failed:\n%s\n"), cmd, sql_strerror(mdb));
j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg);
if (verbose) {
- j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+ j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
return 0;
}
m_msg(file, line, &mdb->errmsg, _("delete %s failed:\n%s\n"), cmd, sql_strerror(mdb));
j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg);
if (verbose) {
- j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
+ j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
return -1;
}
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
stat = -1;
} else {
stat = atoi(row[0]);
for (i = 0; i < sql_num_fields(mdb); i++) {
field = sql_fetch_field(mdb);
for (j = 0; j < (int)field->max_length + 2; j++) {
- send(ctx, "-");
+ send(ctx, "-");
}
send(ctx, "+");
}
col_len = field->max_length;
}
if (col_len < 4 && !IS_NOT_NULL(field->flags)) {
- col_len = 4; /* 4 = length of the word "NULL" */
+ col_len = 4; /* 4 = length of the word "NULL" */
}
field->max_length = col_len; /* reset column info */
}
for (i = 0; i < sql_num_fields(mdb); i++) {
field = sql_fetch_field(mdb);
if (row[i] == NULL) {
- bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL");
+ bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL");
} else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
- bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length,
+ bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length,
add_commas(row[i], ewc));
} else {
- bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]);
+ bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]);
}
send(ctx, buf);
}
for (i = 0; i < sql_num_fields(mdb); i++) {
field = sql_fetch_field(mdb);
if (row[i] == NULL) {
- bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
+ bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
} else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
- bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
+ bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
add_commas(row[i], ewc));
} else {
- bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
+ bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
}
send(ctx, buf);
}
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
/* -----------------------------------------------------------------------
*
count++;
Mmsg(mdb->cmd,
- "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
- "StartFile,EndFile,StartBlock,EndBlock,VolIndex) "
- "VALUES (%u,%u,%u,%u,%u,%u,%u,%u,%u)",
+ "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
+ "StartFile,EndFile,StartBlock,EndBlock,VolIndex) "
+ "VALUES (%u,%u,%u,%u,%u,%u,%u,%u,%u)",
jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex,
jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count);
} else {
/* Worked, now update the Media record with the EndFile and EndBlock */
Mmsg(mdb->cmd,
- "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
+ "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
jm->EndFile, jm->EndBlock, jm->MediaId);
if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
- Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
+ Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
sql_strerror(mdb));
ok = false;
}
/* Create Unique Pool record
- * Returns: 0 on failure
- * 1 on success
+ * Returns: false on failure
+ * true on success
*/
-int
+bool
db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
{
- int stat;
+ bool stat;
char ed1[30], ed2[30], ed3[50];
Dmsg0(200, "In create pool\n");
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 0) {
- Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
+ Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
sql_free_result(mdb);
db_unlock(mdb);
- return 0;
+ return false;
}
sql_free_result(mdb);
}
Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
mdb->cmd, sql_strerror(mdb));
pr->PoolId = 0;
- stat = 0;
+ stat = false;
} else {
pr->PoolId = sql_insert_id(mdb, _("Pool"));
- stat = 1;
+ stat = true;
}
db_unlock(mdb);
+ return stat;
+}
+
+/*
+ * Create Unique Device record
+ * Returns: false on failure
+ * true on success
+ */
+bool
+db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
+{
+ bool stat;
+ char ed1[30], ed2[30];
+
+ Dmsg0(200, "In create Device\n");
+ db_lock(mdb);
+ Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
+ Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
+
+ if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+ mdb->num_rows = sql_num_rows(mdb);
+ if (mdb->num_rows > 0) {
+ Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
+ sql_free_result(mdb);
+ db_unlock(mdb);
+ return false;
+ }
+ sql_free_result(mdb);
+ }
+ /* Must create it */
+ Mmsg(mdb->cmd,
+"INSERT INTO Device (Name,MediaTypeId,StorageId) "
+"VALUES ('%s',%s,%s)",
+ dr->Name,
+ edit_uint64(dr->MediaTypeId, ed1),
+ edit_uint64(dr->StorageId, ed2));
+ Dmsg1(200, "Create Device: %s\n", mdb->cmd);
+ if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+ Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
+ mdb->cmd, sql_strerror(mdb));
+ dr->DeviceId = 0;
+ stat = false;
+ } else {
+ dr->DeviceId = sql_insert_id(mdb, _("Device"));
+ stat = true;
+ }
+ db_unlock(mdb);
+ return stat;
+}
+
+/*
+ * Create Unique storage record
+ * Returns: false on failure
+ * true on success
+ */
+bool
+db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
+{
+ bool stat;
+
+ Dmsg0(200, "In create storage\n");
+ db_lock(mdb);
+ Mmsg(mdb->cmd, "SELECT StorageId,Name FROM Storage WHERE Name='%s'", sr->Name);
+ Dmsg1(200, "selectstorage: %s\n", mdb->cmd);
+
+ if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+ mdb->num_rows = sql_num_rows(mdb);
+ if (mdb->num_rows > 0) {
+ Mmsg1(&mdb->errmsg, _("Storage record %s already exists\n"), sr->Name);
+ sql_free_result(mdb);
+ db_unlock(mdb);
+ return false;
+ }
+ sql_free_result(mdb);
+ }
+
+ /* Must create it */
+ Mmsg(mdb->cmd,
+"INSERT INTO Storage (Name,AutoChanger) "
+"VALUES ('%s',%d)",
+ sr->Name,
+ sr->AutoChanger);
+ Dmsg1(200, "Create storage: %s\n", mdb->cmd);
+ if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+ Mmsg2(&mdb->errmsg, _("Create db storage record %s failed: ERR=%s\n"),
+ mdb->cmd, sql_strerror(mdb));
+ sr->StorageId = 0;
+ stat = false;
+ } else {
+ sr->StorageId = sql_insert_id(mdb, _("Storage"));
+ stat = true;
+ }
+ db_unlock(mdb);
return stat;
}
+/*
+ * Create Unique MediaType record
+ * Returns: false on failure
+ * true on success
+ */
+bool
+db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
+{
+ bool stat;
+
+ Dmsg0(200, "In create mediatype\n");
+ db_lock(mdb);
+ Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
+ Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
+
+ if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+ mdb->num_rows = sql_num_rows(mdb);
+ if (mdb->num_rows > 0) {
+ Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
+ sql_free_result(mdb);
+ db_unlock(mdb);
+ return false;
+ }
+ sql_free_result(mdb);
+ }
+
+ /* Must create it */
+ Mmsg(mdb->cmd,
+"INSERT INTO MediaType (MediaType,ReadOnly) "
+"VALUES ('%s',%d)",
+ mr->MediaType,
+ mr->ReadOnly);
+ Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
+ if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+ Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
+ mdb->cmd, sql_strerror(mdb));
+ mr->MediaTypeId = 0;
+ stat = false;
+ } else {
+ mr->MediaTypeId = sql_insert_id(mdb, _("MediaType"));
+ stat = true;
+ }
+ db_unlock(mdb);
+ return stat;
+}
+
+
+
+
/*
* Create Media record. VolumeName and non-zero Slot must be unique
*
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 0) {
- Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
+ Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
sql_free_result(mdb);
db_unlock(mdb);
return 0;
"INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes,"
"Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
"VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
-"EndFile,EndBlock) "
-"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0)",
+"EndFile,EndBlock,LabelType) "
+"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d)",
mr->VolumeName,
mr->MediaType, mr->PoolId,
edit_uint64(mr->MaxVolBytes,ed1),
mr->InChanger,
edit_uint64(mr->VolReadTime, ed6),
edit_uint64(mr->VolWriteTime, ed7),
- mr->VolParts
+ mr->VolParts,
+ mr->LabelType
);
if (mr->LabelDate) {
char dt[MAX_TIME_LENGTH];
localtime_r(&mr->LabelDate, &tm);
- strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
- Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
- "WHERE MediaId=%d", dt, mr->MediaId);
+ strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
+ Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
+ "WHERE MediaId=%d", dt, mr->MediaId);
stat = UPDATE_DB(jcr, mdb, mdb->cmd);
}
}
{
SQL_ROW row;
int stat;
- char ed1[30], ed2[30];
+ char ed1[50], ed2[50];
db_lock(mdb);
Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
mdb->num_rows = sql_num_rows(mdb);
/* If more than one, report error, but return first row */
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
}
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
sql_free_result(mdb);
db_unlock(mdb);
return 0;
}
- cr->ClientId = atoi(row[0]);
+ cr->ClientId = str_to_int64(row[0]);
if (row[1]) {
bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
} else {
}
/* Must create it */
- Mmsg(mdb->cmd, "INSERT INTO Client (Name, Uname, AutoPrune, "
-"FileRetention, JobRetention) VALUES "
-"('%s', '%s', %d, %s, %s)", cr->Name, cr->Uname, cr->AutoPrune,
+ Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
+"FileRetention,JobRetention) VALUES "
+"('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
edit_uint64(cr->FileRetention, ed1),
edit_uint64(cr->JobRetention, ed2));
* Returns: 0 on failure
* 1 on success with FileSetId in record
*/
-int db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
+bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
{
SQL_ROW row;
- int stat;
+ bool stat;
struct tm tm;
db_lock(mdb);
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
}
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
sql_free_result(mdb);
db_unlock(mdb);
- return 0;
+ return false;
}
- fsr->FileSetId = atoi(row[0]);
+ fsr->FileSetId = str_to_int64(row[0]);
if (row[1] == NULL) {
fsr->cCreateTime[0] = 0;
} else {
}
sql_free_result(mdb);
db_unlock(mdb);
- return 1;
+ return true;
}
sql_free_result(mdb);
}
mdb->cmd, sql_strerror(mdb));
Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
fsr->FileSetId = 0;
- stat = 0;
+ stat = false;
} else {
fsr->FileSetId = sql_insert_id(mdb, _("FileSet"));
fsr->created = true;
- stat = 1;
+ stat = true;
}
db_unlock(mdb);
/* Must create it */
Mmsg(mdb->cmd,
- "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
- "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')",
+ "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
+ "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')",
ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
ar->attr);
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
char ed1[30];
- Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
+ Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
edit_uint64(mdb->num_rows, ed1), mdb->path);
- Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
}
/* Even if there are multiple paths, take the first one */
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
sql_free_result(mdb);
ar->PathId = 0;
ASSERT(ar->PathId);
return 0;
}
- ar->PathId = atoi(row[0]);
+ ar->PathId = str_to_int64(row[0]);
sql_free_result(mdb);
/* Cache path */
if (ar->PathId != mdb->cached_path_id) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
char ed1[30];
- Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
+ Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
edit_uint64(mdb->num_rows, ed1), mdb->fname);
- Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
}
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
+ Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
mdb->fname, sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
ar->FilenameId = 0;
} else {
- ar->FilenameId = atoi(row[0]);
+ ar->FilenameId = str_to_int64(row[0]);
}
sql_free_result(mdb);
return ar->FilenameId > 0;
return ar->FilenameId > 0;
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
*/
/*
- Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
/* -----------------------------------------------------------------------
*
* Generic Routines (or almost generic)
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows == 0) {
- Mmsg(mdb->errmsg, _("No pool record %s exists\n"), pr->Name);
+ Mmsg(mdb->errmsg, _("No pool record %s exists\n"), pr->Name);
sql_free_result(mdb);
db_unlock(mdb);
return 0;
} else if (mdb->num_rows != 1) {
- Mmsg(mdb->errmsg, _("Expecting one pool record, got %d\n"), mdb->num_rows);
+ Mmsg(mdb->errmsg, _("Expecting one pool record, got %d\n"), mdb->num_rows);
sql_free_result(mdb);
db_unlock(mdb);
return 0;
}
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("Error fetching row %s\n"), sql_strerror(mdb));
+ Mmsg1(&mdb->errmsg, _("Error fetching row %s\n"), sql_strerror(mdb));
db_unlock(mdb);
return 0;
}
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
/* -----------------------------------------------------------------------
*
* backup
*/
if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
- Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"),
+ Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"),
sql_strerror(mdb), mdb->cmd);
db_unlock(mdb);
return 0;
}
if ((row = sql_fetch_row(mdb)) == NULL) {
sql_free_result(mdb);
- Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n"));
+ Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n"));
db_unlock(mdb);
return 0;
}
jr->JobType, L_INCREMENTAL, L_DIFFERENTIAL, L_FULL, jr->Name,
jr->ClientId, jr->FileSetId);
} else {
- Mmsg1(&mdb->errmsg, _("Unknown level=%d\n"), jr->JobLevel);
+ Mmsg1(&mdb->errmsg, _("Unknown level=%d\n"), jr->JobLevel);
db_unlock(mdb);
return 0;
}
if (item == -1) { /* find oldest volume */
/* Find oldest volume */
Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
- "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
- "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
- "FirstWritten,LastWritten,VolStatus,InChanger,VolParts "
- "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus IN ('Full',"
- "'Recycle','Purged','Used','Append') "
- "ORDER BY LastWritten LIMIT 1", mr->PoolId, mr->MediaType);
+ "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+ "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
+ "FirstWritten,LastWritten,VolStatus,InChanger,VolParts,"
+ "LabelType "
+ "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus IN ('Full',"
+ "'Recycle','Purged','Used','Append') "
+ "ORDER BY LastWritten LIMIT 1", mr->PoolId, mr->MediaType);
item = 1;
} else {
/* Find next available volume */
if (InChanger) {
- changer = "AND InChanger=1";
+ changer = "AND InChanger=1";
} else {
- changer = "";
+ changer = "";
}
if (strcmp(mr->VolStatus, "Recycled") == 0 ||
- strcmp(mr->VolStatus, "Purged") == 0) {
- order = "ORDER BY LastWritten ASC,MediaId"; /* take oldest */
+ strcmp(mr->VolStatus, "Purged") == 0) {
+ order = "ORDER BY LastWritten ASC,MediaId"; /* take oldest */
} else {
- order = "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId"; /* take most recently written */
+ order = "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId"; /* take most recently written */
}
Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
- "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
- "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
- "FirstWritten,LastWritten,VolStatus,InChanger,VolParts "
- "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
- "%s "
- "%s LIMIT %d",
+ "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+ "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
+ "FirstWritten,LastWritten,VolStatus,InChanger,VolParts,"
+ "LabelType "
+ "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
+ "%s "
+ "%s LIMIT %d",
mr->PoolId, mr->MediaType, mr->VolStatus, changer, order, item);
}
if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
bstrncpy(mr->VolStatus, row[19], sizeof(mr->VolStatus));
mr->InChanger = str_to_int64(row[20]);
mr->VolParts = str_to_int64(row[21]);
+ mr->LabelType = str_to_int64(row[22]);
sql_free_result(mdb);
db_unlock(mdb);
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
/* -----------------------------------------------------------------------
*
mdb->num_rows = sql_num_rows(mdb);
Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows);
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
+ Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
mdb->num_rows);
}
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
+ Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
} else {
fdbr->FileId = (FileId_t)str_to_int64(row[0]);
bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
stat = 1;
}
} else {
- Mmsg2(&mdb->errmsg, _("File record for PathId=%u FilenameId=%u not found.\n"),
+ Mmsg2(&mdb->errmsg, _("File record for PathId=%u FilenameId=%u not found.\n"),
fdbr->PathId, fdbr->FilenameId);
}
sql_free_result(mdb);
char ed1[30];
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"),
+ Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"),
edit_uint64(mdb->num_rows, ed1), mdb->fname);
- Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
}
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
} else {
FilenameId = atoi(row[0]);
if (FilenameId <= 0) {
- Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
+ Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
mdb->cmd, FilenameId);
FilenameId = 0;
}
}
} else {
- Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname);
+ Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname);
}
sql_free_result(mdb);
} else {
char ed1[30];
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
- Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
+ Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
edit_uint64(mdb->num_rows, ed1), mdb->path);
- Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
}
/* Even if there are multiple paths, take the first one */
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
} else {
PathId = atoi(row[0]);
if (PathId <= 0) {
- Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %u\n"),
+ Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %u\n"),
mdb->cmd, PathId);
PathId = 0;
} else {
}
}
} else {
- Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path);
+ Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path);
}
sql_free_result(mdb);
} else {
*
* Returns: number of volumes on success
*/
-int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
+int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames)
{
SQL_ROW row;
+ char ed1[50];
int stat = 0;
int i;
db_lock(mdb);
/* Get one entry per VolumeName, but "sort" by VolIndex */
Mmsg(mdb->cmd,
- "SELECT VolumeName,MAX(VolIndex) FROM JobMedia,Media WHERE "
- "JobMedia.JobId=%u AND JobMedia.MediaId=Media.MediaId "
- "GROUP BY VolumeName "
- "ORDER BY 2 ASC", JobId);
+ "SELECT VolumeName,MAX(VolIndex) FROM JobMedia,Media WHERE "
+ "JobMedia.JobId=%s AND JobMedia.MediaId=Media.MediaId "
+ "GROUP BY VolumeName "
+ "ORDER BY 2 ASC", edit_uint64(JobId,ed1));
Dmsg1(130, "VolNam=%s\n", mdb->cmd);
*VolumeNames[0] = 0;
mdb->num_rows = sql_num_rows(mdb);
Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
if (mdb->num_rows <= 0) {
- Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
+ Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
stat = 0;
} else {
stat = mdb->num_rows;
for (i=0; i < stat; i++) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
stat = 0;
break;
} else {
if (*VolumeNames[0] != 0) {
- pm_strcat(VolumeNames, "|");
+ pm_strcat(VolumeNames, "|");
}
pm_strcat(VolumeNames, row[0]);
}
*
* Returns: number of volumes on success
*/
-int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
+int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS **VolParams)
{
SQL_ROW row;
+ char ed1[50];
int stat = 0;
int i;
VOL_PARAMS *Vols = NULL;
db_lock(mdb);
Mmsg(mdb->cmd,
-"SELECT VolumeName,FirstIndex,LastIndex,StartFile,JobMedia.EndFile,"
-"StartBlock,JobMedia.EndBlock"
-" FROM JobMedia,Media WHERE JobMedia.JobId=%u"
-" AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId", JobId);
+"SELECT VolumeName,MediaType,FirstIndex,LastIndex,StartFile,"
+"JobMedia.EndFile,StartBlock,JobMedia.EndBlock"
+" FROM JobMedia,Media WHERE JobMedia.JobId=%s"
+" AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId",
+ edit_int64(JobId, ed1));
Dmsg1(130, "VolNam=%s\n", mdb->cmd);
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
if (mdb->num_rows <= 0) {
- Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
+ Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
stat = 0;
} else {
stat = mdb->num_rows;
}
for (i=0; i < stat; i++) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
stat = 0;
break;
} else {
bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
- Vols[i].FirstIndex = str_to_uint64(row[1]);
- Vols[i].LastIndex = str_to_uint64(row[2]);
- Vols[i].StartFile = str_to_uint64(row[3]);
- Vols[i].EndFile = str_to_uint64(row[4]);
- Vols[i].StartBlock = str_to_uint64(row[5]);
- Vols[i].EndBlock = str_to_uint64(row[6]);
+ bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
+ Vols[i].FirstIndex = str_to_uint64(row[2]);
+ Vols[i].LastIndex = str_to_uint64(row[3]);
+ Vols[i].StartFile = str_to_uint64(row[4]);
+ Vols[i].EndFile = str_to_uint64(row[5]);
+ Vols[i].StartBlock = str_to_uint64(row[6]);
+ Vols[i].EndBlock = str_to_uint64(row[7]);
}
}
}
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
char ed1[30];
- Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
+ Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
edit_uint64(mdb->num_rows, ed1));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
} else if (mdb->num_rows == 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
} else {
pdbr->PoolId = str_to_int64(row[0]);
- bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
+ bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
pdbr->NumVols = str_to_int64(row[2]);
pdbr->MaxVols = str_to_int64(row[3]);
pdbr->UseOnce = str_to_int64(row[4]);
pdbr->MaxVolJobs = str_to_int64(row[11]);
pdbr->MaxVolFiles = str_to_int64(row[12]);
pdbr->MaxVolBytes = str_to_uint64(row[13]);
- bstrncpy(pdbr->PoolType, row[13]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
- bstrncpy(pdbr->LabelFormat, row[14]!=NULL?row[15]:"", sizeof(pdbr->LabelFormat));
+ bstrncpy(pdbr->PoolType, row[13]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
+ bstrncpy(pdbr->LabelFormat, row[14]!=NULL?row[15]:"", sizeof(pdbr->LabelFormat));
stat = pdbr->PoolId;
}
} else {
- Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
+ Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
}
sql_free_result(mdb);
} else {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
char ed1[30];
- Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"),
+ Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"),
edit_uint64(mdb->num_rows, ed1));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
} else if (mdb->num_rows == 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
} else {
cdbr->ClientId = str_to_int64(row[0]);
- bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name));
- bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname));
+ bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name));
+ bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname));
cdbr->AutoPrune = str_to_int64(row[3]);
cdbr->FileRetention = str_to_int64(row[4]);
cdbr->JobRetention = str_to_int64(row[5]);
stat = 1;
}
} else {
- Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n"));
+ Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n"));
}
sql_free_result(mdb);
} else {
/* If more than one, report error, but return first row */
if (mdb->num_rows > 1) {
- Mmsg1(&mdb->errmsg, _("More than one Counter!: %d\n"), (int)(mdb->num_rows));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("More than one Counter!: %d\n"), (int)(mdb->num_rows));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
}
if (mdb->num_rows >= 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
sql_free_result(mdb);
db_unlock(mdb);
return 0;
db_lock(mdb);
if (fsr->FileSetId != 0) { /* find by id */
Mmsg(mdb->cmd,
- "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet "
- "WHERE FileSetId=%u", fsr->FileSetId);
+ "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet "
+ "WHERE FileSetId=%u", fsr->FileSetId);
} else { /* find by name */
Mmsg(mdb->cmd,
- "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
- "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet);
+ "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
+ "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet);
}
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
char ed1[30];
- Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"),
+ Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"),
edit_uint64(mdb->num_rows, ed1));
sql_data_seek(mdb, mdb->num_rows-1);
}
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
+ Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
} else {
fsr->FileSetId = atoi(row[0]);
- bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
- bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5));
- bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime));
+ bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
+ bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5));
+ bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime));
stat = fsr->FileSetId;
}
sql_free_result(mdb);
}
if (mr->MediaId != 0) { /* find by id */
Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
- "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
- "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
- "Recycle,Slot,FirstWritten,LastWritten,InChanger,EndFile,EndBlock,VolParts "
- "FROM Media WHERE MediaId=%d", mr->MediaId);
+ "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+ "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
+ "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger,"
+ "EndFile,EndBlock,VolParts,LabelType "
+ "FROM Media WHERE MediaId=%u", mr->MediaId);
} else { /* find by name */
Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
- "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
- "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
- "Recycle,Slot,FirstWritten,LastWritten,InChanger,EndFile,EndBlock,VolParts "
- "FROM Media WHERE VolumeName='%s'", mr->VolumeName);
+ "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+ "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
+ "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger,"
+ "EndFile,EndBlock,VolParts,LabelType "
+ "FROM Media WHERE VolumeName='%s'", mr->VolumeName);
}
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
mdb->num_rows = sql_num_rows(mdb);
if (mdb->num_rows > 1) {
char ed1[30];
- Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
+ Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
edit_uint64(mdb->num_rows, ed1));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
} else if (mdb->num_rows == 1) {
if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
- Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+ Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
} else {
/* return values */
mr->MediaId = str_to_int64(row[0]);
- bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
+ bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
mr->VolJobs = str_to_int64(row[2]);
mr->VolFiles = str_to_int64(row[3]);
mr->VolBlocks = str_to_int64(row[4]);
mr->VolWrites = str_to_int64(row[8]);
mr->MaxVolBytes = str_to_uint64(row[9]);
mr->VolCapacityBytes = str_to_uint64(row[10]);
- bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType));
- bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus));
+ bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType));
+ bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus));
mr->PoolId = str_to_int64(row[13]);
mr->VolRetention = str_to_uint64(row[14]);
mr->VolUseDuration = str_to_uint64(row[15]);
mr->MaxVolFiles = str_to_int64(row[17]);
mr->Recycle = str_to_int64(row[18]);
mr->Slot = str_to_int64(row[19]);
- bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten));
+ bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten));
mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten);
- bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten));
+ bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten));
mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten);
mr->InChanger = str_to_uint64(row[22]);
mr->EndFile = str_to_uint64(row[23]);
mr->EndBlock = str_to_uint64(row[24]);
mr->VolParts = str_to_int64(row[25]);
+ mr->LabelType = str_to_int64(row[26]);
stat = mr->MediaId;
}
} else {
if (mr->MediaId != 0) {
- Mmsg1(&mdb->errmsg, _("Media record MediaId=%u not found.\n"), mr->MediaId);
+ Mmsg1(&mdb->errmsg, _("Media record MediaId=%u not found.\n"), mr->MediaId);
} else {
- Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
+ Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
mr->VolumeName);
}
}
sql_free_result(mdb);
} else {
- Mmsg(mdb->errmsg, _("Media record not found in Catalog.\n"));
- }
+ if (mr->MediaId != 0) {
+ Mmsg(mdb->errmsg, _("Media record for MediaId=%u not found in Catalog.\n"),
+ mr->MediaId);
+ } else {
+ Mmsg(mdb->errmsg, _("Media record for Vol=%s not found in Catalog.\n"),
+ mr->VolumeName);
+ } }
db_unlock(mdb);
return stat;
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
*/
/*
- Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
/* -----------------------------------------------------------------------
*
"VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
"VolCapacityBytes,VolStatus,Recycle,VolRetention,"
"VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
- "EndFile,EndBlock,VolParts "
+ "EndFile,EndBlock,VolParts,LabelType "
"FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
} else {
Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
"VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
"VolCapacityBytes,VolStatus,Recycle,VolRetention,"
"VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
- "EndFile,EndBlock,VolParts "
+ "EndFile,EndBlock,VolParts,LabelType "
"FROM Media WHERE Media.PoolId=%u ORDER BY MediaId", mdbr->PoolId);
}
} else {
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "cats.h"
-#if HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
+#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
/* -----------------------------------------------------------------------
*
*
*/
void edit_num_or_null(char *s, size_t n, uint32_t id) {
- bsnprintf(s, n, id ? "%u" : "NULL", id);
+ bsnprintf(s, n, id ? "%u" : "NULL", id);
}
time_t ttime;
struct tm tm;
int stat;
- char ed1[30], ed2[30], ed3[30], ed4[30], ed5[30];
+ char ed1[30], ed2[30], ed3[30], ed4[30];
Dmsg1(100, "update_media: FirstWritten=%d\n", mr->FirstWritten);
localtime_r(&ttime, &tm);
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
- "WHERE VolumeName='%s'", dt, mr->VolumeName);
+ "WHERE VolumeName='%s'", dt, mr->VolumeName);
stat = UPDATE_DB(jcr, mdb, mdb->cmd);
}
strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
Mmsg(mdb->cmd, "UPDATE Media SET VolJobs=%u,"
- "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
- "VolWrites=%u,MaxVolBytes=%s,LastWritten='%s',VolStatus='%s',"
- "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%s "
- " WHERE VolumeName='%s'",
+ "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
+ "VolWrites=%u,MaxVolBytes=%s,LastWritten='%s',VolStatus='%s',"
+ "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d,"
+ "LabelType=%d"
+ " WHERE VolumeName='%s'",
mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
mr->VolMounts, mr->VolErrors, mr->VolWrites,
edit_uint64(mr->MaxVolBytes, ed2), dt,
mr->VolStatus, mr->Slot, mr->InChanger,
edit_uint64(mr->VolReadTime, ed3),
edit_uint64(mr->VolWriteTime, ed4),
- edit_uint64(mr->VolParts, ed5),
+ mr->VolParts,
+ mr->LabelType,
mr->VolumeName);
} else {
Mmsg(mdb->cmd, "UPDATE Media SET VolJobs=%u,"
- "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
- "VolWrites=%u,MaxVolBytes=%s,VolStatus='%s',"
- "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%s "
- " WHERE VolumeName='%s'",
+ "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u,"
+ "VolWrites=%u,MaxVolBytes=%s,VolStatus='%s',"
+ "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d,"
+ "LabelType=%d"
+ " WHERE VolumeName='%s'",
mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
mr->VolMounts, mr->VolErrors, mr->VolWrites,
edit_uint64(mr->MaxVolBytes, ed2),
mr->VolStatus, mr->Slot, mr->InChanger,
edit_uint64(mr->VolReadTime, ed3),
edit_uint64(mr->VolWriteTime, ed4),
- edit_uint64(mr->VolParts, ed5),
+ mr->VolParts,
+ mr->LabelType,
mr->VolumeName);
}
db_lock(mdb);
if (mr->VolumeName[0]) {
Mmsg(mdb->cmd, "UPDATE Media SET "
- "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
- "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
- " WHERE VolumeName='%s'",
+ "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+ "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
+ " WHERE VolumeName='%s'",
mr->Recycle,edit_uint64(mr->VolRetention, ed1),
edit_uint64(mr->VolUseDuration, ed2),
mr->MaxVolJobs, mr->MaxVolFiles,
mr->VolumeName);
} else {
Mmsg(mdb->cmd, "UPDATE Media SET "
- "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
- "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
- " WHERE PoolId=%u",
+ "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+ "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
+ " WHERE PoolId=%u",
mr->Recycle,edit_uint64(mr->VolRetention, ed1),
edit_uint64(mr->VolUseDuration, ed2),
mr->MaxVolJobs, mr->MaxVolFiles,
{
if (mr->InChanger != 0 && mr->Slot != 0) {
Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE "
- "Slot=%d AND PoolId=%u AND MediaId!=%u",
+ "Slot=%d AND PoolId=%u AND MediaId!=%u",
mr->Slot, mr->PoolId, mr->MediaId);
Dmsg1(400, "%s\n", mdb->cmd);
UPDATE_DB(jcr, mdb, mdb->cmd);
return;
}
-#endif /* HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
+#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
#include "bacula.h"
#include "cats.h"
-#ifdef HAVE_SQLITE
+#if HAVE_SQLITE || HAVE_SQLITE3
/* -----------------------------------------------------------------------
*
if (!mult_db_connections) {
for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
if (strcmp(mdb->db_name, db_name) == 0) {
- Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
+ Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
mdb->ref_count++;
V(mutex);
return mdb; /* already open */
V(mutex);
return 0;
}
+
+#ifdef HAVE_SQLITE3
+ int stat = sqlite3_open(db_name, &mdb->db);
+ if (stat != SQLITE_OK) {
+ mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db);
+ } else {
+ mdb->sqlite_errmsg = NULL;
+ }
+
+#else
mdb->db = sqlite_open(
db_name, /* database name */
644, /* mode */
&mdb->sqlite_errmsg); /* error message */
+#endif
Dmsg0(300, "sqlite_open\n");
if (mdb->db == NULL) {
Mmsg2(&mdb->errmsg, _("Unable to open Database=%s. ERR=%s\n"),
- db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
+ db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
free(db_name);
V(mutex);
return 0;
return 0;
}
- mdb->connected = TRUE;
+ mdb->connected = true;
V(mutex);
return 1;
}
*/
int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
{
+#ifdef xxxx
SQL_ROW row;
db_lock(mdb);
sql_free_result(mdb);
db_unlock(mdb);
+#endif
+ strcpy(index, "NULL");
return 1;
}
while (len--) {
switch (*o) {
case '\'':
- *n++ = '\'';
- *n++ = '\'';
+ *n++ = '\'';
+ *n++ = '\'';
o++;
break;
case 0:
- *n++ = '\\';
+ *n++ = '\\';
*n++ = 0;
o++;
break;
db_lock(mdb);
if (mdb->sqlite_errmsg) {
+#ifdef HAVE_SQLITE3
+ sqlite3_free(mdb->sqlite_errmsg);
+#else
actuallyfree(mdb->sqlite_errmsg);
+#endif
mdb->sqlite_errmsg = NULL;
}
rh_data.result_handler = result_handler;
return mdb->fields[mdb->field++];
}
-
-
#endif /* HAVE_SQLITE */
# This routine alters the appropriately configured
# Bacula tables for PostgreSQL, MySQL, or SQLite.
#
-if test xsqlite = x@DB_NAME@ ; then
+if test xsqlite = x@DB_NAME@ -o xsqlite3 = x@DB_NAME@ ; then
echo "Altering SQLite tables"
- @scriptdir@/update_sqlite_tables $*
+ @scriptdir@/update_@DB_NAME@_tables $*
fi
if test xmysql = x@DB_NAME@ ; then
echo "Altering MySQL tables"
if $bindir/mysql $* -f <<END-OF-DATA
USE bacula;
+ALTER TABLE Media ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE Media ADD COLUMN VolParts INTEGER UNSIGNED NOT NULL DEFAULT 0;
END-OF-DATA
if $bindir/psql $* -f - <<END-OF-DATA
\c bacula
+ALTER TABLE media ADD COLUMN labeltype integer;
+UPDATE media SET labeltype=0;
+ALTER TABLE media ALTER COLUMN labeltype SET NOT NULL;
+
ALTER TABLE media ADD COLUMN volparts integer;
UPDATE media SET volparts=0;
ALTER TABLE media ALTER COLUMN volparts SET NOT NULL;
bindir=@SQL_BINDIR@
cd @working_dir@
+sqlite=@DB_NAME@
-$bindir/sqlite $* bacula.db <<END-OF-DATA
-
+${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE Media_backup (
MediaId INTEGER UNSIGNED AUTOINCREMENT,
INSERT INTO Media_backup SELECT
MediaId, VolumeName, Slot, PoolId,
- MediaType, FirstWritten, LastWritten,
+ MediaType, 0, FirstWritten, LastWritten,
LabelDate, VolJobs, VolFiles, VolBlocks,
VolMounts, VolBytes, 0, VolErrors, VolWrites,
VolCapacityBytes, VolStatus, Recycle,
Slot INTEGER DEFAULT 0,
PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
MediaType VARCHAR(128) NOT NULL,
+ LabelType TINYINT DEFAULT 0,
FirstWritten DATETIME DEFAULT 0,
LastWritten DATETIME DEFAULT 0,
LabelDate DATETIME DEFAULT 0,
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
static char OKbackup[] = "2000 OK backup\n";
static char OKstore[] = "2000 OK storage\n";
static char EndJob[] = "2800 End Job TermCode=%d JobFiles=%u "
- "ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n";
+ "ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n";
/* Forward referenced functions */
since[0] = 0;
- if (!get_or_create_client_record(jcr)) {
- goto bail_out;
- }
-
if (!get_or_create_fileset_record(jcr, &fsr)) {
goto bail_out;
}
get_level_since_time(jcr, since, sizeof(since));
- jcr->fname = get_pool_memory(PM_FNAME);
-
/*
* Get the Pool record -- first apply any level defined pools
*/
while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
/* Try to create the pool */
if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
- Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+ Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
db_strerror(jcr->db));
goto bail_out;
} else {
- Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+ Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
}
}
jcr->PoolId = pr.PoolId; /****FIXME**** this can go away */
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr)) {
+ if (!start_storage_daemon_job(jcr, jcr->storage, SD_APPEND)) {
goto bail_out;
}
/*
&ReadBytes, &JobBytes, &Errors) == 5) {
fd_ok = true;
set_jcr_job_status(jcr, jcr->FDJobStatus);
- Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
+ Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
} else {
- Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
+ Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
fd->msg);
}
if (job_canceled(jcr)) {
if (*fname == '|') {
fname++;
got_pipe = 1;
- bpipe = open_bpipe(fname, 0, "w");
+ bpipe = open_bpipe(fname, 0, "w");
fd = bpipe ? bpipe->wfd : NULL;
} else {
/* ***FIXME*** handle BASE */
- fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
+ fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
}
if (fd) {
VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId,
&VolParams);
if (VolCount == 0) {
- Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
- "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
+ Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
+ "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
if (jcr->SDJobFiles != 0) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
}
for (int i=0; i < VolCount; i++) {
/* Write the record */
- fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
- fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
- fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
+ fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
+ fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType);
+ fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
+ fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
+ fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
VolParams[i].EndFile);
- fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
+ fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
VolParams[i].EndBlock);
- fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
+ fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
VolParams[i].LastIndex);
}
if (VolParams) {
}
} else {
berrno be;
- Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
- "%s: ERR=%s\n"), fname, be.strerror());
+ Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
+ "%s: ERR=%s\n"), fname, be.strerror());
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
}
switch (jcr->JobStatus) {
case JS_Terminated:
if (jcr->Errors || jcr->SDErrors) {
- term_msg = _("Backup OK -- with warnings");
+ term_msg = _("Backup OK -- with warnings");
} else {
- term_msg = _("Backup OK");
+ term_msg = _("Backup OK");
}
break;
case JS_FatalError:
case JS_ErrorTerminated:
- term_msg = _("*** Backup Error ***");
+ term_msg = _("*** Backup Error ***");
msg_type = M_ERROR; /* Generate error message */
if (jcr->store_bsock) {
bnet_sig(jcr->store_bsock, BNET_TERMINATE);
}
break;
case JS_Canceled:
- term_msg = _("Backup Canceled");
+ term_msg = _("Backup Canceled");
if (jcr->store_bsock) {
bnet_sig(jcr->store_bsock, BNET_TERMINATE);
if (jcr->SD_msg_chan) {
break;
default:
term_msg = term_code;
- sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
+ sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
break;
}
bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
* normal exit should we complain about this error.
*/
if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes) {
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+ Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
}
jcr->VolumeName[0] = 0; /* none */
}
} else {
compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes);
if (compression < 0.5) {
- bstrncpy(compress, "None", sizeof(compress));
+ bstrncpy(compress, "None", sizeof(compress));
} else {
- bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
+ bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
}
}
jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
*/
/*
- Copyright (C) 2002-2004 Kern Sibbald and John Walker
+ Copyright (C) 2002-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
findex = fi->findex < FirstIndex ? FirstIndex : fi->findex;
findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2;
if (findex == findex2) {
- fprintf(fd, "FileIndex=%d\n", findex);
+ fprintf(fd, "FileIndex=%d\n", findex);
count++;
} else {
- fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
+ fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
count += findex2 - findex + 1;
}
}
bsendmsg(ua, "fi=0x%lx\n", fi);
for ( ; fi; fi=fi->next) {
if (fi->findex == fi->findex2) {
- bsendmsg(ua, "FileIndex=%d\n", fi->findex);
+ bsendmsg(ua, "FileIndex=%d\n", fi->findex);
// Dmsg1(100, "FileIndex=%d\n", fi->findex);
} else {
- bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
+ bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
// Dmsg2(100, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
}
}
memset(&jr, 0, sizeof(jr));
jr.JobId = bsr->JobId;
if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
- bsendmsg(ua, _("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db));
+ bsendmsg(ua, _("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db));
return 0;
}
bsr->VolSessionId = jr.VolSessionId;
bsr->VolSessionTime = jr.VolSessionTime;
if ((bsr->VolCount=db_get_job_volume_parameters(ua->jcr, ua->db, bsr->JobId,
&(bsr->VolParams))) == 0) {
- bsendmsg(ua, _("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
+ bsendmsg(ua, _("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db));
if (bsr->VolParams) {
free(bsr->VolParams);
bsr->VolParams = NULL;
bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */
continue;
}
- fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
- fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
+ fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+ fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
+ fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
+ fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
- fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
+ fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
} else {
- fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
+ fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
bsr->VolParams[i].EndFile);
}
if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
- fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartBlock);
+ fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartBlock);
} else {
- fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
+ fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
bsr->VolParams[i].EndBlock);
}
// Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
count = write_findex(ua, bsr->fi, bsr->VolParams[i].FirstIndex,
bsr->VolParams[i].LastIndex, fd);
if (count) {
- fprintf(fd, "Count=%u\n", count);
+ fprintf(fd, "Count=%u\n", count);
}
total_count += count;
/* If the same file is present on two tapes or in two files
{
if (bsr) {
for (int i=0; i < bsr->VolCount; i++) {
- bsendmsg(ua, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
- bsendmsg(ua, "VolSessionId=%u\n", bsr->VolSessionId);
- bsendmsg(ua, "VolSessionTime=%u\n", bsr->VolSessionTime);
- bsendmsg(ua, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
+ bsendmsg(ua, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
+ bsendmsg(ua, "MediaType\"%s\"\n", bsr->VolParams[i].MediaType);
+ bsendmsg(ua, "VolSessionId=%u\n", bsr->VolSessionId);
+ bsendmsg(ua, "VolSessionTime=%u\n", bsr->VolSessionTime);
+ bsendmsg(ua, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
bsr->VolParams[i].EndFile);
- bsendmsg(ua, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
+ bsendmsg(ua, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
bsr->VolParams[i].EndBlock);
print_findex(ua, bsr->fi);
}
static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d\n";
static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s"
-" VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%" lld " VolMounts=%u"
-" VolErrors=%u VolWrites=%u MaxVolBytes=%" lld " EndTime=%d VolStatus=%10s"
-" Slot=%d relabel=%d InChanger=%d VolReadTime=%" lld " VolWriteTime=%" lld
-" VolParts=%u\n";
+ " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%" lld " VolMounts=%u"
+ " VolErrors=%u VolWrites=%u MaxVolBytes=%" lld " EndTime=%d VolStatus=%10s"
+ " Slot=%d relabel=%d InChanger=%d VolReadTime=%" lld " VolWriteTime=%" lld
+ " VolParts=%u\n";
static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia "
-" FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u "
-" StartBlock=%u EndBlock=%u\n";
+ " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u "
+ " StartBlock=%u EndBlock=%u\n";
/* Responses sent to Storage daemon */
" VolBlocks=%u VolBytes=%s VolMounts=%u VolErrors=%u VolWrites=%u"
" MaxVolBytes=%s VolCapacityBytes=%s VolStatus=%s Slot=%d"
" MaxVolJobs=%u MaxVolFiles=%u InChanger=%d VolReadTime=%s"
- " VolWriteTime=%s EndFile=%u EndBlock=%u VolParts=%u\n";
+ " VolWriteTime=%s EndFile=%u EndBlock=%u VolParts=%u LabelType=%d\n";
static char OK_create[] = "1000 OK CreateJobMedia\n";
edit_uint64(mr->VolReadTime, ed4),
edit_uint64(mr->VolWriteTime, ed5),
mr->EndFile, mr->EndBlock,
- mr->VolParts);
+ mr->VolParts,
+ mr->LabelType);
unbash_spaces(mr->VolumeName);
- Dmsg2(200, "Vol Info for %s: %s", jcr->Job, sd->msg);
+ Dmsg2(400, "Vol Info for %s: %s", jcr->Job, sd->msg);
return stat;
}
/*
* Request to find next appendable Volume for this Job
*/
- Dmsg1(200, "catreq %s", bs->msg);
+ Dmsg1(400, "catreq %s", bs->msg);
if (sscanf(bs->msg, Find_media, &Job, &index) == 2) {
ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
/*
* of a Storage daemon Job Session, when labeling/relabeling a
* Volume, or when an EOF mark is written.
*/
- } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName, &sdmr.VolJobs,
- &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes, &sdmr.VolMounts, &sdmr.VolErrors,
- &sdmr.VolWrites, &sdmr.MaxVolBytes, &sdmr.LastWritten, &sdmr.VolStatus,
- &sdmr.Slot, &label, &sdmr.InChanger, &sdmr.VolReadTime,
- &sdmr.VolWriteTime, &sdmr.VolParts) == 18) {
+ } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName,
+ &sdmr.VolJobs, &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes,
+ &sdmr.VolMounts, &sdmr.VolErrors, &sdmr.VolWrites, &sdmr.MaxVolBytes,
+ &sdmr.LastWritten, &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger,
+ &sdmr.VolReadTime, &sdmr.VolWriteTime, &sdmr.VolParts) == 18) {
db_lock(jcr->db);
- Dmsg3(300, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
+ Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
mr.VolStatus, sdmr.VolStatus);
bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */
unbash_spaces(mr.VolumeName);
if (!db_get_media_record(jcr, jcr->db, &mr)) {
Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"),
mr.VolumeName, db_strerror(jcr->db));
- bnet_fsend(bs, "1991 Catalog Request failed: %s", db_strerror(jcr->db));
+ bnet_fsend(bs, "1991 Catalog Request for vol=%s failed: %s",
+ mr.VolumeName, db_strerror(jcr->db));
db_unlock(jcr->db);
return;
}
mr.FirstWritten = jcr->start_time; /* use Job start time as first write */
}
/* If we just labeled the tape set time */
- Dmsg2(300, "label=%d labeldate=%d\n", label, mr.LabelDate);
+ Dmsg2(400, "label=%d labeldate=%d\n", label, mr.LabelDate);
if (label || mr.LabelDate == 0) {
mr.LabelDate = time(NULL);
} else {
mr.VolFiles, sdmr.VolFiles);
}
}
- Dmsg2(300, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
+ Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
/* Copy updated values to original media record */
mr.VolJobs = sdmr.VolJobs;
mr.VolFiles = sdmr.VolFiles;
mr.VolParts = sdmr.VolParts;
bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
- Dmsg2(300, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
+ Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
/*
* Check if it has expired, and if not update the DB. Note, if
* Volume has expired, has_volume_expired() will update the DB.
Jmsg(jcr, M_ERROR, 0, _("Catalog error updating Media record. %s"),
db_strerror(jcr->db));
bnet_fsend(bs, "1992 Update Media error\n");
- Dmsg0(190, "send error\n");
+ Dmsg0(400, "send error\n");
}
db_unlock(jcr->db);
jm.JobId = jcr->JobId;
jm.MediaId = jcr->MediaId;
- Dmsg6(300, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n",
+ Dmsg6(400, "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, 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(300, "JobMedia record created\n");
+ Dmsg0(400, "JobMedia record created\n");
bnet_fsend(bs, OK_create);
}
Jmsg1(jcr, M_ERROR, 0, _("Invalid Catalog request: %s"), omsg);
free_memory(omsg);
}
- Dmsg1(300, ">CatReq response: %s", bs->msg);
- Dmsg1(200, "Leave catreq jcr 0x%x\n", jcr);
+ Dmsg1(400, ">CatReq response: %s", bs->msg);
+ Dmsg1(400, "Leave catreq jcr 0x%x\n", jcr);
return;
}
unser_uint32(data_len);
p += unser_length(p);
- Dmsg1(300, "UpdCat msg=%s\n", bs->msg);
- Dmsg5(300, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
+ Dmsg1(400, "UpdCat msg=%s\n", bs->msg);
+ Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
VolSessionId, VolSessionTime, FileIndex, Stream, data_len);
if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_UNIX_ATTRIBUTES_EX) {
len = strlen(fname); /* length before attributes */
attr = &fname[len+1];
- Dmsg2(300, "dird<stored: stream=%d %s\n", Stream, fname);
- Dmsg1(300, "dird<stored: attr=%s\n", attr);
+ Dmsg2(400, "dird<stored: stream=%d %s\n", Stream, fname);
+ Dmsg1(400, "dird<stored: attr=%s\n", attr);
ar.attr = attr;
ar.fname = fname;
ar.FileIndex = FileIndex;
ar.link = NULL;
ar.JobId = jcr->JobId;
- Dmsg2(300, "dird<filed: stream=%d %s\n", Stream, fname);
- Dmsg1(120, "dird<filed: attr=%s\n", attr);
+ Dmsg2(400, "dird<filed: stream=%d %s\n", Stream, fname);
+ Dmsg1(400, "dird<filed: attr=%s\n", attr);
if (!db_create_file_attributes_record(jcr, jcr->db, &ar)) {
Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
type = SHA1_SIG;
}
bin_to_base64(SIGbuf, fname, len);
- Dmsg3(190, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
+ Dmsg3(400, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) {
Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5/SHA1. %s"),
db_strerror(jcr->db));
* Version $Id$
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
+void init_device_resources();
static char *configfile = NULL;
static char *runjob = NULL;
static void usage()
{
fprintf(stderr, _(
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
"\nVersion: " VERSION " (" BDATE ")\n\n"
"Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
" -c <file> set configuration file to file\n"
init_job_server(director->MaxConcurrentJobs);
+ init_device_resources();
+
Dmsg0(200, "wait for next job\n");
/* Main loop -- call scheduler to get next job to run */
while ((jcr = wait_for_next_job(runjob))) {
if (job->jobdefs) {
/* Handle Storage alists specifically */
JOB *jobdefs = job->jobdefs;
- for (i=0; i < MAX_STORE; i++) {
- if (jobdefs->storage[i] && !job->storage[i]) {
- STORE *st;
- job->storage[i] = New(alist(10, not_owned_by_alist));
- foreach_alist(st, jobdefs->storage[i]) {
- job->storage[i]->append(st);
- }
+ if (jobdefs->storage && !job->storage) {
+ STORE *st;
+ job->storage = New(alist(10, not_owned_by_alist));
+ foreach_alist(st, jobdefs->storage) {
+ job->storage->append(st);
}
}
foreach_res(pool, R_POOL) {
create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */
}
- /* Loop over all counters, defining them in each database */
+ /* ***FIXME*** we need to update store and media_type records */
+ STORE *store;
+ foreach_res(store, R_STORAGE) {
+ STORAGE_DBR sr;
+ MEDIATYPE_DBR mr;
+ if (store->media_type) {
+ bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
+ mr.ReadOnly = 0;
+ db_create_mediatype_record(NULL, db, &mr);
+ } else {
+ mr.MediaTypeId = 0;
+ }
+ sr.MediaTypeId = mr.MediaTypeId;
+ bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
+ sr.AutoChanger = store->autochanger;
+ db_create_storage_record(NULL, db, &sr);
+ }
+
+ /* Loop over all counters, defining them in each database */
/* Set default value in all counters */
COUNTER *counter;
foreach_res(counter, R_COUNTER) {
void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
+void store_label(LEX *lc, RES_ITEM *item, int index, int pass);
void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
void store_acl(LEX *lc, RES_ITEM *item, int index, int pass);
+static void store_device(LEX *lc, RES_ITEM *item, int index, int pass);
/* We build the current resource here as we are
{"sdaddress", store_str, ITEM(res_store.address), 0, 0, 0},
{"password", store_password, ITEM(res_store.password), 0, ITEM_REQUIRED, 0},
{"sdpassword", store_password, ITEM(res_store.password), 0, 0, 0},
- {"device", store_strname, ITEM(res_store.dev_name), 0, ITEM_REQUIRED, 0},
- {"sddevicename", store_strname, ITEM(res_store.dev_name), 0, 0, 0},
+ {"device", store_device, ITEM(res_store.device), R_DEVICE, ITEM_REQUIRED, 0},
{"mediatype", store_strname, ITEM(res_store.media_type), 0, ITEM_REQUIRED, 0},
{"autochanger", store_yesno, ITEM(res_store.autochanger), 1, ITEM_DEFAULT, 0},
{"enablessl", store_yesno, ITEM(res_store.enable_ssl), 1, ITEM_DEFAULT, 0},
{"type", store_jobtype, ITEM(res_job.JobType), 0, ITEM_REQUIRED, 0},
{"level", store_level, ITEM(res_job.JobLevel), 0, 0, 0},
{"messages", store_res, ITEM(res_job.messages), R_MSGS, ITEM_REQUIRED, 0},
- {"storage", store_alist_res, ITEM(res_job.storage), R_STORAGE, ITEM_REQUIRED, MAX_STORE},
+ {"storage", store_alist_res, ITEM(res_job.storage), R_STORAGE, ITEM_REQUIRED, 0},
{"pool", store_res, ITEM(res_job.pool), R_POOL, ITEM_REQUIRED, 0},
{"fullbackuppool", store_res, ITEM(res_job.full_pool), R_POOL, 0, 0},
{"incrementalbackuppool", store_res, ITEM(res_job.inc_pool), R_POOL, 0, 0},
{"description", store_str, ITEM(res_pool.hdr.desc), 0, 0, 0},
{"pooltype", store_strname, ITEM(res_pool.pool_type), 0, ITEM_REQUIRED, 0},
{"labelformat", store_strname, ITEM(res_pool.label_format), 0, 0, 0},
- {"cleaningprefix", store_strname, ITEM(res_pool.cleaning_prefix), 0, 0, 0},
- {"usecatalog", store_yesno, ITEM(res_pool.use_catalog), 1, ITEM_DEFAULT, 1},
- {"usevolumeonce", store_yesno, ITEM(res_pool.use_volume_once), 1, 0, 0},
+ {"labeltype", store_label, ITEM(res_pool.LabelType), 0, 0, 0},
+ {"cleaningprefix", store_strname, ITEM(res_pool.cleaning_prefix), 0, 0, 0},
+ {"usecatalog", store_yesno, ITEM(res_pool.use_catalog), 1, ITEM_DEFAULT, 1},
+ {"usevolumeonce", store_yesno, ITEM(res_pool.use_volume_once),1, 0, 0},
{"purgeoldestvolume", store_yesno, ITEM(res_pool.purge_oldest_volume), 1, 0, 0},
- {"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 1, 0, 0},
+ {"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 1, 0, 0},
{"recyclecurrentvolume", store_yesno, ITEM(res_pool.recycle_current_volume), 1, 0, 0},
- {"maximumvolumes", store_pint, ITEM(res_pool.max_volumes), 0, 0, 0},
+ {"maximumvolumes", store_pint, ITEM(res_pool.max_volumes), 0, 0, 0},
{"maximumvolumejobs", store_pint, ITEM(res_pool.MaxVolJobs), 0, 0, 0},
{"maximumvolumefiles", store_pint, ITEM(res_pool.MaxVolFiles), 0, 0, 0},
{"maximumvolumebytes", store_size, ITEM(res_pool.MaxVolBytes), 0, 0, 0},
- {"acceptanyvolume", store_yesno, ITEM(res_pool.accept_any_volume), 1, ITEM_DEFAULT, 1},
- {"catalogfiles", store_yesno, ITEM(res_pool.catalog_files), 1, ITEM_DEFAULT, 1},
- {"volumeretention", store_time, ITEM(res_pool.VolRetention), 0, ITEM_DEFAULT, 60*60*24*365},
- {"volumeuseduration", store_time, ITEM(res_pool.VolUseDuration),0, 0, 0},
- {"autoprune", store_yesno, ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1},
- {"recycle", store_yesno, ITEM(res_pool.Recycle), 1, ITEM_DEFAULT, 1},
+ {"acceptanyvolume", store_yesno, ITEM(res_pool.accept_any_volume), 1, ITEM_DEFAULT, 1},
+ {"catalogfiles", store_yesno, ITEM(res_pool.catalog_files), 1, ITEM_DEFAULT, 1},
+ {"volumeretention", store_time, ITEM(res_pool.VolRetention), 0, ITEM_DEFAULT, 60*60*24*365},
+ {"volumeuseduration", store_time, ITEM(res_pool.VolUseDuration), 0, 0, 0},
+ {"autoprune", store_yesno, ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1},
+ {"recycle", store_yesno, ITEM(res_pool.Recycle), 1, ITEM_DEFAULT, 1},
{NULL, NULL, NULL, 0, 0, 0}
};
{"counter", counter_items, R_COUNTER},
{"console", con_items, R_CONSOLE},
{"jobdefs", job_items, R_JOBDEFS},
+ {"device", NULL, R_DEVICE}, /* info obtained from SD */
{NULL, NULL, 0}
};
{NULL, 0}
};
+/*
+ * Tape Label types permitted in Pool records
+ *
+ * tape label label code = token
+ */
+struct s_kw tapelabels[] = {
+ {"bacula", B_BACULA_LABEL},
+ {"ansi", B_ANSI_LABEL},
+ {"ibm", B_IBM_LABEL},
+ {NULL, 0}
+};
+
+
#ifdef old_deprecated_code
/* Keywords (RHS) permitted in Backup and Verify records */
URES *res = (URES *)reshdr;
bool recurse = true;
char ed1[100], ed2[100];
+ DEVICE *dev;
if (res == NULL) {
sendit(sock, "No %s resource defined\n", res_to_str(type));
dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
}
break;
+ case R_DEVICE:
+ dev = &res->res_dev;
+ sendit(sock, "Device: name=%s ok=%d num_writers=%d num_waiting=%d\n"
+" use_cnt=%d open=%d append=%d read=%d labeled=%d\n"
+" volname=%s MediaType=%s\n",
+ dev->hdr.name, dev->found, dev->num_writers, dev->num_waiting,
+ dev->use_count, dev->open, dev->append, dev->read, dev->labeled,
+ dev->VolumeName, dev->MediaType);
+ break;
case R_STORAGE:
sendit(sock, "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n"
" DeviceName=%s MediaType=%s\n",
res->res_store.hdr.name, res->res_store.address, res->res_store.SDport,
res->res_store.MaxConcurrentJobs,
- res->res_store.dev_name, res->res_store.media_type);
+ res->res_store.dev_name(),
+ res->res_store.media_type);
break;
case R_CATALOG:
sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n"
if (res->res_job.WriteBootstrap) {
sendit(sock, " --> WriteBootstrap=%s\n", NPRT(res->res_job.WriteBootstrap));
}
- if (res->res_job.storage[0]) {
- sendit(sock, " --> ");
- /* ***FIXME*** */
-// dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
+ if (res->res_job.storage) {
+ STORE *store;
+ foreach_alist(store, res->res_job.storage) {
+ sendit(sock, " --> ");
+ dump_resource(-R_STORAGE, (RES *)store, sendit, sock);
+ }
}
if (res->res_job.pool) {
sendit(sock, " --> ");
free_addresses(res->res_dir.DIRaddrs);
}
break;
+ case R_DEVICE:
case R_COUNTER:
break;
case R_CONSOLE:
if (res->res_store.media_type) {
free(res->res_store.media_type);
}
- if (res->res_store.dev_name) {
- free(res->res_store.dev_name);
+ if (res->res_store.device) {
+ delete res->res_store.device;
}
break;
case R_CATALOG:
if (res->res_job.ClientRunAfterJob) {
free(res->res_job.ClientRunAfterJob);
}
- for (int i=0; i < MAX_STORE; i++) {
- if (res->res_job.storage[i]) {
- delete (alist *)res->res_job.storage[i];
- }
+ if (res->res_job.storage) {
+ delete res->res_job.storage;
}
break;
case R_MSGS:
URES *res;
int rindex = type - r_first;
int i, size;
- int error = 0;
+ bool error = false;
/* Check Job requirements after applying JobDefs */
if (type != R_JOB && type != R_JOBDEFS) {
/* Resources not containing a resource */
case R_CONSOLE:
case R_CATALOG:
- case R_STORAGE:
case R_POOL:
case R_MSGS:
case R_FILESET:
+ case R_DEVICE:
break;
- /* Resources containing another resource */
+ /* Resources containing another resource or alist */
case R_DIRECTOR:
if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name);
}
res->res_dir.messages = res_all.res_dir.messages;
break;
+ case R_STORAGE:
+ if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) {
+ Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource %s\n",
+ res_all.res_dir.hdr.name);
+ }
+ /* we must explicitly copy the device alist pointer */
+ res->res_store.device = res_all.res_store.device;
+ break;
case R_JOB:
case R_JOBDEFS:
if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) {
res->res_job.schedule = res_all.res_job.schedule;
res->res_job.client = res_all.res_job.client;
res->res_job.fileset = res_all.res_job.fileset;
- for (int i=0; i < MAX_STORE; i++) {
- res->res_job.storage[i] = res_all.res_job.storage[i];
- }
+ res->res_job.storage = res_all.res_job.storage;
res->res_job.pool = res_all.res_job.pool;
res->res_job.full_pool = res_all.res_job.full_pool;
res->res_job.inc_pool = res_all.res_job.inc_pool;
break;
default:
Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type);
- error = 1;
+ error = true;
break;
}
/* Note, the resource name was already saved during pass 1,
case R_COUNTER:
size = sizeof(COUNTER);
break;
+ case R_DEVICE:
+ error = true;
+ break;
default:
printf("Unknown resource type %d in save_resrouce.\n", type);
- error = 1;
- size = 1;
+ error = true;
break;
}
/* Common */
}
}
+/*
+ * Store Device. Note, the resource is created upon the
+ * first reference. The details of the resource are obtained
+ * later from the SD.
+ */
+static void store_device(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+ int token;
+ URES *res;
+ int rindex = R_DEVICE - r_first;
+ int size = sizeof(DEVICE);
+ bool found = false;
+
+ if (pass == 1) {
+ token = lex_get_token(lc, T_NAME);
+ if (!res_head[rindex]) {
+ res = (URES *)malloc(size);
+ memset(res, 0, size);
+ res->res_dev.hdr.name = bstrdup(lc->str);
+ res_head[rindex] = (RES *)res; /* store first entry */
+ Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(R_DEVICE),
+ res->res_dir.hdr.name, rindex);
+ } else {
+ RES *next;
+ /* See if it is already defined */
+ for (next=res_head[rindex]; next->next; next=next->next) {
+ if (strcmp(next->name, lc->str) == 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ res = (URES *)malloc(size);
+ memset(res, 0, size);
+ res->res_dev.hdr.name = bstrdup(lc->str);
+ next->next = (RES *)res;
+ Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(R_DEVICE),
+ res->res_dir.hdr.name, rindex, pass);
+ }
+ }
+
+ scan_to_eol(lc);
+ set_bit(index, res_all.hdr.item_present);
+ } else {
+ store_alist_res(lc, item, index, pass);
+ }
+}
+
+
/*
* Store JobType (backup, verify, restore)
*
set_bit(index, res_all.hdr.item_present);
}
+
+/*
+ * Store Tape Label Type (Bacula, ANSI, IBM)
+ *
+ */
+void store_label(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+ int token, i;
+
+ token = lex_get_token(lc, T_NAME);
+ /* Store the label pass 2 so that type is defined */
+ for (i=0; tapelabels[i].name; i++) {
+ if (strcasecmp(lc->str, tapelabels[i].name) == 0) {
+ *(int *)(item->value) = tapelabels[i].token;
+ i = 0;
+ break;
+ }
+ }
+ if (i != 0) {
+ scan_err1(lc, "Expected a Tape Label keyword, got: %s", lc->str);
+ }
+ scan_to_eol(lc);
+ set_bit(index, res_all.hdr.item_present);
+}
+
+
+
void store_replace(LEX *lc, RES_ITEM *item, int index, int pass)
{
int token, i;
R_COUNTER,
R_CONSOLE,
R_JOBDEFS,
+ R_DEVICE,
R_FIRST = R_DIRECTOR,
- R_LAST = R_JOBDEFS /* keep this updated */
+ R_LAST = R_DEVICE /* keep this updated */
};
/* Job Level keyword structure */
struct s_jl {
- const char *level_name; /* level keyword */
- int level; /* level */
- int job_type; /* JobType permitting this level */
+ const char *level_name; /* level keyword */
+ int level; /* level */
+ int job_type; /* JobType permitting this level */
};
/* Job Type keyword structure */
struct FILESET;
struct POOL;
struct RUN;
+struct DEVICE;
/*
* Director Resource
*
*/
-struct DIRRES {
- RES hdr;
+class DIRRES {
+public:
+ RES hdr;
dlist *DIRaddrs;
- char *password; /* Password for UA access */
- int enable_ssl; /* Use SSL for UA */
- char *query_file; /* SQL query file */
- char *working_directory; /* WorkingDirectory */
+ char *password; /* Password for UA access */
+ int enable_ssl; /* Use SSL for UA */
+ char *query_file; /* SQL query file */
+ char *working_directory; /* WorkingDirectory */
const char *scripts_directory; /* ScriptsDirectory */
- char *pid_directory; /* PidDirectory */
- char *subsys_directory; /* SubsysDirectory */
- int require_ssl; /* Require SSL for all connections */
- MSGS *messages; /* Daemon message handler */
- uint32_t MaxConcurrentJobs; /* Max concurrent jobs for whole director */
- utime_t FDConnectTimeout; /* timeout for connect in seconds */
- utime_t SDConnectTimeout; /* timeout in seconds */
+ char *pid_directory; /* PidDirectory */
+ char *subsys_directory; /* SubsysDirectory */
+ int require_ssl; /* Require SSL for all connections */
+ MSGS *messages; /* Daemon message handler */
+ uint32_t MaxConcurrentJobs; /* Max concurrent jobs for whole director */
+ utime_t FDConnectTimeout; /* timeout for connect in seconds */
+ utime_t SDConnectTimeout; /* timeout in seconds */
};
+/*
+ * Device Resource
+ * This resource is a bit different from the other resources
+ * because it is not defined in the Director
+ * by DEVICE { ... }, but rather by a "reference" such as
+ * DEVICE = xxx; Then when the Director connects to the
+ * SD, it requests the information about the device.
+ */
+class DEVICE {
+public:
+ RES hdr;
+
+ bool found; /* found with SD */
+ int num_writers;
+ int num_waiting;
+ int use_count;
+ bool open;
+ bool append; /* in append mode */
+ bool read;
+ bool labeled;
+ char VolumeName[MAX_NAME_LENGTH];
+ char MediaType[MAX_NAME_LENGTH];
+};
/*
* Console ACL positions
Command_ACL,
FileSet_ACL,
Catalog_ACL,
- Num_ACL /* keep last */
+ Num_ACL /* keep last */
};
/*
* Console Resource
*/
-struct CONRES {
- RES hdr;
- char *password; /* UA server password */
- int enable_ssl; /* Use SSL */
- alist *ACL_lists[Num_ACL]; /* pointers to ACLs */
+class CONRES {
+public:
+ RES hdr;
+ char *password; /* UA server password */
+ int enable_ssl; /* Use SSL */
+ alist *ACL_lists[Num_ACL]; /* pointers to ACLs */
};
* Catalog Resource
*
*/
-struct CAT {
- RES hdr;
+class CAT {
+public:
+ RES hdr;
- int db_port; /* Port -- not yet implemented */
- char *db_address; /* host name for remote access */
- char *db_socket; /* Socket for local access */
+ int db_port; /* Port -- not yet implemented */
+ char *db_address; /* host name for remote access */
+ char *db_socket; /* Socket for local access */
char *db_password;
char *db_user;
char *db_name;
- int mult_db_connections; /* set if multiple connections wanted */
+ int mult_db_connections; /* set if multiple connections wanted */
};
* Client Resource
*
*/
-struct CLIENT {
- RES hdr;
-
- int FDport; /* Where File daemon listens */
- int AutoPrune; /* Do automatic pruning? */
- utime_t FileRetention; /* file retention period in seconds */
- utime_t JobRetention; /* job retention period in seconds */
+class CLIENT {
+public:
+ RES hdr;
+
+ int FDport; /* Where File daemon listens */
+ int AutoPrune; /* Do automatic pruning? */
+ utime_t FileRetention; /* file retention period in seconds */
+ utime_t JobRetention; /* job retention period in seconds */
char *address;
char *password;
- CAT *catalog; /* Catalog resource */
- uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
- uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
- int enable_ssl; /* Use SSL */
+ CAT *catalog; /* Catalog resource */
+ uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
+ uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
+ int enable_ssl; /* Use SSL */
};
/*
* Store Resource
*
*/
-struct STORE {
- RES hdr;
+class STORE {
+public:
+ RES hdr;
- int SDport; /* port where Directors connect */
- int SDDport; /* data port for File daemon */
+ int SDport; /* port where Directors connect */
+ int SDDport; /* data port for File daemon */
char *address;
char *password;
char *media_type;
- char *dev_name;
- int autochanger; /* set if autochanger */
- uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
- uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
- int enable_ssl; /* Use SSL */
+ alist *device; /* Device name(s) */
+ int autochanger; /* set if autochanger */
+ uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
+ uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
+ int enable_ssl; /* Use SSL */
+
+ char *dev_name() const;
+ char *name() const;
};
+inline char *STORE::dev_name() const
+{
+ DEVICE *dev = (DEVICE *)device->first();
+ return dev->hdr.name;
+}
+
+inline char *STORE::name() const { return hdr.name; }
-#define MAX_STORE 2 /* Max storage directives in Job */
/*
* Job Resource
*/
-struct JOB {
- RES hdr;
-
- int JobType; /* job type (backup, verify, restore */
- int JobLevel; /* default backup/verify level */
- int Priority; /* Job priority */
- int RestoreJobId; /* What -- JobId to restore */
- char *RestoreWhere; /* Where on disk to restore -- directory */
- char *RestoreBootstrap; /* Bootstrap file */
- char *RunBeforeJob; /* Run program before Job */
- char *RunAfterJob; /* Run program after Job */
- char *RunAfterFailedJob; /* Run program after Job that errs */
- char *ClientRunBeforeJob; /* Run client program before Job */
- char *ClientRunAfterJob; /* Run client program after Job */
- char *WriteBootstrap; /* Where to write bootstrap Job updates */
- int replace; /* How (overwrite, ..) */
- utime_t MaxRunTime; /* max run time in seconds */
- utime_t MaxWaitTime; /* max blocking time in seconds */
- utime_t MaxStartDelay; /* max start delay in seconds */
- int PrefixLinks; /* prefix soft links with Where path */
- int PruneJobs; /* Force pruning of Jobs */
- int PruneFiles; /* Force pruning of Files */
- int PruneVolumes; /* Force pruning of Volumes */
- int SpoolAttributes; /* Set to spool attributes in SD */
- int spool_data; /* Set to spool data in SD */
- int rerun_failed_levels; /* Upgrade to rerun failed levels */
- uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
- int RescheduleOnError; /* Set to reschedule on error */
- int RescheduleTimes; /* Number of times to reschedule job */
- utime_t RescheduleInterval; /* Reschedule interval */
- utime_t JobRetention; /* job retention period in seconds */
- bool write_part_after_job; /* Set to write part after job in SD */
+class JOB {
+public:
+ RES hdr;
+
+ int JobType; /* job type (backup, verify, restore */
+ int JobLevel; /* default backup/verify level */
+ int Priority; /* Job priority */
+ int RestoreJobId; /* What -- JobId to restore */
+ char *RestoreWhere; /* Where on disk to restore -- directory */
+ char *RestoreBootstrap; /* Bootstrap file */
+ char *RunBeforeJob; /* Run program before Job */
+ char *RunAfterJob; /* Run program after Job */
+ char *RunAfterFailedJob; /* Run program after Job that errs */
+ char *ClientRunBeforeJob; /* Run client program before Job */
+ char *ClientRunAfterJob; /* Run client program after Job */
+ char *WriteBootstrap; /* Where to write bootstrap Job updates */
+ int replace; /* How (overwrite, ..) */
+ utime_t MaxRunTime; /* max run time in seconds */
+ utime_t MaxWaitTime; /* max blocking time in seconds */
+ utime_t MaxStartDelay; /* max start delay in seconds */
+ int PrefixLinks; /* prefix soft links with Where path */
+ int PruneJobs; /* Force pruning of Jobs */
+ int PruneFiles; /* Force pruning of Files */
+ int PruneVolumes; /* Force pruning of Volumes */
+ int SpoolAttributes; /* Set to spool attributes in SD */
+ int spool_data; /* Set to spool data in SD */
+ int rerun_failed_levels; /* Upgrade to rerun failed levels */
+ uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
+ int RescheduleOnError; /* Set to reschedule on error */
+ int RescheduleTimes; /* Number of times to reschedule job */
+ utime_t RescheduleInterval; /* Reschedule interval */
+ utime_t JobRetention; /* job retention period in seconds */
+ bool write_part_after_job; /* Set to write part after job in SD */
- MSGS *messages; /* How and where to send messages */
- SCHED *schedule; /* When -- Automatic schedule */
- CLIENT *client; /* Who to backup */
- FILESET *fileset; /* What to backup -- Fileset */
- alist *storage[MAX_STORE]; /* Where is device -- Storage daemon */
- POOL *pool; /* Where is media -- Media Pool */
- POOL *full_pool; /* Pool for Full backups */
- POOL *inc_pool; /* Pool for Incremental backups */
- POOL *dif_pool; /* Pool for Differental backups */
- JOB *verify_job; /* Job name to verify */
- JOB *jobdefs; /* Job defaults */
- uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
+ MSGS *messages; /* How and where to send messages */
+ SCHED *schedule; /* When -- Automatic schedule */
+ CLIENT *client; /* Who to backup */
+ FILESET *fileset; /* What to backup -- Fileset */
+ alist *storage; /* Where is device -- Storage daemon */
+ POOL *pool; /* Where is media -- Media Pool */
+ POOL *full_pool; /* Pool for Full backups */
+ POOL *inc_pool; /* Pool for Incremental backups */
+ POOL *dif_pool; /* Pool for Differental backups */
+ JOB *verify_job; /* Job name to verify */
+ JOB *jobdefs; /* Job defaults */
+ uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
};
-#undef MAX_FOPTS
+#undef MAX_FOPTS
#define MAX_FOPTS 34
/* File options structure */
struct FOPTS {
- char opts[MAX_FOPTS]; /* options string */
- alist regex; /* regex string(s) */
- alist regexdir; /* regex string(s) for directories */
- alist regexfile; /* regex string(s) for files */
- alist wild; /* wild card strings */
- alist wilddir; /* wild card strings for directories */
- alist wildfile; /* wild card strings for files */
- alist base; /* list of base names */
- alist fstype; /* file system type limitation */
- char *reader; /* reader program */
- char *writer; /* writer program */
+ char opts[MAX_FOPTS]; /* options string */
+ alist regex; /* regex string(s) */
+ alist regexdir; /* regex string(s) for directories */
+ alist regexfile; /* regex string(s) for files */
+ alist wild; /* wild card strings */
+ alist wilddir; /* wild card strings for directories */
+ alist wildfile; /* wild card strings for files */
+ alist base; /* list of base names */
+ alist fstype; /* file system type limitation */
+ char *reader; /* reader program */
+ char *writer; /* writer program */
};
/* This is either an include item or an exclude item */
struct INCEXE {
- FOPTS *current_opts; /* points to current options structure */
- FOPTS **opts_list; /* options list */
- int num_opts; /* number of options items */
- alist name_list; /* filename list -- holds char * */
+ FOPTS *current_opts; /* points to current options structure */
+ FOPTS **opts_list; /* options list */
+ int num_opts; /* number of options items */
+ alist name_list; /* filename list -- holds char * */
};
/*
* FileSet Resource
*
*/
-struct FILESET {
- RES hdr;
+class FILESET {
+public:
+ RES hdr;
- bool new_include; /* Set if new include used */
- INCEXE **include_items; /* array of incexe structures */
- int num_includes; /* number in array */
+ bool new_include; /* Set if new include used */
+ INCEXE **include_items; /* array of incexe structures */
+ int num_includes; /* number in array */
INCEXE **exclude_items;
int num_excludes;
- bool have_MD5; /* set if MD5 initialized */
- struct MD5Context md5c; /* MD5 of include/exclude */
- char MD5[30]; /* base 64 representation of MD5 */
+ bool have_MD5; /* set if MD5 initialized */
+ struct MD5Context md5c; /* MD5 of include/exclude */
+ char MD5[30]; /* base 64 representation of MD5 */
int ignore_fs_changes; /* Don't force Full if FS changed */
};
* Schedule Resource
*
*/
-struct SCHED {
- RES hdr;
+class SCHED {
+public:
+ RES hdr;
RUN *run;
};
/*
* Counter Resource
*/
-struct COUNTER {
- RES hdr;
-
- int32_t MinValue; /* Minimum value */
- int32_t MaxValue; /* Maximum value */
- int32_t CurrentValue; /* Current value */
- COUNTER *WrapCounter; /* Wrap counter name */
- CAT *Catalog; /* Where to store */
- bool created; /* Created in DB */
+class COUNTER {
+public:
+ RES hdr;
+
+ int32_t MinValue; /* Minimum value */
+ int32_t MaxValue; /* Maximum value */
+ int32_t CurrentValue; /* Current value */
+ COUNTER *WrapCounter; /* Wrap counter name */
+ CAT *Catalog; /* Where to store */
+ bool created; /* Created in DB */
};
/*
* Pool Resource
*
*/
-struct POOL {
- RES hdr;
-
- char *pool_type; /* Pool type */
- char *label_format; /* Label format string */
- char *cleaning_prefix; /* Cleaning label prefix */
- int use_catalog; /* maintain catalog for media */
- int catalog_files; /* maintain file entries in catalog */
- int use_volume_once; /* write on volume only once */
- int accept_any_volume; /* accept any volume */
- int purge_oldest_volume; /* purge oldest volume */
- int recycle_oldest_volume; /* attempt to recycle oldest volume */
- int recycle_current_volume; /* attempt recycle of current volume */
- uint32_t max_volumes; /* max number of volumes */
- utime_t VolRetention; /* volume retention period in seconds */
- utime_t VolUseDuration; /* duration volume can be used */
- uint32_t MaxVolJobs; /* Maximum jobs on the Volume */
- uint32_t MaxVolFiles; /* Maximum files on the Volume */
- uint64_t MaxVolBytes; /* Maximum bytes on the Volume */
- int AutoPrune; /* default for pool auto prune */
- int Recycle; /* default for media recycle yes/no */
+class POOL {
+public:
+ RES hdr;
+
+ char *pool_type; /* Pool type */
+ char *label_format; /* Label format string */
+ char *cleaning_prefix; /* Cleaning label prefix */
+ int LabelType; /* Bacula/ANSI/IBM label type */
+ int use_catalog; /* maintain catalog for media */
+ int catalog_files; /* maintain file entries in catalog */
+ int use_volume_once; /* write on volume only once */
+ int accept_any_volume; /* accept any volume */
+ int purge_oldest_volume; /* purge oldest volume */
+ int recycle_oldest_volume; /* attempt to recycle oldest volume */
+ int recycle_current_volume; /* attempt recycle of current volume */
+ uint32_t max_volumes; /* max number of volumes */
+ utime_t VolRetention; /* volume retention period in seconds */
+ utime_t VolUseDuration; /* duration volume can be used */
+ uint32_t MaxVolJobs; /* Maximum jobs on the Volume */
+ uint32_t MaxVolFiles; /* Maximum files on the Volume */
+ uint64_t MaxVolBytes; /* Maximum bytes on the Volume */
+ int AutoPrune; /* default for pool auto prune */
+ int Recycle; /* default for media recycle yes/no */
};
+
+
/* Define the Union of all the above
* resource structure definitions.
*/
CONRES res_con;
CLIENT res_client;
STORE res_store;
- CAT res_cat;
- JOB res_job;
+ CAT res_cat;
+ JOB res_job;
FILESET res_fs;
SCHED res_sch;
POOL res_pool;
MSGS res_msgs;
COUNTER res_counter;
- RES hdr;
+ DEVICE res_dev;
+ RES hdr;
};
/* Run structure contained in Schedule Resource */
-struct RUN {
- RUN *next; /* points to next run record */
- int level; /* level override */
- int Priority; /* priority override */
+class RUN {
+public:
+ RUN *next; /* points to next run record */
+ int level; /* level override */
+ int Priority; /* priority override */
int job_type;
- bool spool_data; /* Data spooling override */
- bool spool_data_set; /* Data spooling override given */
- bool write_part_after_job; /* Write part after job override */
+ bool spool_data; /* Data spooling override */
+ bool spool_data_set; /* Data spooling override given */
+ bool write_part_after_job; /* Write part after job override */
bool write_part_after_job_set; /* Write part after job override given */
- POOL *pool; /* Pool override */
- POOL *full_pool; /* Pool override */
- POOL *inc_pool; /* Pool override */
- POOL *dif_pool; /* Pool override */
- STORE *storage; /* Storage override */
- MSGS *msgs; /* Messages override */
+ POOL *pool; /* Pool override */
+ POOL *full_pool; /* Pool override */
+ POOL *inc_pool; /* Pool override */
+ POOL *dif_pool; /* Pool override */
+ STORE *storage; /* Storage override */
+ MSGS *msgs; /* Messages override */
char *since;
int level_no;
- int minute; /* minute to run job */
- time_t last_run; /* last time run */
- time_t next_run; /* next time to run */
+ int minute; /* minute to run job */
+ time_t last_run; /* last time run */
+ time_t next_run; /* next time to run */
char hour[nbytes_for_bits(24)]; /* bit set for each hour */
char mday[nbytes_for_bits(31)]; /* bit set for each day of month */
char month[nbytes_for_bits(12)]; /* bit set for each month */
* Version $Id$
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* Forward referenced functions */
static char *find_msg_start(char *msg);
+static char Job_status[] = "Status Job=%127s JobStatus=%d\n";
+
+
static char OK_msg[] = "1000 OK\n";
/*
for (;;) {
n = bnet_recv(bs);
- Dmsg2(120, "bget_dirmsg %d: %s\n", n, bs->msg);
+ Dmsg2(900, "bget_dirmsg %d: %s\n", n, bs->msg);
if (is_bnet_stop(bs)) {
return n; /* error or terminate */
break;
case BNET_STATUS:
/* *****FIXME***** Implement more completely */
- bnet_fsend(bs, "Status OK\n");
+ bnet_fsend(bs, "Status OK\n");
bnet_sig(bs, BNET_EOD);
break;
case BNET_BTIME: /* send Bacula time */
char ed1[50];
- bnet_fsend(bs, "btime %s\n", edit_uint64(get_current_btime(),ed1));
+ bnet_fsend(bs, "btime %s\n", edit_uint64(get_current_btime(),ed1));
break;
default:
- Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
+ Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
return n;
}
continue;
* Try to fulfill it.
*/
if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) {
- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+ Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
continue;
}
if (!(jcr=get_jcr_by_full_name(Job))) {
- Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
+ Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
continue;
}
- Dmsg1(200, "Getmsg got jcr 0x%x\n", jcr);
+ Dmsg1(900, "Getmsg got jcr 0x%x\n", jcr);
/* Skip past "Jmsg Job=nnn" */
if (!(msg=find_msg_start(bs->msg))) {
- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+ Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
free_jcr(jcr);
continue;
}
* Jmsg Job=nnn type=nnn level=nnn Message-string
*/
if (bs->msg[0] == 'J') { /* Job message */
- if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d",
+ if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d",
Job, &type, &level) != 3) {
- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
+ Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
free_jcr(jcr);
continue;
}
- Dmsg1(120, "Got msg: %s\n", bs->msg);
+ Dmsg1(900, "Got msg: %s\n", bs->msg);
skip_spaces(&msg);
skip_nonspaces(&msg); /* skip type=nnn */
skip_spaces(&msg);
skip_nonspaces(&msg); /* skip level=nnn */
- if (*msg == ' ') {
+ if (*msg == ' ') {
msg++; /* skip leading space */
}
- Dmsg1(120, "Dispatch msg: %s", msg);
+ Dmsg1(900, "Dispatch msg: %s", msg);
dispatch_message(jcr, type, level, msg);
free_jcr(jcr);
continue;
* CatReq Job=nn Catalog-Request-Message
*/
if (bs->msg[0] == 'C') { /* Catalog request */
- Dmsg2(120, "Catalog req jcr 0x%x: %s", jcr, bs->msg);
+ Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg);
catalog_request(jcr, bs, msg);
- Dmsg1(200, "Calling freejcr 0x%x\n", jcr);
+ Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
free_jcr(jcr);
continue;
}
if (bs->msg[0] == 'U') { /* Catalog update */
- Dmsg2(120, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
+ Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
catalog_update(jcr, bs, msg);
- Dmsg1(200, "Calling freejcr 0x%x\n", jcr);
+ Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
free_jcr(jcr);
continue;
}
if (bs->msg[0] == 'M') { /* Mount request */
- Dmsg1(120, "Mount req: %s", bs->msg);
+ Dmsg1(900, "Mount req: %s", bs->msg);
mount_request(jcr, bs, msg);
free_jcr(jcr);
continue;
}
+ if (bs->msg[0] == 'S') { /* Status change */
+ int JobStatus;
+ char Job[MAX_NAME_LENGTH];
+ if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
+ jcr->SDJobStatus = JobStatus; /* current status */
+ free_jcr(jcr);
+ continue;
+ }
+ }
return n;
}
}
}
/*
- * Get response from File daemon to a command we
+ * Get response from FD or SD to a command we
* sent. Check that the response agrees with what we expect.
*
- * Returns: 0 on failure
- * 1 on success
+ * Returns: false on failure
+ * true on success
*/
-int response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg)
+bool response(JCR *jcr, BSOCK *bs, char *resp, const char *cmd, e_prtmsg prtmsg)
{
int n;
- if (is_bnet_error(fd)) {
- return 0;
+ if (is_bnet_error(bs)) {
+ return false;
}
- if ((n = bget_dirmsg(fd)) >= 0) {
- Dmsg0(110, fd->msg);
- if (strcmp(fd->msg, resp) == 0) {
- return 1;
+ if ((n = bget_dirmsg(bs)) >= 0) {
+ Dmsg0(900, bs->msg);
+ if (strcmp(bs->msg, resp) == 0) {
+ return true;
}
+ Dmsg1(900, "Bad response: ERR=%s", bs->msg);
if (prtmsg == DISPLAY_ERROR) {
- Jmsg(jcr, M_FATAL, 0, _("FD gave bad response to %s command: wanted %s got: %s\n"),
- cmd, resp, fd->msg);
+ Jmsg(jcr, M_FATAL, 0, _("Bad response to %s command: wanted %s got: %s\n"),
+ cmd, resp, bs->msg);
}
- return 0;
+ return false;
}
- Jmsg(jcr, M_FATAL, 0, _("Socket error from Filed on %s command: ERR=%s\n"),
- cmd, bnet_strerror(fd));
- return 0;
+ Jmsg(jcr, M_FATAL, 0, _("Socket error on %s command: ERR=%s\n"),
+ cmd, bnet_strerror(bs));
+ return false;
}
}
if (!inc_opts[0]) {
- strcat(inc_opts, "0"); /* set no options */
+ bstrncat(inc_opts, "0", sizeof(inc_opts)); /* set no options */
}
inc_opts_len = strlen(inc_opts);
Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n",
jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel);
+
+ if (!get_or_create_client_record(jcr)) {
+ goto bail_out;
+ }
+
+ if (!jcr->fname) {
+ jcr->fname = get_pool_memory(PM_FNAME);
+ }
+
Dmsg0(200, "Add jrc to work queue\n");
/* Queue the job to be run */
/* Cancel Storage daemon */
if (jcr->store_bsock) {
- if (!ua->jcr->storage[0]) {
+ if (!ua->jcr->storage) {
copy_storage(ua->jcr, jcr);
} else {
set_storage(ua->jcr, jcr->store);
control_jcr = (JCR *)self->data;
- Dmsg1(400, "job_monitor_watchdog %p called\n", self);
+ Dmsg1(800, "job_monitor_watchdog %p called\n", self);
lock_jcr_chain();
bool cancel;
if (jcr->JobId == 0) {
- Dmsg2(400, "Skipping JCR %p (%s) with JobId 0\n",
+ Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
jcr, jcr->Job);
/* Keep reference counts correct */
free_locked_jcr(jcr);
cancel |= job_check_maxruntime(control_jcr, jcr);
if (cancel) {
- Dmsg3(200, "Cancelling JCR %p jobid %d (%s)\n",
+ Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n",
jcr, jcr->JobId, jcr->Job);
UAContext *ua = new_ua_context(jcr);
cancel_job(ua, jcr);
free_ua_context(ua);
- Dmsg1(200, "Have cancelled JCR %p\n", jcr);
+ Dmsg1(800, "Have cancelled JCR %p\n", jcr);
}
/* Keep reference counts correct */
return false;
}
if ((watchdog_time - jcr->start_time) < jcr->job->MaxWaitTime) {
- Dmsg3(200, "Job %p (%s) with MaxWaitTime %d not expired\n",
+ Dmsg3(800, "Job %p (%s) with MaxWaitTime %d not expired\n",
jcr, jcr->Job, jcr->job->MaxWaitTime);
return false;
}
- Dmsg3(200, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
+ Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
"checking status\n",
jcr->JobId, jcr->Job, jcr->job->MaxWaitTime);
switch (jcr->JobStatus) {
Dmsg0(200, "JCR blocked in #1\n");
break;
case JS_Running:
- Dmsg0(200, "JCR running, checking SD status\n");
+ Dmsg0(800, "JCR running, checking SD status\n");
switch (jcr->SDJobStatus) {
case JS_WaitMount:
case JS_WaitMedia:
case JS_WaitFD:
cancel = true;
- Dmsg0(200, "JCR blocked in #2\n");
+ Dmsg0(800, "JCR blocked in #2\n");
break;
default:
- Dmsg0(200, "JCR not blocked in #2\n");
+ Dmsg0(800, "JCR not blocked in #2\n");
break;
}
break;
case JS_ErrorTerminated:
case JS_Canceled:
case JS_FatalError:
- Dmsg0(200, "JCR already dead in #3\n");
+ Dmsg0(800, "JCR already dead in #3\n");
break;
default:
Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
jcr->JobStatus);
}
- Dmsg3(200, "MaxWaitTime result: %scancel JCR %p (%s)\n",
+ Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
cancel ? "" : "do not ", jcr, jcr->job);
return cancel;
pthread_cond_destroy(&jcr->term_wait);
}
/* Delete lists setup to hold storage pointers */
- for (int i=0; i<MAX_STORE; i++) {
- if (jcr->storage[i]) {
- delete jcr->storage[i];
- }
+ if (jcr->storage) {
+ delete jcr->storage;
}
jcr->job_end_push.destroy();
Dmsg0(200, "End dird free_jcr\n");
*/
void set_jcr_defaults(JCR *jcr, JOB *job)
{
+ STORE *st;
jcr->job = job;
jcr->JobType = job->JobType;
switch (jcr->JobType) {
}
jcr->JobPriority = job->Priority;
/* Copy storage definitions -- deleted in dir_free_jcr above */
- for (int i=0; i < MAX_STORE; i++) {
- STORE *st;
- if (job->storage[i]) {
- if (jcr->storage[i]) {
- delete jcr->storage[i];
- }
- jcr->storage[i] = New(alist(10, not_owned_by_alist));
- foreach_alist(st, job->storage[i]) {
- jcr->storage[i]->append(st);
- }
+ if (job->storage) {
+ if (jcr->storage) {
+ delete jcr->storage;
+ }
+ jcr->storage = New(alist(10, not_owned_by_alist));
+ foreach_alist(st, job->storage) {
+ jcr->storage->append(st);
}
}
- if (jcr->storage[0]) {
- jcr->store = (STORE *)jcr->storage[0]->first();
+ if (jcr->storage) {
+ jcr->store = (STORE *)jcr->storage->first();
}
jcr->client = job->client;
if (!jcr->client_name) {
*/
void copy_storage(JCR *new_jcr, JCR *old_jcr)
{
- for (int i=0; i < MAX_STORE; i++) {
- if (old_jcr->storage[i]) {
- STORE *st;
- if (old_jcr->storage[i]) {
- delete old_jcr->storage[i];
- }
- new_jcr->storage[i] = New(alist(10, not_owned_by_alist));
- foreach_alist(st, old_jcr->storage[i]) {
- new_jcr->storage[i]->append(st);
- }
+ if (old_jcr->storage) {
+ STORE *st;
+ if (old_jcr->storage) {
+ delete old_jcr->storage;
}
- if (old_jcr->store) {
- new_jcr->store = old_jcr->store;
- } else if (new_jcr->storage[0]) {
- new_jcr->store = (STORE *)new_jcr->storage[0]->first();
+ new_jcr->storage = New(alist(10, not_owned_by_alist));
+ foreach_alist(st, old_jcr->storage) {
+ new_jcr->storage->append(st);
}
}
+ if (old_jcr->store) {
+ new_jcr->store = old_jcr->store;
+ } else if (new_jcr->storage) {
+ new_jcr->store = (STORE *)new_jcr->storage->first();
+ }
}
/* Set storage override */
void set_storage(JCR *jcr, STORE *store)
{
+ STORE *storage;
+
jcr->store = store;
- jcr->storage[0]->prepend(store);
+ foreach_alist(storage, jcr->storage) {
+ if (store == storage) {
+ return;
+ }
+ }
+ /* Store not in list, so add it */
+ jcr->storage->prepend(store);
}
*
*/
/*
- Copyright (C) 2003-2004 Kern Sibbald
+ Copyright (C) 2003-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
JCR *jcr = ((wait_pkt *)arg)->jcr;
jobq_t *jq = ((wait_pkt *)arg)->jq;
- Dmsg0(300, "Enter sched_wait.\n");
+ Dmsg0(2300, "Enter sched_wait.\n");
free(arg);
time_t wtime = jcr->sched_time - time(NULL);
set_jcr_job_status(jcr, JS_WaitStartTime);
}
/* Check every 30 seconds if canceled */
while (wtime > 0) {
- Dmsg2(300, "Waiting on sched time, jobid=%d secs=%d\n", jcr->JobId, wtime);
+ Dmsg2(2300, "Waiting on sched time, jobid=%d secs=%d\n", jcr->JobId, wtime);
if (wtime > 30) {
wtime = 30;
}
jobq_add(jq, jcr);
V(jcr->mutex);
free_jcr(jcr); /* we are done with jcr */
- Dmsg0(300, "Exit sched_wait\n");
+ Dmsg0(2300, "Exit sched_wait\n");
return NULL;
}
pthread_t id;
wait_pkt *sched_pkt;
- Dmsg3(300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
+ Dmsg3(2300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
if (jq->valid != JOBQ_VALID) {
Jmsg0(jcr, M_ERROR, 0, "Jobq_add queue not initialized.\n");
return EINVAL;
}
jcr->use_count++; /* mark jcr in use by us */
- Dmsg3(300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
+ Dmsg3(2300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count);
if (!job_canceled(jcr) && wtime > 0) {
set_thread_concurrency(jq->max_workers + 2);
sched_pkt = (wait_pkt *)malloc(sizeof(wait_pkt));
if (job_canceled(jcr)) {
/* Add job to ready queue so that it is canceled quickly */
jq->ready_jobs->prepend(item);
- Dmsg1(300, "Prepended job=%d to ready queue\n", jcr->JobId);
+ Dmsg1(2300, "Prepended job=%d to ready queue\n", jcr->JobId);
} else {
/* Add this job to the wait queue in priority sorted order */
foreach_dlist(li, jq->waiting_jobs) {
- Dmsg2(300, "waiting item jobid=%d priority=%d\n",
+ Dmsg2(2300, "waiting item jobid=%d priority=%d\n",
li->jcr->JobId, li->jcr->JobPriority);
if (li->jcr->JobPriority > jcr->JobPriority) {
jq->waiting_jobs->insert_before(item, li);
- Dmsg2(300, "insert_before jobid=%d before waiting job=%d\n",
+ Dmsg2(2300, "insert_before jobid=%d before waiting job=%d\n",
li->jcr->JobId, jcr->JobId);
inserted = true;
break;
/* If not jobs in wait queue, append it */
if (!inserted) {
jq->waiting_jobs->append(item);
- Dmsg1(300, "Appended item jobid=%d to waiting queue\n", jcr->JobId);
+ Dmsg1(2300, "Appended item jobid=%d to waiting queue\n", jcr->JobId);
}
}
stat = start_server(jq);
pthread_mutex_unlock(&jq->mutex);
- Dmsg0(300, "Return jobq_add\n");
+ Dmsg0(2300, "Return jobq_add\n");
return stat;
}
bool found = false;
jobq_item_t *item;
- Dmsg2(300, "jobq_remove jobid=%d jcr=0x%x\n", jcr->JobId, jcr);
+ Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x\n", jcr->JobId, jcr);
if (jq->valid != JOBQ_VALID) {
return EINVAL;
}
}
if (!found) {
pthread_mutex_unlock(&jq->mutex);
- Dmsg2(300, "jobq_remove jobid=%d jcr=0x%x not in wait queue\n", jcr->JobId, jcr);
+ Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x not in wait queue\n", jcr->JobId, jcr);
return EINVAL;
}
/* Move item to be the first on the list */
jq->waiting_jobs->remove(item);
jq->ready_jobs->prepend(item);
- Dmsg2(300, "jobq_remove jobid=%d jcr=0x%x moved to ready queue\n", jcr->JobId, jcr);
+ Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x moved to ready queue\n", jcr->JobId, jcr);
stat = start_server(jq);
pthread_mutex_unlock(&jq->mutex);
- Dmsg0(300, "Return jobq_remove\n");
+ Dmsg0(2300, "Return jobq_remove\n");
return stat;
}
/* if any threads are idle, wake one */
if (jq->idle_workers > 0) {
- Dmsg0(300, "Signal worker to wake up\n");
+ Dmsg0(2300, "Signal worker to wake up\n");
if ((stat = pthread_cond_signal(&jq->work)) != 0) {
berrno be;
Jmsg1(NULL, M_ERROR, 0, "pthread_cond_signal: ERR=%s\n", be.strerror(stat));
return stat;
}
} else if (jq->num_workers < jq->max_workers) {
- Dmsg0(300, "Create worker thread\n");
+ Dmsg0(2300, "Create worker thread\n");
/* No idle threads so create a new one */
set_thread_concurrency(jq->max_workers + 1);
if ((stat = pthread_create(&id, &jq->attr, jobq_server, (void *)jq)) != 0) {
bool timedout = false;
bool work = true;
- Dmsg0(300, "Start jobq_server\n");
+ Dmsg0(2300, "Start jobq_server\n");
if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) {
berrno be;
Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_lock: ERR=%s\n", be.strerror(stat));
struct timeval tv;
struct timezone tz;
- Dmsg0(300, "Top of for loop\n");
+ Dmsg0(2300, "Top of for loop\n");
if (!work && !jq->quit) {
gettimeofday(&tv, &tz);
timeout.tv_nsec = 0;
/*
* Wait 4 seconds, then if no more work, exit
*/
- Dmsg0(300, "pthread_cond_timedwait()\n");
+ Dmsg0(2300, "pthread_cond_timedwait()\n");
stat = pthread_cond_timedwait(&jq->work, &jq->mutex, &timeout);
if (stat == ETIMEDOUT) {
- Dmsg0(300, "timedwait timedout.\n");
+ Dmsg0(2300, "timedwait timedout.\n");
timedout = true;
break;
} else if (stat != 0) {
- /* This shouldn't happen */
- Dmsg0(300, "This shouldn't happen\n");
+ /* This shouldn't happen */
+ Dmsg0(2300, "This shouldn't happen\n");
jq->num_workers--;
pthread_mutex_unlock(&jq->mutex);
return NULL;
/*
* If anything is in the ready queue, run it
*/
- Dmsg0(300, "Checking ready queue.\n");
+ Dmsg0(2300, "Checking ready queue.\n");
while (!jq->ready_jobs->empty() && !jq->quit) {
JCR *jcr;
je = (jobq_item_t *)jq->ready_jobs->first();
jcr = je->jcr;
jq->ready_jobs->remove(je);
if (!jq->ready_jobs->empty()) {
- Dmsg0(300, "ready queue not empty start server\n");
+ Dmsg0(2300, "ready queue not empty start server\n");
if (start_server(jq) != 0) {
jq->num_workers--;
pthread_mutex_unlock(&jq->mutex);
}
}
jq->running_jobs->append(je);
- Dmsg1(300, "Took jobid=%d from ready and appended to run\n", jcr->JobId);
+ Dmsg1(2300, "Took jobid=%d from ready and appended to run\n", jcr->JobId);
/* Release job queue lock */
if ((stat = pthread_mutex_unlock(&jq->mutex)) != 0) {
}
/* Call user's routine here */
- Dmsg1(300, "Calling user engine for jobid=%d\n", jcr->JobId);
+ Dmsg1(2300, "Calling user engine for jobid=%d\n", jcr->JobId);
jq->engine(je->jcr);
- Dmsg1(300, "Back from user engine jobid=%d.\n", jcr->JobId);
+ Dmsg1(2300, "Back from user engine jobid=%d.\n", jcr->JobId);
/* Reacquire job queue lock */
if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) {
*/
jcr->reschedule_count++;
jcr->sched_time = time(NULL) + jcr->job->RescheduleInterval;
- Dmsg2(300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
+ Dmsg2(2300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
(int)jcr->job->RescheduleInterval);
bstrftime(dt, sizeof(dt), time(NULL));
- Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
+ Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
jcr->Job, dt, (int)jcr->job->RescheduleInterval);
dird_free_jcr(jcr); /* partial cleanup old stuff */
jcr->JobStatus = JS_WaitStartTime;
jcr->SDJobStatus = 0;
if (jcr->JobBytes == 0) {
- Dmsg1(300, "Requeue job=%d\n", jcr->JobId);
+ Dmsg1(2300, "Requeue job=%d\n", jcr->JobId);
jcr->JobStatus = JS_WaitStartTime;
V(jq->mutex);
jobq_add(jq, jcr); /* queue the job to run again */
njcr->JobStatus = jcr->JobStatus;
copy_storage(njcr, jcr);
njcr->messages = jcr->messages;
- Dmsg0(300, "Call to run new job\n");
+ Dmsg0(2300, "Call to run new job\n");
V(jq->mutex);
- run_job(njcr); /* This creates a "new" job */
- free_jcr(njcr); /* release "new" jcr */
+ run_job(njcr); /* This creates a "new" job */
+ free_jcr(njcr); /* release "new" jcr */
P(jq->mutex);
- Dmsg0(300, "Back from running new job.\n");
+ Dmsg0(2300, "Back from running new job.\n");
}
/* Clean up and release old jcr */
if (jcr->db) {
db_close_database(jcr, jcr->db);
jcr->db = NULL;
}
- Dmsg2(300, "====== Termination job=%d use_cnt=%d\n", jcr->JobId, jcr->use_count);
+ Dmsg2(2300, "====== Termination job=%d use_cnt=%d\n", jcr->JobId, jcr->use_count);
jcr->SDJobStatus = 0;
V(jq->mutex); /* release internal lock */
free_jcr(jcr);
* If any job in the wait queue can be run,
* move it to the ready queue
*/
- Dmsg0(300, "Done check ready, now check wait queue.\n");
+ Dmsg0(2300, "Done check ready, now check wait queue.\n");
while (!jq->waiting_jobs->empty() && !jq->quit) {
int Priority;
je = (jobq_item_t *)jq->waiting_jobs->first();
jobq_item_t *re = (jobq_item_t *)jq->running_jobs->first();
if (re) {
Priority = re->jcr->JobPriority;
- Dmsg2(300, "JobId %d is running. Look for pri=%d\n", re->jcr->JobId, Priority);
+ Dmsg2(2300, "JobId %d is running. Look for pri=%d\n", re->jcr->JobId, Priority);
} else {
Priority = je->jcr->JobPriority;
- Dmsg1(300, "No job running. Look for Job pri=%d\n", Priority);
+ Dmsg1(2300, "No job running. Look for Job pri=%d\n", Priority);
}
/*
* Walk down the list of waiting jobs and attempt
JCR *jcr = je->jcr;
bool skip_this_jcr = false;
jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
- Dmsg3(300, "Examining Job=%d JobPri=%d want Pri=%d\n",
+ Dmsg3(2300, "Examining Job=%d JobPri=%d want Pri=%d\n",
jcr->JobId, jcr->JobPriority, Priority);
/* Take only jobs of correct Priority */
if (jcr->JobPriority != Priority) {
jcr->acquired_resource_locks = true;
jq->waiting_jobs->remove(je);
jq->ready_jobs->append(je);
- Dmsg1(300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
+ Dmsg1(2300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
je = jn; /* Point to next waiting job */
} /* end for loop */
break;
} /* end while loop */
- Dmsg0(300, "Done checking wait queue.\n");
+ Dmsg0(2300, "Done checking wait queue.\n");
/*
* If no more ready work and we are asked to quit, then do it
*/
if (jq->ready_jobs->empty() && jq->quit) {
jq->num_workers--;
if (jq->num_workers == 0) {
- Dmsg0(300, "Wake up destroy routine\n");
+ Dmsg0(2300, "Wake up destroy routine\n");
/* Wake up destroy routine if he is waiting */
pthread_cond_broadcast(&jq->work);
}
break;
}
- Dmsg0(300, "Check for work request\n");
+ Dmsg0(2300, "Check for work request\n");
/*
* If no more work requests, and we waited long enough, quit
*/
- Dmsg2(300, "timedout=%d read empty=%d\n", timedout,
+ Dmsg2(2300, "timedout=%d read empty=%d\n", timedout,
jq->ready_jobs->empty());
if (jq->ready_jobs->empty() && timedout) {
- Dmsg0(300, "break big loop\n");
+ Dmsg0(2300, "break big loop\n");
jq->num_workers--;
break;
}
/* Recompute work as something may have changed in last 2 secs */
work = !jq->ready_jobs->empty() || !jq->waiting_jobs->empty();
}
- Dmsg1(300, "Loop again. work=%d\n", work);
+ Dmsg1(2300, "Loop again. work=%d\n", work);
} /* end of big for loop */
Dmsg0(200, "unlock mutex\n");
berrno be;
Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_unlock: ERR=%s\n", be.strerror(stat));
}
- Dmsg0(300, "End jobq_server\n");
+ Dmsg0(2300, "End jobq_server\n");
return NULL;
}
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
break;
}
- if (!get_or_create_client_record(jcr)) {
- goto bail_out;
- }
-
if (!get_or_create_fileset_record(jcr, &fsr)) {
goto bail_out;
}
Dmsg1(100, "find last jobid for: %s\n", NPRT(Name));
if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) {
Jmsg(jcr, M_FATAL, 0, _(
- "Unable to find JobId of previous Job for this client.\n"));
+ "Unable to find JobId of previous Job for this client.\n"));
goto bail_out;
}
input_jobid = jr.JobId;
jcr->JobLevel = jr.JobLevel;
Dmsg1(100, "Last jobid=%d\n", input_jobid);
- jcr->fname = get_pool_memory(PM_FNAME);
-
/*
* Get the Pool record -- first apply any level defined pools
*/
while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
/* Try to create the pool */
if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
- Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+ Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
db_strerror(jcr->db));
goto bail_out;
} else {
- Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+ Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
}
}
jcr->PoolId = pr.PoolId; /****FIXME**** this can go away */
goto bail_out;
}
-
/*
* Open a message channel connection with the Storage
* daemon. This is to let him know that our client
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr)) {
+ if (!start_storage_daemon_job(jcr, jcr->storage, SD_APPEND)) {
goto bail_out;
}
/*
if (*fname == '|') {
fname++;
got_pipe = 1;
- bpipe = open_bpipe(fname, 0, "w");
+ bpipe = open_bpipe(fname, 0, "w");
fd = bpipe ? bpipe->wfd : NULL;
} else {
/* ***FIXME*** handle BASE */
- fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
+ fd = fopen(fname, jcr->JobLevel==L_FULL?"w+":"a+");
}
if (fd) {
VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId,
&VolParams);
if (VolCount == 0) {
- Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
- "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
+ Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to "
+ "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db));
if (jcr->SDJobFiles != 0) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
}
for (int i=0; i < VolCount; i++) {
/* Write the record */
- fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
- fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
- fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
+ fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
+ fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType);
+ fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId);
+ fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime);
+ fprintf(fd, "VolFile=%u-%u\n", VolParams[i].StartFile,
VolParams[i].EndFile);
- fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
+ fprintf(fd, "VolBlock=%u-%u\n", VolParams[i].StartBlock,
VolParams[i].EndBlock);
- fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
+ fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex,
VolParams[i].LastIndex);
}
if (VolParams) {
}
} else {
berrno be;
- Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
- "%s: ERR=%s\n"), fname, be.strerror());
+ Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n"
+ "%s: ERR=%s\n"), fname, be.strerror());
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
}
switch (jcr->JobStatus) {
case JS_Terminated:
if (jcr->Errors || jcr->SDErrors) {
- term_msg = _("Backup OK -- with warnings");
+ term_msg = _("Backup OK -- with warnings");
} else {
- term_msg = _("Backup OK");
+ term_msg = _("Backup OK");
}
break;
case JS_FatalError:
case JS_ErrorTerminated:
- term_msg = _("*** Backup Error ***");
+ term_msg = _("*** Backup Error ***");
msg_type = M_ERROR; /* Generate error message */
if (jcr->store_bsock) {
bnet_sig(jcr->store_bsock, BNET_TERMINATE);
}
break;
case JS_Canceled:
- term_msg = _("Backup Canceled");
+ term_msg = _("Backup Canceled");
if (jcr->store_bsock) {
bnet_sig(jcr->store_bsock, BNET_TERMINATE);
if (jcr->SD_msg_chan) {
break;
default:
term_msg = term_code;
- sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
+ sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus);
break;
}
bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime);
* normal exit should we complain about this error.
*/
if (jcr->JobStatus == JS_Terminated && jcr->jr.JobBytes) {
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+ Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
}
jcr->VolumeName[0] = 0; /* none */
}
} else {
compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes);
if (compression < 0.5) {
- bstrncpy(compress, "None", sizeof(compress));
+ bstrncpy(compress, "None", sizeof(compress));
} else {
- bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
+ bsnprintf(compress, sizeof(compress), "%.1f %%", (float)compression);
}
}
jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
/* Commands sent to Storage daemon */
static char jobcmd[] = "JobId=%d job=%s job_name=%s client_name=%s "
-"type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s SpoolData=%d WritePartAfterJob=%d";
-static char use_device[] = "use device=%s media_type=%s pool_name=%s pool_type=%s\n";
+ "type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s "
+ "SpoolData=%d WritePartAfterJob=%d";
+static char use_device[] = "use device=%s media_type=%s pool_name=%s "
+ "pool_type=%s append=%d\n";
+static char query_device[] = "query device=%s";
/* Response from Storage daemon */
static char OKjob[] = "3000 OK Job SDid=%d SDtime=%d Authorization=%100s\n";
static char OK_device[] = "3000 OK use device\n";
+static char OK_query[] = "3001 OK query append=%d read=%d num_writers=%d "
+ "num_waiting=%d open=%d use_count=%d labeled=%d "
+ "media_type=%127s volume_name=%127s";
/* Storage Daemon requests */
static char Job_start[] = "3010 Job %127s start\n";
static char Job_end[] =
"3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%" lld "\n";
-static char Job_status[] = "3012 Job %127s jobstatus %d\n";
/* Forward referenced functions */
extern "C" void *msg_thread(void *arg);
BSOCK *sd;
STORE *store;
- store = (STORE *)jcr->storage[0]->first();
+ if (jcr->store_bsock) {
+ return true; /* already connected */
+ }
+ store = (STORE *)jcr->storage->first();
/*
* Open message channel with the Storage daemon
jcr->store_bsock = sd;
if (!authenticate_storage_daemon(jcr, store)) {
+ bnet_close(sd);
+ jcr->store_bsock = NULL;
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Here we ask the SD to send us the info for a
+ * particular device resource.
+ */
+bool update_device_res(JCR *jcr, DEVICE *dev)
+{
+ POOL_MEM device_name, media_type, volume_name;
+ int dev_open, dev_append, dev_read, dev_labeled;
+ BSOCK *sd;
+ if (!connect_to_storage_daemon(jcr, 5, 30, 0)) {
+ return false;
+ }
+ sd = jcr->store_bsock;
+ pm_strcpy(device_name, dev->hdr.name);
+ bash_spaces(device_name);
+ bnet_fsend(sd, query_device, device_name.c_str());
+ if (bget_dirmsg(sd) > 0) {
+ Dmsg1(400, "<stored: %s", sd->msg);
+ if (sscanf(sd->msg, OK_query, &dev_append, &dev_read,
+ &dev->num_writers, &dev->num_waiting, &dev_open,
+ &dev->use_count, &dev_labeled, media_type.c_str(),
+ volume_name.c_str()) != 9) {
+ return false;
+ }
+ unbash_spaces(media_type);
+ unbash_spaces(volume_name);
+ bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
+ bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
+ dev->open = dev_open;
+ dev->append = dev_append;
+ dev->read = dev_read;
+ dev->labeled = dev_labeled;
+ dev->found = true;
+ } else {
return false;
}
return true;
/*
* Start a job with the Storage daemon
*/
-int start_storage_daemon_job(JCR *jcr)
+int start_storage_daemon_job(JCR *jcr, alist *store, int append)
{
- int status = 0;
+ bool ok;
STORE *storage;
BSOCK *sd;
char auth_key[100];
POOL_MEM device_name, pool_name, pool_type, media_type;
- int i;
sd = jcr->store_bsock;
/*
bash_spaces(jcr->client->hdr.name);
bash_spaces(jcr->fileset->hdr.name);
if (jcr->fileset->MD5[0] == 0) {
- strcpy(jcr->fileset->MD5, "**Dummy**");
+ bstrncpy(jcr->fileset->MD5, "**Dummy**", sizeof(jcr->fileset->MD5));
}
bnet_fsend(sd, jobcmd, jcr->JobId, jcr->Job, jcr->job->hdr.name,
jcr->client->hdr.name, jcr->JobType, jcr->JobLevel,
return 0;
}
- /*
- * Send use device = xxx media = yyy pool = zzz
- */
-
- for (i=0; i < MAX_STORE; i++) {
- if (jcr->storage[i]) {
- storage = (STORE *)jcr->storage[i]->first();
- pm_strcpy(device_name, storage->dev_name);
- pm_strcpy(media_type, storage->media_type);
- pm_strcpy(pool_type, jcr->pool->pool_type);
- pm_strcpy(pool_name, jcr->pool->hdr.name);
- bash_spaces(device_name);
- bash_spaces(media_type);
- bash_spaces(pool_type);
- bash_spaces(pool_name);
- bnet_fsend(sd, use_device, device_name.c_str(),
- media_type.c_str(), pool_name.c_str(), pool_type.c_str());
- Dmsg1(110, ">stored: %s", sd->msg);
- status = response(jcr, sd, OK_device, "Use Device", NO_DISPLAY);
- if (!status) {
- pm_strcpy(pool_type, sd->msg); /* save message */
- Jmsg(jcr, M_FATAL, 0, _("\n"
- " Storage daemon didn't accept Device \"%s\" because:\n %s"),
- device_name.c_str(), pool_type.c_str()/* sd->msg */);
- }
+// foreach_alist(storage, store) {
+ storage = (STORE *)store->first();
+ pm_strcpy(device_name, storage->dev_name());
+ pm_strcpy(media_type, storage->media_type);
+ pm_strcpy(pool_type, jcr->pool->pool_type);
+ pm_strcpy(pool_name, jcr->pool->hdr.name);
+ bash_spaces(device_name);
+ bash_spaces(media_type);
+ bash_spaces(pool_type);
+ bash_spaces(pool_name);
+ bnet_fsend(sd, use_device, device_name.c_str(),
+ media_type.c_str(), pool_name.c_str(), pool_type.c_str(),
+ append);
+ Dmsg1(200, ">stored: %s", sd->msg);
+ ok = response(jcr, sd, OK_device, "Use Device", NO_DISPLAY);
+ if (!ok) {
+ pm_strcpy(pool_type, sd->msg); /* save message */
+ Jmsg(jcr, M_FATAL, 0, _("\n"
+ " Storage daemon didn't accept Device \"%s\" because:\n %s"),
+ device_name.c_str(), pool_type.c_str()/* sd->msg */);
}
+// }
+ if (ok) {
+ bnet_fsend(sd, "run");
}
- return status;
+ return ok;
}
/*
V(jcr->mutex);
Dmsg0(100, "Start SD msg_thread.\n");
if ((status=pthread_create(&thid, NULL, msg_thread, (void *)jcr)) != 0) {
- Jmsg1(jcr, M_ABORT, 0, _("Cannot create message thread: %s\n"), strerror(status));
+ berrno be;
+ Jmsg1(jcr, M_ABORT, 0, _("Cannot create message thread: %s\n"), be.strerror(status));
}
Dmsg0(100, "SD msg_thread started.\n");
/* Wait for thread to start */
* Storage daemon).
* Note, we are running in a separate thread.
*/
-extern "C"
-void *msg_thread(void *arg)
+extern "C" void *msg_thread(void *arg)
{
JCR *jcr = (JCR *)arg;
BSOCK *sd;
jcr->SDJobBytes = JobBytes;
break;
}
- if (sscanf(sd->msg, Job_status, &Job, &JobStatus) == 2) {
- jcr->SDJobStatus = JobStatus; /* current status */
- continue;
- }
}
if (is_bnet_error(sd)) {
jcr->SDJobStatus = JS_ErrorTerminated;
V(jcr->mutex);
set_jcr_job_status(jcr, JS_Terminated);
}
+
+
+#define MAX_TRIES 30
+#define WAIT_TIME 2
+extern "C" void *device_thread(void *arg)
+{
+ int i;
+ JCR *jcr;
+ DEVICE *dev;
+
+
+ pthread_detach(pthread_self());
+ jcr = new_control_jcr("*DeviceInit*", JT_SYSTEM);
+ for (i=0; i < MAX_TRIES; i++) {
+ if (!connect_to_storage_daemon(jcr, 10, 30, 1)) {
+ Dmsg0(000, "Failed connecting to SD.\n");
+ continue;
+ }
+ LockRes();
+ foreach_res(dev, R_DEVICE) {
+ if (!update_device_res(jcr, dev)) {
+ Dmsg1(900, "Error updating device=%s\n", dev->hdr.name);
+ } else {
+ Dmsg1(900, "Updated Device=%s\n", dev->hdr.name);
+ }
+ }
+ UnlockRes();
+ bnet_close(jcr->store_bsock);
+ jcr->store_bsock = NULL;
+ break;
+
+ }
+ free_jcr(jcr);
+ return NULL;
+}
+
+/*
+ * Start a thread to handle getting Device resource information
+ * from SD. This is called once at startup of the Director.
+ */
+void init_device_resources()
+{
+ int status;
+ pthread_t thid;
+
+ Dmsg0(100, "Start Device thread.\n");
+ if ((status=pthread_create(&thid, NULL, device_thread, NULL)) != 0) {
+ berrno be;
+ Jmsg1(NULL, M_ABORT, 0, _("Cannot create message thread: %s\n"), be.strerror(status));
+ }
+}
DISPLAY_ERROR,
NO_DISPLAY
};
-extern int response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg);
+extern bool response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg);
/* job.c */
extern void set_jcr_defaults(JCR *jcr, JOB *job);
/* msgchan.c */
extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
int max_retry_time, int verbose);
-extern int start_storage_daemon_job(JCR *jcr);
+extern int start_storage_daemon_job(JCR *jcr, alist *store, int append);
extern int start_storage_daemon_message_thread(JCR *jcr);
extern int bget_dirmsg(BSOCK *bs);
extern void wait_for_storage_daemon_termination(JCR *jcr);
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
BSOCK *fd;
JOB_DBR rjr; /* restore job record */
- if (!get_or_create_client_record(jcr)) {
- restore_cleanup(jcr, JS_ErrorTerminated);
- return 0;
- }
-
memset(&rjr, 0, sizeof(rjr));
jcr->jr.JobLevel = L_FULL; /* Full restore */
if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
return 0;
}
Dmsg0(20, "Updated job start record\n");
- jcr->fname = (char *) get_pool_memory(PM_FNAME);
Dmsg1(20, "RestoreJobId=%d\n", jcr->job->RestoreJobId);
rjr.JobId = jcr->job->RestoreJobId; /* specified by Job Resource */
}
if (!db_get_job_record(jcr, jcr->db, &rjr)) {
- Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
+ Jmsg2(jcr, M_FATAL, 0, _("Cannot get job record id=%d %s"), rjr.JobId,
db_strerror(jcr->db));
restore_cleanup(jcr, JS_ErrorTerminated);
return 0;
jcr->VolumeName[0] = 0;
if (!db_get_job_volume_names(jcr, jcr->db, rjr.JobId, &jcr->VolumeName) ||
jcr->VolumeName[0] == 0) {
- Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume names for restore Job %d. %s"),
+ Jmsg(jcr, M_FATAL, 0, _("Cannot find Volume names for restore Job %d. %s"),
rjr.JobId, db_strerror(jcr->db));
restore_cleanup(jcr, JS_ErrorTerminated);
return 0;
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr)) {
+ if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
restore_cleanup(jcr, JS_ErrorTerminated);
return 0;
}
switch (TermCode) {
case JS_Terminated:
if (jcr->ExpectedFiles > jcr->jr.JobFiles) {
- term_msg = _("Restore OK -- warning file count mismatch");
+ term_msg = _("Restore OK -- warning file count mismatch");
} else {
- term_msg = _("Restore OK");
+ term_msg = _("Restore OK");
}
break;
case JS_FatalError:
/* Items corresponding to above at the next hour */
int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy, nh_year;
- Dmsg0(200, "enter find_runs()\n");
+ Dmsg0(1200, "enter find_runs()\n");
/* compute values for time now */
if (sched == NULL) { /* scheduled? */
continue; /* no, skip this job */
}
- Dmsg1(200, "Got job: %s\n", job->hdr.name);
+ Dmsg1(1200, "Got job: %s\n", job->hdr.name);
for (run=sched->run; run; run=run->next) {
bool run_now, run_nh;
/*
bit_is_set(nh_wom, run->wom) &&
bit_is_set(nh_woy, run->woy);
- Dmsg2(200, "run_now=%d run_nh=%d\n", run_now, run_nh);
+ Dmsg2(1200, "run_now=%d run_nh=%d\n", run_now, run_nh);
/* find time (time_t) job is to be run */
localtime_r(&now, &tm); /* reset tm structure */
}
}
UnlockRes();
- Dmsg0(200, "Leave find_runs()\n");
+ Dmsg0(1200, "Leave find_runs()\n");
}
static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
/* For ua_dotcmds.c */
const char *client_backups =
"SELECT DISTINCT Job.JobId,Client.Name as Client,Level,StartTime,"
-"JobFiles,JobBytes,VolumeName"
+"JobFiles,JobBytes,VolumeName,MediaType"
" FROM Client,Job,JobMedia,Media"
" WHERE Client.Name='%s'"
" AND Client.ClientId=Job.ClientId"
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* If no console resource => default console and all is permitted */
if (!ua->cons) {
- Dmsg0(400, "Root cons access OK.\n");
+ Dmsg0(1400, "Root cons access OK.\n");
return true; /* No cons resource -> root console OK for everything */
}
/* Search list for item */
for (int i=0; i<list->size(); i++) {
if (strcasecmp(item, (char *)list->get(i)) == 0) {
- Dmsg3(400, "Found %s in %d %s\n", item, acl, (char *)list->get(i));
+ Dmsg3(1400, "ACL found %s in %d %s\n", item, acl, (char *)list->get(i));
return true;
}
}
stat = 1;
- Dmsg1(200, "Command: %s\n", ua->UA_sock->msg);
+ Dmsg1(900, "Command: %s\n", ua->UA_sock->msg);
if (ua->argc == 0) {
return 1;
}
mr->MaxVolJobs = pr->MaxVolJobs;
mr->MaxVolFiles = pr->MaxVolFiles;
mr->MaxVolBytes = pr->MaxVolBytes;
+ mr->LabelType = pr->LabelType;
}
while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) {
bsendmsg(ua, _("Pool already has maximum volumes = %d\n"), pr.MaxVols);
for (;;) {
- if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
+ if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
return 1;
}
pr.MaxVols = ua->pint32_val;
}
num = ua->pint32_val;
if (num < 0 || num > max) {
- bsendmsg(ua, _("The number must be between 0 and %d\n"), max);
+ bsendmsg(ua, _("The number must be between 0 and %d\n"), max);
continue;
}
break;
bstrncpy(name, ua->cmd, sizeof(name));
if (num > 0) {
- strcat(name, "%04d");
+ bstrncat(name, "%04d", sizeof(name));
for (;;) {
- if (!get_pint(ua, _("Enter the starting number: "))) {
+ if (!get_pint(ua, _("Enter the starting number: "))) {
return 1;
}
startnum = ua->pint32_val;
if (startnum < 1) {
- bsendmsg(ua, _("Start number must be greater than zero.\n"));
+ bsendmsg(ua, _("Start number must be greater than zero.\n"));
continue;
}
break;
mr.InChanger = InChanger;
Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
return 1;
}
if (i == startnum) {
}
JobId = str_to_int64(ua->argv[i]);
if (!(jcr=get_jcr_by_id(JobId))) {
- bsendmsg(ua, _("JobId %d is not running.\n"), JobId);
+ bsendmsg(ua, _("JobId %d is not running.\n"), JobId);
return 1;
}
break;
break;
}
if (!(jcr=get_jcr_by_partial_name(ua->argv[i]))) {
- bsendmsg(ua, _("Job %s is not running.\n"), ua->argv[i]);
+ bsendmsg(ua, _("Job %s is not running.\n"), ua->argv[i]);
return 1;
}
break;
* throw up a list and ask the user to select one.
*/
if (!jcr) {
+ char buf[1000];
/* Count Jobs running */
lock_jcr_chain();
foreach_jcr(jcr) {
unlock_jcr_chain();
if (njobs == 0) {
- bsendmsg(ua, _("No Jobs running.\n"));
+ bsendmsg(ua, _("No Jobs running.\n"));
return 1;
}
start_prompt(ua, _("Select Job:\n"));
free_locked_jcr(jcr);
continue;
}
- add_prompt(ua, jcr->Job);
+ bsnprintf(buf, sizeof(buf), "JobId=%d Job=%s", jcr->JobId, jcr->Job);
+ add_prompt(ua, buf);
free_locked_jcr(jcr);
}
unlock_jcr_chain();
- if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), JobName, sizeof(JobName)) < 0) {
+ if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), buf, sizeof(buf)) < 0) {
return 1;
}
if (njobs == 1) {
- if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
+ if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
return 1;
}
}
/* NOTE! This increments the ref_count */
+ sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
jcr = get_jcr_by_full_name(JobName);
if (!jcr) {
- bsendmsg(ua, _("Job %s not found.\n"), JobName);
+ bsendmsg(ua, _("Job %s not found.\n"), JobName);
return 1;
}
}
*/
static void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
{
- strcpy(pr->PoolType, pool->pool_type);
+ bstrncpy(pr->PoolType, pool->pool_type, sizeof(pr->PoolType));
if (op == POOL_OP_CREATE) {
pr->MaxVols = pool->max_volumes;
pr->NumVols = 0;
pr->MaxVols = pr->NumVols;
}
}
+ pr->LabelType = pool->LabelType;
pr->UseOnce = pool->use_volume_once;
pr->UseCatalog = pool->use_catalog;
pr->AcceptAnyVolume = pool->accept_any_volume;
pr->AutoPrune = pool->AutoPrune;
pr->Recycle = pool->Recycle;
if (pool->label_format) {
- strcpy(pr->LabelFormat, pool->label_format);
+ bstrncpy(pr->LabelFormat, pool->label_format, sizeof(pr->LabelFormat));
} else {
- strcpy(pr->LabelFormat, "*"); /* none */
+ bstrncpy(pr->LabelFormat, "*", sizeof(pr->LabelFormat)); /* none */
}
}
memset(&pr, 0, sizeof(POOL_DBR));
- strcpy(pr.Name, pool->hdr.name);
+ bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
if (db_get_pool_record(jcr, db, &pr)) {
/* Pool Exists */
switch (create_pool(ua->jcr, ua->db, pool, POOL_OP_CREATE)) {
case 0:
bsendmsg(ua, _("Error: Pool %s already exists.\n"
- "Use update to change it.\n"), pool->hdr.name);
+ "Use update to change it.\n"), pool->hdr.name);
break;
case -1:
if (strcasecmp(ua->argk[1], _("restart")) == 0) {
term_python_interpreter();
init_python_interpreter(director->hdr.name, director->scripts_directory ?
- director->scripts_directory : ".");
+ director->scripts_directory : ".");
bsendmsg(ua, _("Python interpreter restarted.\n"));
} else {
bsendmsg(ua, _("Nothing done.\n"));
Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%u",
mr->VolStatus, mr->MediaId);
if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
} else {
- bsendmsg(ua, _("New Volume status is: %s\n"), mr->VolStatus);
+ bsendmsg(ua, _("New Volume status is: %s\n"), mr->VolStatus);
}
}
free_pool_memory(query);
bsendmsg(ua, "%s", db_strerror(ua->db));
} else {
bsendmsg(ua, _("New Recycle flag is: %s\n"),
- mr->Recycle==1?_("yes"):_("no"));
+ mr->Recycle==1?_("yes"):_("no"));
}
free_pool_memory(query);
}
bsendmsg(ua, _("New Pool is: %s\n"), pr.Name);
opr->NumVols--;
if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
pr.NumVols++;
if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
db_make_inchanger_unique(ua->jcr, ua->db, mr);
}
memset(&pr, 0, sizeof(POOL_DBR));
pr.PoolId = mr.PoolId;
if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
break;
}
update_vol_pool(ua, ua->argv[j], &mr, &pr);
switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
case 0: /* Volume Status */
/* Modify Volume Status */
- bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus);
- start_prompt(ua, _("Possible Values are:\n"));
- add_prompt(ua, "Append"); /* Better not translate these as */
- add_prompt(ua, "Archive"); /* They are known in the database code */
- add_prompt(ua, "Disabled");
- add_prompt(ua, "Full");
- add_prompt(ua, "Used");
- add_prompt(ua, "Cleaning");
- if (strcmp(mr.VolStatus, "Purged") == 0) {
- add_prompt(ua, "Recycle");
+ bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus);
+ start_prompt(ua, _("Possible Values are:\n"));
+ add_prompt(ua, "Append"); /* Better not translate these as */
+ add_prompt(ua, "Archive"); /* They are known in the database code */
+ add_prompt(ua, "Disabled");
+ add_prompt(ua, "Full");
+ add_prompt(ua, "Used");
+ add_prompt(ua, "Cleaning");
+ if (strcmp(mr.VolStatus, "Purged") == 0) {
+ add_prompt(ua, "Recycle");
}
- add_prompt(ua, "Read-Only");
- if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
+ add_prompt(ua, "Read-Only");
+ if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
return 1;
}
update_volstatus(ua, ua->cmd, &mr);
break;
case 1: /* Retention */
- bsendmsg(ua, _("Current retention period is: %s\n"),
+ bsendmsg(ua, _("Current retention period is: %s\n"),
edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
- if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
+ if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
return 0;
}
update_volretention(ua, ua->cmd, &mr);
break;
case 2: /* Use Duration */
- bsendmsg(ua, _("Current use duration is: %s\n"),
+ bsendmsg(ua, _("Current use duration is: %s\n"),
edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
- if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
+ if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
return 0;
}
update_voluseduration(ua, ua->cmd, &mr);
break;
case 3: /* Max Jobs */
- bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs);
- if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
+ bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs);
+ if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
return 0;
}
update_volmaxjobs(ua, ua->cmd, &mr);
break;
case 4: /* Max Files */
- bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles);
- if (!get_pint(ua, _("Enter new Maximum Files: "))) {
+ bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles);
+ if (!get_pint(ua, _("Enter new Maximum Files: "))) {
return 0;
}
update_volmaxfiles(ua, ua->cmd, &mr);
break;
case 5: /* Max Bytes */
- bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
- if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
+ bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
+ if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
return 0;
}
update_volmaxbytes(ua, ua->cmd, &mr);
case 6: /* Recycle */
- bsendmsg(ua, _("Current recycle flag is: %s\n"),
- mr.Recycle==1?_("yes"):_("no"));
- if (!get_yesno(ua, _("Enter new Recycle status: "))) {
+ bsendmsg(ua, _("Current recycle flag is: %s\n"),
+ mr.Recycle==1?_("yes"):_("no"));
+ if (!get_yesno(ua, _("Enter new Recycle status: "))) {
return 0;
}
update_volrecycle(ua, ua->cmd, &mr);
memset(&pr, 0, sizeof(POOL_DBR));
pr.PoolId = mr.PoolId;
if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
return 0;
}
- bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot);
- if (!get_pint(ua, _("Enter new Slot: "))) {
+ bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot);
+ if (!get_pint(ua, _("Enter new Slot: "))) {
return 0;
}
Slot = ua->pint32_val;
if (pr.MaxVols > 0 && Slot > (int)pr.MaxVols) {
- bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"),
+ bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"),
pr.MaxVols);
break;
}
* so that any Slot is handled correctly.
*/
if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
+ bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
} else {
- bsendmsg(ua, _("New Slot is: %d\n"), mr.Slot);
+ bsendmsg(ua, _("New Slot is: %d\n"), mr.Slot);
}
break;
case 8: /* InChanger */
- bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger);
- if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) {
+ bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger);
+ if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) {
return 0;
}
mr.InChanger = ua->pint32_val;
* so that any Slot is handled correctly.
*/
if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
+ bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
} else {
- bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger);
+ bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger);
}
break;
case 9: /* Volume Files */
int32_t VolFiles;
- bsendmsg(ua, _("Warning changing Volume Files can result\n"
- "in loss of data on your Volume\n\n"));
- bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles);
- if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
+ bsendmsg(ua, _("Warning changing Volume Files can result\n"
+ "in loss of data on your Volume\n\n"));
+ bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles);
+ if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
return 0;
}
VolFiles = ua->pint32_val;
if (VolFiles != (int)(mr.VolFiles + 1)) {
- bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n"));
- if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) {
+ bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n"));
+ if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) {
break;
}
}
query = get_pool_memory(PM_MESSAGE);
- Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%u",
+ Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%u",
VolFiles, mr.MediaId);
if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
} else {
- bsendmsg(ua, _("New Volume Files is: %u\n"), VolFiles);
+ bsendmsg(ua, _("New Volume Files is: %u\n"), VolFiles);
}
free_pool_memory(query);
break;
memset(&pr, 0, sizeof(POOL_DBR));
pr.PoolId = mr.PoolId;
if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
return 0;
}
- bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name);
- if (!get_cmd(ua, _("Enter new Pool name: "))) {
+ bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name);
+ if (!get_cmd(ua, _("Enter new Pool name: "))) {
return 0;
}
update_vol_pool(ua, ua->cmd, &mr, &pr);
update_all_vols_from_pool(ua);
return 1;
default: /* Done or error */
- bsendmsg(ua, "Selection done.\n");
+ bsendmsg(ua, "Selection done.\n");
return 1;
}
}
}
memset(&pr, 0, sizeof(pr));
- strcpy(pr.Name, pool->hdr.name);
+ bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
if (!get_pool_dbr(ua, &pr)) {
return 0;
}
}
if (!found) {
unique_store[i++] = store;
- Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport);
+ Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport);
}
}
UnlockRes();
}
if (!found) {
unique_client[i++] = client;
- Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport);
+ Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport);
}
}
UnlockRes();
return 1;
}
if (strcasecmp(ua->argk[i], _("dir")) == 0 ||
- strcasecmp(ua->argk[i], _("director")) == 0) {
+ strcasecmp(ua->argk[i], _("director")) == 0) {
debug_level = level;
set_trace(trace_flag);
return 1;
}
if (strcasecmp(ua->argk[i], _("client")) == 0 ||
- strcasecmp(ua->argk[i], _("fd")) == 0) {
+ strcasecmp(ua->argk[i], _("fd")) == 0) {
client = NULL;
if (ua->argv[i]) {
client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
}
if (strcasecmp(ua->argk[i], _("store")) == 0 ||
- strcasecmp(ua->argk[i], _("storage")) == 0 ||
- strcasecmp(ua->argk[i], _("sd")) == 0) {
+ strcasecmp(ua->argk[i], _("storage")) == 0 ||
+ strcasecmp(ua->argk[i], _("sd")) == 0) {
store = NULL;
if (ua->argv[i]) {
store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
jcr->JobLevel = L_FULL;
for (int i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], _("client")) == 0 ||
- strcasecmp(ua->argk[i], _("fd")) == 0) {
+ strcasecmp(ua->argk[i], _("fd")) == 0) {
if (ua->argv[i]) {
client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
continue;
}
if (strcasecmp(ua->argk[i], _("level")) == 0) {
if (!get_level_from_name(ua->jcr, ua->argv[i])) {
- bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]);
+ bsendmsg(ua, _("Level %s not valid.\n"), ua->argv[i]);
}
continue;
}
if (!job) {
job = (JOB *)GetResWithName(R_JOB, ua->argk[1]);
if (!job) {
- bsendmsg(ua, _("No job specified.\n"));
+ bsendmsg(ua, _("No job specified.\n"));
return 1;
}
}
s = bstrdup(ua->argv[i]);
tok = s;
/*
- * We could use strtok() here. But we're not going to, because:
+ * We could use strtok() here. But we're not going to, because:
* (a) strtok() is deprecated, having been replaced by strsep();
* (b) strtok() is broken in significant ways.
- * we could use strsep() instead, but it's not universally available.
+ * we could use strsep() instead, but it's not universally available.
* so we grow our own using strchr().
*/
- sep = strchr(tok, ',');
+ sep = strchr(tok, ',');
while (sep != NULL) {
- *sep = '\0';
- if (strchr(tok, '-')) {
+ *sep = '\0';
+ if (strchr(tok, '-')) {
delete_job_id_range(ua, tok);
} else {
JobId = str_to_int64(tok);
do_job_delete(ua, JobId);
}
tok = ++sep;
- sep = strchr(tok, ',');
+ sep = strchr(tok, ',');
}
/* pick up the last token */
- if (strchr(tok, '-')) {
+ if (strchr(tok, '-')) {
delete_job_id_range(ua, tok);
} else {
JobId = str_to_int64(tok);
}
Dmsg2(120, "Found storage, MediaType=%s DevName=%s\n",
- store->media_type, store->dev_name);
+ store->media_type, store->dev_name());
set_storage(jcr, store);
if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
return;
}
sd = jcr->store_bsock;
- bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+ bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
bash_spaces(dev_name);
bnet_fsend(sd, "%s %s", command, dev_name);
while (bnet_recv(sd) >= 0) {
ua->catalog = (CAT *)GetNextRes(R_CATALOG, NULL);
UnlockRes();
if (!ua->catalog) {
- bsendmsg(ua, _("Could not find a Catalog resource\n"));
+ bsendmsg(ua, _("Could not find a Catalog resource\n"));
return 0;
} else {
- bsendmsg(ua, _("Using default Catalog name=%s DB=%s\n"),
+ bsendmsg(ua, _("Using default Catalog name=%s DB=%s\n"),
ua->catalog->hdr.name, ua->catalog->db_name);
}
}
bsendmsg(ua, _("Could not open database \"%s\".\n"),
ua->catalog->db_name);
if (ua->db) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
close_db(ua);
return 0;
stat = 1;
- Dmsg1(400, "Dot command: %s\n", ua->UA_sock->msg);
+ Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
if (ua->argc == 0) {
return 1;
}
job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
if (job) {
STORE *store;
- bsendmsg(ua, "job=%s", job->hdr.name);
- bsendmsg(ua, "pool=%s", job->pool->hdr.name);
- bsendmsg(ua, "messages=%s", job->messages->hdr.name);
- bsendmsg(ua, "client=%s", job->client->hdr.name);
- store = (STORE *)job->storage[0]->first();
- bsendmsg(ua, "storage=%s", store->hdr.name);
- bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
- bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
- bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
- bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
+ bsendmsg(ua, "job=%s", job->hdr.name);
+ bsendmsg(ua, "pool=%s", job->pool->hdr.name);
+ bsendmsg(ua, "messages=%s", job->messages->hdr.name);
+ bsendmsg(ua, "client=%s", job->client->hdr.name);
+ store = (STORE *)job->storage->first();
+ bsendmsg(ua, "storage=%s", store->hdr.name);
+ bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
+ bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
+ bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
+ bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
}
}
return 1;
strip_trailing_junk(ua->argv[i]);
for (p=ua->argv[i]; p && *p; p=e) {
/* Check for list */
- e = strchr(p, ',');
+ e = strchr(p, ',');
if (e) {
*e++ = 0;
}
/* Check for range */
- h = strchr(p, '-'); /* range? */
+ h = strchr(p, '-'); /* range? */
if (h == p) {
- msg = _("Negative numbers not permitted\n");
+ msg = _("Negative numbers not permitted\n");
goto bail_out;
}
if (h) {
*h++ = 0;
if (!is_an_integer(h)) {
- msg = _("Range end is not integer.\n");
+ msg = _("Range end is not integer.\n");
goto bail_out;
}
skip_spaces(&p);
if (!is_an_integer(p)) {
- msg = _("Range start is not an integer.\n");
+ msg = _("Range start is not an integer.\n");
goto bail_out;
}
beg = atoi(p);
end = atoi(h);
if (end < beg) {
- msg = _("Range end not bigger than start.\n");
+ msg = _("Range end not bigger than start.\n");
goto bail_out;
}
} else {
skip_spaces(&p);
if (!is_an_integer(p)) {
- msg = _("Input value is not an integer.\n");
+ msg = _("Input value is not an integer.\n");
goto bail_out;
}
beg = end = atoi(p);
}
if (beg <= 0 || end <= 0) {
- msg = _("Values must be be greater than zero.\n");
+ msg = _("Values must be be greater than zero.\n");
goto bail_out;
}
if (end >= num_slots) {
- msg = _("Slot too large.\n");
+ msg = _("Slot too large.\n");
goto bail_out;
}
for (i=beg; i<=end; i++) {
printf("Slots turned on:\n");
for (i=1; i<num_slots; i++) {
if (slot_list[i]) {
- printf("%d\n", i);
+ printf("%d\n", i);
}
}
#endif
/* Walk through the list updating the media records */
for (vl=vol_list; vl; vl=vl->next) {
if (vl->Slot >= max_slots) {
- bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"));
+ bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"));
continue;
}
/* Check if user wants us to look at this slot */
if (!slot_list[vl->Slot]) {
- Dmsg1(100, "Skipping slot=%d\n", vl->Slot);
+ Dmsg1(100, "Skipping slot=%d\n", vl->Slot);
continue;
}
/* If scanning, we read the label rather than the barcode */
vl->VolName = NULL;
}
vl->VolName = get_volume_name_from_SD(ua, vl->Slot);
- Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
+ Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
}
slot_list[vl->Slot] = 0; /* clear Slot */
if (!vl->VolName) {
- Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
+ Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot);
memset(&mr, 0, sizeof(mr));
mr.Slot = vl->Slot;
mr.InChanger = 1;
db_lock(ua->db);
db_make_inchanger_unique(ua->jcr, ua->db, &mr);
db_unlock(ua->db);
- bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
+ bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot);
continue;
}
memset(&mr, 0, sizeof(mr));
mr.Slot = vl->Slot;
mr.InChanger = 1;
if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
} else {
bsendmsg(ua, _(
- "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
+ "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
mr.VolumeName, mr.Slot);
}
} else {
- bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
+ bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
mr.VolumeName);
}
db_unlock(ua->db);
continue;
} else {
- bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"),
+ bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"),
mr.VolumeName);
}
db_unlock(ua->db);
if (db_get_media_record(ua->jcr, ua->db, &omr)) {
goto checkVol;
}
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
/* No keyword or Vol not found, ask user to select */
if (!select_media_dbr(ua, &omr)) {
/* Require Volume to be Purged or Recycled */
checkVol:
if (strcmp(omr.VolStatus, "Purged") != 0 && strcmp(omr.VolStatus, "Recycle") != 0) {
- bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"),
+ bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"),
omr.VolumeName, omr.VolStatus);
return 1;
}
/* If VolBytes are zero the Volume is not labeled */
if (db_get_media_record(ua->jcr, ua->db, &mr)) {
if (mr.VolBytes != 0) {
- bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"),
+ bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"),
mr.VolumeName);
continue;
}
if (relabel) {
/* Delete the old media record */
if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
- bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
+ bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
omr.VolumeName, db_strerror(ua->db));
} else {
- bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"),
+ bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"),
omr.VolumeName);
/* Update the number of Volumes in the pool */
pr.NumVols--;
if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
}
}
if (ua->automount) {
- bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
- bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
+ bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
+ bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
bash_spaces(dev_name);
- bnet_fsend(sd, "mount %s", dev_name);
+ bnet_fsend(sd, "mount %s", dev_name);
unbash_spaces(dev_name);
while (bnet_recv(sd) >= 0) {
- bsendmsg(ua, "%s", sd->msg);
+ bsendmsg(ua, "%s", sd->msg);
/* Here we can get
* 3001 OK mount. Device=xxx or
* 3001 Mounted Volume vvvv
* 3906 is cannot mount non-tape
* So for those, no need to print a reminder
*/
- if (strncmp(sd->msg, "3001 ", 5) == 0 ||
- strncmp(sd->msg, "3906 ", 5) == 0) {
+ if (strncmp(sd->msg, "3001 ", 5) == 0 ||
+ strncmp(sd->msg, "3906 ", 5) == 0) {
print_reminder = false;
}
}
/* Display list of Volumes and ask if he really wants to proceed */
bsendmsg(ua, _("The following Volumes will be labeled:\n"
- "Slot Volume\n"
- "==============\n"));
+ "Slot Volume\n"
+ "==============\n"));
for (vl=vol_list; vl; vl=vl->next) {
if (!vl->VolName || !slot_list[vl->Slot]) {
continue;
media_record_exists = false;
if (db_get_media_record(ua->jcr, ua->db, &mr)) {
if (mr.VolBytes != 0) {
- bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"),
+ bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"),
vl->Slot, mr.VolumeName);
if (!mr.InChanger) {
mr.InChanger = 1;
if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, "Error setting InChanger: ERR=%s", db_strerror(ua->db));
+ bsendmsg(ua, "Error setting InChanger: ERR=%s", db_strerror(ua->db));
}
}
continue;
if (media_record_exists) { /* we update it */
mr.VolBytes = 1;
if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
} else { /* create the media record */
set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
if (db_create_media_record(ua->jcr, ua->db, &mr)) {
- bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
+ bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
mr.VolumeName);
pr.NumVols++; /* this is a bit suspect */
if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
} else {
- bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
+ bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
}
}
continue; /* done, go handle next volume */
continue;
}
if (ua) {
- bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p);
+ bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p);
}
return 0;
}
len = strlen(name);
if (len >= MAX_NAME_LENGTH) {
if (ua) {
- bsendmsg(ua, _("Volume name too long.\n"));
+ bsendmsg(ua, _("Volume name too long.\n"));
}
return 0;
}
if (len == 0) {
if (ua) {
- bsendmsg(ua, _("Volume name must be at least one character long.\n"));
+ bsendmsg(ua, _("Volume name must be at least one character long.\n"));
}
return 0;
}
if (!(sd=open_sd_bsock(ua))) {
return false;
}
- bstrncpy(dev_name, ua->jcr->store->dev_name, sizeof(dev_name));
+ bstrncpy(dev_name, ua->jcr->store->dev_name(), sizeof(dev_name));
bash_spaces(dev_name);
bash_spaces(mr->VolumeName);
bash_spaces(mr->MediaType);
mr->VolBytes = 1;
mr->InChanger = 1;
if (!db_update_media_record(ua->jcr, ua->db, mr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
ok = false;
}
} else { /* create the media record */
mr->VolBytes = 1; /* flag indicating Volume labeled */
mr->InChanger = 1;
if (db_create_media_record(ua->jcr, ua->db, mr)) {
- bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d successfully created.\n"),
+ bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d successfully created.\n"),
mr->VolumeName, mr->Slot);
/* Update number of volumes in pool */
pr->NumVols++;
if (!db_update_pool_record(ua->jcr, ua->db, pr)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
} else {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
ok = false;
}
}
bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"),
store->hdr.name, store->address, store->SDport);
if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
- bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
+ bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
return NULL;
}
}
bsendmsg(ua, _("Could not open SD socket.\n"));
return NULL;
}
- bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+ bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
bash_spaces(dev_name);
/* Ask for autochanger list of volumes */
bnet_fsend(sd, _("readlabel %s Slot=%d\n"), dev_name, Slot);
Dmsg1(100, "Got: %s", sd->msg);
if (strncmp(sd->msg, "3001 Volume=", 12) == 0) {
VolName = (char *)malloc(sd->msglen);
- if (sscanf(sd->msg, "3001 Volume=%s Slot=%d", VolName, &rtn_slot) == 2) {
+ if (sscanf(sd->msg, "3001 Volume=%s Slot=%d", VolName, &rtn_slot) == 2) {
break;
}
free(VolName);
return NULL;
}
- bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
+ bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
bash_spaces(dev_name);
/* Ask for autochanger list of volumes */
bnet_fsend(sd, _("autochanger list %s \n"), dev_name);
/* Check for returned SD messages */
if (sd->msg[0] == '3' && B_ISDIGIT(sd->msg[1]) &&
B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) &&
- sd->msg[4] == ' ') {
- bsendmsg(ua, "%s\n", sd->msg); /* pass them on to user */
+ sd->msg[4] == ' ') {
+ bsendmsg(ua, "%s\n", sd->msg); /* pass them on to user */
continue;
}
Slot = atoi(sd->msg);
if (Slot <= 0) {
p--;
- *p = ':';
- bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
+ *p = ':';
+ bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
continue;
}
} else {
*p++ = 0;
if (!is_an_integer(sd->msg) || (Slot=atoi(sd->msg)) <= 0) {
p--;
- *p = ':';
- bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
+ *p = ':';
+ bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg);
continue;
}
} else {
}
if (!is_volume_name_legal(ua, p)) {
p--;
- *p = ':';
- bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg);
+ *p = ':';
+ bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg);
continue;
}
}
vl = (vol_list_t *)malloc(sizeof(vol_list_t));
vl->Slot = Slot;
if (p) {
- if (*p == ':') {
+ if (*p == ':') {
p++; /* skip separator */
}
vl->VolName = bstrdup(p);
{N_("directors"), R_DIRECTOR},
{N_("clients"), R_CLIENT},
{N_("counters"), R_COUNTER},
+ {N_("devices"), R_DEVICE},
{N_("jobs"), R_JOB},
{N_("storages"), R_STORAGE},
{N_("catalogs"), R_CATALOG},
type = reses[j].type;
if (type > 0) {
res = res_head[type-r_first];
-// res = resources[type-r_first].res_head;
} else {
res = NULL;
}
case -1: /* all */
for (j=r_first; j<=r_last; j++) {
dump_resource(j, res_head[j-r_first], bsendmsg, ua);
-// dump_resource(j, resources[j-r_first].res_head, bsendmsg, ua);
}
break;
case -2:
- bsendmsg(ua, _("Keywords for the show command are:\n"));
+ bsendmsg(ua, _("Keywords for the show command are:\n"));
for (j=0; reses[j].res_name; j++) {
- bsendmsg(ua, "%s\n", _(reses[j].res_name));
+ bsendmsg(ua, "%s\n", _(reses[j].res_name));
}
goto bail_out;
case -3:
- bsendmsg(ua, _("%s resource %s not found.\n"), res_name, ua->argv[i]);
+ bsendmsg(ua, _("%s resource %s not found.\n"), res_name, ua->argv[i]);
goto bail_out;
case 0:
- bsendmsg(ua, _("Resource %s not found\n"), res_name);
+ bsendmsg(ua, _("Resource %s not found\n"), res_name);
goto bail_out;
default:
dump_resource(recurse?type:-type, res, bsendmsg, ua);
/* List JOBID */
} else if (strcasecmp(ua->argk[i], _("jobid")) == 0) {
if (ua->argv[i]) {
- jobid = atoi(ua->argv[i]);
+ jobid = str_to_int64(ua->argv[i]);
if (jobid > 0) {
jr.JobId = jobid;
db_list_job_records(ua->jcr, ua->db, &jr, prtit, ua, llist);
} else if (strcasecmp(ua->argk[i], _("files")) == 0) {
for (j=i+1; j<ua->argc; j++) {
- if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
+ if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
jr.JobId = 0;
db_get_job_record(ua->jcr, ua->db, &jr);
jobid = jr.JobId;
- } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
- jobid = atoi(ua->argv[j]);
+ } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
+ jobid = str_to_int64(ua->argv[j]);
} else {
continue;
}
} else if (strcasecmp(ua->argk[i], _("jobmedia")) == 0) {
int done = FALSE;
for (j=i+1; j<ua->argc; j++) {
- if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
+ if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
jr.JobId = 0;
db_get_job_record(ua->jcr, ua->db, &jr);
jobid = jr.JobId;
- } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
- jobid = atoi(ua->argv[j]);
+ } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
+ jobid = str_to_int64(ua->argv[j]);
} else {
continue;
}
/* List MEDIA or VOLUMES */
} else if (strcasecmp(ua->argk[i], _("media")) == 0 ||
- strcasecmp(ua->argk[i], _("volumes")) == 0) {
+ strcasecmp(ua->argk[i], _("volumes")) == 0) {
bool done = false;
for (j=i+1; j<ua->argc; j++) {
- if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
+ if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
jr.JobId = 0;
db_get_job_record(ua->jcr, ua->db, &jr);
jobid = jr.JobId;
- } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
- jobid = atoi(ua->argv[j]);
+ } else if (strcasecmp(ua->argk[j], _("jobid")) == 0 && ua->argv[j]) {
+ jobid = str_to_int64(ua->argv[j]);
} else {
continue;
}
VolumeName = get_pool_memory(PM_FNAME);
n = db_get_job_volume_names(ua->jcr, ua->db, jobid, &VolumeName);
- bsendmsg(ua, _("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
+ bsendmsg(ua, _("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
free_pool_memory(VolumeName);
done = true;
}
uint32_t *ids;
/* Is a specific pool wanted? */
for (i=1; i<ua->argc; i++) {
- if (strcasecmp(ua->argk[i], _("pool")) == 0) {
+ if (strcasecmp(ua->argk[i], _("pool")) == 0) {
if (!get_pool_dbr(ua, &pr)) {
- bsendmsg(ua, _("No Pool specified.\n"));
+ bsendmsg(ua, _("No Pool specified.\n"));
return 1;
}
mr.PoolId = pr.PoolId;
}
/* List Volumes in all pools */
if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
- bsendmsg(ua, _("Error obtaining pool ids. ERR=%s\n"),
+ bsendmsg(ua, _("Error obtaining pool ids. ERR=%s\n"),
db_strerror(ua->db));
return 1;
}
for (i=0; i < num_pools; i++) {
pr.PoolId = ids[i];
if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
- bsendmsg(ua, _("Pool: %s\n"), pr.Name);
+ bsendmsg(ua, _("Pool: %s\n"), pr.Name);
}
mr.PoolId = ids[i];
db_list_media_records(ua->jcr, ua->db, &mr, prtit, ua, llist);
/* List a specific volume */
} else if (strcasecmp(ua->argk[i], _("volume")) == 0) {
if (!ua->argv[i]) {
- bsendmsg(ua, _("No Volume Name specified.\n"));
+ bsendmsg(ua, _("No Volume Name specified.\n"));
return 1;
}
bstrncpy(mr.VolumeName, ua->argv[i], sizeof(mr.VolumeName));
return 1;
/* List next volume */
} else if (strcasecmp(ua->argk[i], _("nextvol")) == 0 ||
- strcasecmp(ua->argk[i], _("nextvolume")) == 0) {
+ strcasecmp(ua->argk[i], _("nextvolume")) == 0) {
list_nextvol(ua);
} else {
- bsendmsg(ua, _("Unknown list keyword: %s\n"), NPRT(ua->argk[i]));
+ bsendmsg(ua, _("Unknown list keyword: %s\n"), NPRT(ua->argk[i]));
}
}
return 1;
} else {
job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
if (!job) {
- Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
+ Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
if ((job = select_job_resource(ua)) == NULL) {
return false;
}
}
if (!find_next_volume_for_append(jcr, &mr, 0)) {
- bsendmsg(ua, _("Could not find next Volume.\n"));
+ bsendmsg(ua, _("Could not find next Volume.\n"));
} else {
- bsendmsg(ua, _("The next Volume to be used by Job \"%s\" will be %s\n"),
+ bsendmsg(ua, _("The next Volume to be used by Job \"%s\" will be %s\n"),
job->hdr.name, mr.VolumeName);
found = true;
}
if (tod) { /* Jobs scheduled today (next 24 hours) */
#ifdef xxx
char buf[300], num[10];
- bsnprintf(buf, sizeof(buf), "tm.hour=%d hour=", tm.tm_hour);
+ bsnprintf(buf, sizeof(buf), "tm.hour=%d hour=", tm.tm_hour);
for (i=0; i<24; i++) {
if (bit_is_set(i, run->hour)) {
- bsnprintf(num, sizeof(num), "%d ", i);
+ bsnprintf(num, sizeof(num), "%d ", i);
bstrncat(buf, num, sizeof(buf));
}
}
- bstrncat(buf, "\n", sizeof(buf));
- Dmsg1(000, "%s", buf);
+ bstrncat(buf, "\n", sizeof(buf));
+ Dmsg1(000, "%s", buf);
#endif
/* find time (time_t) job is to be run */
localtime_r(&now, &tm);
tm.tm_min = run->minute;
tm.tm_sec = 0;
runtime = mktime(&tm);
- Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
+ Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
if (runtime > now) {
- Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
+ Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
return run; /* found it, return run resource */
}
}
tm.tm_min = run->minute;
tm.tm_sec = 0;
runtime = mktime(&tm);
- Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
+ Dmsg2(200, "now=%d runtime=%d\n", now, runtime);
if (runtime < tomorrow) {
- Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
+ Dmsg2(200, "Found it level=%d %c\n", run->level, run->level);
return run; /* found it, return run resource */
}
}
Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
jcr->catalog->db_name);
if (jcr->db) {
- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+ Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
}
return 0;
}
while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
/* Try to create the pool */
if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
- Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
+ Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name,
db_strerror(jcr->db));
if (jcr->db) {
db_close_database(jcr, jcr->db);
}
return 0;
} else {
- Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
+ Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name);
}
}
jcr->PoolId = pr.PoolId;
len = strlen(line);
if (line[0] == '*') { /* prompt */
if (nprompt >= 9) {
- bsendmsg(ua, _("Too many prompts in query, max is 9.\n"));
+ bsendmsg(ua, _("Too many prompts in query, max is 9.\n"));
} else {
- line[len++] = ' ';
+ line[len++] = ' ';
line[len] = 0;
prompt[nprompt++] = bstrdup(line+1);
continue;
}
}
if (*query != 0) {
- pm_strcat(query, " ");
+ pm_strcat(query, " ");
}
pm_strcat(query, line);
if (line[len-1] != ';') {
line[len-1] = 0; /* zap ; */
if (query[0] != 0) {
query = substitute_prompts(ua, query, prompt, nprompt);
- Dmsg1(100, "Query2=%s\n", query);
- if (query[0] == '!') {
+ Dmsg1(100, "Query2=%s\n", query);
+ if (query[0] == '!') {
db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
} else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
- bsendmsg(ua, "%s\n", query);
+ bsendmsg(ua, "%s\n", query);
}
query[0] = 0;
}
if (query[0] != 0) {
query = substitute_prompts(ua, query, prompt, nprompt);
Dmsg1(100, "Query2=%s\n", query);
- if (query[0] == '!') {
+ if (query[0] == '!') {
db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
} else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
- bsendmsg(ua, "%s\n", query);
+ bsendmsg(ua, "%s\n", query);
}
}
}
p++;
switch (*p) {
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- n = (int)(*p) - (int)'1';
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ n = (int)(*p) - (int)'1';
if (prompt[n]) {
if (!subst[n]) {
if (!get_cmd(ua, prompt[n])) {
*o++ = *p++;
}
} else {
- bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
+ bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
}
q += 2;
break;
- case '%':
- *o++ = '%';
+ case '%':
+ *o++ = '%';
q += 2;
break;
default:
- *o++ = '%';
+ *o++ = '%';
q++;
break;
}
}
query = check_pool_memory_size(query, len + 1);
if (*query != 0) {
- strcat(query, " ");
+ pm_strcat(query, " ");
}
- strcat(query, ua->cmd);
+ pm_strcat(query, ua->cmd);
if (ua->cmd[len-1] == ';') {
ua->cmd[len-1] = 0; /* zap ; */
/* Submit query */
db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
*query = 0; /* start new query */
- msg = _("Enter SQL query: ");
+ msg = _("Enter SQL query: ");
} else {
- msg = _("Add to SQL query: ");
+ msg = _("Add to SQL query: ");
}
}
free_pool_memory(query);
*/
/*
- Copyright (C) 2002-2004 Kern Sibbald and John Walker
+ Copyright (C) 2002-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
UnlockRes();
if (!rx.restore_jobs) {
bsendmsg(ua, _(
- "No Restore Job Resource found. You must create at least\n"
- "one before running this command.\n"));
+ "No Restore Job Resource found. You must create at least\n"
+ "one before running this command.\n"));
goto bail_out;
}
goto bail_out;
case 1: /* select by jobid */
if (!build_directory_tree(ua, &rx)) {
- bsendmsg(ua, _("Restore not done.\n"));
+ bsendmsg(ua, _("Restore not done.\n"));
goto bail_out;
}
break;
if (rx.bsr->JobId) {
if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */
- bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n"));
+ bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n"));
goto bail_out;
}
if (!write_bsr_file(ua, rx.bsr)) {
goto bail_out;
}
bsendmsg(ua, _("\n%u file%s selected to be restored.\n\n"), rx.selected_files,
- rx.selected_files==1?"":"s");
+ rx.selected_files==1?"":"s");
} else {
bsendmsg(ua, _("No files selected to be restored.\n"));
goto bail_out;
/* Build run command */
if (rx.where) {
Mmsg(ua->cmd,
- "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
- " where=\"%s\" files=%d catalog=\"%s\"",
- job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
+ "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
+ " where=\"%s\" files=%d catalog=\"%s\"",
+ job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
working_directory, rx.where, rx.selected_files, ua->catalog->hdr.name);
} else {
Mmsg(ua->cmd,
- "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
- " files=%d catalog=\"%s\"",
- job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
+ "run job=\"%s\" client=\"%s\" storage=\"%s\" bootstrap=\"%s/restore.bsr\""
+ " files=%d catalog=\"%s\"",
+ job->hdr.name, rx.ClientName, rx.store?rx.store->hdr.name:"",
working_directory, rx.selected_files, ua->catalog->hdr.name);
}
if (find_arg(ua, _("yes")) > 0) {
}
}
if (!found_kw) {
- bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]);
+ bsendmsg(ua, _("Unknown keyword: %s\n"), ua->argk[i]);
return 0;
}
/* Found keyword in kw[] list, process it */
switch (j) {
case 0: /* jobid */
if (*rx->JobIds != 0) {
- pm_strcat(rx->JobIds, ",");
+ pm_strcat(rx->JobIds, ",");
}
pm_strcat(rx->JobIds, ua->argv[i]);
done = true;
break;
case 2: /* before */
if (str_to_utime(ua->argv[i]) == 0) {
- bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
+ bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
return 0;
}
bstrncpy(date, ua->argv[i], sizeof(date));
case 5: /* pool specified */
rx->pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
if (!rx->pool) {
- bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]);
+ bsendmsg(ua, _("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]);
return 0;
}
if (!acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
rx->pool = NULL;
- bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]);
+ bsendmsg(ua, _("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]);
return 0;
}
break;
if (!done) {
bsendmsg(ua, _("\nFirst you select one or more JobIds that contain files\n"
- "to be restored. You will be presented several methods\n"
- "of specifying the JobIds. Then you will be allowed to\n"
- "select which files from those JobIds are to be restored.\n\n"));
+ "to be restored. You will be presented several methods\n"
+ "of specifying the JobIds. Then you will be allowed to\n"
+ "select which files from those JobIds are to be restored.\n\n"));
}
/* If choice not already made above, prompt */
done = false;
break;
case 1: /* list where a file is saved */
- if (!get_cmd(ua, _("Enter Filename (no path):"))) {
+ if (!get_cmd(ua, _("Enter Filename (no path):"))) {
return 0;
}
len = strlen(ua->cmd);
done = false;
break;
case 2: /* enter a list of JobIds */
- if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
+ if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
return 0;
}
pm_strcpy(rx->JobIds, ua->cmd);
break;
case 3: /* Enter an SQL list command */
- if (!get_cmd(ua, _("Enter SQL list command: "))) {
+ if (!get_cmd(ua, _("Enter SQL list command: "))) {
return 0;
}
gui_save = ua->jcr->gui;
if (!get_client_name(ua, rx)) {
return 0;
}
- bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
- "containg a list of file names with paths, and terminate\n"
- "them with a blank line.\n"));
+ bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
+ "containg a list of file names with paths, and terminate\n"
+ "them with a blank line.\n"));
for ( ;; ) {
- if (!get_cmd(ua, _("Enter full filename: "))) {
+ if (!get_cmd(ua, _("Enter full filename: "))) {
return 0;
}
len = strlen(ua->cmd);
if (!get_client_name(ua, rx)) {
return 0;
}
- bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
- "containg a list of file names with paths, and terminate\n"
- "them with a blank line.\n"));
+ bsendmsg(ua, _("Enter file names with paths, or < to enter a filename\n"
+ "containg a list of file names with paths, and terminate\n"
+ "them with a blank line.\n"));
for ( ;; ) {
- if (!get_cmd(ua, _("Enter full filename: "))) {
+ if (!get_cmd(ua, _("Enter full filename: "))) {
return 0;
}
len = strlen(ua->cmd);
for (p=rx->JobIds; ; ) {
int stat = get_next_jobid_from_list(&p, &JobId);
if (stat < 0) {
- bsendmsg(ua, _("Invalid JobId in list.\n"));
+ bsendmsg(ua, _("Invalid JobId in list.\n"));
return 0;
}
if (stat == 0) {
}
jr.JobId = JobId;
if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
- bsendmsg(ua, _("Unable to get Job record for JobId=%u: ERR=%s\n"),
+ bsendmsg(ua, _("Unable to get Job record for JobId=%u: ERR=%s\n"),
JobId, db_strerror(ua->db));
return 0;
}
if (!acl_access_ok(ua, Job_ACL, jr.Name)) {
- bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"),
+ bsendmsg(ua, _("No authorization. Job \"%s\" not selected.\n"),
jr.Name);
continue;
}
static int get_date(UAContext *ua, char *date, int date_len)
{
bsendmsg(ua, _("The restored files will the most current backup\n"
- "BEFORE the date you specify below.\n\n"));
+ "BEFORE the date you specify below.\n\n"));
for ( ;; ) {
if (!get_cmd(ua, _("Enter date as YYYY-MM-DD HH:MM:SS :"))) {
return 0;
case '<':
p++;
if ((ffd = fopen(p, "r")) == NULL) {
- bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"),
- p, strerror(errno));
+ berrno be;
+ bsendmsg(ua, _("Cannot open file %s: ERR=%s\n"),
+ p, be.strerror());
break;
}
while (fgets(file, sizeof(file), ffd)) {
line++;
if (!insert_file_into_findex_list(ua, rx, file, date)) {
- bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p);
+ bsendmsg(ua, _("Error occurred on line %d of %s\n"), line, p);
}
}
fclose(ffd);
/* Use first JobId as estimate of the number of files to restore */
Mmsg(rx->query, uar_count_files, JobId);
if (!db_sql_query(ua->db, rx->query, count_handler, (void *)rx)) {
- bsendmsg(ua, "%s\n", db_strerror(ua->db));
+ bsendmsg(ua, "%s\n", db_strerror(ua->db));
}
if (rx->found) {
/* Add about 25% more than this job for over estimate */
*/
Mmsg(rx->query, uar_sel_files, JobId);
if (!db_sql_query(ua->db, rx->query, insert_tree_handler, (void *)&tree)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
/*
* Find the MediaTypes for this JobId and add to the name_list
*/
Mmsg(rx->query, uar_mediatype, JobId);
if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
+ bsendmsg(ua, "%s", db_strerror(ua->db));
}
}
char ec1[50];
*/
if (OK) {
for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) {
- Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node);
+ Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node);
if (node->extract || node->extract_dir) {
- Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex);
+ Dmsg2(400, "type=%d FI=%d\n", node->type, node->FileIndex);
add_findex(rx->bsr, node->JobId, node->FileIndex);
if (node->extract && node->type != TN_NEWDIR) {
rx->selected_files++; /* count only saved files */
if (i >= 0) {
bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet));
if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
- bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
+ bsendmsg(ua, _("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
db_strerror(ua->db));
i = -1;
}
Mmsg(rx->query, uar_sel_fileset, cr.ClientId, cr.ClientId);
start_prompt(ua, _("The defined FileSet resources are:\n"));
if (!db_sql_query(ua->db, rx->query, fileset_handler, (void *)ua)) {
- bsendmsg(ua, "%s\n", db_strerror(ua->db));
+ bsendmsg(ua, "%s\n", db_strerror(ua->db));
}
if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"),
fileset_name, sizeof(fileset_name)) < 0) {
bstrncpy(fsr.FileSet, fileset_name, sizeof(fsr.FileSet));
if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
- bsendmsg(ua, _("Error getting FileSet record: %s\n"), db_strerror(ua->db));
- bsendmsg(ua, _("This probably means you modified the FileSet.\n"
- "Continuing anyway.\n"));
+ bsendmsg(ua, _("Error getting FileSet record: %s\n"), db_strerror(ua->db));
+ bsendmsg(ua, _("This probably means you modified the FileSet.\n"
+ "Continuing anyway.\n"));
}
}
memset(&pr, 0, sizeof(pr));
bstrncpy(pr.Name, rx->pool->hdr.name, sizeof(pr.Name));
if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
- bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%u ", pr.PoolId);
+ bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%u ", pr.PoolId);
} else {
- bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name);
+ bsendmsg(ua, _("Pool \"%s\" not found, using any pool.\n"), pr.Name);
}
}
return 0;
}
*p = q;
- *JobId = strtoul(jobid, NULL, 10);
+ *JobId = str_to_int64(jobid);
return 1;
}
static int count_handler(void *ctx, int num_fields, char **row)
{
RESTORE_CTX *rx = (RESTORE_CTX *)ctx;
- rx->JobId = atoi(row[0]);
+ rx->JobId = str_to_int64(row[0]);
rx->found = true;
return 0;
}
static int jobid_fileindex_handler(void *ctx, int num_fields, char **row)
{
RESTORE_CTX *rx = (RESTORE_CTX *)ctx;
- rx->JobId = atoi(row[0]);
- add_findex(rx->bsr, rx->JobId, atoi(row[1]));
+ rx->JobId = str_to_int64(row[0]);
+ add_findex(rx->bsr, rx->JobId, str_to_int64(row[1]));
rx->found = true;
return 0;
}
if (name_list->num_ids > 1) {
bsendmsg(ua, _("Warning, the JobIds that you selected refer to more than one MediaType.\n"
- "Restore is not possible. The MediaTypes used are:\n"));
+ "Restore is not possible. The MediaTypes used are:\n"));
print_name_list(ua, name_list);
rx->store = select_storage_resource(ua);
return;
}
}
if (store && (store != rx->store)) {
- bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"),
+ bsendmsg(ua, _("Warning default storage overridden by %s on command line.\n"),
store->hdr.name);
rx->store = store;
}
if (!rx->store) {
bsendmsg(ua, _("\nWarning. Unable to find Storage resource for\n"
- "MediaType \"%s\", needed by the Jobs you selected.\n"
- "You will be allowed to select a Storage device later.\n"),
+ "MediaType \"%s\", needed by the Jobs you selected.\n"
+ "You will be allowed to select a Storage device later.\n"),
name_list->name[0]);
}
}
break;
case 1: /* JobId */
if (jid) {
- bsendmsg(ua, _("JobId specified twice.\n"));
+ bsendmsg(ua, _("JobId specified twice.\n"));
return 0;
}
jid = ua->argv[i];
case 2: /* client */
case 3: /* fd */
if (client_name) {
- bsendmsg(ua, _("Client specified twice.\n"));
+ bsendmsg(ua, _("Client specified twice.\n"));
return 0;
}
client_name = ua->argv[i];
break;
case 4: /* fileset */
if (fileset_name) {
- bsendmsg(ua, _("FileSet specified twice.\n"));
+ bsendmsg(ua, _("FileSet specified twice.\n"));
return 0;
}
fileset_name = ua->argv[i];
break;
case 5: /* level */
if (level_name) {
- bsendmsg(ua, _("Level specified twice.\n"));
+ bsendmsg(ua, _("Level specified twice.\n"));
return 0;
}
level_name = ua->argv[i];
case 6: /* storage */
case 7: /* sd */
if (store_name) {
- bsendmsg(ua, _("Storage specified twice.\n"));
+ bsendmsg(ua, _("Storage specified twice.\n"));
return 0;
}
store_name = ua->argv[i];
break;
case 8: /* pool */
if (pool_name) {
- bsendmsg(ua, _("Pool specified twice.\n"));
+ bsendmsg(ua, _("Pool specified twice.\n"));
return 0;
}
pool_name = ua->argv[i];
break;
case 9: /* where */
if (where) {
- bsendmsg(ua, _("Where specified twice.\n"));
+ bsendmsg(ua, _("Where specified twice.\n"));
return 0;
}
where = ua->argv[i];
break;
case 10: /* bootstrap */
if (bootstrap) {
- bsendmsg(ua, _("Bootstrap specified twice.\n"));
+ bsendmsg(ua, _("Bootstrap specified twice.\n"));
return 0;
}
bootstrap = ua->argv[i];
break;
case 11: /* replace */
if (replace) {
- bsendmsg(ua, _("Replace specified twice.\n"));
+ bsendmsg(ua, _("Replace specified twice.\n"));
return 0;
}
replace = ua->argv[i];
break;
case 12: /* When */
if (when) {
- bsendmsg(ua, _("When specified twice.\n"));
+ bsendmsg(ua, _("When specified twice.\n"));
return 0;
}
when = ua->argv[i];
break;
case 13: /* Priority */
if (Priority) {
- bsendmsg(ua, _("Priority specified twice.\n"));
+ bsendmsg(ua, _("Priority specified twice.\n"));
return 0;
}
Priority = atoi(ua->argv[i]);
if (Priority <= 0) {
- bsendmsg(ua, _("Priority must be positive nonzero setting it to 10.\n"));
+ bsendmsg(ua, _("Priority must be positive nonzero setting it to 10.\n"));
Priority = 10;
}
kw_ok = true;
break;
case 15: /* Verify Job */
if (verify_job_name) {
- bsendmsg(ua, _("Verify Job specified twice.\n"));
+ bsendmsg(ua, _("Verify Job specified twice.\n"));
return 0;
}
verify_job_name = ua->argv[i];
* End of keyword for loop -- if not found, we got a bogus keyword
*/
if (!kw_ok) {
- Dmsg1(200, "%s not found\n", ua->argk[i]);
+ Dmsg1(800, "%s not found\n", ua->argk[i]);
/*
* Special case for Job Name, it can be the first
* keyword that has no value.
*/
if (!job_name && !ua->argv[i]) {
job_name = ua->argk[i]; /* use keyword as job name */
- Dmsg1(200, "Set jobname=%s\n", job_name);
+ Dmsg1(800, "Set jobname=%s\n", job_name);
} else {
- bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
+ bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
return 0;
}
}
if (catalog_name != NULL) {
catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
if (catalog == NULL) {
- bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name);
+ bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name);
return 0;
}
}
- Dmsg1(200, "Using catalog=%s\n", catalog_name);
+ Dmsg1(800, "Using catalog=%s\n", catalog_name);
if (job_name) {
/* Find Job */
job = (JOB *)GetResWithName(R_JOB, job_name);
if (!job) {
if (*job_name != 0) {
- bsendmsg(ua, _("Job \"%s\" not found\n"), job_name);
+ bsendmsg(ua, _("Job \"%s\" not found\n"), job_name);
}
job = select_job_resource(ua);
} else {
- Dmsg1(200, "Found job=%s\n", job_name);
+ Dmsg1(800, "Found job=%s\n", job_name);
}
} else {
bsendmsg(ua, _("A job name must be specified.\n"));
store = (STORE *)GetResWithName(R_STORAGE, store_name);
if (!store) {
if (*store_name != 0) {
- bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name);
+ bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name);
}
store = select_storage_resource(ua);
}
} else {
- store = (STORE *)job->storage[0]->first(); /* use default */
+ store = (STORE *)job->storage->first(); /* use default */
}
if (!store) {
return 1;
store->hdr.name);
return 0;
}
- Dmsg1(200, "Using storage=%s\n", store->hdr.name);
+ Dmsg1(800, "Using storage=%s\n", store->hdr.name);
if (pool_name) {
pool = (POOL *)GetResWithName(R_POOL, pool_name);
if (!pool) {
if (*pool_name != 0) {
- bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name);
+ bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name);
}
pool = select_pool_resource(ua);
}
pool->hdr.name);
return 0;
}
- Dmsg1(200, "Using pool\n", pool->hdr.name);
+ Dmsg1(800, "Using pool\n", pool->hdr.name);
if (client_name) {
client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
if (!client) {
if (*client_name != 0) {
- bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name);
+ bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name);
}
client = select_client_resource(ua);
}
client->hdr.name);
return 0;
}
- Dmsg1(200, "Using client=%s\n", client->hdr.name);
+ Dmsg1(800, "Using client=%s\n", client->hdr.name);
if (fileset_name) {
fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
if (!fileset) {
- bsendmsg(ua, _("FileSet \"%s\" not found.\n"), fileset_name);
+ bsendmsg(ua, _("FileSet \"%s\" not found.\n"), fileset_name);
fileset = select_fileset_resource(ua);
}
} else {
if (verify_job_name) {
verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name);
if (!verify_job) {
- bsendmsg(ua, _("Verify Job \"%s\" not found.\n"), verify_job_name);
+ bsendmsg(ua, _("Verify Job \"%s\" not found.\n"), verify_job_name);
verify_job = select_job_resource(ua);
}
} else {
if (when) {
jcr->sched_time = str_to_utime(when);
if (jcr->sched_time == 0) {
- bsendmsg(ua, _("Invalid time, using current time.\n"));
+ bsendmsg(ua, _("Invalid time, using current time.\n"));
jcr->sched_time = time(NULL);
}
}
}
}
if (!jcr->replace) {
- bsendmsg(ua, _("Invalid replace option: %s\n"), replace);
+ bsendmsg(ua, _("Invalid replace option: %s\n"), replace);
goto bail_out;
}
} else if (job->replace) {
}
if (level_name) {
if (!get_level_from_name(jcr, level_name)) {
- bsendmsg(ua, _("Level %s not valid.\n"), level_name);
+ bsendmsg(ua, _("Level %s not valid.\n"), level_name);
goto bail_out;
}
}
* Prompt User to see if all run job parameters are correct, and
* allow him to modify them.
*/
- Dmsg1(20, "JobType=%c\n", jcr->JobType);
+ Dmsg1(800, "JobType=%c\n", jcr->JobType);
switch (jcr->JobType) {
char ec1[30];
char dt[MAX_TIME_LENGTH];
case JT_ADMIN:
- bsendmsg(ua, _("Run %s job\n"
+ bsendmsg(ua, _("Run %s job\n"
"JobName: %s\n"
"FileSet: %s\n"
"Client: %s\n"
"Storage: %s\n"
"When: %s\n"
"Priority: %d\n"),
- _("Admin"),
+ _("Admin"),
job->hdr.name,
jcr->fileset->hdr.name,
NPRT(jcr->client->hdr.name),
case JT_BACKUP:
case JT_VERIFY:
if (jcr->JobType == JT_BACKUP) {
- bsendmsg(ua, _("Run %s job\n"
+ bsendmsg(ua, _("Run %s job\n"
"JobName: %s\n"
"FileSet: %s\n"
"Level: %s\n"
"Pool: %s\n"
"When: %s\n"
"Priority: %d\n"),
- _("Backup"),
+ _("Backup"),
job->hdr.name,
jcr->fileset->hdr.name,
level_to_str(jcr->JobLevel),
if (jcr->verify_job) {
Name = jcr->verify_job->hdr.name;
} else {
- Name = "";
+ Name = "";
}
- bsendmsg(ua, _("Run %s job\n"
+ bsendmsg(ua, _("Run %s job\n"
"JobName: %s\n"
"FileSet: %s\n"
"Level: %s\n"
"Verify Job: %s\n"
"When: %s\n"
"Priority: %d\n"),
- _("Verify"),
+ _("Verify"),
job->hdr.name,
jcr->fileset->hdr.name,
level_to_str(jcr->JobLevel),
if (jid) {
jcr->RestoreJobId = atoi(jid);
} else {
- if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
+ if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
goto bail_out;
}
jcr->RestoreJobId = ua->pint32_val;
}
}
jcr->JobLevel = L_FULL; /* default level */
- Dmsg1(20, "JobId to restore=%d\n", jcr->RestoreJobId);
+ Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
if (jcr->RestoreJobId == 0) {
- bsendmsg(ua, _("Run Restore job\n"
- "JobName: %s\n"
- "Bootstrap: %s\n"
- "Where: %s\n"
- "Replace: %s\n"
- "FileSet: %s\n"
- "Client: %s\n"
- "Storage: %s\n"
- "When: %s\n"
- "Catalog: %s\n"
- "Priority: %d\n"),
+ bsendmsg(ua, _("Run Restore job\n"
+ "JobName: %s\n"
+ "Bootstrap: %s\n"
+ "Where: %s\n"
+ "Replace: %s\n"
+ "FileSet: %s\n"
+ "Client: %s\n"
+ "Storage: %s\n"
+ "When: %s\n"
+ "Catalog: %s\n"
+ "Priority: %d\n"),
job->hdr.name,
NPRT(jcr->RestoreBootstrap),
jcr->where?jcr->where:NPRT(job->RestoreWhere),
jcr->catalog->hdr.name,
jcr->JobPriority);
} else {
- bsendmsg(ua, _("Run Restore job\n"
- "JobName: %s\n"
- "Bootstrap: %s\n"
- "Where: %s\n"
- "Replace: %s\n"
- "Client: %s\n"
- "Storage: %s\n"
- "JobId: %s\n"
- "When: %s\n"
- "Catalog: %s\n"
- "Priority: %d\n"),
+ bsendmsg(ua, _("Run Restore job\n"
+ "JobName: %s\n"
+ "Bootstrap: %s\n"
+ "Where: %s\n"
+ "Replace: %s\n"
+ "Client: %s\n"
+ "Storage: %s\n"
+ "JobId: %s\n"
+ "When: %s\n"
+ "Catalog: %s\n"
+ "Priority: %d\n"),
job->hdr.name,
NPRT(jcr->RestoreBootstrap),
jcr->where?jcr->where:NPRT(job->RestoreWhere),
replace,
jcr->client->hdr.name,
jcr->store->hdr.name,
- jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
+ jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
bstrutime(dt, sizeof(dt), jcr->sched_time),
jcr->catalog->hdr.name,
jcr->JobPriority);
add_prompt(ua, _("Priority")); /* 6 */
if (jcr->JobType == JT_BACKUP ||
jcr->JobType == JT_VERIFY) {
- add_prompt(ua, _("Pool")); /* 7 */
+ add_prompt(ua, _("Pool")); /* 7 */
if (jcr->JobType == JT_VERIFY) {
- add_prompt(ua, _("Verify Job")); /* 8 */
+ add_prompt(ua, _("Verify Job")); /* 8 */
}
} else if (jcr->JobType == JT_RESTORE) {
- add_prompt(ua, _("Bootstrap")); /* 7 */
- add_prompt(ua, _("Where")); /* 8 */
- add_prompt(ua, _("Replace")); /* 9 */
- add_prompt(ua, _("JobId")); /* 10 */
+ add_prompt(ua, _("Bootstrap")); /* 7 */
+ add_prompt(ua, _("Where")); /* 8 */
+ add_prompt(ua, _("Replace")); /* 9 */
+ add_prompt(ua, _("JobId")); /* 10 */
}
switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
case 0:
/* Level */
if (jcr->JobType == JT_BACKUP) {
- start_prompt(ua, _("Levels:\n"));
- add_prompt(ua, _("Base"));
- add_prompt(ua, _("Full"));
- add_prompt(ua, _("Incremental"));
- add_prompt(ua, _("Differential"));
- add_prompt(ua, _("Since"));
- switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
+ start_prompt(ua, _("Levels:\n"));
+ add_prompt(ua, _("Base"));
+ add_prompt(ua, _("Full"));
+ add_prompt(ua, _("Incremental"));
+ add_prompt(ua, _("Differential"));
+ add_prompt(ua, _("Since"));
+ switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
case 0:
jcr->JobLevel = L_BASE;
break;
}
goto try_again;
} else if (jcr->JobType == JT_VERIFY) {
- start_prompt(ua, _("Levels:\n"));
- add_prompt(ua, _("Initialize Catalog"));
- add_prompt(ua, _("Verify Catalog"));
- add_prompt(ua, _("Verify Volume to Catalog"));
- add_prompt(ua, _("Verify Disk to Catalog"));
- add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
- switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
+ start_prompt(ua, _("Levels:\n"));
+ add_prompt(ua, _("Initialize Catalog"));
+ add_prompt(ua, _("Verify Catalog"));
+ add_prompt(ua, _("Verify Volume to Catalog"));
+ add_prompt(ua, _("Verify Disk to Catalog"));
+ add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
+ switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
case 0:
jcr->JobLevel = L_VERIFY_INIT;
break;
}
goto try_again;
} else {
- bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n"));
+ bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n"));
}
goto try_again;
case 1:
break;
case 5:
/* When */
- if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
+ if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
break;
}
if (ua->cmd[0] == 0) {
} else {
jcr->sched_time = str_to_utime(ua->cmd);
if (jcr->sched_time == 0) {
- bsendmsg(ua, _("Invalid time, using current time.\n"));
+ bsendmsg(ua, _("Invalid time, using current time.\n"));
jcr->sched_time = time(NULL);
}
}
goto try_again;
case 6:
/* Priority */
- if (!get_pint(ua, _("Enter new Priority: "))) {
+ if (!get_pint(ua, _("Enter new Priority: "))) {
break;
}
if (ua->pint32_val == 0) {
- bsendmsg(ua, _("Priority must be a positive integer.\n"));
+ bsendmsg(ua, _("Priority must be a positive integer.\n"));
} else {
jcr->JobPriority = ua->pint32_val;
}
}
/* Bootstrap */
- if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
+ if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
break;
}
if (jcr->RestoreBootstrap) {
}
if (ua->cmd[0] != 0) {
jcr->RestoreBootstrap = bstrdup(ua->cmd);
- fd = fopen(jcr->RestoreBootstrap, "r");
+ fd = fopen(jcr->RestoreBootstrap, "r");
if (!fd) {
- bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"),
+ bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"),
jcr->RestoreBootstrap, strerror(errno));
free(jcr->RestoreBootstrap);
jcr->RestoreBootstrap = NULL;
goto try_again;
}
/* Where */
- if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
+ if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
break;
}
if (jcr->where) {
free(jcr->where);
jcr->where = NULL;
}
- if (ua->cmd[0] == '/' && ua->cmd[1] == 0) {
+ if (ua->cmd[0] == '/' && ua->cmd[1] == 0) {
ua->cmd[0] = 0;
}
jcr->where = bstrdup(ua->cmd);
goto try_again;
case 9:
/* Replace */
- start_prompt(ua, _("Replace:\n"));
+ start_prompt(ua, _("Replace:\n"));
for (i=0; ReplaceOptions[i].name; i++) {
add_prompt(ua, ReplaceOptions[i].name);
}
- opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
+ opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
if (opt >= 0) {
jcr->replace = ReplaceOptions[opt].token;
}
jid = NULL; /* force reprompt */
jcr->RestoreJobId = 0;
if (jcr->RestoreBootstrap) {
- bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
+ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
}
goto try_again;
default:
if (strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
JobId_t JobId;
- Dmsg1(200, "Calling run_job job=%x\n", jcr->job);
+ Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
start_job:
JobId = run_job(jcr);
free_jcr(jcr); /* release jcr */
if (JobId == 0) {
- bsendmsg(ua, _("Job failed.\n"));
+ bsendmsg(ua, _("Job failed.\n"));
} else {
- bsendmsg(ua, _("Job started. JobId=%u\n"), JobId);
+ bsendmsg(ua, _("Job started. JobId=%u\n"), JobId);
}
return JobId;
}
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "dird.h"
-/* Imported subroutines */
-
/* Imported variables */
extern int r_first;
extern int r_last;
extern int console_msg_pending;
extern char my_name[];
-/* Static variables */
-
-/* Exported variables */
-int quit_cmd_thread = 0;
-
-/* Imported functions */
/* Forward referenced functions */
-
extern "C" void *connect_thread(void *arg);
-
static void *handle_UA_client_request(void *arg);
if ((status=pthread_create(&thid, NULL, connect_thread, (void *)myaddrs)) != 0) {
berrno be;
- be.set_errno(status);
- Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.strerror());
+ Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.strerror(status));
}
started = TRUE;
return;
{
pthread_detach(pthread_self());
- /* ****FIXME**** put # 10 (timeout) on config parameter */
+ /* Permit 10 console connections */
bnet_thread_server((dlist*)arg, 10, &ua_workq, handle_UA_client_request);
return NULL;
}
int stat;
UAContext *ua;
JCR *jcr;
- BSOCK *UA_sock = (BSOCK *)arg;
pthread_detach(pthread_self());
jcr = new_control_jcr("*Console*", JT_CONSOLE);
ua = new_ua_context(jcr);
- ua->UA_sock = UA_sock;
+ ua->UA_sock = (BSOCK *)arg;
bnet_recv(ua->UA_sock); /* Get first message */
if (!authenticate_user_agent(ua)) {
if (stat >= 0) {
pm_strcpy(ua->cmd, ua->UA_sock->msg);
parse_ua_args(ua);
- if (ua->argc > 0 && ua->argk[0][0] == '.') {
+ if (ua->argc > 0 && ua->argk[0][0] == '.') {
do_a_dot_command(ua, ua->cmd);
} else {
do_a_command(ua, ua->cmd);
}
if (!ua->quit) {
if (ua->auto_display_messages) {
- strcpy(ua->cmd, "messages");
+ pm_strcpy(ua->cmd, "messages");
qmessagescmd(ua, ua->cmd);
ua->user_notified_msg_pending = FALSE;
} else if (!ua->user_notified_msg_pending && console_msg_pending) {
- bsendmsg(ua, _("You have messages.\n"));
+ bsendmsg(ua, _("You have messages.\n"));
ua->user_notified_msg_pending = TRUE;
}
bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */
if (ua->UA_sock) {
bnet_close(ua->UA_sock);
+ ua->UA_sock = NULL;
}
free(ua);
}
if (!started) {
return;
}
- quit_cmd_thread = TRUE;
}
*/
/*
- Copyright (C) 2002-2004 Kern Sibbald and John Walker
+ Copyright (C) 2002-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
break;
}
if (!found) {
- bsendmsg(tree->ua, _("Illegal command. Enter \"done\" to exit.\n"));
+ bsendmsg(tree->ua, _("Illegal command. Enter \"done\" to exit.\n"));
continue;
}
if (!stat) {
if (node->inserted) {
tree->FileCount++;
if (tree->DeltaCount > 0 && (tree->FileCount-tree->LastCount) > tree->DeltaCount) {
- bsendmsg(tree->ua, "+");
+ bsendmsg(tree->ua, "+");
tree->LastCount = tree->FileCount;
}
}
bsendmsg(ua, _("No files marked.\n"));
} else {
bsendmsg(ua, _("%s file%s marked.\n"),
- edit_uint64_with_commas(count, ec1), count==0?"":"s");
+ edit_uint64_with_commas(count, ec1), count==0?"":"s");
}
return 1;
}
bsendmsg(ua, _("No directories marked.\n"));
} else {
bsendmsg(ua, _("%s director%s marked.\n"),
- edit_uint64_with_commas(count, ec1), count==1?"y":"ies");
+ edit_uint64_with_commas(count, ec1), count==1?"y":"ies");
}
return 1;
}
const char *tag;
tree_getpath(node, cwd, sizeof(cwd));
if (node->extract) {
- tag = "*";
+ tag = "*";
} else if (node->extract_dir) {
- tag = "+";
+ tag = "+";
} else {
- tag = "";
+ tag = "";
}
- bsendmsg(ua, "%s%s\n", tag, cwd);
+ bsendmsg(ua, "%s%s\n", tag, cwd);
}
}
}
if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) {
const char *tag;
if (node->extract) {
- tag = "*";
+ tag = "*";
} else if (node->extract_dir) {
- tag = "+";
+ tag = "+";
} else {
- tag = "";
+ tag = "";
}
- bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
+ bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
}
}
return 1;
(node->extract || node->extract_dir)) {
const char *tag;
if (node->extract) {
- tag = "*";
+ tag = "*";
} else if (node->extract_dir) {
- tag = "+";
+ tag = "+";
} else {
- tag = "";
+ tag = "";
}
- bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
+ bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":"");
if (tree_node_has_child(node)) {
rlsmark(ua, node);
}
const char *tag;
if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) {
if (node->extract) {
- tag = "*";
+ tag = "*";
} else if (node->extract_dir) {
- tag = "+";
+ tag = "+";
} else {
- tag = " ";
+ tag = " ";
}
tree_getpath(node, cwd, sizeof(cwd));
fdbr.FileId = 0;
memset(&statp, 0, sizeof(statp));
}
ls_output(buf, cwd, tag, &statp);
- bsendmsg(ua, "%s\n", buf);
+ bsendmsg(ua, "%s\n", buf);
}
}
return 1;
if (!node) {
/* Try once more if Win32 drive -- make absolute */
if (ua->argk[1][1] == ':') { /* win32 drive */
- bstrncpy(cwd, "/", sizeof(cwd));
+ bstrncpy(cwd, "/", sizeof(cwd));
bstrncat(cwd, ua->argk[1], sizeof(cwd));
node = tree_cwd(cwd, tree->root, tree->node);
}
if (!node) {
- bsendmsg(ua, _("Invalid path given.\n"));
+ bsendmsg(ua, _("Invalid path given.\n"));
} else {
tree->node = node;
}
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
if (!jcr->verify_jr) {
jcr->verify_jr = &verify_jr;
}
- if (!get_or_create_client_record(jcr)) {
- goto bail_out;
- }
Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
goto bail_out;
}
- if (!jcr->fname) {
- jcr->fname = get_pool_memory(PM_FNAME);
- }
-
/* Print Job Start message */
Jmsg(jcr, M_INFO, 0, _("Start Verify JobId=%d Level=%s Job=%s\n"),
jcr->JobId, level_to_str(jcr->JobLevel), jcr->Job);
/*
* Now start a job with the Storage daemon
*/
- if (!start_storage_daemon_job(jcr)) {
+ if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
goto bail_out;
}
/*
* with what we have and give all ACL streams a new number/type.
*/
#endif
-#if !defined(HAVE_ACL) || ! defined(HAVE_LINUX_OS)
+#if !defined(HAVE_ACL) || !defined(HAVE_LINUX_OS)
/* bacl_get() returns the lenght of the string, or -1 on error. */
int bacl_get(JCR *jcr, int acltype)
}
/***** Do we really want to silently ignore errors from acl_get_file
and acl_to_text? *****/
- return -1;
+ return 0;
}
int bacl_set(JCR *jcr, int acltype)
if (S_ISDIR(st.st_mode) && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
jcr.last_fname = src;
if (bacl_get(&jcr, BACL_TYPE_DEFAULT) < 0) {
- Dmsg1(200, "aclcp: could not read default ACLs for %s\n", jcr.last_fname);
+ Dmsg1(200, "aclcp: could not read default ACLs for %s\n", jcr.last_fname);
return EXIT_FAILURE;
} else {
jcr.last_fname = dst;
/* Copy File options */
if (list == INC_LIST) {
*q = 0; /* terminate options */
- strcpy(buf, fname);
- strcat(buf, " ");
+ bstrncpy(buf, fname, sizeof(buf));
+ bstrncat(buf, " ", sizeof(buf));
optlen = strlen(buf);
} else {
optlen = 0;
/* Copy File options */
if (list == INC_LIST) {
*q = 0; /* terminate options */
- strcpy(buf, fname);
- strcat(buf, " ");
+ bstrncpy(buf, fname, sizeof(buf));
+ bstrncat(buf, " ", sizeof(buf));
optlen = strlen(buf);
} else {
optlen = 0;
*/
if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
&stream, &size) != 5) {
- Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
+ Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
goto bail_out;
}
Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream);
* Now we expect the Stream Data
*/
if (bget_msg(sd) < 0) {
- Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
+ Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd));
goto bail_out;
}
if (size != ((uint32_t)sd->msglen)) {
- Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
+ Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size);
goto bail_out;
}
Dmsg1(30, "Got stream data, len=%d\n", sd->msglen);
case STREAM_UNIX_ATTRIBUTES_EX:
char *ap, *lp, *fp;
- Dmsg0(400, "Stream=Unix Attributes.\n");
+ Dmsg0(400, "Stream=Unix Attributes.\n");
if ((int)sizeof_pool_memory(fname) < sd->msglen) {
fname = realloc_pool_memory(fname, sd->msglen + 1);
* Link name (if file linked i.e. FT_LNK)
* Extended Attributes (if Win32)
*/
- if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
- Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg);
- Dmsg0(0, "\nError scanning header\n");
+ if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
+ Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg);
+ Dmsg0(0, "\nError scanning header\n");
goto bail_out;
}
- Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
+ Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
if (record_file_index != file_index) {
- Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
+ Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
file_index, record_file_index);
- Dmsg0(0, "File index error\n");
+ Dmsg0(0, "File index error\n");
goto bail_out;
}
ap = sd->msg;
- while (*ap++ != ' ') /* skip record file index */
+ while (*ap++ != ' ') /* skip record file index */
;
- while (*ap++ != ' ') /* skip type */
+ while (*ap++ != ' ') /* skip type */
;
/* Save filename and position to attributes */
fp = fname;
}
*fp = *ap++; /* terminate filename & point to attribs */
- Dmsg1(200, "Attr=%s\n", ap);
+ Dmsg1(200, "Attr=%s\n", ap);
/* Skip to Link name */
if (type == FT_LNK || type == FT_LNKSAVED) {
lp = ap;
while (*lp++ != 0) {
;
}
- strcat(lname, lp); /* "save" link name */
+ pm_strcat(lname, lp); /* "save" link name */
} else {
*lname = 0;
}
P(jcr->mutex);
jcr->JobFiles++;
jcr->num_files_examined++;
- pm_strcpy(&jcr->last_fname, fname); /* last file examined */
+ pm_strcpy(jcr->last_fname, fname); /* last file examined */
V(jcr->mutex);
/*
* slash. For a linked file, link is the link.
*/
/* Send file attributes to Director */
- Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname);
+ Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname);
if (type == FT_LNK || type == FT_LNKSAVED) {
- stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
- STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
+ stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
+ STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
0, ap, 0, lname, 0);
} else {
- stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
- STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
+ stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
+ STREAM_UNIX_ATTRIBUTES, "pinsug5", fname,
0, ap, 0, 0);
}
- Dmsg2(200, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
+ Dmsg2(200, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
if (!stat) {
- Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
+ Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
goto bail_out;
}
break;
case STREAM_MD5_SIGNATURE:
char MD5buf[30];
bin_to_base64(MD5buf, (char *)sd->msg, 16); /* encode 16 bytes */
- Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf);
- bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
+ Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf);
+ bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
jcr->JobFiles);
- Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
+ Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
break;
case STREAM_SHA1_SIGNATURE:
char SHA1buf[30];
bin_to_base64(SHA1buf, (char *)sd->msg, 20); /* encode 20 bytes */
- Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf);
- bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE,
+ Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, SHA1buf);
+ bnet_fsend(dir, "%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_SIGNATURE,
SHA1buf, jcr->JobFiles);
- Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
+ Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg);
break;
default:
- Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
+ Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
break;
} /* end switch */
} /* end while bnet_get */
#define foreach_jcr(jcr) \
for ((jcr)=NULL; ((jcr)=get_next_jcr(jcr)); )
+#define SD_APPEND 1
+#define SD_READ 0
struct JCR;
/* This should be empty in the library */
#ifdef DIRECTOR_DAEMON
-#define MAX_STORE 2
/* Director Daemon specific part of JCR */
pthread_t SD_msg_chan; /* Message channel thread id */
pthread_cond_t term_wait; /* Wait for job termination */
BSOCK *ua; /* User agent */
JOB *job; /* Job resource */
JOB *verify_job; /* Job resource of verify target job */
- alist *storage[MAX_STORE]; /* Storage possibilities */
+ alist *storage; /* Storage possibilities */
STORE *store; /* Storage daemon selected */
CLIENT *client; /* Client resource */
POOL *pool; /* Pool resource */
pthread_cond_t job_start_wait; /* Wait for FD to start Job */
int type;
DCR *dcr; /* device context record */
- DEVRES *device; /* device resource to use */
+ alist *dcrs; /* list of dcrs open */
+// DEVRES *device; /* device resource to use */
POOLMEM *job_name; /* base Job name (not unique) */
POOLMEM *fileset_name; /* FileSet */
POOLMEM *fileset_md5; /* MD5 for FileSet */
*/
/*
- Copyright (C) 2003-2004 Kern Sibbald and John Walker
+ Copyright (C) 2003-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
* Loop var through each member of list
*/
#define foreach_alist(var, list) \
- for((*((void **)&(var))=(void*)((list)->first())); (var); (*((void **)&(var))=(void*)((list)->next())))
+ for((*((void **)&(var))=(void*)((list)->first())); \
+ (var); \
+ (*((void **)&(var))=(void*)((list)->next())))
#ifdef the_easy_way
#define foreach_alist(var, list) \
- for((void*(var))=(list)->first(); (var); (void *(var))=(list)->next(var)); )
+ for((void*(var))=(list)->first(); (var); (void *(var))=(list)->next(var)); )
#endif
if (rc < 0) {
if (!bsock->suppress_error_msgs && !bsock->timed_out) {
Qmsg4(bsock->jcr, M_ERROR, 0,
- _("Write error sending to %s:%s:%d: ERR=%s\n"), bsock->who,
+ _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
bsock->host, bsock->port, bnet_strerror(bsock));
}
} else {
}
if (rc < 0) {
if (!bsock->suppress_error_msgs) {
- Qmsg4(bsock->jcr, M_ERROR, 0,
- _("Write error sending to %s:%s:%d: ERR=%s\n"), bsock->who,
+ Qmsg5(bsock->jcr, M_ERROR, 0,
+ _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
+ bsock->msglen, bsock->who,
bsock->host, bsock->port, bnet_strerror(bsock));
}
} else {
/* wait for worker child to exit */
for ( ;; ) {
- Dmsg2(200, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
+ Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
do {
wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
} while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
if (wpid == bpipe->worker_pid || wpid == -1) {
stat = errno;
- Dmsg3(200, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
- wpid==-1?strerror(errno):"none");
+ Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
+ wpid==-1?strerror(errno):"none");
break;
}
- Dmsg3(200, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
- wpid==-1?strerror(errno):"none");
+ Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
+ wpid==-1?strerror(errno):"none");
if (remaining_wait > 0) {
bmicrosleep(1, 0); /* wait one second */
remaining_wait--;
} else {
stat = ETIME; /* set error status */
wpid = -1;
- break; /* don't wait any longer */
+ break; /* don't wait any longer */
}
}
if (wpid > 0) {
if (WIFEXITED(chldstatus)) { /* process exit()ed */
stat = WEXITSTATUS(chldstatus);
if (stat != 0) {
- Dmsg1(200, "Non-zero status %d returned from child.\n", stat);
+ Dmsg1(800, "Non-zero status %d returned from child.\n", stat);
stat |= b_errno_exit; /* exit status returned */
}
- Dmsg1(200, "child status=%d\n", stat & ~b_errno_exit);
+ Dmsg1(800, "child status=%d\n", stat & ~b_errno_exit);
} else if (WIFSIGNALED(chldstatus)) { /* process died */
stat = WTERMSIG(chldstatus);
- Dmsg1(200, "Child died from signale %d\n", stat);
+ Dmsg1(800, "Child died from signale %d\n", stat);
stat |= b_errno_signal; /* exit signal returned */
}
}
stop_child_timer(bpipe->timer_id);
}
free(bpipe);
- Dmsg1(200, "returning stat = %d\n", stat);
+ Dmsg1(800, "returning stat = %d\n", stat);
return stat;
}
stat1 = ferror(bpipe->rfd);
}
if (stat1 < 0) {
- Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
+ Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
} else if (stat1 != 0) {
- Dmsg1(100, "Run program fgets stat=%d\n", stat1);
+ Dmsg1(100, "Run program fgets stat=%d\n", stat1);
}
} else {
stat1 = 0;
while (1) {
fgets(tmp, sizeof_pool_memory(tmp), bpipe->rfd);
- Dmsg1(200, "Run program fgets=%s", tmp);
+ Dmsg1(800, "Run program fgets=%s", tmp);
pm_strcat(results, tmp);
if (feof(bpipe->rfd)) {
- stat1 = 0;
+ stat1 = 0;
Dmsg1(100, "Run program fgets stat=%d\n", stat1);
- break;
+ break;
} else {
- stat1 = ferror(bpipe->rfd);
+ stat1 = ferror(bpipe->rfd);
}
if (stat1 < 0) {
Dmsg2(100, "Run program fgets stat=%d ERR=%s\n", stat1, strerror(errno));
- break;
+ break;
} else if (stat1 != 0) {
Dmsg1(100, "Run program fgets stat=%d\n", stat1);
}
q++;
quote = 0;
} else {
- while (*q && *q != ' ')
+ while (*q && *q != ' ')
q++;
}
if (*q)
- *(q++) = '\0';
+ *(q++) = '\0';
bargv[argc++] = p;
p = q;
- while (*p && (*p == ' ' || *p == '\t'))
+ while (*p && (*p == ' ' || *p == '\t'))
p++;
- if (*p == '\"' || *p == '\'') {
+ if (*p == '\"' || *p == '\'') {
quote = *p;
p++;
}
* Become a daemon.
*/
- Dmsg0(200, "Enter daemon_start\n");
+ Dmsg0(900, "Enter daemon_start\n");
if ( (cpid = fork() ) < 0)
Emsg1(M_ABORT, 0, "Cannot fork to become daemon: %s\n", strerror(errno));
else if (cpid > 0)
}
#endif /* HAVE_CYGWIN */
- Dmsg0(200, "Exit daemon_start\n");
+ Dmsg0(900, "Exit daemon_start\n");
}
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
mbuf[i--] = '0';
} else {
while (val != 0) {
- mbuf[i--] = "0123456789"[val%10];
+ mbuf[i--] = "0123456789"[val%10];
val /= 10;
}
}
mbuf[i--] = '0';
} else {
while (val != 0) {
- mbuf[i--] = "0123456789"[val%10];
+ mbuf[i--] = "0123456789"[val%10];
val /= 10;
}
}
return buf;
}
+char *edit_int64(int64_t val, char *buf)
+{
+ /*
+ * Replacement for sprintf(buf, "%" llu, val)
+ */
+ char mbuf[50];
+ bool negative = false;
+ mbuf[sizeof(mbuf)-1] = 0;
+ int i = sizeof(mbuf)-2; /* edit backward */
+ if (val == 0) {
+ mbuf[i--] = '0';
+ } else {
+ if (val < 0) {
+ negative = true;
+ val = -val;
+ }
+ while (val != 0) {
+ mbuf[i--] = "0123456789"[val%10];
+ val /= 10;
+ }
+ }
+ if (negative) {
+ mbuf[i--] = '-';
+ }
+ strcpy(buf, &mbuf[i+1]);
+ return buf;
+}
+
+
/*
* Given a string "str", separate the integer part into
* str, and the modifier into mod.
* Baculas.
*/
static const char *mod[] = {"n", "seconds", "months", "minutes",
- "hours", "days", "weeks", "quarters", "years", NULL};
+ "hours", "days", "weeks", "quarters", "years", NULL};
static const int32_t mult[] = {60, 1, 60*60*24*30, 60,
60*60, 60*60*24, 60*60*24*7, 60*60*24*91, 60*60*24*365};
times = (uint32_t)(val / mult[i]);
if (times > 0) {
val = val - (utime_t)times * mult[i];
- bsnprintf(mybuf, sizeof(mybuf), "%d %s%s ", times, mod[i], times>1?"s":"");
+ bsnprintf(mybuf, sizeof(mybuf), "%d %s%s ", times, mod[i], times>1?"s":"");
bstrncat(buf, mybuf, buf_len);
}
}
continue;
}
if (msg) {
- Mmsg(msg, _("Illegal character \"%c\" in name.\n"), *p);
+ Mmsg(msg, _("Illegal character \"%c\" in name.\n"), *p);
}
return false;
}
len = strlen(name);
if (len >= MAX_NAME_LENGTH) {
if (msg) {
- Mmsg(msg, _("Name too long.\n"));
+ Mmsg(msg, _("Name too long.\n"));
}
return false;
}
if (len == 0) {
if (msg) {
- Mmsg(msg, _("Volume name must be at least one character long.\n"));
+ Mmsg(msg, _("Volume name must be at least one character long.\n"));
}
return false;
}
for (int i=0; i<8; i++) {
strcpy(buf, str[i]);
if (!duration_to_utime(buf, &val)) {
- printf("Error return from duration_to_utime for in=%s\n", str[i]);
+ printf("Error return from duration_to_utime for in=%s\n", str[i]);
continue;
}
edit_utime(val, outval);
* the randomness. In this program, the hash table can grow when
* it gets too full, so the table size here is a binary number. The
* hashing is provided using an idea from Tcl where the initial
- * hash code is then "randomized" using a simple calculation from
+ * hash code is "randomized" using a simple calculation from
* a random number generator that multiplies by a big number
* (I multiply by a prime number, while Tcl did not)
- * then shifts the results down and does the binary division
+ * then shifts the result down and does the binary division
* by masking. Increasing the size of the hash table is simple.
* Just create a new larger table, walk the old table and
* re-hash insert each entry into the new table.
*
*/
/*
- Copyright (C) 2003-2004 Kern Sibbald and John Walker
+ Copyright (C) 2003-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
walk_index = 0;
}
-#ifdef xxx
-void * htable::operator new(size_t)
-{
- return malloc(sizeof(htable));
-}
-
-void htable::operator delete(void *tbl)
-{
- ((htable *)tbl)->destroy();
- free(tbl);
-}
-#endif
-
uint32_t htable::size()
{
return num_items;
}
+/*
+ * Take each hash link and walk down the chain of items
+ * that hash there counting them (i.e. the hits),
+ * then report that number.
+ * Obiously, the more hits in a chain, the more time
+ * it takes to reference them. Empty chains are not so
+ * hot either -- as it means unused or wasted space.
+ */
+#define MAX_COUNT 20
void htable::stats()
{
- int count[10];
+ int hits[MAX_COUNT];
int max = 0;
int i, j;
hlink *p;
- printf("\n\nNumItems=%d\nBuckets=%d\n", num_items, buckets);
- for (i=0; i<10; i++) {
- count[i] = 0;
+ printf("\n\nNumItems=%d\nTotal buckets=%d\n", num_items, buckets);
+ printf("Hits/bucket: buckets\n");
+ for (i=0; i < MAX_COUNT; i++) {
+ hits[i] = 0;
}
for (i=0; i<(int)buckets; i++) {
p = table[i];
if (j > max) {
max = j;
}
- if (j < 10) {
- count[j]++;
+ if (j < MAX_COUNT) {
+ hits[j]++;
}
}
- for (i=0; i<10; i++) {
- printf("%2d: %d\n",i, count[i]);
+ for (i=0; i < MAX_COUNT; i++) {
+ printf("%2d: %d\n",i, hits[i]);
}
- printf("max = %d\n", max);
+ printf("max hits in a bucket = %d\n", max);
}
void htable::grow_table()
for (hlink *hp=table[index]; hp; hp=(hlink *)hp->next) {
// Dmsg2(100, "hp=0x%x key=%s\n", (long)hp, hp->key);
if (hash == hp->hash && strcmp(key, hp->key) == 0) {
- Dmsg1(100, "lookup return %x\n", ((char *)hp)-loffset);
+ Dmsg1(100, "lookup return %x\n", ((char *)hp)-loffset);
return ((char *)hp)-loffset;
}
}
while (!walkptr && walk_index < buckets) {
walkptr = table[walk_index++];
if (walkptr) {
- Dmsg3(100, "new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
+ Dmsg3(100, "new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
(unsigned)(walkptr->next), walk_index-1);
}
}
while (!walkptr && walk_index < buckets) {
walkptr = table[walk_index++]; /* go to next bucket */
if (walkptr) {
- Dmsg3(100, "first new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
+ Dmsg3(100, "first new walkptr=0x%x next=0x%x inx=%d\n", (unsigned)walkptr,
(unsigned)(walkptr->next), walk_index-1);
}
}
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2003-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
* Loop var through each member of table
*/
#define foreach_htable(var, tbl) \
- for(((void *)(var))=(tbl)->first(); \
- (var); \
- ((void *)(var))=(tbl)->next())
+ for((*((void **)&(var))=(void *)((tbl)->first())); \
+ (var); \
+ (*((void **)&(var))=(void *)((tbl)->next())))
struct hlink {
void *next; /* next hash item */
*
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
if (!last_jobs) {
last_jobs = New(dlist(job_entry, &job_entry->link));
if ((errstat=rwl_init(&lock)) != 0) {
- Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"),
+ Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"),
strerror(errstat));
}
}
}
for ( ; num; num--) {
if (read(fd, &job, sizeof(job)) != sizeof(job)) {
- Dmsg1(000, "Read job entry. ERR=%s\n", strerror(errno));
+ Dmsg1(000, "Read job entry. ERR=%s\n", strerror(errno));
return;
}
if (job.JobId > 0) {
/* First record is number of entires */
num = last_jobs->size();
if (write(fd, &num, sizeof(num)) != sizeof(num)) {
- Dmsg1(000, "Error writing num_items: ERR=%s\n", strerror(errno));
+ Dmsg1(000, "Error writing num_items: ERR=%s\n", strerror(errno));
return 0;
}
foreach_dlist(je, last_jobs) {
if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) {
- Dmsg1(000, "Error writing job: ERR=%s\n", strerror(errno));
+ Dmsg1(000, "Error writing job: ERR=%s\n", strerror(errno));
return 0;
}
}
MQUEUE_ITEM *item = NULL;
struct sigaction sigtimer;
- Dmsg0(400, "Enter new_jcr\n");
+ Dmsg0(3400, "Enter new_jcr\n");
jcr = (JCR *)malloc(size);
memset(jcr, 0, size);
jcr->my_thread_id = pthread_self();
*/
static void remove_jcr(JCR *jcr)
{
- Dmsg0(400, "Enter remove_jcr\n");
+ Dmsg0(3400, "Enter remove_jcr\n");
if (!jcr) {
Emsg0(M_ABORT, 0, "NULL jcr.\n");
}
if (jcr->next) {
jcr->next->prev = jcr->prev;
}
- Dmsg0(400, "Leave remove_jcr\n");
+ Dmsg0(3400, "Leave remove_jcr\n");
}
/*
#ifdef DEBUG
void b_free_jcr(const char *file, int line, JCR *jcr)
{
- Dmsg3(400, "Enter free_jcr 0x%x from %s:%d\n", jcr, file, line);
+ Dmsg3(3400, "Enter free_jcr 0x%x from %s:%d\n", jcr, file, line);
#else
void free_jcr(JCR *jcr)
{
- Dmsg1(400, "Enter free_jcr 0x%x\n", jcr);
+ Dmsg1(3400, "Enter free_jcr 0x%x\n", jcr);
#endif
Emsg2(M_ERROR, 0, _("JCR use_count=%d JobId=%d\n"),
jcr->use_count, jcr->JobId);
}
- Dmsg3(400, "Dec free_jcr 0x%x use_count=%d jobid=%d\n", jcr, jcr->use_count, jcr->JobId);
+ Dmsg3(3400, "Dec free_jcr 0x%x use_count=%d jobid=%d\n", jcr, jcr->use_count, jcr->JobId);
if (jcr->use_count > 0) { /* if in use */
unlock_jcr_chain();
- Dmsg2(400, "free_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "free_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
return;
}
remove_jcr(jcr); /* remove Jcr from chain */
job_end_pop(jcr); /* pop and call hooked routines */
- Dmsg1(400, "End job=%d\n", jcr->JobId);
+ Dmsg1(3400, "End job=%d\n", jcr->JobId);
if (jcr->daemon_free_jcr) {
jcr->daemon_free_jcr(jcr); /* call daemon free routine */
}
free_common_jcr(jcr);
close_msg(NULL); /* flush any daemon messages */
- Dmsg0(400, "Exit free_jcr\n");
+ Dmsg0(3400, "Exit free_jcr\n");
}
void free_locked_jcr(JCR *jcr)
{
jcr->use_count--; /* decrement use count */
- Dmsg2(400, "Dec free_locked_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "Dec free_locked_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
if (jcr->use_count > 0) { /* if in use */
return;
}
P(jcr->mutex);
jcr->use_count++;
V(jcr->mutex);
- Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
}
P(jcr->mutex);
jcr->use_count++;
V(jcr->mutex);
- Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
}
P(jcr->mutex);
jcr->use_count++;
V(jcr->mutex);
- Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
}
P(jcr->mutex);
jcr->use_count++;
V(jcr->mutex);
- Dmsg2(400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "Inc get_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
break;
}
}
{
int errstat;
#ifdef TRACE_JCR_CHAIN
- Dmsg3(400, "Lock jcr chain %d from %s:%d\n", ++lock_count,
+ Dmsg3(3400, "Lock jcr chain %d from %s:%d\n", ++lock_count,
fname, line);
#endif
if ((errstat=rwl_writelock(&lock)) != 0) {
{
int errstat;
#ifdef TRACE_JCR_CHAIN
- Dmsg3(400, "Unlock jcr chain %d from %s:%d\n", lock_count--,
+ Dmsg3(3400, "Unlock jcr chain %d from %s:%d\n", lock_count--,
fname, line);
#endif
if ((errstat=rwl_writeunlock(&lock)) != 0) {
P(jcr->mutex);
jcr->use_count++;
V(jcr->mutex);
- Dmsg2(400, "Inc get_next_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+ Dmsg2(3400, "Inc get_next_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
}
return jcr;
}
BSOCK *fd;
time_t timer_start;
- Dmsg0(400, "Start JCR timeout checks\n");
+ Dmsg0(3400, "Start JCR timeout checks\n");
/* Walk through all JCRs checking if any one is
* blocked for more than specified max time.
}
unlock_jcr_chain();
- Dmsg0(400, "Finished JCR timeout checks\n");
+ Dmsg0(3400, "Finished JCR timeout checks\n");
}
/*
if (argc>0 && argv && argv[0]) {
/* strip trailing filename and save exepath */
for (l=p=argv[0]; *p; p++) {
- if (*p == '/') {
+ if (*p == '/') {
l = p; /* set pos of last slash */
}
}
l = argv[0];
#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
/* On Windows allow c: junk */
- if (l[1] == ':') {
+ if (l[1] == ':') {
l += 2;
}
#endif
for (d=msg->dest_chain; d; d=d->next) {
if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
(strcmp(where, d->where) == 0))) {
- Dmsg4(200, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n",
+ Dmsg4(850, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n",
d, msg_type, dest_code, NPRT(where));
set_bit(msg_type, d->msg_types);
set_bit(msg_type, msg->send_msg); /* set msg_type bit in our local */
if (mail_cmd) {
d->mail_cmd = bstrdup(mail_cmd);
}
- Dmsg5(200, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n",
+ Dmsg5(850, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n",
d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd));
msg->dest_chain = d;
}
DEST *d;
for (d=msg->dest_chain; d; d=d->next) {
- Dmsg2(200, "Remove_msg_dest d=%x where=%s\n", d, NPRT(d->where));
+ Dmsg2(850, "Remove_msg_dest d=%x where=%s\n", d, NPRT(d->where));
if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
((where == NULL && d->where == NULL) ||
(strcmp(where, d->where) == 0))) {
- Dmsg3(200, "Found for remove d=%x msgtype=%d destcode=%d\n",
+ Dmsg3(850, "Found for remove d=%x msgtype=%d destcode=%d\n",
d, msg_type, dest_code);
clear_bit(msg_type, d->msg_types);
- Dmsg0(200, "Return rem_msg_dest\n");
+ Dmsg0(850, "Return rem_msg_dest\n");
return;
}
}
Mmsg(name, "%s/%s.mail.%s.%d", working_directory, my_name,
my_name, (int)(long)d);
}
- Dmsg1(200, "mailname=%s\n", name);
+ Dmsg1(850, "mailname=%s\n", name);
}
/*
POOLMEM *cmd, *line;
int len, stat;
- Dmsg1(350, "Close_msg jcr=0x%x\n", jcr);
+ Dmsg1(850, "Close_msg jcr=0x%x\n", jcr);
if (jcr == NULL) { /* NULL -> global chain */
msgs = daemon_msgs;
if (msgs == NULL) {
return;
}
- Dmsg1(350, "===Begin close msg resource at 0x%x\n", msgs);
+ Dmsg1(850, "===Begin close msg resource at 0x%x\n", msgs);
cmd = get_pool_memory(PM_MESSAGE);
for (d=msgs->dest_chain; d; ) {
if (d->fd) {
break;
case MD_MAIL:
case MD_MAIL_ON_ERROR:
- Dmsg0(350, "Got MD_MAIL or MD_MAIL_ON_ERROR\n");
+ Dmsg0(850, "Got MD_MAIL or MD_MAIL_ON_ERROR\n");
if (!d->fd) {
break;
}
}
if (!(bpipe=open_mail_pipe(jcr, cmd, d))) {
- Pmsg0(000, "open mail pipe failed.\n");
+ Pmsg0(000, "open mail pipe failed.\n");
goto rem_temp_file;
}
- Dmsg0(350, "Opened mail pipe\n");
+ Dmsg0(850, "Opened mail pipe\n");
len = d->max_len+10;
line = get_memory(len);
rewind(d->fd);
}
if (!close_wpipe(bpipe)) { /* close write pipe sending mail */
berrno be;
- Pmsg1(000, "close error: ERR=%s\n", be.strerror());
+ Pmsg1(000, "close error: ERR=%s\n", be.strerror());
}
/*
- * Since we are closing all messages, before "recursing"
+ * Since we are closing all messages, before "recursing"
* make sure we are not closing the daemon messages, otherwise
* kaboom.
*/
if (msgs != daemon_msgs) {
/* read what mail prog returned -- should be nothing */
while (fgets(line, len, bpipe->rfd)) {
- Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line);
+ Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line);
}
}
if (stat != 0 && msgs != daemon_msgs) {
berrno be;
be.set_errno(stat);
- Dmsg1(350, "Calling emsg. CMD=%s\n", cmd);
- Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n"
- "CMD=%s\n"
- "ERR=%s\n"), cmd, be.strerror());
+ Dmsg1(850, "Calling emsg. CMD=%s\n", cmd);
+ Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n"
+ "CMD=%s\n"
+ "ERR=%s\n"), cmd, be.strerror());
}
free_memory(line);
rem_temp_file:
unlink(d->mail_filename);
free_pool_memory(d->mail_filename);
d->mail_filename = NULL;
- Dmsg0(350, "end mail or mail on error\n");
+ Dmsg0(850, "end mail or mail on error\n");
break;
default:
break;
d = d->next; /* point to next buffer */
}
free_pool_memory(cmd);
- Dmsg0(350, "Done walking message chain.\n");
+ Dmsg0(850, "Done walking message chain.\n");
if (jcr) {
free_msgs_res(msgs);
msgs = NULL;
} else {
V(mutex);
}
- Dmsg0(350, "===End close msg resource\n");
+ Dmsg0(850, "===End close msg resource\n");
}
/*
*/
void term_msg()
{
- Dmsg0(300, "Enter term_msg\n");
+ Dmsg0(850, "Enter term_msg\n");
close_msg(NULL); /* close global chain */
free_msgs_res(daemon_msgs); /* free the resources */
daemon_msgs = NULL;
MSGS *msgs;
BPIPE *bpipe;
- Dmsg2(800, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
+ Dmsg2(850, "Enter dispatch_msg type=%d msg=%s\n", type, msg);
/*
* Most messages are prefixed by a date and time. If mtime is
#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
/* If we don't exit on error, error messages are parsed by UA */
if (exit_on_error) {
- MessageBox(NULL, msg, "Bacula", MB_OK);
+ MessageBox(NULL, msg, "Bacula", MB_OK);
}
#endif
#endif
if (bit_is_set(type, d->msg_types)) {
switch (d->dest_code) {
case MD_CONSOLE:
- Dmsg1(800, "CONSOLE for following msg: %s", msg);
+ Dmsg1(850, "CONSOLE for following msg: %s", msg);
if (!con_fd) {
- con_fd = fopen(con_fname, "a+");
- Dmsg0(800, "Console file not open.\n");
+ con_fd = fopen(con_fname, "a+");
+ Dmsg0(850, "Console file not open.\n");
}
if (con_fd) {
Pw(con_lock); /* get write lock on console message file */
len = strlen(msg);
if (len > 0) {
fwrite(msg, len, 1, con_fd);
- if (msg[len-1] != '\n') {
- fwrite("\n", 2, 1, con_fd);
+ if (msg[len-1] != '\n') {
+ fwrite("\n", 2, 1, con_fd);
}
} else {
- fwrite("\n", 2, 1, con_fd);
+ fwrite("\n", 2, 1, con_fd);
}
fflush(con_fd);
console_msg_pending = TRUE;
}
break;
case MD_SYSLOG:
- Dmsg1(800, "SYSLOG for collowing msg: %s\n", msg);
+ Dmsg1(850, "SYSLOG for collowing msg: %s\n", msg);
/*
* We really should do an openlog() here.
*/
- syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
+ syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
break;
case MD_OPERATOR:
- Dmsg1(800, "OPERATOR for following msg: %s\n", msg);
+ Dmsg1(850, "OPERATOR for following msg: %s\n", msg);
mcmd = get_pool_memory(PM_MESSAGE);
if ((bpipe=open_mail_pipe(jcr, mcmd, d))) {
int stat;
if (stat != 0) {
berrno be;
be.set_errno(stat);
- Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
- "CMD=%s\n"
- "ERR=%s\n"), mcmd, be.strerror());
+ Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n"
+ "CMD=%s\n"
+ "ERR=%s\n"), mcmd, be.strerror());
}
}
free_pool_memory(mcmd);
break;
case MD_MAIL:
case MD_MAIL_ON_ERROR:
- Dmsg1(800, "MAIL for following msg: %s", msg);
+ Dmsg1(850, "MAIL for following msg: %s", msg);
if (!d->fd) {
POOLMEM *name = get_pool_memory(PM_MESSAGE);
make_unique_mail_filename(jcr, name, d);
- d->fd = fopen(name, "w+");
+ d->fd = fopen(name, "w+");
if (!d->fd) {
berrno be;
d->fd = stdout;
- Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", name,
+ Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", name,
be.strerror());
d->fd = NULL;
free_pool_memory(name);
fputs(msg, d->fd);
break;
case MD_FILE:
- Dmsg1(800, "FILE for following msg: %s", msg);
+ Dmsg1(850, "FILE for following msg: %s", msg);
if (!d->fd) {
- d->fd = fopen(d->where, "w+");
+ d->fd = fopen(d->where, "w+");
if (!d->fd) {
berrno be;
d->fd = stdout;
- Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
+ Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
be.strerror());
d->fd = NULL;
break;
fputs(msg, d->fd);
break;
case MD_APPEND:
- Dmsg1(800, "APPEND for following msg: %s", msg);
+ Dmsg1(850, "APPEND for following msg: %s", msg);
if (!d->fd) {
- d->fd = fopen(d->where, "a");
+ d->fd = fopen(d->where, "a");
if (!d->fd) {
berrno be;
d->fd = stdout;
- Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
+ Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where,
be.strerror());
d->fd = NULL;
break;
fputs(msg, d->fd);
break;
case MD_DIRECTOR:
- Dmsg1(800, "DIRECTOR for following msg: %s", msg);
+ Dmsg1(850, "DIRECTOR for following msg: %s", msg);
if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
- bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%d %s",
+ bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%d %s",
jcr->Job, type, mtime, msg);
}
break;
case MD_STDOUT:
- Dmsg1(800, "STDOUT for following msg: %s", msg);
+ Dmsg1(850, "STDOUT for following msg: %s", msg);
if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */
fputs(dt, stdout);
fputs(msg, stdout);
}
break;
case MD_STDERR:
- Dmsg1(800, "STDERR for following msg: %s", msg);
+ Dmsg1(850, "STDERR for following msg: %s", msg);
fputs(dt, stderr);
fputs(msg, stderr);
break;
/* visual studio passes the whole path to the file as well
* which makes for very long lines
*/
- const char *f = strrchr(file, '\\');
+ const char *f = strrchr(file, '\\');
if (f) file = f + 1;
- len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+ len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
} else {
len = 0;
}
va_end(arg_ptr);
/*
- * Used the "trace on" command in the console to turn on
- * output to the trace file. "trace off" will close the file.
+ * Used the "trace on" command in the console to turn on
+ * output to the trace file. "trace off" will close the file.
*/
if (trace) {
if (!trace_fd) {
- bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory ? working_directory : ".");
- trace_fd = fopen(buf, "a+");
+ bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory ? working_directory : ".");
+ trace_fd = fopen(buf, "a+");
}
if (trace_fd) {
fputs(buf, trace_fd);
if (level <= debug_level) {
if (!trace_fd) {
- bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory);
- trace_fd = fopen(buf, "a+");
+ bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory);
+ trace_fd = fopen(buf, "a+");
}
#ifdef FULL_LOCATION
if (details) {
- len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+ len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
} else {
len = 0;
}
break;
case M_FATAL:
if (level == -1) /* skip details */
- len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error because: ", my_name);
+ len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error because: ", my_name);
else
- len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error at %s:%d because:\n", my_name, file, line);
+ len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error at %s:%d because:\n", my_name, file, line);
break;
case M_ERROR:
if (level == -1) /* skip details */
- len = bsnprintf(buf, sizeof(buf), "%s: ERROR: ", my_name);
+ len = bsnprintf(buf, sizeof(buf), "%s: ERROR: ", my_name);
else
- len = bsnprintf(buf, sizeof(buf), "%s: ERROR in %s:%d ", my_name, file, line);
+ len = bsnprintf(buf, sizeof(buf), "%s: ERROR in %s:%d ", my_name, file, line);
break;
case M_WARNING:
len = bsnprintf(buf, sizeof(buf), "%s: Warning: ", my_name);
const char *job;
- Dmsg1(800, "Enter Jmsg type=%d\n", type);
+ Dmsg1(850, "Enter Jmsg type=%d\n", type);
/* Special case for the console, which has a dir_bsock and JobId==0,
* in that case, we send the message directly back to the
for (i=0; items[i].name; i++) {
Dmsg3(900, "Item=%s def=%s defval=%d\n", items[i].name,
- (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
+ (items[i].flags & ITEM_DEFAULT) ? "yes" : "no",
items[i].default_value);
if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) {
if (items[i].handler == store_yesno) {
}
/* If this triggers, take a look at lib/parse_conf.h */
if (i >= MAX_RES_ITEMS) {
- Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
+ Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
}
}
}
token = lex_get_token(lc, T_NAME); /* scan destination */
dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
if (dest[0] != 0) {
- pm_strcat(dest, " "); /* separate multiple destinations with space */
+ pm_strcat(dest, " "); /* separate multiple destinations with space */
dest_len++;
}
pm_strcat(dest, lc->str);
dest_len += lc->str_len;
- Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
+ Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
token = lex_get_token(lc, T_SKIP_EOL);
if (token == T_COMMA) {
continue; /* get another destination */
}
if (token != T_EQUALS) {
- scan_err1(lc, _("expected an =, got: %s"), lc->str);
+ scan_err1(lc, _("expected an =, got: %s"), lc->str);
}
break;
}
- Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
+ Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd));
scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd);
free_pool_memory(dest);
- Dmsg0(900, "done with dest codes\n");
+ Dmsg0(900, "done with dest codes\n");
break;
case MD_FILE: /* file */
case MD_APPEND: /* append */
pm_strcpy(dest, lc->str);
dest_len = lc->str_len;
token = lex_get_token(lc, T_SKIP_EOL);
- Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
+ Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
if (token != T_EQUALS) {
- scan_err1(lc, _("expected an =, got: %s"), lc->str);
+ scan_err1(lc, _("expected an =, got: %s"), lc->str);
}
scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
free_pool_memory(dest);
- Dmsg0(900, "done with dest codes\n");
+ Dmsg0(900, "done with dest codes\n");
break;
default:
- scan_err1(lc, _("Unknown item code: %d\n"), item->code);
+ scan_err1(lc, _("Unknown item code: %d\n"), item->code);
break;
}
}
}
}
if (!found) {
- scan_err1(lc, _("message type: %s not found"), str);
+ scan_err1(lc, _("message type: %s not found"), str);
/* NOT REACHED */
}
MD5Update(&md5c, (unsigned char *) (lc->str), lc->str_len);
MD5Final(signature, &md5c);
for (i = j = 0; i < sizeof(signature); i++) {
- sprintf(&sig[j], "%02x", signature[i]);
+ sprintf(&sig[j], "%02x", signature[i]);
j += 2;
}
*(item->value) = bstrdup(sig);
if (pass == 2) {
res = GetResWithName(item->code, lc->str);
if (res == NULL) {
- scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
+ scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
lc->str, lc->line_no, lc->line);
}
if (*(item->value)) {
- scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
+ scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
item->name, lc->line_no, lc->line);
}
*(item->value) = (char *)res;
}
/*
- * Store a resource in an alist. default_value indicates how many
+ * Store a resource pointer in an alist. default_value indicates how many
* times this routine can be called -- i.e. how many alists
* there are.
* If we are in pass 2, do a lookup of the
alist *list;
if (pass == 2) {
- /* Find empty place to store this directive */
- while ((item->value)[i] != NULL && i++ < count) { }
- if (i >= count) {
- scan_err3(lc, _("Too many Storage directives. Max. is %d. line %d: %s\n"),
- count, lc->line_no, lc->line);
+ if (count == 0) { /* always store in item->value */
+ i = 0;
+ if ((item->value)[i] == NULL) {
+ list = New(alist(10, not_owned_by_alist));
+ } else {
+ list = (alist *)(item->value)[i];
+ }
+ } else {
+ /* Find empty place to store this directive */
+ while ((item->value)[i] != NULL && i++ < count) { }
+ if (i >= count) {
+ scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
+ lc->str, count, lc->line_no, lc->line);
+ }
+ list = New(alist(10, not_owned_by_alist));
}
- list = New(alist(10, not_owned_by_alist));
for (;;) {
lex_get_token(lc, T_NAME); /* scan next item */
res = GetResWithName(item->code, lc->str);
if (res == NULL) {
- scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
- lc->str, lc->line_no, lc->line);
+ scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
+ item->name, lc->line_no, lc->line);
}
+ Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n",
+ res, list, list->size(), i, item->name);
list->append(res);
(item->value)[i] = (char *)list;
- if (lc->ch != ',') { /* if no other item follows */
+ if (lc->ch != ',') { /* if no other item follows */
break; /* get out */
}
lex_get_token(lc, T_ALL); /* eat comma */
Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str);
res = GetResWithName(item->code, lc->str);
if (res == NULL) {
- scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
+ scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
lc->str, lc->line_no, lc->line);
}
/* for each item not set, we copy the field from res */
#ifdef xxx
for (int i=0; item->name;; i++, item++) {
if (bit_is_set(i, res->item_present)) {
- Dmsg2(900, "Item %d is present in %s\n", i, res->name);
+ Dmsg2(900, "Item %d is present in %s\n", i, res->name);
} else {
- Dmsg2(900, "Item %d is not present in %s\n", i, res->name);
+ Dmsg2(900, "Item %d is not present in %s\n", i, res->name);
}
}
/* ***FIXME **** add code */
case T_IDENTIFIER:
case T_UNQUOTED_STRING:
if (!size_to_uint64(lc->str, lc->str_len, &uvalue)) {
- scan_err1(lc, _("expected a size number, got: %s"), lc->str);
+ scan_err1(lc, _("expected a size number, got: %s"), lc->str);
}
*(uint64_t *)(item->value) = uvalue;
break;
}
}
if (!duration_to_utime(period, &utime)) {
- scan_err1(lc, _("expected a time period, got: %s"), period);
+ scan_err1(lc, _("expected a time period, got: %s"), period);
}
*(utime_t *)(item->value) = utime;
break;
{
int errstat;
#ifdef TRACE_RES
- Dmsg4(000, "LockRes %d,%d at %s:%d\n", res_locked, res_lock.w_active,
+ Pmsg4(000, "LockRes %d,%d at %s:%d\n", res_locked, res_lock.w_active,
file, line);
#endif
if ((errstat=rwl_writelock(&res_lock)) != 0) {
int errstat;
res_locked--;
#ifdef TRACE_RES
- Dmsg4(000, "UnLockRes %d,%d at %s:%d\n", res_locked, res_lock.w_active,
+ Pmsg4(000, "UnLockRes %d,%d at %s:%d\n", res_locked, res_lock.w_active,
file, line);
#endif
if ((errstat=rwl_writeunlock(&res_lock)) != 0) {
return 0;
}
while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
- Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token));
+ Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token));
switch (state) {
case p_none:
if (token == T_EOL) {
break;
}
if (token != T_IDENTIFIER) {
- scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
+ scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str);
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
break;
}
if (state == p_none) {
- scan_err1(lc, _("expected resource name, got: %s"), lc->str);
+ scan_err1(lc, _("expected resource name, got: %s"), lc->str);
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
break;
case T_IDENTIFIER:
if (level != 1) {
- scan_err1(lc, _("not in resource definition: %s"), lc->str);
+ scan_err1(lc, _("not in resource definition: %s"), lc->str);
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
* scan for = after the keyword */
if (!(items[i].flags & ITEM_NO_EQUALS)) {
token = lex_get_token(lc, T_SKIP_EOL);
- Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
+ Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
if (token != T_EQUALS) {
- scan_err1(lc, _("expected an equals, got: %s"), lc->str);
+ scan_err1(lc, _("expected an equals, got: %s"), lc->str);
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
}
- Dmsg1(900, "calling handler for %s\n", items[i].name);
+ Dmsg1(900, "calling handler for %s\n", items[i].name);
/* Call item handler */
items[i].handler(lc, &items[i], i, pass);
i = -1;
}
}
if (i >= 0) {
- Dmsg2(900, "level=%d id=%s\n", level, lc->str);
- Dmsg1(900, "Keyword = %s\n", lc->str);
- scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
- "Perhaps you left the trailing brace off of the previous resource."), lc->str);
+ Dmsg2(900, "level=%d id=%s\n", level, lc->str);
+ Dmsg1(900, "Keyword = %s\n", lc->str);
+ scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n"
+ "Perhaps you left the trailing brace off of the previous resource."), lc->str);
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
case T_EOB:
level--;
state = p_none;
- Dmsg0(900, "T_EOB => define new resource\n");
+ Dmsg0(900, "T_EOB => define new resource\n");
save_resource(res_type, items, pass); /* save resource */
break;
break;
default:
- scan_err2(lc, _("unexpected token %d %s in resource definition"),
+ scan_err2(lc, _("unexpected token %d %s in resource definition"),
token, lex_tok_to_str(token));
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
break;
default:
- scan_err1(lc, _("Unknown parser state %d\n"), state);
+ scan_err1(lc, _("Unknown parser state %d\n"), state);
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
}
if (state != p_none) {
- scan_err0(lc, _("End of conf file reached with unclosed resource."));
+ scan_err0(lc, _("End of conf file reached with unclosed resource."));
set_exit_on_error(1); /* Never reached if exit_on_error == 1 */
return 0;
}
* Version $Id$
*/
/*
- Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need);
BSOCK * bnet_connect (JCR *jcr, int retry_interval,
- int max_retry_time, const char *name, char *host, char *service,
- int port, int verbose);
+ int max_retry_time, const char *name, char *host, char *service,
+ int port, int verbose);
void bnet_close (BSOCK *bsock);
BSOCK * init_bsock (JCR *jcr, int sockfd, const char *who, const char *ip,
- int port, struct sockaddr *client_addr);
+ int port, struct sockaddr *client_addr);
BSOCK * dup_bsock (BSOCK *bsock);
void term_bsock (BSOCK *bsock);
const char *bnet_strerror (BSOCK *bsock);
int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need);
int cram_md5_auth(BSOCK *bs, char *password, int ssl_need);
void hmac_md5(uint8_t* text, int text_len, uint8_t* key,
- int key_len, uint8_t *hmac);
+ int key_len, uint8_t *hmac);
/* crc32.c */
char * edit_uint64_with_commas (uint64_t val, char *buf);
char * add_commas (char *val, char *buf);
char * edit_uint64 (uint64_t val, char *buf);
+char * edit_int64 (int64_t val, char *buf);
int duration_to_utime (char *str, utime_t *value);
int size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
char *edit_utime (utime_t val, char *buf, int buf_len);
/* bnet_server.c */
void bnet_thread_server(dlist *addr, int max_clients, workq_t *client_wq,
- void *handle_client_request(void *bsock));
+ void *handle_client_request(void *bsock));
void bnet_stop_thread_server(pthread_t tid);
void bnet_server (int port, void handle_client_request(BSOCK *bsock));
int net_connect (int port);
int fstrsch (const char *a, const char *b);
char *next_arg(char **s);
int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
- char **argk, char **argv, int max_args);
+ char **argk, char **argv, int max_args);
void split_path_and_filename(const char *fname, POOLMEM **path,
- int *pnl, POOLMEM **file, int *fnl);
+ int *pnl, POOLMEM **file, int *fnl);
int bsscanf(const char *buf, const char *fmt, ...);
for (p=*s; *p && B_ISSPACE(*p); ) {
p++;
}
- Dmsg1(400, "Next arg=%s\n", p);
+ Dmsg1(900, "Next arg=%s\n", p);
for (n = q = p; *p ; ) {
if (*p == '\\') {
p++;
}
*q = 0;
*s = p;
- Dmsg2(400, "End arg=%s next=%s\n", n, p);
+ Dmsg2(900, "End arg=%s next=%s\n", n, p);
return n;
}
if (p) {
*p++ = 0; /* terminate keyword and point to value */
/* Unquote quoted values */
- if (*p == '"') {
- for (n = q = ++p; *p && *p != '"'; ) {
- if (*p == '\\') {
+ if (*p == '"') {
+ for (n = q = ++p; *p && *p != '"'; ) {
+ if (*p == '\\') {
p++;
}
*q++ = *p++;
// Dmsg1(000, "Got %% nxt=%c\n", *fmt);
switch_top:
switch (*fmt++) {
- case 'u':
- case 'd':
+ case 'u':
+ case 'd':
value = 0;
while (B_ISDIGIT(*buf)) {
- value = B_TIMES10(value) + *buf++ - '0';
+ value = B_TIMES10(value) + *buf++ - '0';
}
vp = (void *)va_arg(ap, void *);
// Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp);
count++;
l = 0;
break;
- case 'l':
+ case 'l':
// Dmsg0(000, "got l\n");
l = 1;
- if (*fmt == 'l') {
+ if (*fmt == 'l') {
l++;
fmt++;
}
- if (*fmt == 'd' || *fmt == 'u') {
+ if (*fmt == 'd' || *fmt == 'u') {
goto switch_top;
}
// Dmsg1(000, "fmt=%c !=d,u\n", *fmt);
error = true;
break;
- case 'q':
+ case 'q':
l = 2;
- if (*fmt == 'd' || *fmt == 'u') {
+ if (*fmt == 'd' || *fmt == 'u') {
goto switch_top;
}
// Dmsg1(000, "fmt=%c !=d,u\n", *fmt);
error = true;
break;
- case 's':
+ case 's':
// Dmsg1(000, "Store string max_len=%d\n", max_len);
cp = (char *)va_arg(ap, char *);
while (*buf && !B_ISSPACE(*buf) && max_len-- > 0) {
count++;
max_len = BIG;
break;
- case 'c':
+ case 'c':
cp = (char *)va_arg(ap, char *);
*cp = *buf++;
count++;
break;
- case '%':
- if (*buf++ != '%') {
+ case '%':
+ if (*buf++ != '%') {
error = true;
}
break;
fmt--;
max_len = 0;
while (B_ISDIGIT(*fmt)) {
- max_len = B_TIMES10(max_len) + *fmt++ - '0';
+ max_len = B_TIMES10(max_len) + *fmt++ - '0';
}
// Dmsg1(000, "Default max_len=%d\n", max_len);
- if (*fmt == 's') {
+ if (*fmt == 's') {
goto switch_top;
}
// Dmsg1(000, "Default c=%c\n", *fmt);
if (wd_is_init) {
return 0;
}
- Dmsg0(400, "Initialising NicB-hacked watchdog thread\n");
+ Dmsg0(800, "Initialising NicB-hacked watchdog thread\n");
watchdog_time = time(NULL);
if ((errstat=rwl_init(&lock)) != 0) {
wd_lock();
wd->next_fire = watchdog_time + wd->interval;
wd_queue->append(wd);
- Dmsg3(400, "Registered watchdog %p, interval %d%s\n",
- wd, wd->interval, wd->one_shot ? " one shot" : "");
+ Dmsg3(800, "Registered watchdog %p, interval %d%s\n",
+ wd, wd->interval, wd->one_shot ? " one shot" : "");
wd_unlock();
ping_watchdog();
foreach_dlist(p, wd_queue) {
if (wd == p) {
wd_queue->remove(wd);
- Dmsg1(400, "Unregistered watchdog %p\n", wd);
+ Dmsg1(800, "Unregistered watchdog %p\n", wd);
ok = true;
goto get_out;
}
foreach_dlist(p, wd_inactive) {
if (wd == p) {
wd_inactive->remove(wd);
- Dmsg1(400, "Unregistered inactive watchdog %p\n", wd);
+ Dmsg1(800, "Unregistered inactive watchdog %p\n", wd);
ok = true;
goto get_out;
}
}
- Dmsg1(400, "Failed to unregister watchdog %p\n", wd);
+ Dmsg1(800, "Failed to unregister watchdog %p\n", wd);
get_out:
wd_unlock();
struct timezone tz;
time_t next_time;
- Dmsg0(400, "NicB-reworked watchdog thread entered\n");
+ Dmsg0(800, "NicB-reworked watchdog thread entered\n");
while (!quit) {
watchdog_t *p;
/* Run the callback */
p->callback(p);
- /* Reschedule (or move to inactive list if it's a one-shot timer) */
+ /* Reschedule (or move to inactive list if it's a one-shot timer) */
if (p->one_shot) {
wd_queue->remove(p);
wd_inactive->append(p);
V(timer_mutex);
}
- Dmsg0(400, "NicB-reworked watchdog thread exited\n");
+ Dmsg0(800, "NicB-reworked watchdog thread exited\n");
return NULL;
}
workq_ele_t *item;
pthread_t id;
- Dmsg0(400, "workq_add\n");
+ Dmsg0(1400, "workq_add\n");
if (wq->valid != WORKQ_VALID) {
return EINVAL;
}
return stat;
}
- Dmsg0(400, "add item to queue\n");
+ Dmsg0(1400, "add item to queue\n");
if (priority) {
/* Add to head of queue */
if (wq->first == NULL) {
/* if any threads are idle, wake one */
if (wq->idle_workers > 0) {
- Dmsg0(400, "Signal worker\n");
+ Dmsg0(1400, "Signal worker\n");
if ((stat = pthread_cond_signal(&wq->work)) != 0) {
pthread_mutex_unlock(&wq->mutex);
return stat;
}
} else if (wq->num_workers < wq->max_workers) {
- Dmsg0(400, "Create worker thread\n");
+ Dmsg0(1400, "Create worker thread\n");
/* No idle threads so create a new one */
set_thread_concurrency(wq->max_workers + 1);
if ((stat = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) {
wq->num_workers++;
}
pthread_mutex_unlock(&wq->mutex);
- Dmsg0(400, "Return workq_add\n");
+ Dmsg0(1400, "Return workq_add\n");
/* Return work_item if requested */
if (work_item) {
*work_item = item;
pthread_t id;
workq_ele_t *item, *prev;
- Dmsg0(400, "workq_remove\n");
+ Dmsg0(1400, "workq_remove\n");
if (wq->valid != WORKQ_VALID) {
return EINVAL;
}
/* if any threads are idle, wake one */
if (wq->idle_workers > 0) {
- Dmsg0(400, "Signal worker\n");
+ Dmsg0(1400, "Signal worker\n");
if ((stat = pthread_cond_signal(&wq->work)) != 0) {
pthread_mutex_unlock(&wq->mutex);
return stat;
}
} else {
- Dmsg0(400, "Create worker thread\n");
+ Dmsg0(1400, "Create worker thread\n");
/* No idle threads so create a new one */
set_thread_concurrency(wq->max_workers + 1);
if ((stat = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) {
wq->num_workers++;
}
pthread_mutex_unlock(&wq->mutex);
- Dmsg0(400, "Return workq_remove\n");
+ Dmsg0(1400, "Return workq_remove\n");
return stat;
}
workq_ele_t *we;
int stat, timedout;
- Dmsg0(400, "Start workq_server\n");
+ Dmsg0(1400, "Start workq_server\n");
if ((stat = pthread_mutex_lock(&wq->mutex)) != 0) {
return NULL;
}
struct timeval tv;
struct timezone tz;
- Dmsg0(400, "Top of for loop\n");
+ Dmsg0(1400, "Top of for loop\n");
timedout = 0;
- Dmsg0(400, "gettimeofday()\n");
+ Dmsg0(1400, "gettimeofday()\n");
gettimeofday(&tv, &tz);
timeout.tv_nsec = 0;
timeout.tv_sec = tv.tv_sec + 2;
/*
* Wait 2 seconds, then if no more work, exit
*/
- Dmsg0(400, "pthread_cond_timedwait()\n");
+ Dmsg0(1400, "pthread_cond_timedwait()\n");
#ifdef xxxxxxxxxxxxxxxx_was_HAVE_CYGWIN
/* CYGWIN dies with a page fault the second
* time that pthread_cond_timedwait() is called
#else
stat = pthread_cond_timedwait(&wq->work, &wq->mutex, &timeout);
#endif
- Dmsg1(400, "timedwait=%d\n", stat);
+ Dmsg1(1400, "timedwait=%d\n", stat);
if (stat == ETIMEDOUT) {
timedout = 1;
break;
} else if (stat != 0) {
- /* This shouldn't happen */
- Dmsg0(400, "This shouldn't happen\n");
+ /* This shouldn't happen */
+ Dmsg0(1400, "This shouldn't happen\n");
wq->num_workers--;
pthread_mutex_unlock(&wq->mutex);
return NULL;
if ((stat = pthread_mutex_unlock(&wq->mutex)) != 0) {
return NULL;
}
- /* Call user's routine here */
- Dmsg0(400, "Calling user engine.\n");
+ /* Call user's routine here */
+ Dmsg0(1400, "Calling user engine.\n");
wq->engine(we->data);
- Dmsg0(400, "Back from user engine.\n");
+ Dmsg0(1400, "Back from user engine.\n");
free(we); /* release work entry */
- Dmsg0(400, "relock mutex\n");
+ Dmsg0(1400, "relock mutex\n");
if ((stat = pthread_mutex_lock(&wq->mutex)) != 0) {
return NULL;
}
- Dmsg0(400, "Done lock mutex\n");
+ Dmsg0(1400, "Done lock mutex\n");
}
/*
* If no more work request, and we are asked to quit, then do it
if (wq->first == NULL && wq->quit) {
wq->num_workers--;
if (wq->num_workers == 0) {
- Dmsg0(400, "Wake up destroy routine\n");
+ Dmsg0(1400, "Wake up destroy routine\n");
/* Wake up destroy routine if he is waiting */
pthread_cond_broadcast(&wq->work);
}
- Dmsg0(400, "Unlock mutex\n");
+ Dmsg0(1400, "Unlock mutex\n");
pthread_mutex_unlock(&wq->mutex);
- Dmsg0(400, "Return from workq_server\n");
+ Dmsg0(1400, "Return from workq_server\n");
return NULL;
}
- Dmsg0(400, "Check for work request\n");
+ Dmsg0(1400, "Check for work request\n");
/*
* If no more work requests, and we waited long enough, quit
*/
- Dmsg1(400, "wq->first==NULL = %d\n", wq->first==NULL);
- Dmsg1(400, "timedout=%d\n", timedout);
+ Dmsg1(1400, "wq->first==NULL = %d\n", wq->first==NULL);
+ Dmsg1(1400, "timedout=%d\n", timedout);
if (wq->first == NULL && timedout) {
- Dmsg0(400, "break big loop\n");
+ Dmsg0(1400, "break big loop\n");
wq->num_workers--;
break;
}
- Dmsg0(400, "Loop again\n");
+ Dmsg0(1400, "Loop again\n");
} /* end of big for loop */
- Dmsg0(400, "unlock mutex\n");
+ Dmsg0(1400, "unlock mutex\n");
pthread_mutex_unlock(&wq->mutex);
- Dmsg0(400, "End workq_server\n");
+ Dmsg0(1400, "End workq_server\n");
return NULL;
}
#include "bacula.h" /* pull in global headers */
#include "stored.h" /* pull in Storage Deamon headers */
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
+/*
+ * Create a new Device Control Record and attach
+ * it to the device (if this is a real job).
+ */
DCR *new_dcr(JCR *jcr, DEVICE *dev)
{
if (jcr && jcr->dcr) {
}
dcr->jcr = jcr;
dcr->dev = dev;
+ if (dev) {
+ dcr->device = dev->device;
+ }
dcr->block = new_block(dev);
dcr->rec = new_record();
dcr->spool_fd = -1;
JCR *jcr = dcr->jcr;
DEVICE *dev = dcr->dev;
+ /*
+ * If we reserved the device, we must decrement the
+ * number of writers.
+ */
+ if (dcr->reserved_device) {
+ lock_device(dev);
+ dev->num_writers--;
+ unlock_device(dev);
+ }
+
/* Detach this dcr only if the dev is initialized */
if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
dcr->dev->attached_dcrs->remove(dcr);
free(dcr);
}
+/*
+ * We "reserve" the drive by setting the ST_READ bit. No one else
+ * should touch the drive until that is cleared.
+ * This allows the DIR to "reserve" the device before actually
+ * starting the job. If the device is not available, the DIR
+ * can wait (to be implemented 1/05).
+ */
+bool reserve_device_for_read(JCR *jcr, DEVICE *dev)
+{
+ DCR *dcr = jcr->dcr;
+ bool ok = false;
+
+ ASSERT(dcr);
+ if (device_is_unmounted(dev)) {
+ Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
+ dev_name(dev));
+ return false;
+ }
+ lock_device(dev);
+ block_device(dev, BST_DOING_ACQUIRE);
+ unlock_device(dev);
+
+ if (dev->can_read() || dev->num_writers > 0) {
+ Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"),
+ dev_name(dev), jcr->JobId);
+ goto get_out;
+ }
+ if (!dcr) {
+ dcr = new_dcr(jcr, dev);
+ }
+ dev->state &= ~ST_APPEND; /* clear any previous append mode */
+ dev->state |= ST_READ; /* set read mode */
+ ok = true;
+
+get_out:
+ P(dev->mutex);
+ unblock_device(dev);
+ V(dev->mutex);
+ return ok;
+}
+
/*********************************************************************
- * Acquire device for reading. We permit (for the moment)
- * only one reader. We read the Volume label from the block and
+ * Acquire device for reading.
+ * The drive should have previously been reserved by calling
+ * reserve_device_for_read(). We read the Volume label from the block and
* leave the block pointers just after the label.
*
* Returns: NULL if failed for any reason
* dcr if successful
*/
-DCR *acquire_device_for_read(JCR *jcr)
+DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev)
{
bool vol_ok = false;
bool tape_previously_mounted;
bool try_autochanger = true;
int i;
DCR *dcr = jcr->dcr;
- DEVICE *dev;
int vol_label_status;
- /* Called for each volume */
- if (!dcr) {
- dcr = new_dcr(jcr, jcr->device->dev);
- }
- dev = dcr->dev;
- if (device_is_unmounted(dev)) {
- Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
- dev_name(dev));
- }
lock_device(dev);
block_device(dev, BST_DOING_ACQUIRE);
unlock_device(dev);
init_dev_wait_timers(dev);
- if (dev_state(dev, ST_READ) || dev->num_writers > 0) {
- Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"),
- dev_name(dev), jcr->JobId);
- goto get_out;
- }
- tape_previously_mounted = dev_state(dev, ST_READ) ||
- dev_state(dev, ST_APPEND) ||
- dev_state(dev, ST_LABEL);
+ tape_previously_mounted = dev->can_read() ||
+ dev->can_append() ||
+ dev->is_labeled();
tape_initially_mounted = tape_previously_mounted;
/* Find next Volume, if any */
Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
}
- dcr->dev->num_parts = dcr->VolCatInfo.VolCatParts;
+ dev->num_parts = dcr->VolCatInfo.VolCatParts;
for (i=0; i<5; i++) {
- dcr->dev->state &= ~ST_LABEL; /* force reread of label */
+ dev->state &= ~ST_LABEL; /* force reread of label */
if (job_canceled(jcr)) {
Mmsg1(dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
goto get_out; /* error return */
* reading. If it is a file, it opens it.
* If it is a tape, it checks the volume name
*/
- for ( ; !(dev->state & ST_OPENED); ) {
+ for ( ; !dev->is_open(); ) {
Dmsg1(120, "bstored: open vol=%s\n", dcr->VolumeName);
if (open_dev(dev, dcr->VolumeName, OPEN_READ_ONLY) < 0) {
if (dev->dev_errno == EIO) { /* no tape loaded */
goto default_path;
}
- /* If we have a device that requires mount,
+ /* If we have a dvd that requires mount,
* we need to try to open the label, so the info can be reported
* if a wrong volume has been mounted. */
- if (dev_cap(dev, CAP_REQMOUNT) && (dcr->VolCatInfo.VolCatParts > 0)) {
+ if (dev->is_dvd() && (dcr->VolCatInfo.VolCatParts > 0)) {
break;
}
Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
}
- if (dev_cap(dev, CAP_REQMOUNT)) {
+ if (dev->is_dvd()) {
vol_label_status = read_dev_volume_label_guess(dcr, 0);
- }
- else {
+ } else {
vol_label_status = read_dev_volume_label(dcr);
}
return dcr;
}
+/*
+ * We reserve the device for appending by incrementing the
+ * reserved_device. We do virtually all the same work that
+ * is done in acquire_device_for_append(), but we do
+ * not attempt to mount the device. This routine allows
+ * the DIR to reserve multiple devices before *really*
+ * starting the job. It also permits the SD to refuse
+ * certain devices (not up, ...).
+ */
+bool reserve_device_for_append(JCR *jcr, DEVICE *dev)
+{
+ DCR *dcr = jcr->dcr;
+ bool recycle;
+ bool ok = false;
+
+ ASSERT(dcr);
+
+ lock_device(dev);
+ block_device(dev, BST_DOING_ACQUIRE);
+ unlock_device(dev);
+ if (device_is_unmounted(dev)) {
+ Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
+ dev_name(dev));
+ goto get_out;
+ }
+ Dmsg1(190, "reserve_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
+ if (dev->can_append()) {
+ Dmsg0(190, "device already in append.\n");
+ /*
+ * Device already in append mode
+ *
+ * Check if we have the right Volume mounted
+ * OK if current volume info OK
+ * OK if next volume matches current volume
+ */
+ bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName));
+ if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
+ !(dir_find_next_appendable_volume(dcr) &&
+ strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
+ Dmsg0(190, "Wrong tape mounted.\n");
+ if (dev->num_writers != 0 || dev->reserved_device) {
+ Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
+ goto get_out;
+ }
+ } else {
+ /*
+ * At this point, the correct tape is already mounted, so
+ * we do not need to do mount_next_write_volume(), unless
+ * we need to recycle the tape.
+ */
+ recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
+ Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
+ if (recycle && dev->num_writers != 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
+ " because it is in use by another job.\n"));
+ goto get_out;
+ }
+ if (dev->num_writers == 0) {
+ memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+ }
+ }
+ } else {
+ if (dev->can_read()) {
+ Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
+ goto get_out;
+ }
+ ASSERT(dev->num_writers == 0);
+ }
+
+ dev->reserved_device++;
+ dcr->reserved_device = true;
+ ok = true;
+
+get_out:
+ P(dev->mutex);
+ unblock_device(dev);
+ V(dev->mutex);
+ return ok;
+}
+
/*
* Acquire device for writing. We permit multiple writers.
* If this is the first one, we read the label.
*
* Returns: NULL if failed for any reason
- * dev if successful (may change if new dev opened)
- * This routine must be single threaded because we may create
- * multiple devices (for files), thus we have our own mutex
- * on top of the device mutex.
+ * dcr if successful.
+ * Note, normally reserve_device_for_append() is called
+ * before this routine.
*/
-DCR *acquire_device_for_append(JCR *jcr)
+DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev)
{
bool release = false;
bool recycle = false;
bool do_mount = false;
- DCR *dcr;
- DEVICE *dev = jcr->device->dev;
+ DCR *dcr = jcr->dcr;
- dcr = new_dcr(jcr, dev);
- if (device_is_unmounted(dev)) {
- Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
- dev_name(dev));
+ if (!dcr) {
+ dcr = new_dcr(jcr, dev);
}
lock_device(dev);
block_device(dev, BST_DOING_ACQUIRE);
unlock_device(dev);
- P(mutex); /* lock all devices */
Dmsg1(190, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
- if (dev_state(dev, ST_APPEND)) {
+ if (dcr->reserved_device) {
+ dev->reserved_device--;
+ dcr->reserved_device = false;
+ }
+ if (dev->can_append()) {
Dmsg0(190, "device already in append.\n");
/*
* Device already in append mode
!(dir_find_next_appendable_volume(dcr) &&
strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
Dmsg0(190, "Wrong tape mounted.\n");
- if (dev->num_writers != 0) {
- DEVICE *d = ((DEVRES *)dev->device)->dev;
- uint32_t open_vols = 0;
- for ( ; d; d=d->next) {
- open_vols++;
- }
- if (dev_state(dev, ST_FILE) && dev->max_open_vols > open_vols) {
- d = init_dev(NULL, (DEVRES *)dev->device); /* init new device */
- d->prev = dev; /* chain in new device */
- d->next = dev->next;
- dev->next = d;
- /* Release old device */
- P(dev->mutex);
- unblock_device(dev);
- V(dev->mutex);
- free_dcr(dcr); /* release dcr pointing to old dev */
- /* Make new device current device and lock it */
- dev = d;
- dcr = new_dcr(jcr, dev); /* get new dcr for new device */
- lock_device(dev);
- block_device(dev, BST_DOING_ACQUIRE);
- unlock_device(dev);
- } else {
- Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
- goto get_out;
- }
+ if (dev->num_writers != 0 || dev->reserved_device) {
+ Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev_name(dev));
+ goto get_out;
}
/* Wrong tape mounted, release it, then fall through to get correct one */
Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
} else {
/* Not already in append mode, so mount the device */
Dmsg0(190, "Not in append mode, try mount.\n");
- if (dev_state(dev, ST_READ)) {
+ if (dev->can_read()) {
Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
goto get_out;
}
if (do_mount || recycle) {
Dmsg0(190, "Do mount_next_write_vol\n");
- V(mutex); /* don't lock everything during mount */
bool mounted = mount_next_write_volume(dcr, release);
- P(mutex); /* re-lock */
if (!mounted) {
if (!job_canceled(jcr)) {
/* Reduce "noise" -- don't print if job canceled */
if (jcr->NumVolumes == 0) {
jcr->NumVolumes = 1;
}
- set_jcr_job_status(jcr, JS_Running);
- dir_send_job_status(jcr);
goto ok_out;
/*
P(dev->mutex);
unblock_device(dev);
V(dev->mutex);
- V(mutex); /* unlock other threads */
return dcr;
}
} else if (dev->num_writers > 0) {
dev->num_writers--;
Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
- if (dev_state(dev, ST_LABEL)) {
+ if (dev->is_labeled()) {
Dmsg0(100, "dir_create_jobmedia_record. Release\n");
if (!dir_create_jobmedia_record(dcr)) {
Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
dir_update_volume_info(dcr, false); /* send Volume info to Director */
}
- if (!dev->num_writers && (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN))) {
+ if (!dev->num_writers && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
offline_or_rewind_dev(dev);
close_dev(dev);
}
}
/* Fire off Alert command and include any output */
- if (!job_canceled(jcr) && jcr->device->alert_command) {
+ if (!job_canceled(jcr) && dcr->device->alert_command) {
POOLMEM *alert;
int status = 1;
BPIPE *bpipe;
char line[MAXSTRING];
alert = get_pool_memory(PM_FNAME);
- alert = edit_device_codes(jcr, alert, jcr->device->alert_command, "");
+ alert = edit_device_codes(dcr, alert, "");
bpipe = open_bpipe(alert, 0, "r");
if (bpipe) {
while (fgets(line, sizeof(line), bpipe->rfd)) {
Dmsg1(400, "alert status=%d\n", status);
free_pool_memory(alert);
}
- if (dev->prev && !dev_state(dev, ST_READ) && !dev->num_writers) {
- P(mutex);
- unlock_device(dev);
- dev->prev->next = dev->next; /* dechain */
- term_dev(dev);
- V(mutex);
- } else {
- unlock_device(dev);
- }
+ unlock_device(dev);
free_dcr(jcr->dcr);
jcr->dcr = NULL;
return true;
BSOCK *ds;
BSOCK *fd_sock = jcr->file_bsock;
bool ok = true;
- DEVICE *dev;
DEV_RECORD rec;
- DCR *dcr;
+ DCR *dcr = jcr->dcr;
+ DEVICE *dev = dcr->dev;
+
Dmsg0(10, "Start append data.\n");
ds = fd_sock;
- if (!bnet_set_buffer_size(ds, jcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
+ if (!bnet_set_buffer_size(ds, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
Jmsg(jcr, M_FATAL, 0, _("Unable to set network buffer size.\n"));
return false;
}
- /*
- * Acquire output device for writing. Note, after acquiring a
- * device, we MUST release it, which is done at the end of this
- * subroutine.
- */
- Dmsg0(100, "just before acquire_device\n");
- if (!(dcr=acquire_device_for_append(jcr))) {
+ if (!acquire_device_for_append(jcr, dev)) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
return false;
}
- dev = dcr->dev;
+
memset(&rec, 0, sizeof(rec));
+ set_jcr_job_status(jcr, JS_Running);
+ dir_send_job_status(jcr);
+
if (dev->VolCatInfo.VolCatName[0] == 0) {
Dmsg0(000, "NULL Volume name. This shouldn't happen!!!\n");
}
commit_data_spool(jcr);
}
- /* If the device is nor a tape, nor a fifo, and WritePartAfterJob
+ /* If the device is nor a dvd and WritePartAfterJob
* is set to yes, open the next part, so, in case of a device
* that requires mount, it will be written to the device.
*/
- if (!(dcr->dev->state & (ST_TAPE|ST_FIFO)) && (jcr->write_part_after_job) && (dcr->dev->part_size > 0)) {
+ if (dev->is_dvd() && jcr->write_part_after_job && (dev->part_size > 0)) {
Dmsg0(100, "Writing last part because write_part_after_job is set.\n");
- if (dcr->dev->part < dcr->dev->num_parts) {
- Jmsg3(dcr->jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
+ if (dev->part < dev->num_parts) {
+ Jmsg3(jcr, M_FATAL, 0, _("Error while writing, current part number is less than the total number of parts (%d/%d, device=%s)\n"),
dev->part, dev->num_parts, dev_name(dev));
- dcr->dev->dev_errno = EIO;
+ dev->dev_errno = EIO;
ok = false;
}
- if (ok && (open_next_part(dcr->dev) < 0)) {
+ if (ok && (open_next_part(dev) < 0)) {
Jmsg2(jcr, M_FATAL, 0, _("Unable to open device next part %s. ERR=%s\n"),
- dev_name(dcr->dev), strerror_dev(dcr->dev));
- dcr->dev->dev_errno = EIO;
+ dev_name(dev), strerror_dev(dev));
+ dev->dev_errno = EIO;
ok = false;
}
- dcr->dev->VolCatInfo.VolCatParts = dcr->dev->num_parts;
+ dev->VolCatInfo.VolCatParts = dev->num_parts;
}
Dmsg1(200, "calling release device JobStatus=%d\n", jcr->JobStatus);
" FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u"
" StartBlock=%u EndBlock=%u\n";
static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
-static char Job_status[] = "3012 Job %s jobstatus %d\n";
+static char Job_status[] = "Status Job=%s JobStatus=%d\n";
/* Responses received from the Director */
" VolBlocks=%u VolBytes=%" lld " VolMounts=%u VolErrors=%u VolWrites=%u"
" MaxVolBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s"
" Slot=%d MaxVolJobs=%u MaxVolFiles=%u InChanger=%d"
- " VolReadTime=%" lld " VolWriteTime=%" lld " EndFile=%u EndBlock=%u VolParts=%u";
+ " VolReadTime=%" lld " VolWriteTime=%" lld " EndFile=%u EndBlock=%u"
+ " VolParts=%u LabelType=%d";
static char OK_create[] = "1000 OK CreateJobMedia\n";
&vol.VolCatCapacityBytes, vol.VolCatStatus,
&vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
&InChanger, &vol.VolReadTime, &vol.VolWriteTime,
- &vol.EndFile, &vol.EndBlock, &vol.VolCatParts);
- if (n != 20) {
+ &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
+ &vol.LabelType);
+ if (n != 21) {
Dmsg2(100, "Bad response from Dir fields=%d: %s\n", n, dir->msg);
Mmsg(jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg);
return false;
char ed1[50], ed2[50], ed3[50], ed4[50];
VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
int InChanger;
+ POOL_MEM VolumeName;
if (vol->VolCatName[0] == 0) {
Jmsg0(jcr, M_FATAL, 0, _("NULL Volume name. This shouldn't happen!!!\n"));
Dmsg0(000, "NULL Volume name. This shouldn't happen!!!\n");
return false;
}
- if (dev_state(dev, ST_READ)) {
+ if (dev->can_read()) {
Jmsg0(jcr, M_FATAL, 0, _("Attempt to update_volume_info in read mode!!!\n"));
Dmsg0(000, "Attempt to update_volume_info in read mode!!!\n");
return false;
bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
vol->VolCatBytes = 1; /* indicates tape labeled */
}
- bash_spaces(vol->VolCatName);
+ pm_strcpy(VolumeName, vol->VolCatName);
+ bash_spaces(VolumeName);
InChanger = vol->InChanger;
bnet_fsend(dir, Update_media, jcr->Job,
- vol->VolCatName, vol->VolCatJobs, vol->VolCatFiles,
+ VolumeName.c_str(), vol->VolCatJobs, vol->VolCatFiles,
vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1),
vol->VolCatMounts, vol->VolCatErrors,
vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
InChanger, /* bool in structure */
edit_uint64(vol->VolReadTime, ed3),
edit_uint64(vol->VolWriteTime, ed4),
- vol->VolCatParts );
+ vol->VolCatParts);
Dmsg1(300, "update_volume_info(): %s", dir->msg);
- unbash_spaces(vol->VolCatName);
if (!do_get_volume_info(dcr)) {
Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
- Dmsg1(000, "Didn't get vol info: %s", jcr->errmsg);
+ Dmsg2(000, "Didn't get vol info vol=%s: ERR=%s",
+ vol->VolCatName, jcr->errmsg);
return false;
}
Dmsg1(420, "get_volume_info(): %s", dir->msg);
#include "stored.h" /* pull in Storage Deamon headers */
/* Forward referenced functions */
-char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd);
-static int get_autochanger_loaded_slot(JCR *jcr);
+char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
+static int get_autochanger_loaded_slot(DCR *dcr);
/*
JCR *jcr = dcr->jcr;
DEVICE *dev = dcr->dev;
int slot;
- int drive = jcr->device->drive_index;
+ int drive = dev->device->drive_index;
int rtn_stat = -1; /* error status */
slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
}
Dmsg1(400, "Want changer slot=%d\n", slot);
- if (slot > 0 && jcr->device->changer_name && jcr->device->changer_command) {
- uint32_t timeout = jcr->device->max_changer_wait;
+ if (slot > 0 && dcr->device->changer_name && dcr->device->changer_command) {
+ uint32_t timeout = dcr->device->max_changer_wait;
POOLMEM *changer;
int loaded, status;
changer = get_pool_memory(PM_FNAME);
- loaded = get_autochanger_loaded_slot(jcr);
+ loaded = get_autochanger_loaded_slot(dcr);
/* If tape we want is not loaded, load it. */
if (loaded != slot) {
/* We are going to load a new tape, so close the device */
force_close_dev(dev);
if (loaded != 0 && loaded != -1) { /* must unload drive */
- Dmsg0(400, "Doing changer unload.\n");
+ Dmsg0(400, "Doing changer unload.\n");
Jmsg(jcr, M_INFO, 0,
- _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
+ _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
loaded, drive);
dcr->VolCatInfo.Slot = loaded; /* slot to be unloaded */
- changer = edit_device_codes(jcr, changer,
- jcr->device->changer_command, "unload");
+ changer = edit_device_codes(dcr, changer, "unload");
status = run_program(changer, timeout, NULL);
if (status != 0) {
berrno be;
be.set_errno(status);
- Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
slot, drive, be.strerror());
}
- Dmsg1(400, "unload status=%d\n", status);
+ Dmsg1(400, "unload status=%d\n", status);
}
/*
* Load the desired cassette
*/
- Dmsg1(400, "Doing changer load slot %d\n", slot);
+ Dmsg1(400, "Doing changer load slot %d\n", slot);
Jmsg(jcr, M_INFO, 0,
- _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"),
+ _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"),
slot, drive);
dcr->VolCatInfo.Slot = slot; /* slot to be loaded */
- changer = edit_device_codes(jcr, changer,
- jcr->device->changer_command, "load");
+ changer = edit_device_codes(dcr, changer, "load");
status = run_program(changer, timeout, NULL);
if (status == 0) {
- Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"),
slot, drive);
} else {
berrno be;
be.set_errno(status);
- Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n"),
slot, drive, be.strerror());
}
- Dmsg2(400, "load slot %d status=%d\n", slot, status);
+ Dmsg2(400, "load slot %d status=%d\n", slot, status);
} else {
status = 0; /* we got what we want */
}
return rtn_stat;
}
-static int get_autochanger_loaded_slot(JCR *jcr)
+static int get_autochanger_loaded_slot(DCR *dcr)
{
+ JCR *jcr = dcr->jcr;
POOLMEM *changer, *results;
int status, loaded;
- uint32_t timeout = jcr->device->max_changer_wait;
- int drive = jcr->device->drive_index;
+ uint32_t timeout = dcr->device->max_changer_wait;
+ int drive = dcr->device->drive_index;
results = get_pool_memory(PM_MESSAGE);
changer = get_pool_memory(PM_FNAME);
/* Find out what is loaded, zero means device is unloaded */
Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded drive %d\" command.\n"),
drive);
- changer = edit_device_codes(jcr, changer, jcr->device->changer_command,
- "loaded");
+ changer = edit_device_codes(dcr, changer, "loaded");
status = run_program(changer, timeout, results);
Dmsg3(50, "run_prog: %s stat=%d result=%s\n", changer, status, results);
if (status == 0) {
{
DEVICE *dev = dcr->dev;
JCR *jcr = dcr->jcr;
- uint32_t timeout = jcr->device->max_changer_wait;
+ uint32_t timeout = dcr->device->max_changer_wait;
POOLMEM *changer;
BPIPE *bpipe;
int slot, loaded;
int len = sizeof_pool_memory(dir->msg) - 1;
- if (!dev_cap(dev, CAP_AUTOCHANGER) || !jcr->device->changer_name ||
- !jcr->device->changer_command) {
+ if (!dev_cap(dev, CAP_AUTOCHANGER) || !dcr->device->changer_name ||
+ !dcr->device->changer_command) {
bnet_fsend(dir, _("3993 Not a autochanger device.\n"));
return false;
}
force_close_dev(dev);
/* First unload any tape */
- loaded = get_autochanger_loaded_slot(jcr);
+ loaded = get_autochanger_loaded_slot(dcr);
if (loaded > 0) {
bnet_fsend(dir, _("3305 Issuing autochanger \"unload slot %d\" command.\n"), loaded);
slot = dcr->VolCatInfo.Slot;
dcr->VolCatInfo.Slot = loaded;
- changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload");
+ changer = edit_device_codes(dcr, changer, "unload");
int stat = run_program(changer, timeout, NULL);
if (stat != 0) {
berrno be;
be.set_errno(stat);
- Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d\" command: ERR=%s.\n"),
+ Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d\" command: ERR=%s.\n"),
loaded, be.strerror());
}
dcr->VolCatInfo.Slot = slot;
}
/* Now list slots occupied */
- changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "list");
+ changer = edit_device_codes(dcr, changer, "list");
bnet_fsend(dir, _("3306 Issuing autochanger \"list\" command.\n"));
bpipe = open_bpipe(changer, timeout, "r");
if (!bpipe) {
* cmd = command string (load, unload, ...)
*
*/
-char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd)
+char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd)
{
const char *p;
const char *str;
char add[20];
+ const char *imsg = dcr->device->changer_command;
*omsg = 0;
Dmsg1(800, "edit_device_codes: %s\n", imsg);
for (p=imsg; *p; p++) {
if (*p == '%') {
switch (*++p) {
- case '%':
- str = "%";
+ case '%':
+ str = "%";
break;
- case 'a':
- str = dev_name(jcr->device->dev);
+ case 'a':
+ str = dev_name(dcr->dev);
break;
- case 'c':
- str = NPRT(jcr->device->changer_name);
+ case 'c':
+ str = NPRT(dcr->device->changer_name);
break;
- case 'd':
- sprintf(add, "%d", jcr->device->dev->drive_index);
+ case 'd':
+ sprintf(add, "%d", dcr->dev->drive_index);
str = add;
break;
- case 'o':
+ case 'o':
str = NPRT(cmd);
break;
- case 's':
- sprintf(add, "%d", jcr->dcr->VolCatInfo.Slot - 1);
+ case 's':
+ sprintf(add, "%d", dcr->VolCatInfo.Slot - 1);
str = add;
break;
- case 'S':
- sprintf(add, "%d", jcr->dcr->VolCatInfo.Slot);
+ case 'S':
+ sprintf(add, "%d", dcr->VolCatInfo.Slot);
str = add;
break;
- case 'j': /* Job name */
- str = jcr->Job;
+ case 'j': /* Job name */
+ str = dcr->jcr->Job;
break;
- case 'v':
- str = NPRT(jcr->dcr->VolumeName);
+ case 'v':
+ str = NPRT(dcr->VolumeName);
break;
- case 'f':
- str = NPRT(jcr->client_name);
+ case 'f':
+ str = NPRT(dcr->jcr->client_name);
break;
default:
- add[0] = '%';
+ add[0] = '%';
add[1] = *p;
add[2] = 0;
str = add;
exit(1);
}
unlock_device(out_dev);
- if (!acquire_device_for_append(out_jcr)) {
+ if (!acquire_device_for_append(out_jcr, out_dev)) {
free_jcr(in_jcr);
exit(1);
}
}
switch (rec->FileIndex) {
case PRE_LABEL:
- Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n");
+ Pmsg0(000, "Volume is prelabeled. This volume cannot be copied.\n");
return false;
case VOL_LABEL:
- Pmsg0(000, "Volume label not copied.\n");
+ Pmsg0(000, "Volume label not copied.\n");
return true;
case SOS_LABEL:
jobs++;
break;
case EOS_LABEL:
while (!write_record_to_block(out_block, rec)) {
- Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
+ Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
rec->remainder);
if (!write_block_to_device(out_jcr->dcr)) {
- Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+ Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
dev_name(out_dev), strerror_dev(out_dev));
- Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+ Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
strerror_dev(out_dev));
}
}
if (!write_block_to_device(out_jcr->dcr)) {
- Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+ Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
dev_name(out_dev), strerror_dev(out_dev));
- Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+ Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
strerror_dev(out_dev));
}
break;
case EOM_LABEL:
- Pmsg0(000, "EOM label not copied.\n");
+ Pmsg0(000, "EOM label not copied.\n");
return true;
case EOT_LABEL: /* end of all tapes */
- Pmsg0(000, "EOT label not copied.\n");
+ Pmsg0(000, "EOT label not copied.\n");
return true;
default:
break;
Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len,
rec->remainder);
if (!write_block_to_device(out_jcr->dcr)) {
- Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
+ Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
dev_name(out_dev), strerror_dev(out_dev));
- Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+ Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
strerror_dev(out_dev));
break;
}
*
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
static void usage()
{
fprintf(stderr,
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
"\nVersion: " VERSION " (" BDATE ")\n\n"
"Usage: bextract <options> <bacula-archive-device-name> <directory-to-store-files>\n"
" -b <file> specify a bootstrap file\n"
break;
case 'e': /* exclude list */
- if ((fd = fopen(optarg, "r")) == NULL) {
+ if ((fd = fopen(optarg, "r")) == NULL) {
berrno be;
- Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n",
+ Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n",
optarg, be.strerror());
exit(1);
}
while (fgets(line, sizeof(line), fd) != NULL) {
strip_trailing_junk(line);
- Dmsg1(900, "add_exclude %s\n", line);
+ Dmsg1(900, "add_exclude %s\n", line);
add_fname_to_exclude_list(ff, line);
}
fclose(fd);
break;
case 'i': /* include list */
- if ((fd = fopen(optarg, "r")) == NULL) {
+ if ((fd = fopen(optarg, "r")) == NULL) {
berrno be;
- Pmsg2(0, "Could not open include file: %s, ERR=%s\n",
+ Pmsg2(0, "Could not open include file: %s, ERR=%s\n",
optarg, be.strerror());
exit(1);
}
while (fgets(line, sizeof(line), fd) != NULL) {
strip_trailing_junk(line);
- Dmsg1(900, "add_include %s\n", line);
+ Dmsg1(900, "add_include %s\n", line);
add_fname_to_include_list(ff, 0, line);
}
fclose(fd);
*/
if (extract) {
if (!is_bopen(&bfd)) {
- Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
+ Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
}
set_attributes(jcr, attr, &bfd);
extract = false;
}
if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) {
- Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
+ Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
}
if (attr->file_index != rec->FileIndex) {
- Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"),
+ Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"),
rec->FileIndex, attr->file_index);
}
attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
if (!is_stream_supported(attr->data_stream)) {
if (!non_support_data++) {
- Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
+ Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
stream_to_ascii(attr->data_stream));
}
extract = false;
fileAddr = faddr;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
berrno be;
- Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
+ Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
attr->ofname, be.strerror());
}
}
wsize = rec->data_len;
}
total += wsize;
- Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
+ Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
berrno be;
- Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
+ Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
attr->ofname, be.strerror());
}
fileAddr += wsize;
fileAddr = faddr;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
berrno be;
- Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
+ Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
extract = false;
return true;
compress_len = compress_buf_size;
if ((stat=uncompress((Bytef *)compress_buf, &compress_len,
(const Bytef *)wbuf, (uLong)wsize) != Z_OK)) {
- Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
+ Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
extract = false;
return true;
}
- Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
+ Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
if ((uLongf)bwrite(&bfd, compress_buf, (size_t)compress_len) != compress_len) {
berrno be;
- Pmsg0(0, "===Write error===\n");
- Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"),
+ Pmsg0(0, "===Write error===\n");
+ Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"),
attr->ofname, be.strerror());
extract = false;
return true;
}
total += compress_len;
fileAddr += compress_len;
- Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
+ Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
compress_len);
}
#else
if (extract) {
- Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n");
+ Emsg0(M_ERROR, 0, "GZIP data stream found, but GZIP not configured!\n");
extract = false;
return true;
}
case STREAM_PROGRAM_NAMES:
case STREAM_PROGRAM_DATA:
if (!prog_name_msg) {
- Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
+ Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n");
prog_name_msg++;
}
break;
/* If extracting, wierd stream (not 1 or 2), close output file anyway */
if (extract) {
if (!is_bopen(&bfd)) {
- Emsg0(M_ERROR, 0, "Logic error output file should be open but is not.\n");
+ Emsg0(M_ERROR, 0, "Logic error output file should be open but is not.\n");
}
set_attributes(jcr, attr, &bfd);
extract = false;
block_len-BLKHDR_CS_LENGTH);
if (BlockCheckSum != CheckSum) {
dev->dev_errno = EIO;
- Mmsg5(dev->errmsg, _("Volume data error at %u:%u! Block checksum mismatch in block %u: calc=%x blk=%x\n"),
- dev->file, dev->block_num, (unsigned)BlockNumber, BlockCheckSum, CheckSum);
+ Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n"
+ "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"),
+ dev->file, dev->block_num, (unsigned)BlockNumber,
+ block_len, BlockCheckSum, CheckSum);
if (block->read_errors == 0 || verbose >= 2) {
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
}
}
if (dev->free_space_errno < 0) { /* Error while getting free space */
- char ed1[50];
- char ed2[50];
+ char ed1[50], ed2[50];
Dmsg1(10, "Cannot get free space on the device ERR=%s.\n", dev->errmsg);
Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
dev->VolCatInfo.VolCatName,
}
if (((dev->free_space_errno > 0) && ((dev->part_size + block->binbuf) >= dev->free_space))) {
- char ed1[50];
- char ed2[50];
+ char ed1[50], ed2[50];
Dmsg0(10, "==== Just enough free space on the device to write the current part...\n");
Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d).\n"),
dev->VolCatInfo.VolCatName,
}
dev->VolCatInfo.VolCatFiles = dev->file;
- if (dev_cap(dev, CAP_REQMOUNT)) { /* Write the current (and last) part. */
+ if (dev->is_dvd()) { /* Write the current (and last) part. */
open_next_part(dev);
}
return false;
}
- /*Dmsg1(200, "dev.c 111->file_size=%u\n",(unsigned int)dev->file_size);
- Dmsg1(200, "dev.c lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR));
- Dmsg1(200, "dev.c dev->part_start=%u\n",(unsigned int)dev->part_start);
- Dmsg1(200, "dev.c dev->file_size-dev->part_start=%u\n",(unsigned int)dev->file_size-dev->part_start);
- Dmsg1(200, "dev.c dev->part_size=%u\n", (unsigned int)dev->part_size);
- Dmsg1(200, "dev.c dev->part=%u\n", (unsigned int)dev->part);
- Dmsg1(200, "dev.c dev->VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts);
- Dmsg3(200, "dev.c Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), ((dev->file_size-dev->part_start) == dev->part_size), (dev->part <= dev->VolCatInfo.VolCatParts));*/
+ /*Dmsg1(200, "dev->file_size=%u\n",(unsigned int)dev->file_size);
+ Dmsg1(200, "lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR));
+ Dmsg1(200, "dev->part_start=%u\n",(unsigned int)dev->part_start);
+ Dmsg1(200, "dev->file_size-dev->part_start=%u\n",(unsigned int)dev->file_size-dev->part_start);
+ Dmsg1(200, "dev->part_size=%u\n", (unsigned int)dev->part_size);
+ Dmsg1(200, "dev->part=%u\n", (unsigned int)dev->part);
+ Dmsg1(200, "dev->VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts);
+ Dmsg3(200, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), ((dev->file_size-dev->part_start) == dev->part_size), (dev->part <= dev->VolCatInfo.VolCatParts));*/
/* Check for part file end */
if ((dev->num_parts > 0) &&
((dev->file_size-dev->part_start) == dev->part_size) &&
Mmsg4(dev->errmsg, _("Read error at file:blk %u:%u on device %s. ERR=%s.\n"),
dev->file, dev->block_num, dev->dev_name, be.strerror());
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
- if (dev->state & ST_EOF) { /* EOF just seen? */
+ if (dev->at_eof()) { /* EOF just seen? */
dev->state |= ST_EOT; /* yes, error => EOT */
}
return false;
}
- Dmsg1(200, "Read device got %d bytes\n", stat);
+ Dmsg3(200, "Read device got %d bytes at %u:%u\n", stat,
+ dev->file, dev->block_num);
if (stat == 0) { /* Got EOF ! */
dev->block_num = block->read_len = 0;
Mmsg3(dev->errmsg, _("Read zero bytes at %u:%u on device %s.\n"),
dev->file, dev->block_num, dev->dev_name);
- if (dev->state & ST_EOF) { /* EOF already read? */
+ if (dev->at_eof()) { /* EOF already read? */
dev->state |= ST_EOT; /* yes, 2 EOFs => EOT */
block->read_len = 0;
return 0;
* absolute positioning -- so much for efficiency. KES Sep 02.
*/
Dmsg0(200, "At end of read block\n");
- if (block->read_len > block->block_len && !(dev->state & ST_TAPE)) {
+ if (block->read_len > block->block_len && !dev->is_tape()) {
+ char ed1[50];
off_t pos = lseek_dev(dev, (off_t)0, SEEK_CUR); /* get curr pos */
pos -= (block->read_len - block->block_len);
lseek_dev(dev, pos, SEEK_SET);
- Dmsg2(200, "Did lseek blk_size=%d rdlen=%d\n", block->block_len,
+ Dmsg3(200, "Did lseek pos=%s blk_size=%d rdlen=%d\n",
+ edit_uint64(pos, ed1), block->block_len,
block->read_len);
dev->file_addr = pos;
dev->file_size = pos;
uint32_t VolSessionTime;
*/
+class DEVICE; /* for forward reference */
+
/*
* DEV_BLOCK for reading and writing blocks.
* This is the basic unit that is written to the device, and
*/
struct DEV_BLOCK {
DEV_BLOCK *next; /* pointer to next one */
- void *dev; /* pointer to device (DEVICE not defined yet) */
+ DEVICE *dev; /* pointer to device */
/* binbuf is the number of bytes remaining in the buffer.
* For writes, it is bytes not yet written.
* For reads, it is remaining bytes not yet read.
* Version $Id$
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
static void usage()
{
fprintf(stderr,
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
"\nVersion: " VERSION " (" BDATE ")\n\n"
-"Usage: bls [-d debug_level] <physical-device-name>\n"
+"Usage: bls [options] <device-name>\n"
" -b <file> specify a bootstrap file\n"
" -c <file> specify a config file\n"
" -d <level> specify debug level\n"
/* List just block information */
static void do_blocks(char *infname)
{
- if (verbose) {
- dump_volume_label(dev);
- rec = new_record();
- }
for ( ;; ) {
if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
- Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
- if (dev->state & ST_EOT) {
+ Dmsg1(100, "!read_block(): ERR=%s\n", dev->strerror());
+ if (dev->at_eom()) {
if (!mount_next_read_volume(dcr)) {
Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"),
dev->file, dev_name(dev), dcr->VolumeName);
get_session_record(dev, record, &sessrec);
free_record(record);
Jmsg(jcr, M_INFO, 0, _("Mounted Volume \"%s\".\n"), dcr->VolumeName);
-
- } else if (dev->state & ST_EOF) {
+ } else if (dev->at_eof()) {
Jmsg(jcr, M_INFO, 0, _("Got EOF at file %u on device %s, Volume \"%s\"\n"),
dev->file, dev_name(dev), dcr->VolumeName);
Dmsg0(20, "read_record got eof. try again\n");
if (rec->Stream == STREAM_UNIX_ATTRIBUTES ||
rec->Stream == STREAM_UNIX_ATTRIBUTES_EX) {
- if (verbose > 1) {
- const char *rtype = "Attributes";
- Pmsg5(-1, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
- rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
- }
if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) {
if (!forge_on) {
Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
build_attr_output_fnames(jcr, attr);
if (file_is_included(&ff, attr->fname) && !file_is_excluded(&ff, attr->fname)) {
+ if (verbose) {
+ Pmsg5(-1, "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n",
+ rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+ }
print_ls_output(jcr, attr);
num_files++;
}
*
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
struct VOL_LIST {
VOL_LIST *next;
char VolumeName[MAX_NAME_LENGTH];
+ char MediaType[MAX_NAME_LENGTH];
int Slot;
uint32_t start_file;
};
struct BSR_VOLUME {
BSR_VOLUME *next;
char VolumeName[MAX_NAME_LENGTH];
+ char MediaType[MAX_NAME_LENGTH];
};
struct BSR_CLIENT {
block = new_block(dev);
lock_device(dev);
- if (!(dev->state & ST_OPENED)) {
+ if (!dev->is_open()) {
Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
- Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
+ Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
unlock_device(dev);
free_block(block);
return false;
}
}
- if (!(dev->state & ST_OPENED)) {
+ if (!dev->is_open()) {
if (!first_open_device(dev)) {
- Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
+ Pmsg1(0, "Device open failed. ERR=%s\n", strerror_dev(dev));
}
}
rewind_dev(dev);
printf("\n");
printf(_("Device status:\n"));
- printf("%sOPENED ", dev->state & ST_OPENED ? "" : "!");
- printf("%sTAPE ", dev->state & ST_TAPE ? "" : "!");
- printf("%sLABEL ", dev->state & ST_LABEL ? "" : "!");
+ printf("%sOPENED ", dev->is_open() ? "" : "!");
+ printf("%sTAPE ", dev->is_tape() ? "" : "!");
+ printf("%sLABEL ", dev->is_labeled() ? "" : "!");
printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
- printf("%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
- printf("%sREAD ", dev->state & ST_READ ? "" : "!");
- printf("%sEOT ", dev->state & ST_EOT ? "" : "!");
+ printf("%sAPPEND ", dev->can_append() ? "" : "!");
+ printf("%sREAD ", dev->can_read() ? "" : "!");
+ printf("%sEOT ", dev->at_eom() ? "" : "!");
printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!");
- printf("%sEOF ", dev->state & ST_EOF ? "" : "!");
+ printf("%sEOF ", dev->at_eof() ? "" : "!");
printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
printf("\n");
if (write_record_to_block(block, rec)) {
empty_block(block);
blkno++;
- Pmsg2(0, "Block %d i=%d\n", blkno, i);
+ Pmsg2(0, "Block %d i=%d\n", blkno, i);
} else {
break;
}
}
if (dev_cap(dev, CAP_TWOEOF)) {
if (!bsf_dev(dev, 1)) {
- Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
+ Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
goto bail_out;
}
}
}
for (int i=0; i<len; i++) {
if (rec->data[i] != 3) {
- Pmsg0(0, _("Bad data in record. Test failed!\n"));
+ Pmsg0(0, _("Bad data in record. Test failed!\n"));
goto bail_out;
}
}
free_record(rec);
if (stat == 0) {
Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
- "this function to verify the last block written to the\n"
- "tape. Bacula will skip the last block verification\n"
- "if you add:\n\n"
- "Backward Space Record = No\n\n"
- "to your Storage daemon's Device resource definition.\n"));
+ "this function to verify the last block written to the\n"
+ "tape. Bacula will skip the last block verification\n"
+ "if you add:\n\n"
+ "Backward Space Record = No\n\n"
+ "to your Storage daemon's Device resource definition.\n"));
}
return stat;
}
*p++ = i;
}
if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
+ Pmsg0(0, _("Error writing record to block.\n"));
goto bail_out;
}
if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
+ Pmsg0(0, _("Error writing block to device.\n"));
goto bail_out;
}
}
*p++ = i;
}
if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
+ Pmsg0(0, _("Error writing record to block.\n"));
goto bail_out;
}
if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
+ Pmsg0(0, _("Error writing block to device.\n"));
goto bail_out;
}
}
if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
berrno be;
if (dev_state(dev, ST_EOF)) {
- Pmsg0(-1, _("Got EOF on tape.\n"));
+ Pmsg0(-1, _("Got EOF on tape.\n"));
if (i == 1001) {
goto read_again;
}
}
- Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.strerror(dev->dev_errno));
+ Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.strerror(dev->dev_errno));
goto bail_out;
}
memset(rec->data, 0, rec->data_len);
if (!read_record_from_block(block, rec)) {
berrno be;
- Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.strerror(dev->dev_errno));
+ Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.strerror(dev->dev_errno));
goto bail_out;
}
p = (int *)rec->data;
for (j=0; j<len; j++) {
if (*p != i) {
- Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
+ Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
i, *p, j);
goto bail_out;
}
p++;
}
if (i == 1000 || i == 2000) {
- Pmsg0(-1, _("1000 blocks re-read correctly.\n"));
+ Pmsg0(-1, _("1000 blocks re-read correctly.\n"));
}
}
Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
*p++ = i;
}
if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
+ Pmsg0(0, _("Error writing record to block.\n"));
goto bail_out;
}
if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
+ Pmsg0(0, _("Error writing block to device.\n"));
goto bail_out;
}
}
*p++ = i;
}
if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
+ Pmsg0(0, _("Error writing record to block.\n"));
goto bail_out;
}
if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
+ Pmsg0(0, _("Error writing block to device.\n"));
goto bail_out;
}
}
}
Pmsg2(-1, "Reposition to file:block %d:%d\n", file, blk);
if (!reposition_dev(dev, file, blk)) {
- Pmsg0(0, "Reposition error.\n");
+ Pmsg0(0, "Reposition error.\n");
goto bail_out;
}
read_again:
if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
berrno be;
if (dev_state(dev, ST_EOF)) {
- Pmsg0(-1, _("Got EOF on tape.\n"));
+ Pmsg0(-1, _("Got EOF on tape.\n"));
if (!got_eof) {
got_eof = true;
goto read_again;
}
}
- Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
+ Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
recno, file, blk, be.strerror(dev->dev_errno));
- Pmsg0(0, _("This may be because the tape drive block size is not\n"
- " set to variable blocking as normally used by Bacula.\n"
- " Please see the Tape Testing chapter in the manual and \n"
- " look for using mt with defblksize and setoptions\n"
- "If your tape drive block size is correct, then perhaps\n"
- " your SCSI driver is *really* stupid and does not\n"
- " correctly report the file:block after a FSF. In this\n"
- " case try setting:\n"
- " Fast Forward Space File = no\n"
- " in your Device resource.\n"));
+ Pmsg0(0, _("This may be because the tape drive block size is not\n"
+ " set to variable blocking as normally used by Bacula.\n"
+ " Please see the Tape Testing chapter in the manual and \n"
+ " look for using mt with defblksize and setoptions\n"
+ "If your tape drive block size is correct, then perhaps\n"
+ " your SCSI driver is *really* stupid and does not\n"
+ " correctly report the file:block after a FSF. In this\n"
+ " case try setting:\n"
+ " Fast Forward Space File = no\n"
+ " in your Device resource.\n"));
goto bail_out;
}
memset(rec->data, 0, rec->data_len);
if (!read_record_from_block(block, rec)) {
berrno be;
- Pmsg1(0, _("Read record failed! ERR=%s\n"), be.strerror(dev->dev_errno));
+ Pmsg1(0, _("Read record failed! ERR=%s\n"), be.strerror(dev->dev_errno));
goto bail_out;
}
p = (int *)rec->data;
for (j=0; j<len; j++) {
if (p[j] != recno) {
- Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
+ Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
recno, p[j], j);
goto bail_out;
}
static int append_test()
{
Pmsg0(-1, _("\n\n=== Append files test ===\n\n"
- "This test is essential to Bacula.\n\n"
+ "This test is essential to Bacula.\n\n"
"I'm going to write one record in file 0,\n"
" two records in file 1,\n"
" and three records in file 2\n\n"));
{
POOLMEM *results, *changer;
int slot, status, loaded;
- int timeout = jcr->device->max_changer_wait;
+ int timeout = dcr->device->max_changer_wait;
int sleep_time = 0;
Dmsg1(100, "Max changer wait = %d sec\n", timeout);
if (!dev_cap(dev, CAP_AUTOCHANGER)) {
return 1;
}
- if (!(jcr->device && jcr->device->changer_name && jcr->device->changer_command)) {
+ if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) {
Pmsg0(-1, "\nAutochanger enabled, but no name or no command device specified.\n");
return 1;
}
Pmsg0(-1, "\nAh, I see you have an autochanger configured.\n"
- "To test the autochanger you must have a blank tape\n"
- " that I can write on in Slot 1.\n");
+ "To test the autochanger you must have a blank tape\n"
+ " that I can write on in Slot 1.\n");
if (!get_cmd("\nDo you wish to continue with the Autochanger test? (y/n): ")) {
return 0;
}
dcr->VolCatInfo.Slot = slot;
/* Find out what is loaded, zero means device is unloaded */
Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
- changer = edit_device_codes(jcr, changer, jcr->device->changer_command,
- "loaded");
+ changer = edit_device_codes(dcr, changer, "loaded");
status = run_program(changer, timeout, results);
Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results);
if (status == 0) {
force_close_dev(dev);
Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
loaded, dev->drive_index);
- changer = edit_device_codes(jcr, changer,
- jcr->device->changer_command, "unload");
+ changer = edit_device_codes(dcr, changer, "unload");
status = run_program(changer, timeout, results);
Pmsg2(-1, "unload status=%s %d\n", status==0?"OK":"Bad", status);
if (status != 0) {
berrno be;
- Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
- Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.strerror(status));
+ Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer);
+ Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.strerror(status));
}
}
dcr->VolCatInfo.Slot = slot;
Pmsg2(-1, _("3303 Issuing autochanger \"load slot %d %d\" command.\n"),
slot, dev->drive_index);
- changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "load");
+ changer = edit_device_codes(dcr, changer, "load");
Dmsg1(100, "Changer=%s\n", changer);
force_close_dev(dev);
status = run_program(changer, timeout, results);
Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
clrerror_dev(dev, -1);
Pmsg0(-1, "\nThe test failed, probably because you need to put\n"
- "a longer sleep time in the mtx-script in the load) case.\n"
- "Adding a 30 second sleep and trying again ...\n");
+ "a longer sleep time in the mtx-script in the load) case.\n"
+ "Adding a 30 second sleep and trying again ...\n");
sleep_time += 30;
goto try_again;
} else {
if (sleep_time) {
Pmsg1(-1, "\nThe test worked this time. Please add:\n\n"
- " sleep %d\n\n"
- "to your mtx-changer script in the load) case.\n\n",
+ " sleep %d\n\n"
+ "to your mtx-changer script in the load) case.\n\n",
sleep_time);
} else {
Pmsg0(-1, "\nThe test autochanger worked!!\n\n");
bool set_off = false;
Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
- "This test is essential to Bacula.\n\n"
- "I'm going to write five files then test forward spacing\n\n"));
+ "This test is essential to Bacula.\n\n"
+ "I'm going to write five files then test forward spacing\n\n"));
argc = 1;
rewindcmd();
wrcmd();
}
if (set_off) {
Pmsg0(-1, "The test worked this time. Please add:\n\n"
- " Fast Forward Space File = no\n\n"
- "to your Device resource for this drive.\n");
+ " Fast Forward Space File = no\n\n"
+ "to your Device resource for this drive.\n");
}
Pmsg0(-1, "\n");
Pmsg0(-1, _("\nThe forward space file test failed.\n"));
if (dev_cap(dev, CAP_FASTFSF)) {
Pmsg0(-1, "You have Fast Forward Space File enabled.\n"
- "I am turning it off then retrying the test.\n");
+ "I am turning it off then retrying the test.\n");
dev->capabilities &= ~CAP_FASTFSF;
set_off = true;
goto test_again;
}
Pmsg0(-1, "You must correct this error or Bacula will not work.\n"
- "Some systems, e.g. OpenBSD, require you to set\n"
- " Use MTIOCGET= no\n"
- "in your device resource. Use with caution.\n");
+ "Some systems, e.g. OpenBSD, require you to set\n"
+ " Use MTIOCGET= no\n"
+ "in your device resource. Use with caution.\n");
return -2;
}
}
if (stat == -1) { /* first test failed */
if (dev_cap(dev, CAP_EOM) || dev_cap(dev, CAP_FASTFSF)) {
- Pmsg0(-1, "\nAppend test failed. Attempting again.\n"
- "Setting \"Hardware End of Medium = no\n"
- " and \"Fast Forward Space File = no\n"
- "and retrying append test.\n\n");
+ Pmsg0(-1, "\nAppend test failed. Attempting again.\n"
+ "Setting \"Hardware End of Medium = no\n"
+ " and \"Fast Forward Space File = no\n"
+ "and retrying append test.\n\n");
dev->capabilities &= ~CAP_EOM; /* turn off eom */
dev->capabilities &= ~CAP_FASTFSF; /* turn off fast fsf */
stat = append_test();
if (stat == 1) {
- Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
- " Hardware End of Medium = No\n\n"
- " Fast Forward Space File = No\n"
- "to your Device resource in the Storage conf file.\n");
+ Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
+ " Hardware End of Medium = No\n\n"
+ " Fast Forward Space File = No\n"
+ "to your Device resource in the Storage conf file.\n");
goto all_done;
}
if (stat == -1) {
- Pmsg0(-1, "\n\nThat appears *NOT* to have corrected the problem.\n");
+ Pmsg0(-1, "\n\nThat appears *NOT* to have corrected the problem.\n");
goto failed;
}
/* Wrong count after append */
if (stat == -2) {
- Pmsg0(-1, "\n\nIt looks like the append failed. Attempting again.\n"
- "Setting \"BSF at EOM = yes\" and retrying append test.\n");
+ Pmsg0(-1, "\n\nIt looks like the append failed. Attempting again.\n"
+ "Setting \"BSF at EOM = yes\" and retrying append test.\n");
dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
stat = append_test();
if (stat == 1) {
- Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
- " Hardware End of Medium = No\n"
- " Fast Forward Space File = No\n"
- " BSF at EOM = yes\n\n"
- "to your Device resource in the Storage conf file.\n");
+ Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
+ " Hardware End of Medium = No\n"
+ " Fast Forward Space File = No\n"
+ " BSF at EOM = yes\n\n"
+ "to your Device resource in the Storage conf file.\n");
goto all_done;
}
}
failed:
Pmsg0(-1, "\nAppend test failed.\n\n");
Pmsg0(-1, "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
- "Unable to correct the problem. You MUST fix this\n"
- "problem before Bacula can use your tape drive correctly\n");
+ "Unable to correct the problem. You MUST fix this\n"
+ "problem before Bacula can use your tape drive correctly\n");
Pmsg0(-1, "\nPerhaps running Bacula in fixed block mode will work.\n"
- "Do so by setting:\n\n"
- "Minimum Block Size = nnn\n"
- "Maximum Block Size = nnn\n\n"
- "in your Storage daemon's Device definition.\n"
- "nnn must match your tape driver's block size, which\n"
- "can be determined by reading your tape manufacturers\n"
- "information, and the information on your kernel dirver.\n"
- "Fixed block sizes, however, are not normally an ideal solution.\n"
- "\n"
- "Some systems, e.g. OpenBSD, require you to set\n"
- " Use MTIOCGET= no\n"
- "in your device resource. Use with caution.\n");
+ "Do so by setting:\n\n"
+ "Minimum Block Size = nnn\n"
+ "Maximum Block Size = nnn\n\n"
+ "in your Storage daemon's Device definition.\n"
+ "nnn must match your tape driver's block size, which\n"
+ "can be determined by reading your tape manufacturers\n"
+ "information, and the information on your kernel dirver.\n"
+ "Fixed block sizes, however, are not normally an ideal solution.\n"
+ "\n"
+ "Some systems, e.g. OpenBSD, require you to set\n"
+ " Use MTIOCGET= no\n"
+ "in your device resource. Use with caution.\n");
return;
}
all_done:
Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
- "Please double check it ...\n"
- "=== Sample correct output ===\n"
- "1 block of 64448 bytes in file 1\n"
- "End of File mark.\n"
- "2 blocks of 64448 bytes in file 2\n"
- "End of File mark.\n"
- "3 blocks of 64448 bytes in file 3\n"
- "End of File mark.\n"
- "1 block of 64448 bytes in file 4\n"
- "End of File mark.\n"
- "Total files=4, blocks=7, bytes = 451,136\n"
- "=== End sample correct output ===\n\n"));
+ "Please double check it ...\n"
+ "=== Sample correct output ===\n"
+ "1 block of 64448 bytes in file 1\n"
+ "End of File mark.\n"
+ "2 blocks of 64448 bytes in file 2\n"
+ "End of File mark.\n"
+ "3 blocks of 64448 bytes in file 3\n"
+ "End of File mark.\n"
+ "1 block of 64448 bytes in file 4\n"
+ "End of File mark.\n"
+ "Total files=4, blocks=7, bytes = 451,136\n"
+ "=== End sample correct output ===\n\n"));
Pmsg0(-1, _("If the above scan output is not identical to the\n"
- "sample output, you MUST correct the problem\n"
- "or Bacula will not be able to write multiple Jobs to \n"
- "the tape.\n\n"));
+ "sample output, you MUST correct the problem\n"
+ "or Bacula will not be able to write multiple Jobs to \n"
+ "the tape.\n\n"));
if (stat == 1) {
re_read_block_test();
if ((stat = read(dev->fd, buf, sizeof(buf))) < 0) {
berrno be;
clrerror_dev(dev, -1);
- Mmsg2(dev->errmsg, "read error on %s. ERR=%s.\n",
+ Mmsg2(dev->errmsg, "read error on %s. ERR=%s.\n",
dev->dev_name, be.strerror());
- Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
+ Pmsg2(0, "Bad status from read %d. ERR=%s\n", stat, strerror_dev(dev));
if (blocks > 0)
- printf("%d block%s of %d bytes in file %d\n",
- blocks, blocks>1?"s":"", block_size, dev->file);
+ printf("%d block%s of %d bytes in file %d\n",
+ blocks, blocks>1?"s":"", block_size, dev->file);
return;
}
Dmsg1(200, "read status = %d\n", stat);
if (stat != block_size) {
update_pos_dev(dev);
if (blocks > 0) {
- printf("%d block%s of %d bytes in file %d\n",
- blocks, blocks>1?"s":"", block_size, dev->file);
+ printf("%d block%s of %d bytes in file %d\n",
+ blocks, blocks>1?"s":"", block_size, dev->file);
blocks = 0;
}
block_size = stat;
}
if (stat == 0) { /* EOF */
update_pos_dev(dev);
- printf("End of File mark.\n");
+ printf("End of File mark.\n");
/* Two reads of zero means end of tape */
if (dev->state & ST_EOF)
dev->state |= ST_EOT;
dev->file++;
}
if (dev->state & ST_EOT) {
- printf("End of tape\n");
+ printf("End of tape\n");
break;
}
} else { /* Got data */
tot_files = dev->file;
for (;;) {
if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
- Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
+ Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
if (dev->state & ST_EOT) {
if (blocks > 0) {
- printf("%d block%s of %d bytes in file %d\n",
- blocks, blocks>1?"s":"", block_size, dev->file);
+ printf("%d block%s of %d bytes in file %d\n",
+ blocks, blocks>1?"s":"", block_size, dev->file);
blocks = 0;
}
goto bail_out;
}
if (dev->state & ST_EOF) {
if (blocks > 0) {
- printf("%d block%s of %d bytes in file %d\n",
- blocks, blocks>1?"s":"", block_size, dev->file);
+ printf("%d block%s of %d bytes in file %d\n",
+ blocks, blocks>1?"s":"", block_size, dev->file);
blocks = 0;
}
- printf(_("End of File mark.\n"));
+ printf(_("End of File mark.\n"));
continue;
}
if (dev->state & ST_SHORT) {
if (blocks > 0) {
- printf("%d block%s of %d bytes in file %d\n",
- blocks, blocks>1?"s":"", block_size, dev->file);
+ printf("%d block%s of %d bytes in file %d\n",
+ blocks, blocks>1?"s":"", block_size, dev->file);
blocks = 0;
}
- printf(_("Short block read.\n"));
+ printf(_("Short block read.\n"));
continue;
}
- printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
+ printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
goto bail_out;
}
if (block->block_len != block_size) {
if (blocks > 0) {
- printf("%d block%s of %d bytes in file %d\n",
- blocks, blocks>1?"s":"", block_size, dev->file);
+ printf("%d block%s of %d bytes in file %d\n",
+ blocks, blocks>1?"s":"", block_size, dev->file);
blocks = 0;
}
block_size = block->block_len;
if (verbose == 1) {
DEV_RECORD *rec = new_record();
read_record_from_block(block, rec);
- Pmsg8(-1, "Blk_block: %u dev_blk=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
+ Pmsg8(-1, "Blk_block: %u dev_blk=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
block->BlockNumber, dev->block_num, block->block_len,
FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
rec->remainder = 0;
free_record(rec);
} else if (verbose > 1) {
- dump_block(block, "");
+ dump_block(block, "");
}
}
"This may take a long time -- hours! ...\n\n");
get_cmd("Do you want to run the simplified test (s) with one tape\n"
- "or the complete multiple tape (m) test: (s/m) ");
+ "or the complete multiple tape (m) test: (s/m) ");
if (cmd[0] == 's') {
Pmsg0(-1, "Simple test (single tape) selected.\n");
simple = true;
* subroutine.
*/
Dmsg0(100, "just before acquire_device\n");
- if (!acquire_device_for_append(jcr)) {
+ if (!acquire_device_for_append(jcr, dev)) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
return;
}
/*
* When we get here we have just filled a block
*/
- Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
+ Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
rec.remainder);
/* Write block to tape */
now = 1; /* prevent divide error */
}
kbs = (double)dev->VolCatInfo.VolCatBytes / (1000.0 * (double)now);
- Pmsg4(-1, "Wrote blk_block=%u, dev_blk_num=%u VolBytes=%s rate=%.1f KB/s\n",
+ Pmsg4(-1, "Wrote blk_block=%u, dev_blk_num=%u VolBytes=%s rate=%.1f KB/s\n",
block->BlockNumber, dev->block_num,
edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
}
/* Every 15000 blocks (approx 1GB) write an EOF.
*/
if ((block->BlockNumber % 15000) == 0) {
- Pmsg0(-1, "Flush block, write EOF\n");
+ Pmsg0(-1, "Flush block, write EOF\n");
flush_block(block, 0);
weof_dev(dev, 1);
}
}
}
if (!ok) {
- Pmsg0(000, _("Not OK\n"));
+ Pmsg0(000, _("Not OK\n"));
break;
}
jcr->JobBytes += rec.data_len; /* increment bytes this job */
/* Get out after writing 10 blocks to the second tape */
if (BlockNumber > 10 && stop != 0) { /* get out */
- Pmsg0(-1, "Done writing ...\n");
+ Pmsg0(-1, "Done writing ...\n");
break;
}
}
set_jcr_job_status(jcr, JS_ErrorTerminated);
}
if (!write_session_label(dcr, EOS_LABEL)) {
- Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
+ Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
ok = false;
}
/* Write out final block of this session */
if (!write_block_to_device(dcr)) {
- Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
+ Pmsg0(-1, _("Set ok=false after write_block_to_device.\n"));
ok = false;
}
Pmsg0(-1, _("Wrote End of Session label.\n"));
read(fd, first_block->buf, first_block->buf_len);
close(fd);
if (state_level != btape_state_level) {
- Pmsg0(-1, "\nThe state file level has changed. You must redo\n"
- "the fill command.\n");
+ Pmsg0(-1, "\nThe state file level has changed. You must redo\n"
+ "the fill command.\n");
return;
}
} else {
berrno be;
Pmsg2(-1, "\nCould not find the state file: %s ERR=%s\n"
- "You must redo the fill command.\n", buf, be.strerror());
+ "You must redo the fill command.\n", buf, be.strerror());
return;
}
do_unfill();
autochanger = autoload_device(dcr, 1, NULL);
if (!autochanger) {
force_close_dev(dev);
- get_cmd(_("Mount first tape. Press enter when ready: "));
+ get_cmd(_("Mount first tape. Press enter when ready: "));
}
free_vol_list(jcr);
jcr->dcr = new_dcr(jcr, dev);
close_dev(dev);
dev->state &= ~(ST_READ|ST_APPEND);
dev->num_writers = 0;
- if (!acquire_device_for_read(jcr)) {
- Pmsg1(-1, "%s", dev->errmsg);
+ if (!acquire_device_for_read(jcr, dev)) {
+ Pmsg1(-1, "%s", dev->errmsg);
goto bail_out;
}
}
}
if (compare_blocks(last_block, block)) {
if (simple) {
- Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
+ Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n"));
} else {
- Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
+ Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n"));
}
}
if (simple) {
}
dev->state &= ~ST_READ;
- if (!acquire_device_for_read(jcr)) {
+ if (!acquire_device_for_read(jcr, dev)) {
Pmsg1(-1, "%s", dev->errmsg);
goto bail_out;
}
dump_block(block, _("Block read back"));
Pmsg1(-1, "\n\nThe blocks differ at byte %u\n", p - last_block->buf);
Pmsg0(-1, "\n\n!!!! The last block written and the block\n"
- "that was read back differ. The test FAILED !!!!\n"
- "This must be corrected before you use Bacula\n"
- "to write multi-tape Volumes.!!!!\n");
+ "that was read back differ. The test FAILED !!!!\n"
+ "This must be corrected before you use Bacula\n"
+ "to write multi-tape Volumes.!!!!\n");
return false;
}
if (verbose) {
first_block = dup_block(block); /* first block second tape */
}
if (verbose) {
- Pmsg3(000, "Block not written: FileIndex=%u blk_block=%u Size=%u\n",
+ Pmsg3(000, "Block not written: FileIndex=%u blk_block=%u Size=%u\n",
(unsigned)file_index, block->BlockNumber, block->block_len);
- dump_block(last_block, "Last block written");
- Pmsg0(-1, "\n");
- dump_block(block, "Block not written");
+ dump_block(last_block, "Last block written");
+ Pmsg0(-1, "\n");
+ dump_block(block, "Block not written");
}
if (stop == 0) {
eot_block = block->BlockNumber;
now = time(NULL);
now -= jcr->run_time;
if (now <= 0) {
- now = 1; /* don't divide by zero */
+ now = 1; /* don't divide by zero */
}
kbs = (double)dev->VolCatInfo.VolCatBytes / (1000 * now);
vol_size = dev->VolCatInfo.VolCatBytes;
} else {
/* Full test in progress */
if (!fixup_device_block_write_error(jcr->dcr)) {
- Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
+ Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
ok = false;
unlock_device(dev);
return 0;
Pmsg1(0, "Begin writing %d Bacula blocks to tape ...\n", count);
for (i=0; i < count; i++) {
if (i % 100 == 0) {
- printf("+");
+ printf("+");
fflush(stdout);
}
if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
+ Pmsg0(0, _("Error writing record to block.\n"));
goto bail_out;
}
if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
+ Pmsg0(0, _("Error writing block to device.\n"));
goto bail_out;
}
}
stat = write(dev->fd, block->buf, block->buf_len);
if (stat == (int)block->buf_len) {
if ((block_num++ % 100) == 0) {
- printf("+");
+ printf("+");
fflush(stdout);
}
p[0] += p[13];
break;
}
if ((block_num++ % 100) == 0) {
- printf("+");
+ printf("+");
fflush(stdout);
}
p[0] += p[13];
break;
}
if (!found)
- Pmsg1(0, _("%s is an illegal command\n"), cmd);
+ Pmsg1(0, _("%s is an illegal command\n"), cmd);
if (quit)
break;
}
create_vol_list(jcr);
close_dev(dev);
dev->state &= ~ST_READ;
- if (!acquire_device_for_read(jcr)) {
+ if (!acquire_device_for_read(jcr, dev)) {
Pmsg2(0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev), dcr->VolumeName);
return false;
}
if (!bsr && VolumeName) {
bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName));
}
- strcpy(dcr->pool_name, "Default");
- strcpy(dcr->pool_type, "Backup");
+ bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name));
+ bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type));
return jcr;
}
/* Try stripping file part */
p = dev_name + strlen(dev_name);
- while (p >= dev_name && *p != '/')
+ while (p >= dev_name && *p != '/')
p--;
- if (*p == '/') {
+ if (*p == '/') {
bstrncpy(VolName, p+1, sizeof(VolName));
*p = 0;
}
dev_name, configfile);
return NULL;
}
- jcr->device = device;
dev = init_dev(NULL, device);
if (!dev) {
create_vol_list(jcr);
if (mode) { /* read only access? */
- if (!acquire_device_for_read(jcr)) {
+ if (!acquire_device_for_read(jcr, dev)) {
return NULL;
}
}
if (!found) {
/* Search for name of Device resource rather than archive name */
if (device_name[0] == '"') {
- strcpy(device_name, device_name+1);
int len = strlen(device_name);
+ bstrncpy(device_name, device_name+1, len+1);
+ len--;
if (len > 0) {
- device_name[len-1] = 0; /* zap trailing " */
+ device_name[len-1] = 0; /* zap trailing " */
}
}
foreach_res(device, R_DEVICE) {
return NULL;
}
Pmsg2(0, _("Using device: \"%s\" for %s.\n"), device_name,
- read_access?"reading":"writing");
+ read_access?"reading":"writing");
return device;
}
int unmount_dev(DEVICE* dev, int timeout);
int write_part(DEVICE *dev);
char *edit_device_codes_dev(DEVICE* dev, char *omsg, const char *imsg);
-void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
-void update_free_space_dev(DEVICE* dev);
+static void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
+static void update_free_space_dev(DEVICE* dev);
/*
* Allocate and initialize the DEVICE structure
if (dev) {
dev->dev_errno = errno;
}
- Emsg2(M_FATAL, 0, "Unable to stat device %s : %s\n", device->device_name,
- be.strerror());
+ Jmsg2(NULL, M_FATAL, 0, _("Unable to stat device %s: ERR=%s\n"),
+ device->device_name, be.strerror());
return NULL;
}
- /* If the device requires mount :
- * - Check that the mount point is available
- * - Check that (un)mount commands are defined
- */
- if (device->cap_bits & CAP_REQMOUNT) {
- if (stat(device->mount_point, &statp) < 0) {
- berrno be;
- if (dev) {
- dev->dev_errno = errno;
- }
- Emsg2(M_FATAL, 0, "Unable to stat mount point %s : %s\n", device->mount_point,
- be.strerror());
- return NULL;
- }
- if (!device->mount_command || !device->unmount_command) {
- Emsg0(M_FATAL, 0, "Mount and unmount commands must defined for a device which requires mount.\n");
- return NULL;
- }
- if (!device->write_part_command) {
- Emsg0(M_FATAL, 0, "Write part command must be defined for a device which requires mount.\n");
- return NULL;
- }
- }
tape = false;
fifo = false;
/* Copy user supplied device parameters from Resource */
dev->dev_name = get_memory(strlen(device->device_name)+1);
- strcpy(dev->dev_name, device->device_name);
+ pm_strcpy(dev->dev_name, device->device_name);
dev->capabilities = device->cap_bits;
dev->min_block_size = device->min_block_size;
dev->max_block_size = device->max_block_size;
dev->state |= ST_FILE;
}
+ /* If the device requires mount :
+ * - Check that the mount point is available
+ * - Check that (un)mount commands are defined
+ */
+ if (dev->is_file() && device->cap_bits & CAP_REQMOUNT) {
+ if (stat(device->mount_point, &statp) < 0) {
+ berrno be;
+ dev->dev_errno = errno;
+ Jmsg2(NULL, M_FATAL, 0, _("Unable to stat mount point %s: ERR=%s\n"),
+ device->mount_point, be.strerror());
+ return NULL;
+ }
+ if (!device->mount_command || !device->unmount_command) {
+ Jmsg0(NULL, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
+ }
+ if (!device->write_part_command) {
+ Jmsg0(NULL, M_ERROR_TERM, 0, _("Write part command must be defined for a device which requires mount.\n"));
+ }
+ dev->state |= ST_DVD;
+ }
+
if (dev->max_block_size > 1000000) {
Emsg3(M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
berrno be;
dev->dev_errno = errstat;
Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
- Emsg0(M_FATAL, 0, dev->errmsg);
+ Emsg0(M_ERROR_TERM, 0, dev->errmsg);
}
if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
berrno be;
dev->dev_errno = errstat;
Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
- Emsg0(M_FATAL, 0, dev->errmsg);
+ Emsg0(M_ERROR_TERM, 0, dev->errmsg);
}
if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
berrno be;
dev->dev_errno = errstat;
Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
- Emsg0(M_FATAL, 0, dev->errmsg);
+ Emsg0(M_ERROR_TERM, 0, dev->errmsg);
}
if ((errstat = rwl_init(&dev->lock)) != 0) {
berrno be;
dev->dev_errno = errstat;
Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
- Emsg0(M_FATAL, 0, dev->errmsg);
+ Emsg0(M_ERROR_TERM, 0, dev->errmsg);
}
dev->fd = -1;
/*
* Write the current volume/part filename to archive_name.
*/
-
-void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name) {
+static void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name)
+{
char partnumber[20];
- if (dev_cap(dev, CAP_REQMOUNT)) {
+ if (dev->is_dvd()) {
/* If we try to open the last part, just open it from disk,
* otherwise, open it from the spooling directory */
if (dev->part < dev->num_parts) {
pm_strcpy(archive_name, dev->device->mount_point);
- }
- else {
+ } else {
/* Use the working directory if spool directory is not defined */
if (dev->device->spool_directory) {
pm_strcpy(archive_name, dev->device->spool_directory);
pm_strcpy(archive_name, working_directory);
}
}
- }
- else {
+ } else {
pm_strcpy(archive_name, dev->dev_name);
}
}
pm_strcat(archive_name, VolName);
/* if part != 0, append .# to the filename (where # is the part number) */
- if (dev->part != 0) {
+ if (dev->is_dvd() && dev->part != 0) {
pm_strcat(archive_name, ".");
bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part);
pm_strcat(archive_name, partnumber);
}
}
-/* Open the device with the operating system and
+/*
+ * Open the device with the operating system and
* initialize buffer pointers.
*
+ * Returns: -1 on error
+ * fd on success
+ *
* Note, for a tape, the VolName is the name we give to the
* volume (not really used here), but for a file, the
* VolName represents the name of the file to be created/opened.
int
open_dev(DEVICE *dev, char *VolName, int mode)
{
- if (dev->state & ST_OPENED) {
+ if (dev->is_open()) {
/*
* *****FIXME***** how to handle two threads wanting
* different volumes mounted???? E.g. one is waiting
Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev_is_tape(dev),
dev->dev_name, dev->VolCatInfo.VolCatName);
dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
- if (dev->state & (ST_TAPE|ST_FIFO)) {
+ if (dev->is_tape() || dev->is_fifo()) {
dev->file_size = 0;
int timeout;
Dmsg0(29, "open_dev: device is tape\n");
}
timeout = dev->max_open_wait;
errno = 0;
- if (dev->state & ST_FIFO && timeout) {
+ if (dev->is_fifo() && timeout) {
/* Set open timer */
dev->tid = start_thread_timer(pthread_self(), timeout);
}
}
get_filename(dev, VolName, archive_name);
- if (dev_cap(dev, CAP_REQMOUNT) && (dev->num_parts > 0)) {
+ if (dev->is_dvd()) {
if (mount_dev(dev, 1) < 0) {
- Mmsg(dev->errmsg, _("Could not mount device %s.\n"),
+ Mmsg(dev->errmsg, _("Could not mount archive device %s.\n"),
dev->dev_name);
Emsg0(M_FATAL, 0, dev->errmsg);
dev->fd = -1;
Dmsg2(29, "open_dev: device is disk %s (mode:%d)\n", archive_name.c_str(), mode);
dev->openmode = mode;
- /* If we are not trying to access the last part, set mode to OPEN_READ_ONLY,
- * as writing would be an error.
+ /*
+ * If we are not trying to access the last part, set mode to
+ * OPEN_READ_ONLY as writing would be an error.
*/
if (dev->part < dev->num_parts) {
mode = OPEN_READ_ONLY;
if (fstat(dev->fd, &filestat) < 0) {
berrno be;
dev->dev_errno = errno;
- Mmsg2(&dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), be.strerror());
+ Mmsg2(&dev->errmsg, _("Could not fstat: %s, ERR=%s\n"), archive_name.c_str(), be.strerror());
Emsg0(M_FATAL, 0, dev->errmsg);
- }
- else {
+ } else {
dev->part_size = filestat.st_size;
}
}
Dmsg4(29, "open_dev: disk fd=%d opened, part=%d/%d, part_size=%u\n", dev->fd, dev->part, dev->num_parts, dev->part_size);
- if ((dev->mode != OPEN_READ_ONLY) && ((dev->free_space_errno == 0) || (dev->num_parts == dev->part))) {
+ if (dev->is_dvd() && (dev->mode != OPEN_READ_ONLY) &&
+ ((dev->free_space_errno == 0) || (dev->num_parts == dev->part))) {
update_free_space_dev(dev);
}
}
* Note that if the right volume is mounted, open_guess_name_dev returns the same
* result as an usual open_dev.
*/
-int open_guess_name_dev(DEVICE *dev) {
+int open_guess_name_dev(DEVICE *dev)
+{
Dmsg1(29, "open_guess_name_dev: dev=%s\n", dev->dev_name);
POOL_MEM guessedname(PM_FNAME);
DIR* dp;
int index;
int name_max;
- if (!dev_cap(dev, CAP_REQMOUNT)) {
+ if (!dev->is_dvd()) {
Dmsg1(100, "open_guess_name_dev: device does not require mount, returning 0. dev=%s\n", dev->dev_name);
return 0;
}
if (dev->free_space_errno >= 0) {
Dmsg1(100, "open_guess_name_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
return 0;
- }
- else {
+ } else {
Dmsg1(100, "open_guess_name_dev: device cannot be mounted, and is not writable, returning 0. dev=%s\n", dev->dev_name);
/* read_dev_volume_label_guess must now check dev->free_space_errno to understand that the media is not writable. */
return 0;
* If timeout, wait until the mount command returns 0.
* If !timeout, try to mount the device only once.
*/
-int mount_dev(DEVICE* dev, int timeout) {
+int mount_dev(DEVICE* dev, int timeout)
+{
if (dev->state & ST_MOUNTED) {
Dmsg0(100, "mount_dev: Device already mounted\n");
return 0;
- }
- else {
+ } else {
return do_mount_dev(dev, 1, timeout);
}
}
* If timeout, wait until the unmount command returns 0.
* If !timeout, try to unmount the device only once.
*/
-int unmount_dev(DEVICE* dev, int timeout) {
+int unmount_dev(DEVICE* dev, int timeout)
+{
if (dev->state & ST_MOUNTED) {
return do_mount_dev(dev, 0, timeout);
- }
- else {
+ } else {
Dmsg0(100, "mount_dev: Device already unmounted\n");
return 0;
}
}
/* Update the free space on the device */
-void update_free_space_dev(DEVICE* dev) {
+static void update_free_space_dev(DEVICE* dev)
+{
POOL_MEM ocmd(PM_FNAME);
POOLMEM* results;
char* icmd;
int timeout;
- char* statstr;
long long int free;
icmd = dev->device->free_space_command;
timeout = 3;
while (1) {
+ char ed1[50];
if (run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results) == 0) {
Dmsg1(100, "Free space program run : %s\n", results);
- /* We also need negatives values, so we can't use dev->free_space, which is unsigned */
- free = strtoll(results, &statstr, 10);
- if (results != statstr) { /* Something parsed */
- if (free >= 0) {
- dev->free_space = free;
- dev->free_space_errno = 1;
- Mmsg0(dev->errmsg, "");
- break;
- }
- else {
- dev->free_space_errno = free;
- dev->free_space = 0;
- if (*statstr == '\n') {
- statstr++;
- }
- if (statstr[strlen(statstr)-1] == '\n') {
- statstr[strlen(statstr)-1] = 0;
- }
- Mmsg1(dev->errmsg, "Error while getting free space (%s)", statstr);
- }
- }
- else {
- dev->free_space = 0;
- dev->free_space_errno = -EPIPE;
- Mmsg1(dev->errmsg, "Error while getting free space (output=%s)", results);
+ free = str_to_int64(results);
+ if (free >= 0) {
+ dev->free_space = free;
+ dev->free_space_errno = 1;
+ Mmsg0(dev->errmsg, "");
+ break;
}
}
- else {
- dev->free_space = 0;
- dev->free_space_errno = -EPIPE;
- Mmsg1(dev->errmsg, "Cannot run free space command (%s)", results);
- }
+ dev->free_space = 0;
+ dev->free_space_errno = -EPIPE;
+ Mmsg1(dev->errmsg, "Cannot run free space command (%s)\n", results);
if (--timeout > 0) {
- Dmsg4(40, "Cannot get free space on device %s. free_space=%lld, free_space_errno=%d ERR=%s\n", dev->dev_name,
- dev->free_space, dev->free_space_errno, dev->errmsg);
+ Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
+ "free_space_errno=%d ERR=%s\n", dev->dev_name,
+ edit_uint64(dev->free_space, ed1), dev->free_space_errno,
+ dev->errmsg);
bmicrosleep(1, 0);
continue;
}
dev->dev_errno = -dev->free_space_errno;
- Dmsg4(40, "Cannot get free space on device %s. free_space=%lld, free_space_errno=%d ERR=%s\n",
- dev->dev_name, dev->free_space, dev->free_space_errno, dev->errmsg);
- free_pool_memory(results);
- return;
+ Dmsg4(40, "Cannot get free space on device %s. free_space=%s, "
+ "free_space_errno=%d ERR=%s\n",
+ dev->dev_name, edit_uint64(dev->free_space, ed1),
+ dev->free_space_errno, dev->errmsg);
+ break;
}
free_pool_memory(results);
-
Dmsg2(29, "update_free_space_dev: free_space=%lld, free_space_errno=%d\n", dev->free_space, dev->free_space_errno);
+ return;
}
-int write_part(DEVICE *dev) {
+int write_part(DEVICE *dev)
+{
Dmsg1(29, "write_part: device is %s\n", dev->dev_name);
if (unmount_dev(dev, 1) < 0) {
Dmsg3(29, "open_next_part %s %s %d\n", dev->dev_name, dev->VolCatInfo.VolCatName, dev->openmode);
/* When appending, do not open a new part if the current is empty */
- if ((dev->state & ST_APPEND) && (dev->part == dev->num_parts) && (dev->part_size == 0)) {
- Dmsg0(29, "open_next_part exited immediatly (dev->part_size == 0).\n");
+ if (dev->can_append() && (dev->part == dev->num_parts) &&
+ (dev->part_size == 0)) {
+ Dmsg0(29, "open_next_part exited immediately (dev->part_size == 0).\n");
return dev->fd;
}
state = dev->state;
dev->state &= ~ST_OPENED;
- if ((dev_cap(dev, CAP_REQMOUNT)) && (dev->part == dev->num_parts) && (dev->state & ST_APPEND)) {
+ if (dev->is_dvd() && (dev->part == dev->num_parts) && dev->can_append()) {
if (write_part(dev) < 0) {
return -1;
}
if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
return -1;
- }
- else {
+ } else {
dev->state = state;
return dev->fd;
}
if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode)) {
dev->state = state;
return dev->fd;
- }
- else {
+ } else {
return 0;
}
}
#endif
/* Protected version of lseek, which opens the right part if necessary */
-off_t lseek_dev(DEVICE *dev, off_t offset, int whence) {
+off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
+{
int pos, openmode;
if (dev->num_parts == 0) { /* If there is only one part, simply call lseek. */
}
switch(whence) {
- case SEEK_SET:
- Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
- if ((uint64_t)offset >= dev->part_start) {
- if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
- /* We are staying in the current part, just seek */
- if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
- return pos;
- }
- else {
- return pos + dev->part_start;
- }
- }
- else {
- /* Load next part, and start again */
- if (open_next_part(dev) < 0) {
- Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
- return -1;
- }
- return lseek_dev(dev, offset, SEEK_SET);
+ case SEEK_SET:
+ Dmsg1(100, "lseek_dev SEEK_SET called %d\n", offset);
+ if ((uint64_t)offset >= dev->part_start) {
+ if ((uint64_t)(offset - dev->part_start) < dev->part_size) {
+ /* We are staying in the current part, just seek */
+ if ((pos = lseek(dev->fd, (off_t)(offset-dev->part_start), SEEK_SET)) < 0) {
+ return pos;
+ } else {
+ return pos + dev->part_start;
}
- }
- else {
- /* pos < dev->part_start :
- * We need to access a previous part,
- * so just load the first one, and seek again
- * until the right one is loaded */
- if (open_first_part(dev) < 0) {
- Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
+ } else {
+ /* Load next part, and start again */
+ if (open_next_part(dev) < 0) {
+ Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
return -1;
}
return lseek_dev(dev, offset, SEEK_SET);
}
- break;
- case SEEK_CUR:
- Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
- if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
- return pos;
- }
- pos += dev->part_start;
- if (offset == 0) {
- return pos;
- }
- else { /* Not used in Bacula, but should work */
- return lseek_dev(dev, pos, SEEK_SET);
- }
- break;
- case SEEK_END:
- Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
- if (offset > 0) { /* Not used by bacula */
- Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
- errno = EINVAL;
+ } else {
+ /* pos < dev->part_start :
+ * We need to access a previous part,
+ * so just load the first one, and seek again
+ * until the right one is loaded */
+ if (open_first_part(dev) < 0) {
+ Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
return -1;
}
+ return lseek_dev(dev, offset, SEEK_SET);
+ }
+ break;
+ case SEEK_CUR:
+ Dmsg1(100, "lseek_dev SEEK_CUR called %d\n", offset);
+ if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
+ return pos;
+ }
+ pos += dev->part_start;
+ if (offset == 0) {
+ return pos;
+ }
+ else { /* Not used in Bacula, but should work */
+ return lseek_dev(dev, pos, SEEK_SET);
+ }
+ break;
+ case SEEK_END:
+ Dmsg1(100, "lseek_dev SEEK_END called %d\n", offset);
+ if (offset > 0) { /* Not used by bacula */
+ Dmsg1(100, "lseek_dev SEEK_END called with an invalid offset %d\n", offset);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (dev->part == dev->num_parts) { /* The right part is already loaded */
+ if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
+ return pos;
+ } else {
+ return pos + dev->part_start;
+ }
+ } else {
+ /* Load the first part, then load the next until we reach the last one.
+ * This is the only way to be sure we compute the right file address. */
+ /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
+ openmode = dev->openmode;
+ dev->openmode = OPEN_READ_ONLY;
- if (dev->part == dev->num_parts) { /* The right part is already loaded */
- if ((pos = lseek(dev->fd, (off_t)0, SEEK_END)) < 0) {
- return pos;
- }
- else {
- return pos + dev->part_start;
- }
+ /* Works because num_parts > 0. */
+ if (open_first_part(dev) < 0) {
+ Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
+ return -1;
}
- else {
- /* Load the first part, then load the next until we reach the last one.
- * This is the only way to be sure we compute the right file address. */
- /* Save previous openmode, and open all but last part read-only (useful for DVDs) */
- openmode = dev->openmode;
- dev->openmode = OPEN_READ_ONLY;
-
- /* Works because num_parts > 0. */
- if (open_first_part(dev) < 0) {
- Dmsg0(100, "lseek_dev failed while trying to open the first part\n");
- return -1;
- }
- while (dev->part < (dev->num_parts-1)) {
- if (open_next_part(dev) < 0) {
- Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
- return -1;
- }
- }
- dev->openmode = openmode;
+ while (dev->part < (dev->num_parts-1)) {
if (open_next_part(dev) < 0) {
Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
return -1;
}
- return lseek_dev(dev, 0, SEEK_END);
}
- break;
- default:
- errno = EINVAL;
- return -1;
+ dev->openmode = openmode;
+ if (open_next_part(dev) < 0) {
+ Dmsg0(100, "lseek_dev failed while trying to open the next part\n");
+ return -1;
+ }
+ return lseek_dev(dev, 0, SEEK_END);
+ }
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
}
}
dev->block_num = dev->file = 0;
dev->file_size = 0;
dev->file_addr = 0;
- if (dev->state & ST_TAPE) {
+ if (dev->is_tape()) {
mt_com.mt_op = MTREW;
mt_com.mt_count = 1;
/* If we get an I/O error on rewind, it is probably because
}
break;
}
- } else if (dev->state & ST_FILE) {
+ } else if (dev->is_file()) {
if (lseek_dev(dev, (off_t)0, SEEK_SET) < 0) {
berrno be;
dev->dev_errno = errno;
if (dev->state & (ST_FIFO | ST_PROG)) {
return 1;
}
- if (!(dev->state & ST_TAPE)) {
+ if (!(dev->is_tape())) {
pos = lseek_dev(dev, (off_t)0, SEEK_END);
// Dmsg1(100, "====== Seek to %lld\n", pos);
if (pos >= 0) {
}
#ifdef MTEOM
- if (dev_cap(dev, CAP_MTIOCGET) && dev_cap(dev, CAP_FASTFSF) && !dev_cap(dev, CAP_EOM)) {
+ if (dev_cap(dev, CAP_MTIOCGET) && dev_cap(dev, CAP_FASTFSF) &&
+ !dev_cap(dev, CAP_EOM)) {
struct mtget mt_stat;
Dmsg0(100,"Using FAST FSF for EOM\n");
if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) == 0 && mt_stat.mt_fileno <= 0) {
}
/* Find out where we are */
- if (dev->state & ST_FILE) {
+ if (dev->is_file()) {
dev->file = 0;
dev->file_addr = 0;
pos = lseek_dev(dev, (off_t)0, SEEK_CUR);
stat |= BMT_EOF;
Dmsg0(-20, " EOF");
}
- if (dev->state & ST_TAPE) {
+ if (dev->is_tape()) {
stat |= BMT_TAPE;
Dmsg0(-20," Bacula status:");
Dmsg2(-20," file=%d block=%d\n", dev->file, dev->block_num);
Emsg0(M_FATAL, 0, dev->errmsg);
return false;
}
- if (!(dev->state & ST_TAPE)) {
+ if (!(dev->is_tape())) {
return true;
}
#ifndef MTLOAD
Emsg0(M_FATAL, 0, dev->errmsg);
return false;
}
- if (!(dev->state & ST_TAPE)) {
+ if (!(dev->is_tape())) {
return true;
}
}
/* Remove the last part file if it is empty */
- if ((dev->state & ST_APPEND) && (dev->num_parts > 0)) {
+ if (dev->can_append() && (dev->num_parts > 0)) {
struct stat statp;
POOL_MEM archive_name(PM_FNAME);
dev->part = dev->num_parts;
bool
dev_can_write(DEVICE *dev)
{
- if ((dev->state & ST_OPENED) && (dev->state & ST_APPEND) &&
- (dev->state & ST_LABEL) && !(dev->state & ST_WEOT)) {
+ if (dev->is_open() && dev->can_append() &&
+ dev->is_labeled() && !(dev->state & ST_WEOT)) {
return true;
} else {
return false;
#ifndef __DEV_H
#define __DEV_H 1
-#undef DCR /* used by Bacula */
+#undef DCR /* used by Bacula */
/* #define NEW_LOCK 1 */
-#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev))
+#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev))
#define new_lock_device_state(dev,state) _new_lock_device(__FILE__, __LINE__, (dev), (state))
-#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev))
+#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev))
#define lock_device(d) _lock_device(__FILE__, __LINE__, (d))
#define unlock_device(d) _unlock_device(__FILE__, __LINE__, (d))
};
/* Generic status bits returned from status_dev() */
-#define BMT_TAPE (1<<0) /* is tape device */
-#define BMT_EOF (1<<1) /* just read EOF */
-#define BMT_BOT (1<<2) /* at beginning of tape */
-#define BMT_EOT (1<<3) /* end of tape reached */
-#define BMT_SM (1<<4) /* DDS setmark */
-#define BMT_EOD (1<<5) /* DDS at end of data */
-#define BMT_WR_PROT (1<<6) /* tape write protected */
-#define BMT_ONLINE (1<<7) /* tape online */
-#define BMT_DR_OPEN (1<<8) /* tape door open */
-#define BMT_IM_REP_EN (1<<9) /* immediate report enabled */
+#define BMT_TAPE (1<<0) /* is tape device */
+#define BMT_EOF (1<<1) /* just read EOF */
+#define BMT_BOT (1<<2) /* at beginning of tape */
+#define BMT_EOT (1<<3) /* end of tape reached */
+#define BMT_SM (1<<4) /* DDS setmark */
+#define BMT_EOD (1<<5) /* DDS at end of data */
+#define BMT_WR_PROT (1<<6) /* tape write protected */
+#define BMT_ONLINE (1<<7) /* tape online */
+#define BMT_DR_OPEN (1<<8) /* tape door open */
+#define BMT_IM_REP_EN (1<<9) /* immediate report enabled */
/* Test capabilities */
#define dev_cap(dev, cap) ((dev)->capabilities & (cap))
/* Bits for device capabilities */
-#define CAP_EOF (1<<0) /* has MTWEOF */
-#define CAP_BSR (1<<1) /* has MTBSR */
-#define CAP_BSF (1<<2) /* has MTBSF */
-#define CAP_FSR (1<<3) /* has MTFSR */
-#define CAP_FSF (1<<4) /* has MTFSF */
-#define CAP_EOM (1<<5) /* has MTEOM */
-#define CAP_REM (1<<6) /* is removable media */
-#define CAP_RACCESS (1<<7) /* is random access device */
-#define CAP_AUTOMOUNT (1<<8) /* Read device at start to see what is there */
-#define CAP_LABEL (1<<9) /* Label blank tapes */
-#define CAP_ANONVOLS (1<<10) /* Mount without knowing volume name */
-#define CAP_ALWAYSOPEN (1<<11) /* always keep device open */
+#define CAP_EOF (1<<0) /* has MTWEOF */
+#define CAP_BSR (1<<1) /* has MTBSR */
+#define CAP_BSF (1<<2) /* has MTBSF */
+#define CAP_FSR (1<<3) /* has MTFSR */
+#define CAP_FSF (1<<4) /* has MTFSF */
+#define CAP_EOM (1<<5) /* has MTEOM */
+#define CAP_REM (1<<6) /* is removable media */
+#define CAP_RACCESS (1<<7) /* is random access device */
+#define CAP_AUTOMOUNT (1<<8) /* Read device at start to see what is there */
+#define CAP_LABEL (1<<9) /* Label blank tapes */
+#define CAP_ANONVOLS (1<<10) /* Mount without knowing volume name */
+#define CAP_ALWAYSOPEN (1<<11) /* always keep device open */
#define CAP_AUTOCHANGER (1<<12) /* AutoChanger */
#define CAP_OFFLINEUNMOUNT (1<<13) /* Offline before unmount */
-#define CAP_STREAM (1<<14) /* Stream device */
-#define CAP_BSFATEOM (1<<15) /* Backspace file at EOM */
-#define CAP_FASTFSF (1<<16) /* Fast forward space file */
-#define CAP_TWOEOF (1<<17) /* Write two eofs for EOM */
+#define CAP_STREAM (1<<14) /* Stream device */
+#define CAP_BSFATEOM (1<<15) /* Backspace file at EOM */
+#define CAP_FASTFSF (1<<16) /* Fast forward space file */
+#define CAP_TWOEOF (1<<17) /* Write two eofs for EOM */
#define CAP_CLOSEONPOLL (1<<18) /* Close device on polling */
#define CAP_POSITIONBLOCKS (1<<19) /* Use block positioning */
-#define CAP_MTIOCGET (1<<20) /* Basic support for fileno and blkno */
-#define CAP_REQMOUNT (1<<21) /* Require mount to read files back (typically: DVD) */
+#define CAP_MTIOCGET (1<<20) /* Basic support for fileno and blkno */
+#define CAP_REQMOUNT (1<<21) /* Require mount to read files back (typically: DVD) */
/* Test state */
#define dev_state(dev, st_state) ((dev)->state & (st_state))
/* Device state bits */
-#define ST_OPENED (1<<0) /* set when device opened */
-#define ST_TAPE (1<<1) /* is a tape device */
-#define ST_FILE (1<<2) /* is a file device */
-#define ST_FIFO (1<<3) /* is a fifo device */
-#define ST_PROG (1<<4) /* is a program device */
-#define ST_LABEL (1<<5) /* label found */
-#define ST_MALLOC (1<<6) /* dev packet malloc'ed in init_dev() */
-#define ST_APPEND (1<<7) /* ready for Bacula append */
-#define ST_READ (1<<8) /* ready for Bacula read */
-#define ST_EOT (1<<9) /* at end of tape */
-#define ST_WEOT (1<<10) /* Got EOT on write */
-#define ST_EOF (1<<11) /* Read EOF i.e. zero bytes */
-#define ST_NEXTVOL (1<<12) /* Start writing on next volume */
-#define ST_SHORT (1<<13) /* Short block read */
-#define ST_MOUNTED (1<<14) /* the device is mounted to the mount point */
+#define ST_OPENED (1<<0) /* set when device opened */
+#define ST_TAPE (1<<1) /* is a tape device */
+#define ST_FILE (1<<2) /* is a file device */
+#define ST_FIFO (1<<3) /* is a fifo device */
+#define ST_DVD (1<<4) /* is a DVD device */
+#define ST_PROG (1<<5) /* is a program device */
+#define ST_LABEL (1<<6) /* label found */
+#define ST_MALLOC (1<<7) /* dev packet malloc'ed in init_dev() */
+#define ST_APPEND (1<<8) /* ready for Bacula append */
+#define ST_READ (1<<9) /* ready for Bacula read */
+#define ST_EOT (1<<10) /* at end of tape */
+#define ST_WEOT (1<<11) /* Got EOT on write */
+#define ST_EOF (1<<12) /* Read EOF i.e. zero bytes */
+#define ST_NEXTVOL (1<<13) /* Start writing on next volume */
+#define ST_SHORT (1<<14) /* Short block read */
+#define ST_MOUNTED (1<<15) /* the device is mounted to the mount point */
/* dev_blocked states (mutually exclusive) */
enum {
- BST_NOT_BLOCKED = 0, /* not blocked */
- BST_UNMOUNTED, /* User unmounted device */
- BST_WAITING_FOR_SYSOP, /* Waiting for operator to mount tape */
- BST_DOING_ACQUIRE, /* Opening/validating/moving tape */
- BST_WRITING_LABEL, /* Labeling a tape */
+ BST_NOT_BLOCKED = 0, /* not blocked */
+ BST_UNMOUNTED, /* User unmounted device */
+ BST_WAITING_FOR_SYSOP, /* Waiting for operator to mount tape */
+ BST_DOING_ACQUIRE, /* Opening/validating/moving tape */
+ BST_WRITING_LABEL, /* Labeling a tape */
BST_UNMOUNTED_WAITING_FOR_SYSOP, /* Closed by user during mount request */
- BST_MOUNT /* Mount request */
+ BST_MOUNT /* Mount request */
};
/* Volume Catalog Information structure definition */
struct VOLUME_CAT_INFO {
/* Media info for the current Volume */
- uint32_t VolCatJobs; /* number of jobs on this Volume */
- uint32_t VolCatFiles; /* Number of files */
- uint32_t VolCatBlocks; /* Number of blocks */
- uint64_t VolCatBytes; /* Number of bytes written */
- uint32_t VolCatParts; /* Number of parts written */
- uint32_t VolCatMounts; /* Number of mounts this volume */
- uint32_t VolCatErrors; /* Number of errors this volume */
- uint32_t VolCatWrites; /* Number of writes this volume */
- uint32_t VolCatReads; /* Number of reads this volume */
- uint64_t VolCatRBytes; /* Number of bytes read */
- uint32_t VolCatRecycles; /* Number of recycles this volume */
- uint32_t EndFile; /* Last file number */
- uint32_t EndBlock; /* Last block number */
- int32_t Slot; /* Slot in changer */
- bool InChanger; /* Set if vol in current magazine */
- uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */
- uint32_t VolCatMaxFiles; /* Maximum files to write to volume */
- uint64_t VolCatMaxBytes; /* Max bytes to write to volume */
+ uint32_t VolCatJobs; /* number of jobs on this Volume */
+ uint32_t VolCatFiles; /* Number of files */
+ uint32_t VolCatBlocks; /* Number of blocks */
+ uint64_t VolCatBytes; /* Number of bytes written */
+ uint32_t VolCatParts; /* Number of parts written */
+ uint32_t VolCatMounts; /* Number of mounts this volume */
+ uint32_t VolCatErrors; /* Number of errors this volume */
+ uint32_t VolCatWrites; /* Number of writes this volume */
+ uint32_t VolCatReads; /* Number of reads this volume */
+ uint64_t VolCatRBytes; /* Number of bytes read */
+ uint32_t VolCatRecycles; /* Number of recycles this volume */
+ uint32_t EndFile; /* Last file number */
+ uint32_t EndBlock; /* Last block number */
+ int32_t LabelType; /* Bacula/ANSI/IBM */
+ int32_t Slot; /* Slot in changer */
+ bool InChanger; /* Set if vol in current magazine */
+ uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */
+ uint32_t VolCatMaxFiles; /* Maximum files to write to volume */
+ uint64_t VolCatMaxBytes; /* Max bytes to write to volume */
uint64_t VolCatCapacityBytes; /* capacity estimate */
- uint64_t VolReadTime; /* time spent reading */
- uint64_t VolWriteTime; /* time spent writing this Volume */
- char VolCatStatus[20]; /* Volume status */
+ uint64_t VolReadTime; /* time spent reading */
+ uint64_t VolWriteTime; /* time spent writing this Volume */
+ char VolCatStatus[20]; /* Volume status */
char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */
};
typedef struct s_steal_lock {
- pthread_t no_wait_id; /* id of no wait thread */
- int dev_blocked; /* state */
- int dev_prev_blocked; /* previous blocked state */
+ pthread_t no_wait_id; /* id of no wait thread */
+ int dev_blocked; /* state */
+ int dev_prev_blocked; /* previous blocked state */
} bsteal_lock_t;
-struct DEVRES; /* Device resource defined in stored_conf.h */
+struct DEVRES; /* Device resource defined in stored_conf.h */
/*
* Device structure definition. There is one of these for
* each physical device. Everything here is "global" to
* that device and effects all jobs using the device.
*/
-struct DEVICE {
+class DEVICE {
public:
- DEVICE *next; /* pointer to next open device */
- DEVICE *prev; /* pointer to prev open device */
- JCR *attached_jcrs; /* attached JCR list */
- dlist *attached_dcrs; /* attached DCR list */
- pthread_mutex_t mutex; /* access control */
+ dlist *attached_dcrs; /* attached DCR list */
+ pthread_mutex_t mutex; /* access control */
pthread_mutex_t spool_mutex; /* mutex for updating spool_size */
- pthread_cond_t wait; /* thread wait variable */
+ pthread_cond_t wait; /* thread wait variable */
pthread_cond_t wait_next_vol; /* wait for tape to be mounted */
- pthread_t no_wait_id; /* this thread must not wait */
- int dev_blocked; /* set if we must wait (i.e. change tape) */
- int dev_prev_blocked; /* previous blocked state */
- int num_waiting; /* number of threads waiting */
- int num_writers; /* number of writing threads */
+ pthread_t no_wait_id; /* this thread must not wait */
+ int dev_blocked; /* set if we must wait (i.e. change tape) */
+ int dev_prev_blocked; /* previous blocked state */
+ int num_waiting; /* number of threads waiting */
+ int num_writers; /* number of writing threads */
+ int reserved_device; /* number of device reservations */
/* New access control in process of being implemented */
- brwlock_t lock; /* New mutual exclusion lock */
-
- int use_count; /* usage count on this device */
- int fd; /* file descriptor */
- int capabilities; /* capabilities mask */
- int state; /* state mask */
- int dev_errno; /* Our own errno */
- int mode; /* read/write modes */
- int openmode; /* parameter passed to open_dev (useful to reopen the device) */
- uint32_t drive_index; /* Autochanger drive index */
- POOLMEM *dev_name; /* device name */
- char *errmsg; /* nicely edited error message */
- uint32_t block_num; /* current block number base 0 */
- uint32_t file; /* current file number base 0 */
- uint64_t file_addr; /* Current file read/write address */
- uint64_t file_size; /* Current file size */
- uint32_t EndBlock; /* last block written */
- uint32_t EndFile; /* last file written */
- uint32_t min_block_size; /* min block size */
- uint32_t max_block_size; /* max block size */
- uint64_t max_volume_size; /* max bytes to put on one volume */
- uint64_t max_file_size; /* max file size to put in one file on volume */
- uint64_t volume_capacity; /* advisory capacity */
- uint64_t max_spool_size; /* maximum spool file size */
- uint64_t spool_size; /* current spool size */
- uint32_t max_rewind_wait; /* max secs to allow for rewind */
- uint32_t max_open_wait; /* max secs to allow for open */
- uint32_t max_open_vols; /* max simultaneous open volumes */
+ brwlock_t lock; /* New mutual exclusion lock */
+
+ int use_count; /* usage count on this device */
+ int fd; /* file descriptor */
+ int capabilities; /* capabilities mask */
+ int state; /* state mask */
+ int dev_errno; /* Our own errno */
+ int mode; /* read/write modes */
+ int openmode; /* parameter passed to open_dev (useful to reopen the device) */
+ uint32_t drive_index; /* Autochanger drive index */
+ POOLMEM *dev_name; /* device name */
+ char *errmsg; /* nicely edited error message */
+ uint32_t block_num; /* current block number base 0 */
+ uint32_t file; /* current file number base 0 */
+ uint64_t file_addr; /* Current file read/write address */
+ uint64_t file_size; /* Current file size */
+ uint32_t EndBlock; /* last block written */
+ uint32_t EndFile; /* last file written */
+ uint32_t min_block_size; /* min block size */
+ uint32_t max_block_size; /* max block size */
+ uint64_t max_volume_size; /* max bytes to put on one volume */
+ uint64_t max_file_size; /* max file size to put in one file on volume */
+ uint64_t volume_capacity; /* advisory capacity */
+ uint64_t max_spool_size; /* maximum spool file size */
+ uint64_t spool_size; /* current spool size */
+ uint32_t max_rewind_wait; /* max secs to allow for rewind */
+ uint32_t max_open_wait; /* max secs to allow for open */
+ uint32_t max_open_vols; /* max simultaneous open volumes */
- uint64_t max_part_size; /* max part size */
- uint64_t part_size; /* current part size */
- uint32_t part; /* current part number */
- uint64_t part_start; /* current part start address (relative to the whole volume) */
- uint32_t num_parts; /* number of parts (total) */
- uint64_t free_space; /* current free space on medium (without the current part) */
- int free_space_errno; /* indicates:
- * - free_space_errno == 0: ignore free_space.
- * - free_space_errno < 0: an error occured.
- * - free_space_errno > 0: free_space is valid. */
+ uint64_t max_part_size; /* max part size */
+ uint64_t part_size; /* current part size */
+ uint32_t part; /* current part number */
+ uint64_t part_start; /* current part start address (relative to the whole volume) */
+ uint32_t num_parts; /* number of parts (total) */
+ uint64_t free_space; /* current free space on medium (without the current part) */
+ int free_space_errno; /* indicates:
+ * - free_space_errno == 0: ignore free_space.
+ * - free_space_errno < 0: an error occured.
+ * - free_space_errno > 0: free_space is valid. */
- utime_t vol_poll_interval; /* interval between polling Vol mount */
- DEVRES *device; /* pointer to Device Resource */
- btimer_t *tid; /* timer id */
+ utime_t vol_poll_interval; /* interval between polling Vol mount */
+ DEVRES *device; /* pointer to Device Resource */
+ btimer_t *tid; /* timer id */
- VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */
- VOLUME_LABEL VolHdr; /* Actual volume label */
+ VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */
+ VOLUME_LABEL VolHdr; /* Actual volume label */
/* Device wait times ***FIXME*** look at durations */
char BadVolName[MAX_NAME_LENGTH]; /* Last wrong Volume mounted */
- bool poll; /* set to poll Volume */
+ bool poll; /* set to poll Volume */
int min_wait;
int max_wait;
int max_num_wait;
int wait_sec;
int rem_wait_sec;
int num_wait;
+
+ int is_tape() const;
+ int is_file() const;
+ int is_fifo() const;
+ int is_dvd() const;
+ int is_open() const;
+ int is_labeled() const;
+ int at_eof() const;
+ int at_eom() const;
+ int can_append() const;
+ int can_read() const;
+ const char *strerror() const;
+ const char *archive_name() const;
};
+/* Note, these return int not bool! */
+inline int DEVICE::is_tape() const { return state & ST_TAPE; }
+inline int DEVICE::is_file() const { return state & ST_FILE; }
+inline int DEVICE::is_fifo() const { return state & ST_FIFO; }
+inline int DEVICE::is_dvd() const { return state & ST_DVD; }
+inline int DEVICE::is_open() const { return state & ST_OPENED; }
+inline int DEVICE::is_labeled() const { return state & ST_LABEL; }
+inline int DEVICE::at_eof() const { return state & ST_EOF; }
+inline int DEVICE::at_eom() const { return state & ST_EOT; }
+inline int DEVICE::can_append() const { return state & ST_APPEND; }
+inline int DEVICE::can_read() const { return state & ST_READ; }
+inline const char *DEVICE::strerror() const { return errmsg; }
+inline const char *DEVICE::archive_name() const { return dev_name; }
+
+
+
+
/*
* Device Context (or Control) Record.
* There is one of these records for each Job that is using
* the device. Items in this record are "local" to the Job and
- * do not affect other Jobs.
+ * do not affect other Jobs. Note, a job can have multiple
+ * DCRs open, each pointing to a different device.
*/
class DCR {
public:
- dlink dev_link; /* link to attach to dev */
- JCR *jcr; /* pointer to JCR */
- DEVICE *dev; /* pointer to device */
- DEV_BLOCK *block; /* pointer to block */
- DEV_RECORD *rec; /* pointer to record */
- int spool_fd; /* fd if spooling */
- bool spool_data; /* set to spool data */
- bool spooling; /* set when actually spooling */
- bool dev_locked; /* set if dev already locked */
- bool NewVol; /* set if new Volume mounted */
- bool WroteVol; /* set if Volume written */
- bool NewFile; /* set when EOF written */
- uint32_t VolFirstIndex; /* First file index this Volume */
- uint32_t VolLastIndex; /* Last file index this Volume */
- uint32_t FileIndex; /* Current File Index */
- uint32_t EndFile; /* End file written */
- uint32_t StartFile; /* Start write file */
- uint32_t StartBlock; /* Start write block */
- uint32_t EndBlock; /* Ending block written */
- int64_t spool_size; /* Current spool size */
- int64_t max_spool_size; /* Max job spool size */
+ dlink dev_link; /* link to attach to dev */
+ JCR *jcr; /* pointer to JCR */
+ DEVICE *dev; /* pointer to device */
+ DEVRES *device; /* pointer to device resource */
+ DEV_BLOCK *block; /* pointer to block */
+ DEV_RECORD *rec; /* pointer to record */
+ int spool_fd; /* fd if spooling */
+ bool spool_data; /* set to spool data */
+ bool spooling; /* set when actually spooling */
+ bool dev_locked; /* set if dev already locked */
+ bool NewVol; /* set if new Volume mounted */
+ bool WroteVol; /* set if Volume written */
+ bool NewFile; /* set when EOF written */
+ bool reserved_device; /* set if reserve done */
+ uint32_t VolFirstIndex; /* First file index this Volume */
+ uint32_t VolLastIndex; /* Last file index this Volume */
+ uint32_t FileIndex; /* Current File Index */
+ uint32_t EndFile; /* End file written */
+ uint32_t StartFile; /* Start write file */
+ uint32_t StartBlock; /* Start write block */
+ uint32_t EndBlock; /* Ending block written */
+ int64_t spool_size; /* Current spool size */
+ int64_t max_spool_size; /* Max job spool size */
char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
char pool_name[MAX_NAME_LENGTH]; /* pool name */
char pool_type[MAX_NAME_LENGTH]; /* pool type */
char media_type[MAX_NAME_LENGTH]; /* media type */
char dev_name[MAX_NAME_LENGTH]; /* dev name */
- VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */
+ VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */
};
* dependent. Arrgggg!
*/
#ifndef MTEOM
-#ifdef MTSEOD
+#ifdef MTSEOD
#define MTEOM MTSEOD
#endif
#ifdef MTEOD
return true;
}
- if (!(dev->state & ST_OPENED)) {
+ if (!dev->is_open()) {
int mode;
if (dev_cap(dev, CAP_STREAM)) {
mode = OPEN_WRITE_ONLY;
}
Dmsg0(129, "Opening device.\n");
if (open_dev(dev, NULL, mode) < 0) {
- Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
+ Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
unlock_device(dev);
return false;
}
{
DEVICE *dev = dcr->dev;
/* Open device */
- if (!(dev_state(dev, ST_OPENED))) {
- int mode;
- if (dev_cap(dev, CAP_STREAM)) {
- mode = OPEN_WRITE_ONLY;
- } else {
- mode = OPEN_READ_WRITE;
- }
- if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
- /* If polling, ignore the error */
- if (!dev->poll) {
- Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s. ERR=%s\n"),
- dev_name(dev), strerror_dev(dev));
- }
- return false;
- }
+ if (!dev->is_open()) {
+ int mode;
+ if (dev_cap(dev, CAP_STREAM)) {
+ mode = OPEN_WRITE_ONLY;
+ } else {
+ mode = OPEN_READ_WRITE;
+ }
+ if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
+ /* If polling, ignore the error */
+ if (!dev->poll) {
+ Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open archive %s. ERR=%s\n"),
+ dev_name(dev), strerror_dev(dev));
+ Dmsg2(000, "Unable to open archive %s. ERR=%s\n",
+ dev_name(dev), strerror_dev(dev));
+ }
+ return false;
+ }
}
return true;
}
while (dev->dev_blocked) {
if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
V(dev->mutex);
- Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
+ Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
strerror(stat));
}
}
extern struct s_last_job last_job;
/* Static variables */
-static char derrmsg[] = "3900 Invalid command\n";
-static char OKsetdebug[] = "3000 OK setdebug=%d\n";
+static char derrmsg[] = "3900 Invalid command\n";
+static char OKsetdebug[] = "3000 OK setdebug=%d\n";
static char illegal_cmd[] = "3997 Illegal command for a Director with Monitor directive enabled\n";
/* Imported functions */
extern void terminate_child();
extern bool job_cmd(JCR *jcr);
+extern bool use_cmd(JCR *jcr);
+extern bool run_cmd(JCR *jcr);
extern bool status_cmd(JCR *sjcr);
extern bool qstatus_cmd(JCR *jcr);
+extern bool query_cmd(JCR *jcr);
/* Forward referenced functions */
static bool label_cmd(JCR *jcr);
{"status", status_cmd, 1},
{".status", qstatus_cmd, 1},
{"unmount", unmount_cmd, 0},
+ {"use device=", use_cmd, 0},
+ {"run", run_cmd, 0},
+ {"query", query_cmd, 0},
{NULL, NULL} /* list terminator */
};
}
Dmsg0(90, "Message channel init completed.\n");
- for (quit=0; !quit;) {
+ for (quit=false; !quit;) {
/* Read command */
if ((bnet_stat = bnet_recv(bs)) <= 0) {
break; /* connection terminated */
bnet_sig(bs, BNET_EOD);
break;
}
+ Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
if (!cmds[i].func(jcr)) { /* do command */
quit = true; /* error, get out */
Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd);
if (dev) {
/******FIXME**** compare MediaTypes */
P(dev->mutex); /* Use P to avoid indefinite block */
- if (!(dev->state & ST_OPENED)) {
+ if (!dev->is_open()) {
label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
force_close_dev(dev);
/* Under certain "safe" conditions, we can steal the lock */
}
/* See what we have for a Volume */
- label_status = read_dev_volume_label(dcr);
-
- if (dev_cap(dev, CAP_REQMOUNT)) {
+ if (dev->is_dvd()) {
label_status = read_dev_volume_label_guess(dcr, 1);
- }
- else {
+ } else {
label_status = read_dev_volume_label(dcr);
}
/* Find resource, and make sure we were able to open it */
if (strcmp(device->hdr.name, dname.c_str()) == 0 && device->dev) {
Dmsg1(20, "Found device %s\n", device->hdr.name);
- jcr->device = device;
found = true;
break;
}
*/
jcr->dcr = new_dcr(jcr, device->dev);
UnlockRes();
+ jcr->dcr->device = device;
return jcr->dcr->dev;
}
UnlockRes();
Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
dev->dev_blocked = BST_MOUNT;
}
- if (dev_state(dev, ST_LABEL)) {
+ if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
dev_name(dev), dev->VolHdr.VolName);
} else {
break;
case BST_NOT_BLOCKED:
- if (dev_state(dev, ST_OPENED)) {
- if (dev_state(dev, ST_LABEL)) {
+ if (dev->is_open()) {
+ if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
dev_name(dev), dev->VolHdr.VolName);
} else {
break;
}
read_label(dcr);
- if (dev_state(dev, ST_LABEL)) {
+ if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
dev_name(dev), dev->VolHdr.VolName);
} else {
dev = find_device(jcr, dname);
if (dev) {
P(dev->mutex); /* Use P to avoid indefinite block */
- if (!(dev->state & ST_OPENED)) {
+ if (!dev->is_open()) {
Dmsg0(90, "Device already unmounted\n");
bnet_fsend(dir, _("3901 Device \"%s\" is already unmounted.\n"), dev_name(dev));
dev = find_device(jcr, dname);
if (dev) {
P(dev->mutex); /* Use P to avoid indefinite block */
- if (!(dev->state & ST_OPENED)) {
+ if (!dev->is_open()) {
Dmsg0(90, "Device already released\n");
bnet_fsend(dir, _("3911 Device %s already released.\n"), dev_name(dev));
P(dev->mutex); /* Use P to avoid indefinite block */
if (!dev_is_tape(dev)) {
bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), dev_name(dev));
- } else if (!(dev->state & ST_OPENED)) {
+ } else if (!dev->is_open()) {
autochanger_list(dcr, dir);
/* Under certain "safe" conditions, we can steal the lock */
} else if (dev->dev_blocked &&
dev = find_device(jcr, dname);
if (dev) {
P(dev->mutex); /* Use P to avoid indefinite block */
- if (!dev_state(dev, ST_OPENED)) {
+ if (!dev->is_open()) {
read_volume_label(jcr, dev, Slot);
force_close_dev(dev);
/* Under certain "safe" conditions, we can steal the lock */
}
/* Ensure that the device is open -- autoload_device() closes it */
- for ( ; !(dev->state & ST_OPENED); ) {
+ for ( ; !dev->is_open(); ) {
if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"),
- dev_name(dev), strerror_dev(dev));
+ dev_name(dev), dev->strerror());
return false;
}
}
*
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
}
}
if (!found) { /* command not found */
- Dmsg1(110, "<filed: Command not found: %s\n", fd->msg);
+ Dmsg1(110, "<filed: Command not found: %s\n", fd->msg);
bnet_fsend(fd, ferrmsg);
break;
}
return false;
}
- Dmsg1(110, "Append open session: %s\n", dev_name(jcr->device->dev));
- jcr->session_opened = TRUE;
+ jcr->session_opened = true;
/* Send "Ticket" to File Daemon */
bnet_fsend(fd, OK_open, jcr->VolSessionId);
bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */
- Dmsg1(110, "Append close session: %s\n", dev_name(jcr->device->dev));
-
jcr->session_opened = false;
return true;
}
jcr->read_EndBlock);
}
- Dmsg1(110, "Read open session: %s\n", dev_name(jcr->device->dev));
-
- jcr->session_opened = TRUE;
+ jcr->session_opened = true;
jcr->JobType = JT_RESTORE;
/* Send "Ticket" to File Daemon */
bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */
- jcr->session_opened = FALSE;
+ jcr->session_opened = false;
return true;
}
static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
"type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
"SpoolData=%d WritePartAfterJob=%d";
-static char use_device[] = "use device=%127s media_type=%127s pool_name=%127s pool_type=%127s\n";
-static char use_devices[] = "use devices=%127s media_type=%127s pool_name=%127s pool_type=%127s\n";
+static char use_device[] = "use device=%127s media_type=%127s "
+ "pool_name=%127s pool_type=%127s append=%d";
+static char query_device[] = "query device=%127s";
+
/* Responses sent to Director daemon */
static char OKjob[] = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n";
static char NO_device[] = "3914 Device \"%s\" not in SD Device resources.\n";
static char BAD_use[] = "3913 Bad use command: %s\n";
static char BAD_job[] = "3915 Bad Job command: %s\n";
+static char OK_query[] = "3001 OK query append=%d read=%d num_writers=%d "
+ "num_waiting=%d open=%d use_count=%d labeled=%d "
+ "media_type=%s volume_name=%s";
+static char BAD_query[] = "3917 Bad query command: %s\n";
/*
* Director requests us to start a job
*/
bool job_cmd(JCR *jcr)
{
- int JobId, errstat;
+ int JobId;
char auth_key[100];
BSOCK *dir = jcr->dir_bsock;
POOL_MEM job_name, client_name, job, fileset_name, fileset_md5;
int JobType, level, spool_attributes, no_attributes, spool_data, write_part_after_job;
- struct timeval tv;
- struct timezone tz;
- struct timespec timeout;
JCR *ojcr;
/*
Dmsg1(110, ">dird: %s", dir->msg);
jcr->sd_auth_key = bstrdup(auth_key);
memset(auth_key, 0, sizeof(auth_key));
+ return true;
+}
+bool use_cmd(JCR *jcr)
+{
/*
* Wait for the device, media, and pool information
*/
memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
return false;
}
+ return true;
+}
+
+bool run_cmd(JCR *jcr)
+{
+ struct timeval tv;
+ struct timezone tz;
+ struct timespec timeout;
+ int errstat;
/* The following jobs don't need the FD */
switch (jcr->JobType) {
POOL_MEM dev_name, media_type, pool_name, pool_type;
BSOCK *dir = jcr->dir_bsock;
DEVRES *device;
- bool quit = false;
-
- while (!quit) {
- bool ok;
- if (bnet_recv(dir) <= 0) {
- Jmsg0(jcr, M_FATAL, 0, _("No Device from Director\n"));
- return false;
- }
+ int append;
+ bool ok;
- Dmsg1(120, "Use device: %s", dir->msg);
- /*
- * If there are multiple devices, the director sends us
- * use_devices (note plurel) until the last one, at which
- * time, it sends us a use_device command (note singlular)
- * so we stop looking after getting the use_device.
- */
- ok = sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(),
- pool_name.c_str(), pool_type.c_str()) == 4;
- if (ok) {
- quit = true; /* got last device */
- } else {
- ok = sscanf(dir->msg, use_devices, dev_name.c_str(), media_type.c_str(),
- pool_name.c_str(), pool_type.c_str()) == 4;
- }
- if (ok) {
- unbash_spaces(dev_name);
- unbash_spaces(media_type);
- unbash_spaces(pool_name);
- unbash_spaces(pool_type);
- LockRes();
- foreach_res(device, R_DEVICE) {
- /* Find resource, and make sure we were able to open it */
- if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
- device->dev && strcmp(device->media_type, media_type.c_str()) == 0) {
- const int name_len = MAX_NAME_LENGTH;
- DCR *dcr;
- UnlockRes();
- dcr = new_dcr(jcr, device->dev);
- if (!dcr) {
- return false;
- }
- Dmsg1(120, "Found device %s\n", device->hdr.name);
- bstrncpy(dcr->pool_name, pool_name, name_len);
- bstrncpy(dcr->pool_type, pool_type, name_len);
- bstrncpy(dcr->media_type, media_type, name_len);
- bstrncpy(dcr->dev_name, dev_name, name_len);
- jcr->device = device;
- Dmsg1(220, "Got: %s", dir->msg);
- return bnet_fsend(dir, OK_device);
+ Dmsg1(120, "Use device: %s", dir->msg);
+ /*
+ * If there are multiple devices, the director sends us
+ * use_device for each device that it wants to use.
+ */
+ ok = sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(),
+ pool_name.c_str(), pool_type.c_str(), &append) == 5;
+ if (ok) {
+ unbash_spaces(dev_name);
+ unbash_spaces(media_type);
+ unbash_spaces(pool_name);
+ unbash_spaces(pool_type);
+ LockRes();
+ foreach_res(device, R_DEVICE) {
+ /* Find resource, and make sure we were able to open it */
+ if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
+ device->dev && strcmp(device->media_type, media_type.c_str()) == 0) {
+ const int name_len = MAX_NAME_LENGTH;
+ DCR *dcr = new_dcr(jcr, device->dev);
+ UnlockRes();
+ Dmsg1(120, "Found device %s\n", device->hdr.name);
+ bstrncpy(dcr->pool_name, pool_name, name_len);
+ bstrncpy(dcr->pool_type, pool_type, name_len);
+ bstrncpy(dcr->media_type, media_type, name_len);
+ bstrncpy(dcr->dev_name, dev_name, name_len);
+ jcr->dcr = dcr;
+ if (!dcr) {
+ bnet_fsend(dir, _("Could not get dcr for device: %s\n"), dev_name.c_str());
+ return false;
}
+ if (append == SD_APPEND) {
+ ok = reserve_device_for_append(jcr, device->dev);
+ } else {
+ ok = reserve_device_for_read(jcr, device->dev);
+ }
+ if (!ok) {
+ bnet_fsend(dir, _("Could not get dcr for device: %s\n"), dev_name.c_str());
+ free_dcr(jcr->dcr);
+ return false;
+ }
+ Dmsg1(220, "Got: %s", dir->msg);
+ return bnet_fsend(dir, OK_device);
}
- UnlockRes();
- if (verbose) {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
- Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
- }
- Jmsg(jcr, M_FATAL, 0, _("\n"
- " Device \"%s\" with MediaType \"%s\" requested by Dir not found in SD Device resources.\n"),
- dev_name.c_str(), media_type.c_str());
- bnet_fsend(dir, NO_device, dev_name.c_str());
- } else {
+ }
+ UnlockRes();
+ if (verbose) {
unbash_spaces(dir->msg);
pm_strcpy(jcr->errmsg, dir->msg);
- if (verbose) {
- Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
- }
- Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
- bnet_fsend(dir, BAD_use, jcr->errmsg);
+ Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
}
+ Jmsg(jcr, M_FATAL, 0, _("\n"
+ " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
+ dev_name.c_str(), media_type.c_str());
+ bnet_fsend(dir, NO_device, dev_name.c_str());
+ } else {
+ unbash_spaces(dir->msg);
+ pm_strcpy(jcr->errmsg, dir->msg);
+ if (verbose) {
+ Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
+ }
+ Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
+ bnet_fsend(dir, BAD_use, jcr->errmsg);
}
return false; /* ERROR return */
}
+/*
+ * Query Device command from Director
+ * Sends Storage Daemon's information on the device to the
+ * caller (presumably the Director).
+ * This command always returns "true" so that the line is
+ * not closed on an error.
+ *
+ */
+bool query_cmd(JCR *jcr)
+{
+ POOL_MEM dev_name;
+ BSOCK *dir = jcr->dir_bsock;
+ DEVRES *device;
+ bool ok;
+
+ Dmsg1(120, "Query: %s", dir->msg);
+
+ ok = sscanf(dir->msg, query_device, dev_name.c_str()) == 1;
+ if (ok) {
+ unbash_spaces(dev_name);
+ LockRes();
+ foreach_res(device, R_DEVICE) {
+ /* Find resource, and make sure we were able to open it */
+ if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
+ device->dev) {
+ DEVICE *dev = device->dev;
+ POOL_MEM VolumeName, MediaType;
+ UnlockRes();
+ if (dev->is_labeled()) {
+ pm_strcpy(VolumeName, dev->VolHdr.VolName);
+ } else {
+ pm_strcpy(VolumeName, "");
+ }
+ bash_spaces(VolumeName);
+ pm_strcpy(MediaType, device->media_type);
+ bash_spaces(MediaType);
+ return bnet_fsend(dir, OK_query, dev->can_append()!=0,
+ dev->can_read()!=0, dev->num_writers, dev->num_waiting,
+ dev->is_open()!=0, dev->use_count, dev->is_labeled()!=0,
+ MediaType.c_str(), VolumeName.c_str());
+ }
+ }
+ UnlockRes();
+ unbash_spaces(dir->msg);
+ pm_strcpy(jcr->errmsg, dir->msg);
+ bnet_fsend(dir, NO_device, dev_name.c_str());
+ } else {
+ unbash_spaces(dir->msg);
+ pm_strcpy(jcr->errmsg, dir->msg);
+ bnet_fsend(dir, BAD_query, jcr->errmsg);
+ }
+ return true;
+}
+
+
/*
* Destroy the Job Control Record and associated
* resources (sockets).
/* Forward referenced functions */
static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec);
+static int read_ansi_ibm_label(DCR *dcr);
+static char *ansi_date(time_t td, char *buf);
extern char my_name[];
extern int debug_level;
Dmsg3(100, "Enter read_volume_label device=%s vol=%s dev_Vol=%s\n",
dev_name(dev), VolName, dev->VolHdr.VolName);
- if (dev_state(dev, ST_LABEL)) { /* did we already read label? */
+ if (!dev->is_open()) {
+ Emsg0(M_ABORT, 0, _("BAD call to read_dev_volume_label\n"));
+ }
+ if (dev->is_labeled()) { /* did we already read label? */
/* Compare Volume Names allow special wild card */
if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
return VOL_NO_MEDIA;
}
bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id));
+
+ /* Read ANSI/IBM label if so requested */
+ int stat = read_ansi_ibm_label(dcr);
+ if (stat != VOL_OK) {
+ return stat;
+ }
/* Read the Volume label block */
record = new_record();
* Writing : returns the label of the current file (on the harddisk).
* Reading : returns an error
*/
-int read_dev_volume_label_guess(DCR *dcr, bool write) {
+int read_dev_volume_label_guess(DCR *dcr, bool write)
+{
int vol_label_status;
+ DEVICE *dev = dcr->dev;
+ JCR *jcr = dcr->jcr;
Dmsg3(100, "Enter read_dev_volume_label_guess device=%s vol=%s dev_Vol=%s\n",
- dev_name(dcr->dev), dcr->VolumeName, dcr->dev->VolHdr.VolName);
+ dev_name(dev), dcr->VolumeName, dev->VolHdr.VolName);
- if (!dev_cap(dcr->dev, CAP_REQMOUNT)) {
+ if (!dev->is_dvd()) {
Dmsg0(100, "Leave read_dev_volume_label_guess !CAP_REQMOUNT\n");
return read_dev_volume_label(dcr);
}
/* For mounted devices, tries to guess the volume name, and read the label if possible.
*/
- if (open_guess_name_dev(dcr->dev) < 0) {
+ if (open_guess_name_dev(dev) < 0) {
if ((!write) || (dcr->VolCatInfo.VolCatParts > 0)) {
- Mmsg2(dcr->jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."),
- dev_name(dcr->dev), dcr->VolumeName);
+ Mmsg2(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."),
+ dev_name(dev), dcr->VolumeName);
Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (!open_guess_name_dev)\n");
return VOL_NO_LABEL;
}
- if (write && (dcr->dev->free_space_errno < 0)) {
+ if (write && (dev->free_space_errno < 0)) {
Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n");
- Mmsg2(dcr->jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
- dcr->dev->dev_name, dcr->dev->errmsg);
+ Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
+ dev->dev_name, dev->errmsg);
return VOL_NO_MEDIA;
}
/* If we can't guess the name, and we are writing, just reopen the right file with open_first_part. */
- if (open_first_part(dcr->dev) < 0) {
+ if (open_first_part(dev) < 0) {
berrno be;
- Mmsg2(dcr->jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
- dcr->dev->dev_name, be.strerror());
+ Mmsg2(jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
+ dev->dev_name, be.strerror());
Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (!open_guess_name_dev && !open_first_part)\n");
return VOL_IO_ERROR;
}
Dmsg0(100, "Leave read_dev_volume_label_guess !open_guess_name_dev\n");
return read_dev_volume_label(dcr);
- }
- else {
+ } else {
if (write && (dcr->dev->free_space_errno < 0)) {
Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n");
- Mmsg2(dcr->jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
- dcr->dev->dev_name, dcr->dev->errmsg);
+ Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable. ERR=%s.\n"),
+ dev->dev_name, dev->errmsg);
return VOL_NO_MEDIA;
}
if (open_first_part(dcr->dev) < 0) {
berrno be;
- Mmsg2(dcr->jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
- dcr->dev->dev_name, be.strerror());
+ Mmsg2(jcr->errmsg, _("open_first_part error on %s. ERR=%s.\n"),
+ dev->dev_name, be.strerror());
Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (open_guess_name_dev && !open_first_part)\n");
return VOL_IO_ERROR;
}
*/
if (vol_label_status != VOL_NAME_ERROR) {
Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && !VOL_NAME_ERROR)\n");
- dcr->dev->state &= ~ST_LABEL;
+ dev->state &= ~ST_LABEL;
return read_dev_volume_label(dcr);
}
else {
/* unser_volume_label
*
- * Unserialize the Volume label into the device Volume_Label
+ * Unserialize the Bacula Volume label into the device Volume_Label
* structure.
*
* Assumes that the record is already read.
}
}
+ /* Write ANSI/IBM label if so requested */
+ if (!write_ansi_ibm_label(dcr, VolName)) {
+ goto bail_out;
+ }
+
create_volume_label_record(dcr, dcr->rec);
dcr->rec->Stream = 0;
debug_level = 1;
File = dev->file;
switch (dev->VolHdr.LabelType) {
- case PRE_LABEL:
- LabelType = "PRE_LABEL";
- break;
- case VOL_LABEL:
- LabelType = "VOL_LABEL";
- break;
- case EOM_LABEL:
- LabelType = "EOM_LABEL";
- break;
- case SOS_LABEL:
- LabelType = "SOS_LABEL";
- break;
- case EOS_LABEL:
- LabelType = "EOS_LABEL";
- break;
- case EOT_LABEL:
- goto bail_out;
- default:
- LabelType = buf;
- sprintf(buf, "Unknown %d", dev->VolHdr.LabelType);
- break;
+ case PRE_LABEL:
+ LabelType = "PRE_LABEL";
+ break;
+ case VOL_LABEL:
+ LabelType = "VOL_LABEL";
+ break;
+ case EOM_LABEL:
+ LabelType = "EOM_LABEL";
+ break;
+ case SOS_LABEL:
+ LabelType = "SOS_LABEL";
+ break;
+ case EOS_LABEL:
+ LabelType = "EOS_LABEL";
+ break;
+ case EOT_LABEL:
+ goto bail_out;
+ default:
+ LabelType = buf;
+ sprintf(buf, "Unknown %d", dev->VolHdr.LabelType);
+ break;
}
-
Pmsg11(-1, "\nVolume Label:\n"
"Id : %s"
"VerNo : %d\n"
}
debug_level = dbl;
}
+
+/*
+ * Write an ANSI or IBM 80 character tape label
+ * Assume we are positioned at the beginning of the tape.
+ * Returns: true of OK
+ * false if error
+ */
+bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
+{
+ DEVICE *dev = dcr->dev;
+ JCR *jcr = dcr->jcr;
+ char label[80]; /* tape label */
+ char date[20]; /* ansi date buffer */
+ time_t now;
+ int len;
+ int stat;
+
+ switch (dcr->VolCatInfo.LabelType) {
+ case B_BACULA_LABEL:
+ return true;
+ case B_ANSI_LABEL:
+ case B_IBM_LABEL:
+ ser_declare;
+ Dmsg0(000, "Write ansi label.\n");
+ len = strlen(VolName);
+ if (len > 6) {
+ len = 6; /* max len ANSI label */
+ }
+ memset(label, ' ', sizeof(label));
+ ser_begin(label, sizeof(label));
+ ser_bytes("VOL1", 4);
+ ser_bytes(VolName, len);
+ label[79] = '1'; /* ANSI label flag */
+ /* Write VOL1 label */
+ stat = write(dev->fd, label, sizeof(label));
+ if (stat != sizeof(label)) {
+ berrno be;
+ Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
+ be.strerror());
+ return false;
+ }
+ /* Now construct HDR1 label */
+ ser_begin(label, sizeof(label));
+ ser_bytes("HDR1", 4);
+ len = strlen(VolName);
+ if (len > 17) {
+ len = 17; /* Max filename len */
+ }
+ ser_bytes(VolName, len); /* stick Volume name in Filename field */
+ if (len > 6) {
+ len = 6;
+ }
+ ser_begin(&label[21], sizeof(label)-21);
+ ser_bytes(VolName, len); /* write Vol Ser No. */
+ ser_begin(&label[27], sizeof(label)-27);
+ ser_bytes("000100010001", 12); /* File section, File seq no, Generation no */
+ now = time(NULL);
+ ser_bytes(ansi_date(now, date), 6); /* current date */
+ ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
+ ser_bytes(" 000000BACULA ", 27);
+ /* Write HDR1 label */
+ stat = write(dev->fd, label, sizeof(label));
+ if (stat != sizeof(label)) {
+ berrno be;
+ Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
+ be.strerror());
+ return false;
+ }
+ /* Now construct HDR2 label */
+ memset(label, ' ', sizeof(label));
+ ser_begin(label, sizeof(label));
+ ser_bytes("HDR2F3200032000", 15);
+ /* Write HDR1 label */
+ stat = write(dev->fd, label, sizeof(label));
+ if (stat != sizeof(label)) {
+ berrno be;
+ Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
+ be.strerror());
+ return false;
+ }
+ if (weof_dev(dev, 1) < 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
+ return false;
+ }
+ return true;
+ default:
+ Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
+ return false; /* should not get here */
+ }
+}
+
+static int read_ansi_ibm_label(DCR *dcr)
+{
+ DEVICE *dev = dcr->dev;
+ JCR *jcr = dcr->jcr;
+ char label[80]; /* tape label */
+ int retry, stat, i, num_rec;
+
+ if (dcr->VolCatInfo.LabelType == B_BACULA_LABEL) {
+ return VOL_OK;
+ }
+ /*
+ * Read VOL1, HDR1, HDR2 labels, but ignore the data
+ * If tape read the following EOF mark, on disk do
+ * not read.
+ */
+ Dmsg0(000, "Read ansi label.\n");
+ if (dev->state & ST_TAPE) {
+ num_rec = 4;
+ } else {
+ num_rec = 3;
+ }
+ for (i=0; i < num_rec; i++) {
+ retry = 0;
+ do {
+ stat = read(dev->fd, label, sizeof(label));
+ if (retry == 1) {
+ dev->VolCatInfo.VolCatErrors++;
+ }
+ } while (stat == -1 && (errno == EINTR || errno == EIO) && retry++ < 11);
+ if (stat < 0) {
+ berrno be;
+ clrerror_dev(dev, -1);
+ Dmsg1(200, "Read device got: ERR=%s\n", be.strerror());
+ Mmsg2(dev->errmsg, _("Read error on device %s in ANSI/IBM label. ERR=%s\n"),
+ dev->dev_name, be.strerror());
+ Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
+ if (dev->state & ST_EOF) { /* EOF just seen? */
+ dev->state |= ST_EOT; /* yes, error => EOT */
+ }
+ return VOL_IO_ERROR;
+ }
+ Dmsg1(000, "ANSI label=%80s\n", label);
+ }
+ return VOL_OK;
+}
+
+
+static char *ansi_date(time_t td, char *buf)
+{
+ struct tm *tm;
+
+ if (td == 0) {
+ td = time(NULL);
+ }
+ tm = gmtime(&td);
+ bsnprintf(buf, 6, "%d", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);
+ return buf;
+}
}
/* Ensure the device is open */
- /* If we have a device that requires mount, we first want to guess
- * which device is loaded, so we continue (if the wrong device is
+ /* If we have a dvd that requires mount, we first want to guess
+ * which Volume is loaded, so we continue (if the wrong device is
* loaded, open_device would fail). */
- if (!dev_cap(dev, CAP_REQMOUNT)) {
+ if (!dev->is_dvd()) {
if (!open_device(dcr)) {
if (dev->poll) {
goto mount_next_vol;
- }
- else {
+ } else {
return false;
}
}
- }
- else {
- /* Just copy the VolCatName in the device resource (usually done by open_dev).
- * It is necessary so we can open the real files later. */
- bstrncpy(dcr->dev->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatName, sizeof(dcr->dev->VolCatInfo.VolCatName));
+ } else {
+ /*
+ * Just copy the VolCatName in the device resource
+ * (usually done by open_dev).
+ * It is necessary so we can open the real files later.
+ */
+ bstrncpy(dev->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatName, sizeof(dev->VolCatInfo.VolCatName));
}
/*
vol_label_status = VOL_OK;
create_volume_label(dev, dcr->VolumeName, "Default");
dev->VolHdr.LabelType = PRE_LABEL;
- } else if (dev_cap(dev, CAP_REQMOUNT)) {
+ } else if (dev->is_dvd()) {
vol_label_status = read_dev_volume_label_guess(dcr, 1);
- }
- else {
+ } else {
vol_label_status = read_dev_volume_label(dcr);
}
if (job_canceled(jcr)) {
}
/* Attempt write to check write permission */
Dmsg0(200, "Attempt to write to device.\n");
+ if (!write_ansi_ibm_label(dcr, dev->VolHdr.VolName)) {
+ return false;
+ }
if (!write_block_to_dev(dcr)) {
Jmsg2(jcr, M_ERROR, 0, _("Unable to write device \"%s\". ERR=%s\n"),
dev_name(dev), strerror_dev(dev));
if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) {
close_dev(dev);
dev->state &= ~ST_READ;
- if (!acquire_device_for_read(jcr)) {
+ if (!acquire_device_for_read(jcr, dev)) {
Jmsg2(jcr, M_FATAL, 0, "Cannot open Dev=%s, Vol=%s\n", dev_name(dev),
dcr->VolumeName);
return false;
dev->state &= ~(ST_LABEL|ST_READ|ST_APPEND);
dcr->VolumeName[0] = 0;
- if ((dev->state & ST_OPENED) &&
- (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN))) {
+ if (dev->is_open() && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
offline_or_rewind_dev(dev);
close_dev(dev);
}
/* If we have not closed the device, then at least rewind the tape */
- if (dev->state & ST_OPENED) {
+ if (dev->is_open()) {
offline_or_rewind_dev(dev);
}
Dmsg0(190, "===== release_volume ---");
*/
/*
- Copyright (C) 2002 Kern Sibbald and John Walker
+ Copyright (C) 2002-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
static BSR *store_vol(LEX *lc, BSR *bsr);
+static BSR *store_mediatype(LEX *lc, BSR *bsr);
static BSR *store_client(LEX *lc, BSR *bsr);
static BSR *store_job(LEX *lc, BSR *bsr);
static BSR *store_jobid(LEX *lc, BSR *bsr);
*/
struct kw_items items[] = {
{"volume", store_vol},
+ {"mediatype", store_mediatype},
{"client", store_client},
{"job", store_job},
{"jobid", store_jobid},
for (i=0; items[i].name; i++) {
if (strcasecmp(items[i].name, lc->str) == 0) {
token = lex_get_token(lc, T_ALL);
- Dmsg1 (200, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
+ Dmsg1 (200, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
if (token != T_EQUALS) {
- scan_err1(lc, "expected an equals, got: %s", lc->str);
+ scan_err1(lc, "expected an equals, got: %s", lc->str);
bsr = NULL;
break;
}
- Dmsg1(200, "calling handler for %s\n", items[i].name);
+ Dmsg1(200, "calling handler for %s\n", items[i].name);
/* Call item handler */
bsr = items[i].handler(lc, bsr);
i = -1;
}
}
if (i >= 0) {
- Dmsg1(200, "Keyword = %s\n", lc->str);
- scan_err1(lc, "Keyword %s not found", lc->str);
+ Dmsg1(200, "Keyword = %s\n", lc->str);
+ scan_err1(lc, "Keyword %s not found", lc->str);
bsr = NULL;
break;
}
return bsr;
}
+/* Shove the MediaType in each Volume in the current bsr */
+static BSR *store_mediatype(LEX *lc, BSR *bsr)
+{
+ int token;
+
+ token = lex_get_token(lc, T_STRING);
+ if (token == T_ERROR) {
+ return NULL;
+ }
+ if (!bsr->volume) {
+ Emsg1(M_ERROR,0, _("MediaType %s in bsr at inappropriate place.\n"),
+ lc->str);
+ return bsr;
+ }
+ BSR_VOLUME *bv;
+ for (bv=bsr->volume; bv; bv=bv->next) {
+ bstrncpy(bv->MediaType, lc->str, sizeof(bv->MediaType));
+ }
+ return bsr;
+}
+
+
static BSR *store_client(LEX *lc, BSR *bsr)
{
int token;
{
if (FileIndex) {
if (FileIndex->findex == FileIndex->findex2) {
- Dmsg1(-1, "FileIndex : %u\n", FileIndex->findex);
+ Dmsg1(-1, "FileIndex : %u\n", FileIndex->findex);
} else {
- Dmsg2(-1, "FileIndex : %u-%u\n", FileIndex->findex, FileIndex->findex2);
+ Dmsg2(-1, "FileIndex : %u-%u\n", FileIndex->findex, FileIndex->findex2);
}
dump_findex(FileIndex->next);
}
{
if (jobid) {
if (jobid->JobId == jobid->JobId2) {
- Dmsg1(-1, "JobId : %u\n", jobid->JobId);
+ Dmsg1(-1, "JobId : %u\n", jobid->JobId);
} else {
- Dmsg2(-1, "JobId : %u-%u\n", jobid->JobId, jobid->JobId2);
+ Dmsg2(-1, "JobId : %u-%u\n", jobid->JobId, jobid->JobId2);
}
dump_jobid(jobid->next);
}
{
if (sessid) {
if (sessid->sessid == sessid->sessid2) {
- Dmsg1(-1, "SessId : %u\n", sessid->sessid);
+ Dmsg1(-1, "SessId : %u\n", sessid->sessid);
} else {
- Dmsg2(-1, "SessId : %u-%u\n", sessid->sessid, sessid->sessid2);
+ Dmsg2(-1, "SessId : %u-%u\n", sessid->sessid, sessid->sessid2);
}
dump_sessid(sessid->next);
}
for (bsrvol = bsr->volume; bsrvol; bsrvol=bsrvol->next) {
vol = new_vol();
bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName));
+ bstrncpy(vol->MediaType, bsrvol->MediaType, sizeof(vol->MediaType));
vol->start_file = sfile;
if (add_vol(jcr, vol)) {
jcr->NumVolumes++;
- Dmsg1(400, "Added volume %s\n", vol->VolumeName);
+ Dmsg2(400, "Added volume=%s mediatype=%s\n", vol->VolumeName,
+ vol->MediaType);
} else {
- Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName);
+ Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName);
free((char *)vol);
}
sfile = 0; /* start at beginning of second volume */
} else {
/* This is the old way -- deprecated */
for (p = jcr->dcr->VolumeName; p && *p; ) {
- n = strchr(p, '|'); /* volume name separator */
+ n = strchr(p, '|'); /* volume name separator */
if (n) {
*n++ = 0; /* Terminate name */
}
vol = new_vol();
bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName));
+ bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType));
if (add_vol(jcr, vol)) {
jcr->NumVolumes++;
} else {
uint32_t new_VolSessionId();
/* From acquire.c */
-DCR *acquire_device_for_append(JCR *jcr);
-DCR *acquire_device_for_read(JCR *jcr);
-bool release_device(JCR *jcr);
-DCR *new_dcr(JCR *jcr, DEVICE *dev);
-void free_dcr(DCR *dcr);
+bool reserve_device_for_append(JCR *jcr, DEVICE *dev);
+DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev);
+bool reserve_device_for_read(JCR *jcr, DEVICE *dev);
+DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev);
+bool release_device(JCR *jcr);
+DCR *new_dcr(JCR *jcr, DEVICE *dev);
+void free_dcr(DCR *dcr);
/* From askdir.c */
enum get_vol_info_rw {
GET_VOL_INFO_FOR_WRITE,
GET_VOL_INFO_FOR_READ
};
-bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
-bool dir_find_next_appendable_volume(DCR *dcr);
-bool dir_update_volume_info(DCR *dcr, bool label);
-bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
-bool dir_ask_sysop_to_mount_volume(DCR *dcr);
-bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
-bool dir_send_job_status(JCR *jcr);
-bool dir_create_jobmedia_record(DCR *dcr);
+bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
+bool dir_find_next_appendable_volume(DCR *dcr);
+bool dir_update_volume_info(DCR *dcr, bool label);
+bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
+bool dir_ask_sysop_to_mount_volume(DCR *dcr);
+bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
+bool dir_send_job_status(JCR *jcr);
+bool dir_create_jobmedia_record(DCR *dcr);
/* authenticate.c */
-int authenticate_director(JCR *jcr);
-int authenticate_filed(JCR *jcr);
+int authenticate_director(JCR *jcr);
+int authenticate_filed(JCR *jcr);
/* From autochanger.c */
-int autoload_device(DCR *dcr, int writing, BSOCK *dir);
-bool autochanger_list(DCR *dcr, BSOCK *dir);
-void invalidate_slot_in_catalog(DCR *dcr);
-char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd);
+int autoload_device(DCR *dcr, int writing, BSOCK *dir);
+bool autochanger_list(DCR *dcr, BSOCK *dir);
+void invalidate_slot_in_catalog(DCR *dcr);
+char *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
/* From block.c */
-void dump_block(DEV_BLOCK *b, const char *msg);
+void dump_block(DEV_BLOCK *b, const char *msg);
DEV_BLOCK *new_block(DEVICE *dev);
DEV_BLOCK *dup_block(DEV_BLOCK *eblock);
-void init_block_write(DEV_BLOCK *block);
-void empty_block(DEV_BLOCK *block);
-void free_block(DEV_BLOCK *block);
-bool write_block_to_device(DCR *dcr);
-bool write_block_to_dev(DCR *dcr);
-void print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
-void ser_block_header(DEV_BLOCK *block);
+void init_block_write(DEV_BLOCK *block);
+void empty_block(DEV_BLOCK *block);
+void free_block(DEV_BLOCK *block);
+bool write_block_to_device(DCR *dcr);
+bool write_block_to_dev(DCR *dcr);
+void print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void ser_block_header(DEV_BLOCK *block);
#define CHECK_BLOCK_NUMBERS true
#define NO_BLOCK_NUMBER_CHECK false
-bool read_block_from_device(DCR *dcr, bool check_block_numbers);
-bool read_block_from_dev(DCR *dcr, bool check_block_numbers);
+bool read_block_from_device(DCR *dcr, bool check_block_numbers);
+bool read_block_from_dev(DCR *dcr, bool check_block_numbers);
/* From butil.c -- utilities for SD tool programs */
-void print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
+void print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
- const char *VolumeName, int mode);
-void display_tape_error_status(JCR *jcr, DEVICE *dev);
+ const char *VolumeName, int mode);
+void display_tape_error_status(JCR *jcr, DEVICE *dev);
/* From dev.c */
-DEVICE *init_dev(DEVICE *dev, DEVRES *device);
-int open_dev(DEVICE *dev, char *VolName, int mode);
-off_t lseek_dev(DEVICE *dev, off_t offset, int whence);
-int open_first_part(DEVICE *dev);
-int open_next_part(DEVICE *dev);
-int open_guess_name_dev(DEVICE *dev);
-void close_dev(DEVICE *dev);
-void force_close_dev(DEVICE *dev);
-bool truncate_dev(DEVICE *dev);
-void term_dev(DEVICE *dev);
-char * strerror_dev(DEVICE *dev);
-void clrerror_dev(DEVICE *dev, int func);
-bool update_pos_dev(DEVICE *dev);
-bool rewind_dev(DEVICE *dev);
-bool load_dev(DEVICE *dev);
-bool offline_dev(DEVICE *dev);
-int flush_dev(DEVICE *dev);
-int weof_dev(DEVICE *dev, int num);
-int write_block(DEVICE *dev);
+DEVICE *init_dev(DEVICE *dev, DEVRES *device);
+int open_dev(DEVICE *dev, char *VolName, int mode);
+off_t lseek_dev(DEVICE *dev, off_t offset, int whence);
+int open_first_part(DEVICE *dev);
+int open_next_part(DEVICE *dev);
+int open_guess_name_dev(DEVICE *dev);
+void close_dev(DEVICE *dev);
+void force_close_dev(DEVICE *dev);
+bool truncate_dev(DEVICE *dev);
+void term_dev(DEVICE *dev);
+char * strerror_dev(DEVICE *dev);
+void clrerror_dev(DEVICE *dev, int func);
+bool update_pos_dev(DEVICE *dev);
+bool rewind_dev(DEVICE *dev);
+bool load_dev(DEVICE *dev);
+bool offline_dev(DEVICE *dev);
+int flush_dev(DEVICE *dev);
+int weof_dev(DEVICE *dev, int num);
+int write_block(DEVICE *dev);
uint32_t status_dev(DEVICE *dev);
-int eod_dev(DEVICE *dev);
-bool fsf_dev(DEVICE *dev, int num);
-bool fsr_dev(DEVICE *dev, int num);
-bool bsf_dev(DEVICE *dev, int num);
-bool bsr_dev(DEVICE *dev, int num);
-void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
-bool dev_can_write(DEVICE *dev);
-bool offline_or_rewind_dev(DEVICE *dev);
-bool reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
-void init_dev_wait_timers(DEVICE *dev);
-bool double_dev_wait_time(DEVICE *dev);
+int eod_dev(DEVICE *dev);
+bool fsf_dev(DEVICE *dev, int num);
+bool fsr_dev(DEVICE *dev, int num);
+bool bsf_dev(DEVICE *dev, int num);
+bool bsr_dev(DEVICE *dev, int num);
+void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
+bool dev_can_write(DEVICE *dev);
+bool offline_or_rewind_dev(DEVICE *dev);
+bool reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
+void init_dev_wait_timers(DEVICE *dev);
+bool double_dev_wait_time(DEVICE *dev);
/* Get info about device */
-char * dev_name(DEVICE *dev);
-char * dev_vol_name(DEVICE *dev);
+char * dev_name(DEVICE *dev);
+char * dev_vol_name(DEVICE *dev);
uint32_t dev_block(DEVICE *dev);
uint32_t dev_file(DEVICE *dev);
-bool dev_is_tape(DEVICE *dev);
+bool dev_is_tape(DEVICE *dev);
/* From device.c */
-bool open_device(DCR *dcr);
-bool first_open_device(DEVICE *dev);
-bool fixup_device_block_write_error(DCR *dcr);
-void _lock_device(const char *file, int line, DEVICE *dev);
-void _unlock_device(const char *file, int line, DEVICE *dev);
-void _block_device(const char *file, int line, DEVICE *dev, int state);
-void _unblock_device(const char *file, int line, DEVICE *dev);
-void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
-void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
-void set_new_volume_parameters(DCR *dcr);
-void set_new_file_parameters(DCR *dcr);
-bool device_is_unmounted(DEVICE *dev);
-void dev_lock(DEVICE *dev);
-void dev_unlock(DEVICE *dev);
+bool open_device(DCR *dcr);
+bool first_open_device(DEVICE *dev);
+bool fixup_device_block_write_error(DCR *dcr);
+void _lock_device(const char *file, int line, DEVICE *dev);
+void _unlock_device(const char *file, int line, DEVICE *dev);
+void _block_device(const char *file, int line, DEVICE *dev, int state);
+void _unblock_device(const char *file, int line, DEVICE *dev);
+void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
+void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
+void set_new_volume_parameters(DCR *dcr);
+void set_new_file_parameters(DCR *dcr);
+bool device_is_unmounted(DEVICE *dev);
+void dev_lock(DEVICE *dev);
+void dev_unlock(DEVICE *dev);
const char *edit_blocked_reason(DEVICE *dev);
/* From dircmd.c */
-void *handle_connection_request(void *arg);
+void *handle_connection_request(void *arg);
/* From fd_cmds.c */
-void run_job(JCR *jcr);
-bool bootstrap_cmd(JCR *jcr);
+void run_job(JCR *jcr);
+bool bootstrap_cmd(JCR *jcr);
/* From job.c */
-void stored_free_jcr(JCR *jcr);
-void connection_from_filed(void *arg);
-void handle_filed_connection(BSOCK *fd, char *job_name);
+void stored_free_jcr(JCR *jcr);
+void connection_from_filed(void *arg);
+void handle_filed_connection(BSOCK *fd, char *job_name);
/* From label.c */
-int read_dev_volume_label(DCR *dcr);
-int read_dev_volume_label_guess(DCR *dcr, bool write);
-void create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
-void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
-bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
-bool write_session_label(DCR *dcr, int label);
-bool write_volume_label_to_block(DCR *dcr);
-void dump_volume_label(DEVICE *dev);
-void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int read_dev_volume_label(DCR *dcr);
+int read_dev_volume_label_guess(DCR *dcr, bool write);
+void create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
+void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
+bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
+bool write_ansi_ibm_label(DCR *dcr, const char *VolName);
+bool write_session_label(DCR *dcr, int label);
+bool write_volume_label_to_block(DCR *dcr);
+void dump_volume_label(DEVICE *dev);
+void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
/* From match_bsr.c */
-int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
- SESSION_LABEL *sesrec);
-int match_bsr_block(BSR *bsr, DEV_BLOCK *block);
-void position_bsr_block(BSR *bsr, DEV_BLOCK *block);
-BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev);
-bool match_set_eof(BSR *bsr, DEV_RECORD *rec);
+int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
+ SESSION_LABEL *sesrec);
+int match_bsr_block(BSR *bsr, DEV_BLOCK *block);
+void position_bsr_block(BSR *bsr, DEV_BLOCK *block);
+BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev);
+bool match_set_eof(BSR *bsr, DEV_RECORD *rec);
/* From mount.c */
-bool mount_next_write_volume(DCR *dcr, bool release);
-bool mount_next_read_volume(DCR *dcr);
-void release_volume(DCR *ddr);
-void mark_volume_in_error(DCR *dcr);
+bool mount_next_write_volume(DCR *dcr, bool release);
+bool mount_next_read_volume(DCR *dcr);
+void release_volume(DCR *ddr);
+void mark_volume_in_error(DCR *dcr);
/* From parse_bsr.c */
-BSR *parse_bsr(JCR *jcr, char *lf);
-void dump_bsr(BSR *bsr, bool recurse);
-void free_bsr(BSR *bsr);
+BSR *parse_bsr(JCR *jcr, char *lf);
+void dump_bsr(BSR *bsr, bool recurse);
+void free_bsr(BSR *bsr);
VOL_LIST *new_vol();
-int add_vol(JCR *jcr, VOL_LIST *vol);
-void free_vol_list(JCR *jcr);
-void create_vol_list(JCR *jcr);
+int add_vol(JCR *jcr, VOL_LIST *vol);
+void free_vol_list(JCR *jcr);
+void create_vol_list(JCR *jcr);
/* From record.c */
const char *FI_to_ascii(int fi);
const char *stream_to_ascii(int stream, int fi);
-bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
DEV_RECORD *new_record();
-void free_record(DEV_RECORD *rec);
-void empty_record(DEV_RECORD *rec);
+void free_record(DEV_RECORD *rec);
+void empty_record(DEV_RECORD *rec);
/* From read_record.c */
bool read_records(DCR *dcr,
bool mount_cb(DCR *dcr));
/* From spool.c */
-bool begin_data_spool (JCR *jcr);
-bool discard_data_spool (JCR *jcr);
-bool commit_data_spool (JCR *jcr);
-bool are_attributes_spooled (JCR *jcr);
-bool begin_attribute_spool (JCR *jcr);
-bool discard_attribute_spool (JCR *jcr);
-bool commit_attribute_spool (JCR *jcr);
-bool write_block_to_spool_file (DCR *dcr);
-void list_spool_stats (BSOCK *bs);
+bool begin_data_spool (JCR *jcr);
+bool discard_data_spool (JCR *jcr);
+bool commit_data_spool (JCR *jcr);
+bool are_attributes_spooled (JCR *jcr);
+bool begin_attribute_spool (JCR *jcr);
+bool discard_attribute_spool (JCR *jcr);
+bool commit_attribute_spool (JCR *jcr);
+bool write_block_to_spool_file (DCR *dcr);
+void list_spool_stats (BSOCK *bs);
{
BSOCK *fd = jcr->file_bsock;
bool ok = true;
- DCR *dcr;
+ DCR *dcr = jcr->dcr;
Dmsg0(20, "Start read data.\n");
- if (!bnet_set_buffer_size(fd, jcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
+ if (!bnet_set_buffer_size(fd, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
return false;
}
Dmsg2(200, "Found %d volumes names to restore. First=%s\n", jcr->NumVolumes,
jcr->VolList->VolumeName);
- /*
- * Ready device for reading, and read records
- */
- if (!(dcr=acquire_device_for_read(jcr))) {
+ /* Ready device for reading */
+ if (!acquire_device_for_read(jcr, dcr->dev)) {
free_vol_list(jcr);
+ bnet_fsend(fd, FD_error);
return false;
}
if (dev_state(dev, ST_EOT)) {
DEV_RECORD *trec = new_record();
- Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n",
+ Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n",
dev->file, dev_name(dev), dcr->VolumeName);
if (!mount_cb(dcr)) {
- Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
+ Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
ok = false;
/*
* Create EOT Label so that Media record may
} else if (dev_state(dev, ST_EOF)) {
if (verbose) {
- Jmsg(jcr, M_INFO, 0, "Got EOF at file %u on device %s, Volume \"%s\"\n",
+ Jmsg(jcr, M_INFO, 0, "Got EOF at file %u on device %s, Volume \"%s\"\n",
dev->file, dev_name(dev), dcr->VolumeName);
}
- Dmsg3(200, "Got EOF at file %u on device %s, Volume \"%s\"\n",
+ Dmsg3(200, "Got EOF at file %u on device %s, Volume \"%s\"\n",
dev->file, dev_name(dev), dcr->VolumeName);
continue;
} else if (dev_state(dev, ST_SHORT)) {
- Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
+ Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
continue;
} else {
/* I/O error or strange end of tape */
display_tape_error_status(jcr, dev);
if (forge_on || jcr->ignore_label_errors) {
fsr_dev(dev, 1); /* try skipping bad record */
- Dmsg0(000, "Did fsr\n");
+ Dmsg0(000, "Did fsr\n");
continue; /* try to continue */
}
ok = false;
if (!found) {
rec = new_record();
recs->prepend(rec);
- Dmsg2(300, "New record for SI=%d ST=%d\n",
+ Dmsg2(300, "New record for SI=%d ST=%d\n",
block->VolSessionId, block->VolSessionTime);
- } else {
-#ifdef xxx
- if (rec->Block != 0 && (rec->Block+1) != block->BlockNumber) {
- Jmsg(jcr, M_ERROR, 0, _("Invalid block number. Expected %u, got %u\n"),
- rec->Block+1, block->BlockNumber);
- }
-#endif
}
Dmsg3(300, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
Dmsg1(300, "Block empty %d\n", is_block_empty(rec));
for (rec->state=0; !is_block_empty(rec); ) {
if (!read_record_from_block(block, rec)) {
- Dmsg3(400, "!read-break. state=%s blk=%d rem=%d\n", rec_state_to_str(rec),
+ Dmsg3(400, "!read-break. state=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
break;
}
- Dmsg5(300, "read-OK. state=%s blk=%d rem=%d file:block=%d:%d\n",
+ Dmsg5(300, "read-OK. state=%s blk=%d rem=%d file:block=%d:%d\n",
rec_state_to_str(rec), block->BlockNumber, rec->remainder,
dev->file, dev->block_num);
/*
* get all the data.
*/
record++;
- Dmsg6(300, "recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
+ Dmsg6(300, "recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
rec_state_to_str(rec), block->BlockNumber,
rec->VolSessionId, rec->VolSessionTime, rec->FileIndex);
if (rec->FileIndex == EOM_LABEL) { /* end of tape? */
- Dmsg0(40, "Get EOM LABEL\n");
+ Dmsg0(40, "Get EOM LABEL\n");
break; /* yes, get out */
}
handle_session_record(dev, rec, &sessrec);
ok = record_cb(dcr, rec);
if (rec->FileIndex == EOS_LABEL) {
- Dmsg2(300, "Remove rec. SI=%d ST=%d\n", rec->VolSessionId,
+ Dmsg2(300, "Remove rec. SI=%d ST=%d\n", rec->VolSessionId,
rec->VolSessionTime);
recs->remove(rec);
free_record(rec);
int stat = match_bsr(jcr->bsr, rec, &dev->VolHdr, &sessrec);
if (stat == -1) { /* no more possible matches */
done = true; /* all items found, stop */
- Dmsg2(300, "All done=(file:block) %d:%d\n", dev->file, dev->block_num);
+ Dmsg2(300, "All done=(file:block) %d:%d\n", dev->file, dev->block_num);
break;
} else if (stat == 0) { /* no match */
- Dmsg4(300, "Clear rem=%d FI=%d before set_eof pos %d:%d\n",
+ Dmsg4(300, "Clear rem=%d FI=%d before set_eof pos %d:%d\n",
rec->remainder, rec->FileIndex, dev->file, dev->block_num);
rec->remainder = 0;
rec->state &= ~REC_PARTIAL_RECORD;
if (try_repositioning(jcr, rec, dev)) {
break;
}
- continue; /* we don't want record, read next one */
+ continue; /* we don't want record, read next one */
}
}
if (is_partial_record(rec)) {
- Dmsg6(300, "Partial, break. recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
+ Dmsg6(300, "Partial, break. recno=%d state=%s blk=%d SI=%d ST=%d FI=%d\n", record,
rec_state_to_str(rec), block->BlockNumber,
rec->VolSessionId, rec->VolSessionTime, rec->FileIndex);
break; /* read second part of record */
}
ok = record_cb(dcr, rec);
if (rec->Stream == STREAM_MD5_SIGNATURE || rec->Stream == STREAM_SHA1_SIGNATURE) {
- Dmsg3(300, "Done FI=%d before set_eof pos %d:%d\n", rec->FileIndex,
+ Dmsg3(300, "Done FI=%d before set_eof pos %d:%d\n", rec->FileIndex,
dev->file, dev->block_num);
if (match_set_eof(jcr->bsr, rec) && try_repositioning(jcr, rec, dev)) {
- Dmsg2(300, "Break after match_set_eof pos %d:%d\n",
+ Dmsg2(300, "Break after match_set_eof pos %d:%d\n",
dev->file, dev->block_num);
break;
}
- Dmsg2(300, "After set_eof pos %d:%d\n", dev->file, dev->block_num);
+ Dmsg2(300, "After set_eof pos %d:%d\n", dev->file, dev->block_num);
}
} /* end for loop over records */
Dmsg2(300, "After end records position=(file:block) %d:%d\n", dev->file, dev->block_num);
}
if (bsr) {
if (verbose) {
- Jmsg(jcr, M_INFO, 0, "Reposition from (file:block) %d:%d to %d:%d\n",
+ Jmsg(jcr, M_INFO, 0, "Reposition from (file:block) %d:%d to %d:%d\n",
dev->file, dev->block_num, bsr->volfile->sfile,
bsr->volblock->sblock);
}
jcr->bsr->reposition = true; /* force repositioning */
bsr = find_next_bsr(jcr->bsr, dev);
if (bsr && (bsr->volfile->sfile != 0 || bsr->volblock->sblock != 0)) {
- Jmsg(jcr, M_INFO, 0, _("Forward spacing to file:block %u:%u.\n"),
+ Jmsg(jcr, M_INFO, 0, _("Forward spacing to file:block %u:%u.\n"),
bsr->volfile->sfile, bsr->volblock->sblock);
- Dmsg2(300, "Forward spacing to file:block %u:%u.\n",
+ Dmsg2(300, "Forward spacing to file:block %u:%u.\n",
bsr->volfile->sfile, bsr->volblock->sblock);
reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
}
#ifdef xxxxxSMCHECK
if (!sm_check_rtn(__FILE__, __LINE__, False)) {
/* We damaged a buffer */
- Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n"
+ Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n"
"rem=%d remainder=%d\n",
FI_to_ascii(rec->FileIndex), rec->VolSessionId,
stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
remlen, rec->remainder);
- Dmsg5(0, "Damaged block: bufp=%x binbuf=%d buf_len=%d rem=%d moved=%d\n",
+ Dmsg5(0, "Damaged block: bufp=%x binbuf=%d buf_len=%d rem=%d moved=%d\n",
block->bufp, block->binbuf, block->buf_len, block->buf_len-block->binbuf,
remlen);
- Dmsg2(0, "Damaged block: buf=%x binbuffrombuf=%d \n",
+ Dmsg2(0, "Damaged block: buf=%x binbuffrombuf=%d \n",
block->buf, block->bufp-block->buf);
- Emsg0(M_ABORT, 0, "Damaged buffer\n");
+ Emsg0(M_ABORT, 0, "Damaged buffer\n");
}
#endif
/* Clear state flags */
rec->state = 0;
- if (((DEVICE *)block->dev)->state & ST_TAPE) {
+ if (block->dev->is_tape()) {
rec->state |= REC_ISTAPE;
}
if (rec->remainder && (rec->VolSessionId != VolSessionId ||
rec->VolSessionTime != VolSessionTime)) {
rec->state |= REC_NO_MATCH;
- Dmsg0(450, "remainder and VolSession doesn't match\n");
+ Dmsg0(450, "remainder and VolSession doesn't match\n");
return false; /* This is from some other Session */
}
* of a previous partially written record.
*/
if (Stream < 0) { /* continuation record? */
- Dmsg1(500, "Got negative Stream => continuation. remainder=%d\n",
+ Dmsg1(500, "Got negative Stream => continuation. remainder=%d\n",
rec->remainder);
rec->state |= REC_CONTINUATION;
- if (!rec->remainder) { /* if we didn't read previously */
+ if (!rec->remainder) { /* if we didn't read previously */
rec->data_len = 0; /* return data as if no continuation */
} else if (rec->Stream != -Stream) {
rec->state |= REC_NO_MATCH;
}
Dmsg6(450, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n"
- "remlen=%d data_len=%d\n",
+ "remlen=%d data_len=%d\n",
FI_to_ascii(rec->FileIndex), rec->VolSessionId,
stream_to_ascii(rec->Stream, rec->FileIndex), data_bytes, remlen,
rec->data_len);
* then reread.
*/
Dmsg0(450, "read_record_block: nothing\n");
-#ifdef xxx
- if (!rec->remainder) {
- rec->remainder = 1; /* set to expect continuation */
- rec->data_len = 0; /* no data transferred */
- }
-#endif
rec->state |= (REC_NO_HEADER | REC_BLOCK_EMPTY);
empty_block(block); /* mark block empty */
return false;
stat = open_data_spool_file(jcr);
if (stat) {
jcr->dcr->spooling = true;
- Jmsg(jcr, M_INFO, 0, _("Spooling data ...\n"));
+ Jmsg(jcr, M_INFO, 0, _("Spooling data ...\n"));
P(mutex);
spool_stats.data_jobs++;
V(mutex);
Dmsg0(100, "Committing spooled data\n");
stat = despool_data(jcr->dcr, true /*commit*/);
if (!stat) {
- Pmsg1(000, "Bad return from despool WroteVol=%d\n", jcr->dcr->WroteVol);
+ Pmsg1(000, "Bad return from despool WroteVol=%d\n", jcr->dcr->WroteVol);
close_data_spool_file(jcr);
return false;
}
} else {
dir = working_directory;
}
- Mmsg(name, "%s/%s.data.spool.%s.%s", dir, my_name, jcr->Job, jcr->device->hdr.name);
+ Mmsg(name, "%s/%s.data.spool.%s.%s", dir, my_name, jcr->Job,
+ jcr->dcr->device->hdr.name);
}
} else if (stat != (ssize_t)rlen) {
if (stat == -1) {
berrno be;
- Jmsg(dcr->jcr, M_FATAL, 0, _("Spool header read error. ERR=%s\n"),
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Spool header read error. ERR=%s\n"),
be.strerror());
} else {
- Pmsg2(000, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
- Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool header read error. Wanted %u bytes, got %u\n"), rlen, stat);
+ Pmsg2(000, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
+ Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool header read error. Wanted %u bytes, got %u\n"), rlen, stat);
}
return RB_ERROR;
}
#ifdef xDEBUG
char ec1[30], ec2[30], ec3[30], ec4[30];
Dmsg4(100, "Despool in write_block_to_spool_file max_size=%s size=%s "
- "max_job_size=%s job_size=%s\n",
+ "max_job_size=%s job_size=%s\n",
edit_uint64_with_commas(dcr->max_spool_size, ec1),
edit_uint64_with_commas(dcr->spool_size, ec2),
edit_uint64_with_commas(dcr->dev->max_spool_size, ec3),
#endif
Jmsg(dcr->jcr, M_INFO, 0, _("User specified spool size reached.\n"));
if (!despool_data(dcr, false)) {
- Pmsg0(000, "Bad return from despool in write_block.\n");
+ Pmsg0(000, "Bad return from despool in write_block.\n");
return false;
}
/* Despooling cleared these variables so reset them */
stat = write(dcr->spool_fd, (char*)&hdr, sizeof(hdr));
if (stat == -1) {
berrno be;
- Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"),
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"),
be.strerror());
}
if (stat != (ssize_t)sizeof(hdr)) {
if (stat != -1) {
if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR) - stat) != 0) {
berrno be;
- Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
be.strerror());
return false;
}
}
if (!despool_data(dcr, false)) {
- Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
return false;
}
continue; /* try again */
stat = write(dcr->spool_fd, block->buf, (size_t)block->binbuf);
if (stat == -1) {
berrno be;
- Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing data to spool file. ERR=%s\n"),
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing data to spool file. ERR=%s\n"),
be.strerror());
}
if (stat != (ssize_t)block->binbuf) {
if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR)
- stat - sizeof(spool_hdr)) != 0) {
berrno be;
- Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
be.strerror());
return false;
}
}
if (!despool_data(dcr, false)) {
- Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
+ Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
return false;
}
if (!write_spool_header(dcr)) {
if (are_attributes_spooled(jcr)) {
if (fseek(jcr->dir_bsock->spool_fd, 0, SEEK_END) != 0) {
berrno be;
- Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"),
+ Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"),
be.strerror());
}
size = ftell(jcr->dir_bsock->spool_fd);
bnet_fsend(user, _("\nDevice status:\n"));
LockRes();
foreach_res(device, R_DEVICE) {
- for (dev=device->dev; dev; dev=dev->next) {
- if (dev_state(dev, ST_OPENED)) {
- if (dev_state(dev, ST_LABEL)) {
- bnet_fsend(user, _("Device \"%s\" is mounted with Volume \"%s\"\n"),
- dev_name(dev), dev->VolHdr.VolName);
- } else {
- bnet_fsend(user, _("Device \"%s\" open but no Bacula volume is mounted.\n"), dev_name(dev));
+ dev = device->dev;
+ if (dev->is_open()) {
+ if (dev->is_labeled()) {
+ bnet_fsend(user, _("Device \"%s\" is mounted with Volume \"%s\"\n"),
+ dev_name(dev), dev->VolHdr.VolName);
+ } else {
+ bnet_fsend(user, _("Device \"%s\" open but no Bacula volume is mounted.\n"), dev_name(dev));
+ }
+ send_blocked_status(jcr, dev);
+ if (dev_state(dev, ST_APPEND)) {
+ bpb = dev->VolCatInfo.VolCatBlocks;
+ if (bpb <= 0) {
+ bpb = 1;
}
- send_blocked_status(jcr, dev);
- if (dev_state(dev, ST_APPEND)) {
- bpb = dev->VolCatInfo.VolCatBlocks;
- if (bpb <= 0) {
- bpb = 1;
- }
- bpb = dev->VolCatInfo.VolCatBytes / bpb;
- bnet_fsend(user, _(" Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
- edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
- edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
- edit_uint64_with_commas(bpb, b3));
- } else { /* reading */
- bpb = dev->VolCatInfo.VolCatReads;
- if (bpb <= 0) {
- bpb = 1;
- }
- if (dev->VolCatInfo.VolCatRBytes > 0) {
- bpb = dev->VolCatInfo.VolCatRBytes / bpb;
- } else {
- bpb = 0;
- }
- bnet_fsend(user, _(" Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"),
- edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
- edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2),
- edit_uint64_with_commas(bpb, b3));
+ bpb = dev->VolCatInfo.VolCatBytes / bpb;
+ bnet_fsend(user, _(" Total Bytes=%s Blocks=%s Bytes/block=%s\n"),
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
+ edit_uint64_with_commas(bpb, b3));
+ } else { /* reading */
+ bpb = dev->VolCatInfo.VolCatReads;
+ if (bpb <= 0) {
+ bpb = 1;
}
- bnet_fsend(user, _(" Positioned at File=%s Block=%s\n"),
- edit_uint64_with_commas(dev->file, b1),
- edit_uint64_with_commas(dev->block_num, b2));
-
- } else {
- bnet_fsend(user, _("Device \"%s\" is not open.\n"), dev_name(dev));
- send_blocked_status(jcr, dev);
+ if (dev->VolCatInfo.VolCatRBytes > 0) {
+ bpb = dev->VolCatInfo.VolCatRBytes / bpb;
+ } else {
+ bpb = 0;
+ }
+ bnet_fsend(user, _(" Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"),
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
+ edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2),
+ edit_uint64_with_commas(bpb, b3));
}
+ bnet_fsend(user, _(" Positioned at File=%s Block=%s\n"),
+ edit_uint64_with_commas(dev->file, b1),
+ edit_uint64_with_commas(dev->block_num, b2));
+
+ } else {
+ bnet_fsend(user, _("Device \"%s\" is not open.\n"), dev_name(dev));
+ send_blocked_status(jcr, dev);
}
}
UnlockRes();
bnet_fsend(user, "\n");
bnet_fsend(user, _("Device status:\n"));
- bnet_fsend(user, "%sOPENED ", dev->state & ST_OPENED ? "" : "!");
- bnet_fsend(user, "%sTAPE ", dev->state & ST_TAPE ? "" : "!");
- bnet_fsend(user, "%sLABEL ", dev->state & ST_LABEL ? "" : "!");
+ bnet_fsend(user, "%sOPENED ", dev->is_open() ? "" : "!");
+ bnet_fsend(user, "%sTAPE ", dev->is_tape() ? "" : "!");
+ bnet_fsend(user, "%sLABEL ", dev->is_labeled() ? "" : "!");
bnet_fsend(user, "%sMALLOC ", dev->state & ST_MALLOC ? "" : "!");
- bnet_fsend(user, "%sAPPEND ", dev->state & ST_APPEND ? "" : "!");
- bnet_fsend(user, "%sREAD ", dev->state & ST_READ ? "" : "!");
- bnet_fsend(user, "%sEOT ", dev->state & ST_EOT ? "" : "!");
+ bnet_fsend(user, "%sAPPEND ", dev->can_append() ? "" : "!");
+ bnet_fsend(user, "%sREAD ", dev->can_read() ? "" : "!");
+ bnet_fsend(user, "%sEOT ", dev->at_eom() ? "" : "!");
bnet_fsend(user, "%sWEOT ", dev->state & ST_WEOT ? "" : "!");
- bnet_fsend(user, "%sEOF ", dev->state & ST_EOF ? "" : "!");
+ bnet_fsend(user, "%sEOF ", dev->at_eof() ? "" : "!");
bnet_fsend(user, "%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!");
bnet_fsend(user, "%sSHORT ", dev->state & ST_SHORT ? "" : "!");
bnet_fsend(user, "%sMOUNTED ", dev->state & ST_MOUNTED ? "" : "!");
bnet_fsend(user, "\n");
bnet_fsend(user, _("Device parameters:\n"));
- bnet_fsend(user, "Device name: %s\n", dev->dev_name);
+ bnet_fsend(user, "Archive name: %s Device name: %s\n", dev->dev_name,
+ dev->device->hdr.name);
bnet_fsend(user, "File=%u block=%u\n", dev->file, dev->block_num);
bnet_fsend(user, "Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
}
bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
job_type_to_str(jcr->JobType), jcr->Job);
}
- if (jcr->device) {
+ if (jcr->dcr && jcr->dcr->device) {
bstrncpy(JobName, jcr->Job, sizeof(JobName));
/* There are three periods after the Job name */
char *p;
job_type_to_str(jcr->JobType),
JobName,
jcr->JobId,
- jcr->dcr?jcr->dcr->VolumeName:"*none*",
- jcr->device?jcr->device->device_name:"none");
+ jcr->dcr->VolumeName,
+ jcr->dcr->device->device_name);
sec = time(NULL) - jcr->run_time;
if (sec <= 0) {
sec = 1;
*
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
static void usage()
{
fprintf(stderr, _(
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
+"Copyright (C) 2000-2005 Kern Sibbald.\n"
"\nVersion: " VERSION " (" BDATE ")\n\n"
"Usage: stored [options] [-c config_file] [config_file]\n"
" -c <file> use <file> as configuration file\n"
init_signals(terminate_stored);
}
-
if (configfile == NULL) {
configfile = bstrdup(CONFIG_FILE);
}
*/
VolSessionTime = (long)daemon_start_time;
if (VolSessionTime == 0) { /* paranoid */
- Emsg0(M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
+ Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
}
/* Make sure on Solaris we can run concurrent, watch dog + servers + misc */
me = (STORES *)GetNextRes(R_STORAGE, NULL);
if (!me) {
UnlockRes();
- Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
+ Jmsg1(NULL, M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
configfile);
}
if (GetNextRes(R_STORAGE, (RES *)me) != NULL) {
UnlockRes();
- Emsg1(M_ERROR_TERM, 0, _("Only one Storage resource permitted in %s\n"),
+ Jmsg1(NULL, M_ERROR_TERM, 0, _("Only one Storage resource permitted in %s\n"),
configfile);
}
if (GetNextRes(R_DIRECTOR, NULL) == NULL) {
UnlockRes();
- Emsg1(M_ERROR_TERM, 0, _("No Director resource defined in %s. Cannot continue.\n"),
+ Jmsg1(NULL, M_ERROR_TERM, 0, _("No Director resource defined in %s. Cannot continue.\n"),
configfile);
}
if (GetNextRes(R_DEVICE, NULL) == NULL){
UnlockRes();
- Emsg1(M_ERROR_TERM, 0, _("No Device resource defined in %s. Cannot continue.\n"),
+ Jmsg1(NULL, M_ERROR_TERM, 0, _("No Device resource defined in %s. Cannot continue.\n"),
configfile);
}
if (!me->messages) {
me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
if (!me->messages) {
- Emsg1(M_ERROR_TERM, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
+ Jmsg1(NULL, M_ERROR_TERM, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
configfile);
}
}
UnlockRes();
if (!me->working_directory) {
- Emsg1(M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
+ Jmsg1(NULL, M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"),
configfile);
}
}
/*
- * We are started as a separate thread. The
- * resources are alread locked.
+ * Here we attempt to init and open each device. This is done
+ * once at startup in a separate thread.
*/
extern "C"
void *device_allocation(void *arg)
device->dev = init_dev(NULL, device);
Dmsg1(10, "SD init done %s\n", device->device_name);
if (!device->dev) {
- Emsg1(M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
+ Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
continue;
}
if (device->cap_bits & CAP_ALWAYSOPEN) {
- Dmsg1(20, "calling first_open_device %s\n", device->device_name);
+ Dmsg1(20, "calling first_open_device %s\n", device->device_name);
if (!first_open_device(device->dev)) {
- Emsg1(M_ERROR, 0, _("Could not open device %s\n"), device->device_name);
+ Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), device->device_name);
}
}
if (device->cap_bits & CAP_AUTOMOUNT && device->dev &&
/* Initialize FD start condition variable */
int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
if (errstat != 0) {
- Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
+ Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
}
- jcr->device = device;
dcr = new_dcr(jcr, device->dev);
switch (read_dev_volume_label(dcr)) {
- case VOL_OK:
- memcpy(&dcr->dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dcr->dev->VolCatInfo));
- break;
- default:
- Emsg1(M_WARNING, 0, _("Could not mount device %s\n"), device->device_name);
- break;
+ case VOL_OK:
+ memcpy(&dcr->dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dcr->dev->VolCatInfo));
+ break;
+ default:
+ Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), device->device_name);
+ break;
}
free_jcr(jcr);
}
fd = jcr->file_bsock;
if (fd) {
fd->timed_out = true;
- Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
+ Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId);
pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
- if (jcr->device && jcr->device->dev && jcr->device->dev->dev_blocked) {
- pthread_cond_signal(&jcr->device->dev->wait_next_vol);
+ /* ***FIXME*** wiffle through all dcrs */
+ if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
+ pthread_cond_signal(&jcr->dcr->dev->wait_next_vol);
}
bmicrosleep(0, 50000);
}
{NULL, NULL, 0, 0, 0, 0}
};
+/* Autochanger definition */
+static RES_ITEM changer_items[] = {
+ {"name", store_name, ITEM(res_changer.hdr.name), 0, ITEM_REQUIRED, 0},
+ {"description", store_str, ITEM(res_changer.hdr.desc), 0, 0, 0},
+ {"device", store_alist_res, ITEM(res_changer.device), R_DEVICE, ITEM_REQUIRED, 0},
+ {"changerdevice", store_strname, ITEM(res_changer.changer_name), 0, 0, 0},
+ {"changercommand", store_strname, ITEM(res_changer.changer_command), 0, 0, 0},
+ {NULL, NULL, 0, 0, 0, 0}
+};
+
+
// {"mountanonymousvolumes", store_yesno, ITEM(res_dev.cap_bits), CAP_ANONVOLS, ITEM_DEFAULT, 0},
/* This is the master resource definition */
RES_TABLE resources[] = {
- {"director", dir_items, R_DIRECTOR},
- {"storage", store_items, R_STORAGE},
- {"device", dev_items, R_DEVICE},
- {"messages", msgs_items, R_MSGS},
- {NULL, NULL, 0}
+ {"director", dir_items, R_DIRECTOR},
+ {"storage", store_items, R_STORAGE},
+ {"device", dev_items, R_DEVICE},
+ {"messages", msgs_items, R_MSGS},
+ {"autochanger", changer_items, R_AUTOCHANGER},
+ {NULL, NULL, 0}
};
sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
- strcpy(buf, " ");
+ bstrncpy(buf, " ", sizeof(buf));
if (res->res_dev.cap_bits & CAP_EOF) {
bstrncat(buf, "CAP_EOF ", sizeof(buf));
}
bstrncat(buf, "\n", sizeof(buf));
sendit(sock, buf);
break;
+ case R_AUTOCHANGER:
+ DEVRES *dev;
+ sendit(sock, "Changer: name=%s Changer_devname=%s Changer_cmd=%s\n",
+ res->res_changer.hdr.name,
+ res->res_changer.changer_name, res->res_changer.changer_command);
+ foreach_alist(dev, res->res_changer.device) {
+ sendit(sock, " --->Device: name=%s\n", dev->hdr.name);
+ }
+ bstrncat(buf, "\n", sizeof(buf));
+ sendit(sock, buf);
+ break;
case R_MSGS:
sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
if (res->res_msgs.mail_cmd)
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;
- case R_STORAGE:
- if (res->res_store.sdaddrs) {
- free_addresses(res->res_store.sdaddrs);
- }
- if (res->res_store.sddaddrs) {
- free_addresses(res->res_store.sddaddrs);
- }
- 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);
- }
- if (res->res_dev.changer_name) {
- free(res->res_dev.changer_name);
- }
- if (res->res_dev.changer_command) {
- free(res->res_dev.changer_command);
- }
- if (res->res_dev.alert_command) {
- free(res->res_dev.alert_command);
- }
- if (res->res_dev.spool_directory) {
- free(res->res_dev.spool_directory);
- }
- if (res->res_dev.mount_point) {
- free(res->res_dev.mount_point);
- }
- if (res->res_dev.mount_command) {
- free(res->res_dev.mount_command);
- }
- if (res->res_dev.unmount_command) {
- free(res->res_dev.unmount_command);
- }
- if (res->res_dev.write_part_command) {
- free(res->res_dev.write_part_command);
- }
- if (res->res_dev.free_space_command) {
- free(res->res_dev.free_space_command);
- }
- 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;
- default:
- Dmsg1(0, "Unknown resource type %d\n", type);
- break;
+ case R_DIRECTOR:
+ if (res->res_dir.password) {
+ free(res->res_dir.password);
+ }
+ if (res->res_dir.address) {
+ free(res->res_dir.address);
+ }
+ break;
+ case R_AUTOCHANGER:
+ if (res->res_changer.changer_name) {
+ free(res->res_changer.changer_name);
+ }
+ if (res->res_changer.changer_command) {
+ free(res->res_changer.changer_command);
+ }
+ case R_STORAGE:
+ if (res->res_store.sdaddrs) {
+ free_addresses(res->res_store.sdaddrs);
+ }
+ if (res->res_store.sddaddrs) {
+ free_addresses(res->res_store.sddaddrs);
+ }
+ 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);
+ }
+ if (res->res_dev.changer_name) {
+ free(res->res_dev.changer_name);
+ }
+ if (res->res_dev.changer_command) {
+ free(res->res_dev.changer_command);
+ }
+ if (res->res_dev.alert_command) {
+ free(res->res_dev.alert_command);
+ }
+ if (res->res_dev.spool_directory) {
+ free(res->res_dev.spool_directory);
+ }
+ if (res->res_dev.mount_point) {
+ free(res->res_dev.mount_point);
+ }
+ if (res->res_dev.mount_command) {
+ free(res->res_dev.mount_command);
+ }
+ if (res->res_dev.unmount_command) {
+ free(res->res_dev.unmount_command);
+ }
+ if (res->res_dev.write_part_command) {
+ free(res->res_dev.write_part_command);
+ }
+ if (res->res_dev.free_space_command) {
+ free(res->res_dev.free_space_command);
+ }
+ 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;
+ default:
+ Dmsg1(0, "Unknown resource type %d\n", type);
+ break;
}
/* Common stuff again -- free the resource, recurse to next one */
if (res) {
/* Save the new resource by chaining it into the head list for
* the resource. If this is pass 2, we update any resource
- * pointers (currently only in the Job resource).
+ * or alist pointers.
*/
void save_resource(int type, RES_ITEM *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) {
- Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource \"%s\"\n", res_all.res_dir.hdr.name);
- }
- res->res_store.messages = res_all.res_store.messages;
- break;
- default:
- printf("Unknown resource type %d\n", type);
- error = 1;
- break;
+ /* Resources not containing a resource */
+ case R_DIRECTOR:
+ case R_DEVICE:
+ case R_MSGS:
+ break;
+
+ /* Resources containing a resource or an alist */
+ case R_STORAGE:
+ if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+ Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource \"%s\"\n", res_all.res_dir.hdr.name);
+ }
+ res->res_store.messages = res_all.res_store.messages;
+ break;
+ case R_AUTOCHANGER:
+ if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) {
+ Emsg1(M_ERROR_TERM, 0, "Cannot find AutoChanger resource %s\n",
+ res_all.res_changer.hdr.name);
+ }
+ /* we must explicitly copy the device alist pointer */
+ res->res_changer.device = res_all.res_changer.device;
+ break;
+ default:
+ printf("Unknown resource type %d\n", type);
+ error = 1;
+ break;
}
case R_MSGS:
size = sizeof(MSGS);
break;
+ case R_AUTOCHANGER:
+ size = sizeof(AUTOCHANGER);
+ break;
default:
printf("Unknown resource type %d\n", type);
error = 1;
R_STORAGE,
R_DEVICE,
R_MSGS,
+ R_AUTOCHANGER,
R_FIRST = R_DIRECTOR,
- R_LAST = R_MSGS /* keep this updated */
+ R_LAST = R_AUTOCHANGER /* keep this updated */
};
enum {
/* Definition of the contents of each Resource */
-struct DIRRES {
- RES hdr;
+class DIRRES {
+public:
+ RES hdr;
- char *password; /* Director password */
- char *address; /* Director IP address or zero */
- int enable_ssl; /* Use SSL with this Director */
- int monitor; /* Have only access to status and .status functions */
+ char *password; /* Director password */
+ char *address; /* Director IP address or zero */
+ int enable_ssl; /* Use SSL with this Director */
+ int monitor; /* Have only access to status and .status functions */
};
/* Storage daemon "global" definitions */
-struct s_res_store {
- RES hdr;
+class s_res_store {
+public:
+ RES hdr;
dlist *sdaddrs;
dlist *sddaddrs;
- char *working_directory; /* working directory for checkpoints */
+ char *working_directory; /* working directory for checkpoints */
char *pid_directory;
char *subsys_directory;
- int require_ssl; /* Require SSL on all connections */
+ int require_ssl; /* Require SSL on all connections */
uint32_t max_concurrent_jobs; /* maximum concurrent jobs to run */
- MSGS *messages; /* Daemon message handler */
- utime_t heartbeat_interval; /* Interval to send hb to FD */
+ MSGS *messages; /* Daemon message handler */
+ utime_t heartbeat_interval; /* Interval to send hb to FD */
};
typedef struct s_res_store STORES;
/* Device specific definitions */
-struct DEVRES {
- RES hdr;
-
- char *media_type; /* User assigned media type */
- char *device_name; /* Archive device name */
- char *changer_name; /* Changer device name */
- char *changer_command; /* Changer command -- external program */
- char *alert_command; /* Alert command -- external program */
- char *spool_directory; /* Spool file directory */
- uint32_t drive_index; /* Autochanger drive index */
- uint32_t cap_bits; /* Capabilities of this device */
- uint32_t max_changer_wait; /* Changer timeout */
- uint32_t max_rewind_wait; /* maximum secs to wait for rewind */
- uint32_t max_open_wait; /* maximum secs to wait for open */
- uint32_t max_open_vols; /* maximum simultaneous open volumes */
- uint32_t min_block_size; /* min block size */
- uint32_t max_block_size; /* max block size */
- uint32_t max_volume_jobs; /* max jobs to put on one volume */
+class DEVRES {
+public:
+ RES hdr;
+
+ char *media_type; /* User assigned media type */
+ char *device_name; /* Archive device name */
+ char *changer_name; /* Changer device name */
+ char *changer_command; /* Changer command -- external program */
+ char *alert_command; /* Alert command -- external program */
+ char *spool_directory; /* Spool file directory */
+ uint32_t drive_index; /* Autochanger drive index */
+ uint32_t cap_bits; /* Capabilities of this device */
+ uint32_t max_changer_wait; /* Changer timeout */
+ uint32_t max_rewind_wait; /* maximum secs to wait for rewind */
+ uint32_t max_open_wait; /* maximum secs to wait for open */
+ uint32_t max_open_vols; /* maximum simultaneous open volumes */
+ uint32_t min_block_size; /* min block size */
+ uint32_t max_block_size; /* max block size */
+ uint32_t max_volume_jobs; /* max jobs to put on one volume */
uint32_t max_network_buffer_size; /* max network buf size */
- utime_t vol_poll_interval; /* interval between polling volume during mount */
- int64_t max_volume_files; /* max files to put on one volume */
- 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 */
- int64_t max_spool_size; /* Max spool size for all jobs */
- int64_t max_job_spool_size; /* Max spool size for any single job */
+ utime_t vol_poll_interval; /* interval between polling volume during mount */
+ int64_t max_volume_files; /* max files to put on one volume */
+ 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 */
+ int64_t max_spool_size; /* Max spool size for all jobs */
+ int64_t max_job_spool_size; /* Max spool size for any single job */
- int64_t max_part_size; /* Max part size */
- char *mount_point; /* Mount point for require mount devices */
- char *mount_command; /* Mount command */
- char *unmount_command; /* Unmount command */
- char *write_part_command; /* Write part command */
- char *free_space_command; /* Free space command */
+ int64_t max_part_size; /* Max part size */
+ char *mount_point; /* Mount point for require mount devices */
+ char *mount_command; /* Mount command */
+ char *unmount_command; /* Unmount command */
+ char *write_part_command; /* Write part command */
+ char *free_space_command; /* Free space command */
- DEVICE *dev; /* Pointer to phyical dev -- set at runtime */
+ DEVICE *dev; /* Pointer to phyical dev -- set at runtime */
+};
+
+class AUTOCHANGER {
+public:
+ RES hdr;
+ alist *device;
+ char *changer_name; /* Changer device name */
+ char *changer_command; /* Changer command -- external program */
};
union URES {
- DIRRES res_dir;
- STORES res_store;
- DEVRES res_dev;
- MSGS res_msgs;
- RES hdr;
+ DIRRES res_dir;
+ STORES res_store;
+ DEVRES res_dev;
+ MSGS res_msgs;
+ AUTOCHANGER res_changer;
+ RES hdr;
};
/* */
#undef VERSION
-#define VERSION "1.37.2"
-#define BDATE "12 January 2005"
-#define LSMDATE "12Jan05"
+#define VERSION "1.37.3"
+#define BDATE "28 January 2005"
+#define LSMDATE "28Jan05"
/* Debug flags */
#undef DEBUG