From 859ba42e8791b51165cd871103f8687ec51d1862 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 2 Apr 2005 09:22:59 +0000 Subject: [PATCH] - 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. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1906 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ChangeLog | 545 ++++++++++++++++++++ bacula/ReleaseNotes | 6 +- bacula/src/cats/cats.h | 16 +- bacula/src/cats/make_mysql_tables.in | 14 +- bacula/src/cats/make_postgresql_tables.in | 16 +- bacula/src/cats/make_sqlite3_tables.in | 6 +- bacula/src/cats/make_sqlite_tables.in | 6 +- bacula/src/cats/sql_create.c | 346 +++++++------ bacula/src/cats/sql_get.c | 428 +++++++-------- bacula/src/cats/sql_list.c | 38 +- bacula/src/cats/sql_update.c | 70 +-- bacula/src/cats/update_mysql_tables.in | 9 +- bacula/src/cats/update_postgresql_tables.in | 11 +- bacula/src/cats/update_sqlite3_tables.in | 63 ++- bacula/src/cats/update_sqlite_tables.in | 60 ++- bacula/src/dird/catreq.c | 180 +++---- bacula/src/dird/msgchan.c | 84 +-- bacula/src/stored/askdir.c | 271 +++++----- bacula/src/stored/dev.h | 2 + bacula/src/stored/job.c | 265 +++++----- bacula/src/version.h | 6 +- 21 files changed, 1574 insertions(+), 868 deletions(-) diff --git a/bacula/ChangeLog b/bacula/ChangeLog index f2b320cca6..4bdbd37550 100644 --- a/bacula/ChangeLog +++ b/bacula/ChangeLog @@ -1,4 +1,549 @@ +Changes to 1.37.12: +02Apr05 +- Reset NumVols in Pool record from database on every update + Pool. +- Modify DB to support multiple simultaneous copies and + RAIT stiping. +- Pass copy and stripe between DIR and SD and put into + the JobMedia DB record. +- Update and test SQLite and MySQL datebase creation and + update scripts. +- Implement version 9 of the DB. +31Mar05 +- Convert more atoi to str_to_int64() for DB. +- Implement filling in NumVols by querying DB rather + than trying to keep track of it. +- Add storage name to string passed to in use storage= +- Fix newVolume() so that the Python script is always + called. +- Fix handling of pool,PoolId, and storage in ua_output. +- Same fix in ua_status.c +- Remove required locking of resources +- Replace pthread_cond_signal() by pthread_cond_broadcast() + hoping to fix the /lib/tls hang problems (lost signal). +- Move resource locking seaching from parse_conf.c to res.c + in src/lib. +- Modify end of volume handling so that fixup_... does not + redo what block.c has already done -- writing Vol info to + DIR. This fixes a bug with bad numbers of files on a tape + when it filled as reported by Peter. +- In release_device() do not update the DIR on the Volume + info if the the information was already written at the + end of the tape. +28Mar05 +- NOTE!!!! This version has a new DIR <--> SD protocol. Both + must be updated at the same time. +- Begin implementation of passing all the Storage and Device + possibilities to the SD for examination during the reserve + phase. +- Modify the reserve and acquire code in the SD to make a + job wait if the device is not available. +- Implement New Volume Each Job in DIR and pass to SD, not yet + used. +- Remove init/update of the Device resource in DIR +- Remove passing PoolId to SD and back. +26Mar05 +- Remove \a and -e from error echos in most Makefiles. +- Add more debug code when there are errors on the tape + to try to find Peter's tape problem. +- Add wait.c (oops forgot previously). +- Move all the reserve/acquire_device_for_read/append to have + only a DCR as the argument. +- Rework the reserve_device_for_append() in stored to wait + if the drive is not available. Note! This is a short + term solution. +25Mar05 +- Comment out Multiple Connections in the document. +- Move the P() and V() to subroutines so that they can be accessed + from class methods. The reference to strerror() caused problems. +- Implement new DEVICE class methods block() and unblock() that + do what was previously done in 3 lines of code. +- Implement wait_for_device(), which will wait for any device + to be released then return. This requires a new global mutex + and condition variable, and is implemented in src/stored/wait.c +- Change the code in reserve_device_for_read(), which previously + failed the job to use the new device wait code. +22Mar05 +- Apply reschedule patch to 1.37 code. +- Add copyright to title page of manual so it is clear. +- Create patch for rescheduling problem found by Ludovic. Storage + pointers were lost during rescheduling. +- Attempt to fix 2.6 rescue disk -- failed! +- Start working on adding a wait routine in the SD. +- Cleanup some old invalid doc in watchdog. +- Convert a number of references to dev->dev_name to dev->print_name(). +- Add new wait.c file to SD. +- Add a few more methods to DEVICE in SD to cleanup code a + bit -- implement a few of the methods. +18Mar05 +- Fix more print_name()s for printing device name. +- Modify open_dev to try 10 times every 6 seconds to + open the device if it gets an I/O error (meaning no + volume mounted). This gives a bit of settling in time + for an autochanger and avoids spurious messages. +- Change all yes/no to yes|no in the manual. +- Fix win32 create_file.c typo. +- Fix a typo in an error message. +17Mar05 +- Detect if fseeko exists with autoconf. If so, use it + and ftello. +- Remove old bacula-*.conf from examples directory (out + of date). +- Remove latex-fr index files from CVS. +- Rewrite code that stops reading the tape so that the + tape is marked at EOT, then once the work is done, + the EOT flag is removed. +- Flush output to file after every send in console. +- Make setting VolFiles to smaller number fatal. +- Disable Multiple Connections code. +- Add patch from user for NetBSD statvsfs() fix to + fstype.c +- Take more care with errors in acquire.c +- Don't run through dvd code in append.c if bad status + returned. +- Modify code so that an autochanger fault is fatal. +- Use dev->print_name() in more places. +- Implement dev->can_steal_lock() to simplify code. +- Make btape re-read first 10000 records on fill command. +- Check error return and fail job from fseeko and ftello + in spool.c. Don't let a -1 slip in as size. + +Changes to 1.37.7: +15Mar05 +- Apply NetBSD patch from kardel in bug 258. +14Mar05 +- Add a second job and a second client to the default + bacula-dir.conf file. +- Remove old style Include/Excludes. +- Fix ANSI labels to put EOF1 and EOF2 after each file mark. +- Add Python to SD and FD. +12Mar05 +- Implement IBM labels +- Implement EOF and EOV labels at the end of a volume. +- Fix a rather ugly problem with the PoolId not getting + passed correctly. Now the DIR passes the Pool name and + Media Type to the SD, who passes them back when requesting + the next Volume. The DIR then looks up the correct PoolId. + This takes more time, but always works, AND allows wild + card Media Types (i.e. the SD can decide). +- The DIR <==> SD protocol has changed. + +Changes to 1.37.6: +11Mar05 +- Fix scanf of PoolId in catreq to handle 64 bit Ids. +10Mar05 +- Add new ua_update.c file and move update_cmd there. +- Modify "update slots" to obtain actual number of slots. +- Tweak autochanger code to handle new slots request. +- Modify autochanger code to lock/unlock around slots and + update slots code. +09Mar05 +- Patch the FD so that it does not issue an error message if + it attempts to restore the permissions on a Win32 drive. +- Edit "Resource-name" (physical-name) for the device name + everywhere in the SD. +- Remove .linked.tex files in preparation for cutover to + using .tex in place of .wml. +08Mar05 +- Copy latest config.sub and config.guess from autoconf. +- Try new way of identifying drives with: + "resource-name" (physical-name) + More work need to a complete conversion. +07Mar05 +- Rework some of the autochanger data so that the DIR has + the number of drives. +- Modify the way the Device info is returned so that it comes + back as a special message type and can be sent anytime the + Device status changes. +- Copy the change name and changer command into the device + record if none is specified. +- Require the change command and changer name to be specified in + and AutoChanger resource. +- Force all the Media Type records of all devices in an Autochanger + to be the same. +06Mar05 +- Add new "run" command to Job resource in DIR. This permits + cloning a job as many times as you want. +- Pass PoolId to SD on Query request. It is now used in the + Find_media catalog request. +- Reworked the Device resource in the DIR. Eliminated num_waiting + and use_count, but added max_writers, reserved, and PoolId. +- This DIR is nolonger compatible with previous SDs. +- Add since and cloned keywords to the Console run command + to support cloning. +- Implemented store_alist_str() to allow multiple string items + to be specified in a .conf file. +- Added %s (since time) to Job code editing. +- Reworked reserving drives in the SD. It now does it much simpler + and correctly. +05Mar05 +- Integrate HP-UX patch from Olivier Mehani +- 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 + 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 + 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 '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 + 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 + alist fix patch. +- Remove duplicate code from chksum.h (mentioned by Preben). +13Dec04 +- Integrate Tim Oberfoell patch to ACLs + to handle both the "standard" and "default" ACLs. +12Dec04 +- Integrated Preben 'Peppe' Guldberg + three cleanup patches (btest, verify, find). +- Integrated Preben 'Peppe' Guldberg + three cleanup patches (backup, chksum, and verify) +09Dec04 +- Integrated Preben 'Peppe' Guldberg + patch to avoid doing MTIOCGET on OSes that do not support + it such as OpenBSD. +- Integrated Preben 'Peppe' Guldberg + patch to add filesystem type matching to FileSets in the + Options resource. +- Integrated Preben 'Peppe' Guldberg + 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 + 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 + 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 +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) diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index 9d61aa680a..1a4d135ef3 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -1,8 +1,10 @@ - Release Notes for Bacula 1.37.10 + Release Notes for Bacula 1.37.12 - Bacula code: Total files = 414 Total lines = 123,723 (*.h *.c *.in) + Bacula code: Total files = 419 Total lines = 124,877 (*.h *.c *.in) +Note! The DB has been upgraded from version 8 to 9 and requres +a DB upgrade. Major Changes: - This version has a new DIR <--> SD protocol. Both must be diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 90f99df892..a941cb25d4 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -73,7 +73,7 @@ typedef int (DB_RESULT_HANDLER)(void *, int, char **); #ifdef HAVE_SQLITE -#define BDB_VERSION 8 +#define BDB_VERSION 9 #include @@ -181,7 +181,7 @@ SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb); #ifdef HAVE_SQLITE3 -#define BDB_VERSION 8 +#define BDB_VERSION 9 #include @@ -296,7 +296,7 @@ SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb); #ifdef HAVE_MYSQL -#define BDB_VERSION 8 +#define BDB_VERSION 9 #include @@ -360,13 +360,13 @@ typedef struct s_db { #ifdef HAVE_POSTGRESQL -#define BDB_VERSION 8 +#define BDB_VERSION 9 #include /* TEMP: the following is taken from select OID, typname from pg_type; */ -#define IS_NUM(x) ((x) == 20 || (x) == 21 || (x) == 23 || (x) == 700 || (x) == 701) -#define IS_NOT_NULL(x) ((x) == 1) +#define IS_NUM(x) ((x) == 20 || (x) == 21 || (x) == 23 || (x) == 700 || (x) == 701) +#define IS_NOT_NULL(x) ((x) == 1) typedef char **POSTGRESQL_ROW; typedef struct pg_field { @@ -583,6 +583,8 @@ struct JOBMEDIA_DBR { uint32_t EndFile; /* End file on Volume */ uint32_t StartBlock; /* start block on tape */ uint32_t EndBlock; /* last block */ + uint32_t Copy; /* identical copy */ + uint32_t Stripe; /* RAIT strip number */ }; @@ -597,6 +599,8 @@ struct VOL_PARAMS { uint32_t EndFile; /* End file on Volume */ uint32_t StartBlock; /* start block on tape */ uint32_t EndBlock; /* last block */ + uint32_t Copy; /* identical copy */ + uint32_t Stripe; /* RAIT strip number */ }; diff --git a/bacula/src/cats/make_mysql_tables.in b/bacula/src/cats/make_mysql_tables.in index 677b65d198..19e898c037 100644 --- a/bacula/src/cats/make_mysql_tables.in +++ b/bacula/src/cats/make_mysql_tables.in @@ -126,6 +126,8 @@ CREATE TABLE JobMedia ( StartBlock INTEGER UNSIGNED NOT NULL DEFAULT 0, EndBlock INTEGER UNSIGNED NOT NULL DEFAULT 0, VolIndex INTEGER UNSIGNED NOT NULL DEFAULT 0, + Copy INTEGER UNSIGNED NOT NULL DEFAULT 0, + Stripe INTEGER UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY(JobMediaId), INDEX (JobId, MediaId) ); @@ -232,12 +234,6 @@ CREATE TABLE UnsavedFiles ( ); -CREATE TABLE Version ( - VersionId INTEGER UNSIGNED NOT NULL - ); - --- Initialize Version -INSERT INTO Version (VersionId) VALUES (8); CREATE TABLE Counters ( Counter TINYBLOB NOT NULL, @@ -254,6 +250,12 @@ CREATE TABLE CDImages ( PRIMARY KEY (MediaId) ); +CREATE TABLE Version ( + VersionId INTEGER UNSIGNED NOT NULL + ); + +-- Initialize Version +INSERT INTO Version (VersionId) VALUES (9); END-OF-DATA then diff --git a/bacula/src/cats/make_postgresql_tables.in b/bacula/src/cats/make_postgresql_tables.in index f990fdcecc..8035656587 100644 --- a/bacula/src/cats/make_postgresql_tables.in +++ b/bacula/src/cats/make_postgresql_tables.in @@ -99,6 +99,8 @@ CREATE TABLE jobmedia startblock bigint not null default 0, endblock bigint not null default 0, volindex integer not null default 0, + copy integer not null default 0, + stripe integer not null default 0, primary key (jobmediaid) ); @@ -237,12 +239,6 @@ CREATE TABLE counters primary key (counter) ); -CREATE TABLE version -( - versionid integer not null -); - -INSERT INTO Version (VersionId) VALUES (8); CREATE TABLE basefiles @@ -271,6 +267,14 @@ CREATE TABLE CDImages primary key (MediaId) ); + +CREATE TABLE version +( + versionid integer not null +); + +INSERT INTO Version (VersionId) VALUES (9); + -- Make sure we have appropriate permissions diff --git a/bacula/src/cats/make_sqlite3_tables.in b/bacula/src/cats/make_sqlite3_tables.in index 83dfb0e117..6735135cb1 100644 --- a/bacula/src/cats/make_sqlite3_tables.in +++ b/bacula/src/cats/make_sqlite3_tables.in @@ -92,6 +92,8 @@ CREATE TABLE JobMedia ( StartBlock INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, VolIndex INTEGER UNSIGNED DEFAULT 0, + Copy INTEGER UNSIGNED DEFAULT 0, + Stripe INTEGER UNSIGNED DEFAULT 0, PRIMARY KEY(JobMediaId) ); @@ -242,8 +244,6 @@ CREATE TABLE Version ( VersionId INTEGER UNSIGNED NOT NULL ); --- Initialize Version -INSERT INTO Version (VersionId) VALUES (8); CREATE TABLE Counters ( Counter TEXT NOT NULL, @@ -260,6 +260,8 @@ CREATE TABLE CDImages ( PRIMARY KEY (MediaId) ); +-- Initialize Version +INSERT INTO Version (VersionId) VALUES (9); PRAGMA default_synchronous = OFF; PRAGMA default_cache_size = 10000; diff --git a/bacula/src/cats/make_sqlite_tables.in b/bacula/src/cats/make_sqlite_tables.in index 83dfb0e117..6735135cb1 100644 --- a/bacula/src/cats/make_sqlite_tables.in +++ b/bacula/src/cats/make_sqlite_tables.in @@ -92,6 +92,8 @@ CREATE TABLE JobMedia ( StartBlock INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, VolIndex INTEGER UNSIGNED DEFAULT 0, + Copy INTEGER UNSIGNED DEFAULT 0, + Stripe INTEGER UNSIGNED DEFAULT 0, PRIMARY KEY(JobMediaId) ); @@ -242,8 +244,6 @@ CREATE TABLE Version ( VersionId INTEGER UNSIGNED NOT NULL ); --- Initialize Version -INSERT INTO Version (VersionId) VALUES (8); CREATE TABLE Counters ( Counter TEXT NOT NULL, @@ -260,6 +260,8 @@ CREATE TABLE CDImages ( PRIMARY KEY (MediaId) ); +-- Initialize Version +INSERT INTO Version (VersionId) VALUES (9); PRAGMA default_synchronous = OFF; PRAGMA default_cache_size = 10000; diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 8fe07996aa..3c3590c7a6 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -29,7 +29,7 @@ /* The following is necessary so that we do not include * the dummy external definition of DB. */ -#define __SQL_C /* indicate that this is sql.c */ +#define __SQL_C /* indicate that this is sql.c */ #include "bacula.h" #include "cats.h" @@ -60,7 +60,7 @@ extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname); /* Create a new record for the Job * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) @@ -85,12 +85,12 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) Mmsg(mdb->cmd, "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate) VALUES " "('%s','%s','%c','%c','%c','%s',%s)", - jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel), - (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1)); + jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel), + (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1)); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); jr->JobId = 0; stat = 0; } else { @@ -103,13 +103,14 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) /* Create a JobMedia record for medium used this job * Returns: false on failure - * true on success + * true on success */ bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm) { bool ok = true;; int count; + char ed1[50], ed2[50]; db_lock(mdb); @@ -123,25 +124,28 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm) Mmsg(mdb->cmd, "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex," - "StartFile,EndFile,StartBlock,EndBlock,VolIndex) " - "VALUES (%u,%u,%u,%u,%u,%u,%u,%u,%u)", - jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex, - jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count); + "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy,Stripe) " + "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u,%u)", + edit_int64(jm->JobId, ed1), + edit_int64(jm->MediaId, ed2), + jm->FirstIndex, jm->LastIndex, + jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count, + jm->Copy, jm->Stripe); Dmsg0(300, mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd, - sql_strerror(mdb)); + sql_strerror(mdb)); ok = false; } else { /* Worked, now update the Media record with the EndFile and EndBlock */ Mmsg(mdb->cmd, "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u", - jm->EndFile, jm->EndBlock, jm->MediaId); + jm->EndFile, jm->EndBlock, jm->MediaId); if (!UPDATE_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd, - sql_strerror(mdb)); - ok = false; + sql_strerror(mdb)); + ok = false; } } db_unlock(mdb); @@ -153,12 +157,12 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm) /* Create Unique Pool record * Returns: false on failure - * true on success + * true on success */ bool db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) { - bool stat; + bool stat; char ed1[30], ed2[30], ed3[50]; Dmsg0(200, "In create pool\n"); @@ -170,9 +174,9 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 0) { Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name); - sql_free_result(mdb); - db_unlock(mdb); - return false; + sql_free_result(mdb); + db_unlock(mdb); + return false; } sql_free_result(mdb); } @@ -183,20 +187,20 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration," "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) " "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')", - pr->Name, - pr->NumVols, pr->MaxVols, - pr->UseOnce, pr->UseCatalog, - pr->AcceptAnyVolume, - pr->AutoPrune, pr->Recycle, - edit_uint64(pr->VolRetention, ed1), - edit_uint64(pr->VolUseDuration, ed2), - pr->MaxVolJobs, pr->MaxVolFiles, - edit_uint64(pr->MaxVolBytes, ed3), - pr->PoolType, pr->LabelType, pr->LabelFormat); + pr->Name, + pr->NumVols, pr->MaxVols, + pr->UseOnce, pr->UseCatalog, + pr->AcceptAnyVolume, + pr->AutoPrune, pr->Recycle, + edit_uint64(pr->VolRetention, ed1), + edit_uint64(pr->VolUseDuration, ed2), + pr->MaxVolJobs, pr->MaxVolFiles, + edit_uint64(pr->MaxVolBytes, ed3), + pr->PoolType, pr->LabelType, pr->LabelFormat); Dmsg1(200, "Create Pool: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); pr->PoolId = 0; stat = false; } else { @@ -210,7 +214,7 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) /* * Create Unique Device record * Returns: false on failure - * true on success + * true on success */ bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr) @@ -227,9 +231,9 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 0) { Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name); - sql_free_result(mdb); - db_unlock(mdb); - return false; + sql_free_result(mdb); + db_unlock(mdb); + return false; } sql_free_result(mdb); } @@ -237,13 +241,13 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr) /* Must create it */ Mmsg(mdb->cmd, "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)", - dr->Name, - edit_uint64(dr->MediaTypeId, ed1), - edit_int64(dr->StorageId, ed2)); + dr->Name, + edit_uint64(dr->MediaTypeId, ed1), + edit_int64(dr->StorageId, ed2)); Dmsg1(200, "Create Device: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); dr->DeviceId = 0; ok = false; } else { @@ -259,7 +263,7 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr) /* * Create a Unique record for Storage -- no duplicates * Returns: false on failure - * true on success with id in sr->StorageId + * true on success with id in sr->StorageId */ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) { @@ -279,18 +283,18 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - sql_free_result(mdb); - db_unlock(mdb); - return false; - } - sr->StorageId = str_to_int64(row[0]); - sr->AutoChanger = atoi(row[1]); /* bool */ - sql_free_result(mdb); - db_unlock(mdb); - return true; + sql_free_result(mdb); + db_unlock(mdb); + return false; + } + sr->StorageId = str_to_int64(row[0]); + sr->AutoChanger = atoi(row[1]); /* bool */ + sql_free_result(mdb); + db_unlock(mdb); + return true; } sql_free_result(mdb); } @@ -301,7 +305,7 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); ok = false; } else { @@ -317,12 +321,12 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) /* * Create Unique MediaType record * Returns: false on failure - * true on success + * true on success */ bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr) { - bool stat; + bool stat; Dmsg0(200, "In create mediatype\n"); db_lock(mdb); @@ -333,9 +337,9 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 0) { Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType); - sql_free_result(mdb); - db_unlock(mdb); - return false; + sql_free_result(mdb); + db_unlock(mdb); + return false; } sql_free_result(mdb); } @@ -344,12 +348,12 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr) Mmsg(mdb->cmd, "INSERT INTO MediaType (MediaType,ReadOnly) " "VALUES ('%s',%d)", - mr->MediaType, - mr->ReadOnly); + mr->MediaType, + mr->ReadOnly); Dmsg1(200, "Create mediatype: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); mr->MediaTypeId = 0; stat = false; } else { @@ -365,7 +369,7 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr) * Create Media record. VolumeName and non-zero Slot must be unique * * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) @@ -376,16 +380,16 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) db_lock(mdb); Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'", - mr->VolumeName); + mr->VolumeName); Dmsg1(300, "selectpool: %s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 0) { Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName); - sql_free_result(mdb); - db_unlock(mdb); - return 0; + sql_free_result(mdb); + db_unlock(mdb); + return 0; } sql_free_result(mdb); } @@ -397,51 +401,51 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts," "EndFile,EndBlock,LabelType,StorageId) " "VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s)", - mr->VolumeName, - mr->MediaType, mr->PoolId, - edit_uint64(mr->MaxVolBytes,ed1), - edit_uint64(mr->VolCapacityBytes, ed2), - mr->Recycle, - edit_uint64(mr->VolRetention, ed3), - edit_uint64(mr->VolUseDuration, ed4), - mr->MaxVolJobs, - mr->MaxVolFiles, - mr->VolStatus, - mr->Slot, - edit_uint64(mr->VolBytes, ed5), - mr->InChanger, - edit_uint64(mr->VolReadTime, ed6), - edit_uint64(mr->VolWriteTime, ed7), - mr->VolParts, - mr->LabelType, - edit_int64(mr->StorageId, ed8) - ); + mr->VolumeName, + mr->MediaType, mr->PoolId, + edit_uint64(mr->MaxVolBytes,ed1), + edit_uint64(mr->VolCapacityBytes, ed2), + mr->Recycle, + edit_uint64(mr->VolRetention, ed3), + edit_uint64(mr->VolUseDuration, ed4), + mr->MaxVolJobs, + mr->MaxVolFiles, + mr->VolStatus, + mr->Slot, + edit_uint64(mr->VolBytes, ed5), + mr->InChanger, + edit_uint64(mr->VolReadTime, ed6), + edit_uint64(mr->VolWriteTime, ed7), + mr->VolParts, + mr->LabelType, + edit_int64(mr->StorageId, ed8) + ); Dmsg1(500, "Create Volume: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); stat = 0; } else { mr->MediaId = sql_insert_id(mdb, _("Media")); stat = 1; if (mr->set_label_date) { - char dt[MAX_TIME_LENGTH]; - if (mr->LabelDate == 0) { - mr->LabelDate = time(NULL); - } - localtime_r(&mr->LabelDate, &tm); + char dt[MAX_TIME_LENGTH]; + if (mr->LabelDate == 0) { + mr->LabelDate = time(NULL); + } + localtime_r(&mr->LabelDate, &tm); strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm); Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' " "WHERE MediaId=%d", dt, mr->MediaId); - stat = UPDATE_DB(jcr, mdb, mdb->cmd); + stat = UPDATE_DB(jcr, mdb, mdb->cmd); } } /* * Make sure that if InChanger is non-zero any other identical slot - * has InChanger zero. + * has InChanger zero. */ db_make_inchanger_unique(jcr, mdb, mr); @@ -452,7 +456,7 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) /* * Create a Unique record for the client -- no duplicates * Returns: 0 on failure - * 1 on success with id in cr->ClientId + * 1 on success with id in cr->ClientId */ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) { @@ -472,22 +476,22 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - sql_free_result(mdb); - db_unlock(mdb); - return 0; - } - cr->ClientId = str_to_int64(row[0]); - if (row[1]) { - bstrncpy(cr->Uname, row[1], sizeof(cr->Uname)); - } else { - cr->Uname[0] = 0; /* no name */ - } - sql_free_result(mdb); - db_unlock(mdb); - return 1; + sql_free_result(mdb); + db_unlock(mdb); + return 0; + } + cr->ClientId = str_to_int64(row[0]); + if (row[1]) { + bstrncpy(cr->Uname, row[1], sizeof(cr->Uname)); + } else { + cr->Uname[0] = 0; /* no name */ + } + sql_free_result(mdb); + db_unlock(mdb); + return 1; } sql_free_result(mdb); } @@ -501,7 +505,7 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); cr->ClientId = 0; stat = 0; @@ -520,7 +524,7 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) /* * Create a Unique record for the counter -- no duplicates * Returns: 0 on failure - * 1 on success with counter filled in + * 1 on success with counter filled in */ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) { @@ -544,7 +548,7 @@ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; } else { @@ -559,7 +563,7 @@ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) * Create a FileSet record. This record is unique in the * name and the MD5 signature of the include/exclude sets. * Returns: 0 on failure - * 1 on success with FileSetId in record + * 1 on success with FileSetId in record */ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) { @@ -580,22 +584,22 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - sql_free_result(mdb); - db_unlock(mdb); - return false; - } - fsr->FileSetId = str_to_int64(row[0]); - if (row[1] == NULL) { - fsr->cCreateTime[0] = 0; - } else { - bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime)); - } - sql_free_result(mdb); - db_unlock(mdb); - return true; + sql_free_result(mdb); + db_unlock(mdb); + return false; + } + fsr->FileSetId = str_to_int64(row[0]); + if (row[1] == NULL) { + fsr->cCreateTime[0] = 0; + } else { + bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime)); + } + sql_free_result(mdb); + db_unlock(mdb); + return true; } sql_free_result(mdb); } @@ -612,7 +616,7 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); fsr->FileSetId = 0; stat = false; @@ -630,19 +634,19 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) /* * struct stat * { - * dev_t st_dev; * device * - * ino_t st_ino; * inode * - * mode_t st_mode; * protection * - * nlink_t st_nlink; * number of hard links * - * uid_t st_uid; * user ID of owner * - * gid_t st_gid; * group ID of owner * - * dev_t st_rdev; * device type (if inode device) * - * off_t st_size; * total size, in bytes * - * unsigned long st_blksize; * blocksize for filesystem I/O * - * unsigned long st_blocks; * number of blocks allocated * - * time_t st_atime; * time of last access * - * time_t st_mtime; * time of last modification * - * time_t st_ctime; * time of last inode change * + * dev_t st_dev; * device * + * ino_t st_ino; * inode * + * mode_t st_mode; * protection * + * nlink_t st_nlink; * number of hard links * + * uid_t st_uid; * user ID of owner * + * gid_t st_gid; * group ID of owner * + * dev_t st_rdev; * device type (if inode device) * + * off_t st_size; * total size, in bytes * + * unsigned long st_blksize; * blocksize for filesystem I/O * + * unsigned long st_blocks; * number of blocks allocated * + * time_t st_atime; * time of last access * + * time_t st_mtime; * time of last modification * + * time_t st_ctime; * time of last inode change * * }; */ @@ -667,7 +671,7 @@ int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) * Make sure we have an acceptable attributes record. */ if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES || - ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) { + ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) { Mmsg0(&mdb->errmsg, _("Attempt to put non-attributes into catalog\n")); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); goto bail_out; @@ -718,12 +722,12 @@ static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) Mmsg(mdb->cmd, "INSERT INTO File (FileIndex,JobId,PathId,FilenameId," "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')", - ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, - ar->attr); + ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, + ar->attr); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); ar->FileId = 0; stat = 0; @@ -754,31 +758,31 @@ static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - char ed1[30]; + char ed1[30]; Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"), - edit_uint64(mdb->num_rows, ed1), mdb->path); + edit_uint64(mdb->num_rows, ed1), mdb->path); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } /* Even if there are multiple paths, take the first one */ if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - sql_free_result(mdb); - ar->PathId = 0; - ASSERT(ar->PathId); - return 0; - } - ar->PathId = str_to_int64(row[0]); - sql_free_result(mdb); - /* Cache path */ - if (ar->PathId != mdb->cached_path_id) { - mdb->cached_path_id = ar->PathId; - mdb->cached_path_len = mdb->pnl; - pm_strcpy(mdb->cached_path, mdb->path); - } - ASSERT(ar->PathId); - return 1; + sql_free_result(mdb); + ar->PathId = 0; + ASSERT(ar->PathId); + return 0; + } + ar->PathId = str_to_int64(row[0]); + sql_free_result(mdb); + /* Cache path */ + if (ar->PathId != mdb->cached_path_id) { + mdb->cached_path_id = ar->PathId; + mdb->cached_path_len = mdb->pnl; + pm_strcpy(mdb->cached_path, mdb->path); + } + ASSERT(ar->PathId); + return 1; } sql_free_result(mdb); } @@ -787,7 +791,7 @@ static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); ar->PathId = 0; stat = 0; @@ -818,22 +822,22 @@ static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - char ed1[30]; + char ed1[30]; Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"), - edit_uint64(mdb->num_rows, ed1), mdb->fname); + edit_uint64(mdb->num_rows, ed1), mdb->fname); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"), - mdb->fname, sql_strerror(mdb)); + mdb->fname, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - ar->FilenameId = 0; - } else { - ar->FilenameId = str_to_int64(row[0]); - } - sql_free_result(mdb); - return ar->FilenameId > 0; + ar->FilenameId = 0; + } else { + ar->FilenameId = str_to_int64(row[0]); + } + sql_free_result(mdb); + return ar->FilenameId > 0; } sql_free_result(mdb); } @@ -842,7 +846,7 @@ static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"), - mdb->cmd, sql_strerror(mdb)); + mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); ar->FilenameId = 0; } else { diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 78d0f13400..596adc6312 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -1,8 +1,8 @@ /* * Bacula Catalog Database Get record interface routines * Note, these routines generally get a record by id or - * by name. If more logic is involved, the routine - * should be in find.c + * by name. If more logic is involved, the routine + * should be in find.c * * Kern Sibbald, March 2000 * @@ -33,7 +33,7 @@ /* The following is necessary so that we do not include * the dummy external definition of DB. */ -#define __SQL_C /* indicate that this is sql.c */ +#define __SQL_C /* indicate that this is sql.c */ #include "bacula.h" #include "cats.h" @@ -65,7 +65,7 @@ extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname); * (with attributes) in the database. * * Returns: 0 on failure - * 1 on success with the File record in FILE_DBR + * 1 on success with the File record in FILE_DBR */ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr) { @@ -90,7 +90,7 @@ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, /* * Get a File record * Returns: 0 on failure - * 1 on success + * 1 on success * * DO NOT use Jmsg in this routine. * @@ -133,21 +133,21 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr) Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows); if (mdb->num_rows > 1) { Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"), - mdb->num_rows); + mdb->num_rows); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb)); - } else { - fdbr->FileId = (FileId_t)str_to_int64(row[0]); - bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat)); - bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG)); - stat = 1; - } + } else { + fdbr->FileId = (FileId_t)str_to_int64(row[0]); + bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat)); + bstrncpy(fdbr->SIG, row[2], sizeof(fdbr->SIG)); + stat = 1; + } } else { Mmsg2(&mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"), - edit_int64(fdbr->PathId, ed1), - edit_int64(fdbr->FilenameId, ed2)); + edit_int64(fdbr->PathId, ed1), + edit_int64(fdbr->FilenameId, ed2)); } sql_free_result(mdb); } else { @@ -159,7 +159,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr) /* Get Filename record * Returns: 0 on failure - * FilenameId on success + * FilenameId on success * * DO NOT use Jmsg in this routine (see notes for get_file_record) */ @@ -177,20 +177,20 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { Mmsg2(&mdb->errmsg, _("More than one Filename!: %s for file: %s\n"), - edit_uint64(mdb->num_rows, ed1), mdb->fname); + edit_uint64(mdb->num_rows, ed1), mdb->fname); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); - } else { - FilenameId = str_to_int64(row[0]); - if (FilenameId <= 0) { + } else { + FilenameId = str_to_int64(row[0]); + if (FilenameId <= 0) { Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"), - mdb->cmd, FilenameId); - FilenameId = 0; - } - } + mdb->cmd, FilenameId); + FilenameId = 0; + } + } } else { Mmsg1(&mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname); } @@ -203,7 +203,7 @@ static int db_get_filename_record(JCR *jcr, B_DB *mdb) /* Get path record * Returns: 0 on failure - * PathId on success + * PathId on success * * DO NOT use Jmsg in this routine (see notes for get_file_record) */ @@ -227,28 +227,28 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"), - edit_uint64(mdb->num_rows, ed1), mdb->path); + edit_uint64(mdb->num_rows, ed1), mdb->path); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } /* Even if there are multiple paths, take the first one */ if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); - } else { - PathId = str_to_int64(row[0]); - if (PathId <= 0) { + } else { + PathId = str_to_int64(row[0]); + if (PathId <= 0) { Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %s\n"), - mdb->cmd, edit_int64(PathId, ed1)); - PathId = 0; - } else { - /* Cache path */ - if (PathId != mdb->cached_path_id) { - mdb->cached_path_id = PathId; - mdb->cached_path_len = mdb->pnl; - pm_strcpy(&mdb->cached_path, mdb->path); - } - } - } + mdb->cmd, edit_int64(PathId, ed1)); + PathId = 0; + } else { + /* Cache path */ + if (PathId != mdb->cached_path_id) { + mdb->cached_path_id = PathId; + mdb->cached_path_len = mdb->pnl; + pm_strcpy(&mdb->cached_path, mdb->path); + } + } + } } else { Mmsg1(&mdb->errmsg, _("Path record: %s not found.\n"), mdb->path); } @@ -263,7 +263,7 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb) /* * Get Job record for given JobId or Job name * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { @@ -281,18 +281,18 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus," "Type,Level,ClientId " "FROM Job WHERE JobId=%s", - edit_int64(jr->JobId, ed1)); + edit_int64(jr->JobId, ed1)); } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); - return 0; /* failed */ + return 0; /* failed */ } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1)); sql_free_result(mdb); db_unlock(mdb); - return 0; /* failed */ + return 0; /* failed */ } jr->VolSessionId = str_to_uint64(row[0]); @@ -317,10 +317,10 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) /* * Find VolumeNames for a given JobId * Returns: 0 on error or no Volumes found - * number of volumes on success - * Volumes are concatenated in VolumeNames - * separated by a vertical bar (|) in the order - * that they were written. + * number of volumes on success + * Volumes are concatenated in VolumeNames + * separated by a vertical bar (|) in the order + * that they were written. * * Returns: number of volumes on success */ @@ -346,22 +346,22 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume Dmsg1(130, "Num rows=%d\n", mdb->num_rows); if (mdb->num_rows <= 0) { Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); - stat = 0; + stat = 0; } else { - stat = mdb->num_rows; - for (i=0; i < stat; i++) { - if ((row = sql_fetch_row(mdb)) == NULL) { + stat = mdb->num_rows; + for (i=0; i < stat; i++) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - stat = 0; - break; - } else { - if (*VolumeNames[0] != 0) { + stat = 0; + break; + } else { + if (*VolumeNames[0] != 0) { pm_strcat(VolumeNames, "|"); - } - pm_strcat(VolumeNames, row[0]); - } - } + } + pm_strcat(VolumeNames, row[0]); + } + } } sql_free_result(mdb); } else { @@ -374,8 +374,8 @@ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **Volume /* * Find Volume parameters for a give JobId * Returns: 0 on error or no Volumes found - * number of volumes on success - * List of Volumes and start/end file/blocks (malloced structure!) + * number of volumes on success + * List of Volumes and start/end file/blocks (malloced structure!) * * Returns: number of volumes on success */ @@ -390,10 +390,10 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS db_lock(mdb); Mmsg(mdb->cmd, "SELECT VolumeName,MediaType,FirstIndex,LastIndex,StartFile," -"JobMedia.EndFile,StartBlock,JobMedia.EndBlock" +"JobMedia.EndFile,StartBlock,JobMedia.EndBlock,Copy,Stripe" " FROM JobMedia,Media WHERE JobMedia.JobId=%s" " AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId", - edit_int64(JobId, ed1)); + edit_int64(JobId, ed1)); Dmsg1(130, "VolNam=%s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { @@ -401,29 +401,31 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS Dmsg1(130, "Num rows=%d\n", mdb->num_rows); if (mdb->num_rows <= 0) { Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); - stat = 0; + stat = 0; } else { - stat = mdb->num_rows; - if (stat > 0) { - *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS)); - } - for (i=0; i < stat; i++) { - if ((row = sql_fetch_row(mdb)) == NULL) { + stat = mdb->num_rows; + if (stat > 0) { + *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS)); + } + for (i=0; i < stat; i++) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - stat = 0; - break; - } else { - bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH); - bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH); - Vols[i].FirstIndex = str_to_uint64(row[2]); - Vols[i].LastIndex = str_to_uint64(row[3]); - Vols[i].StartFile = str_to_uint64(row[4]); - Vols[i].EndFile = str_to_uint64(row[5]); - Vols[i].StartBlock = str_to_uint64(row[6]); - Vols[i].EndBlock = str_to_uint64(row[7]); - } - } + stat = 0; + break; + } else { + bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH); + bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH); + Vols[i].FirstIndex = str_to_uint64(row[2]); + Vols[i].LastIndex = str_to_uint64(row[3]); + Vols[i].StartFile = str_to_uint64(row[4]); + Vols[i].EndFile = str_to_uint64(row[5]); + Vols[i].StartBlock = str_to_uint64(row[6]); + Vols[i].EndBlock = str_to_uint64(row[7]); + Vols[i].Copy = str_to_uint64(row[8]); + Vols[i].Stripe = str_to_uint64(row[9]); + } + } } sql_free_result(mdb); } @@ -437,7 +439,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS * Get the number of pool records * * Returns: -1 on failure - * number on success + * number on success */ int db_get_num_pool_records(JCR *jcr, B_DB *mdb) { @@ -455,7 +457,7 @@ int db_get_num_pool_records(JCR *jcr, B_DB *mdb) * The caller must free ids if non-NULL. * * Returns 0: on failure - * 1: on success + * 1: on success */ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) { @@ -470,11 +472,11 @@ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) if (QUERY_DB(jcr, mdb, mdb->cmd)) { *num_ids = sql_num_rows(mdb); if (*num_ids > 0) { - id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); - while ((row = sql_fetch_row(mdb)) != NULL) { - id[i++] = str_to_uint64(row[0]); - } - *ids = id; + id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); + while ((row = sql_fetch_row(mdb)) != NULL) { + id[i++] = str_to_uint64(row[0]); + } + *ids = id; } sql_free_result(mdb); stat = 1; @@ -492,7 +494,7 @@ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) * The caller must free ids if non-NULL. * * Returns 0: on failure - * 1: on success + * 1: on success */ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) { @@ -507,11 +509,11 @@ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) if (QUERY_DB(jcr, mdb, mdb->cmd)) { *num_ids = sql_num_rows(mdb); if (*num_ids > 0) { - id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); - while ((row = sql_fetch_row(mdb)) != NULL) { - id[i++] = str_to_uint64(row[0]); - } - *ids = id; + id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); + while ((row = sql_fetch_row(mdb)) != NULL) { + id[i++] = str_to_uint64(row[0]); + } + *ids = id; } sql_free_result(mdb); stat = 1; @@ -531,7 +533,7 @@ int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) * otherwise, we search on the PoolName * * Returns: false on failure - * true on success + * true on success */ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) { @@ -540,51 +542,51 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) char ed1[50]; db_lock(mdb); - if (pdbr->PoolId != 0) { /* find by id */ + if (pdbr->PoolId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume," "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," "MaxVolBytes,PoolType,LabelType,LabelFormat FROM Pool WHERE Pool.PoolId=%s", - edit_int64(pdbr->PoolId, ed1)); - } else { /* find by name */ + edit_int64(pdbr->PoolId, ed1)); + } else { /* find by name */ Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume," "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," "MaxVolBytes,PoolType,LabelType,LabelFormat FROM Pool WHERE Pool.Name='%s'", - pdbr->Name); + pdbr->Name); } if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - char ed1[30]; + char ed1[30]; Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"), - edit_uint64(mdb->num_rows, ed1)); + edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - } else { - pdbr->PoolId = str_to_int64(row[0]); + } else { + pdbr->PoolId = str_to_int64(row[0]); bstrncpy(pdbr->Name, row[1]!=NULL?row[1]:"", sizeof(pdbr->Name)); - pdbr->NumVols = str_to_int64(row[2]); - pdbr->MaxVols = str_to_int64(row[3]); - pdbr->UseOnce = str_to_int64(row[4]); - pdbr->UseCatalog = str_to_int64(row[5]); - pdbr->AcceptAnyVolume = str_to_int64(row[6]); - pdbr->AutoPrune = str_to_int64(row[7]); - pdbr->Recycle = str_to_int64(row[8]); - pdbr->VolRetention = str_to_int64(row[9]); - pdbr->VolUseDuration = str_to_int64(row[10]); - pdbr->MaxVolJobs = str_to_int64(row[11]); - pdbr->MaxVolFiles = str_to_int64(row[12]); - pdbr->MaxVolBytes = str_to_uint64(row[13]); + pdbr->NumVols = str_to_int64(row[2]); + pdbr->MaxVols = str_to_int64(row[3]); + pdbr->UseOnce = str_to_int64(row[4]); + pdbr->UseCatalog = str_to_int64(row[5]); + pdbr->AcceptAnyVolume = str_to_int64(row[6]); + pdbr->AutoPrune = str_to_int64(row[7]); + pdbr->Recycle = str_to_int64(row[8]); + pdbr->VolRetention = str_to_int64(row[9]); + pdbr->VolUseDuration = str_to_int64(row[10]); + pdbr->MaxVolJobs = str_to_int64(row[11]); + pdbr->MaxVolFiles = str_to_int64(row[12]); + pdbr->MaxVolBytes = str_to_uint64(row[13]); bstrncpy(pdbr->PoolType, row[14]!=NULL?row[14]:"", sizeof(pdbr->PoolType)); - pdbr->LabelType = str_to_int64(row[15]); + pdbr->LabelType = str_to_int64(row[15]); bstrncpy(pdbr->LabelFormat, row[16]!=NULL?row[16]:"", sizeof(pdbr->LabelFormat)); - ok = true; - } + ok = true; + } } else { Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n")); } @@ -605,7 +607,7 @@ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) * otherwise, we search on the Client Name * * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) { @@ -614,12 +616,12 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) char ed1[50]; db_lock(mdb); - if (cdbr->ClientId != 0) { /* find by id */ + if (cdbr->ClientId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention " "FROM Client WHERE Client.ClientId=%s", - edit_int64(cdbr->ClientId, ed1)); - } else { /* find by name */ + edit_int64(cdbr->ClientId, ed1)); + } else { /* find by name */ Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention " "FROM Client WHERE Client.Name='%s'", cdbr->Name); @@ -629,21 +631,21 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Client!: %s\n"), - edit_uint64(mdb->num_rows, ed1)); + edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - } else { - cdbr->ClientId = str_to_int64(row[0]); + } else { + cdbr->ClientId = str_to_int64(row[0]); bstrncpy(cdbr->Name, row[1]!=NULL?row[1]:"", sizeof(cdbr->Name)); bstrncpy(cdbr->Uname, row[2]!=NULL?row[1]:"", sizeof(cdbr->Uname)); - cdbr->AutoPrune = str_to_int64(row[3]); - cdbr->FileRetention = str_to_int64(row[4]); - cdbr->JobRetention = str_to_int64(row[5]); - stat = 1; - } + cdbr->AutoPrune = str_to_int64(row[3]); + cdbr->FileRetention = str_to_int64(row[4]); + cdbr->JobRetention = str_to_int64(row[5]); + stat = 1; + } } else { Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n")); } @@ -659,7 +661,7 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) * Get Counter Record * * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) { @@ -678,24 +680,24 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - sql_free_result(mdb); - db_unlock(mdb); - return 0; - } - cr->MinValue = str_to_int64(row[0]); - cr->MaxValue = str_to_int64(row[1]); - cr->CurrentValue = str_to_int64(row[2]); - if (row[3]) { - bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter)); - } else { - cr->WrapCounter[0] = 0; - } - sql_free_result(mdb); - db_unlock(mdb); - return 1; + sql_free_result(mdb); + db_unlock(mdb); + return 0; + } + cr->MinValue = str_to_int64(row[0]); + cr->MaxValue = str_to_int64(row[1]); + cr->CurrentValue = str_to_int64(row[2]); + if (row[3]) { + bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter)); + } else { + cr->WrapCounter[0] = 0; + } + sql_free_result(mdb); + db_unlock(mdb); + return 1; } sql_free_result(mdb); } else { @@ -711,7 +713,7 @@ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) * otherwise, we search on the name * * Returns: 0 on failure - * id on success + * id on success */ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) { @@ -720,12 +722,12 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) char ed1[50]; db_lock(mdb); - if (fsr->FileSetId != 0) { /* find by id */ + if (fsr->FileSetId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet " "WHERE FileSetId=%s", - edit_int64(fsr->FileSetId, ed1)); - } else { /* find by name */ + edit_int64(fsr->FileSetId, ed1)); + } else { /* find by name */ Mmsg(mdb->cmd, "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet " "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", fsr->FileSet); @@ -734,19 +736,19 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) if (QUERY_DB(jcr, mdb, mdb->cmd)) { mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { - char ed1[30]; + char ed1[30]; Mmsg1(&mdb->errmsg, _("Error got %s FileSets but expected only one!\n"), - edit_uint64(mdb->num_rows, ed1)); - sql_data_seek(mdb, mdb->num_rows-1); + edit_uint64(mdb->num_rows, ed1)); + sql_data_seek(mdb, mdb->num_rows-1); } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet); } else { - fsr->FileSetId = str_to_int64(row[0]); + fsr->FileSetId = str_to_int64(row[0]); bstrncpy(fsr->FileSet, row[1]!=NULL?row[1]:"", sizeof(fsr->FileSet)); bstrncpy(fsr->MD5, row[2]!=NULL?row[2]:"", sizeof(fsr->MD5)); bstrncpy(fsr->cCreateTime, row[3]!=NULL?row[3]:"", sizeof(fsr->cCreateTime)); - stat = fsr->FileSetId; + stat = fsr->FileSetId; } sql_free_result(mdb); } else { @@ -761,7 +763,7 @@ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) * Get the number of Media records * * Returns: -1 on failure - * number on success + * number on success */ int db_get_num_media_records(JCR *jcr, B_DB *mdb) { @@ -781,7 +783,7 @@ int db_get_num_media_records(JCR *jcr, B_DB *mdb) * The caller must free ids if non-NULL. * * Returns 0: on failure - * 1: on success + * 1: on success */ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[]) { @@ -798,11 +800,11 @@ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_ if (QUERY_DB(jcr, mdb, mdb->cmd)) { *num_ids = sql_num_rows(mdb); if (*num_ids > 0) { - id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); - while ((row = sql_fetch_row(mdb)) != NULL) { - id[i++] = str_to_uint64(row[0]); - } - *ids = id; + id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); + while ((row = sql_fetch_row(mdb)) != NULL) { + id[i++] = str_to_uint64(row[0]); + } + *ids = id; } sql_free_result(mdb); stat = 1; @@ -819,7 +821,7 @@ int db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_ /* Get Media Record * * Returns: 0 on failure - * id on success + * id on success */ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { @@ -834,15 +836,15 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) db_unlock(mdb); return 1; } - if (mr->MediaId != 0) { /* find by id */ + if (mr->MediaId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs," "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId " "FROM Media WHERE MediaId=%s", - edit_int64(mr->MediaId, ed1)); - } else { /* find by name */ + edit_int64(mr->MediaId, ed1)); + } else { /* find by name */ Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs," @@ -856,65 +858,65 @@ int db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) mdb->num_rows = sql_num_rows(mdb); if (mdb->num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"), - edit_uint64(mdb->num_rows, ed1)); + edit_uint64(mdb->num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { - if ((row = sql_fetch_row(mdb)) == NULL) { + if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); - } else { - /* return values */ - mr->MediaId = str_to_int64(row[0]); + } else { + /* return values */ + mr->MediaId = str_to_int64(row[0]); bstrncpy(mr->VolumeName, row[1]!=NULL?row[1]:"", sizeof(mr->VolumeName)); - mr->VolJobs = str_to_int64(row[2]); - mr->VolFiles = str_to_int64(row[3]); - mr->VolBlocks = str_to_int64(row[4]); - mr->VolBytes = str_to_uint64(row[5]); - mr->VolMounts = str_to_int64(row[6]); - mr->VolErrors = str_to_int64(row[7]); - mr->VolWrites = str_to_int64(row[8]); - mr->MaxVolBytes = str_to_uint64(row[9]); - mr->VolCapacityBytes = str_to_uint64(row[10]); + mr->VolJobs = str_to_int64(row[2]); + mr->VolFiles = str_to_int64(row[3]); + mr->VolBlocks = str_to_int64(row[4]); + mr->VolBytes = str_to_uint64(row[5]); + mr->VolMounts = str_to_int64(row[6]); + mr->VolErrors = str_to_int64(row[7]); + mr->VolWrites = str_to_int64(row[8]); + mr->MaxVolBytes = str_to_uint64(row[9]); + mr->VolCapacityBytes = str_to_uint64(row[10]); bstrncpy(mr->MediaType, row[11]!=NULL?row[11]:"", sizeof(mr->MediaType)); bstrncpy(mr->VolStatus, row[12]!=NULL?row[12]:"", sizeof(mr->VolStatus)); - mr->PoolId = str_to_int64(row[13]); - mr->VolRetention = str_to_uint64(row[14]); - mr->VolUseDuration = str_to_uint64(row[15]); - mr->MaxVolJobs = str_to_int64(row[16]); - mr->MaxVolFiles = str_to_int64(row[17]); - mr->Recycle = str_to_int64(row[18]); - mr->Slot = str_to_int64(row[19]); + mr->PoolId = str_to_int64(row[13]); + mr->VolRetention = str_to_uint64(row[14]); + mr->VolUseDuration = str_to_uint64(row[15]); + mr->MaxVolJobs = str_to_int64(row[16]); + mr->MaxVolFiles = str_to_int64(row[17]); + mr->Recycle = str_to_int64(row[18]); + mr->Slot = str_to_int64(row[19]); bstrncpy(mr->cFirstWritten, row[20]!=NULL?row[20]:"", sizeof(mr->cFirstWritten)); - mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten); + mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten); bstrncpy(mr->cLastWritten, row[21]!=NULL?row[21]:"", sizeof(mr->cLastWritten)); - mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten); - mr->InChanger = str_to_uint64(row[22]); - mr->EndFile = str_to_uint64(row[23]); - mr->EndBlock = str_to_uint64(row[24]); - mr->VolParts = str_to_int64(row[25]); - mr->LabelType = str_to_int64(row[26]); + mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten); + mr->InChanger = str_to_uint64(row[22]); + mr->EndFile = str_to_uint64(row[23]); + mr->EndBlock = str_to_uint64(row[24]); + mr->VolParts = str_to_int64(row[25]); + mr->LabelType = str_to_int64(row[26]); bstrncpy(mr->cLabelDate, row[27]!=NULL?row[27]:"", sizeof(mr->cLabelDate)); - mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate); - mr->StorageId = str_to_int64(row[28]); - stat = mr->MediaId; - } + mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate); + mr->StorageId = str_to_int64(row[28]); + stat = mr->MediaId; + } } else { - if (mr->MediaId != 0) { + if (mr->MediaId != 0) { Mmsg1(&mdb->errmsg, _("Media record MediaId=%s not found.\n"), - edit_int64(mr->MediaId, ed1)); - } else { + edit_int64(mr->MediaId, ed1)); + } else { Mmsg1(&mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"), - mr->VolumeName); - } + mr->VolumeName); + } } sql_free_result(mdb); } else { if (mr->MediaId != 0) { Mmsg(mdb->errmsg, _("Media record for MediaId=%u not found in Catalog.\n"), - mr->MediaId); + mr->MediaId); } else { Mmsg(mdb->errmsg, _("Media record for Vol=%s not found in Catalog.\n"), - mr->VolumeName); + mr->VolumeName); } } db_unlock(mdb); return stat; diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index c97c5a4ad6..b512b1c655 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -29,7 +29,7 @@ /* The following is necessary so that we do not include * the dummy external definition of DB. */ -#define __SQL_C /* indicate that this is sql.c */ +#define __SQL_C /* indicate that this is sql.c */ #include "bacula.h" #include "cats.h" @@ -52,13 +52,13 @@ extern int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_ * Submit general SQL query */ int db_list_sql_query(JCR *jcr, B_DB *mdb, char *query, DB_LIST_HANDLER *sendit, - void *ctx, int verbose, e_list_type type) + void *ctx, int verbose, e_list_type type) { db_lock(mdb); if (sql_query(mdb, query) != 0) { Mmsg(mdb->errmsg, _("Query failed: %s\n"), sql_strerror(mdb)); if (verbose) { - sendit(ctx, mdb->errmsg); + sendit(ctx, mdb->errmsg); } db_unlock(mdb); return 0; @@ -131,7 +131,7 @@ db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, */ void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, - DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) + DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char ed1[50]; db_lock(mdb); @@ -152,7 +152,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger," "EndFile,EndBlock,VolParts,LabelType,StorageId" " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", - edit_int64(mdbr->PoolId, ed1)); + edit_int64(mdbr->PoolId, ed1)); } } else { if (mdbr->VolumeName[0] != 0) { @@ -163,7 +163,7 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus," "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten " "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", - edit_int64(mdbr->PoolId, ed1)); + edit_int64(mdbr->PoolId, ed1)); } } @@ -179,26 +179,26 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, } void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, - DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) + DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char ed1[50]; db_lock(mdb); if (type == VERT_LIST) { - if (JobId > 0) { /* do by JobId */ + if (JobId > 0) { /* do by JobId */ Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," - "JobMedia.EndBlock " + "JobMedia.EndBlock,Copy,Stripe " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId " "AND JobMedia.JobId=%s", edit_int64(JobId, ed1)); } else { Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," - "JobMedia.EndBlock " + "JobMedia.EndBlock,Copy,Stripe " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId"); } } else { - if (JobId > 0) { /* do by JobId */ + if (JobId > 0) { /* do by JobId */ Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId " "AND JobMedia.JobId=%s", edit_int64(JobId, ed1)); @@ -228,13 +228,13 @@ void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, */ void db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, - void *ctx, e_list_type type) + void *ctx, e_list_type type) { char ed1[50]; db_lock(mdb); if (type == VERT_LIST) { if (jr->JobId == 0 && jr->Job[0] == 0) { - Mmsg(mdb->cmd, + Mmsg(mdb->cmd, "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level," "Job.ClientId,Client.Name,JobStatus,SchedTime," "StartTime,EndTime,JobTDate," @@ -243,8 +243,8 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, "FROM Job,Client,Pool,FileSet WHERE " "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId " "AND FileSet.FileSetId=Job.FileSetId ORDER BY StartTime"); - } else { /* single record */ - Mmsg(mdb->cmd, + } else { /* single record */ + Mmsg(mdb->cmd, "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level," "Job.ClientId,Client.Name,JobStatus,SchedTime," "StartTime,EndTime,JobTDate," @@ -253,17 +253,17 @@ db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%s AND " "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId " "AND FileSet.FileSetId=Job.FileSetId", - edit_int64(jr->JobId, ed1)); + edit_int64(jr->JobId, ed1)); } } else { if (jr->JobId == 0 && jr->Job[0] == 0) { - Mmsg(mdb->cmd, + Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " "FROM Job ORDER BY StartTime"); - } else { /* single record */ + } else { /* single record */ Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level," "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%s", - edit_int64(jr->JobId, ed1)); + edit_int64(jr->JobId, ed1)); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index e3f0779239..6e098bddaf 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -29,7 +29,7 @@ /* The following is necessary so that we do not include * the dummy external definition of DB. */ -#define __SQL_C /* indicate that this is sql.c */ +#define __SQL_C /* indicate that this is sql.c */ #include "bacula.h" #include "cats.h" @@ -56,7 +56,7 @@ extern int UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update /* Update the attributes record by adding the MD5 signature */ int db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, - int type) + int type) { int stat; char ed1[50]; @@ -89,7 +89,7 @@ int db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId) * Update the Job record at start of Job * * Returns: false on failure - * true on success + * true on success */ bool db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) @@ -124,7 +124,6 @@ db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) /* * Given an incoming integer, set the string buffer to either NULL or the value * - * */ static void edit_num_or_null(char *s, size_t n, uint64_t id) { char ed1[50]; @@ -136,7 +135,7 @@ static void edit_num_or_null(char *s, size_t n, uint64_t id) { * Update the Job record at end of Job * * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) @@ -147,13 +146,13 @@ db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) int stat; char ed1[30], ed2[30], ed3[50]; btime_t JobTDate; - char PoolId [50]; + char PoolId [50]; char FileSetId [50]; char ClientId [50]; /* some values are set to zero, which translates to NULL in SQL */ - edit_num_or_null(PoolId, sizeof(PoolId), jr->PoolId); + edit_num_or_null(PoolId, sizeof(PoolId), jr->PoolId); edit_num_or_null(FileSetId, sizeof(FileSetId), jr->FileSetId); edit_num_or_null(ClientId, sizeof(ClientId), jr->ClientId); @@ -181,7 +180,7 @@ db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) /* * Update Client record * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) @@ -214,7 +213,7 @@ db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) /* * Update Counters record * Returns: 0 on failure - * 1 on success + * 1 on success */ int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) { @@ -239,6 +238,9 @@ db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) char ed1[50], ed2[50], ed3[50], ed4[50]; db_lock(mdb); + Mmsg(mdb->cmd, "SELECT count(*) from Pool"); + pr->NumVols = get_sql_record_max(jcr, mdb); + Mmsg(mdb->cmd, "UPDATE Pool SET NumVols=%u,MaxVols=%u,UseOnce=%d,UseCatalog=%d," "AcceptAnyVolume=%d,VolRetention='%s',VolUseDuration='%s'," @@ -278,7 +280,7 @@ db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) * Update the Media Record at end of Session * * Returns: 0 on failure - * numrows on success + * numrows on success */ int db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) @@ -307,7 +309,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) if (mr->set_label_date) { ttime = mr->LabelDate; if (ttime == 0) { - ttime = time(NULL); + ttime = time(NULL); } localtime_r(&ttime, &tm); strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm); @@ -331,16 +333,16 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s,VolParts=%d," "LabelType=%d,StorageId=%s" " WHERE VolumeName='%s'", - mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1), - mr->VolMounts, mr->VolErrors, mr->VolWrites, - edit_uint64(mr->MaxVolBytes, ed2), - mr->VolStatus, mr->Slot, mr->InChanger, - edit_uint64(mr->VolReadTime, ed3), - edit_uint64(mr->VolWriteTime, ed4), - mr->VolParts, - mr->LabelType, - edit_int64(mr->StorageId, ed5), - mr->VolumeName); + mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1), + mr->VolMounts, mr->VolErrors, mr->VolWrites, + edit_uint64(mr->MaxVolBytes, ed2), + mr->VolStatus, mr->Slot, mr->InChanger, + edit_uint64(mr->VolReadTime, ed3), + edit_uint64(mr->VolWriteTime, ed4), + mr->VolParts, + mr->LabelType, + edit_int64(mr->StorageId, ed5), + mr->VolumeName); Dmsg1(400, "%s\n", mdb->cmd); @@ -357,7 +359,7 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) * Update the Media Record Default values from Pool * * Returns: 0 on failure - * numrows on success + * numrows on success */ int db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) @@ -372,21 +374,21 @@ db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) "Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s" " WHERE VolumeName='%s'", - mr->Recycle,edit_uint64(mr->VolRetention, ed1), - edit_uint64(mr->VolUseDuration, ed2), - mr->MaxVolJobs, mr->MaxVolFiles, - edit_uint64(mr->VolBytes, ed3), - mr->VolumeName); + mr->Recycle,edit_uint64(mr->VolRetention, ed1), + edit_uint64(mr->VolUseDuration, ed2), + mr->MaxVolJobs, mr->MaxVolFiles, + edit_uint64(mr->VolBytes, ed3), + mr->VolumeName); } else { Mmsg(mdb->cmd, "UPDATE Media SET " "Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s" " WHERE PoolId=%s", - mr->Recycle,edit_uint64(mr->VolRetention, ed1), - edit_uint64(mr->VolUseDuration, ed2), - mr->MaxVolJobs, mr->MaxVolFiles, - edit_uint64(mr->VolBytes, ed3), - edit_int64(mr->PoolId, ed4)); + mr->Recycle,edit_uint64(mr->VolRetention, ed1), + edit_uint64(mr->VolUseDuration, ed2), + mr->MaxVolJobs, mr->MaxVolFiles, + edit_uint64(mr->VolBytes, ed3), + edit_int64(mr->PoolId, ed4)); } Dmsg1(400, "%s\n", mdb->cmd); @@ -411,8 +413,8 @@ db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) if (mr->InChanger != 0 && mr->Slot != 0) { Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE " "Slot=%d AND StorageId=%s AND MediaId!=%s", - mr->Slot, - edit_int64(mr->StorageId, ed1), edit_int64(mr->MediaId, ed2)); + mr->Slot, + edit_int64(mr->StorageId, ed1), edit_int64(mr->MediaId, ed2)); Dmsg1(400, "%s\n", mdb->cmd); UPDATE_DB(jcr, mdb, mdb->cmd); } diff --git a/bacula/src/cats/update_mysql_tables.in b/bacula/src/cats/update_mysql_tables.in index f86c0484ef..9a0322d73f 100755 --- a/bacula/src/cats/update_mysql_tables.in +++ b/bacula/src/cats/update_mysql_tables.in @@ -1,6 +1,6 @@ #!/bin/sh # -# Shell script to update MySQL tables from version 1.36 to 1.37.3 +# Shell script to update MySQL tables from version 1.36 to 1.37.12 # echo " " echo "This script will update a Bacula MySQL database from version 8 to 9" @@ -22,6 +22,10 @@ ALTER TABLE Pool ADD COLUMN MigrationHighBytes BIGINT UNSIGNED DEFAULT 0; ALTER TABLE Pool ADD COLUMN MigrationLowBytes BIGINT UNSIGNED DEFAULT 0; ALTER TABLE Pool ADD COLUMN MigrationTime BIGINT UNSIGNED DEFAULT 0; +ALTER TABLE JobMedia ADD COLUMN Copy INTEGER UNSIGNED NOT NULL DEFAULT 0; +ALTER TABLE JobMedia ADD COLUMN Stripe INTEGER UNSIGNED NOT NULL DEFAULT 0; + + CREATE TABLE MediaType ( MediaTypeId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, MediaType VARCHAR(128) NOT NULL, @@ -55,6 +59,9 @@ CREATE TABLE Device ( PRIMARY KEY(DeviceId) ); +DELETE FROM Version; +INSERT INTO Version (VersionId) VALUES (9); + END-OF-DATA then echo "Update of Bacula MySQL tables succeeded." diff --git a/bacula/src/cats/update_postgresql_tables.in b/bacula/src/cats/update_postgresql_tables.in index 109700161a..6f24920f23 100755 --- a/bacula/src/cats/update_postgresql_tables.in +++ b/bacula/src/cats/update_postgresql_tables.in @@ -1,6 +1,6 @@ #!/bin/sh # -# Shell script to update PostgreSQL tables from version 1.36 to 1.37.3 +# Shell script to update PostgreSQL tables from version 1.36 to 1.37.12 # echo " " echo "This script will update a Bacula PostgreSQL database from version 8 to 9" @@ -30,6 +30,12 @@ ALTER TABLE pool ADD COLUMN MigrationTime BIGINT; ALTER TABLE pool SET MigrationTime=0; +ALTER TABLE jobmedia ADD COLUMN Copy integer; +UPDATE jobmedia SET Copy=0; +ALTER TABLE jobmedia ADD COLUMN Stripe integer; +UPDATE jobmedia SET Stripe=0; + + ALTER TABLE media ADD COLUMN volparts integer; UPDATE media SET volparts=0; ALTER TABLE media ALTER COLUMN volparts SET NOT NULL; @@ -67,6 +73,9 @@ CREATE TABLE Storage ( PRIMARY KEY(StorageId) ); +DELETE FROM version; +INSERT INTO version (versionId) VALUES (9); + vacuum; END-OF-DATA diff --git a/bacula/src/cats/update_sqlite3_tables.in b/bacula/src/cats/update_sqlite3_tables.in index b4e4c35513..2fcaec6979 100755 --- a/bacula/src/cats/update_sqlite3_tables.in +++ b/bacula/src/cats/update_sqlite3_tables.in @@ -1,6 +1,6 @@ #!/bin/sh # -# shell script to update SQLite from version 1.36 to 1.37.3 +# shell script to update SQLite from version 1.36 to 1.37.12 # echo " " echo "This script will update a Bacula SQLite database from version 8 to 9" @@ -20,6 +20,7 @@ CREATE TEMPORARY TABLE Media_backup ( Slot INTEGER DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL, MediaType VARCHAR(128) NOT NULL, + LabelType TINYINT DEFAULT 0, FirstWritten DATETIME DEFAULT 0, LastWritten DATETIME DEFAULT 0, LabelDate DATETIME DEFAULT 0, @@ -101,7 +102,7 @@ CREATE TABLE Media ( INSERT INTO Media ( MediaId, VolumeName, Slot, PoolId, - MediaType, FirstWritten, LastWritten, + MediaType, LabelType, FirstWritten, LastWritten, LabelDate, VolJobs, VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors, VolWrites, VolCapacityBytes, VolStatus, Recycle, @@ -113,6 +114,58 @@ INSERT INTO Media ( SELECT * FROM Media_backup; DROP TABLE Media_backup; +CREATE INDEX inx8 ON Media (PoolId); + + +CREATE TEMPORARY TABLE JobMedia_backup ( + JobMediaId INTEGER, + JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, + MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL, + FirstIndex INTEGER UNSIGNED NOT NULL, + LastIndex INTEGER UNSIGNED NOT NULL, + StartFile INTEGER UNSIGNED DEFAULT 0, + EndFile INTEGER UNSIGNED DEFAULT 0, + StartBlock INTEGER UNSIGNED DEFAULT 0, + EndBlock INTEGER UNSIGNED DEFAULT 0, + VolIndex INTEGER UNSIGNED DEFAULT 0, + Copy INTEGER UNSIGNED DEFAULT 0, + Stripe INTEGER UNSIGNED DEFAULT 0, + PRIMARY KEY(JobMediaId) + ); + +INSERT INTO JobMedia_backup SELECT + JobMediaId, JobId, MediaId, + FirstIndex, LastIndex, StartFile, + EndFile, StartBlock, EndBlock, + VolIndex, 0, 0 + FROM JobMedia; + +DROP TABLE JobMedia; + +CREATE TABLE JobMedia ( + JobMediaId INTEGER, + JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, + MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL, + FirstIndex INTEGER UNSIGNED NOT NULL, + LastIndex INTEGER UNSIGNED NOT NULL, + StartFile INTEGER UNSIGNED DEFAULT 0, + EndFile INTEGER UNSIGNED DEFAULT 0, + StartBlock INTEGER UNSIGNED DEFAULT 0, + EndBlock INTEGER UNSIGNED DEFAULT 0, + VolIndex INTEGER UNSIGNED DEFAULT 0, + Copy INTEGER UNSIGNED DEFAULT 0, + Stripe INTEGER UNSIGNED DEFAULT 0, + PRIMARY KEY(JobMediaId) + ); + +INSERT INTO JobMedia ( + JobMediaId, JobId, MediaId, + FirstIndex, LastIndex, StartFile, + EndFile, StartBlock, EndBlock, + VolIndex, Copy, Stripe) + SELECT * FROM JobMedia_backup; + +DROP TABLE JobMedia_backup; CREATE TEMPORARY TABLE Pool_backup ( PoolId INTEGER, @@ -198,7 +251,7 @@ INSERT INTO Pool ( DROP TABLE Pool_backup; CREATE TABLE MediaType ( - MediaTypeId INTERGER, + MediaTypeId INTEGER, MediaType VARCHAR(128) NOT NULL, ReadOnly TINYINT DEFAULT 0, PRIMARY KEY(MediaTypeId) @@ -230,6 +283,10 @@ CREATE TABLE Device ( PRIMARY KEY(DeviceId) ); + +DELETE FROM Version; +INSERT INTO Version (VersionId) VALUES (9); + COMMIT; END-OF-DATA diff --git a/bacula/src/cats/update_sqlite_tables.in b/bacula/src/cats/update_sqlite_tables.in index b409ee050d..2fcaec6979 100755 --- a/bacula/src/cats/update_sqlite_tables.in +++ b/bacula/src/cats/update_sqlite_tables.in @@ -1,6 +1,6 @@ #!/bin/sh # -# shell script to update SQLite from version 1.36 to 1.37.3 +# shell script to update SQLite from version 1.36 to 1.37.12 # echo " " echo "This script will update a Bacula SQLite database from version 8 to 9" @@ -20,6 +20,7 @@ CREATE TEMPORARY TABLE Media_backup ( Slot INTEGER DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL, MediaType VARCHAR(128) NOT NULL, + LabelType TINYINT DEFAULT 0, FirstWritten DATETIME DEFAULT 0, LastWritten DATETIME DEFAULT 0, LabelDate DATETIME DEFAULT 0, @@ -101,7 +102,7 @@ CREATE TABLE Media ( INSERT INTO Media ( MediaId, VolumeName, Slot, PoolId, - MediaType, FirstWritten, LastWritten, + MediaType, LabelType, FirstWritten, LastWritten, LabelDate, VolJobs, VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors, VolWrites, VolCapacityBytes, VolStatus, Recycle, @@ -113,6 +114,58 @@ INSERT INTO Media ( SELECT * FROM Media_backup; DROP TABLE Media_backup; +CREATE INDEX inx8 ON Media (PoolId); + + +CREATE TEMPORARY TABLE JobMedia_backup ( + JobMediaId INTEGER, + JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, + MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL, + FirstIndex INTEGER UNSIGNED NOT NULL, + LastIndex INTEGER UNSIGNED NOT NULL, + StartFile INTEGER UNSIGNED DEFAULT 0, + EndFile INTEGER UNSIGNED DEFAULT 0, + StartBlock INTEGER UNSIGNED DEFAULT 0, + EndBlock INTEGER UNSIGNED DEFAULT 0, + VolIndex INTEGER UNSIGNED DEFAULT 0, + Copy INTEGER UNSIGNED DEFAULT 0, + Stripe INTEGER UNSIGNED DEFAULT 0, + PRIMARY KEY(JobMediaId) + ); + +INSERT INTO JobMedia_backup SELECT + JobMediaId, JobId, MediaId, + FirstIndex, LastIndex, StartFile, + EndFile, StartBlock, EndBlock, + VolIndex, 0, 0 + FROM JobMedia; + +DROP TABLE JobMedia; + +CREATE TABLE JobMedia ( + JobMediaId INTEGER, + JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, + MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL, + FirstIndex INTEGER UNSIGNED NOT NULL, + LastIndex INTEGER UNSIGNED NOT NULL, + StartFile INTEGER UNSIGNED DEFAULT 0, + EndFile INTEGER UNSIGNED DEFAULT 0, + StartBlock INTEGER UNSIGNED DEFAULT 0, + EndBlock INTEGER UNSIGNED DEFAULT 0, + VolIndex INTEGER UNSIGNED DEFAULT 0, + Copy INTEGER UNSIGNED DEFAULT 0, + Stripe INTEGER UNSIGNED DEFAULT 0, + PRIMARY KEY(JobMediaId) + ); + +INSERT INTO JobMedia ( + JobMediaId, JobId, MediaId, + FirstIndex, LastIndex, StartFile, + EndFile, StartBlock, EndBlock, + VolIndex, Copy, Stripe) + SELECT * FROM JobMedia_backup; + +DROP TABLE JobMedia_backup; CREATE TEMPORARY TABLE Pool_backup ( PoolId INTEGER, @@ -231,6 +284,9 @@ CREATE TABLE Device ( ); +DELETE FROM Version; +INSERT INTO Version (VersionId) VALUES (9); + COMMIT; END-OF-DATA diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 17ff0a1946..945a34d165 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -8,7 +8,7 @@ * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: - * Handle Catalog services. + * Handle Catalog services. * * Version $Id$ */ @@ -52,7 +52,7 @@ static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s" static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia " " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u " - " StartBlock=%u EndBlock=%u\n"; + " StartBlock=%u EndBlock=%u Copy=%d Strip=%d\n"; /* Responses sent to Storage daemon */ @@ -124,14 +124,14 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) bstrncpy(pr.Name, pool_name, sizeof(pr.Name)); ok = db_get_pool_record(jcr, jcr->db, &pr); if (ok) { - mr.PoolId = pr.PoolId; - ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/); + mr.PoolId = pr.PoolId; + ok = find_next_volume_for_append(jcr, &mr, true /*permit create new vol*/); } /* * Send Find Media response to Storage daemon */ if (ok) { - send_volume_info_to_storage_daemon(jcr, bs, &mr); + send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { bnet_fsend(bs, "1901 No Media.\n"); Dmsg0(500, "1901 No Media.\n"); @@ -147,51 +147,51 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) */ unbash_spaces(mr.VolumeName); if (db_get_media_record(jcr, jcr->db, &mr)) { - const char *reason = NULL; /* detailed reason for rejection */ - /* - * If we are reading, accept any volume (reason == NULL) - * If we are writing, check if the Volume is valid - * for this job, and do a recycle if necessary - */ - if (writing) { - /* - * SD wants to write this Volume, so make - * sure it is suitable for this job, i.e. - * Pool matches, and it is either Append or Recycle - * and Media Type matches and Pool allows any volume. - */ - if (mr.PoolId != jcr->PoolId) { + const char *reason = NULL; /* detailed reason for rejection */ + /* + * If we are reading, accept any volume (reason == NULL) + * If we are writing, check if the Volume is valid + * for this job, and do a recycle if necessary + */ + if (writing) { + /* + * SD wants to write this Volume, so make + * sure it is suitable for this job, i.e. + * Pool matches, and it is either Append or Recycle + * and Media Type matches and Pool allows any volume. + */ + if (mr.PoolId != jcr->PoolId) { reason = "not in Pool"; - } else if (strcmp(mr.MediaType, jcr->store->media_type) != 0) { + } else if (strcmp(mr.MediaType, jcr->store->media_type) != 0) { reason = "not correct MediaType"; - } else { - /* - * ****FIXME*** - * This test (accept_any_volume) is turned off + } else { + /* + * ****FIXME*** + * This test (accept_any_volume) is turned off * because it doesn't properly check if the volume - * really is out of sequence! - * - * } else if (!jcr->pool->accept_any_volume) { + * really is out of sequence! + * + * } else if (!jcr->pool->accept_any_volume) { * reason = "Volume not in sequence"; - */ - - /* - * Now try recycling if necessary - * reason set non-NULL if we cannot use it - */ - check_if_volume_valid_or_recyclable(jcr, &mr, &reason); - } - } - if (reason == NULL) { - /* - * Send Find Media response to Storage daemon - */ - send_volume_info_to_storage_daemon(jcr, bs, &mr); - } else { - /* Not suitable volume */ + */ + + /* + * Now try recycling if necessary + * reason set non-NULL if we cannot use it + */ + check_if_volume_valid_or_recyclable(jcr, &mr, &reason); + } + } + if (reason == NULL) { + /* + * Send Find Media response to Storage daemon + */ + send_volume_info_to_storage_daemon(jcr, bs, &mr); + } else { + /* Not suitable volume */ bnet_fsend(bs, "1998 Volume \"%s\" status is %s, %s.\n", mr.VolumeName, - mr.VolStatus, reason); - } + mr.VolStatus, reason); + } } else { bnet_fsend(bs, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName); @@ -211,39 +211,39 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) db_lock(jcr->db); Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, - mr.VolStatus, sdmr.VolStatus); + mr.VolStatus, sdmr.VolStatus); bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */ unbash_spaces(mr.VolumeName); if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"), - mr.VolumeName, db_strerror(jcr->db)); + mr.VolumeName, db_strerror(jcr->db)); bnet_fsend(bs, "1991 Catalog Request for vol=%s failed: %s", - mr.VolumeName, db_strerror(jcr->db)); - db_unlock(jcr->db); - return; + mr.VolumeName, db_strerror(jcr->db)); + db_unlock(jcr->db); + return; } /* Set first written time if this is first job */ if (mr.FirstWritten == 0) { - mr.FirstWritten = jcr->start_time; /* use Job start time as first write */ - mr.set_first_written = true; + mr.FirstWritten = jcr->start_time; /* use Job start time as first write */ + mr.set_first_written = true; } /* If we just labeled the tape set time */ if (label || mr.LabelDate == 0) { - mr.LabelDate = jcr->start_time; - mr.set_label_date = true; + mr.LabelDate = jcr->start_time; + mr.set_label_date = true; Dmsg2(400, "label=%d labeldate=%d\n", label, mr.LabelDate); } else { - /* - * Insanity check for VolFiles get set to a smaller value - */ - if (sdmr.VolFiles < mr.VolFiles) { + /* + * Insanity check for VolFiles get set to a smaller value + */ + if (sdmr.VolFiles < mr.VolFiles) { Jmsg(jcr, M_FATAL, 0, _("Volume Files at %u being set to %u" " for Volume \"%s\". This is incorrect.\n"), - mr.VolFiles, sdmr.VolFiles, mr.VolumeName); + mr.VolFiles, sdmr.VolFiles, mr.VolumeName); bnet_fsend(bs, "1992 Update Media error\n"); - db_unlock(jcr->db); - return; - } + db_unlock(jcr->db); + return; + } } Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs); /* Copy updated values to original media record */ @@ -255,7 +255,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) mr.VolErrors = sdmr.VolErrors; mr.VolWrites = sdmr.VolWrites; mr.LastWritten = sdmr.LastWritten; - mr.Slot = sdmr.Slot; + mr.Slot = sdmr.Slot; mr.InChanger = sdmr.InChanger; mr.VolReadTime = sdmr.VolReadTime; mr.VolWriteTime = sdmr.VolWriteTime; @@ -268,10 +268,10 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) * Volume has expired, has_volume_expired() will update the DB. */ if (has_volume_expired(jcr, &mr) || db_update_media_record(jcr, jcr->db, &mr)) { - send_volume_info_to_storage_daemon(jcr, bs, &mr); + send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { Jmsg(jcr, M_FATAL, 0, _("Catalog error updating Media record. %s"), - db_strerror(jcr->db)); + db_strerror(jcr->db)); bnet_fsend(bs, "1992 Update Media error\n"); Dmsg0(400, "send error\n"); } @@ -282,19 +282,19 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) */ } else if (sscanf(bs->msg, Create_job_media, &Job, &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile, - &jm.StartBlock, &jm.EndBlock) == 7) { + &jm.StartBlock, &jm.EndBlock, &jm.Copy, &jm.Stripe) == 9) { jm.JobId = jcr->JobId; jm.MediaId = jcr->MediaId; Dmsg6(400, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n", - jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); + jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) { Jmsg(jcr, M_FATAL, 0, _("Catalog error creating JobMedia record. %s"), - db_strerror(jcr->db)); + db_strerror(jcr->db)); bnet_fsend(bs, "1991 Update JobMedia error\n"); } else { Dmsg0(400, "JobMedia record created\n"); - bnet_fsend(bs, OK_create); + bnet_fsend(bs, OK_create); } } else { @@ -331,12 +331,12 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg) if (!jcr->pool->catalog_files) { return; } - db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ - skip_nonspaces(&p); /* UpdCat */ + db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ + skip_nonspaces(&p); /* UpdCat */ skip_spaces(&p); - skip_nonspaces(&p); /* Job=nnn */ + skip_nonspaces(&p); /* Job=nnn */ skip_spaces(&p); - skip_nonspaces(&p); /* FileAttributes */ + skip_nonspaces(&p); /* FileAttributes */ p += 1; unser_begin(p, 0); unser_uint32(VolSessionId); @@ -351,12 +351,12 @@ void catalog_update(JCR *jcr, BSOCK *bs, char *msg) VolSessionId, VolSessionTime, FileIndex, Stream, data_len); if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_UNIX_ATTRIBUTES_EX) { - skip_nonspaces(&p); /* skip FileIndex */ + skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); - skip_nonspaces(&p); /* skip FileType */ + skip_nonspaces(&p); /* skip FileType */ skip_spaces(&p); fname = p; - len = strlen(fname); /* length before attributes */ + len = strlen(fname); /* length before attributes */ attr = &fname[len+1]; Dmsg2(400, "dirdFileIndex != 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)); + } } } } diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index 3215f71742..28edd03599 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -9,9 +9,9 @@ * * Basic tasks done here: * Open a message channel with the Storage daemon - * to authenticate ourself and to pass the JobId. + * to authenticate ourself and to pass the JobId. * Create a thread to interact with the Storage daemon - * who returns a job status and requests Catalog services, etc. + * who returns a job status and requests Catalog services, etc. * * Version $Id$ */ @@ -43,7 +43,7 @@ static char jobcmd[] = "JobId=%d job=%s job_name=%s client_name=%s " "type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s " "SpoolData=%d WritePartAfterJob=%d NewVol=%d\n"; static char use_storage[] = "use storage=%s media_type=%s pool_name=%s " - "pool_type=%s append=%d\n"; + "pool_type=%s append=%d copy=%d stripe=%d\n"; static char use_device[] = "use device=%s\n"; //static char query_device[] = "query device=%s"; @@ -53,7 +53,7 @@ static char OK_device[] = "3000 OK use device device=%s\n"; /* Storage Daemon requests */ static char Job_start[] = "3010 Job %127s start\n"; -static char Job_end[] = +static char Job_end[] = "3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%" lld "\n"; /* Forward referenced functions */ @@ -64,13 +64,13 @@ extern "C" void *msg_thread(void *arg); * and perform authentication. */ bool connect_to_storage_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose) + int max_retry_time, int verbose) { BSOCK *sd; STORE *store; if (jcr->store_bsock) { - return true; /* already connected */ + return true; /* already connected */ } store = (STORE *)jcr->storage->first(); @@ -81,11 +81,11 @@ bool connect_to_storage_daemon(JCR *jcr, int retry_interval, store->SDport); sd = bnet_connect(jcr, retry_interval, max_retry_time, _("Storage daemon"), store->address, - NULL, store->SDport, verbose); + NULL, store->SDport, verbose); if (sd == NULL) { return false; } - sd->res = (RES *)store; /* save pointer to other end */ + sd->res = (RES *)store; /* save pointer to other end */ jcr->store_bsock = sd; if (!authenticate_storage_daemon(jcr, store)) { @@ -132,6 +132,8 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append) char auth_key[100]; POOL_MEM store_name, device_name, pool_name, pool_type, media_type; char PoolId[50]; + int copy = 0; + int stripe = 0; sd = jcr->store_bsock; /* @@ -144,10 +146,10 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append) bstrncpy(jcr->fileset->MD5, "**Dummy**", sizeof(jcr->fileset->MD5)); } bnet_fsend(sd, jobcmd, jcr->JobId, jcr->Job, jcr->job->hdr.name, - jcr->client->hdr.name, jcr->JobType, jcr->JobLevel, - jcr->fileset->hdr.name, !jcr->pool->catalog_files, - jcr->job->SpoolAttributes, jcr->fileset->MD5, jcr->spool_data, - jcr->write_part_after_job, jcr->job->NewVolEachJob); + jcr->client->hdr.name, jcr->JobType, jcr->JobLevel, + jcr->fileset->hdr.name, !jcr->pool->catalog_files, + jcr->job->SpoolAttributes, jcr->fileset->MD5, jcr->spool_data, + jcr->write_part_after_job, jcr->job->NewVolEachJob); Dmsg1(100, ">stored: %s\n", sd->msg); unbash_spaces(jcr->job->hdr.name); unbash_spaces(jcr->client->hdr.name); @@ -155,17 +157,17 @@ int start_storage_daemon_job(JCR *jcr, alist *store, int append) if (bget_dirmsg(sd) > 0) { Dmsg1(100, "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, _("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, "msg); - /* ****FIXME**** save actual device name */ - ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; + /* ****FIXME**** save actual device name */ + ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; } else { - POOL_MEM err_msg; - pm_strcpy(err_msg, sd->msg); /* save message */ + POOL_MEM err_msg; + pm_strcpy(err_msg, sd->msg); /* save message */ Jmsg(jcr, M_WARNING, 0, _("\n" " Storage daemon didn't accept Device \"%s\" because:\n %s"), - device_name.c_str(), err_msg.c_str()/* sd->msg */); + device_name.c_str(), err_msg.c_str()/* sd->msg */); } // if (!ok) { -// break; +// break; // } // } if (ok) { @@ -235,7 +237,7 @@ int start_storage_daemon_message_thread(JCR *jcr) pthread_t thid; P(jcr->mutex); - jcr->use_count++; /* mark in use by msg thread */ + jcr->use_count++; /* mark in use by msg thread */ jcr->sd_msg_thread_done = false; jcr->SD_msg_chan = 0; V(jcr->mutex); @@ -256,13 +258,13 @@ extern "C" void msg_thread_cleanup(void *arg) { JCR *jcr = (JCR *)arg; Dmsg0(200, "End msg_thread\n"); - db_end_transaction(jcr, jcr->db); /* terminate any open transaction */ + db_end_transaction(jcr, jcr->db); /* terminate any open transaction */ P(jcr->mutex); jcr->sd_msg_thread_done = true; pthread_cond_broadcast(&jcr->term_wait); /* wakeup any waiting threads */ jcr->SD_msg_chan = 0; V(jcr->mutex); - free_jcr(jcr); /* release jcr */ + free_jcr(jcr); /* release jcr */ } /* @@ -291,14 +293,14 @@ extern "C" void *msg_thread(void *arg) while ((stat=bget_dirmsg(sd)) >= 0) { Dmsg1(200, "msg); if (sscanf(sd->msg, Job_start, &Job) == 1) { - continue; + continue; } if (sscanf(sd->msg, Job_end, &Job, &JobStatus, &JobFiles, - &JobBytes) == 4) { - jcr->SDJobStatus = JobStatus; /* termination status */ - jcr->SDJobFiles = JobFiles; - jcr->SDJobBytes = JobBytes; - break; + &JobBytes) == 4) { + jcr->SDJobStatus = JobStatus; /* termination status */ + jcr->SDJobFiles = JobFiles; + jcr->SDJobBytes = JobBytes; + break; } } if (is_bnet_error(sd)) { @@ -325,11 +327,11 @@ void wait_for_storage_daemon_termination(JCR *jcr) Dmsg0(300, "I'm waiting for message thread termination.\n"); pthread_cond_timedwait(&jcr->term_wait, &jcr->mutex, &timeout); if (job_canceled(jcr)) { - cancel_count++; + cancel_count++; } /* Give SD 30 seconds to clean up after cancel */ if (cancel_count == 3) { - break; + break; } } V(jcr->mutex); @@ -351,15 +353,15 @@ extern "C" void *device_thread(void *arg) for (i=0; i < MAX_TRIES; i++) { if (!connect_to_storage_daemon(jcr, 10, 30, 1)) { Dmsg0(000, "Failed connecting to SD.\n"); - continue; + continue; } LockRes(); foreach_res(dev, R_DEVICE) { - if (!update_device_res(jcr, dev)) { + if (!update_device_res(jcr, dev)) { Dmsg1(900, "Error updating device=%s\n", dev->hdr.name); - } else { + } else { Dmsg1(900, "Updated Device=%s\n", dev->hdr.name); - } + } } UnlockRes(); bnet_close(jcr->store_bsock); diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 3f93b37adf..a84c238a22 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -39,7 +39,7 @@ static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s" " VolParts=%u\n"; static char Create_job_media[] = "CatReq Job=%s CreateJobMedia" " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u" - " StartBlock=%u EndBlock=%u\n"; + " StartBlock=%u EndBlock=%u Copy=%d Strip=%d\n"; static char FileAttributes[] = "UpdCat Job=%s FileAttributes "; static char Job_status[] = "Status Job=%s JobStatus=%d\n"; @@ -119,15 +119,15 @@ bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer) /* This is mostly to indicate that we are here */ ok = bnet_fsend(dir, Device_update, jcr->Job, - dev_name.c_str(), /* Changer name */ - 0, 0, 0, /* append, read, num_writers */ - 0, 0, 0, /* is_open, is_labeled, offline */ - 0, 0, /* reserved, max_writers */ - 0, /* Autoselect */ - changer->device->size(), /* Number of devices */ + dev_name.c_str(), /* Changer name */ + 0, 0, 0, /* append, read, num_writers */ + 0, 0, 0, /* is_open, is_labeled, offline */ + 0, 0, /* reserved, max_writers */ + 0, /* Autoselect */ + changer->device->size(), /* Number of devices */ "0", /* PoolId */ "*", /* ChangerName */ - MediaType.c_str(), /* MediaType */ + MediaType.c_str(), /* MediaType */ "*"); /* VolName */ Dmsg1(100, ">dird: %s\n", dir->msg); return ok; @@ -150,7 +150,7 @@ bool dir_send_job_status(JCR *jcr) * dir_find_next_appendable_volume() * * Returns: true on success and vol info in dcr->VolCatInfo - * false on failure + * false on failure */ static bool do_get_volume_info(DCR *dcr) { @@ -160,7 +160,7 @@ static bool do_get_volume_info(DCR *dcr) int n; int InChanger; - dcr->VolumeName[0] = 0; /* No volume */ + dcr->VolumeName[0] = 0; /* No volume */ if (bnet_recv(dir) <= 0) { Dmsg0(200, "getvolname error bnet_recv\n"); Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); @@ -169,27 +169,27 @@ static bool do_get_volume_info(DCR *dcr) memset(&vol, 0, sizeof(vol)); Dmsg1(100, "msg); n = sscanf(dir->msg, OK_media, vol.VolCatName, - &vol.VolCatJobs, &vol.VolCatFiles, - &vol.VolCatBlocks, &vol.VolCatBytes, - &vol.VolCatMounts, &vol.VolCatErrors, - &vol.VolCatWrites, &vol.VolCatMaxBytes, - &vol.VolCatCapacityBytes, vol.VolCatStatus, - &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles, - &InChanger, &vol.VolReadTime, &vol.VolWriteTime, - &vol.EndFile, &vol.EndBlock, &vol.VolCatParts, - &vol.LabelType); + &vol.VolCatJobs, &vol.VolCatFiles, + &vol.VolCatBlocks, &vol.VolCatBytes, + &vol.VolCatMounts, &vol.VolCatErrors, + &vol.VolCatWrites, &vol.VolCatMaxBytes, + &vol.VolCatCapacityBytes, vol.VolCatStatus, + &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles, + &InChanger, &vol.VolReadTime, &vol.VolWriteTime, + &vol.EndFile, &vol.EndBlock, &vol.VolCatParts, + &vol.LabelType); if (n != 21) { Dmsg2(100, "Bad response from Dir fields=%d: %s\n", n, dir->msg); Mmsg(jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg); return false; } - vol.InChanger = InChanger; /* bool in structure */ + vol.InChanger = InChanger; /* bool in structure */ unbash_spaces(vol.VolCatName); bstrncpy(dcr->VolumeName, vol.VolCatName, sizeof(dcr->VolumeName)); memcpy(&dcr->VolCatInfo, &vol, sizeof(dcr->VolCatInfo)); Dmsg2(300, "do_reqest_vol_info got slot=%d Volume=%s\n", - vol.Slot, vol.VolCatName); + vol.Slot, vol.VolCatName); return true; } @@ -198,11 +198,11 @@ static bool do_get_volume_info(DCR *dcr) * Get Volume info for a specific volume from the Director's Database * * Returns: true on success (not Director guarantees that Pool and MediaType - * are correct and VolStatus==Append or - * VolStatus==Recycle) - * false on failure + * are correct and VolStatus==Append or + * VolStatus==Recycle) + * false on failure * - * Volume information returned in jcr + * Volume information returned in jcr */ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { @@ -222,9 +222,9 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) /* * Get info on the next appendable volume in the Director's database * Returns: true on success - * false on failure + * false on failure * - * Volume information returned in dcr + * Volume information returned in dcr * */ bool dir_find_next_appendable_volume(DCR *dcr) @@ -235,9 +235,9 @@ bool dir_find_next_appendable_volume(DCR *dcr) Dmsg0(200, "dir_find_next_appendable_volume\n"); /* - * Try the three oldest or most available volumes. Note, - * the most available could already be mounted on another - * drive, so we continue looking for a not in use Volume. + * Try the three oldest or most available volumes. Note, + * the most available could already be mounted on another + * drive, so we continue looking for a not in use Volume. */ for (int vol_index=1; vol_index < 3; vol_index++) { bash_spaces(dcr->media_type); @@ -248,36 +248,36 @@ bool dir_find_next_appendable_volume(DCR *dcr) Dmsg1(100, ">dird: %s", dir->msg); if (do_get_volume_info(dcr)) { Dmsg2(300, "JobId=%d got possible Vol=%s\n", jcr->JobId, dcr->VolumeName); - bool found = false; - /* - * Walk through all jobs and see if the volume is - * already mounted. If so, try a different one. - * This would be better done by walking through - * all the devices. - */ - lock_jcr_chain(); - foreach_jcr(njcr) { - if (jcr == njcr) { - free_locked_jcr(njcr); - continue; /* us */ - } + bool found = false; + /* + * Walk through all jobs and see if the volume is + * already mounted. If so, try a different one. + * This would be better done by walking through + * all the devices. + */ + lock_jcr_chain(); + foreach_jcr(njcr) { + if (jcr == njcr) { + free_locked_jcr(njcr); + continue; /* us */ + } Dmsg2(300, "Compare to JobId=%d using Vol=%s\n", njcr->JobId, njcr->dcr->VolumeName); - if (njcr->dcr && strcmp(dcr->VolumeName, njcr->dcr->VolumeName) == 0) { - found = true; + if (njcr->dcr && strcmp(dcr->VolumeName, njcr->dcr->VolumeName) == 0) { + found = true; Dmsg1(400, "Vol in use by JobId=%u\n", njcr->JobId); - free_locked_jcr(njcr); - break; - } - free_locked_jcr(njcr); - } - unlock_jcr_chain(); - if (!found) { + free_locked_jcr(njcr); + break; + } + free_locked_jcr(njcr); + } + unlock_jcr_chain(); + if (!found) { Dmsg0(400, "dir_find_next_appendable_volume return true\n"); - return true; /* Got good Volume */ - } + return true; /* Got good Volume */ + } } else { Dmsg0(200, "No volume info, return false\n"); - return false; + return false; } } Dmsg0(400, "dir_find_next_appendable_volume return true\n"); @@ -316,7 +316,7 @@ bool dir_update_volume_info(DCR *dcr, bool label) /* Just labeled or relabeled the tape */ if (label) { bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus)); - vol->VolCatBytes = 1; /* indicates tape labeled */ + vol->VolCatBytes = 1; /* indicates tape labeled */ } pm_strcpy(VolumeName, vol->VolCatName); bash_spaces(VolumeName); @@ -327,7 +327,7 @@ bool dir_update_volume_info(DCR *dcr, bool label) vol->VolCatMounts, vol->VolCatErrors, vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2), LastWritten, vol->VolCatStatus, vol->Slot, label, - InChanger, /* bool in structure */ + InChanger, /* bool in structure */ edit_uint64(vol->VolReadTime, ed3), edit_uint64(vol->VolWriteTime, ed4), vol->VolCatParts); @@ -336,7 +336,7 @@ bool dir_update_volume_info(DCR *dcr, bool label) if (!do_get_volume_info(dcr)) { Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg); Pmsg2(000, "Didn't get vol info vol=%s: ERR=%s", - vol->VolCatName, jcr->errmsg); + vol->VolCatName, jcr->errmsg); return false; } Dmsg1(420, "get_volume_info(): %s", dir->msg); @@ -354,19 +354,20 @@ bool dir_create_jobmedia_record(DCR *dcr) BSOCK *dir = jcr->dir_bsock; if (!dcr->WroteVol) { - return true; /* nothing written to tape */ + return true; /* nothing written to tape */ } dcr->WroteVol = false; bnet_fsend(dir, Create_job_media, jcr->Job, dcr->VolFirstIndex, dcr->VolLastIndex, dcr->StartFile, dcr->EndFile, - dcr->StartBlock, dcr->EndBlock); + dcr->StartBlock, dcr->EndBlock, + dcr->Copy, dcr->Stripe); Dmsg1(100, ">dird: %s", dir->msg); if (bnet_recv(dir) <= 0) { Dmsg0(190, "create_jobmedia error bnet_recv\n"); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"), - bnet_strerror(dir)); + bnet_strerror(dir)); return false; } Dmsg1(100, "msg); @@ -394,7 +395,7 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) dir->msglen = sprintf(dir->msg, FileAttributes, jcr->Job); dir->msg = check_pool_memory_size(dir->msg, dir->msglen + - sizeof(DEV_RECORD) + rec->data_len); + sizeof(DEV_RECORD) + rec->data_len); ser_begin(dir->msg + dir->msglen, 0); ser_uint32(rec->VolSessionId); ser_uint32(rec->VolSessionTime); @@ -415,16 +416,16 @@ bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) * Leaves with device blocked. * * Returns: true on success (operator issues a mount command) - * false on failure - * Note, must create dev->errmsg on error return. + * false on failure + * Note, must create dev->errmsg on error return. * * On success, dcr->VolumeName and dcr->VolCatInfo contain - * information on suggested volume, but this may not be the - * same as what is actually mounted. + * information on suggested volume, but this may not be the + * same as what is actually mounted. * * When we return with success, the correct tape may or may not - * actually be mounted. The calling routine must read it and - * verify the label. + * actually be mounted. The calling routine must read it and + * verify the label. */ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { @@ -438,51 +439,51 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) ASSERT(dev->dev_blocked); for ( ;; ) { if (job_canceled(jcr)) { - Mmsg(dev->errmsg, + Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"), - jcr->Job, dev->print_name()); + jcr->Job, dev->print_name()); Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); - return false; + return false; } /* First pass, we *know* there are no appendable volumes, so no need to call */ if (!first && dir_find_next_appendable_volume(dcr)) { /* get suggested volume */ - unmounted = (dev->dev_blocked == BST_UNMOUNTED) || - (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); - /* - * If we have a valid volume name and we are not - * removable media, return now, or if we have a - * Slot for an autochanger, otherwise wait - * for the operator to mount the media. - */ - if (!unmounted && ((dcr->VolumeName[0] && !dev_cap(dev, CAP_REM) && - dev_cap(dev, CAP_LABEL)) || - (dcr->VolumeName[0] && dcr->VolCatInfo.Slot))) { + unmounted = (dev->dev_blocked == BST_UNMOUNTED) || + (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); + /* + * If we have a valid volume name and we are not + * removable media, return now, or if we have a + * Slot for an autochanger, otherwise wait + * for the operator to mount the media. + */ + if (!unmounted && ((dcr->VolumeName[0] && !dev_cap(dev, CAP_REM) && + dev_cap(dev, CAP_LABEL)) || + (dcr->VolumeName[0] && dcr->VolCatInfo.Slot))) { Dmsg0(400, "Return 1 from mount without wait.\n"); - return true; - } - jstat = JS_WaitMount; - if (!dev->poll) { - Jmsg(jcr, M_MOUNT, 0, _( + return true; + } + jstat = JS_WaitMount; + if (!dev->poll) { + Jmsg(jcr, M_MOUNT, 0, _( "Please mount Volume \"%s\" on Storage Device %s for Job %s\n" "Use \"mount\" command to release Job.\n"), - dcr->VolumeName, dev->print_name(), jcr->Job); + dcr->VolumeName, dev->print_name(), jcr->Job); Dmsg3(400, "Mount %s on %s for Job %s\n", - dcr->VolumeName, dcr->dev_name, jcr->Job); - } + dcr->VolumeName, dcr->dev_name, jcr->Job); + } } else { - jstat = JS_WaitMedia; - if (!dev->poll) { - Jmsg(jcr, M_MOUNT, 0, _( + jstat = JS_WaitMedia; + if (!dev->poll) { + Jmsg(jcr, M_MOUNT, 0, _( "Job %s waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Media type: %s\n" " Pool: %s\n"), - jcr->Job, - dev->print_name(), - dcr->media_type, - dcr->pool_name); - } + jcr->Job, + dev->print_name(), + dcr->media_type, + dcr->pool_name); + } } first = false; @@ -492,47 +493,47 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) stat = wait_for_sysop(dcr); if (dev->poll) { Dmsg1(400, "Poll timeout in create append vol on device %s\n", dev->print_name()); - continue; + continue; } if (stat == ETIMEDOUT) { - if (!double_dev_wait_time(dev)) { + if (!double_dev_wait_time(dev)) { Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"), - dev->print_name(), jcr->Job); + dev->print_name(), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name()); - return false; /* exceeded maximum waits */ - } - continue; + return false; /* exceeded maximum waits */ + } + continue; } if (stat == EINVAL) { - berrno be; + berrno be; Mmsg2(dev->errmsg, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), - stat, be.strerror(stat)); + stat, be.strerror(stat)); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - return false; + return false; } if (stat != 0) { - berrno be; + berrno be; Jmsg(jcr, M_WARNING, 0, _("pthread error in mount_next_volume stat=%d ERR=%s\n"), stat, - be.strerror(stat)); + be.strerror(stat)); } Dmsg1(400, "Someone woke me for device %s\n", dev->print_name()); /* If no VolumeName, and cannot get one, try again */ if (dcr->VolumeName[0] == 0 && !job_canceled(jcr) && - !dir_find_next_appendable_volume(dcr)) { - Jmsg(jcr, M_MOUNT, 0, _( + !dir_find_next_appendable_volume(dcr)) { + Jmsg(jcr, M_MOUNT, 0, _( "Someone woke me up, but I cannot find any appendable\n" "volumes for Job=%s.\n"), jcr->Job); - /* Restart wait counters after user interaction */ - init_device_wait_timers(dcr); - continue; + /* Restart wait counters after user interaction */ + init_device_wait_timers(dcr); + continue; } unmounted = (dev->dev_blocked == BST_UNMOUNTED) || - (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); + (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); if (unmounted) { - continue; /* continue to wait */ + continue; /* continue to wait */ } /* @@ -550,12 +551,12 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) * Request to mount specific Volume * * Entered with device blocked and dcr->VolumeName is desired - * volume. + * volume. * Leaves with device blocked. * * Returns: true on success (operator issues a mount command) - * false on failure - * Note, must create dev->errmsg on error return. + * false on failure + * Note, must create dev->errmsg on error return. * */ bool dir_ask_sysop_to_mount_volume(DCR *dcr) @@ -574,49 +575,49 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) for ( ;; ) { if (job_canceled(jcr)) { Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"), - jcr->Job, dev->print_name()); - return false; + jcr->Job, dev->print_name()); + return false; } if (!dev->poll) { msg = _("Please mount"); Jmsg(jcr, M_MOUNT, 0, _("%s Volume \"%s\" on Storage Device %s for Job %s\n"), - msg, dcr->VolumeName, dev->print_name(), jcr->Job); + msg, dcr->VolumeName, dev->print_name(), jcr->Job); Dmsg3(400, "Mount \"%s\" on device \"%s\" for Job %s\n", - dcr->VolumeName, dcr->dev_name, jcr->Job); + dcr->VolumeName, dcr->dev_name, jcr->Job); } jcr->JobStatus = JS_WaitMount; dir_send_job_status(jcr); - stat = wait_for_sysop(dcr); ; /* wait on device */ + stat = wait_for_sysop(dcr); ; /* wait on device */ if (dev->poll) { Dmsg1(400, "Poll timeout in mount vol on device %s\n", dev->print_name()); Dmsg1(400, "Blocked=%s\n", edit_blocked_reason(dev)); - return true; + return true; } if (stat == ETIMEDOUT) { - if (!double_dev_wait_time(dev)) { + if (!double_dev_wait_time(dev)) { Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"), - dev->print_name(), jcr->Job); + dev->print_name(), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name()); - return false; /* exceeded maximum waits */ - } - continue; + return false; /* exceeded maximum waits */ + } + continue; } if (stat == EINVAL) { - berrno be; + berrno be; Mmsg2(dev->errmsg, _("pthread error in mount_volume stat=%d ERR=%s\n"), - stat, be.strerror(stat)); + stat, be.strerror(stat)); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - return false; + return false; } if (stat != 0) { - berrno be; + berrno be; Jmsg(jcr, M_FATAL, 0, _("pthread error in mount_next_volume stat=%d: ERR=%s\n"), stat, - be.strerror(stat)); + be.strerror(stat)); } Dmsg1(400, "Someone woke me for device %s\n", dev->print_name()); break; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index bd9df85310..3aa8f06546 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -340,6 +340,8 @@ public: char pool_type[MAX_NAME_LENGTH]; /* pool type */ char media_type[MAX_NAME_LENGTH]; /* media type */ char dev_name[MAX_NAME_LENGTH]; /* dev name */ + int Copy; /* identical copy number */ + int Stripe; /* RAIT stripe */ VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */ }; diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 4dc568b35e..c77d950168 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -43,7 +43,7 @@ static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s " "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s " "SpoolData=%d WritePartAfterJob=%d NewVol=%d\n"; static char use_storage[] = "use storage=%127s media_type=%127s " - "pool_name=%127s pool_type=%127s append=%d\n"; + "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n"; static char use_device[] = "use device=%127s\n"; //static char query_device[] = "query device=%127s"; @@ -85,10 +85,10 @@ bool job_cmd(JCR *jcr) */ Dmsg1(100, "msg); if (sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(), - client_name.c_str(), - &JobType, &level, fileset_name.c_str(), &no_attributes, - &spool_attributes, fileset_md5.c_str(), &spool_data, - &write_part_after_job, &NewVol) != 13) { + client_name.c_str(), + &JobType, &level, fileset_name.c_str(), &no_attributes, + &spool_attributes, fileset_md5.c_str(), &spool_data, + &write_part_after_job, &NewVol) != 13) { pm_strcpy(jcr->errmsg, dir->msg); bnet_fsend(dir, BAD_job, jcr->errmsg); Dmsg1(100, ">dird: %s\n", dir->msg); @@ -173,12 +173,12 @@ bool run_cmd(JCR *jcr) return false; } - set_jcr_job_status(jcr, JS_WaitFD); /* wait for FD to connect */ + set_jcr_job_status(jcr, JS_WaitFD); /* wait for FD to connect */ dir_send_job_status(jcr); gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; - timeout.tv_sec = tv.tv_sec + 30 * 60; /* wait 30 minutes */ + timeout.tv_sec = tv.tv_sec + 30 * 60; /* wait 30 minutes */ Dmsg1(100, "%s waiting on FD to contact SD\n", jcr->Job); /* @@ -190,7 +190,7 @@ bool run_cmd(JCR *jcr) for ( ;!job_canceled(jcr); ) { errstat = pthread_cond_timedwait(&jcr->job_start_wait, &jcr->mutex, &timeout); if (errstat == 0 || errstat == ETIMEDOUT) { - break; + break; } } V(jcr->mutex); @@ -199,7 +199,7 @@ bool run_cmd(JCR *jcr) if (jcr->authenticated && !job_canceled(jcr)) { Dmsg1(100, "Running job %s\n", jcr->Job); - run_job(jcr); /* Run the job */ + run_job(jcr); /* Run the job */ } return false; } @@ -212,7 +212,7 @@ void handle_filed_connection(BSOCK *fd, char *job_name) { JCR *jcr; - bmicrosleep(0, 50000); /* wait 50 millisecs */ + bmicrosleep(0, 50000); /* wait 50 millisecs */ if (!(jcr=get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("Job name not found: %s\n"), job_name); Dmsg1(100, "Job name not found: %s\n", job_name); @@ -226,7 +226,7 @@ void handle_filed_connection(BSOCK *fd, char *job_name) if (jcr->authenticated) { Jmsg2(jcr, M_FATAL, 0, "Hey!!!! JobId %u Job %s already authenticated.\n", - jcr->JobId, jcr->Job); + jcr->JobId, jcr->Job); free_jcr(jcr); return; } @@ -256,10 +256,10 @@ void handle_filed_connection(BSOCK *fd, char *job_name) /* * Use Device command from Director * He tells is what Device Name to use, the Media Type, - * the Pool Name, and the Pool Type. + * the Pool Name, and the Pool Type. * * Ensure that the device exists and is opened, then store - * the media and pool info in the JCR. + * the media and pool info in the JCR. */ class DIRSTORE { public: @@ -282,145 +282,148 @@ static bool use_storage_cmd(JCR *jcr) AUTOCHANGER *changer; int append; bool ok; + int Copy, Stripe; /* * If there are multiple devices, the director sends us - * use_device for each device that it wants to use. + * use_device for each device that it wants to use. */ Dmsg1(100, "msg); ok = sscanf(dir->msg, use_storage, store_name.c_str(), media_type.c_str(), pool_name.c_str(), - pool_type.c_str(), &append) == 5; + pool_type.c_str(), &append, &Copy, &Stripe) == 7; if (ok) { unbash_spaces(store_name); unbash_spaces(media_type); unbash_spaces(pool_name); unbash_spaces(pool_type); if (bnet_recv(dir) <= 0) { - return false; + return false; } ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1; if (!ok) { - return false; + return false; } /* Eat to BNET_EOD */ while (bnet_recv(dir) > 0) { } LockRes(); foreach_res(device, R_DEVICE) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 && - strcmp(device->media_type, media_type.c_str()) == 0) { - const int name_len = MAX_NAME_LENGTH; - DCR *dcr; - UnlockRes(); - if (!device->dev) { - device->dev = init_dev(jcr, NULL, device); - } - if (!device->dev) { + /* Find resource, and make sure we were able to open it */ + if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 && + strcmp(device->media_type, media_type.c_str()) == 0) { + const int name_len = MAX_NAME_LENGTH; + DCR *dcr; + UnlockRes(); + if (!device->dev) { + device->dev = init_dev(jcr, NULL, device); + } + if (!device->dev) { Jmsg(jcr, M_WARNING, 0, _("\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n"), - dev_name.c_str()); - bnet_fsend(dir, NOT_open, dev_name.c_str()); + dev_name.c_str()); + bnet_fsend(dir, NOT_open, dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); - return false; - } - dcr = new_dcr(jcr, device->dev); - if (!dcr) { + return false; + } + dcr = new_dcr(jcr, device->dev); + if (!dcr) { bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); - return false; - } + return false; + } Dmsg1(100, "Found device %s\n", device->hdr.name); - bstrncpy(dcr->pool_name, pool_name, name_len); - bstrncpy(dcr->pool_type, pool_type, name_len); - bstrncpy(dcr->media_type, media_type, name_len); - bstrncpy(dcr->dev_name, dev_name, name_len); - jcr->dcr = dcr; - if (append == SD_APPEND) { - ok = reserve_device_for_append(dcr); - } else { - ok = reserve_device_for_read(dcr); - } - if (!ok) { + bstrncpy(dcr->pool_name, pool_name, name_len); + bstrncpy(dcr->pool_type, pool_type, name_len); + bstrncpy(dcr->media_type, media_type, name_len); + bstrncpy(dcr->dev_name, dev_name, name_len); + dcr->Copy = Copy; + dcr->Stripe = Stripe; + jcr->dcr = dcr; + if (append == SD_APPEND) { + ok = reserve_device_for_append(dcr); + } else { + ok = reserve_device_for_read(dcr); + } + if (!ok) { bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); - free_dcr(jcr->dcr); - return false; - } + free_dcr(jcr->dcr); + return false; + } Dmsg1(220, "Got: %s", dir->msg); - bash_spaces(dev_name); - ok = bnet_fsend(dir, OK_device, dev_name.c_str()); + bash_spaces(dev_name); + ok = bnet_fsend(dir, OK_device, dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); - return ok; - } + return ok; + } } foreach_res(changer, R_AUTOCHANGER) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) { - const int name_len = MAX_NAME_LENGTH; - DCR *dcr; - /* Try each device in this AutoChanger */ - foreach_alist(device, changer->device) { + /* Find resource, and make sure we were able to open it */ + if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) { + const int name_len = MAX_NAME_LENGTH; + DCR *dcr; + /* Try each device in this AutoChanger */ + foreach_alist(device, changer->device) { Dmsg1(100, "Try changer device %s\n", device->hdr.name); - if (!device->dev) { - device->dev = init_dev(jcr, NULL, device); - } - if (!device->dev) { + if (!device->dev) { + device->dev = init_dev(jcr, NULL, device); + } + if (!device->dev) { Dmsg1(100, "Device %s could not be opened. Skipped\n", dev_name.c_str()); Jmsg(jcr, M_WARNING, 0, _("\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"), - device->hdr.name, dev_name.c_str()); - continue; - } - if (!device->dev->autoselect) { - continue; /* device is not available */ - } - dcr = new_dcr(jcr, device->dev); - if (!dcr) { + device->hdr.name, dev_name.c_str()); + continue; + } + if (!device->dev->autoselect) { + continue; /* device is not available */ + } + dcr = new_dcr(jcr, device->dev); + if (!dcr) { bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); - UnlockRes(); - return false; - } + UnlockRes(); + return false; + } Dmsg1(100, "Found changer device %s\n", device->hdr.name); - bstrncpy(dcr->pool_name, pool_name, name_len); - bstrncpy(dcr->pool_type, pool_type, name_len); - bstrncpy(dcr->media_type, media_type, name_len); - bstrncpy(dcr->dev_name, dev_name, name_len); - jcr->dcr = dcr; - if (append == SD_APPEND) { - ok = reserve_device_for_append(dcr); - } else { - ok = reserve_device_for_read(dcr); - } - if (!ok) { + bstrncpy(dcr->pool_name, pool_name, name_len); + bstrncpy(dcr->pool_type, pool_type, name_len); + bstrncpy(dcr->media_type, media_type, name_len); + bstrncpy(dcr->dev_name, dev_name, name_len); + jcr->dcr = dcr; + if (append == SD_APPEND) { + ok = reserve_device_for_append(dcr); + } else { + ok = reserve_device_for_read(dcr); + } + if (!ok) { Jmsg(jcr, M_WARNING, 0, _("Could not reserve device: %s\n"), dev_name.c_str()); - free_dcr(jcr->dcr); - continue; - } + free_dcr(jcr->dcr); + continue; + } Dmsg1(100, "Device %s opened.\n", dev_name.c_str()); - UnlockRes(); - pm_strcpy(dev_name, device->hdr.name); - bash_spaces(dev_name); - ok = bnet_fsend(dir, OK_device, dev_name.c_str()); + UnlockRes(); + pm_strcpy(dev_name, device->hdr.name); + bash_spaces(dev_name); + ok = bnet_fsend(dir, OK_device, dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); - return ok; - } - break; /* we found it but could not open a device */ - } + return ok; + } + break; /* we found it but could not open a device */ + } } UnlockRes(); if (verbose) { - unbash_spaces(dir->msg); - pm_strcpy(jcr->errmsg, dir->msg); + unbash_spaces(dir->msg); + pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); } Jmsg(jcr, M_FATAL, 0, _("\n" " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"), - dev_name.c_str(), media_type.c_str()); + dev_name.c_str(), media_type.c_str()); bnet_fsend(dir, NO_device, dev_name.c_str()); Dmsg1(100, ">dird: %s\n", dir->msg); } else { @@ -434,7 +437,7 @@ static bool use_storage_cmd(JCR *jcr) Dmsg1(100, ">dird: %s\n", dir->msg); } - return false; /* ERROR return */ + return false; /* ERROR return */ } #ifdef needed @@ -461,39 +464,39 @@ bool query_cmd(JCR *jcr) unbash_spaces(dev_name); LockRes(); foreach_res(device, R_DEVICE) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0) { - if (!device->dev) { - device->dev = init_dev(jcr, NULL, device); - } - if (!device->dev) { - break; - } - UnlockRes(); - ok = dir_update_device(jcr, device->dev); - if (ok) { - ok = bnet_fsend(dir, OK_query); - } else { - bnet_fsend(dir, NO_query); - } - return ok; - } + /* Find resource, and make sure we were able to open it */ + if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0) { + if (!device->dev) { + device->dev = init_dev(jcr, NULL, device); + } + if (!device->dev) { + break; + } + UnlockRes(); + ok = dir_update_device(jcr, device->dev); + if (ok) { + ok = bnet_fsend(dir, OK_query); + } else { + bnet_fsend(dir, NO_query); + } + return ok; + } } foreach_res(changer, R_AUTOCHANGER) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) { - UnlockRes(); - if (!changer->device || changer->device->size() == 0) { - continue; /* no devices */ - } - ok = dir_update_changer(jcr, changer); - if (ok) { - ok = bnet_fsend(dir, OK_query); - } else { - bnet_fsend(dir, NO_query); - } - return ok; - } + /* Find resource, and make sure we were able to open it */ + if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) { + UnlockRes(); + if (!changer->device || changer->device->size() == 0) { + continue; /* no devices */ + } + ok = dir_update_changer(jcr, changer); + if (ok) { + ok = bnet_fsend(dir, OK_query); + } else { + bnet_fsend(dir, NO_query); + } + return ok; + } } /* If we get here, the device/autochanger was not found */ UnlockRes(); diff --git a/bacula/src/version.h b/bacula/src/version.h index df1bd94f5a..725330d613 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION -#define VERSION "1.37.11" -#define BDATE "31 March 2005" -#define LSMDATE "31Mar05" +#define VERSION "1.37.12" +#define BDATE "02 April 2005" +#define LSMDATE "02Apr05" /* Debug flags */ #undef DEBUG -- 2.39.5