]> git.sur5r.net Git - bacula/bacula/commitdiff
Update to cygwin 1.5.5+add slots=1,3... code
authorKern Sibbald <kern@sibbald.com>
Tue, 18 Nov 2003 21:05:27 +0000 (21:05 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 18 Nov 2003 21:05:27 +0000 (21:05 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@808 91ce42f0-d328-0410-95d8-f526ca767f89

37 files changed:
bacula/ChangeLog
bacula/Makefile.in
bacula/ReleaseNotes
bacula/autoconf/configure.in
bacula/configure
bacula/kernstodo
bacula/platforms/redhat/bacula-dir.in
bacula/platforms/redhat/bacula-fd.in
bacula/platforms/redhat/bacula-sd.in
bacula/src/cats/.cvsignore
bacula/src/cats/Makefile.in
bacula/src/cats/cats.h
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_sqlite_tables.in
bacula/src/cats/protos.h
bacula/src/cats/sql_create.c
bacula/src/cats/sql_update.c
bacula/src/cats/update_bacula_tables.in [new file with mode: 0755]
bacula/src/cats/update_mysql_tables.in [new file with mode: 0755]
bacula/src/cats/update_sqlite_tables.in [new file with mode: 0755]
bacula/src/dird/bacula-dir.conf.in
bacula/src/dird/run_conf.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_select.c
bacula/src/filed/win32/Makefile.in
bacula/src/filed/win32/bin/chown.exe
bacula/src/filed/win32/bin/cygwin1.dll
bacula/src/filed/win32/bin/cygz.dll
bacula/src/filed/win32/bin/mount.exe
bacula/src/filed/win32/bin/sh.exe
bacula/src/filed/win32/bin/umount.exe
bacula/src/lib/scan.c
bacula/src/stored/askdir.c
bacula/src/stored/dircmd.c
bacula/src/tools/Makefile.in
bacula/src/version.h

index 16c0ee65f6b6ba763c0023d93362a7044b9ba7c5..6f2a41164198a35a67fc29ccc85bd39f245d73c3 100644 (file)
@@ -1,4 +1,84 @@
 
 
+2003-11-xx Version 1.33  xxNov03
+18Nov03
+- Start daemons at level 90 rather than 20 so that MySQL will already
+  be started.
+- Write alter_mysql_tables.in and alter_sqlite_tables.in
+- Add Drive and InChanger to Media record.
+- Update database level to 7.
+- Add db_make_inchanger_unique() and call it when creating and updating
+  the Media record.
+- Add Drive and InChanger to database code for Media record.
+- Allow changing InChanger flag in update command.
+- First cut at allowing the user to specify slots for updating autochanger.
+- Add scan to "update slots scan".
+- Add command in SD to readlabel.
+15Nov03
+- In the bacula start/stop script, ordered the stop: FD SD Dir to
+  give the SD the best chances of updating the catalog before dying.
+- Add Drive and InChanger to MEDIA_DBR record and to Volume update
+  from the SD.
+- Reorganize the Volume info update from SD so that the Dir sends back the
+  current information in case the Volume status has changed by expiring.
+  The DIR-SD protocol is not backward compatible (must update).
+- Fixed the signal handler to pass the signal to the exit_handler() 
+  previously it passed 1.
+- Modified SD so that on normal shutdown, it walks through all jcrs and
+  cancels them so that the Volume status will be updated in the catalog.
+- Found and fixed a bug where ST_LABEL was not set in append mode
+  (when a different tape was accepted other than the original one
+  proposed by the DIR.
+- Update the catalog Volume info after dev->file is incremented rather
+  than waiting for end of job.
+12Nov03
+- Change getdomainname() prototype for Darwin.
+- Add gethost_strerror() to create correct error message for
+  gethostbyname().
+- After doing a kill() of a stalled connection in watchdog, turn off
+  the timer to prevent an infinite loop.
+- Allow Bacula to rewrite the label on a disk volume.
+- Correct usage report printed by bsmtp.
+11Nov03
+- Complete changing references to bsmtp from smtp.
+- Add L_NONE for Admin and Restore jobs and update level_to_str()
+- Fix segfault from double free of RestoreBootstrap in job.c
+10Nov03
+- Change console to bconsole
+- Change console.conf to bconsole.conf
+- Change smtp to bsmtp
+- Implement .bconsolerc
+- Check if volume has expired when doing an update media for the SD
+09Nov03
+- Implement new code that assures that a non-zero Slot is unique within
+  a given Pool. When setting a non-zero Slot, the Slot of all other
+  Volumes with the same Slot is set to zero.
+07Nov03
+- Fix bug reported by Lars where an incorrect Volume name was printed
+  by the "status dir" command.
+06Nov03
+- Pretty up a few error messages printed by smtp.
+- Make btime_t int64_t so that one can do arithmetic.
+- Implement since as utime (64 bit UTC). 
+- Compute clock diff between Dir and FD, and adjust since time.
+- Apply SQL fix from Nic Bellamy (thanks).
+- Apply John's zlib #ifdefing fix.
+05Nov03
+- Add Dan's with-sd-user, ... to configure.in.
+- Add Dan's userid and group modifications to bacula.in
+- Lots of documentation updates.
+- Make console print "Enter a period to cancel a command" when starting.
+- Fix the "list nextvol" command so that it doesn't try to close the
+  database twice, giving a segfault.
+- Fix (hopefully) to dircmd.c so that a mount request does a pthread_cond_signal.
+  There was one path were the signal was not sent. This should fix the bug
+  that requires you to do two "mount" commands to free a job waiting on a mount.
+- Make dir_ask_sysop_to_mount_next_volume() return immediately if a slot is
+  specified.
+- Correct some of the messages in testfind.c (pointed out by Dan -- thanks).
+- Alias fd to client, sd to storage.
+- Changed order of Console commands so that short commands such as q (quit) 
+  are more logical.
+
 2003-11-03 Version 1.32d 02Nov03 Release
 02Nov03
 - Mainly a bug fix release.
 2003-11-03 Version 1.32d 02Nov03 Release
 02Nov03
 - Mainly a bug fix release.
index 0fb34b60f16763c4d6b35c9f0fa4a4dac6d0dbb1..fedea8aa3ffcb4f82a0f658677a90489403bf73e 100755 (executable)
@@ -120,9 +120,10 @@ Makefiles:
        chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
        chmod 755 src/cats/create_mysql_database
        chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
        chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
        chmod 755 src/cats/create_mysql_database
        chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
-       chmod 755 src/cats/alter_mysql_tables
+       chmod 755 src/cats/update_mysql_tables
        chmod 755 src/cats/create_sqlite_database
        chmod 755 src/cats/create_sqlite_database
-       chmod 755 src/cats/alter_sqlite_tables
+       chmod 755 src/cats/update_sqlite_tables
+       chomd 755 src/cats/update_bacula_tables
        chmod 755 src/cats/create_bdb_database
        chmod 755 src/cats/grant_mysql_privileges
 
        chmod 755 src/cats/create_bdb_database
        chmod 755 src/cats/grant_mysql_privileges
 
index a53eb61ac3ad8d16ce191cf6e62e6ebaab954973..4e851806ce62ba4d90d30247ca46a79a12f62639 100644 (file)
 
 
-          Release Notes for Bacula 1.32d
+          Release Notes for Bacula 1.33
 
   Bacula code: Total files = 259 Total lines = 78,087 (*.h *.c *.in)
 
 
   Bacula code: Total files = 259 Total lines = 78,087 (*.h *.c *.in)
 
-Most Significant Changes since 1.32c
-- Mainly a bug fix release.
-- Do a clean of both Gnome directories.
-- Require that FileSet id match when finding an Incremental
-  previous job. This was already the case for a Full.
-- Print message if no status returned from FD.
-- Correct "Do not forget to mount the drive" message. Test was
-  backward.
-- "status dir" stopped scanning the run records on the first
-  one that matched giving an incomplete listing.
-- Edit commas in Bytes on "estimate" command output.
+Most Significant Changes since 1.32d
+- Implement "update slots scan" that reads the volume label.
 
 
-Most Significant Changes since 1.32b
-- Implemented a RunAfterFailedJob record in the Job resource.
-- Implemented "delete job" command in the Console.
-- Gnome 2.0 console compiles and works. 
-- Implemented VerifyJob record in the Job resource
-  that tells Verify which job to verify (JobId not required) 
-- First cut Verify Disk to Catalog
-- Fix "status dir" to examine all run commands in Schedule.
-- Close unused file descriptors in bpipe.c
-- There is now a patch for FreeBSD 4.8 pthreads that
-  fixes the problems of data loss at the end of a tape.
-  Please see:
-  <bacula-source>/platforms/freebsd/pthreads-fix.txt
-- Fixed (I think) the elusive Windows "packet too big" bug.
-- Added %v to RunBefore/After editing codes. It edits in
-  a list of Volumes used for the job (not tested).
-
-Most Significant Changes since 1.32a:
-- Improve forward space file/block during restore, many
-  optimizations.
-- Fix a Bacula bug that did not allow appending to a tape    
-  on FreeBSD systems.
-- Fix pruning so that it will not prune the current job.
-- Modify configure to use non-threaded MySQL client lib if
-  the threaded version is not present.
-- Implement restore by file before date.
-- When pruning don't prune the current job.
-
-Major Changes 1.32a Release:
-- Implemented forward space file/block whenever possible 
-  during restore. Restoring a small number of files is now  
-  much faster.
-- There is a new option to restore that allows you   
-  to restore files based on their Filename. You can
-  also specify a file to read which contains the list.
-- Added ClientRunBeforeJob and ClientRunAfterJob.
-- Implemented Include | and < in File daemon.
-- Automatic labeling of tape Volumes should work now.
-- Recycling has been completely restructured and should work.
-- Implemented full length time interval qualifiers (e.g
-  "5n is now "5 min" or "5 minutes". A modifier is now required!
-- Fixed gnome-console to compile with RH9 (Gnome 2.0)
-- Implemented "list nextvol job=xxx", which displays the
-  next volume to be used by job xxx. The Volume name to
-  be used is also added to the "status dir" output.
-- Lots of fixes with variable expansion and counter variables
-- Implemented a new Include/Exclude syntax.
-- While writing a tape, an end of file mark will be written
-  every 1Gb. This makes restores faster. If you want to
-  change this use "Maximum File Size" in the SD Device
-  resource.
-
-
-Other Changes 1.32a Release:
-- Fixed sparse file bug.
-- A warning message is sent when a job starts that will be
-  blocked because the user did an "unmount".
-- Block checksum errors if any are printed in the job report.
-- Implemented a single routine to read_records. It also returns
-  a different record packet for each session.  This means
-  that multiple simultaneous jobs should work.
-- Added SDConnectTimeout to FD.    
-- Lots of doc enhancements
-- Fixed a PurgeOldestVolume bug (VolStatus not returned)
-- Don't crash if DB address record not specified.
-- Return VolStatus on find_next_volume.
-- Use alist for incexe name_list.
-- Use bget_dirmsg() everywhere possible when talking to FD.
-- Delete old semaphore job and workq job scheduling code.
-- edit_run_codes in one place (/lib)  Add Job name
-- Update query.sql to find current backups correctly.
-- Correct ambiguous SQL statement for pruning.
-- Set heartbeat interval to zero by default.
-- Fix a possible race condition in stopping the 
-  heartbeat thread.
-- Eliminate gnome2-console directory. Everything is in gnome-console
-- Enhanced "packet too big" message to indicate who sent it.
-- Corrected console prompt problem in non-readline versions.
-- Correct a number of variable expansion problems.
-- Added a number of new regression tests.
-- In an attempt to make configuration a bit less confusing, I've changed
-  the name of a number of variables. The old ones still work, but will
-  be phased out over time. FDAddress, FDPassword, SDAddress SDPassword,
-  SDDeviceName, and DBPassword.
-- A possible fix to the very intermittent SD crashes that Alex gets.
-              
 
 
 Items to note:  !!!!!
 
 
 Items to note:  !!!!!
-- Modifiers (sec, min, hour, day, ...) are now required on conf file
-  time interval specifications.
-- Duplicate names within the same conf resource are prohibited.
-- If you have used a prior BETA version of 1.32, please do
-  the following to cleanup any zero length spool files:
+- The daemon protocol has changed, you must update everything at once.
+- The database level has been updated. You must either re-initialize
+  your databases with:
+   
+    ./drop_bacula_tables
+    ./make_bacula_tables
 
 
-   cd <working-directory-as-in-Bacula-conf>
-   rm -f *.spool.*
+  which will delete ALL prior catalog information, or you can
+  update your database with:
 
 
-  Please be sure there are no spaces between the asterisks
-  and the periods.
+    ./alter_bacula_tables
index 664b8f0a34ac220675351bc08e3c5322d0f7c6d0..91207688a165c2ee4a7cb9f5875f84aff00eaa49 100644 (file)
@@ -1518,14 +1518,14 @@ AC_OUTPUT([autoconf/Make.common \
           src/cats/Makefile \
           src/cats/make_catalog_backup \
           src/cats/delete_catalog_backup \
           src/cats/Makefile \
           src/cats/make_catalog_backup \
           src/cats/delete_catalog_backup \
-          src/cats/alter_mysql_tables \
           src/cats/make_mysql_tables \
           src/cats/drop_mysql_tables \
           src/cats/make_mysql_tables \
           src/cats/drop_mysql_tables \
+          src/cats/update_mysql_tables \
           src/cats/create_mysql_database \
           src/cats/grant_mysql_privileges \
           src/cats/create_mysql_database \
           src/cats/grant_mysql_privileges \
-          src/cats/alter_sqlite_tables \
           src/cats/make_sqlite_tables \
           src/cats/drop_sqlite_tables \
           src/cats/make_sqlite_tables \
           src/cats/drop_sqlite_tables \
+          src/cats/update_sqlite_tables \
           src/cats/create_sqlite_database \
           src/cats/sqlite \
           src/cats/mysql \
           src/cats/create_sqlite_database \
           src/cats/sqlite \
           src/cats/mysql \
@@ -1534,6 +1534,7 @@ AC_OUTPUT([autoconf/Make.common \
           src/cats/drop_bdb_tables \
           src/cats/make_bacula_tables \
           src/cats/drop_bacula_tables \
           src/cats/drop_bdb_tables \
           src/cats/make_bacula_tables \
           src/cats/drop_bacula_tables \
+          src/cats/update_bacula_tables \
           src/findlib/Makefile \
           src/tools/Makefile \
           $PFILES ],  
           src/findlib/Makefile \
           src/tools/Makefile \
           $PFILES ],  
@@ -1548,12 +1549,12 @@ chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables
 chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
 chmod 755 src/cats/create_mysql_database 
 chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
 chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
 chmod 755 src/cats/create_mysql_database 
 chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
-chmod 755 src/cats/alter_mysql_tables
 chmod 755 src/cats/grant_mysql_privileges
 chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables 
 chmod 755 src/cats/make_bacula_tables src/cats/drop_bacula_tables 
 chmod 755 src/cats/grant_mysql_privileges
 chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables 
 chmod 755 src/cats/make_bacula_tables src/cats/drop_bacula_tables 
+chmod 755 src/cats/update_bacula_tables src/cats/update_mysql_tables
+chmod 755 src/cats/update/mysql_tables
 chmod 755 src/cats/create_sqlite_database
 chmod 755 src/cats/create_sqlite_database
-chmod 755 src/cats/alter_sqlite_tables
 chmod 755 src/cats/sqlite
 chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables 
 chmod 755 src/cats/create_bdb_database
 chmod 755 src/cats/sqlite
 chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables 
 chmod 755 src/cats/create_bdb_database
index 5e93cb11a1c13c670763b232f3a52878a79992d5..258c1663faedbfe77c25573e36b87411500d987c 100755 (executable)
@@ -17576,7 +17576,7 @@ if test "x${subsysdir}" = "x${sbindir}" ; then
    exit 1
 fi
 
    exit 1
 fi
 
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/fd scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/mtx-changer 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/tconsole/Makefile 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/alter_mysql_tables src/cats/make_mysql_tables src/cats/drop_mysql_tables src/cats/create_mysql_database src/cats/grant_mysql_privileges src/cats/alter_sqlite_tables src/cats/make_sqlite_tables src/cats/drop_sqlite_tables src/cats/create_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/make_bdb_tables src/cats/drop_bdb_tables src/cats/make_bacula_tables src/cats/drop_bacula_tables src/findlib/Makefile src/tools/Makefile $PFILES"
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ac_config_files="$ac_config_files autoconf/Make.common Makefile rescue/Makefile rescue/linux/Makefile rescue/freebsd/Makefile rescue/solaris/Makefile scripts/startmysql scripts/stopmysql scripts/btraceback scripts/startit scripts/stopit scripts/bconsole scripts/gconsole scripts/bacula scripts/fd scripts/Makefile scripts/logrotate scripts/bacula.desktop.gnome1 scripts/bacula.desktop.gnome2 scripts/mtx-changer 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/tconsole/Makefile 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/make_mysql_tables src/cats/drop_mysql_tables src/cats/update_mysql_tables src/cats/create_mysql_database src/cats/grant_mysql_privileges src/cats/make_sqlite_tables src/cats/drop_sqlite_tables src/cats/update_sqlite_tables src/cats/create_sqlite_database src/cats/sqlite src/cats/mysql src/cats/create_bdb_database src/cats/make_bdb_tables src/cats/drop_bdb_tables src/cats/make_bacula_tables src/cats/drop_bacula_tables src/cats/update_bacula_tables src/findlib/Makefile src/tools/Makefile $PFILES"
           ac_config_commands="$ac_config_commands default"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
           ac_config_commands="$ac_config_commands default"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
   "src/cats/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/cats/Makefile" ;;
   "src/cats/make_catalog_backup" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_catalog_backup" ;;
   "src/cats/delete_catalog_backup" ) CONFIG_FILES="$CONFIG_FILES src/cats/delete_catalog_backup" ;;
   "src/cats/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/cats/Makefile" ;;
   "src/cats/make_catalog_backup" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_catalog_backup" ;;
   "src/cats/delete_catalog_backup" ) CONFIG_FILES="$CONFIG_FILES src/cats/delete_catalog_backup" ;;
-  "src/cats/alter_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/alter_mysql_tables" ;;
   "src/cats/make_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_mysql_tables" ;;
   "src/cats/drop_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_mysql_tables" ;;
   "src/cats/make_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_mysql_tables" ;;
   "src/cats/drop_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_mysql_tables" ;;
+  "src/cats/update_mysql_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_mysql_tables" ;;
   "src/cats/create_mysql_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_mysql_database" ;;
   "src/cats/grant_mysql_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_mysql_privileges" ;;
   "src/cats/create_mysql_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_mysql_database" ;;
   "src/cats/grant_mysql_privileges" ) CONFIG_FILES="$CONFIG_FILES src/cats/grant_mysql_privileges" ;;
-  "src/cats/alter_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/alter_sqlite_tables" ;;
   "src/cats/make_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_sqlite_tables" ;;
   "src/cats/drop_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite_tables" ;;
   "src/cats/make_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_sqlite_tables" ;;
   "src/cats/drop_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_sqlite_tables" ;;
+  "src/cats/update_sqlite_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_sqlite_tables" ;;
   "src/cats/create_sqlite_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_sqlite_database" ;;
   "src/cats/sqlite" ) CONFIG_FILES="$CONFIG_FILES src/cats/sqlite" ;;
   "src/cats/mysql" ) CONFIG_FILES="$CONFIG_FILES src/cats/mysql" ;;
   "src/cats/create_sqlite_database" ) CONFIG_FILES="$CONFIG_FILES src/cats/create_sqlite_database" ;;
   "src/cats/sqlite" ) CONFIG_FILES="$CONFIG_FILES src/cats/sqlite" ;;
   "src/cats/mysql" ) CONFIG_FILES="$CONFIG_FILES src/cats/mysql" ;;
@@ -18162,6 +18162,7 @@ do
   "src/cats/drop_bdb_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_bdb_tables" ;;
   "src/cats/make_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_bacula_tables" ;;
   "src/cats/drop_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_bacula_tables" ;;
   "src/cats/drop_bdb_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_bdb_tables" ;;
   "src/cats/make_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/make_bacula_tables" ;;
   "src/cats/drop_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/drop_bacula_tables" ;;
+  "src/cats/update_bacula_tables" ) CONFIG_FILES="$CONFIG_FILES src/cats/update_bacula_tables" ;;
   "src/findlib/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/findlib/Makefile" ;;
   "src/tools/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/tools/Makefile" ;;
   "$PFILES" ) CONFIG_FILES="$CONFIG_FILES $PFILES" ;;
   "src/findlib/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/findlib/Makefile" ;;
   "src/tools/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/tools/Makefile" ;;
   "$PFILES" ) CONFIG_FILES="$CONFIG_FILES $PFILES" ;;
@@ -18937,12 +18938,12 @@ chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables
 chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
 chmod 755 src/cats/create_mysql_database
 chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
 chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
 chmod 755 src/cats/create_mysql_database
 chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
-chmod 755 src/cats/alter_mysql_tables
 chmod 755 src/cats/grant_mysql_privileges
 chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
 chmod 755 src/cats/make_bacula_tables src/cats/drop_bacula_tables
 chmod 755 src/cats/grant_mysql_privileges
 chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
 chmod 755 src/cats/make_bacula_tables src/cats/drop_bacula_tables
+chmod 755 src/cats/update_bacula_tables src/cats/update_mysql_tables
+chmod 755 src/cats/update/mysql_tables
 chmod 755 src/cats/create_sqlite_database
 chmod 755 src/cats/create_sqlite_database
-chmod 755 src/cats/alter_sqlite_tables
 chmod 755 src/cats/sqlite
 chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables
 chmod 755 src/cats/create_bdb_database
 chmod 755 src/cats/sqlite
 chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables
 chmod 755 src/cats/create_bdb_database
index 2dd8c85eb8d328ae877c7ef19215e584436abdab..ad5eecdb119ed1a618be754e977933661085ab90 100644 (file)
@@ -47,6 +47,31 @@ For 1.33 Testing/Documentation:
                 
 
 For 1.33
                 
 
 For 1.33
+- Optimize fsf not to read.
+- Use ioctl() fsf if it exists. Figure out where we are from
+  the mt_status command. Use slow fsf only if other does not work.
+- Add flag to write only one EOF mark on the tape.
+- Implement autochanger testing in btape "test" command.
+- Make sure that Volumes are recycled based on "Least recently used"
+  rather than lowest MediaId.
+- Implement RestoreJobRetention? Maybe better "JobRetention" in a Job,
+  which would take precidence over the Catalog "JobRetention".
+- Implement Label Format in Add and Label console commands.
+- Enhance "update slots" to include a "scan" feature
+  scan 1; scan 1-5; scan 1,2,4 ...  to update the catalog 
+- Allow a slot or range of slots on the label barcodes command.
+- Finish implementation of Verify=DiskToCatalog
+- Possibly up network buffers to 65K.
+- Keep last 5 or 10 completed jobs and show them in a similar list.
+- Make a Running Jobs: output similar to current Scheduled Jobs:
+- Optimize fsf not to read.
+- Use ioctl() fsf if it exists. Figure out where we are from
+  the mt_status command. Use slow fsf only if other does not work.
+- Add flag to write only one EOF mark on the tape.
+- Implement autochanger testing in btape "test" command.
+
+After 1.33:
+- Print warning message if FileId > 4 billion
 - do a "messages" before the first prompt in Console
 - Add a date and time stamp at the beginning of every line in the 
   Job report (Volker Sauer).
 - do a "messages" before the first prompt in Console
 - Add a date and time stamp at the beginning of every line in the 
   Job report (Volker Sauer).
@@ -117,29 +142,6 @@ For 1.33
   to start a job or pass its DHCP obtained IP number.
 - Implement multiple Consoles.
 - Implement a query tape prompt/replace feature for a console
   to start a job or pass its DHCP obtained IP number.
 - Implement multiple Consoles.
 - Implement a query tape prompt/replace feature for a console
-- Make sure that Volumes are recycled based on "Least recently used"
-  rather than lowest MediaId.
-- Implement RestoreJobRetention? Maybe better "JobRetention" in a Job,
-  which would take precidence over the Catalog "JobRetention".
-- Implement Label Format in Add and Label console commands.
-- Enhance "update slots" to include a "scan" feature
-  scan 1; scan 1-5; scan 1,2,4 ...  to update the catalog 
-- Allow a slot or range of slots on the label barcodes command.
-- Fix time difference problem between Bacula and Client
-  so that everything is in GMT.
-- Finish implementation of Verify=DiskToCatalog
-- Change console to bconsole.
-- Change smtp to bsmtp.
-- Possibly up network buffers to 65K.
-- Keep last 5 or 10 completed jobs and show them in a similar list.
-- Make a Running Jobs: output similar to current Scheduled Jobs:
-- Fix TimeZone problem!
-- Optimize fsf not to read.
-- Use ioctl() fsf if it exists. Figure out where we are from
-  the mt_status command. Use slow fsf only if other does
-  not work.
-- Add flag to write only one EOF mark on the tape.
-- Implement autochange testing in btape.
 - From Johan?
     Two jobs ready to go, first one blocked waiting for media
     Cancel 2nd job ("waiting execution" one)
 - From Johan?
     Two jobs ready to go, first one blocked waiting for media
     Cancel 2nd job ("waiting execution" one)
@@ -184,19 +186,9 @@ For 1.33
     gotten the CPU and created the file.  You must use atomic functions
     (those that don't get interrupted by other processes) and O_EXCL is
     the only way for this particular example.
     gotten the CPU and created the file.  You must use atomic functions
     (those that don't get interrupted by other processes) and O_EXCL is
     the only way for this particular example.
-- Mount a tape that is not right for the job (wrong # files on tape)
-  Bacula asks for another tape, fix problems with first tape and
-  say "mount". All works OK, but status shows:
-   Device /dev/nst0 open but no Bacula volume is mounted.
-       Total Bytes=1,153,820,213 Blocks=17,888 Bytes/block=64,502
-       Positioned at File=9 Block=3,951
-   Full Backup job Rufus.2003-10-26_16.45.31 using Volume "DLT-24Oct03" on device /dev/nst0
-       Files=21,003 Bytes=253,954,408 Bytes/sec=2,919,016
-       FDReadSeqNo=192,134 in_msg=129830 out_msg=5 fd=7
 - Automatically create pools, but instead of looking for what
   in in Job records, walk through the pool resources.
 - Check and double check tree code, why does it take so long?
 - Automatically create pools, but instead of looking for what
   in in Job records, walk through the pool resources.
 - Check and double check tree code, why does it take so long?
-- Upgrade to cygwin 1.5
 - Add device name to "Current Volume not acceptable because ..."
 - Make sure that Bacula rechecks the tape after the 20 min wait.
 - Set IO_NOWAIT on Bacula TCP/IP packets.
 - Add device name to "Current Volume not acceptable because ..."
 - Make sure that Bacula rechecks the tape after the 20 min wait.
 - Set IO_NOWAIT on Bacula TCP/IP packets.
@@ -648,11 +640,16 @@ Migration triggered by:
 It is somewhat like a Full save becomes an incremental since
 the Base job (or jobs) plus other non-base files.
 Need:
 It is somewhat like a Full save becomes an incremental since
 the Base job (or jobs) plus other non-base files.
 Need:
-- New BaseFile table that contains:
-    JobId, BaseJobId, FileId (from Base).
+- A Base backup is same as Full backup, just different type.
+- New BaseFiles table that contains:
+    BaseId - index
+    BaseJobId - Base JobId referenced for this FileId (needed ???)
+    JobId - JobId currently running
+    FileId - File not backed up, exists in Base Job
+    FileIndex - FileIndex from Base Job.
   i.e. for each base file that exists but is not saved because
   it has not changed, the File daemon sends the JobId, BaseId,
   i.e. for each base file that exists but is not saved because
   it has not changed, the File daemon sends the JobId, BaseId,
-  and FileId back to the Director who creates the DB entry.
+  FileId, FileIndex back to the Director who creates the DB entry.
 - To initiate a Base save, the Director sends the FD 
   the FileId, and full filename for each file in the Base.
 - When the FD finds a Base file, he requests the Director to
 - To initiate a Base save, the Director sends the FD 
   the FileId, and full filename for each file in the Base.
 - When the FD finds a Base file, he requests the Director to
@@ -890,3 +887,18 @@ Done: (see kernsdone for more)
 - Implement ClientRunBeforeJob and ClientRunAfterJob.
 - Implement forward spacing block/file: position_device(bsr) --
   just before read_block_from_device();
 - Implement ClientRunBeforeJob and ClientRunAfterJob.
 - Implement forward spacing block/file: position_device(bsr) --
   just before read_block_from_device();
+- Change console to bconsole.
+- Change smtp to bsmtp.
+- Fix time difference problem between Bacula and Client
+  so that everything is in GMT.
+- Fix TimeZone problem!
+- Mount a tape that is not right for the job (wrong # files on tape)
+  Bacula asks for another tape, fix problems with first tape and
+  say "mount". All works OK, but status shows:
+   Device /dev/nst0 open but no Bacula volume is mounted.
+       Total Bytes=1,153,820,213 Blocks=17,888 Bytes/block=64,502
+       Positioned at File=9 Block=3,951
+   Full Backup job Rufus.2003-10-26_16.45.31 using Volume "DLT-24Oct03" on device /dev/nst0
+       Files=21,003 Bytes=253,954,408 Bytes/sec=2,919,016
+       FDReadSeqNo=192,134 in_msg=129830 out_msg=5 fd=7
+- Upgrade to cygwin 1.5
index d568cdb9993601e05178347728debcded757e060..05fec1b7126a93012f9c2606d8e43b0240857a1b 100755 (executable)
@@ -3,7 +3,7 @@
 # bacula       This shell script takes care of starting and stopping
 #             the bacula Director daemon
 #
 # bacula       This shell script takes care of starting and stopping
 #             the bacula Director daemon
 #
-# chkconfig: 2345 20 99
+# chkconfig: 2345 90 99
 # description: It comes by night and sucks the vital essence from your computers.
 #
 #  For Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
 # description: It comes by night and sucks the vital essence from your computers.
 #
 #  For Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
index 19f04f028b35d82bf480378100d82adefa260bcb..8b725bc72222400b1b37247312b51562810e3a46 100755 (executable)
@@ -3,7 +3,7 @@
 # bacula       This shell script takes care of starting and stopping
 #             the bacula File daemon.
 #
 # bacula       This shell script takes care of starting and stopping
 #             the bacula File daemon.
 #
-# chkconfig: 2345 20 99
+# chkconfig: 2345 90 99
 # description: It comes by night and sucks the vital essence from your computers.
 #
 #  For Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
 # description: It comes by night and sucks the vital essence from your computers.
 #
 #  For Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
index a4bfdd4f5a47a7964286014c23ea26d0562a2be5..e58287625d338a806b1b1cdbae54ca4786577f9b 100755 (executable)
@@ -3,7 +3,7 @@
 # bacula       This shell script takes care of starting and stopping
 #             the bacula Storage daemon.
 #
 # bacula       This shell script takes care of starting and stopping
 #             the bacula Storage daemon.
 #
-# chkconfig: 2345 20 99
+# chkconfig: 2345 90 99
 # description: It comes by night and sucks the vital essence from your computers.
 #
 #  For Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
 # description: It comes by night and sucks the vital essence from your computers.
 #
 #  For Bacula release @VERSION@ (@DATE@) -- @DISTNAME@
index c2353f3f7f4924ead745671b30aa15892d7d5ff1..e7a8344a055032be555ceaedfd77da93a60c0523 100644 (file)
@@ -2,8 +2,6 @@
 Makefile
 make_catalog_backup
 delete_catalog_backup
 Makefile
 make_catalog_backup
 delete_catalog_backup
-alter_mysql_tables
-alter_sqlite_tables
 create_bdb_database
 create_mysql_database
 create_sqlite_database
 create_bdb_database
 create_mysql_database
 create_sqlite_database
@@ -20,3 +18,8 @@ mysql
 sqlite
 make_bacula_tables
 drop_bacula_tables
 sqlite
 make_bacula_tables
 drop_bacula_tables
+update.sql
+update2_sqlite_tables
+update_bacula_tables
+update_mysql_tables
+update_sqlite_tables
index e4ee4d48afc21b52d091c5b1fd655b0bf478d3fe..ad9ad1dafeb6215cbb5d4c386095e211b7ee9ca1 100644 (file)
@@ -64,8 +64,9 @@ realclean: clean
        $(RMF) create_mysql_database make_sqlite_tables sqlite
        $(RMF) create_bdb_database drop_bdb_tables make_dbd_tables
        $(RMF) make_catalog_backup delete_catalog_backup
        $(RMF) create_mysql_database make_sqlite_tables sqlite
        $(RMF) create_bdb_database drop_bdb_tables make_dbd_tables
        $(RMF) make_catalog_backup delete_catalog_backup
-       $(RMF) alter_mysql_tables alter_sqlite_tables create_sqlite_database
+       $(RMF) update_mysql_tables update_sqlite_tables create_sqlite_database
        $(RMF) drop_bacula_tables drop_sqlite_tables make_bacula_tables
        $(RMF) drop_bacula_tables drop_sqlite_tables make_bacula_tables
+       $(RMF) update_bacula_tables
        $(RMF) drop_bdb_tables make_bdb_tables mysql
 
 distclean: realclean
        $(RMF) drop_bdb_tables make_bdb_tables mysql
 
 distclean: realclean
@@ -76,8 +77,10 @@ install:
        $(INSTALL_SCRIPT) create_@DB_NAME@_database $(DESTDIR)$(scriptdir)/create_@DB_NAME@_database
        $(INSTALL_SCRIPT) drop_@DB_NAME@_tables $(DESTDIR)$(scriptdir)/drop_@DB_NAME@_tables
        $(INSTALL_SCRIPT) make_@DB_NAME@_tables $(DESTDIR)$(scriptdir)/make_@DB_NAME@_tables
        $(INSTALL_SCRIPT) create_@DB_NAME@_database $(DESTDIR)$(scriptdir)/create_@DB_NAME@_database
        $(INSTALL_SCRIPT) drop_@DB_NAME@_tables $(DESTDIR)$(scriptdir)/drop_@DB_NAME@_tables
        $(INSTALL_SCRIPT) make_@DB_NAME@_tables $(DESTDIR)$(scriptdir)/make_@DB_NAME@_tables
+       $(INSTALL_SCRIPT) update_@DB_NAME@_tables $(DESTDIR)$(scriptdir)/update_@DB_NAME@_tables
        $(INSTALL_SCRIPT) drop_bacula_tables $(DESTDIR)$(scriptdir)/drop_bacula_tables
        $(INSTALL_SCRIPT) make_bacula_tables $(DESTDIR)$(scriptdir)/make_bacula_tables
        $(INSTALL_SCRIPT) drop_bacula_tables $(DESTDIR)$(scriptdir)/drop_bacula_tables
        $(INSTALL_SCRIPT) make_bacula_tables $(DESTDIR)$(scriptdir)/make_bacula_tables
+       $(INSTALL_SCRIPT) update_bacula_tables $(DESTDIR)$(scriptdir)/update_bacula_tables
        $(INSTALL_SCRIPT) make_catalog_backup $(DESTDIR)$(scriptdir)/make_catalog_backup  
        $(INSTALL_SCRIPT) delete_catalog_backup $(DESTDIR)$(scriptdir)/delete_catalog_backup  
        $(INSTALL_SCRIPT) grant_mysql_privileges $(DESTDIR)$(scriptdir)/grant_mysql_privileges  
        $(INSTALL_SCRIPT) make_catalog_backup $(DESTDIR)$(scriptdir)/make_catalog_backup  
        $(INSTALL_SCRIPT) delete_catalog_backup $(DESTDIR)$(scriptdir)/delete_catalog_backup  
        $(INSTALL_SCRIPT) grant_mysql_privileges $(DESTDIR)$(scriptdir)/grant_mysql_privileges  
@@ -86,8 +89,10 @@ uninstall:
        (cd $(DESTDIR)$(scriptdir); $(RMF) create_@DB_NAME@_database)
        (cd $(DESTDIR)$(scriptdir); $(RMF) drop_@DB_NAME@_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) make_@DB_NAME@_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) create_@DB_NAME@_database)
        (cd $(DESTDIR)$(scriptdir); $(RMF) drop_@DB_NAME@_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) make_@DB_NAME@_tables)
+       (cd $(DESTDIR)$(scriptdir); $(RMF) update_@DB_NAME@_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) drop_bacula_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) make_bacula_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) drop_bacula_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) make_bacula_tables)
+       (cd $(DESTDIR)$(scriptdir); $(RMF) update_bacula_tables)
        (cd $(DESTDIR)$(scriptdir); $(RMF) make_catalog_backup)
        (cd $(DESTDIR)$(scriptdir); $(RMF) delete_catalog_backup)
        (cd $(DESTDIR)$(scriptdir); $(RMF) grant_mysql_privileges)
        (cd $(DESTDIR)$(scriptdir); $(RMF) make_catalog_backup)
        (cd $(DESTDIR)$(scriptdir); $(RMF) delete_catalog_backup)
        (cd $(DESTDIR)$(scriptdir); $(RMF) grant_mysql_privileges)
index 62eedfc3a1142bf995d54300500b58884e1e593f..f17fecad423ef9992d1ee25742e92e8c2c31874f 100644 (file)
@@ -48,7 +48,7 @@ typedef int (DB_RESULT_HANDLER)(void *, int, char **);
 
 #ifdef HAVE_SQLITE
 
 
 #ifdef HAVE_SQLITE
 
-#define BDB_VERSION 6
+#define BDB_VERSION 7
 
 #include <sqlite.h>
 
 
 #include <sqlite.h>
 
@@ -142,7 +142,7 @@ extern void my_sqlite_free_table(B_DB *mdb);
 
 #ifdef HAVE_MYSQL
 
 
 #ifdef HAVE_MYSQL
 
-#define BDB_VERSION 6
+#define BDB_VERSION 7
 
 #include <mysql.h>
 
 
 #include <mysql.h>
 
index d84dad313f77c276a4a4e4ef2ae4f16526c1ab0a..2f49e348214f399a92b9ba5d48aaa2b0966b2803 100644 (file)
@@ -24,7 +24,7 @@ CREATE TABLE Path (
 # ****FIXME**** make FileId BIGINT someday when MySQL works *****
 CREATE TABLE File (
    FileId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
 # ****FIXME**** make FileId BIGINT someday when MySQL works *****
 CREATE TABLE File (
    FileId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-   FileIndex INTEGER UNSIGNED NOT NULL,
+   FileIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
    PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
    FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
    PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
    FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
@@ -50,12 +50,12 @@ CREATE TABLE Job (
    StartTime DATETIME NOT NULL,
    EndTime DATETIME NOT NULL,
    JobTDate BIGINT UNSIGNED NOT NULL,
    StartTime DATETIME NOT NULL,
    EndTime DATETIME NOT NULL,
    JobTDate BIGINT UNSIGNED NOT NULL,
-   VolSessionId INTEGER UNSIGNED NOT NULL,
-   VolSessionTime INTEGER UNSIGNED NOT NULL,
-   JobFiles INTEGER UNSIGNED NOT NULL,
+   VolSessionId INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolSessionTime INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   JobFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
    JobBytes BIGINT UNSIGNED NOT NULL,
    JobBytes BIGINT UNSIGNED NOT NULL,
-   JobErrors INTEGER UNSIGNED NOT NULL,
-   JobMissingFiles INTEGER UNSIGNED NOT NULL,
+   JobErrors INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   JobMissingFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
    PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
    FileSetId INTEGER UNSIGNED NOT NULL REFERENCES FileSet,
    PurgedFiles TINYINT NOT NULL DEFAULT 0,
    PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
    FileSetId INTEGER UNSIGNED NOT NULL REFERENCES FileSet,
    PurgedFiles TINYINT NOT NULL DEFAULT 0,
@@ -77,13 +77,13 @@ CREATE TABLE JobMedia (
    JobMediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
    MediaId INTEGER UNSIGNED NOT NULL REFERENCES Media,
    JobMediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
    MediaId INTEGER UNSIGNED NOT NULL REFERENCES Media,
-   FirstIndex INTEGER UNSIGNED NOT NULL,
-   LastIndex INTEGER UNSIGNED NOT NULL,
-   StartFile INTEGER UNSIGNED NOT NULL,
-   EndFile INTEGER UNSIGNED NOT NULL,
-   StartBlock INTEGER UNSIGNED NOT NULL,
-   EndBlock INTEGER UNSIGNED NOT NULL,
-   VolIndex INTEGER UNSIGNED NOT NULL,
+   FirstIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   LastIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   StartFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   EndFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   StartBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   EndBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
    PRIMARY KEY(JobMediaId),
    INDEX (JobId, MediaId)
    );
    PRIMARY KEY(JobMediaId),
    INDEX (JobId, MediaId)
    );
@@ -98,22 +98,24 @@ CREATE TABLE Media (
    FirstWritten DATETIME NOT NULL,
    LastWritten DATETIME NOT NULL,
    LabelDate DATETIME NOT NULL,
    FirstWritten DATETIME NOT NULL,
    LastWritten DATETIME NOT NULL,
    LabelDate DATETIME NOT NULL,
-   VolJobs INTEGER UNSIGNED NOT NULL,
-   VolFiles INTEGER UNSIGNED NOT NULL,
-   VolBlocks INTEGER UNSIGNED NOT NULL,
-   VolMounts INTEGER UNSIGNED NOT NULL,
-   VolBytes BIGINT UNSIGNED NOT NULL,
-   VolErrors INTEGER UNSIGNED NOT NULL,
-   VolWrites INTEGER UNSIGNED NOT NULL,
+   VolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolBlocks INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolMounts INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
+   VolErrors INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   VolWrites INTEGER UNSIGNED NOT NULL DEFAULT 0,
    VolCapacityBytes BIGINT UNSIGNED NOT NULL,
    VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged',
     'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
    VolCapacityBytes BIGINT UNSIGNED NOT NULL,
    VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged',
     'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
-   Recycle TINYINT NOT NULL,
-   VolRetention BIGINT UNSIGNED NOT NULL,
-   VolUseDuration BIGINT UNSIGNED NOT NULL,
-   MaxVolJobs INTEGER UNSIGNED NOT NULL,
-   MaxVolFiles INTEGER UNSIGNED NOT NULL,
-   MaxVolBytes BIGINT UNSIGNED NOT NULL,
+   Recycle TINYINT NOT NULL DEFAULT 0,
+   VolRetention BIGINT UNSIGNED NOT NULL DEFAULT 0,
+   VolUseDuration BIGINT UNSIGNED NOT NULL DEFAULT 0,
+   MaxVolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   MaxVolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
+   Drive INTEGER NOT NULL DEFAULT 0,
+   InChanger TINYINT NOT NULL DEFAULT 0,
    PRIMARY KEY(MediaId),
    INDEX (PoolId)
    );
    PRIMARY KEY(MediaId),
    INDEX (PoolId)
    );
@@ -121,15 +123,15 @@ CREATE TABLE Media (
 CREATE TABLE Pool (
    PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    Name TINYBLOB NOT NULL,
 CREATE TABLE Pool (
    PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    Name TINYBLOB NOT NULL,
-   NumVols INTEGER UNSIGNED NOT NULL,
-   MaxVols INTEGER UNSIGNED NOT NULL,
+   NumVols INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   MaxVols INTEGER UNSIGNED NOT NULL DEFAULT 0,
    UseOnce TINYINT NOT NULL,
    UseCatalog TINYINT NOT NULL,
    AcceptAnyVolume TINYINT DEFAULT 0,
    VolRetention BIGINT UNSIGNED NOT NULL,
    VolUseDuration BIGINT UNSIGNED NOT NULL,
    UseOnce TINYINT NOT NULL,
    UseCatalog TINYINT NOT NULL,
    AcceptAnyVolume TINYINT DEFAULT 0,
    VolRetention BIGINT UNSIGNED NOT NULL,
    VolUseDuration BIGINT UNSIGNED NOT NULL,
-   MaxVolJobs INTEGER UNSIGNED NOT NULL,
-   MaxVolFiles INTEGER UNSIGNED NOT NULL,
+   MaxVolJobs INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED NOT NULL,
    AutoPrune TINYINT DEFAULT 0,
    Recycle TINYINT DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED NOT NULL,
    AutoPrune TINYINT DEFAULT 0,
    Recycle TINYINT DEFAULT 0,
@@ -173,7 +175,7 @@ CREATE TABLE Version (
    );
 
 -- Initialize Version           
    );
 
 -- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (6);
+INSERT INTO Version (VersionId) VALUES (7);
 
 CREATE TABLE Counters (
    Counter TINYBLOB NOT NULL,
 
 CREATE TABLE Counters (
    Counter TINYBLOB NOT NULL,
index 56244601a6a89d0ec10d5579b847a45cb02a525d..d6a77d4f3d5fc113fb22e06f21807bdbbbe26599 100644 (file)
@@ -115,6 +115,8 @@ CREATE TABLE Media (
    MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
+   Drive INTEGER DEFAULT 0,
+   InChanger TINYINT DEFAULT 0,
    PRIMARY KEY(MediaId)
    );
 
    PRIMARY KEY(MediaId)
    );
 
@@ -184,7 +186,7 @@ CREATE TABLE Version (
    );
 
 -- Initialize Version           
    );
 
 -- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (6);
+INSERT INTO Version (VersionId) VALUES (7);
 
 CREATE TABLE Counters (
    Counter TEXT NOT NULL,     
 
 CREATE TABLE Counters (
    Counter TEXT NOT NULL,     
index 441947369cb8fc6cdee8d3418c8bc9722f6a4a73..767492e6356c3e34c2a4a7aca8f18497eaa0835a 100644 (file)
@@ -31,7 +31,7 @@
 
 /* sql.c */
 B_DB *db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password, 
 
 /* sql.c */
 B_DB *db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password, 
-                      char *db_address, int db_port, char *db_socket);
+                       char *db_address, int db_port, char *db_socket);
 int db_open_database(JCR *jcr, B_DB *db);
 void db_close_database(JCR *jcr, B_DB *db);
 void db_escape_string(char *snew, char *old, int len);
 int db_open_database(JCR *jcr, B_DB *db);
 void db_close_database(JCR *jcr, B_DB *db);
 void db_escape_string(char *snew, char *old, int len);
@@ -51,7 +51,7 @@ 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_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);         
+int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);          
 int 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);
 
 int 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);
 
@@ -105,6 +105,6 @@ int  db_update_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *mr);
 int  db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
 int  db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type);  
 int  db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId);
 int  db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
 int  db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type);  
 int  db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId);
-void db_make_slot_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
+void db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
 
 #endif /* __SQL_PROTOS_H */
 
 #endif /* __SQL_PROTOS_H */
index 2cca2d6e4cd7e169b097b7e42a24f33874f2cc91..b4a95977c2eed9a955d7435b54aa4ed2bcf1bc1e 100644 (file)
@@ -256,8 +256,10 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       sql_free_result(mdb);
    }
 
       sql_free_result(mdb);
    }
 
-   /* Make sur Slot, if non-zero, is unique */
-   db_make_slot_unique(jcr, mdb, mr);
+   /* Make sure that if InChanger is non-zero any other identical slot
+    *  has InChanger zero.
+    */
+   db_make_inchanger_unique(jcr, mdb, mr);
 
    /* Must create it */
    if (mr->LabelDate) {
 
    /* Must create it */
    if (mr->LabelDate) {
@@ -269,8 +271,8 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    Mmsg(&mdb->cmd, 
 "INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes," 
 "Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
    Mmsg(&mdb->cmd, 
 "INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes," 
 "Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
-"VolStatus,LabelDate,Slot,VolBytes) "
-"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s','%s',%d,%s)", 
+"VolStatus,LabelDate,Slot,VolBytes,Drive,InChanger) "
+"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s','%s',%d,%s,%d,%d)", 
                  mr->VolumeName,
                  mr->MediaType, mr->PoolId, 
                  edit_uint64(mr->MaxVolBytes,ed1),
                  mr->VolumeName,
                  mr->MediaType, mr->PoolId, 
                  edit_uint64(mr->MaxVolBytes,ed1),
@@ -282,7 +284,9 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
                  mr->MaxVolFiles,
                  mr->VolStatus, dt,
                  mr->Slot,
                  mr->MaxVolFiles,
                  mr->VolStatus, dt,
                  mr->Slot,
-                 edit_uint64(mr->VolBytes, ed5));
+                 edit_uint64(mr->VolBytes, ed5),
+                 mr->Drive,
+                 mr->InChanger);
 
    Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
 
    Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
index b37efec6c509d440b0e849a276d641b8d181b64c..2846fc8567d8fb0702a5a758b2085624abf2cdbf 100644 (file)
@@ -272,21 +272,21 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       stat = UPDATE_DB(jcr, mdb, mdb->cmd);
    }
    
       stat = UPDATE_DB(jcr, mdb, mdb->cmd);
    }
    
-   /* Make sure Slot, if non-zero, is unique */
-   db_make_slot_unique(jcr, mdb, mr);
+   /* Make sure InChanger is 0 for any record having the same Slot */
+   db_make_inchanger_unique(jcr, mdb, mr);
 
    ttime = mr->LastWritten;
    localtime_r(&ttime, &tm);
    strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
 
 
    ttime = mr->LastWritten;
    localtime_r(&ttime, &tm);
    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 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->VolumeName);
+   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,Drive=%d,InChanger=%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->VolumeName, mr->Drive, mr->InChanger);
 
    Dmsg1(400, "%s\n", mdb->cmd);
 
 
    Dmsg1(400, "%s\n", mdb->cmd);
 
@@ -296,16 +296,16 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 }
 
 /* 
 }
 
 /* 
- * If we have a non-zero Slot, ensure that no other Media
- *  record in this Pool has the same Slot by setting Slot=0.
+ * If we have a non-zero InChanger, ensure that no other Media
+ *  record in this Pool has InChanger set on the same Slot.
  *
  * This routine assumes the database is already locked.
  */
 void
  *
  * This routine assumes the database is already locked.
  */
 void
-db_make_slot_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) 
+db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) 
 {
 {
-   if (mr->Slot != 0) {
-      Mmsg(&mdb->cmd, "UPDATE Media SET Slot=0 WHERE PoolId=%u "
+   if (mr->InChanger != 0) {
+      Mmsg(&mdb->cmd, "UPDATE Media SET InChanger=0 WHERE PoolId=%u "
            "AND Slot=%d\n", mr->PoolId, mr->Slot);
       Dmsg1(400, "%s\n", mdb->cmd);
       UPDATE_DB(jcr, mdb, mdb->cmd);
            "AND Slot=%d\n", mr->PoolId, mr->Slot);
       Dmsg1(400, "%s\n", mdb->cmd);
       UPDATE_DB(jcr, mdb, mdb->cmd);
diff --git a/bacula/src/cats/update_bacula_tables.in b/bacula/src/cats/update_bacula_tables.in
new file mode 100755 (executable)
index 0000000..a1b1984
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# This routine alters the appropriately configured
+#  Bacula tables for either MySQL or SQLite
+#
+if test xsqlite = x@DB_NAME@ ; then
+  echo "Altering SQLite tables"
+  . ./update_sqlite_tables
+fi
+if test xmysql = x@DB_NAME@ ; then
+  echo "Altering MySQL tables"
+  . ./update_mysql_tables
+fi
diff --git a/bacula/src/cats/update_mysql_tables.in b/bacula/src/cats/update_mysql_tables.in
new file mode 100755 (executable)
index 0000000..b017499
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Shell script to update MySQL tables from version 1.32 to 1.33
+#
+echo " "
+echo "Depending on the size of your database,"
+echo "this script may take several minutes to run."
+echo " "
+bindir=@SQL_BINDIR@
+
+if $bindir/mysql $* -f <<END-OF-DATA
+USE bacula;
+
+ALTER TABLE Media ADD COLUMN Drive INTEGER NOT NULL DEFAULT 0;
+ALTER TABLE Media ADD COLUMN InChanger TINYINT NOT NULL DEFAULT 0;
+
+
+DROP TABLE BaseFiles;
+
+
+CREATE TABLE BaseFiles (
+   BaseId INTEGER UNSIGNED AUTO_INCREMENT,
+   JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
+   FileId INTEGER UNSIGNED NOT NULL REFERENCES File,
+   FileIndex INTEGER UNSIGNED,
+   PRIMARY KEY(BaseId)
+   );
+
+DROP TABLE UnsavedFiles;
+
+CREATE TABLE UnsavedFiles (
+   UnsavedId INTEGER UNSIGNED AUTO_INCREMENT,
+   JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
+   PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
+   FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename,
+   PRIMARY KEY (UnsavedId)
+   );
+
+UPDATE Version SET VersionId=7;
+
+END-OF-DATA
+then
+   echo "Update of Bacula MySQL tables succeeded."
+else
+   echo "Update of Bacula MySQL tables failed."
+fi
+exit 0
diff --git a/bacula/src/cats/update_sqlite_tables.in b/bacula/src/cats/update_sqlite_tables.in
new file mode 100755 (executable)
index 0000000..cace325
--- /dev/null
@@ -0,0 +1,105 @@
+#!/bin/sh
+#
+# shell script to update SQLite from version 1.32 to 1.33
+#
+echo " "
+echo "Depending on the size of your database,"
+echo "this script may take several minutes to run."
+echo " "
+
+bindir=@SQL_BINDIR@
+cd @working_dir@
+
+$bindir/sqlite $* bacula.db <<END-OF-DATA
+
+BEGIN TRANSACTION;
+CREATE TEMPORARY TABLE Media_backup (
+   MediaId INTEGER UNSIGNED AUTOINCREMENT,
+   VolumeName VARCHAR(128) NOT NULL,
+   Slot INTEGER DEFAULT 0,
+   PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
+   MediaType VARCHAR(128) NOT NULL,
+   FirstWritten DATETIME DEFAULT 0,
+   LastWritten DATETIME DEFAULT 0,
+   LabelDate DATETIME DEFAULT 0,
+   VolJobs INTEGER UNSIGNED DEFAULT 0,
+   VolFiles INTEGER UNSIGNED DEFAULT 0,
+   VolBlocks INTEGER UNSIGNED DEFAULT 0,
+   VolMounts INTEGER UNSIGNED DEFAULT 0,
+   VolBytes BIGINT UNSIGNED DEFAULT 0,
+   VolErrors INTEGER UNSIGNED DEFAULT 0,
+   VolWrites INTEGER UNSIGNED DEFAULT 0,
+   VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
+   VolStatus VARCHAR(20) NOT NULL,
+   Recycle TINYINT DEFAULT 0,
+   VolRetention BIGINT UNSIGNED DEFAULT 0,
+   VolUseDuration BIGINT UNSIGNED DEFAULT 0,
+   MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
+   MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
+   MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
+   Drive INTEGER DEFAULT 0,
+   InChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(MediaId)
+   );
+
+INSERT INTO Media_backup SELECT 
+   MediaId, VolumeName, Slot, PoolId,
+   MediaType, FirstWritten, LastWritten,
+   LabelDate, VolJobs, VolFiles, VolBlocks,
+   VolMounts, VolBytes, VolErrors, VolWrites,
+   VolCapacityBytes, VolStatus, Recycle,
+   VolRetention, VolUseDuration, MaxVolJobs,
+   MaxVolFiles, MaxVolBytes
+   FROM Media;
+
+
+DROP TABLE Media;
+
+CREATE TABLE Media (
+   MediaId INTEGER UNSIGNED AUTOINCREMENT,
+   VolumeName VARCHAR(128) NOT NULL,
+   Slot INTEGER DEFAULT 0,
+   PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
+   MediaType VARCHAR(128) NOT NULL,
+   FirstWritten DATETIME DEFAULT 0,
+   LastWritten DATETIME DEFAULT 0,
+   LabelDate DATETIME DEFAULT 0,
+   VolJobs INTEGER UNSIGNED DEFAULT 0,
+   VolFiles INTEGER UNSIGNED DEFAULT 0,
+   VolBlocks INTEGER UNSIGNED DEFAULT 0,
+   VolMounts INTEGER UNSIGNED DEFAULT 0,
+   VolBytes BIGINT UNSIGNED DEFAULT 0,
+   VolErrors INTEGER UNSIGNED DEFAULT 0,
+   VolWrites INTEGER UNSIGNED DEFAULT 0,
+   VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
+   VolStatus VARCHAR(20) NOT NULL,
+   Recycle TINYINT DEFAULT 0,
+   VolRetention BIGINT UNSIGNED DEFAULT 0,
+   VolUseDuration BIGINT UNSIGNED DEFAULT 0,
+   MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
+   MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
+   MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
+   Drive INTEGER DEFAULT 0,
+   InChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(MediaId)
+   );
+
+INSERT INTO Media (
+   MediaId, VolumeName, Slot, PoolId,
+   MediaType, FirstWritten, LastWritten,
+   LabelDate, VolJobs, VolFiles, VolBlocks,
+   VolMounts, VolBytes, VolErrors, VolWrites,
+   VolCapacityBytes, VolStatus, Recycle,
+   VolRetention, VolUseDuration, MaxVolJobs,
+   MaxVolFiles, MaxVolBytes)
+   SELECT * FROM Media_backup;
+
+DROP TABLE Media_backup;
+
+CREATE INDEX inx8 ON Media (PoolId);
+
+COMMIT;
+
+UPDATE Version SET VersionId=7;
+
+END-OF-DATA
index 3a7679972b4046cb061f32ea9a63b3524d138fc2..01ac8dcdeb57e27dee9d4e1c0cd78f19ac801c27 100644 (file)
@@ -177,8 +177,8 @@ Catalog {
 #  and to the console
 Messages {
   Name = Standard
 #  and to the console
 Messages {
   Name = Standard
-  mailcommand = "@sbindir@/bsmtp -h @bsmtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: %t %e of %c %l\" %r"
-  operatorcommand = "@sbindir@/bsmtp -h @bsmtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: Intervention needed for %j\" %r"
+  mailcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: %t %e of %c %l\" %r"
+  operatorcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: Intervention needed for %j\" %r"
   mail = @job_email@ = all, !skipped            
   operator = @job_email@ = mount
   console = all, !skipped, !saved
   mail = @job_email@ = all, !skipped            
   operator = @job_email@ = mount
   console = all, !skipped, !saved
index 920f92638474342ad553e64813f2a09d10922847..15ba907004702751f50f3e42f5e773f5f1e305f5 100644 (file)
@@ -145,19 +145,6 @@ static void set_defaults()
 }
 
 
 }
 
 
-/* Check if string is a number */
-static int is_num(char *num)
-{
-   char *p = num;
-   int ch;
-   while ((ch = *p++)) {
-      if (ch < '0' || ch > '9') {
-        return FALSE;
-      }
-   }
-   return TRUE;
-}
-
 /* Keywords (RHS) permitted in Run records */
 static struct s_kw RunFields[] = {
    {"pool",     'P'},
 /* Keywords (RHS) permitted in Run records */
 static struct s_kw RunFields[] = {
    {"pool",     'P'},
@@ -420,7 +407,7 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
         *p++ = 0;                 /* separate two halves */
 
         /* Check for day range */
         *p++ = 0;                 /* separate two halves */
 
         /* Check for day range */
-        if (is_num(lc->str) && is_num(p)) {
+        if (is_an_integer(lc->str) && is_an_integer(p)) {
            code = atoi(lc->str) - 1;
            code2 = atoi(p) - 1;
            if (code < 0 || code > 30 || code2 < 0 || code2 > 30) {
            code = atoi(lc->str) - 1;
            code2 = atoi(p) - 1;
            if (code < 0 || code > 30 || code2 < 0 || code2 > 30) {
index 0e36adb67d017aaa073b1f7ef4375a0c020d903c..c94fa5a253dd241f7282460b43cc53eed9c2d1ae 100644 (file)
@@ -184,7 +184,7 @@ static int add_cmd(UAContext *ua, char *cmd)
    int first_id = 0;
    char name[MAX_NAME_LENGTH];
    STORE *store;
    int first_id = 0;
    char name[MAX_NAME_LENGTH];
    STORE *store;
-   int slot = 0;
+   int Slot = 0, InChanger = 0;
 
    bsendmsg(ua, _(
 "You probably don't want to be using this command since it\n"
 
    bsendmsg(ua, _(
 "You probably don't want to be using this command since it\n"
@@ -287,13 +287,18 @@ getVolName:
       if (!get_pint(ua, _("Enter slot (0 for none): "))) {
         return 1;
       }
       if (!get_pint(ua, _("Enter slot (0 for none): "))) {
         return 1;
       }
-      slot = ua->pint32_val;
+      Slot = ua->pint32_val;
+      if (!get_yesno(ua, _("InChanger? yes/no: "))) {
+        return 1;
+      }
+      InChanger = ua->pint32_val;
    }
           
    set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
    for (i=startnum; i < num+startnum; i++) { 
       bsnprintf(mr.VolumeName, sizeof(mr.VolumeName), name, i);
    }
           
    set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
    for (i=startnum; i < num+startnum; i++) { 
       bsnprintf(mr.VolumeName, sizeof(mr.VolumeName), name, i);
-      mr.Slot = slot++;
+      mr.Slot = Slot++;
+      mr.InChanger = InChanger;
       Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
       if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
         bsendmsg(ua, db_strerror(ua->db));
       Dmsg1(200, "Create Volume %s\n", mr.VolumeName);
       if (!db_create_media_record(ua->jcr, ua->db, &mr)) {
         bsendmsg(ua, db_strerror(ua->db));
@@ -794,7 +799,7 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
    if (!db_sql_query(ua->db, query, NULL, NULL)) {  
       bsendmsg(ua, "%s", db_strerror(ua->db));
    } else {      
    if (!db_sql_query(ua->db, query, NULL, NULL)) {  
       bsendmsg(ua, "%s", db_strerror(ua->db));
    } else {      
-      bsendmsg(ua, _("New recycle flag is: %s\n"),
+      bsendmsg(ua, _("New Recycle flag is: %s\n"),
          mr->Recycle==1?_("yes"):_("no"));
    }
    free_pool_memory(query);
          mr->Recycle==1?_("yes"):_("no"));
    }
    free_pool_memory(query);
@@ -895,6 +900,7 @@ static int update_volume(UAContext *ua)
       add_prompt(ua, _("Maximum Volume Bytes"));
       add_prompt(ua, _("Recycle Flag"));
       add_prompt(ua, _("Slot"));
       add_prompt(ua, _("Maximum Volume Bytes"));
       add_prompt(ua, _("Recycle Flag"));
       add_prompt(ua, _("Slot"));
+      add_prompt(ua, _("InChanger Flag"));
       add_prompt(ua, _("Volume Files"));
       add_prompt(ua, _("Pool"));
       add_prompt(ua, _("Done"));
       add_prompt(ua, _("Volume Files"));
       add_prompt(ua, _("Pool"));
       add_prompt(ua, _("Done"));
@@ -971,7 +977,7 @@ static int update_volume(UAContext *ua)
         break;
 
       case 7:                        /* Slot */
         break;
 
       case 7:                        /* Slot */
-        int slot;
+        int Slot;
 
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
 
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
@@ -983,13 +989,13 @@ static int update_volume(UAContext *ua)
          if (!get_pint(ua, _("Enter new Slot: "))) {
            return 0;
         }
          if (!get_pint(ua, _("Enter new Slot: "))) {
            return 0;
         }
-        slot = ua->pint32_val;
-        if (pr.MaxVols > 0 && slot > (int)pr.MaxVols) {
+        Slot = ua->pint32_val;
+        if (pr.MaxVols > 0 && Slot > (int)pr.MaxVols) {
             bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"),
               pr.MaxVols);
            break;
         }
             bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"),
               pr.MaxVols);
            break;
         }
-        mr.Slot = slot;
+        mr.Slot = Slot;
         /*
          * Make sure to use db_update... rather than doing this directly,
          *   so that any Slot is handled correctly. 
         /*
          * Make sure to use db_update... rather than doing this directly,
          *   so that any Slot is handled correctly. 
@@ -1001,7 +1007,25 @@ static int update_volume(UAContext *ua)
         }
         break;
 
         }
         break;
 
-      case 8:                        /* Volume Files */
+      case 8:                        /* InChanger */
+         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;
+        /*
+         * Make sure to use db_update... rather than doing this directly,
+         *   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));
+        } else {
+            bsendmsg(ua, _("New InChanger flag is: %s\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"));
         int32_t VolFiles;
          bsendmsg(ua, _("Warning changing Volume Files can result\n"
                         "in loss of data on your Volume\n\n"));
@@ -1027,7 +1051,7 @@ static int update_volume(UAContext *ua)
         free_pool_memory(query);
         break;
 
         free_pool_memory(query);
         break;
 
-      case 9:                         /* Volume's Pool */
+      case 10:                        /* Volume's Pool */
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
         if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
         memset(&pr, 0, sizeof(POOL_DBR));
         pr.PoolId = mr.PoolId;
         if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
@@ -1040,6 +1064,7 @@ static int update_volume(UAContext *ua)
         }
         update_volpool(ua, ua->cmd, &mr);
         return 1;
         }
         update_volpool(ua, ua->cmd, &mr);
         return 1;
+
       default:                       /* Done or error */
          bsendmsg(ua, "Selection done.\n");
         return 1;
       default:                       /* Done or error */
          bsendmsg(ua, "Selection done.\n");
         return 1;
index b6e1c55c239e255bcd2af9de157ff43e5d24c454..c79cef291f589476257e264bc9de487ea50b2e30 100644 (file)
@@ -43,8 +43,12 @@ static int do_label(UAContext *ua, char *cmd, int relabel);
 static void label_from_barcodes(UAContext *ua);
 static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
               POOL_DBR *pr, int relabel, bool media_record_exits);
 static void label_from_barcodes(UAContext *ua);
 static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
               POOL_DBR *pr, int relabel, bool media_record_exits);
-static vol_list_t *get_slot_list_from_SD(UAContext *ua);
+static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan);
+static void free_vol_list(vol_list_t *vol_list);
 static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
 static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
+static BSOCK *open_sd_bsock(UAContext *ua);
+static void close_sd_bsock(UAContext *ua);
+static char *get_volume_name_from_SD(UAContext *ua, int Slot);
 
 
 /*
 
 
 /*
@@ -62,6 +66,91 @@ int relabel_cmd(UAContext *ua, char *cmd)
    return do_label(ua, cmd, 1);      /* relabel tape */
 }
 
    return do_label(ua, cmd, 1);      /* relabel tape */
 }
 
+#define MAX_SLOTS 5000
+
+static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots)
+{
+   int i;
+   char *msg;
+
+   for (int i=0; i<num_slots; i++) {
+      slot_list[i] = 0;
+   }
+   i = find_arg_with_value(ua, "slots");
+   if (i >= 0) {
+      /* scan slot list in ua->argv[i] */
+      char *p, *e, *h;
+      int beg, end;
+
+      strip_trailing_junk(ua->argv[i]);
+      for (p=ua->argv[i]; p && *p; p=e) {
+        /* Check for list */
+         e = strchr(p, ',');
+        if (e) {
+           *e++ = 0;
+        }
+        /* Check for range */
+         h = strchr(p, '-');             /* range? */
+        if (h == p) {
+            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");
+              goto bail_out;
+           }
+           skip_spaces(&p);
+           if (!is_an_integer(p)) {
+               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");
+              goto bail_out;
+           }
+        } else {
+           skip_spaces(&p);
+           if (!is_an_integer(p)) {
+               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");
+           goto bail_out;
+        }
+        if (end >= num_slots) {
+            msg = _("Slot too large.\n");
+           goto bail_out;
+        }
+        for (i=beg; i<=end; i++) {
+           slot_list[i] = 1;         /* Turn on specified range */
+        }
+      }
+   } else { 
+      /* Turn everything on */
+      for (i=0; i<num_slots; i++) {
+        slot_list[i] = 1;
+      }
+   }
+#ifdef xxx_debug
+   printf("Slots turned on:\n");
+   for (i=1; i<num_slots; i++) {
+      if (slot_list[i]) {
+         printf("%d\n", i); 
+      }
+   }
+#endif
+   return true;
+
+bail_out:
+   return false;
+}
 
 /*
  * Update Slots corresponding to Volumes in autochanger 
 
 /*
  * Update Slots corresponding to Volumes in autochanger 
@@ -71,6 +160,8 @@ int update_slots(UAContext *ua)
    STORE *store;
    vol_list_t *vl, *vol_list = NULL;
    MEDIA_DBR mr;
    STORE *store;
    vol_list_t *vl, *vol_list = NULL;
    MEDIA_DBR mr;
+   char *slot_list;
+   bool scan;       
 
    if (!open_db(ua)) {
       return 1;
 
    if (!open_db(ua)) {
       return 1;
@@ -81,8 +172,15 @@ int update_slots(UAContext *ua)
    }
    ua->jcr->store = store;
 
    }
    ua->jcr->store = store;
 
-   vol_list = get_slot_list_from_SD(ua);
+   scan = find_arg(ua, _("scan")) >= 0;
+
+   slot_list = (char *)malloc(MAX_SLOTS);
+   if (!get_user_slot_list(ua, slot_list, MAX_SLOTS)) {
+      free(slot_list);
+      return 1;
+   }
 
 
+   vol_list = get_vol_list_from_SD(ua, scan);
 
    if (!vol_list) {
       bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
 
    if (!vol_list) {
       bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
@@ -91,13 +189,28 @@ int update_slots(UAContext *ua)
 
    /* Walk through the list updating the media records */
    for (vl=vol_list; vl; vl=vl->next) {
 
    /* Walk through the list updating the media records */
    for (vl=vol_list; vl; vl=vl->next) {
-
+      /* Check if user wants us to look at this slot */
+      if (!slot_list[vl->Slot]) {
+        continue;
+      }
+      /* If scanning, we read the label rather than the barcode */
+      if (scan) {
+        if (vl->VolName) {
+           free(vl->VolName);
+           vl->VolName = NULL;
+        }
+        vl->VolName = get_volume_name_from_SD(ua, vl->Slot);
+      }
+      if (!vl->VolName) {
+        continue;
+      }
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
       db_lock(ua->db);
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
       db_lock(ua->db);
       if (db_get_media_record(ua->jcr, ua->db, &mr)) {
-         if (mr.Slot != vl->Slot) {
+         if (mr.Slot != vl->Slot || !mr.InChanger) {
             mr.Slot = vl->Slot;
             mr.Slot = vl->Slot;
+            mr.InChanger = 1;
             if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
                 bsendmsg(ua, _("%s\n"), db_strerror(ua->db));
             } else {
             if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
                 bsendmsg(ua, _("%s\n"), db_strerror(ua->db));
             } else {
@@ -120,23 +233,15 @@ int update_slots(UAContext *ua)
 
 
 bail_out:
 
 
 bail_out:
-   /* Free list */
-   for (vl=vol_list; vl; ) {
-      vol_list_t *ovl;
-      free(vl->VolName);
-      ovl = vl;
-      vl = vl->next;
-      free(ovl);
-   }
 
 
-   if (ua->jcr->store_bsock) {
-      bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE);
-      bnet_close(ua->jcr->store_bsock);
-      ua->jcr->store_bsock = NULL;
-   }
+   free_vol_list(vol_list);
+   free(slot_list);
+   close_sd_bsock(ua);
+
    return 1;
 }
 
    return 1;
 }
 
+
 /*
  * Common routine for both label and relabel
  */
 /*
  * Common routine for both label and relabel
  */
@@ -144,7 +249,6 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
 {
    STORE *store;
    BSOCK *sd;
 {
    STORE *store;
    BSOCK *sd;
-   sd = ua->jcr->store_bsock;
    char dev_name[MAX_NAME_LENGTH];
    MEDIA_DBR mr, omr;
    POOL_DBR pr;
    char dev_name[MAX_NAME_LENGTH];
    MEDIA_DBR mr, omr;
    POOL_DBR pr;
@@ -241,6 +345,7 @@ checkName:
       } else {
         mr.Slot = ua->pint32_val;
       }
       } else {
         mr.Slot = ua->pint32_val;
       }
+      mr.InChanger = 1;              /* assumed if we are labeling it */
    }
 
    bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
    }
 
    bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
@@ -253,17 +358,11 @@ checkName:
       }
    }
 
       }
    }
 
-   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"));
-      return 1;   
-   }
-   sd = ua->jcr->store_bsock;
 
    ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists);
 
    if (ok) {
 
    ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists);
 
    if (ok) {
+      sd = ua->jcr->store_bsock;
       if (relabel) {
         if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
             bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
       if (relabel) {
         if (!db_delete_media_record(ua->jcr, ua->db, &omr)) {
             bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"),
@@ -297,9 +396,7 @@ checkName:
    if (print_reminder) {
       bsendmsg(ua, _("Do not forget to mount the drive!!!\n"));
    }
    if (print_reminder) {
       bsendmsg(ua, _("Do not forget to mount the drive!!!\n"));
    }
-   bnet_sig(sd, BNET_TERMINATE);
-   bnet_close(sd);
-   ua->jcr->store_bsock = NULL;
+   close_sd_bsock(ua);
 
    return 1;
 }
 
    return 1;
 }
@@ -315,8 +412,15 @@ static void label_from_barcodes(UAContext *ua)
    MEDIA_DBR mr, omr;
    vol_list_t *vl, *vol_list = NULL;
    bool media_record_exists;
    MEDIA_DBR mr, omr;
    vol_list_t *vl, *vol_list = NULL;
    bool media_record_exists;
+   char *slot_list;
 
 
-   vol_list = get_slot_list_from_SD(ua);
+   slot_list = (char *)malloc(MAX_SLOTS);
+   if (!get_user_slot_list(ua, slot_list, MAX_SLOTS)) {
+      free(slot_list);
+      return;
+   }
+
+   vol_list = get_vol_list_from_SD(ua, false /*no scan*/);
 
    if (!vol_list) {
       bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
 
    if (!vol_list) {
       bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
@@ -328,6 +432,9 @@ static void label_from_barcodes(UAContext *ua)
                   "Slot  Volume\n"
                   "==============\n"));
    for (vl=vol_list; vl; vl=vl->next) {
                   "Slot  Volume\n"
                   "==============\n"));
    for (vl=vol_list; vl; vl=vl->next) {
+      if (!vl->VolName || !slot_list[vl->Slot]) {
+        continue;
+      }
       bsendmsg(ua, "%4d  %s\n", vl->Slot, vl->VolName);
    }
    if (!get_cmd(ua, _("Do you want to continue? (y/n): ")) ||
       bsendmsg(ua, "%4d  %s\n", vl->Slot, vl->VolName);
    }
    if (!get_cmd(ua, _("Do you want to continue? (y/n): ")) ||
@@ -343,7 +450,9 @@ static void label_from_barcodes(UAContext *ua)
 
    /* Fire off the label requests */
    for (vl=vol_list; vl; vl=vl->next) {
 
    /* Fire off the label requests */
    for (vl=vol_list; vl; vl=vl->next) {
-
+      if (!vl->VolName || !slot_list[vl->Slot]) {
+        continue;
+      }
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
       media_record_exists = false;
       memset(&mr, 0, sizeof(mr));
       bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
       media_record_exists = false;
@@ -351,10 +460,17 @@ static void label_from_barcodes(UAContext *ua)
          if (mr.VolBytes != 0) {
              bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"), 
                vl->Slot, mr.VolumeName);
          if (mr.VolBytes != 0) {
              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));
+               }
+            }
             continue;
          } 
          media_record_exists = true;
       }
             continue;
          } 
          media_record_exists = true;
       }
+      mr.InChanger = 1;
       /*
        * Deal with creating cleaning tape here. Normal tapes created in
        *  send_label_request() below
       /*
        * Deal with creating cleaning tape here. Normal tapes created in
        *  send_label_request() below
@@ -377,38 +493,17 @@ static void label_from_barcodes(UAContext *ua)
         continue;                    /* done, go handle next volume */
       }
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
         continue;                    /* done, go handle next volume */
       }
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
-      if (ua->jcr->store_bsock) {
-        bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE);
-        bnet_close(ua->jcr->store_bsock);
-        ua->jcr->store_bsock = NULL;
-      }
-      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"));
-        goto bail_out;
-      }
 
       mr.Slot = vl->Slot;
 
       mr.Slot = vl->Slot;
-      send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists);
+      if (!send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists)) {
+        goto bail_out;
+      }
    }
 
 
 bail_out:
    }
 
 
 bail_out:
-   /* Free list */
-   for (vl=vol_list; vl; ) {
-      vol_list_t *ovl;
-      free(vl->VolName);
-      ovl = vl;
-      vl = vl->next;
-      free(ovl);
-   }
-
-   if (ua->jcr->store_bsock) {
-      bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE);
-      bnet_close(ua->jcr->store_bsock);
-      ua->jcr->store_bsock = NULL;
-   }
+   free_vol_list(vol_list);
+   close_sd_bsock(ua);
 
    return;
 }
 
    return;
 }
@@ -456,7 +551,9 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    char dev_name[MAX_NAME_LENGTH];
    int ok = FALSE;
 
    char dev_name[MAX_NAME_LENGTH];
    int ok = FALSE;
 
-   sd = ua->jcr->store_bsock;
+   if (!(sd=open_sd_bsock(ua))) {
+      return 0;
+   }
    bstrncpy(dev_name, ua->jcr->store->dev_name, sizeof(dev_name));
    bash_spaces(dev_name);
    bash_spaces(mr->VolumeName);
    bstrncpy(dev_name, ua->jcr->store->dev_name, sizeof(dev_name));
    bash_spaces(dev_name);
    bash_spaces(mr->VolumeName);
@@ -490,6 +587,7 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    if (ok) {
       if (media_record_exists) {      /* we update it */
         mr->VolBytes = 1;
    if (ok) {
       if (media_record_exists) {      /* we update it */
         mr->VolBytes = 1;
+        mr->InChanger = 1;
         if (!db_update_media_record(ua->jcr, ua->db, mr)) {
              bsendmsg(ua, "%s", db_strerror(ua->db));
             ok = FALSE;
         if (!db_update_media_record(ua->jcr, ua->db, mr)) {
              bsendmsg(ua, "%s", db_strerror(ua->db));
             ok = FALSE;
@@ -497,6 +595,7 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
       } else {                       /* create the media record */
         set_pool_dbr_defaults_in_media_dbr(mr, pr);
         mr->VolBytes = 1;               /* flag indicating Volume labeled */
       } else {                       /* create the media record */
         set_pool_dbr_defaults_in_media_dbr(mr, pr);
         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"),
            mr->VolumeName, mr->Slot);
         if (db_create_media_record(ua->jcr, ua->db, mr)) {
             bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d  successfully created.\n"),
            mr->VolumeName, mr->Slot);
@@ -511,7 +610,69 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    return ok;
 }
 
    return ok;
 }
 
-static vol_list_t *get_slot_list_from_SD(UAContext *ua)
+static BSOCK *open_sd_bsock(UAContext *ua) 
+{
+   STORE *store = ua->jcr->store;
+
+   if (!ua->jcr->store_bsock) {
+      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"));
+        return NULL;
+      }
+   }
+   return ua->jcr->store_bsock;
+}
+
+static void close_sd_bsock(UAContext *ua)
+{
+   if (ua->jcr->store_bsock) {
+      bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE);
+      bnet_close(ua->jcr->store_bsock);
+      ua->jcr->store_bsock = NULL;
+   }
+}
+
+static char *get_volume_name_from_SD(UAContext *ua, int Slot) 
+{
+   STORE *store = ua->jcr->store;
+   BSOCK *sd;
+   char dev_name[MAX_NAME_LENGTH];
+   char *VolName = NULL;
+   int rtn_slot;
+
+   if (!(sd=open_sd_bsock(ua))) {
+      return NULL;
+   }
+   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, "Sent: %s", sd->msg);
+
+   /* Get Volume name in this Slot */
+   while (bnet_recv(sd) >= 0) {
+      bsendmsg(ua, "%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) {
+           break;
+        }
+        free(VolName);
+        VolName = NULL;
+      }
+   }
+   Dmsg1(200, "get_vol_name=%s\n", NPRT(VolName));
+   return VolName;
+}
+
+/*
+ * We get the slot list from the Storage daemon.
+ *  If scan is set, we return all slots found,
+ *  otherwise, we return only slots with valid barcodes (Volume names)
+ */
+static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan) 
 {
    STORE *store = ua->jcr->store;
    char dev_name[MAX_NAME_LENGTH];
 {
    STORE *store = ua->jcr->store;
    char dev_name[MAX_NAME_LENGTH];
@@ -520,13 +681,9 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
    vol_list_t *vol_list = NULL;
 
 
    vol_list_t *vol_list = NULL;
 
 
-   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"));
+   if (!(sd=open_sd_bsock(ua))) {
       return NULL;
    }
       return NULL;
    }
-   sd  = ua->jcr->store_bsock;
 
    bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
    bash_spaces(dev_name);
 
    bstrncpy(dev_name, store->dev_name, sizeof(dev_name));
    bash_spaces(dev_name);
@@ -547,25 +704,46 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
         continue;
       }
 
         continue;
       }
 
-      /* Validate Slot:Barcode */
+      /* Validate Slot: if scanning, otherwise Slot:Barcode */
       p = strchr(sd->msg, ':');
       p = strchr(sd->msg, ':');
-      if (p && strlen(p) > 1) {
-        *p++ = 0;
-        if (!is_an_integer(sd->msg)) {
+      if (scan && p) {
+        /* Scanning -- require only valid slot */
+        Slot = atoi(sd->msg);
+        if (Slot <= 0) {
+           p--;
+            *p = ':';
+            bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg); 
            continue;
         }
       } else {
            continue;
         }
       } else {
-        continue;
-      }
-      Slot = atoi(sd->msg);
-      if (Slot <= 0 || !is_volume_name_legal(ua, p)) {
-        continue;
+        /* Not scanning */
+        if (p && strlen(p) > 1) {
+           *p++ = 0;
+           if (!is_an_integer(sd->msg) || (Slot=atoi(sd->msg)) <= 0) {
+              p--;
+               *p = ':';
+               bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg); 
+              continue;
+           }
+        } else {
+           continue;
+        }
+        if (!is_volume_name_legal(ua, p)) {
+           p--;
+            *p = ':';
+            bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg); 
+           continue;
+        }
       }
 
       /* Add Slot and VolumeName to list */
       vl = (vol_list_t *)malloc(sizeof(vol_list_t));
       vl->Slot = Slot;
       }
 
       /* Add Slot and VolumeName to list */
       vl = (vol_list_t *)malloc(sizeof(vol_list_t));
       vl->Slot = Slot;
-      vl->VolName = bstrdup(p);
+      if (p) {
+        vl->VolName = bstrdup(p);
+      } else {
+        vl->VolName = NULL;
+      }
       if (!vol_list) {
         vl->next = vol_list;
         vol_list = vl;
       if (!vol_list) {
         vl->next = vol_list;
         vol_list = vl;
@@ -580,9 +758,26 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
         }
       }
    }
         }
       }
    }
+   close_sd_bsock(ua);
    return vol_list;
 }
 
    return vol_list;
 }
 
+static void free_vol_list(vol_list_t *vol_list)
+{
+   vol_list_t *vl;
+   /* Free list */
+   for (vl=vol_list; vl; ) {
+      vol_list_t *ovl;
+      if (vl->VolName) {
+        free(vl->VolName);
+      }
+      ovl = vl;
+      vl = vl->next;
+      free(ovl);
+   }
+}
+
+
 /*
  * Check if this is a cleaning tape by comparing the Volume name
  *  with the Cleaning Prefix. If they match, this is a cleaning 
 /*
  * Check if this is a cleaning tape by comparing the Volume name
  *  with the Cleaning Prefix. If they match, this is a cleaning 
index 0b1e1ef07e7309ebe95856a139af815ad45267c2..98d2528c4ad7bda69687cb5e93426bc1c87217fc 100644 (file)
@@ -738,15 +738,16 @@ STORE *get_storage_resource(UAContext *ua, int use_default)
 
    for (i=1; i<ua->argc; i++) {
       if (use_default && !ua->argv[i]) {
 
    for (i=1; i<ua->argc; i++) {
       if (use_default && !ua->argv[i]) {
+        /* Ignore scan and barcode(s) keywords */
+         if (strncasecmp("scan", ua->argk[i], 4) == 0 ||
+             strncasecmp("barcode", ua->argk[i], 7) == 0) {
+           continue;
+        }
         /* Default argument is storage */
         if (store_name) {
             bsendmsg(ua, _("Storage name given twice.\n"));
            return NULL;
         }
         /* Default argument is storage */
         if (store_name) {
             bsendmsg(ua, _("Storage name given twice.\n"));
            return NULL;
         }
-        /* Ignore barcode(s) keywords */
-         if (strncasecmp("barcode", ua->argk[i], 7) == 0) {
-           continue;
-        }
         store_name = ua->argk[i];
          if (*store_name == '?') {
            *store_name = 0;
         store_name = ua->argk[i];
          if (*store_name == '?') {
            *store_name = 0;
index 7d8e42062e1e2913e840fd94a612f7828763a117..c31a19cf0ead92795072a4a8d021149d1801f839 100755 (executable)
@@ -61,6 +61,7 @@ Makefile: $(srcdir)/Makefile.in $(topdir)/config.status
 
 clean:
        rm -f *.exe *.o *.res *.a 1 2 3
 
 clean:
        rm -f *.exe *.o *.res *.a 1 2 3
+       rm -f bin/smtp.exe bin/console.exe
        rm -f bin/bacula-fd.exe bin/bsmtp.exe bin/testfind.exe
 
 distclean: clean
        rm -f bin/bacula-fd.exe bin/bsmtp.exe bin/testfind.exe
 
 distclean: clean
index cc88a8bcdb32909c43d26d63575a1ca37430c64a..8403c8e4a8c003bc3942371e28fe093c081d97e1 100755 (executable)
Binary files a/bacula/src/filed/win32/bin/chown.exe and b/bacula/src/filed/win32/bin/chown.exe differ
index 5dff1432827885a0fc556389ff431a6cc2b7ca18..78210c9523fae98003e0e563eca3087e450e2348 100755 (executable)
Binary files a/bacula/src/filed/win32/bin/cygwin1.dll and b/bacula/src/filed/win32/bin/cygwin1.dll differ
index 6672c9e83aed9dd807a84da9a050e3b215dd8f1b..08386eac7bd7e3689eee5c61b0b82f34a48e07fa 100755 (executable)
Binary files a/bacula/src/filed/win32/bin/cygz.dll and b/bacula/src/filed/win32/bin/cygz.dll differ
index bc46d6feabf67bf671796b8b2f6e6b6aeb5e0634..beda551a8845d2b5482fd4c083ade7ee227f2f66 100755 (executable)
Binary files a/bacula/src/filed/win32/bin/mount.exe and b/bacula/src/filed/win32/bin/mount.exe differ
index 5f736fd9dc01f97a2a0f3c4f77684e16334cfcc8..34ffc0e5918cb0ca07ed20e25f9d0fb02af8fc5c 100755 (executable)
Binary files a/bacula/src/filed/win32/bin/sh.exe and b/bacula/src/filed/win32/bin/sh.exe differ
index eef24c7bce932f9ce7f6d11c3aeeac143d83490a..cb6b25112d2afc178b50a3f9ed828ca6352d5b40 100755 (executable)
Binary files a/bacula/src/filed/win32/bin/umount.exe and b/bacula/src/filed/win32/bin/umount.exe differ
index f435502b6cca66434b2d32198fc0f57f951b9888..9f38dc755b22a032b83609589e8fcffb0024dea7 100644 (file)
@@ -65,7 +65,7 @@ int skip_spaces(char **msg)
    if (!p) {
       return 0;
    }
    if (!p) {
       return 0;
    }
-   while (*p && *p == ' ') {
+   while (*p && B_ISSPACE(*p)) {
       p++;
    }
    *msg = p;
       p++;
    }
    *msg = p;
@@ -85,7 +85,7 @@ int skip_nonspaces(char **msg)
    if (!p) {
       return 0;
    }
    if (!p) {
       return 0;
    }
-   while (*p && *p != ' ') {
+   while (*p && !B_ISSPACE(*p)) {
       p++;
    }
    *msg = p;
       p++;
    }
    *msg = p;
index c89a91e213f08434d5be7917cb53221e48fcbbd8..8811dcbe5a2a84cc74cec5a531fdea08a2dafeac 100644 (file)
@@ -256,7 +256,8 @@ int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec)
 
 
 /*
 
 
 /*
- *   
+ *   Request to mount next Volume, which Volume not specified
+ *
  *   Entered with device blocked.
  *   Leaves with device blocked.
  *
  *   Entered with device blocked.
  *   Leaves with device blocked.
  *
@@ -362,8 +363,8 @@ Please use the \"label\"  command to create a new Volume for:\n\
       wait_sec = min_wait;
       num_wait = 0;
       /* If no VolumeName, and cannot get one, try again */
       wait_sec = min_wait;
       num_wait = 0;
       /* If no VolumeName, and cannot get one, try again */
-      if (jcr->VolumeName[0] == 0 && 
-         !dir_find_next_appendable_volume(jcr) && !job_canceled(jcr)) {
+      if (jcr->VolumeName[0] == 0 && !job_canceled(jcr) &&
+         !dir_find_next_appendable_volume(jcr)) {
         Jmsg(jcr, M_MOUNT, 0, _(
 "Someone woke me up, but I cannot find any appendable\n\
 volumes for Job=%s.\n"), jcr->Job);
         Jmsg(jcr, M_MOUNT, 0, _(
 "Someone woke me up, but I cannot find any appendable\n\
 volumes for Job=%s.\n"), jcr->Job);
@@ -378,7 +379,8 @@ volumes for Job=%s.\n"), jcr->Job);
 }
 
 /*
 }
 
 /*
- *   
+ *   Request to mount specific Volume
+ *
  *   Entered with device blocked and jcr->VolumeName is desired
  *     volume.
  *   Leaves with device blocked.
  *   Entered with device blocked and jcr->VolumeName is desired
  *     volume.
  *   Leaves with device blocked.
@@ -540,7 +542,7 @@ static int wait_for_sysop(JCR *jcr, DEVICE *dev, int wait_sec)
       Dmsg1(100, "Additional wait %d sec.\n", add_wait);
    }
 
       Dmsg1(100, "Additional wait %d sec.\n", add_wait);
    }
 
-   dev->dev_blocked = dev_blocked;
+   dev->dev_blocked = dev_blocked;    /* restore entry state */
    V(dev->mutex);
    return stat;
 }
    V(dev->mutex);
    return stat;
 }
index cceb5cac516201280a2606dd95447df8f2714fb6..ab506c3a58dc84350d5cc712113641870832c6e5 100644 (file)
@@ -64,6 +64,7 @@ extern int status_cmd(JCR *sjcr);
 /* Forward referenced functions */
 static int label_cmd(JCR *jcr);
 static int relabel_cmd(JCR *jcr);
 /* Forward referenced functions */
 static int label_cmd(JCR *jcr);
 static int relabel_cmd(JCR *jcr);
+static int readlabel_cmd(JCR *jcr);
 static int release_cmd(JCR *jcr);
 static int setdebug_cmd(JCR *jcr);
 static int cancel_cmd(JCR *cjcr);
 static int release_cmd(JCR *jcr);
 static int setdebug_cmd(JCR *jcr);
 static int cancel_cmd(JCR *cjcr);
@@ -71,6 +72,8 @@ static int mount_cmd(JCR *jcr);
 static int unmount_cmd(JCR *jcr);
 static int autochanger_cmd(JCR *sjcr);
 static int do_label(JCR *jcr, int relabel);
 static int unmount_cmd(JCR *jcr);
 static int autochanger_cmd(JCR *sjcr);
 static int do_label(JCR *jcr, int relabel);
+static bool find_device(JCR *jcr, char *dname);
+static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
                               char *newname, char *poolname, 
                               int Slot, int relabel);
 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
                               char *newname, char *poolname, 
                               int Slot, int relabel);
@@ -94,6 +97,7 @@ static struct s_cmds cmds[] = {
    {"status",    status_cmd},
    {"autochanger", autochanger_cmd},
    {"release",   release_cmd},
    {"status",    status_cmd},
    {"autochanger", autochanger_cmd},
    {"release",   release_cmd},
+   {"readlabel", readlabel_cmd},
    {NULL,       NULL}                /* list terminator */
 };
 
    {NULL,       NULL}                /* list terminator */
 };
 
@@ -264,9 +268,8 @@ static int do_label(JCR *jcr, int relabel)
 {
    POOLMEM *dname, *newname, *oldname, *poolname, *mtype;
    BSOCK *dir = jcr->dir_bsock;
 {
    POOLMEM *dname, *newname, *oldname, *poolname, *mtype;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
    DEVICE *dev;
-   int found = 0, ok = 0;
+   bool ok = false;
    int slot;   
 
    dname = get_memory(dir->msglen+1);
    int slot;   
 
    dname = get_memory(dir->msglen+1);
@@ -277,36 +280,23 @@ static int do_label(JCR *jcr, int relabel)
    if (relabel) {
       if (sscanf(dir->msg, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d",
          dname, oldname, newname, poolname, mtype, &slot) == 6) {
    if (relabel) {
       if (sscanf(dir->msg, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d",
          dname, oldname, newname, poolname, mtype, &slot) == 6) {
-        ok = 1;
+        ok = true;
       }
    } else {
       *oldname = 0;
       if (sscanf(dir->msg, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d",
          dname, newname, poolname, mtype, &slot) == 5) {
       }
    } else {
       *oldname = 0;
       if (sscanf(dir->msg, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d",
          dname, newname, poolname, mtype, &slot) == 5) {
-        ok = 1;
+        ok = true;
       }
    }
    if (ok) {
       }
    }
    if (ok) {
-      unbash_spaces(dname);
       unbash_spaces(newname);
       unbash_spaces(oldname);
       unbash_spaces(poolname);
       unbash_spaces(mtype);
       unbash_spaces(newname);
       unbash_spaces(oldname);
       unbash_spaces(poolname);
       unbash_spaces(mtype);
-      device = NULL;
-      LockRes();
-      while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
-        /* Find resource, and make sure we were able to open it */
-        if (strcmp(device->hdr.name, dname) == 0 && device->dev) {
-            Dmsg1(20, "Found device %s\n", device->hdr.name);
-           found = 1;
-           break;
-        }
-      }
-      UnlockRes();
-      if (found) {
+      if (find_device(jcr, dname)) {
         /******FIXME**** compare MediaTypes */
         /******FIXME**** compare MediaTypes */
-        jcr->device = device;
-        dev = device->dev;
+        dev = jcr->device->dev;
 
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
 
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
@@ -375,9 +365,6 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
    /* Ensure that the device is open -- autoload_device() closes it */
    for ( ; !(dev->state & ST_OPENED); ) {
       if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
    /* Ensure that the device is open -- autoload_device() closes it */
    for ( ; !(dev->state & ST_OPENED); ) {
       if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
-        if (dev->dev_errno == EAGAIN || dev->dev_errno == EBUSY) {
-           bmicrosleep(30, 0);
-        }
          bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"), 
            dev_name(dev), strerror_dev(dev));
         goto bail_out;
          bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"), 
            dev_name(dev), strerror_dev(dev));
         goto bail_out;
@@ -410,7 +397,7 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
       }
       pm_strcpy(&jcr->VolumeName, newname);
       bnet_fsend(dir, _("3000 OK label. Volume=%s Device=%s\n"), 
       }
       pm_strcpy(&jcr->VolumeName, newname);
       bnet_fsend(dir, _("3000 OK label. Volume=%s Device=%s\n"), 
-        newname, dev->dev_name);
+        newname, dev_name(dev));
       break;
    case VOL_NO_MEDIA:
       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
       break;
    case VOL_NO_MEDIA:
       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
@@ -452,7 +439,7 @@ static int read_label(JCR *jcr, DEVICE *dev)
       break;
    default:
       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
       break;
    default:
       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
-        dev->dev_name, jcr->errmsg);
+        dev_name(dev), jcr->errmsg);
       stat = 0;
       break;
    }
       stat = 0;
       break;
    }
@@ -461,45 +448,52 @@ static int read_label(JCR *jcr, DEVICE *dev)
    return stat;
 }
 
    return stat;
 }
 
+static bool find_device(JCR *jcr, char *dname)
+{
+   DEVRES *device = NULL;
+   bool found = false;
+
+   unbash_spaces(dname);
+   LockRes();
+   while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
+      /* Find resource, and make sure we were able to open it */
+      if (strcmp(device->hdr.name, dname) == 0 && device->dev) {
+         Dmsg1(20, "Found device %s\n", device->hdr.name);
+        jcr->device = device;
+        found = true;
+        break;
+      }
+   }
+   UnlockRes();
+   return found;
+}
+
+
 /*
  * Mount command from Director
  */
 static int mount_cmd(JCR *jcr)
 {
 /*
  * Mount command from Director
  */
 static int mount_cmd(JCR *jcr)
 {
-   POOLMEM *dev_name;
+   POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
    DEVICE *dev;
-   int found = 0;
-
-   dev_name = get_memory(dir->msglen+1);
-   if (sscanf(dir->msg, "mount %s", dev_name) == 1) {
-      unbash_spaces(dev_name);
-      device = NULL;
-      LockRes();
-      while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
-        /* Find resource, and make sure we were able to open it */
-        if (strcmp(device->hdr.name, dev_name) == 0 && device->dev) {
-            Dmsg1(20, "Found device %s\n", device->hdr.name);
-           found = 1;
-           break;
-        }
-      }
-      UnlockRes();
-      if (found) {
+
+   dname = get_memory(dir->msglen+1);
+   if (sscanf(dir->msg, "mount %s", dname) == 1) {
+      if (find_device(jcr, dname)) {
         DEV_BLOCK *block;
         DEV_BLOCK *block;
-        jcr->device = device;
-        dev = device->dev;
+        dev = jcr->device->dev;
         P(dev->mutex);               /* Use P to avoid indefinite block */
         switch (dev->dev_blocked) {         /* device blocked? */
         case BST_WAITING_FOR_SYSOP:
            /* Someone is waiting, wake him */
             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
            dev->dev_blocked = BST_MOUNT;
         P(dev->mutex);               /* Use P to avoid indefinite block */
         switch (dev->dev_blocked) {         /* device blocked? */
         case BST_WAITING_FOR_SYSOP:
            /* Someone is waiting, wake him */
             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
            dev->dev_blocked = BST_MOUNT;
-            bnet_fsend(dir, "3001 OK mount. Device=%s\n", dev->dev_name);
+            bnet_fsend(dir, "3001 OK mount. Device=%s\n", dev_name(dev));
            pthread_cond_signal(&dev->wait_next_vol);
            break;
 
            pthread_cond_signal(&dev->wait_next_vol);
            break;
 
+        /* In both of these two cases, we (the user) unmounted the Volume */
         case BST_UNMOUNTED_WAITING_FOR_SYSOP:
         case BST_UNMOUNTED:
            /* We freed the device, so reopen it and wake any waiting threads */
         case BST_UNMOUNTED_WAITING_FOR_SYSOP:
         case BST_UNMOUNTED:
            /* We freed the device, so reopen it and wake any waiting threads */
@@ -512,8 +506,9 @@ static int mount_cmd(JCR *jcr)
            read_dev_volume_label(jcr, dev, block);
            free_block(block);
            if (dev->dev_blocked == BST_UNMOUNTED) {
            read_dev_volume_label(jcr, dev, block);
            free_block(block);
            if (dev->dev_blocked == BST_UNMOUNTED) {
+              /* We blocked the device, so unblock it */
                Dmsg0(100, "Unmounted. Unblocking device\n");
                Dmsg0(100, "Unmounted. Unblocking device\n");
-              read_label(jcr, dev);
+              read_label(jcr, dev);  /* this should not be necessary */
               unblock_device(dev);
            } else {
                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
               unblock_device(dev);
            } else {
                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
@@ -521,33 +516,33 @@ static int mount_cmd(JCR *jcr)
            }
            if (dev_state(dev, ST_LABEL)) {
                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), 
            }
            if (dev_state(dev, ST_LABEL)) {
                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), 
-                 dev->dev_name, dev->VolHdr.VolName);
+                 dev_name(dev), dev->VolHdr.VolName);
            } else {
                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
            } else {
                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
-                         dev->dev_name);
+                         dev_name(dev));
            }
            pthread_cond_signal(&dev->wait_next_vol);
            break;
 
         case BST_DOING_ACQUIRE:
             bnet_fsend(dir, _("3001 Device %s is mounted; doing acquire.\n"), 
            }
            pthread_cond_signal(&dev->wait_next_vol);
            break;
 
         case BST_DOING_ACQUIRE:
             bnet_fsend(dir, _("3001 Device %s is mounted; doing acquire.\n"), 
-                      dev->dev_name);
+                      dev_name(dev));
            break;
 
         case BST_WRITING_LABEL:
            break;
 
         case BST_WRITING_LABEL:
-            bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), dev->dev_name);
+            bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), dev_name(dev));
            break;
 
         case BST_NOT_BLOCKED:
            if (dev_state(dev, ST_OPENED)) {
               if (dev_state(dev, ST_LABEL)) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
            break;
 
         case BST_NOT_BLOCKED:
            if (dev_state(dev, ST_OPENED)) {
               if (dev_state(dev, ST_LABEL)) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
-                    dev->dev_name, dev->VolHdr.VolName);
+                    dev_name(dev), dev->VolHdr.VolName);
               } else {
                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"   
                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
               } else {
                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"   
                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
-                            dev->dev_name);
+                            dev_name(dev));
               }
            } else {
               if (!dev_is_tape(dev)) {
               }
            } else {
               if (!dev_is_tape(dev)) {
@@ -562,11 +557,11 @@ static int mount_cmd(JCR *jcr)
               read_label(jcr, dev);
               if (dev_state(dev, ST_LABEL)) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), 
               read_label(jcr, dev);
               if (dev_state(dev, ST_LABEL)) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), 
-                    dev->dev_name, dev->VolHdr.VolName);
+                    dev_name(dev), dev->VolHdr.VolName);
               } else {
                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
               } else {
                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
-                            dev->dev_name);
+                            dev_name(dev));
               }
            }
            break;
               }
            }
            break;
@@ -577,13 +572,13 @@ static int mount_cmd(JCR *jcr)
         }
         V(dev->mutex);
       } else {
         }
         V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device %s not found\n"), dev_name);
+         bnet_fsend(dir, _("3999 Device %s not found\n"), dname);
       }
    } else {
       pm_strcpy(&jcr->errmsg, dir->msg);
       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
    }
       }
    } else {
       pm_strcpy(&jcr->errmsg, dir->msg);
       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
    }
-   free_memory(dev_name);
+   free_memory(dname);
    bnet_sig(dir, BNET_EOD);
    return 1;
 }
    bnet_sig(dir, BNET_EOD);
    return 1;
 }
@@ -595,27 +590,12 @@ static int unmount_cmd(JCR *jcr)
 {
    POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
 {
    POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
    DEVICE *dev;
-   int found = 0;
 
    dname = get_memory(dir->msglen+1);
    if (sscanf(dir->msg, "unmount %s", dname) == 1) {
 
    dname = get_memory(dir->msglen+1);
    if (sscanf(dir->msg, "unmount %s", dname) == 1) {
-      unbash_spaces(dname);
-      device = NULL;
-      LockRes();
-      while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
-        /* Find resource, and make sure we were able to open it */
-        if (strcmp(device->hdr.name, dname) == 0 && device->dev) {
-            Dmsg1(20, "Found device %s\n", device->hdr.name);
-           found = 1;
-           break;
-        }
-      }
-      UnlockRes();
-      if (found) {
-        jcr->device = device;
-        dev = device->dev;
+      if (find_device(jcr, dname)) {
+        dev = jcr->device->dev;
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
             Dmsg0(90, "Device already unmounted\n");
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
             Dmsg0(90, "Device already unmounted\n");
@@ -631,18 +611,15 @@ static int unmount_cmd(JCR *jcr)
             bnet_fsend(dir, _("3001 Device %s unmounted.\n"), dev_name(dev));
 
         } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
             bnet_fsend(dir, _("3001 Device %s unmounted.\n"), dev_name(dev));
 
         } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
-            bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"),
-              dev_name(dev));
+            bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), dev_name(dev));
 
         } else if (dev->dev_blocked == BST_WRITING_LABEL) {
 
         } else if (dev->dev_blocked == BST_WRITING_LABEL) {
-            bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
-              dev_name(dev));
+            bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), dev_name(dev));
 
         } else if (dev_state(dev, ST_READ) || dev->num_writers) {
            if (dev_state(dev, ST_READ)) {
                 Dmsg0(90, "Device in read mode\n");
 
         } else if (dev_state(dev, ST_READ) || dev->num_writers) {
            if (dev_state(dev, ST_READ)) {
                 Dmsg0(90, "Device in read mode\n");
-                bnet_fsend(dir, _("3904 Device %s is busy with 1 reader.\n"),
-                  dev_name(dev));
+                bnet_fsend(dir, _("3904 Device %s is busy with 1 reader.\n"), dev_name(dev));
            } else {
                 Dmsg1(90, "Device busy with %d writers\n", dev->num_writers);
                 bnet_fsend(dir, _("3905 Device %s is busy with %d writer(s).\n"),
            } else {
                 Dmsg1(90, "Device busy with %d writers\n", dev->num_writers);
                 bnet_fsend(dir, _("3905 Device %s is busy with %d writer(s).\n"),
@@ -689,27 +666,12 @@ static int release_cmd(JCR *jcr)
 {
    POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
 {
    POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
    DEVICE *dev;
-   int found = 0;
 
    dname = get_memory(dir->msglen+1);
    if (sscanf(dir->msg, "release %s", dname) == 1) {
 
    dname = get_memory(dir->msglen+1);
    if (sscanf(dir->msg, "release %s", dname) == 1) {
-      unbash_spaces(dname);
-      device = NULL;
-      LockRes();
-      while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
-        /* Find resource, and make sure we were able to open it */
-        if (strcmp(device->hdr.name, dname) == 0 && device->dev) {
-            Dmsg1(20, "Found device %s\n", device->hdr.name);
-           found = 1;
-           break;
-        }
-      }
-      UnlockRes();
-      if (found) {
-        jcr->device = device;
-        dev = device->dev;
+      if (find_device(jcr, dname)) {
+        dev = jcr->device->dev;
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
             Dmsg0(90, "Device already released\n");
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!(dev->state & ST_OPENED)) {
             Dmsg0(90, "Device already released\n");
@@ -722,18 +684,15 @@ static int release_cmd(JCR *jcr)
             bnet_fsend(dir, _("3912 Device %s waiting for mount.\n"), dev_name(dev));
 
         } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
             bnet_fsend(dir, _("3912 Device %s waiting for mount.\n"), dev_name(dev));
 
         } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
-            bnet_fsend(dir, _("3913 Device %s is busy in acquire.\n"),
-              dev_name(dev));
+            bnet_fsend(dir, _("3913 Device %s is busy in acquire.\n"), dev_name(dev));
 
         } else if (dev->dev_blocked == BST_WRITING_LABEL) {
 
         } else if (dev->dev_blocked == BST_WRITING_LABEL) {
-            bnet_fsend(dir, _("3914 Device %s is being labeled.\n"),
-              dev_name(dev));
+            bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), dev_name(dev));
 
         } else if (dev_state(dev, ST_READ) || dev->num_writers) {
            if (dev_state(dev, ST_READ)) {
                 Dmsg0(90, "Device in read mode\n");
 
         } else if (dev_state(dev, ST_READ) || dev->num_writers) {
            if (dev_state(dev, ST_READ)) {
                 Dmsg0(90, "Device in read mode\n");
-                bnet_fsend(dir, _("3915 Device %s is busy with 1 reader.\n"),
-                  dev_name(dev));
+                bnet_fsend(dir, _("3915 Device %s is busy with 1 reader.\n"), dev_name(dev));
            } else {
                 Dmsg1(90, "Device busy with %d writers\n", dev->num_writers);
                 bnet_fsend(dir, _("3916 Device %s is busy with %d writer(s).\n"),
            } else {
                 Dmsg1(90, "Device busy with %d writers\n", dev->num_writers);
                 bnet_fsend(dir, _("3916 Device %s is busy with %d writer(s).\n"),
@@ -766,33 +725,17 @@ static int release_cmd(JCR *jcr)
  */
 static int autochanger_cmd(JCR *jcr)
 {
  */
 static int autochanger_cmd(JCR *jcr)
 {
-   POOLMEM *devname;
+   POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
    DEVICE *dev;
-   int found = 0;
-
-   devname = get_memory(dir->msglen+1);
-   if (sscanf(dir->msg, "autochanger list %s ", devname) == 1) {
-      unbash_spaces(devname);
-      device = NULL;
-      LockRes();
-      while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
-        /* Find resource, and make sure we were able to open it */
-        if (strcmp(device->hdr.name, devname) == 0 && device->dev) {
-            Dmsg1(20, "Found device %s\n", device->hdr.name);
-           found = 1;
-           break;
-        }
-      }
-      UnlockRes();
-      if (found) {
-        jcr->device = device;
-        dev = device->dev;
+
+   dname = get_memory(dir->msglen+1);
+   if (sscanf(dir->msg, "autochanger list %s ", dname) == 1) {
+      if (find_device(jcr, dname)) {
+        dev = jcr->device->dev;
         P(dev->mutex);               /* Use P to avoid indefinite block */
         if (!dev_is_tape(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));
+            bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), dev_name(dev));
         } else if (!(dev->state & ST_OPENED)) {
            if (open_dev(dev, NULL, READ_WRITE) < 0) {
                bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev));
         } else if (!(dev->state & ST_OPENED)) {
            if (open_dev(dev, NULL, READ_WRITE) < 0) {
                bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev));
@@ -808,8 +751,7 @@ static int autochanger_cmd(JCR *jcr)
            autochanger_list(jcr, dev, dir);
         } else if (dev_state(dev, ST_READ) || dev->num_writers) {
            if (dev_state(dev, ST_READ)) {
            autochanger_list(jcr, dev, dir);
         } else if (dev_state(dev, ST_READ) || dev->num_writers) {
            if (dev_state(dev, ST_READ)) {
-                bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"),
-                  dev_name(dev));
+                bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"), dev_name(dev));
            } else {
                 bnet_fsend(dir, _("3902 Device %s is busy with %d writer(s).\n"),
                   dev_name(dev), dev->num_writers);
            } else {
                 bnet_fsend(dir, _("3902 Device %s is busy with %d writer(s).\n"),
                   dev_name(dev), dev->num_writers);
@@ -819,14 +761,112 @@ static int autochanger_cmd(JCR *jcr)
         }
         V(dev->mutex);
       } else {
         }
         V(dev->mutex);
       } else {
-         bnet_fsend(dir, _("3999 Device %s not found\n"), devname);
+         bnet_fsend(dir, _("3999 Device %s not found\n"), dname);
       }
    } else {  /* error on scanf */
       pm_strcpy(&jcr->errmsg, dir->msg);
       bnet_fsend(dir, _("3908 Error scanning autocharger list command: %s\n"),
         jcr->errmsg);
    }
       }
    } else {  /* error on scanf */
       pm_strcpy(&jcr->errmsg, dir->msg);
       bnet_fsend(dir, _("3908 Error scanning autocharger list command: %s\n"),
         jcr->errmsg);
    }
-   free_memory(devname);
+   free_memory(dname);
    bnet_sig(dir, BNET_EOD);
    return 1;
 }
    bnet_sig(dir, BNET_EOD);
    return 1;
 }
+
+/*
+ * Read and return the Volume label
+ */
+static int readlabel_cmd(JCR *jcr)
+{
+   POOLMEM *dname;
+   BSOCK *dir = jcr->dir_bsock;
+   DEVICE *dev;
+   int Slot;
+
+   dname = get_memory(dir->msglen+1);
+   if (sscanf(dir->msg, "readlabel %s Slot=%d", dname, &Slot) == 2) {
+      if (find_device(jcr, dname)) {
+        dev = jcr->device->dev;
+
+        P(dev->mutex);               /* Use P to avoid indefinite block */
+        if (!(dev->state & ST_OPENED)) {
+           if (open_dev(dev, NULL, READ_WRITE) < 0) {
+               bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev));
+           } else {
+              read_volume_label(jcr, dev, Slot);
+              force_close_dev(dev);
+           }
+         /* Under certain "safe" conditions, we can steal the lock */
+        } else if (dev->dev_blocked && 
+                   (dev->dev_blocked == BST_UNMOUNTED ||
+                    dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
+                    dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) {
+           read_volume_label(jcr, dev, Slot);
+        } else if (dev_state(dev, ST_READ) || dev->num_writers) {
+           if (dev_state(dev, ST_READ)) {
+                bnet_fsend(dir, _("3911 Device %s is busy with 1 reader.\n"),
+                           dev_name(dev));
+           } else {
+                bnet_fsend(dir, _("3912 Device %s is busy with %d writer(s).\n"),
+                  dev_name(dev), dev->num_writers);
+           }
+        } else {                     /* device not being used */
+           read_volume_label(jcr, dev, Slot);
+        }
+        V(dev->mutex);
+      } else {
+         bnet_fsend(dir, _("3999 Device %s not found\n"), dname);
+      }
+   } else {
+      pm_strcpy(&jcr->errmsg, dir->msg);
+      bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
+   }
+   free_memory(dname);
+   bnet_sig(dir, BNET_EOD);
+   return 1;
+}
+
+/* 
+ * Read the tape label
+ *
+ *  Enter with the mutex set
+ */
+static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
+{
+   BSOCK *dir = jcr->dir_bsock;
+   DEV_BLOCK *block;
+   bsteal_lock_t hold;
+   
+   steal_device_lock(dev, &hold, BST_WRITING_LABEL);
+   
+   jcr->VolumeName[0] = 0;
+   jcr->VolCatInfo.Slot = Slot;
+   autoload_device(jcr, dev, 0, dir);     /* autoload if possible */
+   block = new_block(dev);
+
+   /* Ensure that the device is open -- autoload_device() closes it */
+   for ( ; !(dev->state & ST_OPENED); ) {
+      if (open_dev(dev, jcr->VolumeName, READ_WRITE) < 0) {
+         bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"), 
+           dev_name(dev), strerror_dev(dev));
+        goto bail_out;
+      }
+   }
+
+   dev->state &= ~ST_LABEL;          /* force read of label */
+   switch (read_dev_volume_label(jcr, dev, block)) {               
+   case VOL_OK:
+      bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolName, Slot);
+      Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolName);
+      break;
+   default:
+      bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
+                dev_name(dev), jcr->errmsg);
+      break;
+   }
+
+bail_out:
+   free_block(block);
+   give_back_device_lock(dev, &hold);
+   return;
+}
index c820dfa35fbc946ba6d35805af2d520fab7c12ca..afee4657070b11f0194b72496cdbdaf33b1ef836 100644 (file)
@@ -36,7 +36,7 @@ EXTRAOBJS = @OBJLIST@
 .c.o:
        $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
 #-------------------------------------------------------------------------
 .c.o:
        $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
 #-------------------------------------------------------------------------
-all: Makefile bsmtp dbcheck testfind testls hammer
+all: Makefile bsmtp dbcheck testfind testls 
        @echo "==== Make of tools is good ===="
        @echo " "
 
        @echo "==== Make of tools is good ===="
        @echo " "
 
index 66d98188d1c2396f04124a2a9b5017f6a6294b9b..2a8b2205c5981c00084f4bf33c4dd8b2d5e2d813 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.33"
 #define VSTRING "1"
 #undef  VERSION
 #define VERSION "1.33"
 #define VSTRING "1"
-#define BDATE   "14 Nov 2003"
-#define LSMDATE "14Nov03"
+#define BDATE   "18 Nov 2003"
+#define LSMDATE "18Nov03"
 
 /* Debug flags */
 #undef  DEBUG
 
 /* Debug flags */
 #undef  DEBUG