+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)
- 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
#ifdef HAVE_SQLITE
-#define BDB_VERSION 8
+#define BDB_VERSION 9
#include <sqlite.h>
#ifdef HAVE_SQLITE3
-#define BDB_VERSION 8
+#define BDB_VERSION 9
#include <sqlite3.h>
#ifdef HAVE_MYSQL
-#define BDB_VERSION 8
+#define BDB_VERSION 9
#include <mysql.h>
#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 {
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 */
};
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 */
};
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)
);
);
-CREATE TABLE Version (
- VersionId INTEGER UNSIGNED NOT NULL
- );
-
--- Initialize Version
-INSERT INTO Version (VersionId) VALUES (8);
CREATE TABLE Counters (
Counter TINYBLOB NOT NULL,
PRIMARY KEY (MediaId)
);
+CREATE TABLE Version (
+ VersionId INTEGER UNSIGNED NOT NULL
+ );
+
+-- Initialize Version
+INSERT INTO Version (VersionId) VALUES (9);
END-OF-DATA
then
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)
);
primary key (counter)
);
-CREATE TABLE version
-(
- versionid integer not null
-);
-
-INSERT INTO Version (VersionId) VALUES (8);
CREATE TABLE basefiles
primary key (MediaId)
);
+
+CREATE TABLE version
+(
+ versionid integer not null
+);
+
+INSERT INTO Version (VersionId) VALUES (9);
+
-- Make sure we have appropriate permissions
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)
);
VersionId INTEGER UNSIGNED NOT NULL
);
--- Initialize Version
-INSERT INTO Version (VersionId) VALUES (8);
CREATE TABLE Counters (
Counter TEXT NOT NULL,
PRIMARY KEY (MediaId)
);
+-- Initialize Version
+INSERT INTO Version (VersionId) VALUES (9);
PRAGMA default_synchronous = OFF;
PRAGMA default_cache_size = 10000;
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)
);
VersionId INTEGER UNSIGNED NOT NULL
);
--- Initialize Version
-INSERT INTO Version (VersionId) VALUES (8);
CREATE TABLE Counters (
Counter TEXT NOT NULL,
PRIMARY KEY (MediaId)
);
+-- Initialize Version
+INSERT INTO Version (VersionId) VALUES (9);
PRAGMA default_synchronous = OFF;
PRAGMA default_cache_size = 10000;
/* 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"
/* 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)
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 {
/* 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);
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);
/* 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");
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);
}
"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 {
/*
* 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)
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);
}
/* 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 {
/*
* 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)
{
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);
}
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 {
/*
* 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);
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);
}
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 {
* 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)
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);
}
"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);
/*
* 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)
{
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);
}
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;
/*
* 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)
{
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 {
* 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)
{
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);
}
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;
/*
* 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 *
* };
*/
* 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;
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;
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);
}
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;
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);
}
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 {
/*
* 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
*
/* 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"
* (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)
{
/*
* Get a File record
* Returns: 0 on failure
- * 1 on success
+ * 1 on success
*
* DO NOT use Jmsg in this routine.
*
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 {
/* 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)
*/
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);
}
/* 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)
*/
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);
}
/*
* 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)
{
"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]);
/*
* 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
*/
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 {
/*
* 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
*/
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)) {
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);
}
* 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)
{
* 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[])
{
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;
* 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[])
{
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;
* 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)
{
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"));
}
* 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)
{
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);
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"));
}
* 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)
{
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 {
* 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)
{
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);
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 {
* 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)
{
* 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[])
{
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;
/* 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)
{
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,"
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;
/* 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"
* 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;
*/
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);
"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) {
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));
}
}
}
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));
*/
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,"
"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,"
"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)) {
/* 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"
/* 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];
* 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)
/*
* 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];
* 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)
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);
/*
* 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)
/*
* 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)
{
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',"
* 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)
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);
"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);
* 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)
"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);
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);
}
#!/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"
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,
PRIMARY KEY(DeviceId)
);
+DELETE FROM Version;
+INSERT INTO Version (VersionId) VALUES (9);
+
END-OF-DATA
then
echo "Update of Bacula MySQL tables succeeded."
#!/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"
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;
PRIMARY KEY(StorageId)
);
+DELETE FROM version;
+INSERT INTO version (versionId) VALUES (9);
+
vacuum;
END-OF-DATA
#!/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"
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,
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,
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,
DROP TABLE Pool_backup;
CREATE TABLE MediaType (
- MediaTypeId INTERGER,
+ MediaTypeId INTEGER,
MediaType VARCHAR(128) NOT NULL,
ReadOnly TINYINT DEFAULT 0,
PRIMARY KEY(MediaTypeId)
PRIMARY KEY(DeviceId)
);
+
+DELETE FROM Version;
+INSERT INTO Version (VersionId) VALUES (9);
+
COMMIT;
END-OF-DATA
#!/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"
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,
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,
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,
);
+DELETE FROM Version;
+INSERT INTO Version (VersionId) VALUES (9);
+
COMMIT;
END-OF-DATA
* This routine runs as a thread and must be thread reentrant.
*
* Basic tasks done here:
- * Handle Catalog services.
+ * Handle Catalog services.
*
* Version $Id$
*/
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 */
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");
*/
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);
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 */
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;
* 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");
}
*/
} 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 {
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);
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);
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));
+ }
}
}
}
*
* 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$
*/
"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";
/* 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 */
* 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();
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)) {
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;
/*
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);
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;
}
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) {
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);
{
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 */
}
/*
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)) {
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);
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);
" 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";
/* 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;
* 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)
{
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"));
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;
}
* 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)
{
/*
* 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)
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);
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");
/* 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);
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);
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);
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);
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);
* 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)
{
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;
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 */
}
/*
* 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)
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;
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 */
};
"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";
*/
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);
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);
/*
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);
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;
}
{
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);
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;
}
/*
* 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:
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 {
Dmsg1(100, ">dird: %s\n", dir->msg);
}
- return false; /* ERROR return */
+ return false; /* ERROR return */
}
#ifdef needed
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();
/* */
#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