]> 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.
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/alter_mysql_tables
+       chmod 755 src/cats/update_mysql_tables
        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
 
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)
 
-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:  !!!!!
-- 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/alter_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/alter_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 \
@@ -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/update_bacula_tables \
           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/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/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/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
index 5e93cb11a1c13c670763b232f3a52878a79992d5..258c1663faedbfe77c25573e36b87411500d987c 100755 (executable)
@@ -17576,7 +17576,7 @@ if test "x${subsysdir}" = "x${sbindir}" ; then
    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
   "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/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/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/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" ;;
@@ -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/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" ;;
@@ -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/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/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/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
index 2dd8c85eb8d328ae877c7ef19215e584436abdab..ad5eecdb119ed1a618be754e977933661085ab90 100644 (file)
@@ -47,6 +47,31 @@ For 1.33 Testing/Documentation:
                 
 
 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).
@@ -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
-- 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)
@@ -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.
-- 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?
-- 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.
@@ -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:
-- 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,
-  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
@@ -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();
+- 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
 #
-# 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@
index 19f04f028b35d82bf480378100d82adefa260bcb..8b725bc72222400b1b37247312b51562810e3a46 100755 (executable)
@@ -3,7 +3,7 @@
 # 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@
index a4bfdd4f5a47a7964286014c23ea26d0562a2be5..e58287625d338a806b1b1cdbae54ca4786577f9b 100755 (executable)
@@ -3,7 +3,7 @@
 # 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@
index c2353f3f7f4924ead745671b30aa15892d7d5ff1..e7a8344a055032be555ceaedfd77da93a60c0523 100644 (file)
@@ -2,8 +2,6 @@
 Makefile
 make_catalog_backup
 delete_catalog_backup
-alter_mysql_tables
-alter_sqlite_tables
 create_bdb_database
 create_mysql_database
 create_sqlite_database
@@ -20,3 +18,8 @@ mysql
 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) 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) update_bacula_tables
        $(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) 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) 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  
@@ -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) update_@DB_NAME@_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)
index 62eedfc3a1142bf995d54300500b58884e1e593f..f17fecad423ef9992d1ee25742e92e8c2c31874f 100644 (file)
@@ -48,7 +48,7 @@ typedef int (DB_RESULT_HANDLER)(void *, int, char **);
 
 #ifdef HAVE_SQLITE
 
-#define BDB_VERSION 6
+#define BDB_VERSION 7
 
 #include <sqlite.h>
 
@@ -142,7 +142,7 @@ extern void my_sqlite_free_table(B_DB *mdb);
 
 #ifdef HAVE_MYSQL
 
-#define BDB_VERSION 6
+#define BDB_VERSION 7
 
 #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,
-   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,
@@ -50,12 +50,12 @@ CREATE TABLE Job (
    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,
-   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,
@@ -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,
-   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)
    );
@@ -98,22 +98,24 @@ CREATE TABLE Media (
    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,
-   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)
    );
@@ -121,15 +123,15 @@ CREATE TABLE Media (
 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,
-   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,
@@ -173,7 +175,7 @@ CREATE TABLE Version (
    );
 
 -- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (6);
+INSERT INTO Version (VersionId) VALUES (7);
 
 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,
+   Drive INTEGER DEFAULT 0,
+   InChanger TINYINT DEFAULT 0,
    PRIMARY KEY(MediaId)
    );
 
@@ -184,7 +186,7 @@ CREATE TABLE Version (
    );
 
 -- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (6);
+INSERT INTO Version (VersionId) VALUES (7);
 
 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, 
-                      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);
@@ -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_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);
 
@@ -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);
-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 */
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);
    }
 
-   /* 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) {
@@ -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,"
-"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),
@@ -282,7 +284,9 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
                  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)) {
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);
    }
    
-   /* 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);
 
-   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);
 
@@ -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
-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);
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
-  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
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'},
@@ -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 */
-        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) {
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 slot = 0;
+   int Slot = 0, InChanger = 0;
 
    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;
       }
-      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);
-      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));
@@ -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 {      
-      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);
@@ -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, _("InChanger Flag"));
       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 */
-        int slot;
+        int Slot;
 
         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;
         }
-        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;
         }
-        mr.Slot = slot;
+        mr.Slot = Slot;
         /*
          * 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;
 
-      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"));
@@ -1027,7 +1051,7 @@ static int update_volume(UAContext *ua)
         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)) {
@@ -1040,6 +1064,7 @@ static int update_volume(UAContext *ua)
         }
         update_volpool(ua, ua->cmd, &mr);
         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 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 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 */
 }
 
+#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 
@@ -71,6 +160,8 @@ int update_slots(UAContext *ua)
    STORE *store;
    vol_list_t *vl, *vol_list = NULL;
    MEDIA_DBR mr;
+   char *slot_list;
+   bool scan;       
 
    if (!open_db(ua)) {
       return 1;
@@ -81,8 +172,15 @@ int update_slots(UAContext *ua)
    }
    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"));
@@ -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) {
-
+      /* 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)) {
-         if (mr.Slot != vl->Slot) {
+         if (mr.Slot != vl->Slot || !mr.InChanger) {
             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 {
@@ -120,23 +233,15 @@ int update_slots(UAContext *ua)
 
 
 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;
 }
 
+
 /*
  * 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;
-   sd = ua->jcr->store_bsock;
    char dev_name[MAX_NAME_LENGTH];
    MEDIA_DBR mr, omr;
    POOL_DBR pr;
@@ -241,6 +345,7 @@ checkName:
       } else {
         mr.Slot = ua->pint32_val;
       }
+      mr.InChanger = 1;              /* assumed if we are labeling it */
    }
 
    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) {
+      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"),
@@ -297,9 +396,7 @@ checkName:
    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;
 }
@@ -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;
+   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"));
@@ -328,6 +432,9 @@ static void label_from_barcodes(UAContext *ua)
                   "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): ")) ||
@@ -343,7 +450,9 @@ static void label_from_barcodes(UAContext *ua)
 
    /* 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;
@@ -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.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;
       }
+      mr.InChanger = 1;
       /*
        * 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));
-      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;
-      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:
-   /* 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;
 }
@@ -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;
 
-   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);
@@ -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;
+        mr->InChanger = 1;
         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 */
+        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);
@@ -511,7 +610,69 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    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];
@@ -520,13 +681,9 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
    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;
    }
-   sd  = ua->jcr->store_bsock;
 
    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;
       }
 
-      /* Validate Slot:Barcode */
+      /* Validate Slot: if scanning, otherwise Slot:Barcode */
       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;
-      }
-      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;
-      vl->VolName = bstrdup(p);
+      if (p) {
+        vl->VolName = bstrdup(p);
+      } else {
+        vl->VolName = NULL;
+      }
       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;
 }
 
+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 
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]) {
+        /* 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;
         }
-        /* Ignore barcode(s) keywords */
-         if (strncasecmp("barcode", ua->argk[i], 7) == 0) {
-           continue;
-        }
         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
+       rm -f bin/smtp.exe bin/console.exe
        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;
    }
-   while (*p && *p == ' ') {
+   while (*p && B_ISSPACE(*p)) {
       p++;
    }
    *msg = p;
@@ -85,7 +85,7 @@ int skip_nonspaces(char **msg)
    if (!p) {
       return 0;
    }
-   while (*p && *p != ' ') {
+   while (*p && !B_ISSPACE(*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.
  *
@@ -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 */
-      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);
@@ -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.
@@ -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);
    }
 
-   dev->dev_blocked = dev_blocked;
+   dev->dev_blocked = dev_blocked;    /* restore entry state */
    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);
+static int readlabel_cmd(JCR *jcr);
 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 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);
@@ -94,6 +97,7 @@ static struct s_cmds cmds[] = {
    {"status",    status_cmd},
    {"autochanger", autochanger_cmd},
    {"release",   release_cmd},
+   {"readlabel", readlabel_cmd},
    {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;
-   DEVRES *device;
    DEVICE *dev;
-   int found = 0, ok = 0;
+   bool ok = false;
    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) {
-        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) {
-        ok = 1;
+        ok = true;
       }
    }
    if (ok) {
-      unbash_spaces(dname);
       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 */
-        jcr->device = device;
-        dev = device->dev;
+        dev = jcr->device->dev;
 
         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) {
-        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;
@@ -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"), 
-        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));
@@ -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"),
-        dev->dev_name, jcr->errmsg);
+        dev_name(dev), jcr->errmsg);
       stat = 0;
       break;
    }
@@ -461,45 +448,52 @@ static int read_label(JCR *jcr, DEVICE *dev)
    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)
 {
-   POOLMEM *dev_name;
+   POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    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;
-        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;
-            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;
 
+        /* 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 */
@@ -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) {
+              /* We blocked the device, so unblock it */
                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");
@@ -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"), 
-                 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"),
-                         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"), 
-                      dev->dev_name);
+                      dev_name(dev));
            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"),
-                    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"),
-                            dev->dev_name);
+                            dev_name(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"), 
-                    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"),
-                            dev->dev_name);
+                            dev_name(dev));
               }
            }
            break;
@@ -577,13 +572,13 @@ static int mount_cmd(JCR *jcr)
         }
         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);
    }
-   free_memory(dev_name);
+   free_memory(dname);
    bnet_sig(dir, BNET_EOD);
    return 1;
 }
@@ -595,27 +590,12 @@ static int unmount_cmd(JCR *jcr)
 {
    POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
-   int found = 0;
 
    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");
@@ -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, _("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) {
-            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");
-                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"),
@@ -689,27 +666,12 @@ static int release_cmd(JCR *jcr)
 {
    POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    DEVICE *dev;
-   int found = 0;
 
    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");
@@ -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, _("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) {
-            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");
-                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"),
@@ -766,33 +725,17 @@ static int release_cmd(JCR *jcr)
  */
 static int autochanger_cmd(JCR *jcr)
 {
-   POOLMEM *devname;
+   POOLMEM *dname;
    BSOCK *dir = jcr->dir_bsock;
-   DEVRES *device;
    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)) {
-            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));
@@ -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)) {
-                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);
@@ -819,14 +761,112 @@ static int autochanger_cmd(JCR *jcr)
         }
         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);
    }
-   free_memory(devname);
+   free_memory(dname);
    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) $<
 #-------------------------------------------------------------------------
-all: Makefile bsmtp dbcheck testfind testls hammer
+all: Makefile bsmtp dbcheck testfind testls 
        @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"
-#define BDATE   "14 Nov 2003"
-#define LSMDATE "14Nov03"
+#define BDATE   "18 Nov 2003"
+#define LSMDATE "18Nov03"
 
 /* Debug flags */
 #undef  DEBUG