]> git.sur5r.net Git - bacula/bacula/commitdiff
- Reset NumVols in Pool record from database on every update
authorKern Sibbald <kern@sibbald.com>
Sat, 2 Apr 2005 09:22:59 +0000 (09:22 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 2 Apr 2005 09:22:59 +0000 (09:22 +0000)
  Pool.
- Modify DB to support multiple simultaneous copies and
  RAIT stiping.
- Pass copy and stripe between DIR and SD and put into
  the JobMedia DB record.
- Update and test SQLite and MySQL datebase creation and
  update scripts.
- Implement version 9 of the DB.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1906 91ce42f0-d328-0410-95d8-f526ca767f89

21 files changed:
bacula/ChangeLog
bacula/ReleaseNotes
bacula/src/cats/cats.h
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_postgresql_tables.in
bacula/src/cats/make_sqlite3_tables.in
bacula/src/cats/make_sqlite_tables.in
bacula/src/cats/sql_create.c
bacula/src/cats/sql_get.c
bacula/src/cats/sql_list.c
bacula/src/cats/sql_update.c
bacula/src/cats/update_mysql_tables.in
bacula/src/cats/update_postgresql_tables.in
bacula/src/cats/update_sqlite3_tables.in
bacula/src/cats/update_sqlite_tables.in
bacula/src/dird/catreq.c
bacula/src/dird/msgchan.c
bacula/src/stored/askdir.c
bacula/src/stored/dev.h
bacula/src/stored/job.c
bacula/src/version.h

index f2b320cca665dc58e774d912e1845dc984729a1f..4bdbd37550432c68e9cd3a716b819f2d56ee5aef 100644 (file)
@@ -1,4 +1,549 @@
 
+Changes to 1.37.12:
+02Apr05
+- Reset NumVols in Pool record from database on every update
+  Pool.
+- Modify DB to support multiple simultaneous copies and
+  RAIT stiping.
+- Pass copy and stripe between DIR and SD and put into
+  the JobMedia DB record.
+- Update and test SQLite and MySQL datebase creation and
+  update scripts.
+- Implement version 9 of the DB.
+31Mar05
+- Convert more atoi to str_to_int64() for DB.
+- Implement filling in NumVols by querying DB rather
+  than trying to keep track of it.
+- Add storage name to string passed to in use storage=
+- Fix newVolume() so that the Python script is always
+  called.
+- Fix handling of pool,PoolId, and storage in ua_output.
+- Same fix in ua_status.c
+- Remove required locking of resources
+- Replace pthread_cond_signal() by pthread_cond_broadcast()
+  hoping to fix the /lib/tls hang problems (lost signal).
+- Move resource locking seaching from parse_conf.c to res.c
+  in src/lib.
+- Modify end of volume handling so that fixup_... does not
+  redo what block.c has already done -- writing Vol info to
+  DIR. This fixes a bug with bad numbers of files on a tape
+  when it filled as reported by Peter.
+- In release_device() do not update the DIR on the Volume
+  info if the the information was already written at the
+  end of the tape.
+28Mar05
+- NOTE!!!! This version has a new DIR <--> SD protocol. Both 
+  must be updated at the same time.
+- Begin implementation of passing all the Storage and Device
+  possibilities to the SD for examination during the reserve 
+  phase.
+- Modify the reserve and acquire code in the SD to make a 
+  job wait if the device is not available.
+- Implement New Volume Each Job in DIR and pass to SD, not yet
+  used.
+- Remove init/update of the Device resource in DIR
+- Remove passing PoolId to SD and back.
+26Mar05
+- Remove \a and -e from error echos in most Makefiles.
+- Add more debug code when there are errors on the tape 
+  to try to find Peter's tape problem.
+- Add wait.c (oops forgot previously).
+- Move all the reserve/acquire_device_for_read/append to have
+  only a DCR as the argument.
+- Rework the reserve_device_for_append() in stored to wait
+  if the drive is not available.  Note! This is a short
+  term solution.
+25Mar05
+- Comment out Multiple Connections in the document.
+- Move the P() and V() to subroutines so that they can be accessed
+  from class methods. The reference to strerror() caused problems.
+- Implement new DEVICE class methods block() and unblock() that
+  do what was previously done in 3 lines of code.
+- Implement wait_for_device(), which will wait for any device
+  to be released then return. This requires a new global mutex
+  and condition variable, and is implemented in src/stored/wait.c
+- Change the code in reserve_device_for_read(), which previously
+  failed the job to use the new device wait code.
+22Mar05
+- Apply reschedule patch to 1.37 code.
+- Add copyright to title page of manual so it is clear.
+- Create patch for rescheduling problem found by Ludovic. Storage
+  pointers were lost during rescheduling.
+- Attempt to fix 2.6 rescue disk -- failed!
+- Start working on adding a wait routine in the SD.
+- Cleanup some old invalid doc in watchdog.
+- Convert a number of references to dev->dev_name to dev->print_name().
+- Add new wait.c file to SD.
+- Add a few more methods to DEVICE in SD to cleanup code a
+  bit -- implement a few of the methods.
+18Mar05
+- Fix more print_name()s for printing device name.
+- Modify open_dev to try 10 times every 6 seconds to
+  open the device if it gets an I/O error (meaning no
+  volume mounted). This gives a bit of settling in time
+  for an autochanger and avoids spurious messages.
+- Change all yes/no to yes|no in the manual.
+- Fix win32 create_file.c typo.
+- Fix a typo in an error message.
+17Mar05
+- Detect if fseeko exists with autoconf. If so, use it 
+  and ftello.
+- Remove old bacula-*.conf from examples directory (out
+  of date).
+- Remove latex-fr index files from CVS.
+- Rewrite code that stops reading the tape so that the
+  tape is marked at EOT, then once the work is done,
+  the EOT flag is removed.
+- Flush output to file after every send in console.
+- Make setting VolFiles to smaller number fatal.
+- Disable Multiple Connections code.
+- Add patch from user for NetBSD statvsfs() fix to
+  fstype.c
+- Take more care with errors in acquire.c
+- Don't run through dvd code in append.c if bad status
+  returned.
+- Modify code so that an autochanger fault is fatal.
+- Use dev->print_name() in more places.
+- Implement dev->can_steal_lock() to simplify code.
+- Make btape re-read first 10000 records on fill command.
+- Check error return and fail job from fseeko and ftello
+  in spool.c.  Don't let a -1 slip in as size.
+
+Changes to 1.37.7:
+15Mar05
+- Apply NetBSD patch from kardel in bug 258.
+14Mar05
+- Add a second job and a second client to the default
+  bacula-dir.conf file.
+- Remove old style Include/Excludes.
+- Fix ANSI labels to put EOF1 and EOF2 after each file mark.
+- Add Python to SD and FD.
+12Mar05
+- Implement IBM labels
+- Implement EOF and EOV labels at the end of a volume.
+- Fix a rather ugly problem with the PoolId not getting
+  passed correctly. Now the DIR passes the Pool name and
+  Media Type to the SD, who passes them back when requesting
+  the next Volume. The DIR then looks up the correct PoolId.
+  This takes more time, but always works, AND allows wild
+  card Media Types (i.e. the SD can decide).
+- The DIR <==> SD protocol has changed.
+
+Changes to 1.37.6:
+11Mar05
+- Fix scanf of PoolId in catreq to handle 64 bit Ids.
+10Mar05
+- Add new ua_update.c file and move update_cmd there.
+- Modify "update slots" to obtain actual number of slots.
+- Tweak autochanger code to handle new slots request.
+- Modify autochanger code to lock/unlock around slots and
+  update slots code.
+09Mar05
+- Patch the FD so that it does not issue an error message if
+  it attempts to restore the permissions on a Win32 drive.
+- Edit "Resource-name" (physical-name) for the device name
+  everywhere in the SD.
+- Remove .linked.tex files in preparation for cutover to
+  using .tex in place of .wml.
+08Mar05
+- Copy latest config.sub and config.guess from autoconf.
+- Try new way of identifying drives with:
+   "resource-name" (physical-name)
+  More work need to a complete conversion.
+07Mar05
+- Rework some of the autochanger data so that the DIR has   
+  the number of drives.
+- Modify the way the Device info is returned so that it comes
+  back as a special message type and can be sent anytime the
+  Device status changes.
+- Copy the change name and changer command into the device
+  record if none is specified.
+- Require the change command and changer name to be specified in
+  and AutoChanger resource.
+- Force all the Media Type records of all devices in an Autochanger
+  to be the same.
+06Mar05
+- Add new "run" command to Job resource in DIR. This permits
+  cloning a job as many times as you want.
+- Pass PoolId to SD on Query request. It is now used in the
+  Find_media catalog request.
+- Reworked the Device resource in the DIR. Eliminated num_waiting
+  and use_count, but added max_writers, reserved, and PoolId.
+- This DIR is nolonger compatible with previous SDs.
+- Add since and cloned keywords to the Console run command
+  to support cloning.
+- Implemented store_alist_str() to allow multiple string items
+  to be specified in a .conf file.
+- Added %s (since time) to Job code editing.
+- Reworked reserving drives in the SD. It now does it much simpler
+  and correctly. 
+05Mar05
+- Integrate HP-UX patch from  Olivier Mehani <olivier.mehani@linbox.com>
+- Fix FD job.c to test correctly for no level.
+
+Changes to 1.37.4:
+04Mar05
+- Change Developers to Developer's Guide as requested by Michael.
+- Fix developers link in manual
+- Add additional dcr changes in SD to allow multiple dcrs.
+02Mar05
+- Fix a few problems with the MySQL table create in 1.37.
+- Delete the new tables in the table delete files.
+- Increase the number of items permitted in a conf table.
+- Make Director loop over alternative Devices specified in the
+  Storage resource until one is reserved by SD.
+- Fix storing of StorageId in Media records.
+- Add AutoSelect = yes|no in bacula-sd.conf
+- Add Autochanger support to Label command.
+- Do not autoselect devices with autoselect set false 
+01Mar05
+- Implement setting DIR Storage device to Autochanger
+  name. 
+- Select first available device in Autochanger.
+- Pass back actual device name used.
+- Allow Query of AutoChanger.
+- Modify Query to include name of AutoChanger if 
+  Device belongs to one.
+- Remove old Pool code in jobq.c
+- Add Autoselect flag to query and DEVICE class (still
+  need Directive).
+28Feb05
+- Lock autochanger script when running.
+- Mark Volume not InChanger if correct volume is not     
+  autoloaded.
+- Corrected some typos in the make_xxx_tables.in files.
+- Made preliminary split of pre-run and run code for each
+  job type. This will permit early opening of SD for reserving
+  drives.
+- Add offline and autochanger fields to Device Query record.
+- Correct pthread_mutex_init() for autochanger in SD.
+- Tweak Makefile for LaTeX manual, plus add nav buttons.
+26Feb05
+- Clean up drive reservation system. Add more sanity checks.
+- Implement a few more methods for the DEVICE class in SD.
+- Add latex directories to make clean
+- move DEV_BSIZE to B_DEV_BSIZE to avoid conflicts with
+  certain header files (FreeBSD).
+24Feb05
+- Fix an ASSERT that was triggering in stored/acquire.c
+  attempt to fix a bug report.
+23Feb05
+- Corrected SunOs to SunOS in btraceback (user submitted).
+- Applied patch from Roger HÃ¥kansson <hson@ludd.luth.se>
+  to warn the user of defective AWKs during ./configure.
+20Feb05
+- Add some changes submitted by a user for HP client build.
+  Not all changes accepted.
+- Rework code in filed/backup.c to ease #ifdefing and make
+  program flow more obvious.
+- Split DVD code out of dev.c into dvd.c
+- Tweak #ifdefing to add back all the performance measurement
+  #defines in version.h
+- Put most of MTIOCGET code in a subroutine to simplify the
+  mainline code.
+- Make clean remove old CVS files
+- Remove unnecessary image files from Latex directory
+- Implement remaining parts of Storage DB record and
+  its use in the Director.
+- Implement
+  FullMaxWaitTime, Differential Max Wait Time, and               
+  Incremental Max Wait time in Job resource.
+- Start work on SD Autochanger code.
+19Feb05
+- Add back JobId index for MySQL as default -- speeds up 
+  pruning.
+- Add more database fields and fix the update scripts to
+  include the new items.
+- Pass actual level to FD so that ClientRun editing can reflect
+  correct level -- ditto for job status. This makes the DIR
+  incompatible with older clients!
+- Move jobq.c acquire resources to static subroutine so that
+  the code logic becomes clearer. This is in preparation for
+  actually using the new Device resources.
+- Fix some lower case problems in sql_cmds.c reported by
+  Debian.
+- Correct a seg fault in the SD reported by a user. Occurred
+  only when a high debug level was set.
+- Modify init_dev() in dev.c to take JCR as first arg so that
+  proper error messages can be reported in next item.
+- Modify the query and use device SD commands to attempt to
+  open the device if it could not previously be opened.
+- Correct error message for Could not reserve device.
+- Correct some minor details with Autochanger resource in SD.
+18Feb05
+- Fix seg fault if debug level 900 set in SD.
+- Truncate Win32 child return code to 8 bits.
+- Remove some old lld's.
+
+Changes to 1.37.3:
+16Feb05
+- Make another attempt at fixing the ClientRunXXX return code 
+  bug on Win32 machines.
+- Apply ua_status patch from Carsten Paeth <calle@calle.in-berlin.de>
+  which enforces console ACLs in the status command for Jobs.
+15Feb05
+- Fix Media LabelDate and FirstWritten to be correctly set.
+- Fix deadlock in multiple simultaneous jobs.
+- Fix tape "truncation"/"number of files" after restore bug.
+10Feb05
+- Ensure that correct error messages are returned when
+  reading an ANSI label.
+09Feb05
+- Modified ANSI label code to preserve any ANSI label 
+  already found by skipping over it rather than rewriting
+  it.
+- Split the ANSI label code into ansi_label.c
+- Do not let user relabel an ANSI labeled tape.
+- Applied a patch for the console help command supplied
+  in a bug report. 
+- Added some new dev methods. Most notably was
+  set_eof(), which handles setting all the dev variables
+  when an EOF is just read. This is now used most everywhere
+  in the code.
+07Feb05
+- Added code to detect that no files were inserted into the 
+  tree for a restore. If a specific JobId was specified, the
+  user has the option of restoring everything.
+- More progress in implementing 64 bit DB Ids.
+- Modified the daemon start messages for RH.
+- Implement update scripts for all database types.
+- First cut at implementing restore directory (it will not
+  recurse).
+04Feb05
+- OK, I think ANSI labels work.
+- Added Label Type = ANSI|IBM|Bacula to Device resource in SD.
+  If this is set, it will force writing of the appropriate
+  label type.
+- Added Check Labels = yes|no to Device resource in SD. If this
+  is set, Bacula will check for ANSI labels and accept them,      
+  otherwise, ANSI labels will not be accepted when the tape
+  is first mounted.
+02Feb05
+- Second cut ANSI labels.
+01Feb05
+- Merge Preben's patch for ACLs and for Mac OS X resource forks.
+- Some doc updates.
+- Display more informative message when a device was not
+  found or could not be opened.
+- Add the sqlite3 database scripts. 
+- Add some patches for 1.36.1 (note, I have now prepared
+  a 1.36.2 with all the patches and some new features --
+  to be documented).
+- Some minor doc updates.
+- Add Arno's baculareport.pl script to the examples directory.
+29Jan05 -- after vacation
+- Add support for SQLite3 (it seems to run at 1/2 the speed
+  of SQLite2).  Use --with-sqlite3 instead of --with-sqlite
+  to get SQLite3.
+- Add target for running qemu to boot Rescue CDROM
+- Add code to support kernel 2.6 in Rescue CDROM -- does NOT yet
+  boot correctly.
+- Implement ANSI labels -- not yet tested.
+  This required changes to DB format. No upgrade script yet.
+  Note, more work needed to modify "update" command to handle
+  changing label types, also must restrict volume name lengths
+  to 6 characters.
+- Add new Device, Storage, and MediaType records to DB. No
+  upgrade script yet.
+- Add MediaType to bsr file record types. Not yet used in SD.
+- Permit multiple device specifications in Storage resource in 
+  Dir conf file.
+- Implement Device resources. Director requests Device resource
+  info from SD on startup. 
+- Note!!!! DIR->SD incompatible with previous versions.
+- Remove multiple Storage definitions in Job resource.  One can
+  still specify multiple Storage resources, but they all go into
+  a single alist, and imply sending data to each Storage daemon 
+  simultaneously.
+- Implement Device query command between DIR and SD.
+- Allow DIR to "reserve" a Device. It will then be acquired
+  when the FD connects to the SD.
+- Turn all DIR resources into classes, and implement a few class
+  methods -- more to come.
+- Turn DEVICE in SD into a class, and implement a number of inline
+  class methods -- more to come.
+- I had serious problems with ACL errors on my Laptop, and so had
+  to add the following patch:
+  @@ -181,7 +181,7 @@
+      }
+      /***** Do we really want to silently ignore errors from acl_get_file
+        and acl_to_text?  *****/
+  -   return -1;
+  +   return 0;
+   }
+- Added edit_int64()
+- Reworked and tested a bit the htable routines.
+- Major changes to SD acquire.c -- DIR can now reserve devices. Needs
+  lots of testing!!!!
+- Made a special state code for DVD -- this simplifies the logic
+  of the code, but I probably broke it. Testing needed!!!!
+- Add AutoChanger resource to SD, but not yet used.
+
+Changes to 1.37.2:
+12Jan05
+- Integrate Preben 'Peppe' Guldberg <peppe@wielders.org>'s
+  acl patch. Fix case where configured but no ACL exists.
+  Rework calling arguments to be shorter and positioned
+  more typically in Bacula usage.
+11Jan05
+- Fix scripts/bacula.in to have awk on an environment variable
+  and add comments for Solaris users.
+- Turn off inet_aton in src/lib/address_conf.c for Win32
+- Add new files to win32 build and eliminate a compiler warning.
+- Add sample DVD Device resource to bacula-sd.conf
+08Jan05
+- Integrate Nicolas' patch for direct DVD support.        
+07Jan05
+- Fix fstype error returns.
+- Apply Preben's cleanup.patch which puts back much of the
+  cleanup code in src/filed/restore.c
+06Jan05
+- Apply all of Preben's patches, but revert to old backup.c
+  and old restore.c in filed. Also turn off code in new
+  acl.c because of errors.  The new code, when fully implemented
+  moves platform specific code into acl.c.
+  One of the patches also implements WildFile and WildDir -- thanks.
+01Jan05
+- Implement Python in the SD (no events yet though).
+- Fix some typos in the previous commit.
+30Dec04
+- Enhance CDROM boot to include some documentation at boot time.
+- NOTE!!!!! The CDROM will not boot 2.6 kernels because the
+    boot sequence has changed significantly. Updates to come
+    later.
+- Add memtest option to CDROM boot.
+- Include Nicolas' changes to fix llist JobMedia records.
+- Make sure that ClientRunBefore/After messages from the program
+  are terminated with a newline. Add strerror to output error
+  messages.
+- Return program exit status code in Win32.
+29Dec04
+- Add memtest86 to Bacula Rescue disk
+- Enhance Rescue disk startup screen
+24Dec04
+- Move some variables to eliminate Solaris 2.6 compiler warnings.
+- Fix the seg fault at the end of a job in the FD when using
+  old style include/excludes.
+22Dec04
+- Apply Preben's ACL patch.
+- Integrate Preben's restore patch.
+- Integrate Preben's verify teaks.
+- Fix doc/latex/Makefile to copy/remove .eps files when building
+  html and web outputs.
+21Dec04
+- Fix Bacula so that it does not exit if there is a syntax error
+  in its conf file during a reload command. Bug 182.
+- Apply fixes suggested for old Solaris networking.
+  Fixes bug 190.
+- Apply Preben 'Peppe' Guldberg <peppe@wielders.org>
+  three patches that clean up white space:
+  ws.patch.02.strings:
+    Breaks strings that span lines into concatenated strings. I am not sure
+    if you like this one. Other code works with concatenated strings, though.
+  ws.patch.03.trailing:
+    This removes trailing whitespace. No changes resulted from this for
+    my setup.
+  ws.patch.04.leading:
+    This replaces space runs at the start of line with tabs. No changes
+    again.
+- Fix overriding storage specification to be done
+  through a subroutine.
+- Fix autoconf so it runs with FC3. 
+- Add Python4.3 to configure search paths.
+- Always copy and delete storage definitions into jcr.
+- Check that VolumeName supplied by Python is valid. 
+  Return 0 if not.
+19Dec04
+- Fix undefined in non-Python build.
+- Update rescue disk to include mkinitrd
+- Fix umount_drives in rescue disk (only one arg to umount)
+- Ensure that if SD is manually set in Console, it is used.
+- Put generate_event on pointer and plug it in init. This
+  permits using it in /lib
+- Correct despooling size reported to be Job specific rather
+  than for the whole drive.
+18Dec04
+- Fix bug 207. jcr use count off by one when manually
+  scheduling jobs.
+- Remove FNMATCH test in configure.in and always use
+  the one in our library to get the FN_CASEFOLD GNU
+  extensions on all platforms.
+- While using the rescue CDROM after my computer would not
+  boot, I realized that it would be very useful to have
+  a umount_disks. So, it is not implemented, along with
+  updates to the READMEs and some minor tweaks.
+- Moved mounting the CDROM in the rescue boot from /cdrom
+  to /mnt/cdrom (more standard location).
+- Reboot in CDROM rescue should now work -- requires -d
+  option (no write) to work.
+- Hopefully fixed all the IPV6/4 problems and buffer
+  problems with networking in lib. Bugs 190 and 204.
+  Cleaned up a lot of #ifdefing problems by using routines
+  in address_conf.c
+17Dec04
+- Apply Preben 'Peppe' Guldberg <peppe@wielders.org>
+  alist fix patch.
+- Remove duplicate code from chksum.h (mentioned by Preben).
+13Dec04
+- Integrate Tim Oberfoell <oberfoell@web.de> patch to ACLs
+  to handle both the "standard" and "default" ACLs.
+12Dec04
+- Integrated Preben 'Peppe' Guldberg <peppe@wielders.org>
+  three cleanup patches (btest, verify, find).
+- Integrated Preben 'Peppe' Guldberg <peppe@wielders.org>
+  three cleanup patches (backup, chksum, and verify)
+09Dec04
+- Integrated Preben 'Peppe' Guldberg <peppe@wielders.org>
+  patch to avoid doing MTIOCGET on OSes that do not support
+  it such as OpenBSD.
+- Integrated Preben 'Peppe' Guldberg <peppe@wielders.org>
+  patch to add filesystem type matching to FileSets in the
+  Options resource.
+- Integrated Preben 'Peppe' Guldberg <peppe@wielders.org>
+  patch to add Mac OSX resource fork support (save/restore)
+  to Bacula -- HFS Plus support.
+- Add FileSet to client Job listing query.
+06Dec04
+- Integrated Preben 'Peppe' Guldberg <peppe@wielders.org>
+  patch to backup directories skipped (due to no file system
+  changes or no recursion), and to add a slash to the end
+  of the directory name during the match process.
+- Implement Jamie ffolliott <jamieff@inline.net>
+  patch to dird_conf.c that enables Multiple Connections and
+  fixes a typo in show. The rest of his patch awaits my suggested
+  changes.
+05Dec04 
+- Implement run command in Python
+04Dec04 
+- Implement conversion of the manual, and some minor
+  tweaks to the script tags.
+- Apply a patch supplied by Preben 'Peppe' Guldberg that implements
+  ignore case in wild cards and regexes.
+- Fix a truncated line in the above patch due to my cut and paste.
+03Dec04
+- Fix it so that the InChanger flag is only changed for Volumes
+  in the same Pool.
+- Add PIDOF configuration path and apply to bacula.in
+- Add user supplied patch to add inet_aton() of old Solaris
+  systems.
+- Require pools to match before allowing multiple simultaneous
+  accesses to same storage resource.
+- Add patch supplied by Martin to correct buffer overrun in
+  bsnprintf() with no library snprintf().
+02Dec04
+- Apply user supplied patch that implements No Hard Links.
+- Document Python interface
+- Add hardlink keyword patch supplied by David R Bosso <dbosso@lsit.ucsb.edu>
+01Dec04
+- Fix non-python prototypes in dummy routines.
+- Add python 2.3 to config search list (user submitted patch)
+- Add JobStatus to Python variables.
+28Nov04
+- Add "python restart" command in Console.
+- Make built-in variables table driven.
+- First cut of Python Events for Bacula. Director only.
+  StartJob, EndJob, NewVolume events.
+
 Version 1.36.1 released 26Nov04:
 24Nov04
 - Take Dan's fix to the fix_postgresql_tables (thanks Dan)
index 9d61aa680a4b555d8ab21954ec726634f5211204..1a4d135ef36566d4249c61106e69214fcc18a33a 100644 (file)
@@ -1,8 +1,10 @@
 
-          Release Notes for Bacula 1.37.10
+          Release Notes for Bacula 1.37.12
 
-  Bacula code: Total files = 414 Total lines = 123,723 (*.h *.c *.in)
+  Bacula code: Total files = 419 Total lines = 124,877 (*.h *.c *.in)
 
+Note! The DB has been upgraded from version 8 to 9 and requres
+a DB upgrade.
 
 Major Changes:
 - This version has a new DIR <--> SD protocol. Both must be
index 90f99df892ae3b6d6d5b36a2dc3f2e46d7889853..a941cb25d4982f2e51ab4c4b280a8577096fee7b 100644 (file)
@@ -73,7 +73,7 @@ typedef int (DB_RESULT_HANDLER)(void *, int, char **);
 
 #ifdef HAVE_SQLITE
 
-#define BDB_VERSION 8
+#define BDB_VERSION 9
 
 #include <sqlite.h>
 
@@ -181,7 +181,7 @@ SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb);
 #ifdef HAVE_SQLITE3
 
 
-#define BDB_VERSION 8
+#define BDB_VERSION 9
 
 #include <sqlite3.h>
 
@@ -296,7 +296,7 @@ SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb);
 
 #ifdef HAVE_MYSQL
 
-#define BDB_VERSION 8
+#define BDB_VERSION 9
 
 #include <mysql.h>
 
@@ -360,13 +360,13 @@ typedef struct s_db {
 
 #ifdef HAVE_POSTGRESQL
 
-#define BDB_VERSION 8
+#define BDB_VERSION 9
 
 #include <libpq-fe.h>
 
 /* TEMP: the following is taken from select OID, typname from pg_type; */
-#define IS_NUM(x)             ((x) == 20 || (x) == 21 || (x) == 23 || (x) == 700 || (x) == 701)
-#define IS_NOT_NULL(x)        ((x) == 1)
+#define IS_NUM(x)        ((x) == 20 || (x) == 21 || (x) == 23 || (x) == 700 || (x) == 701)
+#define IS_NOT_NULL(x)   ((x) == 1)
 
 typedef char **POSTGRESQL_ROW;
 typedef struct pg_field {
@@ -583,6 +583,8 @@ struct JOBMEDIA_DBR {
    uint32_t EndFile;                  /* End file on Volume */
    uint32_t StartBlock;               /* start block on tape */
    uint32_t EndBlock;                 /* last block */
+   uint32_t Copy;                     /* identical copy */
+   uint32_t Stripe;                   /* RAIT strip number */
 };
 
 
@@ -597,6 +599,8 @@ struct VOL_PARAMS {
    uint32_t EndFile;                  /* End file on Volume */
    uint32_t StartBlock;               /* start block on tape */
    uint32_t EndBlock;                 /* last block */
+   uint32_t Copy;                     /* identical copy */
+   uint32_t Stripe;                   /* RAIT strip number */
 };
 
 
index 677b65d198cb4eccc7459c81916f084c481d16d2..19e898c0371d41ec258224d52a9bb2bd546e7af9 100644 (file)
@@ -126,6 +126,8 @@ CREATE TABLE JobMedia (
    StartBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
    EndBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
    VolIndex INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   Copy INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   Stripe INTEGER UNSIGNED NOT NULL DEFAULT 0,
    PRIMARY KEY(JobMediaId),
    INDEX (JobId, MediaId)
    );
@@ -232,12 +234,6 @@ CREATE TABLE UnsavedFiles (
    );
 
 
-CREATE TABLE Version (
-   VersionId INTEGER UNSIGNED NOT NULL 
-   );
-
--- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (8);
 
 CREATE TABLE Counters (
    Counter TINYBLOB NOT NULL,
@@ -254,6 +250,12 @@ CREATE TABLE CDImages (
    PRIMARY KEY (MediaId)
    );
 
+CREATE TABLE Version (
+   VersionId INTEGER UNSIGNED NOT NULL 
+   );
+
+-- Initialize Version           
+INSERT INTO Version (VersionId) VALUES (9);
 
 END-OF-DATA
 then
index f990fdcecccb6bf864e05411645b16d22bfdaa6d..8035656587d143a8e4215419cb318880082c7211 100644 (file)
@@ -99,6 +99,8 @@ CREATE TABLE jobmedia
     startblock       bigint      not null default 0,
     endblock         bigint      not null default 0,
     volindex         integer     not null default 0,
+    copy             integer     not null default 0,
+    stripe           integer     not null default 0,
     primary key (jobmediaid)
 );
 
@@ -237,12 +239,6 @@ CREATE TABLE counters
     primary key (counter)
 );
 
-CREATE TABLE version
-(
-    versionid        integer               not null
-);
-
-INSERT INTO Version (VersionId) VALUES (8);
 
 
 CREATE TABLE basefiles
@@ -271,6 +267,14 @@ CREATE TABLE CDImages
    primary key (MediaId)
 );
 
+
+CREATE TABLE version
+(
+    versionid        integer               not null
+);
+
+INSERT INTO Version (VersionId) VALUES (9);
+
 -- Make sure we have appropriate permissions
 
 
index 83dfb0e117eecb4bb53bcecbf1a8c290425fd174..6735135cb13c5b95d31da8f949e0b88d4b069297 100644 (file)
@@ -92,6 +92,8 @@ CREATE TABLE JobMedia (
    StartBlock INTEGER UNSIGNED DEFAULT 0,
    EndBlock INTEGER UNSIGNED DEFAULT 0,
    VolIndex INTEGER UNSIGNED DEFAULT 0,
+   Copy     INTEGER UNSIGNED DEFAULT 0,
+   Stripe   INTEGER UNSIGNED DEFAULT 0,
    PRIMARY KEY(JobMediaId) 
    );
 
@@ -242,8 +244,6 @@ CREATE TABLE Version (
    VersionId INTEGER UNSIGNED NOT NULL 
    );
 
--- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (8);
 
 CREATE TABLE Counters (
    Counter TEXT NOT NULL,     
@@ -260,6 +260,8 @@ CREATE TABLE CDImages (
    PRIMARY KEY (MediaId)
    );
 
+-- Initialize Version           
+INSERT INTO Version (VersionId) VALUES (9);
 
 PRAGMA default_synchronous = OFF;
 PRAGMA default_cache_size = 10000;
index 83dfb0e117eecb4bb53bcecbf1a8c290425fd174..6735135cb13c5b95d31da8f949e0b88d4b069297 100644 (file)
@@ -92,6 +92,8 @@ CREATE TABLE JobMedia (
    StartBlock INTEGER UNSIGNED DEFAULT 0,
    EndBlock INTEGER UNSIGNED DEFAULT 0,
    VolIndex INTEGER UNSIGNED DEFAULT 0,
+   Copy     INTEGER UNSIGNED DEFAULT 0,
+   Stripe   INTEGER UNSIGNED DEFAULT 0,
    PRIMARY KEY(JobMediaId) 
    );
 
@@ -242,8 +244,6 @@ CREATE TABLE Version (
    VersionId INTEGER UNSIGNED NOT NULL 
    );
 
--- Initialize Version           
-INSERT INTO Version (VersionId) VALUES (8);
 
 CREATE TABLE Counters (
    Counter TEXT NOT NULL,     
@@ -260,6 +260,8 @@ CREATE TABLE CDImages (
    PRIMARY KEY (MediaId)
    );
 
+-- Initialize Version           
+INSERT INTO Version (VersionId) VALUES (9);
 
 PRAGMA default_synchronous = OFF;
 PRAGMA default_cache_size = 10000;
index 8fe07996aa149f2543f7ff0d476c77582a6412c9..3c3590c7a63d7f42c79321ebb6521ef241c7f336 100644 (file)
@@ -29,7 +29,7 @@
 /* The following is necessary so that we do not include
  * the dummy external definition of DB.
  */
-#define __SQL_C                      /* indicate that this is sql.c */
+#define __SQL_C                       /* indicate that this is sql.c */
 
 #include "bacula.h"
 #include "cats.h"
@@ -60,7 +60,7 @@ extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
 
 /* Create a new record for the Job
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int
 db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
@@ -85,12 +85,12 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
    Mmsg(mdb->cmd,
 "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate) VALUES "
 "('%s','%s','%c','%c','%c','%s',%s)",
-          jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
-          (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1));
+           jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
+           (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1));
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       jr->JobId = 0;
       stat = 0;
    } else {
@@ -103,13 +103,14 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 
 /* Create a JobMedia record for medium used this job
  * Returns: false on failure
- *         true  on success
+ *          true  on success
  */
 bool
 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
 {
    bool ok = true;;
    int count;
+   char ed1[50], ed2[50];
 
    db_lock(mdb);
 
@@ -123,25 +124,28 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
 
    Mmsg(mdb->cmd,
         "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
-        "StartFile,EndFile,StartBlock,EndBlock,VolIndex) "
-        "VALUES (%u,%u,%u,%u,%u,%u,%u,%u,%u)",
-       jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex,
-       jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count);
+        "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy,Stripe) "
+        "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u,%u)",
+        edit_int64(jm->JobId, ed1),
+        edit_int64(jm->MediaId, ed2),
+        jm->FirstIndex, jm->LastIndex,
+        jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
+        jm->Copy, jm->Stripe);
 
    Dmsg0(300, mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
-        sql_strerror(mdb));
+         sql_strerror(mdb));
       ok = false;
    } else {
       /* Worked, now update the Media record with the EndFile and EndBlock */
       Mmsg(mdb->cmd,
            "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
-          jm->EndFile, jm->EndBlock, jm->MediaId);
+           jm->EndFile, jm->EndBlock, jm->MediaId);
       if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
          Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
-             sql_strerror(mdb));
-        ok = false;
+              sql_strerror(mdb));
+         ok = false;
       }
    }
    db_unlock(mdb);
@@ -153,12 +157,12 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
 
 /* Create Unique Pool record
  * Returns: false on failure
- *         true  on success
+ *          true  on success
  */
 bool
 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 {
-   bool stat;       
+   bool stat;        
    char ed1[30], ed2[30], ed3[50];
 
    Dmsg0(200, "In create pool\n");
@@ -170,9 +174,9 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 0) {
          Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return false;
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return false;
       }
       sql_free_result(mdb);
    }
@@ -183,20 +187,20 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
-                 pr->Name,
-                 pr->NumVols, pr->MaxVols,
-                 pr->UseOnce, pr->UseCatalog,
-                 pr->AcceptAnyVolume,
-                 pr->AutoPrune, pr->Recycle,
-                 edit_uint64(pr->VolRetention, ed1),
-                 edit_uint64(pr->VolUseDuration, ed2),
-                 pr->MaxVolJobs, pr->MaxVolFiles,
-                 edit_uint64(pr->MaxVolBytes, ed3),
-                 pr->PoolType, pr->LabelType, pr->LabelFormat);
+                  pr->Name,
+                  pr->NumVols, pr->MaxVols,
+                  pr->UseOnce, pr->UseCatalog,
+                  pr->AcceptAnyVolume,
+                  pr->AutoPrune, pr->Recycle,
+                  edit_uint64(pr->VolRetention, ed1),
+                  edit_uint64(pr->VolUseDuration, ed2),
+                  pr->MaxVolJobs, pr->MaxVolFiles,
+                  edit_uint64(pr->MaxVolBytes, ed3),
+                  pr->PoolType, pr->LabelType, pr->LabelFormat);
    Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       pr->PoolId = 0;
       stat = false;
    } else {
@@ -210,7 +214,7 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
 /*
  * Create Unique Device record
  * Returns: false on failure
- *         true  on success
+ *          true  on success
  */
 bool
 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
@@ -227,9 +231,9 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 0) {
          Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return false;
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return false;
       }
       sql_free_result(mdb);
    }
@@ -237,13 +241,13 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
    /* Must create it */
    Mmsg(mdb->cmd,
 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
-                 dr->Name,
-                 edit_uint64(dr->MediaTypeId, ed1),
-                 edit_int64(dr->StorageId, ed2));
+                  dr->Name,
+                  edit_uint64(dr->MediaTypeId, ed1),
+                  edit_int64(dr->StorageId, ed2));
    Dmsg1(200, "Create Device: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       dr->DeviceId = 0;
       ok = false;
    } else {
@@ -259,7 +263,7 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
 /*
  * Create a Unique record for Storage -- no duplicates
  * Returns: false on failure
- *         true  on success with id in sr->StorageId
+ *          true  on success with id in sr->StorageId
  */
 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
 {
@@ -279,18 +283,18 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           sql_free_result(mdb);
-           db_unlock(mdb);
-           return false;
-        }
-        sr->StorageId = str_to_int64(row[0]);
-        sr->AutoChanger = atoi(row[1]);   /* bool */
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return true;
+            sql_free_result(mdb);
+            db_unlock(mdb);
+            return false;
+         }
+         sr->StorageId = str_to_int64(row[0]);
+         sr->AutoChanger = atoi(row[1]);   /* bool */
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return true;
       }
       sql_free_result(mdb);
    }
@@ -301,7 +305,7 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       ok = false;
    } else {
@@ -317,12 +321,12 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
 /*
  * Create Unique MediaType record
  * Returns: false on failure
- *         true  on success
+ *          true  on success
  */
 bool
 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
 {
-   bool stat;       
+   bool stat;        
 
    Dmsg0(200, "In create mediatype\n");
    db_lock(mdb);
@@ -333,9 +337,9 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 0) {
          Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return false;
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return false;
       }
       sql_free_result(mdb);
    }
@@ -344,12 +348,12 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
    Mmsg(mdb->cmd,
 "INSERT INTO MediaType (MediaType,ReadOnly) "
 "VALUES ('%s',%d)",
-                 mr->MediaType,
-                 mr->ReadOnly);
+                  mr->MediaType,
+                  mr->ReadOnly);
    Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       mr->MediaTypeId = 0;
       stat = false;
    } else {
@@ -365,7 +369,7 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
  * Create Media record. VolumeName and non-zero Slot must be unique
  *
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int
 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
@@ -376,16 +380,16 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 
    db_lock(mdb);
    Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
-          mr->VolumeName);
+           mr->VolumeName);
    Dmsg1(300, "selectpool: %s\n", mdb->cmd);
 
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 0) {
          Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return 0;
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return 0;
       }
       sql_free_result(mdb);
    }
@@ -397,51 +401,51 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
 "EndFile,EndBlock,LabelType,StorageId) "
 "VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s)",
-                 mr->VolumeName,
-                 mr->MediaType, mr->PoolId,
-                 edit_uint64(mr->MaxVolBytes,ed1),
-                 edit_uint64(mr->VolCapacityBytes, ed2),
-                 mr->Recycle,
-                 edit_uint64(mr->VolRetention, ed3),
-                 edit_uint64(mr->VolUseDuration, ed4),
-                 mr->MaxVolJobs,
-                 mr->MaxVolFiles,
-                 mr->VolStatus,
-                 mr->Slot,
-                 edit_uint64(mr->VolBytes, ed5),
-                 mr->InChanger,
-                 edit_uint64(mr->VolReadTime, ed6),
-                 edit_uint64(mr->VolWriteTime, ed7),
-                 mr->VolParts,
-                 mr->LabelType,
-                 edit_int64(mr->StorageId, ed8) 
-                 );
+                  mr->VolumeName,
+                  mr->MediaType, mr->PoolId,
+                  edit_uint64(mr->MaxVolBytes,ed1),
+                  edit_uint64(mr->VolCapacityBytes, ed2),
+                  mr->Recycle,
+                  edit_uint64(mr->VolRetention, ed3),
+                  edit_uint64(mr->VolUseDuration, ed4),
+                  mr->MaxVolJobs,
+                  mr->MaxVolFiles,
+                  mr->VolStatus,
+                  mr->Slot,
+                  edit_uint64(mr->VolBytes, ed5),
+                  mr->InChanger,
+                  edit_uint64(mr->VolReadTime, ed6),
+                  edit_uint64(mr->VolWriteTime, ed7),
+                  mr->VolParts,
+                  mr->LabelType,
+                  edit_int64(mr->StorageId, ed8) 
+                  );
 
 
    Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       stat = 0;
    } else {
       mr->MediaId = sql_insert_id(mdb, _("Media"));
       stat = 1;
       if (mr->set_label_date) {
-        char dt[MAX_TIME_LENGTH];
-        if (mr->LabelDate == 0) {
-           mr->LabelDate = time(NULL);
-        }
-        localtime_r(&mr->LabelDate, &tm);
+         char dt[MAX_TIME_LENGTH];
+         if (mr->LabelDate == 0) {
+            mr->LabelDate = time(NULL);
+         }
+         localtime_r(&mr->LabelDate, &tm);
          strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
          Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
               "WHERE MediaId=%d", dt, mr->MediaId);
-        stat = UPDATE_DB(jcr, mdb, mdb->cmd);
+         stat = UPDATE_DB(jcr, mdb, mdb->cmd);
       }
    }
 
    /*
     * Make sure that if InChanger is non-zero any other identical slot
-    *  has InChanger zero.
+    *   has InChanger zero.
     */
    db_make_inchanger_unique(jcr, mdb, mr);
 
@@ -452,7 +456,7 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 /*
  * Create a Unique record for the client -- no duplicates
  * Returns: 0 on failure
- *         1 on success with id in cr->ClientId
+ *          1 on success with id in cr->ClientId
  */
 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
 {
@@ -472,22 +476,22 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           sql_free_result(mdb);
-           db_unlock(mdb);
-           return 0;
-        }
-        cr->ClientId = str_to_int64(row[0]);
-        if (row[1]) {
-           bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
-        } else {
-           cr->Uname[0] = 0;         /* no name */
-        }
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return 1;
+            sql_free_result(mdb);
+            db_unlock(mdb);
+            return 0;
+         }
+         cr->ClientId = str_to_int64(row[0]);
+         if (row[1]) {
+            bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
+         } else {
+            cr->Uname[0] = 0;         /* no name */
+         }
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return 1;
       }
       sql_free_result(mdb);
    }
@@ -501,7 +505,7 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       cr->ClientId = 0;
       stat = 0;
@@ -520,7 +524,7 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
 /*
  * Create a Unique record for the counter -- no duplicates
  * Returns: 0 on failure
- *         1 on success with counter filled in
+ *          1 on success with counter filled in
  */
 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
 {
@@ -544,7 +548,7 @@ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       stat = 0;
    } else {
@@ -559,7 +563,7 @@ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
  * Create a FileSet record. This record is unique in the
  *  name and the MD5 signature of the include/exclude sets.
  *  Returns: 0 on failure
- *          1 on success with FileSetId in record
+ *           1 on success with FileSetId in record
  */
 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 {
@@ -580,22 +584,22 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           sql_free_result(mdb);
-           db_unlock(mdb);
-           return false;
-        }
-        fsr->FileSetId = str_to_int64(row[0]);
-        if (row[1] == NULL) {
-           fsr->cCreateTime[0] = 0;
-        } else {
-           bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
-        }
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return true;
+            sql_free_result(mdb);
+            db_unlock(mdb);
+            return false;
+         }
+         fsr->FileSetId = str_to_int64(row[0]);
+         if (row[1] == NULL) {
+            fsr->cCreateTime[0] = 0;
+         } else {
+            bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
+         }
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return true;
       }
       sql_free_result(mdb);
    }
@@ -612,7 +616,7 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       fsr->FileSetId = 0;
       stat = false;
@@ -630,19 +634,19 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 /*
  *  struct stat
  *  {
- *     dev_t         st_dev;       * device *
- *     ino_t         st_ino;       * inode *
- *     mode_t        st_mode;      * protection *
- *     nlink_t       st_nlink;     * number of hard links *
- *     uid_t         st_uid;       * user ID of owner *
- *     gid_t         st_gid;       * group ID of owner *
- *     dev_t         st_rdev;      * device type (if inode device) *
- *     off_t         st_size;      * total size, in bytes *
- *     unsigned long st_blksize;   * blocksize for filesystem I/O *
- *     unsigned long st_blocks;    * number of blocks allocated *
- *     time_t        st_atime;     * time of last access *
- *     time_t        st_mtime;     * time of last modification *
- *     time_t        st_ctime;     * time of last inode change *
+ *      dev_t         st_dev;       * device *
+ *      ino_t         st_ino;       * inode *
+ *      mode_t        st_mode;      * protection *
+ *      nlink_t       st_nlink;     * number of hard links *
+ *      uid_t         st_uid;       * user ID of owner *
+ *      gid_t         st_gid;       * group ID of owner *
+ *      dev_t         st_rdev;      * device type (if inode device) *
+ *      off_t         st_size;      * total size, in bytes *
+ *      unsigned long st_blksize;   * blocksize for filesystem I/O *
+ *      unsigned long st_blocks;    * number of blocks allocated *
+ *      time_t        st_atime;     * time of last access *
+ *      time_t        st_mtime;     * time of last modification *
+ *      time_t        st_ctime;     * time of last inode change *
  *  };
  */
 
@@ -667,7 +671,7 @@ int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
     * Make sure we have an acceptable attributes record.
     */
    if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
-        ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
+         ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
       Mmsg0(&mdb->errmsg, _("Attempt to put non-attributes into catalog\n"));
       Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       goto bail_out;
@@ -718,12 +722,12 @@ static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
    Mmsg(mdb->cmd,
         "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
         "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')",
-       ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
-       ar->attr);
+        ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
+        ar->attr);
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
-        mdb->cmd, sql_strerror(mdb));
+         mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
       ar->FileId = 0;
       stat = 0;
@@ -754,31 +758,31 @@ static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        char ed1[30];
+         char ed1[30];
          Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
-           edit_uint64(mdb->num_rows, ed1), mdb->path);
+            edit_uint64(mdb->num_rows, ed1), mdb->path);
          Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       /* Even if there are multiple paths, take the first one */
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           sql_free_result(mdb);
-           ar->PathId = 0;
-           ASSERT(ar->PathId);
-           return 0;
-        }
-        ar->PathId = str_to_int64(row[0]);
-        sql_free_result(mdb);
-        /* Cache path */
-        if (ar->PathId != mdb->cached_path_id) {
-           mdb->cached_path_id = ar->PathId;
-           mdb->cached_path_len = mdb->pnl;
-           pm_strcpy(mdb->cached_path, mdb->path);
-        }
-        ASSERT(ar->PathId);
-        return 1;
+            sql_free_result(mdb);
+            ar->PathId = 0;
+            ASSERT(ar->PathId);
+            return 0;
+         }
+         ar->PathId = str_to_int64(row[0]);
+         sql_free_result(mdb);
+         /* Cache path */
+         if (ar->PathId != mdb->cached_path_id) {
+            mdb->cached_path_id = ar->PathId;
+            mdb->cached_path_len = mdb->pnl;
+            pm_strcpy(mdb->cached_path, mdb->path);
+         }
+         ASSERT(ar->PathId);
+         return 1;
       }
       sql_free_result(mdb);
    }
@@ -787,7 +791,7 @@ static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
-        mdb->cmd, sql_strerror(mdb));
+         mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
       ar->PathId = 0;
       stat = 0;
@@ -818,22 +822,22 @@ static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        char ed1[30];
+         char ed1[30];
          Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
-           edit_uint64(mdb->num_rows, ed1), mdb->fname);
+            edit_uint64(mdb->num_rows, ed1), mdb->fname);
          Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
-               mdb->fname, sql_strerror(mdb));
+                mdb->fname, sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           ar->FilenameId = 0;
-        } else {
-           ar->FilenameId = str_to_int64(row[0]);
-        }
-        sql_free_result(mdb);
-        return ar->FilenameId > 0;
+            ar->FilenameId = 0;
+         } else {
+            ar->FilenameId = str_to_int64(row[0]);
+         }
+         sql_free_result(mdb);
+         return ar->FilenameId > 0;
       }
       sql_free_result(mdb);
    }
@@ -842,7 +846,7 @@ static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 
    if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
-           mdb->cmd, sql_strerror(mdb));
+            mdb->cmd, sql_strerror(mdb));
       Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
       ar->FilenameId = 0;
    } else {
index 78d0f1340093e4d4f2a8c5ef471a9d76ca6e7ed9..596adc6312ddcab6aa1ee0be116914fc4dc7298f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Bacula Catalog Database Get record interface routines
  *  Note, these routines generally get a record by id or
- *       by name.  If more logic is involved, the routine
- *       should be in find.c
+ *        by name.  If more logic is involved, the routine
+ *        should be in find.c
  *
  *    Kern Sibbald, March 2000
  *
@@ -33,7 +33,7 @@
 /* The following is necessary so that we do not include
  * the dummy external definition of DB.
  */
-#define __SQL_C                      /* indicate that this is sql.c */
+#define __SQL_C                       /* indicate that this is sql.c */
 
 #include "bacula.h"
 #include "cats.h"
@@ -65,7 +65,7 @@ extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
  * (with attributes) in the database.
  *
  *  Returns: 0 on failure
- *          1 on success with the File record in FILE_DBR
+ *           1 on success with the File record in FILE_DBR
  */
 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
 {
@@ -90,7 +90,7 @@ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr,
 /*
  * Get a File record
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  *
  *  DO NOT use Jmsg in this routine.
  *
@@ -133,21 +133,21 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
       Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows);
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
-           mdb->num_rows);
+            mdb->num_rows);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
-        } else {
-           fdbr->FileId = (FileId_t)str_to_int64(row[0]);
-           bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
-           bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG));
-           stat = 1;
-        }
+         } else {
+            fdbr->FileId = (FileId_t)str_to_int64(row[0]);
+            bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
+            bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG));
+            stat = 1;
+         }
       } else {
          Mmsg2(&mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"),
-           edit_int64(fdbr->PathId, ed1), 
-           edit_int64(fdbr->FilenameId, ed2));
+            edit_int64(fdbr->PathId, ed1), 
+            edit_int64(fdbr->FilenameId, ed2));
       }
       sql_free_result(mdb);
    } else {
@@ -159,7 +159,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
 
 /* Get Filename record
  * Returns: 0 on failure
- *         FilenameId on success
+ *          FilenameId on success
  *
  *   DO NOT use Jmsg in this routine (see notes for get_file_record)
  */
@@ -177,20 +177,20 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"),
-           edit_uint64(mdb->num_rows, ed1), mdb->fname);
+            edit_uint64(mdb->num_rows, ed1), mdb->fname);
          Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-        } else {
-           FilenameId = str_to_int64(row[0]);
-           if (FilenameId <= 0) {
+         } else {
+            FilenameId = str_to_int64(row[0]);
+            if (FilenameId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
-                 mdb->cmd, FilenameId);
-              FilenameId = 0;
-           }
-        }
+                  mdb->cmd, FilenameId);
+               FilenameId = 0;
+            }
+         }
       } else {
          Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname);
       }
@@ -203,7 +203,7 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb)
 
 /* Get path record
  * Returns: 0 on failure
- *         PathId on success
+ *          PathId on success
  *
  *   DO NOT use Jmsg in this routine (see notes for get_file_record)
  */
@@ -227,28 +227,28 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
-           edit_uint64(mdb->num_rows, ed1), mdb->path);
+            edit_uint64(mdb->num_rows, ed1), mdb->path);
          Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       /* Even if there are multiple paths, take the first one */
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-        } else {
-           PathId = str_to_int64(row[0]);
-           if (PathId <= 0) {
+         } else {
+            PathId = str_to_int64(row[0]);
+            if (PathId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %s\n"),
-                 mdb->cmd, edit_int64(PathId, ed1));
-              PathId = 0;
-           } else {
-              /* Cache path */
-              if (PathId != mdb->cached_path_id) {
-                 mdb->cached_path_id = PathId;
-                 mdb->cached_path_len = mdb->pnl;
-                 pm_strcpy(&mdb->cached_path, mdb->path);
-              }
-           }
-        }
+                  mdb->cmd, edit_int64(PathId, ed1));
+               PathId = 0;
+            } else {
+               /* Cache path */
+               if (PathId != mdb->cached_path_id) {
+                  mdb->cached_path_id = PathId;
+                  mdb->cached_path_len = mdb->pnl;
+                  pm_strcpy(&mdb->cached_path, mdb->path);
+               }
+            }
+         }
       } else {
          Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path);
       }
@@ -263,7 +263,7 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
 /*
  * Get Job record for given JobId or Job name
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 {
@@ -281,18 +281,18 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
 "Type,Level,ClientId "
 "FROM Job WHERE JobId=%s", 
-         edit_int64(jr->JobId, ed1));
+          edit_int64(jr->JobId, ed1));
     }
 
    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
       db_unlock(mdb);
-      return 0;                      /* failed */
+      return 0;                       /* failed */
    }
    if ((row = sql_fetch_row(mdb)) == NULL) {
       Mmsg1(&mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1));
       sql_free_result(mdb);
       db_unlock(mdb);
-      return 0;                      /* failed */
+      return 0;                       /* failed */
    }
 
    jr->VolSessionId = str_to_uint64(row[0]);
@@ -317,10 +317,10 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 /*
  * Find VolumeNames for a given JobId
  *  Returns: 0 on error or no Volumes found
- *          number of volumes on success
- *             Volumes are concatenated in VolumeNames
- *             separated by a vertical bar (|) in the order
- *             that they were written.
+ *           number of volumes on success
+ *              Volumes are concatenated in VolumeNames
+ *              separated by a vertical bar (|) in the order
+ *              that they were written.
  *
  *  Returns: number of volumes on success
  */
@@ -346,22 +346,22 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
          Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
-        stat = 0;
+         stat = 0;
       } else {
-        stat = mdb->num_rows;
-        for (i=0; i < stat; i++) {
-           if ((row = sql_fetch_row(mdb)) == NULL) {
+         stat = mdb->num_rows;
+         for (i=0; i < stat; i++) {
+            if ((row = sql_fetch_row(mdb)) == NULL) {
                Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
                Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-              stat = 0;
-              break;
-           } else {
-              if (*VolumeNames[0] != 0) {
+               stat = 0;
+               break;
+            } else {
+               if (*VolumeNames[0] != 0) {
                   pm_strcat(VolumeNames, "|");
-              }
-              pm_strcat(VolumeNames, row[0]);
-           }
-        }
+               }
+               pm_strcat(VolumeNames, row[0]);
+            }
+         }
       }
       sql_free_result(mdb);
    } else {
@@ -374,8 +374,8 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume
 /*
  * Find Volume parameters for a give JobId
  *  Returns: 0 on error or no Volumes found
- *          number of volumes on success
- *          List of Volumes and start/end file/blocks (malloced structure!)
+ *           number of volumes on success
+ *           List of Volumes and start/end file/blocks (malloced structure!)
  *
  *  Returns: number of volumes on success
  */
@@ -390,10 +390,10 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
    db_lock(mdb);
    Mmsg(mdb->cmd,
 "SELECT VolumeName,MediaType,FirstIndex,LastIndex,StartFile,"
-"JobMedia.EndFile,StartBlock,JobMedia.EndBlock"
+"JobMedia.EndFile,StartBlock,JobMedia.EndBlock,Copy,Stripe"
 " FROM JobMedia,Media WHERE JobMedia.JobId=%s"
 " AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId",
-       edit_int64(JobId, ed1));
+        edit_int64(JobId, ed1));
 
    Dmsg1(130, "VolNam=%s\n", mdb->cmd);
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
@@ -401,29 +401,31 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
          Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
-        stat = 0;
+         stat = 0;
       } else {
-        stat = mdb->num_rows;
-        if (stat > 0) {
-           *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS));
-        }
-        for (i=0; i < stat; i++) {
-           if ((row = sql_fetch_row(mdb)) == NULL) {
+         stat = mdb->num_rows;
+         if (stat > 0) {
+            *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS));
+         }
+         for (i=0; i < stat; i++) {
+            if ((row = sql_fetch_row(mdb)) == NULL) {
                Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
                Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-              stat = 0;
-              break;
-           } else {
-              bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
-              bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
-              Vols[i].FirstIndex = str_to_uint64(row[2]);
-              Vols[i].LastIndex = str_to_uint64(row[3]);
-              Vols[i].StartFile = str_to_uint64(row[4]);
-              Vols[i].EndFile = str_to_uint64(row[5]);
-              Vols[i].StartBlock = str_to_uint64(row[6]);
-              Vols[i].EndBlock = str_to_uint64(row[7]);
-           }
-        }
+               stat = 0;
+               break;
+            } else {
+               bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
+               bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
+               Vols[i].FirstIndex = str_to_uint64(row[2]);
+               Vols[i].LastIndex = str_to_uint64(row[3]);
+               Vols[i].StartFile = str_to_uint64(row[4]);
+               Vols[i].EndFile = str_to_uint64(row[5]);
+               Vols[i].StartBlock = str_to_uint64(row[6]);
+               Vols[i].EndBlock = str_to_uint64(row[7]);
+               Vols[i].Copy = str_to_uint64(row[8]);
+               Vols[i].Stripe = str_to_uint64(row[9]);
+            }
+         }
       }
       sql_free_result(mdb);
    }
@@ -437,7 +439,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
  * Get the number of pool records
  *
  * Returns: -1 on failure
- *         number on success
+ *          number on success
  */
 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
 {
@@ -455,7 +457,7 @@ int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
  *  The caller must free ids if non-NULL.
  *
  *  Returns 0: on failure
- *         1: on success
+ *          1: on success
  */
 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
 {
@@ -470,11 +472,11 @@ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       *num_ids = sql_num_rows(mdb);
       if (*num_ids > 0) {
-        id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
-        while ((row = sql_fetch_row(mdb)) != NULL) {
-           id[i++] = str_to_uint64(row[0]);
-        }
-        *ids = id;
+         id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
+         while ((row = sql_fetch_row(mdb)) != NULL) {
+            id[i++] = str_to_uint64(row[0]);
+         }
+         *ids = id;
       }
       sql_free_result(mdb);
       stat = 1;
@@ -492,7 +494,7 @@ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
  *  The caller must free ids if non-NULL.
  *
  *  Returns 0: on failure
- *         1: on success
+ *          1: on success
  */
 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
 {
@@ -507,11 +509,11 @@ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       *num_ids = sql_num_rows(mdb);
       if (*num_ids > 0) {
-        id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
-        while ((row = sql_fetch_row(mdb)) != NULL) {
-           id[i++] = str_to_uint64(row[0]);
-        }
-        *ids = id;
+         id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
+         while ((row = sql_fetch_row(mdb)) != NULL) {
+            id[i++] = str_to_uint64(row[0]);
+         }
+         *ids = id;
       }
       sql_free_result(mdb);
       stat = 1;
@@ -531,7 +533,7 @@ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
  *  otherwise, we search on the PoolName
  *
  * Returns: false on failure
- *         true on success
+ *          true on success
  */
 bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
 {
@@ -540,51 +542,51 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
    char ed1[50];
 
    db_lock(mdb);
-   if (pdbr->PoolId != 0) {              /* find by id */
+   if (pdbr->PoolId != 0) {               /* find by id */
       Mmsg(mdb->cmd,
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,"
 "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "MaxVolBytes,PoolType,LabelType,LabelFormat FROM Pool WHERE Pool.PoolId=%s", 
-        edit_int64(pdbr->PoolId, ed1));
-   } else {                          /* find by name */
+         edit_int64(pdbr->PoolId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd,
 "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume,"
 "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "MaxVolBytes,PoolType,LabelType,LabelFormat FROM Pool WHERE Pool.Name='%s'", 
-        pdbr->Name);
+         pdbr->Name);
    }
 
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        char ed1[30];
+         char ed1[30];
          Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"),
-           edit_uint64(mdb->num_rows, ed1));
+            edit_uint64(mdb->num_rows, ed1));
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-        } else {
-           pdbr->PoolId = str_to_int64(row[0]);
+         } else {
+            pdbr->PoolId = str_to_int64(row[0]);
             bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name));
-           pdbr->NumVols = str_to_int64(row[2]);
-           pdbr->MaxVols = str_to_int64(row[3]);
-           pdbr->UseOnce = str_to_int64(row[4]);
-           pdbr->UseCatalog = str_to_int64(row[5]);
-           pdbr->AcceptAnyVolume = str_to_int64(row[6]);
-           pdbr->AutoPrune = str_to_int64(row[7]);
-           pdbr->Recycle = str_to_int64(row[8]);
-           pdbr->VolRetention = str_to_int64(row[9]);
-           pdbr->VolUseDuration = str_to_int64(row[10]);
-           pdbr->MaxVolJobs = str_to_int64(row[11]);
-           pdbr->MaxVolFiles = str_to_int64(row[12]);
-           pdbr->MaxVolBytes = str_to_uint64(row[13]);
+            pdbr->NumVols = str_to_int64(row[2]);
+            pdbr->MaxVols = str_to_int64(row[3]);
+            pdbr->UseOnce = str_to_int64(row[4]);
+            pdbr->UseCatalog = str_to_int64(row[5]);
+            pdbr->AcceptAnyVolume = str_to_int64(row[6]);
+            pdbr->AutoPrune = str_to_int64(row[7]);
+            pdbr->Recycle = str_to_int64(row[8]);
+            pdbr->VolRetention = str_to_int64(row[9]);
+            pdbr->VolUseDuration = str_to_int64(row[10]);
+            pdbr->MaxVolJobs = str_to_int64(row[11]);
+            pdbr->MaxVolFiles = str_to_int64(row[12]);
+            pdbr->MaxVolBytes = str_to_uint64(row[13]);
             bstrncpy(pdbr->PoolType, row[14]!=NULL?row[14]:"", sizeof(pdbr->PoolType));
-           pdbr->LabelType = str_to_int64(row[15]);
+            pdbr->LabelType = str_to_int64(row[15]);
             bstrncpy(pdbr->LabelFormat, row[16]!=NULL?row[16]:"", sizeof(pdbr->LabelFormat));
-           ok = true;
-        }
+            ok = true;
+         }
       } else {
          Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n"));
       }
@@ -605,7 +607,7 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr)
  *  otherwise, we search on the Client Name
  *
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
 {
@@ -614,12 +616,12 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
    char ed1[50];
 
    db_lock(mdb);
-   if (cdbr->ClientId != 0) {              /* find by id */
+   if (cdbr->ClientId != 0) {               /* find by id */
       Mmsg(mdb->cmd,
 "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention "
 "FROM Client WHERE Client.ClientId=%s", 
-       edit_int64(cdbr->ClientId, ed1));
-   } else {                          /* find by name */
+        edit_int64(cdbr->ClientId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd,
 "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention "
 "FROM Client WHERE Client.Name='%s'", cdbr->Name);
@@ -629,21 +631,21 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"),
-           edit_uint64(mdb->num_rows, ed1));
+            edit_uint64(mdb->num_rows, ed1));
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-        } else {
-           cdbr->ClientId = str_to_int64(row[0]);
+         } else {
+            cdbr->ClientId = str_to_int64(row[0]);
             bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name));
             bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname));
-           cdbr->AutoPrune = str_to_int64(row[3]);
-           cdbr->FileRetention = str_to_int64(row[4]);
-           cdbr->JobRetention = str_to_int64(row[5]);
-           stat = 1;
-        }
+            cdbr->AutoPrune = str_to_int64(row[3]);
+            cdbr->FileRetention = str_to_int64(row[4]);
+            cdbr->JobRetention = str_to_int64(row[5]);
+            stat = 1;
+         }
       } else {
          Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n"));
       }
@@ -659,7 +661,7 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr)
  * Get Counter Record
  *
  * Returns: 0 on failure
- *         1 on success
+ *          1 on success
  */
 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
 {
@@ -678,24 +680,24 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-           sql_free_result(mdb);
-           db_unlock(mdb);
-           return 0;
-        }
-        cr->MinValue = str_to_int64(row[0]);
-        cr->MaxValue = str_to_int64(row[1]);
-        cr->CurrentValue = str_to_int64(row[2]);
-        if (row[3]) {
-           bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter));
-        } else {
-           cr->WrapCounter[0] = 0;
-        }
-        sql_free_result(mdb);
-        db_unlock(mdb);
-        return 1;
+            sql_free_result(mdb);
+            db_unlock(mdb);
+            return 0;
+         }
+         cr->MinValue = str_to_int64(row[0]);
+         cr->MaxValue = str_to_int64(row[1]);
+         cr->CurrentValue = str_to_int64(row[2]);
+         if (row[3]) {
+            bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter));
+         } else {
+            cr->WrapCounter[0] = 0;
+         }
+         sql_free_result(mdb);
+         db_unlock(mdb);
+         return 1;
       }
       sql_free_result(mdb);
    } else {
@@ -711,7 +713,7 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
  *  otherwise, we search on the name
  *
  * Returns: 0 on failure
- *         id on success
+ *          id on success
  */
 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 {
@@ -720,12 +722,12 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    char ed1[50];
 
    db_lock(mdb);
-   if (fsr->FileSetId != 0) {              /* find by id */
+   if (fsr->FileSetId != 0) {               /* find by id */
       Mmsg(mdb->cmd,
            "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet "
            "WHERE FileSetId=%s", 
-          edit_int64(fsr->FileSetId, ed1));
-   } else {                          /* find by name */
+           edit_int64(fsr->FileSetId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd,
            "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
            "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet);
@@ -734,19 +736,19 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
-        char ed1[30];
+         char ed1[30];
          Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"),
-           edit_uint64(mdb->num_rows, ed1));
-        sql_data_seek(mdb, mdb->num_rows-1);
+            edit_uint64(mdb->num_rows, ed1));
+         sql_data_seek(mdb, mdb->num_rows-1);
       }
       if ((row = sql_fetch_row(mdb)) == NULL) {
          Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet);
       } else {
-        fsr->FileSetId = str_to_int64(row[0]);
+         fsr->FileSetId = str_to_int64(row[0]);
          bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet));
          bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5));
          bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime));
-        stat = fsr->FileSetId;
+         stat = fsr->FileSetId;
       }
       sql_free_result(mdb);
    } else {
@@ -761,7 +763,7 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
  * Get the number of Media records
  *
  * Returns: -1 on failure
- *         number on success
+ *          number on success
  */
 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
 {
@@ -781,7 +783,7 @@ int db_get_num_media_records(JCR *jcr, B_DB *mdb)
  *  The caller must free ids if non-NULL.
  *
  *  Returns 0: on failure
- *         1: on success
+ *          1: on success
  */
 int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
 {
@@ -798,11 +800,11 @@ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       *num_ids = sql_num_rows(mdb);
       if (*num_ids > 0) {
-        id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
-        while ((row = sql_fetch_row(mdb)) != NULL) {
-           id[i++] = str_to_uint64(row[0]);
-        }
-        *ids = id;
+         id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t));
+         while ((row = sql_fetch_row(mdb)) != NULL) {
+            id[i++] = str_to_uint64(row[0]);
+         }
+         *ids = id;
       }
       sql_free_result(mdb);
       stat = 1;
@@ -819,7 +821,7 @@ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_
 /* Get Media Record
  *
  * Returns: 0 on failure
- *         id on success
+ *          id on success
  */
 int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 {
@@ -834,15 +836,15 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       db_unlock(mdb);
       return 1;
    }
-   if (mr->MediaId != 0) {              /* find by id */
+   if (mr->MediaId != 0) {               /* find by id */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
          "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
          "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger,"
          "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId "
          "FROM Media WHERE MediaId=%s", 
-        edit_int64(mr->MediaId, ed1));
-   } else {                          /* find by name */
+         edit_int64(mr->MediaId, ed1));
+   } else {                           /* find by name */
       Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
          "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
          "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs,"
@@ -856,65 +858,65 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"),
-           edit_uint64(mdb->num_rows, ed1));
+            edit_uint64(mdb->num_rows, ed1));
          Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
-        if ((row = sql_fetch_row(mdb)) == NULL) {
+         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-        } else {
-           /* return values */
-           mr->MediaId = str_to_int64(row[0]);
+         } else {
+            /* return values */
+            mr->MediaId = str_to_int64(row[0]);
             bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName));
-           mr->VolJobs = str_to_int64(row[2]);
-           mr->VolFiles = str_to_int64(row[3]);
-           mr->VolBlocks = str_to_int64(row[4]);
-           mr->VolBytes = str_to_uint64(row[5]);
-           mr->VolMounts = str_to_int64(row[6]);
-           mr->VolErrors = str_to_int64(row[7]);
-           mr->VolWrites = str_to_int64(row[8]);
-           mr->MaxVolBytes = str_to_uint64(row[9]);
-           mr->VolCapacityBytes = str_to_uint64(row[10]);
+            mr->VolJobs = str_to_int64(row[2]);
+            mr->VolFiles = str_to_int64(row[3]);
+            mr->VolBlocks = str_to_int64(row[4]);
+            mr->VolBytes = str_to_uint64(row[5]);
+            mr->VolMounts = str_to_int64(row[6]);
+            mr->VolErrors = str_to_int64(row[7]);
+            mr->VolWrites = str_to_int64(row[8]);
+            mr->MaxVolBytes = str_to_uint64(row[9]);
+            mr->VolCapacityBytes = str_to_uint64(row[10]);
             bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType));
             bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus));
-           mr->PoolId = str_to_int64(row[13]);
-           mr->VolRetention = str_to_uint64(row[14]);
-           mr->VolUseDuration = str_to_uint64(row[15]);
-           mr->MaxVolJobs = str_to_int64(row[16]);
-           mr->MaxVolFiles = str_to_int64(row[17]);
-           mr->Recycle = str_to_int64(row[18]);
-           mr->Slot = str_to_int64(row[19]);
+            mr->PoolId = str_to_int64(row[13]);
+            mr->VolRetention = str_to_uint64(row[14]);
+            mr->VolUseDuration = str_to_uint64(row[15]);
+            mr->MaxVolJobs = str_to_int64(row[16]);
+            mr->MaxVolFiles = str_to_int64(row[17]);
+            mr->Recycle = str_to_int64(row[18]);
+            mr->Slot = str_to_int64(row[19]);
             bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten));
-           mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten);
+            mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten);
             bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten));
-           mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten);
-           mr->InChanger = str_to_uint64(row[22]);
-           mr->EndFile = str_to_uint64(row[23]);
-           mr->EndBlock = str_to_uint64(row[24]);
-           mr->VolParts = str_to_int64(row[25]);
-           mr->LabelType = str_to_int64(row[26]);
+            mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten);
+            mr->InChanger = str_to_uint64(row[22]);
+            mr->EndFile = str_to_uint64(row[23]);
+            mr->EndBlock = str_to_uint64(row[24]);
+            mr->VolParts = str_to_int64(row[25]);
+            mr->LabelType = str_to_int64(row[26]);
             bstrncpy(mr->cLabelDate, row[27]!=NULL?row[27]:"", sizeof(mr->cLabelDate));
-           mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate);
-           mr->StorageId = str_to_int64(row[28]);
-           stat = mr->MediaId;
-        }
+            mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate);
+            mr->StorageId = str_to_int64(row[28]);
+            stat = mr->MediaId;
+         }
       } else {
-        if (mr->MediaId != 0) {
+         if (mr->MediaId != 0) {
             Mmsg1(&mdb->errmsg, _("Media record MediaId=%s not found.\n"), 
-              edit_int64(mr->MediaId, ed1));
-        } else {
+               edit_int64(mr->MediaId, ed1));
+         } else {
             Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"),
-                 mr->VolumeName);
-        }
+                  mr->VolumeName);
+         }
       }
       sql_free_result(mdb);
    } else {
       if (mr->MediaId != 0) {
          Mmsg(mdb->errmsg, _("Media record for MediaId=%u not found in Catalog.\n"),
-           mr->MediaId);
+            mr->MediaId);
        } else {
          Mmsg(mdb->errmsg, _("Media record for Vol=%s not found in Catalog.\n"),
-           mr->VolumeName);
+            mr->VolumeName);
    }   }
    db_unlock(mdb);
    return stat;
index c97c5a4ad6a200194a8e5bd79f9cf1eae0f49d6a..b512b1c6559ab1a079aa882c3b3f2a1e31bbac4f 100644 (file)
@@ -29,7 +29,7 @@
 /* The following is necessary so that we do not include
  * the dummy external definition of DB.
  */
-#define __SQL_C                      /* indicate that this is sql.c */
+#define __SQL_C                       /* indicate that this is sql.c */
 
 #include "bacula.h"
 #include "cats.h"
@@ -52,13 +52,13 @@ extern int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_
  * Submit general SQL query
  */
 int db_list_sql_query(JCR *jcr, B_DB *mdb, char *query, DB_LIST_HANDLER *sendit,
-                     void *ctx, int verbose, e_list_type type)
+                      void *ctx, int verbose, e_list_type type)
 {
    db_lock(mdb);
    if (sql_query(mdb, query) != 0) {
       Mmsg(mdb->errmsg, _("Query failed: %s\n"), sql_strerror(mdb));
       if (verbose) {
-        sendit(ctx, mdb->errmsg);
+         sendit(ctx, mdb->errmsg);
       }
       db_unlock(mdb);
       return 0;
@@ -131,7 +131,7 @@ db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx,
  */
 void
 db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
-                     DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
+                      DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
 {
    char ed1[50];
    db_lock(mdb);
@@ -152,7 +152,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
             "EndFile,EndBlock,VolParts,LabelType,StorageId"
             " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", 
-           edit_int64(mdbr->PoolId, ed1));
+            edit_int64(mdbr->PoolId, ed1));
       }
    } else {
       if (mdbr->VolumeName[0] != 0) {
@@ -163,7 +163,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,"
             "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
             "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", 
-           edit_int64(mdbr->PoolId, ed1));
+            edit_int64(mdbr->PoolId, ed1));
       }
    }
 
@@ -179,26 +179,26 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
 }
 
 void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
-                             DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
+                              DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
 {
    char ed1[50];
    db_lock(mdb);
    if (type == VERT_LIST) {
-      if (JobId > 0) {                  /* do by JobId */
+      if (JobId > 0) {                   /* do by JobId */
          Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
             "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
-            "JobMedia.EndBlock "
+            "JobMedia.EndBlock,Copy,Stripe "
             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
             "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
       } else {
          Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
             "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
-            "JobMedia.EndBlock "
+            "JobMedia.EndBlock,Copy,Stripe "
             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
       }
 
    } else {
-      if (JobId > 0) {                  /* do by JobId */
+      if (JobId > 0) {                   /* do by JobId */
          Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
             "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
@@ -228,13 +228,13 @@ void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
  */
 void
 db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
-                   void *ctx, e_list_type type)
+                    void *ctx, e_list_type type)
 {
    char ed1[50];
    db_lock(mdb);
    if (type == VERT_LIST) {
       if (jr->JobId == 0 && jr->Job[0] == 0) {
-        Mmsg(mdb->cmd,
+         Mmsg(mdb->cmd,
             "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level,"
             "Job.ClientId,Client.Name,JobStatus,SchedTime,"
             "StartTime,EndTime,JobTDate,"
@@ -243,8 +243,8 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
             "FROM Job,Client,Pool,FileSet WHERE "
             "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId "
             "AND FileSet.FileSetId=Job.FileSetId  ORDER BY StartTime");
-      } else {                          /* single record */
-        Mmsg(mdb->cmd,
+      } else {                           /* single record */
+         Mmsg(mdb->cmd,
             "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level,"
             "Job.ClientId,Client.Name,JobStatus,SchedTime,"
             "StartTime,EndTime,JobTDate,"
@@ -253,17 +253,17 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
             "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%s AND "
             "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId "
             "AND FileSet.FileSetId=Job.FileSetId", 
-           edit_int64(jr->JobId, ed1));
+            edit_int64(jr->JobId, ed1));
       }
    } else {
       if (jr->JobId == 0 && jr->Job[0] == 0) {
-        Mmsg(mdb->cmd,
+         Mmsg(mdb->cmd,
            "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus "
            "FROM Job ORDER BY StartTime");
-      } else {                          /* single record */
+      } else {                           /* single record */
          Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,"
             "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%s", 
-           edit_int64(jr->JobId, ed1));
+            edit_int64(jr->JobId, ed1));
       }
    }
    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
index e3f0779239449d715c0d87fca65d5e9731540056..6e098bddaf67ad11e5d69ff5825afef2e4bdadca 100644 (file)
@@ -29,7 +29,7 @@
 /* The following is necessary so that we do not include
  * the dummy external definition of DB.
  */
-#define __SQL_C                      /* indicate that this is sql.c */
+#define __SQL_C                       /* indicate that this is sql.c */
 
 #include "bacula.h"
 #include "cats.h"
@@ -56,7 +56,7 @@ extern int UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update
 /* Update the attributes record by adding the MD5 signature */
 int
 db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG,
-                         int type)
+                          int type)
 {
    int stat;
    char ed1[50];
@@ -89,7 +89,7 @@ int db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId)
  * Update the Job record at start of Job
  *
  *  Returns: false on failure
- *          true  on success
+ *           true  on success
  */
 bool
 db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
@@ -124,7 +124,6 @@ db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 /*
  * Given an incoming integer, set the string buffer to either NULL or the value
  *
- *
  */
 static void edit_num_or_null(char *s, size_t n, uint64_t id) {
    char ed1[50];
@@ -136,7 +135,7 @@ static void edit_num_or_null(char *s, size_t n, uint64_t id) {
  * Update the Job record at end of Job
  *
  *  Returns: 0 on failure
- *          1 on success
+ *           1 on success
  */
 int
 db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
@@ -147,13 +146,13 @@ db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
    int stat;
    char ed1[30], ed2[30], ed3[50];
    btime_t JobTDate;
-   char PoolId   [50];
+   char PoolId    [50];
    char FileSetId [50];
    char ClientId  [50];
 
 
    /* some values are set to zero, which translates to NULL in SQL */
-   edit_num_or_null(PoolId,    sizeof(PoolId),   jr->PoolId);
+   edit_num_or_null(PoolId,    sizeof(PoolId),    jr->PoolId);
    edit_num_or_null(FileSetId, sizeof(FileSetId), jr->FileSetId);
    edit_num_or_null(ClientId,  sizeof(ClientId),  jr->ClientId);
 
@@ -181,7 +180,7 @@ db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 /*
  * Update Client record
  *   Returns: 0 on failure
- *           1 on success
+ *            1 on success
  */
 int
 db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
@@ -214,7 +213,7 @@ db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
 /*
  * Update Counters record
  *   Returns: 0 on failure
- *           1 on success
+ *            1 on success
  */
 int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
 {
@@ -239,6 +238,9 @@ db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
    char ed1[50], ed2[50], ed3[50], ed4[50];
 
    db_lock(mdb);
+   Mmsg(mdb->cmd, "SELECT count(*) from Pool");
+   pr->NumVols = get_sql_record_max(jcr, mdb);
+
    Mmsg(mdb->cmd,
 "UPDATE Pool SET NumVols=%u,MaxVols=%u,UseOnce=%d,UseCatalog=%d,"
 "AcceptAnyVolume=%d,VolRetention='%s',VolUseDuration='%s',"
@@ -278,7 +280,7 @@ db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
  * Update the Media Record at end of Session
  *
  * Returns: 0 on failure
- *         numrows on success
+ *          numrows on success
  */
 int
 db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
@@ -307,7 +309,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    if (mr->set_label_date) {
       ttime = mr->LabelDate;
       if (ttime == 0) {
-        ttime = time(NULL);
+         ttime = time(NULL);
       }
       localtime_r(&ttime, &tm);
       strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
@@ -331,16 +333,16 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
         "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d,"
         "LabelType=%d,StorageId=%s"
         " WHERE VolumeName='%s'",
-       mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
-       mr->VolMounts, mr->VolErrors, mr->VolWrites,
-       edit_uint64(mr->MaxVolBytes, ed2),
-       mr->VolStatus, mr->Slot, mr->InChanger,
-       edit_uint64(mr->VolReadTime, ed3),
-       edit_uint64(mr->VolWriteTime, ed4),
-       mr->VolParts,
-       mr->LabelType,
-       edit_int64(mr->StorageId, ed5),
-       mr->VolumeName);
+        mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
+        mr->VolMounts, mr->VolErrors, mr->VolWrites,
+        edit_uint64(mr->MaxVolBytes, ed2),
+        mr->VolStatus, mr->Slot, mr->InChanger,
+        edit_uint64(mr->VolReadTime, ed3),
+        edit_uint64(mr->VolWriteTime, ed4),
+        mr->VolParts,
+        mr->LabelType,
+        edit_int64(mr->StorageId, ed5),
+        mr->VolumeName);
 
    Dmsg1(400, "%s\n", mdb->cmd);
 
@@ -357,7 +359,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
  * Update the Media Record Default values from Pool
  *
  * Returns: 0 on failure
- *         numrows on success
+ *          numrows on success
  */
 int
 db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
@@ -372,21 +374,21 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
            "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
            "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
            " WHERE VolumeName='%s'",
-          mr->Recycle,edit_uint64(mr->VolRetention, ed1),
-          edit_uint64(mr->VolUseDuration, ed2),
-          mr->MaxVolJobs, mr->MaxVolFiles,
-          edit_uint64(mr->VolBytes, ed3),
-          mr->VolumeName);
+           mr->Recycle,edit_uint64(mr->VolRetention, ed1),
+           edit_uint64(mr->VolUseDuration, ed2),
+           mr->MaxVolJobs, mr->MaxVolFiles,
+           edit_uint64(mr->VolBytes, ed3),
+           mr->VolumeName);
    } else {
       Mmsg(mdb->cmd, "UPDATE Media SET "
            "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
            "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
            " WHERE PoolId=%s",
-          mr->Recycle,edit_uint64(mr->VolRetention, ed1),
-          edit_uint64(mr->VolUseDuration, ed2),
-          mr->MaxVolJobs, mr->MaxVolFiles,
-          edit_uint64(mr->VolBytes, ed3),
-          edit_int64(mr->PoolId, ed4));
+           mr->Recycle,edit_uint64(mr->VolRetention, ed1),
+           edit_uint64(mr->VolUseDuration, ed2),
+           mr->MaxVolJobs, mr->MaxVolFiles,
+           edit_uint64(mr->VolBytes, ed3),
+           edit_int64(mr->PoolId, ed4));
    }
 
    Dmsg1(400, "%s\n", mdb->cmd);
@@ -411,8 +413,8 @@ db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    if (mr->InChanger != 0 && mr->Slot != 0) {
       Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE "
            "Slot=%d AND StorageId=%s AND MediaId!=%s",
-           mr->Slot, 
-           edit_int64(mr->StorageId, ed1), edit_int64(mr->MediaId, ed2));
+            mr->Slot, 
+            edit_int64(mr->StorageId, ed1), edit_int64(mr->MediaId, ed2));
       Dmsg1(400, "%s\n", mdb->cmd);
       UPDATE_DB(jcr, mdb, mdb->cmd);
    }
index f86c0484efa58ef3eca50edaa7e83e9d263eebb1..9a0322d73f5ef8658c74b52a97113806c1d76c1c 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Shell script to update MySQL tables from version 1.36 to 1.37.3
+# Shell script to update MySQL tables from version 1.36 to 1.37.12
 #
 echo " "
 echo "This script will update a Bacula MySQL database from version 8 to 9"
@@ -22,6 +22,10 @@ ALTER TABLE Pool  ADD COLUMN MigrationHighBytes BIGINT UNSIGNED DEFAULT 0;
 ALTER TABLE Pool  ADD COLUMN MigrationLowBytes BIGINT UNSIGNED DEFAULT 0;
 ALTER TABLE Pool  ADD COLUMN MigrationTime BIGINT UNSIGNED DEFAULT 0;
 
+ALTER TABLE JobMedia ADD COLUMN Copy INTEGER UNSIGNED NOT NULL DEFAULT 0;
+ALTER TABLE JobMedia ADD COLUMN Stripe INTEGER UNSIGNED NOT NULL DEFAULT 0;
+
+
 CREATE TABLE MediaType (
    MediaTypeId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    MediaType VARCHAR(128) NOT NULL,
@@ -55,6 +59,9 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
+DELETE FROM Version;
+INSERT INTO Version (VersionId) VALUES (9);
+
 END-OF-DATA
 then
    echo "Update of Bacula MySQL tables succeeded."
index 109700161a7d7978c88afc18f177ebda83c662dc..6f24920f233e81b3ba13a5d7e589e6c8f72347ac 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Shell script to update PostgreSQL tables from version 1.36 to 1.37.3
+# Shell script to update PostgreSQL tables from version 1.36 to 1.37.12
 #
 echo " "
 echo "This script will update a Bacula PostgreSQL database from version 8 to 9"
@@ -30,6 +30,12 @@ ALTER TABLE pool ADD COLUMN MigrationTime      BIGINT;
 ALTER TABLE pool SET MigrationTime=0;
 
 
+ALTER TABLE jobmedia ADD COLUMN Copy integer;
+UPDATE jobmedia SET Copy=0;
+ALTER TABLE jobmedia ADD COLUMN Stripe integer;
+UPDATE jobmedia SET Stripe=0;
+
+
 ALTER TABLE media ADD COLUMN volparts integer;
 UPDATE media SET volparts=0;
 ALTER TABLE media ALTER COLUMN volparts SET NOT NULL;
@@ -67,6 +73,9 @@ CREATE TABLE Storage (
    PRIMARY KEY(StorageId)
    );
 
+DELETE FROM version;
+INSERT INTO version (versionId) VALUES (9);
+
 vacuum;
 
 END-OF-DATA
index b4e4c355135118032fb5e1c412ff0532c3cb9712..2fcaec69791a18cbca7c46d873cf594c36db63ba 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# shell script to update SQLite from version 1.36 to 1.37.3
+# shell script to update SQLite from version 1.36 to 1.37.12
 #
 echo " "
 echo "This script will update a Bacula SQLite database from version 8 to 9"
@@ -20,6 +20,7 @@ CREATE TEMPORARY TABLE Media_backup (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
    LabelDate DATETIME DEFAULT 0,
@@ -101,7 +102,7 @@ CREATE TABLE Media (
 
 INSERT INTO Media (
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, FirstWritten, LastWritten,
+   MediaType, LabelType, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
    VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
@@ -113,6 +114,58 @@ INSERT INTO Media (
    SELECT * FROM Media_backup;
 
 DROP TABLE Media_backup;
+CREATE INDEX inx8 ON Media (PoolId);
+
+
+CREATE TEMPORARY TABLE JobMedia_backup (
+   JobMediaId INTEGER,
+   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
+   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
+   FirstIndex INTEGER UNSIGNED NOT NULL,
+   LastIndex INTEGER UNSIGNED NOT NULL,
+   StartFile INTEGER UNSIGNED DEFAULT 0,
+   EndFile INTEGER UNSIGNED DEFAULT 0,
+   StartBlock INTEGER UNSIGNED DEFAULT 0,
+   EndBlock INTEGER UNSIGNED DEFAULT 0,
+   VolIndex INTEGER UNSIGNED DEFAULT 0,
+   Copy     INTEGER UNSIGNED DEFAULT 0,
+   Stripe   INTEGER UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobMediaId) 
+   );
+
+INSERT INTO JobMedia_backup SELECT
+   JobMediaId, JobId, MediaId,
+   FirstIndex, LastIndex, StartFile,
+   EndFile, StartBlock, EndBlock,
+   VolIndex, 0, 0 
+   FROM JobMedia;
+
+DROP TABLE JobMedia;
+
+CREATE TABLE JobMedia (
+   JobMediaId INTEGER,
+   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
+   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
+   FirstIndex INTEGER UNSIGNED NOT NULL,
+   LastIndex INTEGER UNSIGNED NOT NULL,
+   StartFile INTEGER UNSIGNED DEFAULT 0,
+   EndFile INTEGER UNSIGNED DEFAULT 0,
+   StartBlock INTEGER UNSIGNED DEFAULT 0,
+   EndBlock INTEGER UNSIGNED DEFAULT 0,
+   VolIndex INTEGER UNSIGNED DEFAULT 0,
+   Copy     INTEGER UNSIGNED DEFAULT 0,
+   Stripe   INTEGER UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobMediaId) 
+   );
+
+INSERT INTO JobMedia (
+   JobMediaId, JobId, MediaId,
+   FirstIndex, LastIndex, StartFile,
+   EndFile, StartBlock, EndBlock,
+   VolIndex, Copy, Stripe)
+   SELECT * FROM JobMedia_backup;
+
+DROP TABLE JobMedia_backup;
 
 CREATE TEMPORARY TABLE Pool_backup (
    PoolId INTEGER,
@@ -198,7 +251,7 @@ INSERT INTO Pool (
 DROP TABLE Pool_backup;
 
 CREATE TABLE MediaType (
-   MediaTypeId INTERGER,
+   MediaTypeId INTEGER,
    MediaType VARCHAR(128) NOT NULL,
    ReadOnly TINYINT DEFAULT 0,
    PRIMARY KEY(MediaTypeId)
@@ -230,6 +283,10 @@ CREATE TABLE Device (
    PRIMARY KEY(DeviceId)
    );
 
+
+DELETE FROM Version;
+INSERT INTO Version (VersionId) VALUES (9);
+
 COMMIT;
 
 END-OF-DATA
index b409ee050def3e84b9852ea0a0844f2e35bd30b9..2fcaec69791a18cbca7c46d873cf594c36db63ba 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# shell script to update SQLite from version 1.36 to 1.37.3
+# shell script to update SQLite from version 1.36 to 1.37.12
 #
 echo " "
 echo "This script will update a Bacula SQLite database from version 8 to 9"
@@ -20,6 +20,7 @@ CREATE TEMPORARY TABLE Media_backup (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
    LabelDate DATETIME DEFAULT 0,
@@ -101,7 +102,7 @@ CREATE TABLE Media (
 
 INSERT INTO Media (
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, FirstWritten, LastWritten,
+   MediaType, LabelType, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
    VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
@@ -113,6 +114,58 @@ INSERT INTO Media (
    SELECT * FROM Media_backup;
 
 DROP TABLE Media_backup;
+CREATE INDEX inx8 ON Media (PoolId);
+
+
+CREATE TEMPORARY TABLE JobMedia_backup (
+   JobMediaId INTEGER,
+   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
+   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
+   FirstIndex INTEGER UNSIGNED NOT NULL,
+   LastIndex INTEGER UNSIGNED NOT NULL,
+   StartFile INTEGER UNSIGNED DEFAULT 0,
+   EndFile INTEGER UNSIGNED DEFAULT 0,
+   StartBlock INTEGER UNSIGNED DEFAULT 0,
+   EndBlock INTEGER UNSIGNED DEFAULT 0,
+   VolIndex INTEGER UNSIGNED DEFAULT 0,
+   Copy     INTEGER UNSIGNED DEFAULT 0,
+   Stripe   INTEGER UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobMediaId) 
+   );
+
+INSERT INTO JobMedia_backup SELECT
+   JobMediaId, JobId, MediaId,
+   FirstIndex, LastIndex, StartFile,
+   EndFile, StartBlock, EndBlock,
+   VolIndex, 0, 0 
+   FROM JobMedia;
+
+DROP TABLE JobMedia;
+
+CREATE TABLE JobMedia (
+   JobMediaId INTEGER,
+   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
+   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
+   FirstIndex INTEGER UNSIGNED NOT NULL,
+   LastIndex INTEGER UNSIGNED NOT NULL,
+   StartFile INTEGER UNSIGNED DEFAULT 0,
+   EndFile INTEGER UNSIGNED DEFAULT 0,
+   StartBlock INTEGER UNSIGNED DEFAULT 0,
+   EndBlock INTEGER UNSIGNED DEFAULT 0,
+   VolIndex INTEGER UNSIGNED DEFAULT 0,
+   Copy     INTEGER UNSIGNED DEFAULT 0,
+   Stripe   INTEGER UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobMediaId) 
+   );
+
+INSERT INTO JobMedia (
+   JobMediaId, JobId, MediaId,
+   FirstIndex, LastIndex, StartFile,
+   EndFile, StartBlock, EndBlock,
+   VolIndex, Copy, Stripe)
+   SELECT * FROM JobMedia_backup;
+
+DROP TABLE JobMedia_backup;
 
 CREATE TEMPORARY TABLE Pool_backup (
    PoolId INTEGER,
@@ -231,6 +284,9 @@ CREATE TABLE Device (
    );
 
 
+DELETE FROM Version;
+INSERT INTO Version (VersionId) VALUES (9);
+
 COMMIT;
 
 END-OF-DATA
index 17ff0a194657b8cf3e69e9dfdf64b1abb266e75f..945a34d16518c7739240f7656f645018fe5faba3 100644 (file)
@@ -8,7 +8,7 @@
  *    This routine runs as a thread and must be thread reentrant.
  *
  *  Basic tasks done here:
- *     Handle Catalog services.
+ *      Handle Catalog services.
  *
  *   Version $Id$
  */
@@ -52,7 +52,7 @@ static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s"
 
 static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia "
    " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u "
-   " StartBlock=%u EndBlock=%u\n";
+   " StartBlock=%u EndBlock=%u Copy=%d Strip=%d\n";
 
 
 /* Responses  sent to Storage daemon */
@@ -124,14 +124,14 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
       ok = db_get_pool_record(jcr, jcr->db, &pr);
       if (ok) {
-        mr.PoolId = pr.PoolId;
-        ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
+         mr.PoolId = pr.PoolId;
+         ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/);
       }
       /*
        * Send Find Media response to Storage daemon
        */
       if (ok) {
-        send_volume_info_to_storage_daemon(jcr, bs, &mr);
+         send_volume_info_to_storage_daemon(jcr, bs, &mr);
       } else {
          bnet_fsend(bs, "1901 No Media.\n");
          Dmsg0(500, "1901 No Media.\n");
@@ -147,51 +147,51 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
        */
       unbash_spaces(mr.VolumeName);
       if (db_get_media_record(jcr, jcr->db, &mr)) {
-        const char *reason = NULL;           /* detailed reason for rejection */
-        /*
-         * If we are reading, accept any volume (reason == NULL)
-         * If we are writing, check if the Volume is valid
-         *   for this job, and do a recycle if necessary
-         */
-        if (writing) {
-           /*
-            * SD wants to write this Volume, so make
-            *   sure it is suitable for this job, i.e.
-            *   Pool matches, and it is either Append or Recycle
-            *   and Media Type matches and Pool allows any volume.
-            */
-           if (mr.PoolId != jcr->PoolId) {
+         const char *reason = NULL;           /* detailed reason for rejection */
+         /*
+          * If we are reading, accept any volume (reason == NULL)
+          * If we are writing, check if the Volume is valid
+          *   for this job, and do a recycle if necessary
+          */
+         if (writing) {
+            /*
+             * SD wants to write this Volume, so make
+             *   sure it is suitable for this job, i.e.
+             *   Pool matches, and it is either Append or Recycle
+             *   and Media Type matches and Pool allows any volume.
+             */
+            if (mr.PoolId != jcr->PoolId) {
                reason = "not in Pool";
-           } else if (strcmp(mr.MediaType, jcr->store->media_type) != 0) {
+            } else if (strcmp(mr.MediaType, jcr->store->media_type) != 0) {
                reason = "not correct MediaType";
-           } else {
-             /*
-              * ****FIXME***
-              *   This test (accept_any_volume) is turned off
+            } else {
+              /*
+               * ****FIXME***
+               *   This test (accept_any_volume) is turned off
                *   because it doesn't properly check if the volume
-              *   really is out of sequence!
-              *
-              * } else if (!jcr->pool->accept_any_volume) {
+               *   really is out of sequence!
+               *
+               * } else if (!jcr->pool->accept_any_volume) {
                *    reason = "Volume not in sequence";
-              */
-
-              /*
-               * Now try recycling if necessary
-               *   reason set non-NULL if we cannot use it
-               */
-              check_if_volume_valid_or_recyclable(jcr, &mr, &reason);
-           }
-        }
-        if (reason == NULL) {
-           /*
-            * Send Find Media response to Storage daemon
-            */
-           send_volume_info_to_storage_daemon(jcr, bs, &mr);
-        } else {
-           /* Not suitable volume */
+               */
+
+               /*
+                * Now try recycling if necessary
+                *   reason set non-NULL if we cannot use it
+                */
+               check_if_volume_valid_or_recyclable(jcr, &mr, &reason);
+            }
+         }
+         if (reason == NULL) {
+            /*
+             * Send Find Media response to Storage daemon
+             */
+            send_volume_info_to_storage_daemon(jcr, bs, &mr);
+         } else {
+            /* Not suitable volume */
             bnet_fsend(bs, "1998 Volume \"%s\" status is %s, %s.\n", mr.VolumeName,
-              mr.VolStatus, reason);
-        }
+               mr.VolStatus, reason);
+         }
 
       } else {
          bnet_fsend(bs, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName);
@@ -211,39 +211,39 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
 
       db_lock(jcr->db);
       Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
-        mr.VolStatus, sdmr.VolStatus);
+         mr.VolStatus, sdmr.VolStatus);
       bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */
       unbash_spaces(mr.VolumeName);
       if (!db_get_media_record(jcr, jcr->db, &mr)) {
          Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"),
-             mr.VolumeName, db_strerror(jcr->db));
+              mr.VolumeName, db_strerror(jcr->db));
          bnet_fsend(bs, "1991 Catalog Request for vol=%s failed: %s", 
-           mr.VolumeName, db_strerror(jcr->db));
-        db_unlock(jcr->db);
-        return;
+            mr.VolumeName, db_strerror(jcr->db));
+         db_unlock(jcr->db);
+         return;
       }
       /* Set first written time if this is first job */
       if (mr.FirstWritten == 0) {
-        mr.FirstWritten = jcr->start_time;   /* use Job start time as first write */
-        mr.set_first_written = true;
+         mr.FirstWritten = jcr->start_time;   /* use Job start time as first write */
+         mr.set_first_written = true;
       }
       /* If we just labeled the tape set time */
       if (label || mr.LabelDate == 0) {
-        mr.LabelDate = jcr->start_time;
-        mr.set_label_date = true;
+         mr.LabelDate = jcr->start_time;
+         mr.set_label_date = true;
          Dmsg2(400, "label=%d labeldate=%d\n", label, mr.LabelDate);
       } else {
-        /*
-         * Insanity check for VolFiles get set to a smaller value
-         */
-        if (sdmr.VolFiles < mr.VolFiles) {
+         /*
+          * Insanity check for VolFiles get set to a smaller value
+          */
+         if (sdmr.VolFiles < mr.VolFiles) {
             Jmsg(jcr, M_FATAL, 0, _("Volume Files at %u being set to %u"
                  " for Volume \"%s\". This is incorrect.\n"),
-              mr.VolFiles, sdmr.VolFiles, mr.VolumeName);
+               mr.VolFiles, sdmr.VolFiles, mr.VolumeName);
             bnet_fsend(bs, "1992 Update Media error\n");
-           db_unlock(jcr->db);
-           return;
-        }
+            db_unlock(jcr->db);
+            return;
+         }
       }
       Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
       /* Copy updated values to original media record */
@@ -255,7 +255,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       mr.VolErrors    = sdmr.VolErrors;
       mr.VolWrites    = sdmr.VolWrites;
       mr.LastWritten  = sdmr.LastWritten;
-      mr.Slot        = sdmr.Slot;
+      mr.Slot         = sdmr.Slot;
       mr.InChanger    = sdmr.InChanger;
       mr.VolReadTime  = sdmr.VolReadTime;
       mr.VolWriteTime = sdmr.VolWriteTime;
@@ -268,10 +268,10 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
        *   Volume has expired, has_volume_expired() will update the DB.
        */
       if (has_volume_expired(jcr, &mr) || db_update_media_record(jcr, jcr->db, &mr)) {
-        send_volume_info_to_storage_daemon(jcr, bs, &mr);
+         send_volume_info_to_storage_daemon(jcr, bs, &mr);
       } else {
          Jmsg(jcr, M_FATAL, 0, _("Catalog error updating Media record. %s"),
-           db_strerror(jcr->db));
+            db_strerror(jcr->db));
          bnet_fsend(bs, "1992 Update Media error\n");
          Dmsg0(400, "send error\n");
       }
@@ -282,19 +282,19 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
     */
    } else if (sscanf(bs->msg, Create_job_media, &Job,
       &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile,
-      &jm.StartBlock, &jm.EndBlock) == 7) {
+      &jm.StartBlock, &jm.EndBlock, &jm.Copy, &jm.Stripe) == 9) {
 
       jm.JobId = jcr->JobId;
       jm.MediaId = jcr->MediaId;
       Dmsg6(400, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n",
-        jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex);
+         jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex);
       if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) {
          Jmsg(jcr, M_FATAL, 0, _("Catalog error creating JobMedia record. %s"),
-           db_strerror(jcr->db));
+            db_strerror(jcr->db));
          bnet_fsend(bs, "1991 Update JobMedia error\n");
       } else {
          Dmsg0(400, "JobMedia record created\n");
-        bnet_fsend(bs, OK_create);
+         bnet_fsend(bs, OK_create);
       }
 
    } else {
@@ -331,12 +331,12 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
    if (!jcr->pool->catalog_files) {
       return;
    }
-   db_start_transaction(jcr, jcr->db);    /* start transaction if not already open */
-   skip_nonspaces(&p);               /* UpdCat */
+   db_start_transaction(jcr, jcr->db);     /* start transaction if not already open */
+   skip_nonspaces(&p);                /* UpdCat */
    skip_spaces(&p);
-   skip_nonspaces(&p);               /* Job=nnn */
+   skip_nonspaces(&p);                /* Job=nnn */
    skip_spaces(&p);
-   skip_nonspaces(&p);               /* FileAttributes */
+   skip_nonspaces(&p);                /* FileAttributes */
    p += 1;
    unser_begin(p, 0);
    unser_uint32(VolSessionId);
@@ -351,12 +351,12 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
       VolSessionId, VolSessionTime, FileIndex, Stream, data_len);
 
    if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_UNIX_ATTRIBUTES_EX) {
-      skip_nonspaces(&p);            /* skip FileIndex */
+      skip_nonspaces(&p);             /* skip FileIndex */
       skip_spaces(&p);
-      skip_nonspaces(&p);            /* skip FileType */
+      skip_nonspaces(&p);             /* skip FileType */
       skip_spaces(&p);
       fname = p;
-      len = strlen(fname);       /* length before attributes */
+      len = strlen(fname);        /* length before attributes */
       attr = &fname[len+1];
 
       Dmsg2(400, "dird<stored: stream=%d %s\n", Stream, fname);
@@ -382,22 +382,22 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg)
       if (jcr->FileIndex != FileIndex) {
          Jmsg(jcr, M_WARNING, 0, "Got MD5/SHA1 but not same File as attributes\n");
       } else {
-        /* Update signature in catalog */
-        char SIGbuf[50];           /* 24 bytes should be enough */
-        int len, type;
-        if (Stream == STREAM_MD5_SIGNATURE) {
-           len = 16;
-           type = MD5_SIG;
-        } else {
-           len = 20;
-           type = SHA1_SIG;
-        }
-        bin_to_base64(SIGbuf, fname, len);
+         /* Update signature in catalog */
+         char SIGbuf[50];           /* 24 bytes should be enough */
+         int len, type;
+         if (Stream == STREAM_MD5_SIGNATURE) {
+            len = 16;
+            type = MD5_SIG;
+         } else {
+            len = 20;
+            type = SHA1_SIG;
+         }
+         bin_to_base64(SIGbuf, fname, len);
          Dmsg3(400, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
-        if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) {
+         if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) {
             Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5/SHA1. %s"),
-              db_strerror(jcr->db));
-        }
+               db_strerror(jcr->db));
+         }
       }
    }
 }
index 3215f71742206dcbe19f5a8b455ca98522e8d476..28edd03599dc527686b7048b118e5574f0023113 100644 (file)
@@ -9,9 +9,9 @@
  *
  *  Basic tasks done here:
  *    Open a message channel with the Storage daemon
- *     to authenticate ourself and to pass the JobId.
+ *      to authenticate ourself and to pass the JobId.
  *    Create a thread to interact with the Storage daemon
- *     who returns a job status and requests Catalog services, etc.
+ *      who returns a job status and requests Catalog services, etc.
  *
  *   Version $Id$
  */
@@ -43,7 +43,7 @@ static char jobcmd[]     = "JobId=%d job=%s job_name=%s client_name=%s "
    "type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s "
    "SpoolData=%d WritePartAfterJob=%d NewVol=%d\n";
 static char use_storage[] = "use storage=%s media_type=%s pool_name=%s "
-   "pool_type=%s append=%d\n";
+   "pool_type=%s append=%d copy=%d stripe=%d\n";
 static char use_device[] = "use device=%s\n";
 //static char query_device[] = "query device=%s";
 
@@ -53,7 +53,7 @@ static char OK_device[]  = "3000 OK use device device=%s\n";
 
 /* Storage Daemon requests */
 static char Job_start[]  = "3010 Job %127s start\n";
-static char Job_end[]   =
+static char Job_end[]    =
    "3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%" lld "\n";
 
 /* Forward referenced functions */
@@ -64,13 +64,13 @@ extern "C" void *msg_thread(void *arg);
  * and perform authentication.
  */
 bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
-                             int max_retry_time, int verbose)
+                              int max_retry_time, int verbose)
 {
    BSOCK *sd;
    STORE *store;
 
    if (jcr->store_bsock) {
-      return true;                   /* already connected */
+      return true;                    /* already connected */
    }
    store = (STORE *)jcr->storage->first();
 
@@ -81,11 +81,11 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
       store->SDport);
    sd = bnet_connect(jcr, retry_interval, max_retry_time,
           _("Storage daemon"), store->address,
-         NULL, store->SDport, verbose);
+          NULL, store->SDport, verbose);
    if (sd == NULL) {
       return false;
    }
-   sd->res = (RES *)store;       /* save pointer to other end */
+   sd->res = (RES *)store;        /* save pointer to other end */
    jcr->store_bsock = sd;
 
    if (!authenticate_storage_daemon(jcr, store)) {
@@ -132,6 +132,8 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
    char auth_key[100];
    POOL_MEM store_name, device_name, pool_name, pool_type, media_type;
    char PoolId[50];
+   int copy = 0;
+   int stripe = 0;
 
    sd = jcr->store_bsock;
    /*
@@ -144,10 +146,10 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
       bstrncpy(jcr->fileset->MD5, "**Dummy**", sizeof(jcr->fileset->MD5));
    }
    bnet_fsend(sd, jobcmd, jcr->JobId, jcr->Job, jcr->job->hdr.name,
-             jcr->client->hdr.name, jcr->JobType, jcr->JobLevel,
-             jcr->fileset->hdr.name, !jcr->pool->catalog_files,
-             jcr->job->SpoolAttributes, jcr->fileset->MD5, jcr->spool_data, 
-             jcr->write_part_after_job, jcr->job->NewVolEachJob);
+              jcr->client->hdr.name, jcr->JobType, jcr->JobLevel,
+              jcr->fileset->hdr.name, !jcr->pool->catalog_files,
+              jcr->job->SpoolAttributes, jcr->fileset->MD5, jcr->spool_data, 
+              jcr->write_part_after_job, jcr->job->NewVolEachJob);
    Dmsg1(100, ">stored: %s\n", sd->msg);
    unbash_spaces(jcr->job->hdr.name);
    unbash_spaces(jcr->client->hdr.name);
@@ -155,17 +157,17 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
    if (bget_dirmsg(sd) > 0) {
        Dmsg1(100, "<stored: %s", sd->msg);
        if (sscanf(sd->msg, OKjob, &jcr->VolSessionId,
-                 &jcr->VolSessionTime, &auth_key) != 3) {
+                  &jcr->VolSessionTime, &auth_key) != 3) {
           Dmsg1(100, "BadJob=%s\n", sd->msg);
           Jmsg(jcr, M_FATAL, 0, _("Storage daemon rejected Job command: %s\n"), sd->msg);
-         return 0;
+          return 0;
        } else {
-         jcr->sd_auth_key = bstrdup(auth_key);
+          jcr->sd_auth_key = bstrdup(auth_key);
           Dmsg1(150, "sd_auth_key=%s\n", jcr->sd_auth_key);
        }
    } else {
       Jmsg(jcr, M_FATAL, 0, _("<stored: bad response to Job command: %s\n"),
-        bnet_strerror(sd));
+         bnet_strerror(sd));
       return 0;
    }
 
@@ -192,30 +194,30 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append)
       pm_strcpy(media_type, storage->media_type);
       bash_spaces(media_type);
       bnet_fsend(sd, use_storage, store_name.c_str(), media_type.c_str(), 
-                pool_name.c_str(), pool_type.c_str(), append);
+                 pool_name.c_str(), pool_type.c_str(), append, copy, stripe);
 
       DEVICE *dev;
       /* Loop over alternative storage Devices until one is OK */
       foreach_alist(dev, storage->device) {
-        pm_strcpy(device_name, dev->hdr.name);
-        bash_spaces(device_name);
-        bnet_fsend(sd, use_device, device_name.c_str());
+         pm_strcpy(device_name, dev->hdr.name);
+         bash_spaces(device_name);
+         bnet_fsend(sd, use_device, device_name.c_str());
          Dmsg1(100, ">stored: %s", sd->msg);
       }
       bnet_sig(sd, BNET_EOD);
       if (bget_dirmsg(sd) > 0) {
          Dmsg1(100, "<stored: %s", sd->msg);
-        /* ****FIXME**** save actual device name */
-        ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1;
+         /* ****FIXME**** save actual device name */
+         ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1;
       } else {
-        POOL_MEM err_msg;
-        pm_strcpy(err_msg, sd->msg); /* save message */
+         POOL_MEM err_msg;
+         pm_strcpy(err_msg, sd->msg); /* save message */
          Jmsg(jcr, M_WARNING, 0, _("\n"
             "     Storage daemon didn't accept Device \"%s\" because:\n     %s"),
-           device_name.c_str(), err_msg.c_str()/* sd->msg */);
+            device_name.c_str(), err_msg.c_str()/* sd->msg */);
       }
 //    if (!ok) {
-//      break;
+//       break;
 //    }
 // }
    if (ok) {
@@ -235,7 +237,7 @@ int start_storage_daemon_message_thread(JCR *jcr)
    pthread_t thid;
 
    P(jcr->mutex);
-   jcr->use_count++;                 /* mark in use by msg thread */
+   jcr->use_count++;                  /* mark in use by msg thread */
    jcr->sd_msg_thread_done = false;
    jcr->SD_msg_chan = 0;
    V(jcr->mutex);
@@ -256,13 +258,13 @@ extern "C" void msg_thread_cleanup(void *arg)
 {
    JCR *jcr = (JCR *)arg;
    Dmsg0(200, "End msg_thread\n");
-   db_end_transaction(jcr, jcr->db);      /* terminate any open transaction */
+   db_end_transaction(jcr, jcr->db);       /* terminate any open transaction */
    P(jcr->mutex);
    jcr->sd_msg_thread_done = true;
    pthread_cond_broadcast(&jcr->term_wait); /* wakeup any waiting threads */
    jcr->SD_msg_chan = 0;
    V(jcr->mutex);
-   free_jcr(jcr);                    /* release jcr */
+   free_jcr(jcr);                     /* release jcr */
 }
 
 /*
@@ -291,14 +293,14 @@ extern "C" void *msg_thread(void *arg)
    while ((stat=bget_dirmsg(sd)) >= 0) {
       Dmsg1(200, "<stored: %s", sd->msg);
       if (sscanf(sd->msg, Job_start, &Job) == 1) {
-        continue;
+         continue;
       }
       if (sscanf(sd->msg, Job_end, &Job, &JobStatus, &JobFiles,
-                &JobBytes) == 4) {
-        jcr->SDJobStatus = JobStatus; /* termination status */
-        jcr->SDJobFiles = JobFiles;
-        jcr->SDJobBytes = JobBytes;
-        break;
+                 &JobBytes) == 4) {
+         jcr->SDJobStatus = JobStatus; /* termination status */
+         jcr->SDJobFiles = JobFiles;
+         jcr->SDJobBytes = JobBytes;
+         break;
       }
    }
    if (is_bnet_error(sd)) {
@@ -325,11 +327,11 @@ void wait_for_storage_daemon_termination(JCR *jcr)
       Dmsg0(300, "I'm waiting for message thread termination.\n");
       pthread_cond_timedwait(&jcr->term_wait, &jcr->mutex, &timeout);
       if (job_canceled(jcr)) {
-        cancel_count++;
+         cancel_count++;
       }
       /* Give SD 30 seconds to clean up after cancel */
       if (cancel_count == 3) {
-        break;
+         break;
       }
    }
    V(jcr->mutex);
@@ -351,15 +353,15 @@ extern "C" void *device_thread(void *arg)
    for (i=0; i < MAX_TRIES; i++) {
       if (!connect_to_storage_daemon(jcr, 10, 30, 1)) {
          Dmsg0(000, "Failed connecting to SD.\n");
-        continue;
+         continue;
       }
       LockRes();
       foreach_res(dev, R_DEVICE) {
-        if (!update_device_res(jcr, dev)) {
+         if (!update_device_res(jcr, dev)) {
             Dmsg1(900, "Error updating device=%s\n", dev->hdr.name);
-        } else {
+         } else {
             Dmsg1(900, "Updated Device=%s\n", dev->hdr.name);
-        }
+         }
       }
       UnlockRes();
       bnet_close(jcr->store_bsock);
index 3f93b37adfb6e41cf20ef3ffad7630ad4eec2447..a84c238a2207e9654dcde14ba865395e858e7d05 100644 (file)
@@ -39,7 +39,7 @@ static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s"
    " VolParts=%u\n";
 static char Create_job_media[] = "CatReq Job=%s CreateJobMedia"
    " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u"
-   " StartBlock=%u EndBlock=%u\n";
+   " StartBlock=%u EndBlock=%u Copy=%d Strip=%d\n";
 static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
 static char Job_status[]     = "Status Job=%s JobStatus=%d\n";
 
@@ -119,15 +119,15 @@ bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer)
    /* This is mostly to indicate that we are here */
    ok = bnet_fsend(dir, Device_update,
       jcr->Job,
-      dev_name.c_str(),        /* Changer name */
-      0, 0, 0,                 /* append, read, num_writers */
-      0, 0, 0,                 /* is_open, is_labeled, offline */
-      0, 0,                    /* reserved, max_writers */
-      0,                       /* Autoselect */
-      changer->device->size(), /* Number of devices */
+      dev_name.c_str(),         /* Changer name */
+      0, 0, 0,                  /* append, read, num_writers */
+      0, 0, 0,                  /* is_open, is_labeled, offline */
+      0, 0,                     /* reserved, max_writers */
+      0,                        /* Autoselect */
+      changer->device->size(),  /* Number of devices */
       "0",                      /* PoolId */
       "*",                      /* ChangerName */
-      MediaType.c_str(),       /* MediaType */
+      MediaType.c_str(),        /* MediaType */
       "*");                     /* VolName */
    Dmsg1(100, ">dird: %s\n", dir->msg);
    return ok;
@@ -150,7 +150,7 @@ bool dir_send_job_status(JCR *jcr)
  *   dir_find_next_appendable_volume()
  *
  *  Returns: true  on success and vol info in dcr->VolCatInfo
- *          false on failure
+ *           false on failure
  */
 static bool do_get_volume_info(DCR *dcr)
 {
@@ -160,7 +160,7 @@ static bool do_get_volume_info(DCR *dcr)
     int n;
     int InChanger;
 
-    dcr->VolumeName[0] = 0;          /* No volume */
+    dcr->VolumeName[0] = 0;           /* No volume */
     if (bnet_recv(dir) <= 0) {
        Dmsg0(200, "getvolname error bnet_recv\n");
        Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n"));
@@ -169,27 +169,27 @@ static bool do_get_volume_info(DCR *dcr)
     memset(&vol, 0, sizeof(vol));
     Dmsg1(100, "<dird %s", dir->msg);
     n = sscanf(dir->msg, OK_media, vol.VolCatName,
-              &vol.VolCatJobs, &vol.VolCatFiles,
-              &vol.VolCatBlocks, &vol.VolCatBytes,
-              &vol.VolCatMounts, &vol.VolCatErrors,
-              &vol.VolCatWrites, &vol.VolCatMaxBytes,
-              &vol.VolCatCapacityBytes, vol.VolCatStatus,
-              &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
-              &InChanger, &vol.VolReadTime, &vol.VolWriteTime,
-              &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
-              &vol.LabelType);
+               &vol.VolCatJobs, &vol.VolCatFiles,
+               &vol.VolCatBlocks, &vol.VolCatBytes,
+               &vol.VolCatMounts, &vol.VolCatErrors,
+               &vol.VolCatWrites, &vol.VolCatMaxBytes,
+               &vol.VolCatCapacityBytes, vol.VolCatStatus,
+               &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
+               &InChanger, &vol.VolReadTime, &vol.VolWriteTime,
+               &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
+               &vol.LabelType);
     if (n != 21) {
        Dmsg2(100, "Bad response from Dir fields=%d: %s\n", n, dir->msg);
        Mmsg(jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg);
        return false;
     }
-    vol.InChanger = InChanger;       /* bool in structure */
+    vol.InChanger = InChanger;        /* bool in structure */
     unbash_spaces(vol.VolCatName);
     bstrncpy(dcr->VolumeName, vol.VolCatName, sizeof(dcr->VolumeName));
     memcpy(&dcr->VolCatInfo, &vol, sizeof(dcr->VolCatInfo));
 
     Dmsg2(300, "do_reqest_vol_info got slot=%d Volume=%s\n",
-         vol.Slot, vol.VolCatName);
+          vol.Slot, vol.VolCatName);
     return true;
 }
 
@@ -198,11 +198,11 @@ static bool do_get_volume_info(DCR *dcr)
  * Get Volume info for a specific volume from the Director's Database
  *
  * Returns: true  on success   (not Director guarantees that Pool and MediaType
- *                            are correct and VolStatus==Append or
- *                            VolStatus==Recycle)
- *         false on failure
+ *                             are correct and VolStatus==Append or
+ *                             VolStatus==Recycle)
+ *          false on failure
  *
- *         Volume information returned in jcr
+ *          Volume information returned in jcr
  */
 bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
 {
@@ -222,9 +222,9 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
 /*
  * Get info on the next appendable volume in the Director's database
  * Returns: true  on success
- *         false on failure
+ *          false on failure
  *
- *         Volume information returned in dcr
+ *          Volume information returned in dcr
  *
  */
 bool dir_find_next_appendable_volume(DCR *dcr)
@@ -235,9 +235,9 @@ bool dir_find_next_appendable_volume(DCR *dcr)
 
     Dmsg0(200, "dir_find_next_appendable_volume\n");
     /*
-     * Try the three oldest or most available volumes. Note,
-     *  the most available could already be mounted on another
-     *  drive, so we continue looking for a not in use Volume.
+     * Try the three oldest or most available volumes.  Note,
+     *   the most available could already be mounted on another
+     *   drive, so we continue looking for a not in use Volume.
      */
     for (int vol_index=1;  vol_index < 3; vol_index++) {
        bash_spaces(dcr->media_type);
@@ -248,36 +248,36 @@ bool dir_find_next_appendable_volume(DCR *dcr)
        Dmsg1(100, ">dird: %s", dir->msg);
        if (do_get_volume_info(dcr)) {
           Dmsg2(300, "JobId=%d got possible Vol=%s\n", jcr->JobId, dcr->VolumeName);
-         bool found = false;
-         /*
-          * Walk through all jobs and see if the volume is
-          *  already mounted. If so, try a different one.
-          * This would be better done by walking through
-          *  all the devices.
-          */
-         lock_jcr_chain();
-         foreach_jcr(njcr) {
-            if (jcr == njcr) {
-               free_locked_jcr(njcr);
-               continue;             /* us */
-            }
+          bool found = false;
+          /*
+           * Walk through all jobs and see if the volume is
+           *  already mounted. If so, try a different one.
+           * This would be better done by walking through
+           *  all the devices.
+           */
+          lock_jcr_chain();
+          foreach_jcr(njcr) {
+             if (jcr == njcr) {
+                free_locked_jcr(njcr);
+                continue;             /* us */
+             }
              Dmsg2(300, "Compare to JobId=%d using Vol=%s\n", njcr->JobId, njcr->dcr->VolumeName);
-            if (njcr->dcr && strcmp(dcr->VolumeName, njcr->dcr->VolumeName) == 0) {
-               found = true;
+             if (njcr->dcr && strcmp(dcr->VolumeName, njcr->dcr->VolumeName) == 0) {
+                found = true;
                 Dmsg1(400, "Vol in use by JobId=%u\n", njcr->JobId);
-               free_locked_jcr(njcr);
-               break;
-            }
-            free_locked_jcr(njcr);
-         }
-         unlock_jcr_chain();
-         if (!found) {
+                free_locked_jcr(njcr);
+                break;
+             }
+             free_locked_jcr(njcr);
+          }
+          unlock_jcr_chain();
+          if (!found) {
              Dmsg0(400, "dir_find_next_appendable_volume return true\n");
-            return true;             /* Got good Volume */
-         }
+             return true;             /* Got good Volume */
+          }
        } else {
           Dmsg0(200, "No volume info, return false\n");
-         return false;
+          return false;
        }
     }
     Dmsg0(400, "dir_find_next_appendable_volume return true\n");
@@ -316,7 +316,7 @@ bool dir_update_volume_info(DCR *dcr, bool label)
    /* Just labeled or relabeled the tape */
    if (label) {
       bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
-      vol->VolCatBytes = 1;          /* indicates tape labeled */
+      vol->VolCatBytes = 1;           /* indicates tape labeled */
    }
    pm_strcpy(VolumeName, vol->VolCatName);
    bash_spaces(VolumeName);
@@ -327,7 +327,7 @@ bool dir_update_volume_info(DCR *dcr, bool label)
       vol->VolCatMounts, vol->VolCatErrors,
       vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
       LastWritten, vol->VolCatStatus, vol->Slot, label,
-      InChanger,                     /* bool in structure */
+      InChanger,                      /* bool in structure */
       edit_uint64(vol->VolReadTime, ed3),
       edit_uint64(vol->VolWriteTime, ed4),
       vol->VolCatParts);
@@ -336,7 +336,7 @@ bool dir_update_volume_info(DCR *dcr, bool label)
    if (!do_get_volume_info(dcr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
       Pmsg2(000, "Didn't get vol info vol=%s: ERR=%s", 
-        vol->VolCatName, jcr->errmsg);
+         vol->VolCatName, jcr->errmsg);
       return false;
    }
    Dmsg1(420, "get_volume_info(): %s", dir->msg);
@@ -354,19 +354,20 @@ bool dir_create_jobmedia_record(DCR *dcr)
    BSOCK *dir = jcr->dir_bsock;
 
    if (!dcr->WroteVol) {
-      return true;                   /* nothing written to tape */
+      return true;                    /* nothing written to tape */
    }
 
    dcr->WroteVol = false;
    bnet_fsend(dir, Create_job_media, jcr->Job,
       dcr->VolFirstIndex, dcr->VolLastIndex,
       dcr->StartFile, dcr->EndFile,
-      dcr->StartBlock, dcr->EndBlock);
+      dcr->StartBlock, dcr->EndBlock, 
+      dcr->Copy, dcr->Stripe);
     Dmsg1(100, ">dird: %s", dir->msg);
    if (bnet_recv(dir) <= 0) {
       Dmsg0(190, "create_jobmedia error bnet_recv\n");
       Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"),
-          bnet_strerror(dir));
+           bnet_strerror(dir));
       return false;
    }
    Dmsg1(100, "<dir: %s", dir->msg);
@@ -394,7 +395,7 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec)
 
    dir->msglen = sprintf(dir->msg, FileAttributes, jcr->Job);
    dir->msg = check_pool_memory_size(dir->msg, dir->msglen +
-               sizeof(DEV_RECORD) + rec->data_len);
+                sizeof(DEV_RECORD) + rec->data_len);
    ser_begin(dir->msg + dir->msglen, 0);
    ser_uint32(rec->VolSessionId);
    ser_uint32(rec->VolSessionTime);
@@ -415,16 +416,16 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec)
  *   Leaves with device blocked.
  *
  *   Returns: true  on success (operator issues a mount command)
- *           false on failure
- *             Note, must create dev->errmsg on error return.
+ *            false on failure
+ *              Note, must create dev->errmsg on error return.
  *
  *    On success, dcr->VolumeName and dcr->VolCatInfo contain
- *     information on suggested volume, but this may not be the
- *     same as what is actually mounted.
+ *      information on suggested volume, but this may not be the
+ *      same as what is actually mounted.
  *
  *    When we return with success, the correct tape may or may not
- *     actually be mounted. The calling routine must read it and
- *     verify the label.
+ *      actually be mounted. The calling routine must read it and
+ *      verify the label.
  */
 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
 {
@@ -438,51 +439,51 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
    ASSERT(dev->dev_blocked);
    for ( ;; ) {
       if (job_canceled(jcr)) {
-        Mmsg(dev->errmsg,
+         Mmsg(dev->errmsg,
               _("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"),
-             jcr->Job, dev->print_name());
+              jcr->Job, dev->print_name());
          Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
-        return false;
+         return false;
       }
       /* First pass, we *know* there are no appendable volumes, so no need to call */
       if (!first && dir_find_next_appendable_volume(dcr)) { /* get suggested volume */
-        unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                    (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
-        /*
-         * If we have a valid volume name and we are not
-         *   removable media, return now, or if we have a
-         *   Slot for an autochanger, otherwise wait
-         *   for the operator to mount the media.
-         */
-        if (!unmounted && ((dcr->VolumeName[0] && !dev_cap(dev, CAP_REM) &&
-               dev_cap(dev, CAP_LABEL)) ||
-                (dcr->VolumeName[0] && dcr->VolCatInfo.Slot))) {
+         unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
+                     (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+         /*
+          * If we have a valid volume name and we are not
+          *   removable media, return now, or if we have a
+          *   Slot for an autochanger, otherwise wait
+          *   for the operator to mount the media.
+          */
+         if (!unmounted && ((dcr->VolumeName[0] && !dev_cap(dev, CAP_REM) &&
+                dev_cap(dev, CAP_LABEL)) ||
+                 (dcr->VolumeName[0] && dcr->VolCatInfo.Slot))) {
             Dmsg0(400, "Return 1 from mount without wait.\n");
-           return true;
-        }
-        jstat = JS_WaitMount;
-        if (!dev->poll) {
-           Jmsg(jcr, M_MOUNT, 0, _(
+            return true;
+         }
+         jstat = JS_WaitMount;
+         if (!dev->poll) {
+            Jmsg(jcr, M_MOUNT, 0, _(
 "Please mount Volume \"%s\" on Storage Device %s for Job %s\n"
 "Use \"mount\" command to release Job.\n"),
-             dcr->VolumeName, dev->print_name(), jcr->Job);
+              dcr->VolumeName, dev->print_name(), jcr->Job);
             Dmsg3(400, "Mount %s on %s for Job %s\n",
-                 dcr->VolumeName, dcr->dev_name, jcr->Job);
-        }
+                  dcr->VolumeName, dcr->dev_name, jcr->Job);
+         }
       } else {
-        jstat = JS_WaitMedia;
-        if (!dev->poll) {
-           Jmsg(jcr, M_MOUNT, 0, _(
+         jstat = JS_WaitMedia;
+         if (!dev->poll) {
+            Jmsg(jcr, M_MOUNT, 0, _(
 "Job %s waiting. Cannot find any appendable volumes.\n"
 "Please use the \"label\"  command to create a new Volume for:\n"
 "    Storage:      %s\n"
 "    Media type:   %s\n"
 "    Pool:         %s\n"),
-              jcr->Job,
-              dev->print_name(),
-              dcr->media_type,
-              dcr->pool_name);
-        }
+               jcr->Job,
+               dev->print_name(),
+               dcr->media_type,
+               dcr->pool_name);
+         }
       }
       first = false;
 
@@ -492,47 +493,47 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
       stat = wait_for_sysop(dcr);
       if (dev->poll) {
          Dmsg1(400, "Poll timeout in create append vol on device %s\n", dev->print_name());
-        continue;
+         continue;
       }
 
       if (stat == ETIMEDOUT) {
-        if (!double_dev_wait_time(dev)) {
+         if (!double_dev_wait_time(dev)) {
             Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"),
-              dev->print_name(), jcr->Job);
+               dev->print_name(), jcr->Job);
             Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
             Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name());
-           return false;             /* exceeded maximum waits */
-        }
-        continue;
+            return false;             /* exceeded maximum waits */
+         }
+         continue;
       }
       if (stat == EINVAL) {
-        berrno be;
+         berrno be;
          Mmsg2(dev->errmsg, _("pthread error in mount_next_volume stat=%d ERR=%s\n"),
-              stat, be.strerror(stat));
+               stat, be.strerror(stat));
          Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
-        return false;
+         return false;
       }
       if (stat != 0) {
-        berrno be;
+         berrno be;
          Jmsg(jcr, M_WARNING, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat,
-           be.strerror(stat));
+            be.strerror(stat));
       }
       Dmsg1(400, "Someone woke me for device %s\n", dev->print_name());
 
       /* If no VolumeName, and cannot get one, try again */
       if (dcr->VolumeName[0] == 0 && !job_canceled(jcr) &&
-         !dir_find_next_appendable_volume(dcr)) {
-        Jmsg(jcr, M_MOUNT, 0, _(
+          !dir_find_next_appendable_volume(dcr)) {
+         Jmsg(jcr, M_MOUNT, 0, _(
 "Someone woke me up, but I cannot find any appendable\n"
 "volumes for Job=%s.\n"), jcr->Job);
-        /* Restart wait counters after user interaction */
-        init_device_wait_timers(dcr);
-        continue;
+         /* Restart wait counters after user interaction */
+         init_device_wait_timers(dcr);
+         continue;
       }
       unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                 (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+                  (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
       if (unmounted) {
-        continue;                    /* continue to wait */
+         continue;                    /* continue to wait */
       }
 
       /*
@@ -550,12 +551,12 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
  *   Request to mount specific Volume
  *
  *   Entered with device blocked and dcr->VolumeName is desired
- *     volume.
+ *      volume.
  *   Leaves with device blocked.
  *
  *   Returns: true  on success (operator issues a mount command)
- *           false on failure
- *                 Note, must create dev->errmsg on error return.
+ *            false on failure
+ *                  Note, must create dev->errmsg on error return.
  *
  */
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
@@ -574,49 +575,49 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
    for ( ;; ) {
       if (job_canceled(jcr)) {
          Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"),
-             jcr->Job, dev->print_name());
-        return false;
+              jcr->Job, dev->print_name());
+         return false;
       }
 
       if (!dev->poll) {
          msg = _("Please mount");
          Jmsg(jcr, M_MOUNT, 0, _("%s Volume \"%s\" on Storage Device %s for Job %s\n"),
-             msg, dcr->VolumeName, dev->print_name(), jcr->Job);
+              msg, dcr->VolumeName, dev->print_name(), jcr->Job);
          Dmsg3(400, "Mount \"%s\" on device \"%s\" for Job %s\n",
-              dcr->VolumeName, dcr->dev_name, jcr->Job);
+               dcr->VolumeName, dcr->dev_name, jcr->Job);
       }
 
       jcr->JobStatus = JS_WaitMount;
       dir_send_job_status(jcr);
 
-      stat = wait_for_sysop(dcr);    ;    /* wait on device */
+      stat = wait_for_sysop(dcr);    ;     /* wait on device */
       if (dev->poll) {
          Dmsg1(400, "Poll timeout in mount vol on device %s\n", dev->print_name());
          Dmsg1(400, "Blocked=%s\n", edit_blocked_reason(dev));
-        return true;
+         return true;
       }
 
       if (stat == ETIMEDOUT) {
-        if (!double_dev_wait_time(dev)) {
+         if (!double_dev_wait_time(dev)) {
             Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"),
-              dev->print_name(), jcr->Job);
+               dev->print_name(), jcr->Job);
             Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
             Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name());
-           return false;             /* exceeded maximum waits */
-        }
-        continue;
+            return false;             /* exceeded maximum waits */
+         }
+         continue;
       }
       if (stat == EINVAL) {
-        berrno be;
+         berrno be;
          Mmsg2(dev->errmsg, _("pthread error in mount_volume stat=%d ERR=%s\n"),
-              stat, be.strerror(stat));
+               stat, be.strerror(stat));
          Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
-        return false;
+         return false;
       }
       if (stat != 0) {
-        berrno be;
+         berrno be;
          Jmsg(jcr, M_FATAL, 0, _("pthread error in mount_next_volume stat=%d: ERR=%s\n"), stat,
-           be.strerror(stat));
+            be.strerror(stat));
       }
       Dmsg1(400, "Someone woke me for device %s\n", dev->print_name());
       break;
index bd9df85310e66d0df0f139f9f3d0ae49968d1f38..3aa8f06546160cf360e7e118bbb7094e63aef23e 100644 (file)
@@ -340,6 +340,8 @@ public:
    char pool_type[MAX_NAME_LENGTH];   /* pool type */
    char media_type[MAX_NAME_LENGTH];  /* media type */
    char dev_name[MAX_NAME_LENGTH];    /* dev name */
+   int Copy;                          /* identical copy number */
+   int Stripe;                        /* RAIT stripe */
    VOLUME_CAT_INFO VolCatInfo;        /* Catalog info for desired volume */
 };
 
index 4dc568b35e170ea1750cde4b6c66b92a2da8b74d..c77d95016844fab60565b8907053bb0bb5af4768 100644 (file)
@@ -43,7 +43,7 @@ static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
       "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
       "SpoolData=%d WritePartAfterJob=%d NewVol=%d\n";
 static char use_storage[]  = "use storage=%127s media_type=%127s "
-   "pool_name=%127s pool_type=%127s append=%d\n";
+   "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
 static char use_device[]  = "use device=%127s\n";
 //static char query_device[] = "query device=%127s";
 
@@ -85,10 +85,10 @@ bool job_cmd(JCR *jcr)
     */
    Dmsg1(100, "<dird: %s\n", dir->msg);
    if (sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(),
-             client_name.c_str(),
-             &JobType, &level, fileset_name.c_str(), &no_attributes,
-             &spool_attributes, fileset_md5.c_str(), &spool_data, 
-             &write_part_after_job, &NewVol) != 13) {
+              client_name.c_str(),
+              &JobType, &level, fileset_name.c_str(), &no_attributes,
+              &spool_attributes, fileset_md5.c_str(), &spool_data, 
+              &write_part_after_job, &NewVol) != 13) {
       pm_strcpy(jcr->errmsg, dir->msg);
       bnet_fsend(dir, BAD_job, jcr->errmsg);
       Dmsg1(100, ">dird: %s\n", dir->msg);
@@ -173,12 +173,12 @@ bool run_cmd(JCR *jcr)
       return false;
    }
 
-   set_jcr_job_status(jcr, JS_WaitFD);         /* wait for FD to connect */
+   set_jcr_job_status(jcr, JS_WaitFD);          /* wait for FD to connect */
    dir_send_job_status(jcr);
 
    gettimeofday(&tv, &tz);
    timeout.tv_nsec = tv.tv_usec * 1000;
-   timeout.tv_sec = tv.tv_sec + 30 * 60;       /* wait 30 minutes */
+   timeout.tv_sec = tv.tv_sec + 30 * 60;        /* wait 30 minutes */
 
    Dmsg1(100, "%s waiting on FD to contact SD\n", jcr->Job);
    /*
@@ -190,7 +190,7 @@ bool run_cmd(JCR *jcr)
    for ( ;!job_canceled(jcr); ) {
       errstat = pthread_cond_timedwait(&jcr->job_start_wait, &jcr->mutex, &timeout);
       if (errstat == 0 || errstat == ETIMEDOUT) {
-        break;
+         break;
       }
    }
    V(jcr->mutex);
@@ -199,7 +199,7 @@ bool run_cmd(JCR *jcr)
 
    if (jcr->authenticated && !job_canceled(jcr)) {
       Dmsg1(100, "Running job %s\n", jcr->Job);
-      run_job(jcr);                  /* Run the job */
+      run_job(jcr);                   /* Run the job */
    }
    return false;
 }
@@ -212,7 +212,7 @@ void handle_filed_connection(BSOCK *fd, char *job_name)
 {
    JCR *jcr;
 
-   bmicrosleep(0, 50000);            /* wait 50 millisecs */
+   bmicrosleep(0, 50000);             /* wait 50 millisecs */
    if (!(jcr=get_jcr_by_full_name(job_name))) {
       Jmsg1(NULL, M_FATAL, 0, _("Job name not found: %s\n"), job_name);
       Dmsg1(100, "Job name not found: %s\n", job_name);
@@ -226,7 +226,7 @@ void handle_filed_connection(BSOCK *fd, char *job_name)
 
    if (jcr->authenticated) {
       Jmsg2(jcr, M_FATAL, 0, "Hey!!!! JobId %u Job %s already authenticated.\n",
-        jcr->JobId, jcr->Job);
+         jcr->JobId, jcr->Job);
       free_jcr(jcr);
       return;
    }
@@ -256,10 +256,10 @@ void handle_filed_connection(BSOCK *fd, char *job_name)
 /*
  *   Use Device command from Director
  *   He tells is what Device Name to use, the Media Type,
- *     the Pool Name, and the Pool Type.
+ *      the Pool Name, and the Pool Type.
  *
  *    Ensure that the device exists and is opened, then store
- *     the media and pool info in the JCR.
+ *      the media and pool info in the JCR.
  */
 class DIRSTORE {
 public:
@@ -282,145 +282,148 @@ static bool use_storage_cmd(JCR *jcr)
    AUTOCHANGER *changer;
    int append;
    bool ok;
+   int Copy, Stripe;
 
    /*
     * If there are multiple devices, the director sends us
-    *  use_device for each device that it wants to use.
+    *   use_device for each device that it wants to use.
     */
    Dmsg1(100, "<dird: %s", dir->msg);
    ok = sscanf(dir->msg, use_storage, store_name.c_str(), 
                media_type.c_str(), pool_name.c_str(), 
-              pool_type.c_str(), &append) == 5;
+               pool_type.c_str(), &append, &Copy, &Stripe) == 7;
    if (ok) {
       unbash_spaces(store_name);
       unbash_spaces(media_type);
       unbash_spaces(pool_name);
       unbash_spaces(pool_type);
       if (bnet_recv(dir) <= 0) {
-        return false;   
+         return false;   
       }
       ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
       if (!ok) {
-        return false;
+         return false;
       }
       /* Eat to BNET_EOD */
       while (bnet_recv(dir) > 0) {
       }
       LockRes();
       foreach_res(device, R_DEVICE) {
-        /* Find resource, and make sure we were able to open it */
-        if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
-            strcmp(device->media_type, media_type.c_str()) == 0) {
-           const int name_len = MAX_NAME_LENGTH;
-           DCR *dcr;
-           UnlockRes();
-           if (!device->dev) {
-              device->dev = init_dev(jcr, NULL, device);
-           }
-           if (!device->dev) {
+         /* Find resource, and make sure we were able to open it */
+         if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
+             strcmp(device->media_type, media_type.c_str()) == 0) {
+            const int name_len = MAX_NAME_LENGTH;
+            DCR *dcr;
+            UnlockRes();
+            if (!device->dev) {
+               device->dev = init_dev(jcr, NULL, device);
+            }
+            if (!device->dev) {
                Jmsg(jcr, M_WARNING, 0, _("\n"
                   "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
-                   dev_name.c_str());
-              bnet_fsend(dir, NOT_open, dev_name.c_str());
+                    dev_name.c_str());
+               bnet_fsend(dir, NOT_open, dev_name.c_str());
                Dmsg1(100, ">dird: %s\n", dir->msg);
-              return false;
-           }  
-           dcr = new_dcr(jcr, device->dev);
-           if (!dcr) {
+               return false;
+            }  
+            dcr = new_dcr(jcr, device->dev);
+            if (!dcr) {
                bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str());
                Dmsg1(100, ">dird: %s\n", dir->msg);
-              return false;
-           }
+               return false;
+            }
             Dmsg1(100, "Found device %s\n", device->hdr.name);
-           bstrncpy(dcr->pool_name, pool_name, name_len);
-           bstrncpy(dcr->pool_type, pool_type, name_len);
-           bstrncpy(dcr->media_type, media_type, name_len);
-           bstrncpy(dcr->dev_name, dev_name, name_len);
-           jcr->dcr = dcr;
-           if (append == SD_APPEND) {
-              ok = reserve_device_for_append(dcr);
-           } else {
-              ok = reserve_device_for_read(dcr);
-           }
-           if (!ok) {
+            bstrncpy(dcr->pool_name, pool_name, name_len);
+            bstrncpy(dcr->pool_type, pool_type, name_len);
+            bstrncpy(dcr->media_type, media_type, name_len);
+            bstrncpy(dcr->dev_name, dev_name, name_len);
+            dcr->Copy = Copy;
+            dcr->Stripe = Stripe;
+            jcr->dcr = dcr;
+            if (append == SD_APPEND) {
+               ok = reserve_device_for_append(dcr);
+            } else {
+               ok = reserve_device_for_read(dcr);
+            }
+            if (!ok) {
                bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), dev_name.c_str());
                Dmsg1(100, ">dird: %s\n", dir->msg);
-              free_dcr(jcr->dcr);
-              return false;
-           }
+               free_dcr(jcr->dcr);
+               return false;
+            }
             Dmsg1(220, "Got: %s", dir->msg);
-           bash_spaces(dev_name);
-           ok = bnet_fsend(dir, OK_device, dev_name.c_str());
+            bash_spaces(dev_name);
+            ok = bnet_fsend(dir, OK_device, dev_name.c_str());
             Dmsg1(100, ">dird: %s\n", dir->msg);
-           return ok;
-        }
+            return ok;
+         }
       }
 
       foreach_res(changer, R_AUTOCHANGER) {
-        /* Find resource, and make sure we were able to open it */
-        if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
-           const int name_len = MAX_NAME_LENGTH;
-           DCR *dcr;
-           /* Try each device in this AutoChanger */
-           foreach_alist(device, changer->device) {
+         /* Find resource, and make sure we were able to open it */
+         if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
+            const int name_len = MAX_NAME_LENGTH;
+            DCR *dcr;
+            /* Try each device in this AutoChanger */
+            foreach_alist(device, changer->device) {
                Dmsg1(100, "Try changer device %s\n", device->hdr.name);
-              if (!device->dev) {
-                 device->dev = init_dev(jcr, NULL, device);
-              }
-              if (!device->dev) {
+               if (!device->dev) {
+                  device->dev = init_dev(jcr, NULL, device);
+               }
+               if (!device->dev) {
                   Dmsg1(100, "Device %s could not be opened. Skipped\n", dev_name.c_str());
                   Jmsg(jcr, M_WARNING, 0, _("\n"
                      "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
-                      device->hdr.name, dev_name.c_str());
-                 continue;
-              }
-              if (!device->dev->autoselect) {
-                 continue;           /* device is not available */
-              }
-              dcr = new_dcr(jcr, device->dev);
-              if (!dcr) {
+                       device->hdr.name, dev_name.c_str());
+                  continue;
+               }
+               if (!device->dev->autoselect) {
+                  continue;           /* device is not available */
+               }
+               dcr = new_dcr(jcr, device->dev);
+               if (!dcr) {
                   bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str());
                   Dmsg1(100, ">dird: %s\n", dir->msg);
-                 UnlockRes();
-                 return false;
-              }
+                  UnlockRes();
+                  return false;
+               }
                Dmsg1(100, "Found changer device %s\n", device->hdr.name);
-              bstrncpy(dcr->pool_name, pool_name, name_len);
-              bstrncpy(dcr->pool_type, pool_type, name_len);
-              bstrncpy(dcr->media_type, media_type, name_len);
-              bstrncpy(dcr->dev_name, dev_name, name_len);
-              jcr->dcr = dcr;
-              if (append == SD_APPEND) {
-                 ok = reserve_device_for_append(dcr);
-              } else {
-                 ok = reserve_device_for_read(dcr);
-              }
-              if (!ok) {
+               bstrncpy(dcr->pool_name, pool_name, name_len);
+               bstrncpy(dcr->pool_type, pool_type, name_len);
+               bstrncpy(dcr->media_type, media_type, name_len);
+               bstrncpy(dcr->dev_name, dev_name, name_len);
+               jcr->dcr = dcr;
+               if (append == SD_APPEND) {
+                  ok = reserve_device_for_append(dcr);
+               } else {
+                  ok = reserve_device_for_read(dcr);
+               }
+               if (!ok) {
                   Jmsg(jcr, M_WARNING, 0, _("Could not reserve device: %s\n"), dev_name.c_str());
-                 free_dcr(jcr->dcr);
-                 continue;
-              }
+                  free_dcr(jcr->dcr);
+                  continue;
+               }
                Dmsg1(100, "Device %s opened.\n", dev_name.c_str());
-              UnlockRes();
-              pm_strcpy(dev_name, device->hdr.name);
-              bash_spaces(dev_name);
-              ok = bnet_fsend(dir, OK_device, dev_name.c_str());
+               UnlockRes();
+               pm_strcpy(dev_name, device->hdr.name);
+               bash_spaces(dev_name);
+               ok = bnet_fsend(dir, OK_device, dev_name.c_str());
                Dmsg1(100, ">dird: %s\n", dir->msg);
-              return ok;
-           }
-           break;                    /* we found it but could not open a device */
-        }
+               return ok;
+            }
+            break;                    /* we found it but could not open a device */
+         }
       }
 
       UnlockRes();
       if (verbose) {
-        unbash_spaces(dir->msg);
-        pm_strcpy(jcr->errmsg, dir->msg);
+         unbash_spaces(dir->msg);
+         pm_strcpy(jcr->errmsg, dir->msg);
          Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
       }
       Jmsg(jcr, M_FATAL, 0, _("\n"
          "     Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
-          dev_name.c_str(), media_type.c_str());
+           dev_name.c_str(), media_type.c_str());
       bnet_fsend(dir, NO_device, dev_name.c_str());
       Dmsg1(100, ">dird: %s\n", dir->msg);
    } else {
@@ -434,7 +437,7 @@ static bool use_storage_cmd(JCR *jcr)
       Dmsg1(100, ">dird: %s\n", dir->msg);
    }
 
-   return false;                     /* ERROR return */
+   return false;                      /* ERROR return */
 }
 
 #ifdef needed
@@ -461,39 +464,39 @@ bool query_cmd(JCR *jcr)
       unbash_spaces(dev_name);
       LockRes();
       foreach_res(device, R_DEVICE) {
-        /* Find resource, and make sure we were able to open it */
-        if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0) {
-           if (!device->dev) {
-              device->dev = init_dev(jcr, NULL, device);
-           }
-           if (!device->dev) {
-              break;
-           }  
-           UnlockRes();
-           ok = dir_update_device(jcr, device->dev);
-           if (ok) {
-              ok = bnet_fsend(dir, OK_query);
-           } else {
-              bnet_fsend(dir, NO_query);
-           }
-           return ok;
-        }
+         /* Find resource, and make sure we were able to open it */
+         if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0) {
+            if (!device->dev) {
+               device->dev = init_dev(jcr, NULL, device);
+            }
+            if (!device->dev) {
+               break;
+            }  
+            UnlockRes();
+            ok = dir_update_device(jcr, device->dev);
+            if (ok) {
+               ok = bnet_fsend(dir, OK_query);
+            } else {
+               bnet_fsend(dir, NO_query);
+            }
+            return ok;
+         }
       }
       foreach_res(changer, R_AUTOCHANGER) {
-        /* Find resource, and make sure we were able to open it */
-        if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
-           UnlockRes();
-           if (!changer->device || changer->device->size() == 0) {
-              continue;              /* no devices */
-           }
-           ok = dir_update_changer(jcr, changer);
-           if (ok) {
-              ok = bnet_fsend(dir, OK_query);
-           } else {
-              bnet_fsend(dir, NO_query);
-           }
-           return ok;
-        }
+         /* Find resource, and make sure we were able to open it */
+         if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
+            UnlockRes();
+            if (!changer->device || changer->device->size() == 0) {
+               continue;              /* no devices */
+            }
+            ok = dir_update_changer(jcr, changer);
+            if (ok) {
+               ok = bnet_fsend(dir, OK_query);
+            } else {
+               bnet_fsend(dir, NO_query);
+            }
+            return ok;
+         }
       }
       /* If we get here, the device/autochanger was not found */
       UnlockRes();
index df1bd94f5ab9b6a39021f662d7e3a809618d0d64..725330d613db5850181c89a00a274229b7341d54 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.11"
-#define BDATE   "31 March 2005"
-#define LSMDATE "31Mar05"
+#define VERSION "1.37.12"
+#define BDATE   "02 April 2005"
+#define LSMDATE "02Apr05"
 
 /* Debug flags */
 #undef  DEBUG