+++ /dev/null
- This patch was submited by Dirk Nehring and permit to track
- real job size in the catalog.
-
- Add ReadBytes to Job (physical bytes read)
- Add code to fill the field
-
-
-
-diff -ur bacula-2.4.2.orig/src/cats/make_mysql_tables.in bacula-2.4.2/src/cats/make_mysql_tables.in
---- bacula-2.4.2.orig/src/cats/make_mysql_tables.in 2007-10-22 12:31:08.000000000 +0200
-+++ bacula-2.4.2/src/cats/make_mysql_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -102,6 +102,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
-diff -ur bacula-2.4.2.orig/src/cats/make_postgresql_tables.in bacula-2.4.2/src/cats/make_postgresql_tables.in
---- bacula-2.4.2.orig/src/cats/make_postgresql_tables.in 2007-03-30 23:46:04.000000000 +0200
-+++ bacula-2.4.2/src/cats/make_postgresql_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -67,6 +67,7 @@
- volsessiontime integer default 0,
- jobfiles integer default 0,
- jobbytes bigint default 0,
-+ readbytes bigint default 0,
- joberrors integer default 0,
- jobmissingfiles integer default 0,
- poolid integer default 0,
-diff -ur bacula-2.4.2.orig/src/cats/make_sqlite3_tables.in bacula-2.4.2/src/cats/make_sqlite3_tables.in
---- bacula-2.4.2.orig/src/cats/make_sqlite3_tables.in 2007-06-03 22:27:52.000000000 +0200
-+++ bacula-2.4.2/src/cats/make_sqlite3_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -64,6 +64,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-diff -ur bacula-2.4.2.orig/src/cats/make_sqlite_tables.in bacula-2.4.2/src/cats/make_sqlite_tables.in
---- bacula-2.4.2.orig/src/cats/make_sqlite_tables.in 2007-03-30 23:46:04.000000000 +0200
-+++ bacula-2.4.2/src/cats/make_sqlite_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -64,6 +64,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-diff -ur bacula-2.4.2.orig/src/cats/make_test_tables bacula-2.4.2/src/cats/make_test_tables
---- bacula-2.4.2.orig/src/cats/make_test_tables 2002-04-23 21:48:51.000000000 +0200
-+++ bacula-2.4.2/src/cats/make_test_tables 2008-07-28 09:06:17.000000000 +0200
-@@ -49,6 +49,7 @@
- VolSessionTime INTEGER UNSIGNED NOT NULL,
- JobFiles INTEGER UNSIGNED NOT NULL,
- JobBytes BIGINT UNSIGNED NOT NULL,
-+ ReadBytes BIGINT UNSIGNED NOT NULL,
- JobErrors INTEGER UNSIGNED NOT NULL,
- JobMissingFiles INTEGER UNSIGNED NOT NULL,
- PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
-diff -ur bacula-2.4.2.orig/src/cats/sql_update.c bacula-2.4.2/src/cats/sql_update.c
---- bacula-2.4.2.orig/src/cats/sql_update.c 2007-06-07 16:46:43.000000000 +0200
-+++ bacula-2.4.2/src/cats/sql_update.c 2008-07-28 09:06:17.000000000 +0200
-@@ -149,7 +149,7 @@
- time_t ttime;
- struct tm tm;
- int stat;
-- char ed1[30], ed2[30], ed3[50];
-+ char ed1[30], ed2[30], ed3[50], ed4[50];
- btime_t JobTDate;
- char PoolId[50], FileSetId[50], ClientId[50], PriorJobId[50];
-
-@@ -181,10 +181,11 @@
- db_lock(mdb);
- Mmsg(mdb->cmd,
- "UPDATE Job SET JobStatus='%c',EndTime='%s',"
--"ClientId=%s,JobBytes=%s,JobFiles=%u,JobErrors=%u,VolSessionId=%u,"
-+"ClientId=%s,JobBytes=%s,ReadBytes=%s,JobFiles=%u,JobErrors=%u,VolSessionId=%u,"
- "VolSessionTime=%u,PoolId=%s,FileSetId=%s,JobTDate=%s,"
- "RealEndTime='%s',PriorJobId=%s WHERE JobId=%s",
- (char)(jr->JobStatus), dt, ClientId, edit_uint64(jr->JobBytes, ed1),
-+ edit_uint64(jcr->ReadBytes, ed4),
- jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime,
- PoolId, FileSetId, edit_uint64(JobTDate, ed2),
- rdt,
-diff -ur bacula-2.4.2.orig/src/cats/update_mysql_tables.in bacula-2.4.2/src/cats/update_mysql_tables.in
---- bacula-2.4.2.orig/src/cats/update_mysql_tables.in 2007-03-30 23:46:04.000000000 +0200
-+++ bacula-2.4.2/src/cats/update_mysql_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -63,6 +63,8 @@
- ALTER TABLE Job ADD COLUMN PriorJobId INTEGER UNSIGNED DEFAULT 0 REFERENCES Job;
- ALTER TABLE Job ADD COLUMN RealEndTime DATETIME DEFAULT 0;
-
-+-- 3.0 additions
-+ALTER TABLE Job ADD ReadBytes BIGINT UNSIGNED DEFAULT 0 AFTER JobBytes;
-
-
- DELETE FROM Version;
-diff -ur bacula-2.4.2.orig/src/cats/update_postgresql_tables.in bacula-2.4.2/src/cats/update_postgresql_tables.in
---- bacula-2.4.2.orig/src/cats/update_postgresql_tables.in 2007-03-30 23:46:04.000000000 +0200
-+++ bacula-2.4.2/src/cats/update_postgresql_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -73,6 +73,9 @@
- DELETE FROM version;
- INSERT INTO version (versionId) VALUES (10);
-
-+-- 3.0 additions
-+ALTER TABLE job ADD COLUMN readbytes bigint default 0;
-+
- vacuum;
-
- END-OF-DATA
-diff -ur bacula-2.4.2.orig/src/cats/update_sqlite3_tables.in bacula-2.4.2/src/cats/update_sqlite3_tables.in
---- bacula-2.4.2.orig/src/cats/update_sqlite3_tables.in 2007-03-30 23:46:04.000000000 +0200
-+++ bacula-2.4.2/src/cats/update_sqlite3_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -157,6 +157,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -170,7 +171,7 @@
- JobId, Job, Name, Type, Level, ClientId, JobStatus,
- SchedTime, StartTime, EndTime, 0,
- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-+ JobFiles, JobBytes, 0, JobErrors, JobMissingFiles,
- PoolId, FileSetId, 0, PurgedFiles, HasBase
- FROM Job;
-
-@@ -194,6 +195,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -209,7 +211,7 @@
- JobId, Job, Name, Type, Level, ClientId, JobStatus,
- SchedTime, StartTime, EndTime, RealEndTime,
- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-+ JobFiles, JobBytes, ReadBytes, JobErrors, JobMissingFiles,
- PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase)
- SELECT * FROM Job_backup;
-
-diff -ur bacula-2.4.2.orig/src/cats/update_sqlite_tables.in bacula-2.4.2/src/cats/update_sqlite_tables.in
---- bacula-2.4.2.orig/src/cats/update_sqlite_tables.in 2007-03-30 23:46:04.000000000 +0200
-+++ bacula-2.4.2/src/cats/update_sqlite_tables.in 2008-07-28 09:06:17.000000000 +0200
-@@ -157,6 +157,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -170,7 +171,7 @@
- JobId, Job, Name, Type, Level, ClientId, JobStatus,
- SchedTime, StartTime, EndTime, 0,
- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-+ JobFiles, JobBytes, 0, JobErrors, JobMissingFiles,
- PoolId, FileSetId, 0, PurgedFiles, HasBase
- FROM Job;
-
-@@ -194,6 +195,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-diff -ur bacula-2.4.2.orig/src/dird/backup.c bacula-2.4.2/src/dird/backup.c
---- bacula-2.4.2.orig/src/dird/backup.c 2008-01-09 08:29:57.000000000 +0100
-+++ bacula-2.4.2/src/dird/backup.c 2008-07-28 09:16:24.000000000 +0200
-@@ -339,7 +339,7 @@
- {
- char sdt[50], edt[50], schedt[50];
- char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], compress[50];
-- char ec6[30], ec7[30], ec8[30], elapsed[50];
-+ char ec6[30], ec7[30], ec8[30], ec9[30], ec10[30], elapsed[50];
- char term_code[100], fd_term_msg[100], sd_term_msg[100];
- const char *term_msg;
- int msg_type = M_INFO;
-@@ -461,6 +461,7 @@
- " Priority: %d\n"
- " FD Files Written: %s\n"
- " SD Files Written: %s\n"
-+" FD Bytes Read: %s (%sB)\n"
- " FD Bytes Written: %s (%sB)\n"
- " SD Bytes Written: %s (%sB)\n"
- " Rate: %.1f KB/s\n"
-@@ -492,6 +493,8 @@
- jcr->JobPriority,
- edit_uint64_with_commas(jcr->jr.JobFiles, ec1),
- edit_uint64_with_commas(jcr->SDJobFiles, ec2),
-+ edit_uint64_with_commas(jcr->ReadBytes, ec9),
-+ edit_uint64_with_suffix(jcr->ReadBytes, ec10),
- edit_uint64_with_commas
+++ /dev/null
-Index: src/dird/catreq.c
-===================================================================
---- src/dird/catreq.c (révision 8270)
-+++ src/dird/catreq.c (copie de travail)
-@@ -357,13 +357,11 @@
- }
-
- /*
-- * Update File Attributes in the catalog with data
-- * sent by the Storage daemon. Note, we receive the whole
-- * attribute record, but we select out only the stat packet,
-- * VolSessionId, VolSessionTime, FileIndex, file type, and
-- * file name to store in the catalog.
-+ * Note, we receive the whole attribute record, but we select out only the stat
-+ * packet, VolSessionId, VolSessionTime, FileIndex, file type, and file name to
-+ * store in the catalog.
- */
--void catalog_update(JCR *jcr, BSOCK *bs)
-+static void update_attribute(JCR *jcr, char *msg, int32_t msglen)
- {
- unser_declare;
- uint32_t VolSessionId, VolSessionTime;
-@@ -375,20 +373,7 @@
- int len;
- char *fname, *attr;
- ATTR_DBR *ar = NULL;
-- POOLMEM *omsg;
-
-- if (job_canceled(jcr) || !jcr->pool->catalog_files) {
-- goto bail_out; /* user disabled cataloging */
-- }
-- if (!jcr->db) {
-- omsg = get_memory(bs->msglen+1);
-- pm_strcpy(omsg, bs->msg);
-- bs->fsend(_("1994 Invalid Catalog Update: %s"), omsg);
-- Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog Update; DB not open: %s"), omsg);
-- free_memory(omsg);
-- goto bail_out;
-- }
--
- /* Start transaction allocates jcr->attr and jcr->ar if needed */
- db_start_transaction(jcr, jcr->db); /* start transaction if not already open */
- ar = jcr->ar;
-@@ -397,7 +382,7 @@
- * there may be a cached attr so we cannot yet write into
- * jcr->attr or jcr->ar
- */
-- p = bs->msg;
-+ p = msg;
- skip_nonspaces(&p); /* UpdCat */
- skip_spaces(&p);
- skip_nonspaces(&p); /* Job=nnn */
-@@ -412,7 +397,7 @@
- unser_uint32(data_len);
- p += unser_length(p);
-
-- Dmsg1(400, "UpdCat msg=%s\n", bs->msg);
-+ Dmsg1(400, "UpdCat msg=%s\n", msg);
- Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
- VolSessionId, VolSessionTime, FileIndex, Stream, data_len);
-
-@@ -424,9 +409,9 @@
- }
- }
- /* Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */
-- jcr->attr = check_pool_memory_size(jcr->attr, bs->msglen);
-- memcpy(jcr->attr, bs->msg, bs->msglen);
-- p = jcr->attr - bs->msg + p; /* point p into jcr->attr */
-+ jcr->attr = check_pool_memory_size(jcr->attr, msglen);
-+ memcpy(jcr->attr, msg, msglen);
-+ p = jcr->attr - msg + p; /* point p into jcr->attr */
- skip_nonspaces(&p); /* skip FileIndex */
- skip_spaces(&p);
- filetype = str_to_int32(p); /* TODO: choose between unserialize and str_to_int32 */
-@@ -510,8 +495,110 @@
- }
- }
- }
-+}
-+
-+/*
-+ * Update File Attributes in the catalog with data
-+ * sent by the Storage daemon.
-+ */
-+void catalog_update(JCR *jcr, BSOCK *bs)
-+{
-+ POOLMEM *omsg;
-+
-+ if (job_canceled(jcr) || !jcr->pool->catalog_files) {
-+ goto bail_out; /* user disabled cataloging */
-+ }
-+ if (!jcr->db) {
-+ omsg = get_memory(bs->msglen+1);
-+ pm_strcpy(omsg, bs->msg);
-+ bs->fsend(_("1994 Invalid Catalog Update: %s"), omsg);
-+ Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog Update; DB not open: %s"), omsg);
-+ free_memory(omsg);
-+ goto bail_out;
-+
-+ }
-+
-+ update_attribute(jcr, bs->msg, bs->msglen);
-+
- bail_out:
- if (job_canceled(jcr)) {
- cancel_storage_daemon_job(jcr);
- }
- }
-+
-+/*
-+ * Update File Attributes in the catalog with data read from
-+ * the storage daemon spool file. We receive the filename and
-+ * we try to read it.
-+ */
-+bool despool_attributes_from_file(JCR *jcr, const char *file)
-+{
-+ bool ret=false;
-+ int32_t pktsiz;
-+ size_t nbytes;
-+ ssize_t last = 0, size = 0;
-+ int count = 0;
-+ int32_t msglen; /* message length */
-+ POOLMEM *msg = get_pool_memory(PM_MESSAGE);
-+ FILE *spool_fd=NULL;
-+
-+ Dmsg0(0, "Begin despool_attributes_from_file\n");
-+
-+ if (job_canceled(jcr) || !jcr->pool->catalog_files || !jcr->db) {
-+ goto bail_out; /* user disabled cataloging */
-+ }
-+
-+ spool_fd = fopen(file, "rb");
-+ if (!spool_fd) {
-+ Dmsg0(0, "cancel despool_attributes_from_file\n");
-+ /* send an error message */
-+ goto bail_out;
-+ }
-+#if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
-+ posix_fadvise(fileno(spool_fd), 0, 0, POSIX_FADV_WILLNEED);
-+#endif
-+
-+ while (fread((char *)&pktsiz, 1, sizeof(int32_t), spool_fd) ==
-+ sizeof(int32_t)) {
-+ size += sizeof(int32_t);
-+ msglen = ntohl(pktsiz);
-+ if (msglen > 0) {
-+ if (msglen > (int32_t) sizeof_pool_memory(msg)) {
-+ msg = realloc_pool_memory(msg, msglen + 1);
-+ }
-+ nbytes = fread(msg, 1, msglen, spool_fd);
-+ if (nbytes != (size_t) msglen) {
-+ berrno be;
-+ Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, msglen);
-+ Qmsg1(jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
-+ be.bstrerror());
-+ goto bail_out;
-+ }
-+ size += nbytes;
-+ if ((++count & 0x3F) == 0) {
-+ last = size;
-+ }
-+ }
-+ update_attribute(jcr, msg, msglen);
-+ }
-+ if (ferror(spool_fd)) {
-+ berrno be;
-+ Qmsg1(jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
-+ be.bstrerror());
-+ goto bail_out;
-+ }
-+ ret = true;
-+
-+bail_out:
-+ if (spool_fd) {
-+ fclose(spool_fd);
-+ }
-+
-+ if (job_canceled(jcr)) {
-+ cancel_storage_daemon_job(jcr);
-+ }
-+
-+ free_pool_memory(msg);
-+ Dmsg1(0, "End despool_attributes_from_file ret=%i\n", ret);
-+ return ret;
-+}
-Index: src/dird/getmsg.c
-===================================================================
---- src/dird/getmsg.c (révision 8270)
-+++ src/dird/getmsg.c (copie de travail)
-@@ -135,7 +135,7 @@
-
- for (;;) {
- n = bs->recv();
-- Dmsg2(300, "bget_dirmsg %d: %s\n", n, bs->msg);
-+ Dmsg2(100, "bget_dirmsg %d: %s\n", n, bs->msg);
-
- if (is_bnet_stop(bs)) {
- return n; /* error or terminate */
-@@ -236,6 +236,22 @@
- catalog_update(jcr, bs);
- continue;
- }
-+ if (bs->msg[0] == 'B') { /* SD sending file spool attributes */
-+ Dmsg2(0, "Blast attributes jcr 0x%x: %s", jcr, bs->msg);
-+ char filename[MAX_NAME_LENGTH];
-+ if (sscanf(bs->msg, "BlastAttr Job=%127s File=%127s",
-+ Job, filename) != 2) {
-+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
-+ continue;
-+ }
-+ unbash_spaces(filename);
-+ if (despool_attributes_from_file(jcr, filename)) {
-+ bs->fsend("1000 OK BlastAttr\n");
-+ } else {
-+ bs->fsend("1990 ERROR BlastAttr\n");
-+ }
-+ continue;
-+ }
- if (bs->msg[0] == 'M') { /* Mount request */
- Dmsg1(900, "Mount req: %s", bs->msg);
- mount_request(jcr, bs, msg);
-Index: src/dird/protos.h
-===================================================================
---- src/dird/protos.h (révision 8270)
-+++ src/dird/protos.h (copie de travail)
-@@ -80,6 +80,7 @@
- /* catreq.c */
- extern void catalog_request(JCR *jcr, BSOCK *bs);
- extern void catalog_update(JCR *jcr, BSOCK *bs);
-+extern bool despool_attributes_from_file(JCR *jcr, const char *file);
-
- /* dird_conf.c */
- extern const char *level_to_str(int level);
-Index: src/stored/spool.c
-===================================================================
---- src/stored/spool.c (révision 8270)
-+++ src/stored/spool.c (copie de travail)
-@@ -622,13 +622,40 @@
- V(mutex);
- }
-
-+static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd)
-+{
-+ Mmsg(name, "%s/%s.attr.%s.%d.spool", working_directory, my_name,
-+ jcr->Job, fd);
-+}
-+
-+static bool blast_attr_spool_file(JCR *jcr, boffset_t size)
-+{
-+ /* send full spool file name */
-+ POOLMEM *name = get_pool_memory(PM_MESSAGE);
-+ make_unique_spool_filename(jcr, &name, jcr->dir_bsock->m_fd);
-+ bash_spaces(name);
-+ jcr->dir_bsock->fsend("BlastAttr Job=%s File=%s\n",
-+ jcr->Job, name);
-+ free_pool_memory(name);
-+
-+ if (jcr->dir_bsock->recv() <= 0) {
-+ Jmsg(jcr, M_FATAL, 0, _("Network error on BlastAttributes.\n"));
-+ return false;
-+ }
-+
-+ if (!bstrcmp(jcr->dir_bsock->msg, "1000 OK BlastAttr\n")) {
-+ return false;
-+ }
-+ return true;
-+}
-+
- bool commit_attribute_spool(JCR *jcr)
- {
- boffset_t size;
- char ec1[30];
- char tbuf[100];
-
-- Dmsg1(100, "Commit attributes at %s\n", bstrftimes(tbuf, sizeof(tbuf),
-+ Dmsg1(0, "Commit attributes at %s\n", bstrftimes(tbuf, sizeof(tbuf),
- ( utime_t)time(NULL)));
- if (are_attributes_spooled(jcr)) {
- if (fseeko(jcr->dir_bsock->m_spool_fd, 0, SEEK_END) != 0) {
-@@ -654,7 +681,13 @@
- dir_send_job_status(jcr);
- Jmsg(jcr, M_INFO, 0, _("Sending spooled attrs to the Director. Despooling %s bytes ...\n"),
- edit_uint64_with_commas(size, ec1));
-- jcr->dir_bsock->despool(update_attr_spool_size, size);
-+
-+ if (!blast_attr_spool_file(jcr, size)) {
-+ /* Can't read spool file from director side,
-+ * send content over network.
-+ */
-+ jcr->dir_bsock->despool(update_attr_spool_size, size);
-+ }
- return close_attr_spool_file(jcr, jcr->dir_bsock);
- }
- return true;
-@@ -664,13 +697,6 @@
- return false;
- }
-
--static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd)
--{
-- Mmsg(name, "%s/%s.attr.%s.%d.spool", working_directory, my_name,
-- jcr->Job, fd);
--}
--
--
- bool open_attr_spool_file(JCR *jcr, BSOCK *bs)
- {
- POOLMEM *name = get_pool_memory(PM_MESSAGE);
+++ /dev/null
-Index: src/dird/bsr.c
-===================================================================
---- src/dird/bsr.c (révision 8163)
-+++ src/dird/bsr.c (copie de travail)
-@@ -325,6 +325,7 @@
- */
- static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
- {
-+ char ed1[50], ed2[50];
- uint32_t count = 0;
- uint32_t total_count = 0;
- uint32_t LastIndex = 0;
-@@ -362,18 +363,20 @@
- }
- fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-- if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-- fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-- } else {
-- fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-- bsr->VolParams[i].EndFile);
-- }
-- if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-- fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-- } else {
-- fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-- bsr->VolParams[i].EndBlock);
-- }
-+// if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-+// fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-+// } else {
-+// fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-+// bsr->VolParams[i].EndFile);
-+// }
-+// if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-+// fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-+// } else {
-+// fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-+// bsr->VolParams[i].EndBlock);
-+// }
-+ fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
-+ edit_uint64(bsr->VolParams[i].EndAddr, ed2));
- // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
- // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
-
-@@ -428,18 +431,20 @@
- }
- fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
- fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
-- if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-- fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-- } else {
-- fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-- bsr->VolParams[i].EndFile);
-- }
-- if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-- fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-- } else {
-- fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-- bsr->VolParams[i].EndBlock);
-- }
-+// if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
-+// fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
-+// } else {
-+// fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
-+// bsr->VolParams[i].EndFile);
-+// }
-+// if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
-+// fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
-+// } else {
-+// fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
-+// bsr->VolParams[i].EndBlock);
-+// }
-+ fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
-+ edit_uint64(bsr->VolParams[i].EndAddr, ed2));
- // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
- // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
-
-Index: src/cats/cats.h
-===================================================================
---- src/cats/cats.h (révision 8163)
-+++ src/cats/cats.h (copie de travail)
-@@ -844,6 +844,8 @@
- uint32_t StartBlock; /* start block on tape */
- uint32_t EndBlock; /* last block */
- int32_t Slot; /* Slot */
-+ uint64_t StartAddr; /* Start address */
-+ uint64_t EndAddr; /* End address */
- // uint32_t Copy; /* identical copy */
- // uint32_t Stripe; /* RAIT strip number */
- };
-Index: src/cats/sql_get.c
-===================================================================
---- src/cats/sql_get.c (révision 8163)
-+++ src/cats/sql_get.c (copie de travail)
-@@ -463,6 +463,8 @@
- 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].StartAddr = (((uint64_t)Vols[i].StartFile)<<32) | Vols[i].StartBlock;
-+ Vols[i].EndAddr = (((uint64_t)Vols[i].EndFile)<<32) | Vols[i].EndBlock;
- // Vols[i].Copy = str_to_uint64(row[8]);
- Vols[i].Slot = str_to_uint64(row[9]);
- StorageId = str_to_uint64(row[10]);
-Index: src/stored/match_bsr.c
-===================================================================
---- src/stored/match_bsr.c (révision 8174)
-+++ src/stored/match_bsr.c (copie de travail)
-@@ -36,15 +36,6 @@
-
- /*
- * ***FIXME***
-- * find_smallest_volfile needs to be fixed to only look at items that
-- * are not marked as done. Otherwise, it can find a bsr
-- * that has already been consumed, and this will cause the
-- * bsr to be used, thus we may seek back and re-read the
-- * same records, causing an error. This deficiency must
-- * be fixed. For the moment, it has been kludged in
-- * read_record.c to avoid seeking back if find_next_bsr
-- * returns a bsr pointing to a smaller address (file/block).
-- *
- * Also for efficiency, once a bsr is done, it really should be
- * delinked from the bsr chain. This will avoid the above
- * problem and make traversal of the bsr chain more efficient.
-@@ -73,7 +64,7 @@
- static int match_jobid(BSR *bsr, BSR_JOBID *jobid, SESSION_LABEL *sessrec, bool done);
- static int match_findex(BSR *bsr, BSR_FINDEX *findex, DEV_RECORD *rec, bool done);
- static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool done);
--static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done);
-+static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done);
- static int match_stream(BSR *bsr, BSR_STREAM *stream, DEV_RECORD *rec, bool done);
- static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, bool done, JCR *jcr);
- static int match_block_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_BLOCK *block);
-@@ -255,7 +246,29 @@
- }
-
- /*
-- * ***FIXME***
-+ * Get the smallest address from this voladdr part
-+ * Don't use "done" elements
-+ */
-+static bool get_smallest_voladdr(BSR_VOLADDR *va, uint64_t *ret)
-+{
-+ bool ok=false;
-+ uint64_t min_val=0;
-+
-+ for (; va ; va = va->next) {
-+ if (!va->done) {
-+ if (ok) {
-+ min_val = MIN(min_val, va->saddr);
-+ } else {
-+ min_val = va->saddr;
-+ ok=true;
-+ }
-+ }
-+ }
-+ *ret = min_val;
-+ return ok;
-+}
-+
-+/* FIXME
- * This routine needs to be fixed to only look at items that
- * are not marked as done. Otherwise, it can find a bsr
- * that has already been consumed, and this will cause the
-@@ -264,6 +277,7 @@
- * be fixed. For the moment, it has been kludged in
- * read_record.c to avoid seeking back if find_next_bsr
- * returns a bsr pointing to a smaller address (file/block).
-+ *
- */
- static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr)
- {
-@@ -272,7 +286,19 @@
- BSR_VOLBLOCK *vb;
- uint32_t found_bsr_sfile, bsr_sfile;
- uint32_t found_bsr_sblock, bsr_sblock;
-+ uint64_t found_bsr_saddr, bsr_saddr;
-
-+ /* if we have VolAddr, use it, else try with File and Block */
-+ if (get_smallest_voladdr(found_bsr->voladdr, &found_bsr_saddr)) {
-+ if (get_smallest_voladdr(bsr->voladdr, &bsr_saddr)) {
-+ if (found_bsr_saddr > bsr_saddr) {
-+ return bsr;
-+ } else {
-+ return found_bsr;
-+ }
-+ }
-+ }
-+
- /* Find the smallest file in the found_bsr */
- vf = found_bsr->volfile;
- found_bsr_sfile = vf->sfile;
-@@ -374,20 +400,20 @@
- volrec->VolumeName);
-
- if (!match_volfile(bsr, bsr->volfile, rec, 1)) {
-- Dmsg3(dbglevel, "Fail on file=%u. bsr=%u,%u\n",
-- rec->File, bsr->volfile->sfile, bsr->volfile->efile);
-+ if (bsr->volfile) {
-+ Dmsg3(dbglevel, "Fail on file=%u. bsr=%u,%u\n",
-+ rec->File, bsr->volfile->sfile, bsr->volfile->efile);
-+ }
- goto no_match;
- }
-- Dmsg3(dbglevel, "OK bsr file=%u. bsr=%u,%u\n",
-- rec->File, bsr->volfile->sfile, bsr->volfile->efile);
-
-- if (!match_volblock(bsr, bsr->volblock, rec, 1)) {
-- Dmsg3(dbglevel, "Fail on Block=%u. bsr=%u,%u\n",
-- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-+ if (!match_voladdr(bsr, bsr->voladdr, rec, 1)) {
-+ if (bsr->voladdr) {
-+ Dmsg3(dbglevel, "Fail on Addr=%lld. bsr=%lld,%lld\n",
-+ get_record_address(rec), bsr->voladdr->saddr, bsr->voladdr->eaddr);
-+ }
- goto no_match;
- }
-- Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
-- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-
- if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
- Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n",
-@@ -605,42 +631,35 @@
- return 0;
- }
-
--static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done)
-+static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done)
- {
-- /*
-- * Currently block matching does not work correctly for disk
-- * files in all cases, so it is "turned off" by the following
-- * return statement.
-- */
-- return 1;
--
--
-- if (!volblock) {
-+ if (!voladdr) {
- return 1; /* no specification matches all */
- }
- /* For the moment, these tests work only with disk. */
- if (rec->state & REC_ISTAPE) {
- return 1; /* All File records OK for this match */
- }
--// Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
--// volblock->sblock, volblock->eblock, rec->Block);
-- if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
-+ uint64_t addr = get_record_address(rec);
-+// Dmsg3(dbglevel, "match_voladdr: saddr=%lld eaddr=%lld recaddr=%lld\n",
-+// volblock->saddr, volblock->eaddr, addr);
-+ if (voladdr->saddr <= addr && voladdr->eaddr >= addr) {
- return 1;
- }
- /* Once we get past last eblock, we are done */
-- if (rec->Block > volblock->eblock) {
-- volblock->done = true; /* set local done */
-+ if (addr > voladdr->eaddr) {
-+ voladdr->done = true; /* set local done */
- }
-- if (volblock->next) {
-- return match_volblock(bsr, volblock->next, rec, volblock->done && done);
-+ if (voladdr->next) {
-+ return match_voladdr(bsr, voladdr->next, rec, voladdr->done && done);
- }
-
- /* If we are done and all prior matches are done, this bsr is finished */
-- if (volblock->done && done) {
-+ if (voladdr->done && done) {
- bsr->done = true;
- bsr->root->reposition = true;
-- Dmsg2(dbglevel, "bsr done from volblock rec=%u voleblock=%u\n",
-- rec->Block, volblock->eblock);
-+ Dmsg2(dbglevel, "bsr done from voladdr rec=%lld voleaddr=%lld\n",
-+ addr, voladdr->eaddr);
- }
- return 0;
- }
-@@ -733,3 +752,29 @@
- }
- return 0;
- }
-+
-+uint64_t get_bsr_start_addr(BSR *bsr, uint32_t *file, uint32_t *block)
-+{
-+ uint64_t bsr_addr = 0;
-+ uint32_t sfile = 0, sblock = 0;
-+
-+ if (bsr) {
-+ if (bsr->voladdr) {
-+ bsr_addr = bsr->voladdr->saddr;
-+ sfile = bsr_addr>>32;
-+ sblock = (uint32_t)bsr_addr;
-+
-+ } else if (bsr->volfile && bsr->volblock) {
-+ bsr_addr = (((uint64_t)bsr->volfile->sfile)<<32)|bsr->volblock->sblock;
-+ sfile = bsr->volfile->sfile;
-+ sblock = bsr->volblock->sblock;
-+ }
-+ }
-+
-+ if (file && block) {
-+ *file = sfile;
-+ *block = sblock;
-+ }
-+
-+ return bsr_addr;
-+}
-Index: src/stored/read_record.c
-===================================================================
---- src/stored/read_record.c (révision 8163)
-+++ src/stored/read_record.c (copie de travail)
-@@ -344,19 +344,21 @@
- * when find_next_bsr() is fixed not to return a bsr already
- * completed.
- */
-- if (dev->file > bsr->volfile->sfile ||
-- (dev->file == bsr->volfile->sfile && dev->block_num > bsr->volblock->sblock)) {
-+ uint32_t block, file;
-+ /* TODO: use dev->file_addr ? */
-+ uint64_t dev_addr = (((uint64_t) dev->file)<<32) | dev->block_num;
-+ uint64_t bsr_addr = get_bsr_start_addr(bsr, &file, &block);
-+
-+ if (dev_addr > bsr_addr) {
- return false;
- }
- if (verbose) {
-- Jmsg(jcr, M_INFO, 0, _("Reposition from (file:block) %u:%u to %u:%u\n"),
-- dev->file, dev->block_num, bsr->volfile->sfile,
-- bsr->volblock->sblock);
-+ Jmsg(jcr, M_INFO,0, _("Reposition from (file:block) %u:%u to %u:%u\n"),
-+ dev->file, dev->block_num, file, block);
- }
- Dmsg4(10, "Try_Reposition from (file:block) %u:%u to %u:%u\n",
-- dev->file, dev->block_num, bsr->volfile->sfile,
-- bsr->volblock->sblock);
-- dev->reposition(dcr, bsr->volfile->sfile, bsr->volblock->sblock);
-+ dev->file, dev->block_num, file, block);
-+ dev->reposition(dcr, file, block);
- rec->Block = 0;
- }
- return false;
-@@ -369,6 +371,7 @@
- {
- BSR *bsr = NULL;
- DEVICE *dev = dcr->dev;
-+ uint32_t file, block;
- /*
- * Now find and position to first file and block
- * on this tape.
-@@ -376,11 +379,11 @@
- if (jcr->bsr) {
- jcr->bsr->reposition = true; /* force repositioning */
- bsr = find_next_bsr(jcr->bsr, dev);
-- if (bsr && (bsr->volfile->sfile != 0 || bsr->volblock->sblock != 0)) {
-+
-+ if (get_bsr_start_addr(bsr, &file, &block) > 0) {
- Jmsg(jcr, M_INFO, 0, _("Forward spacing Volume \"%s\" to file:block %u:%u.\n"),
-- dev->VolHdr.VolumeName,
-- bsr->volfile->sfile, bsr->volblock->sblock);
-- dev->reposition(dcr, bsr->volfile->sfile, bsr->volblock->sblock);
-+ dev->VolHdr.VolumeName, file, block);
-+ dev->reposition(dcr, file, block);
- }
- }
- return bsr;
-Index: src/stored/parse_bsr.c
-===================================================================
---- src/stored/parse_bsr.c (révision 8163)
-+++ src/stored/parse_bsr.c (copie de travail)
-@@ -52,6 +52,7 @@
- static BSR *store_sessid(LEX *lc, BSR *bsr);
- static BSR *store_volfile(LEX *lc, BSR *bsr);
- static BSR *store_volblock(LEX *lc, BSR *bsr);
-+static BSR *store_voladdr(LEX *lc, BSR *bsr);
- static BSR *store_sesstime(LEX *lc, BSR *bsr);
- static BSR *store_include(LEX *lc, BSR *bsr);
- static BSR *store_exclude(LEX *lc, BSR *bsr);
-@@ -85,6 +86,7 @@
- {"exclude", store_exclude},
- {"volfile", store_volfile},
- {"volblock", store_volblock},
-+ {"voladdr", store_voladdr},
- {"stream", store_stream},
- {"slot", store_slot},
- {"device", store_device},
-@@ -212,17 +214,17 @@
- {
- /*
- * Every bsr should have a volfile entry and a volblock entry
-+ * or a VolAddr
- * if we are going to use positioning
- */
- for ( ; bsr; bsr=bsr->next) {
-- if (!bsr->volfile || !bsr->volblock) {
-+ if (!((bsr->volfile && bsr->volblock) || bsr->voladdr)) {
- return false;
- }
- }
- return true;
- }
-
--
- static BSR *store_vol(LEX *lc, BSR *bsr)
- {
- int token;
-@@ -563,7 +565,41 @@
- return bsr;
- }
-
-+/*
-+ * Routine to handle Volume start/end address
-+ */
-+static BSR *store_voladdr(LEX *lc, BSR *bsr)
-+{
-+ int token;
-+ BSR_VOLADDR *voladdr;
-
-+ for (;;) {
-+ token = lex_get_token(lc, T_PINT64_RANGE);
-+ if (token == T_ERROR) {
-+ return NULL;
-+ }
-+ voladdr = (BSR_VOLADDR *)malloc(sizeof(BSR_VOLADDR));
-+ memset(voladdr, 0, sizeof(BSR_VOLADDR));
-+ voladdr->saddr = lc->pint64_val;
-+ voladdr->eaddr = lc->pint64_val2;
-+ /* Add it to the end of the chain */
-+ if (!bsr->voladdr) {
-+ bsr->voladdr = voladdr;
-+ } else {
-+ /* Add to end of chain */
-+ BSR_VOLADDR *bs = bsr->voladdr;
-+ for ( ;bs->next; bs=bs->next)
-+ { }
-+ bs->next = voladdr;
-+ }
-+ token = lex_get_token(lc, T_ALL);
-+ if (token != T_COMMA) {
-+ break;
-+ }
-+ }
-+ return bsr;
-+}
-+
- static BSR *store_sessid(LEX *lc, BSR *bsr)
- {
- int token;
-@@ -705,6 +741,13 @@
- }
- }
-
-+void dump_voladdr(BSR_VOLADDR *voladdr)
-+{
-+ if (voladdr) {
-+ Pmsg2(-1, _("VolAddr : %lld-%lld\n"), voladdr->saddr, voladdr->eaddr);
-+ dump_voladdr(voladdr->next);
-+ }
-+}
-
- void dump_findex(BSR_FINDEX *FileIndex)
- {
-@@ -795,6 +838,7 @@
- dump_sesstime(bsr->sesstime);
- dump_volfile(bsr->volfile);
- dump_volblock(bsr->volblock);
-+ dump_voladdr(bsr->voladdr);
- dump_client(bsr->client);
- dump_jobid(bsr->JobId);
- dump_job(bsr->job);
-@@ -840,6 +884,7 @@
- free_bsr_item((BSR *)bsr->sesstime);
- free_bsr_item((BSR *)bsr->volfile);
- free_bsr_item((BSR *)bsr->volblock);
-+ free_bsr_item((BSR *)bsr->voladdr);
- free_bsr_item((BSR *)bsr->JobId);
- free_bsr_item((BSR *)bsr->job);
- free_bsr_item((BSR *)bsr->FileIndex);
-Index: src/stored/record.c
-===================================================================
---- src/stored/record.c (révision 8163)
-+++ src/stored/record.c (copie de travail)
-@@ -422,6 +422,10 @@
- return true;
- }
-
-+uint64_t get_record_address(DEV_RECORD *rec)
-+{
-+ return ((uint64_t)rec->File)<<32 | rec->Block;
-+}
-
- /*
- * Read a Record from the block
-@@ -456,7 +460,6 @@
- rec->File = ((DEVICE *)block->dev)->EndFile;
- }
-
--
- /*
- * Get the header. There is always a full header,
- * otherwise we find it in the next block.
-Index: src/stored/bsr.h
-===================================================================
---- src/stored/bsr.h (révision 8163)
-+++ src/stored/bsr.h (copie de travail)
-@@ -106,6 +106,12 @@
- bool done; /* local done */
- };
-
-+struct BSR_VOLADDR {
-+ BSR_VOLADDR *next;
-+ uint64_t saddr; /* start address */
-+ uint64_t eaddr; /* end address */
-+ bool done; /* local done */
-+};
-
- struct BSR_FINDEX {
- BSR_FINDEX *next;
-@@ -157,6 +163,7 @@
- uint32_t found; /* count of restored files this bsr */
- BSR_VOLFILE *volfile;
- BSR_VOLBLOCK *volblock;
-+ BSR_VOLADDR *voladdr;
- BSR_SESSTIME *sesstime;
- BSR_SESSID *sessid;
- BSR_JOBID *JobId;
-Index: src/stored/protos.h
-===================================================================
---- src/stored/protos.h (révision 8163)
-+++ src/stored/protos.h (copie de travail)
-@@ -183,7 +183,11 @@
- void position_bsr_block(BSR *bsr, DEV_BLOCK *block);
- BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev);
- bool is_this_bsr_done(BSR *bsr, DEV_RECORD *rec);
-+uint64_t get_bsr_start_addr(BSR *bsr,
-+ uint32_t *file=NULL,
-+ uint32_t *block=NULL);
-
-+
- /* From mount.c */
- bool mount_next_read_volume(DCR *dcr);
-
-@@ -203,6 +207,7 @@
- DEV_RECORD *new_record();
- void free_record(DEV_RECORD *rec);
- void empty_record(DEV_RECORD *rec);
-+uint64_t get_record_address(DEV_RECORD *rec);
-
- /* From read_record.c */
- bool read_records(DCR *dcr,
+++ /dev/null
-Index: src/cats/sql.c
-===================================================================
---- src/cats/sql.c (révision 8008)
-+++ src/cats/sql.c (copie de travail)
-@@ -311,33 +311,6 @@
- return mdb->errmsg;
- }
-
--static void update_lock_dbg(B_DB *mdb)
--{
-- if (mdb->allow_transactions) { /* batch connection */
-- return;
-- }
-- if (_db_lock_recurse_count && !pthread_equal(_db_lock_threadid, pthread_self())) {
-- Dmsg2(1, "ERROR: not the same threadif %p != %p\n", _db_lock_threadid, pthread_self());
-- }
-- _db_lock_recurse_count++;
-- _db_lock_time = (utime_t) time(NULL);
-- _db_lock_threadid = pthread_self();
--}
--
--static void update_unlock_dbg(B_DB *mdb)
--{
-- if (mdb->allow_transactions) { /* batch connection */
-- return;
-- }
-- if (!pthread_equal(_db_lock_threadid, pthread_self())) {
-- Dmsg2(1, "ERROR: not the same threadid %p != %p", _db_lock_threadid, pthread_self());
-- }
-- _db_lock_recurse_count--;
-- if (!_db_lock_recurse_count) {
-- memset(&_db_lock_threadid, 0, sizeof(_db_lock_threadid));
-- }
--}
--
- /*
- * Lock database, this can be called multiple times by the same
- * thread without blocking, but must be unlocked the number of
-@@ -351,7 +324,6 @@
- e_msg(file, line, M_FATAL, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
- errstat, be.bstrerror(errstat));
- }
-- update_lock_dbg(mdb);
- }
-
- /*
-@@ -362,7 +334,6 @@
- void _db_unlock(const char *file, int line, B_DB *mdb)
- {
- int errstat;
-- update_unlock_dbg(mdb);
- if ((errstat=rwl_writeunlock(&mdb->lock)) != 0) {
- berrno be;
- e_msg(file, line, M_FATAL, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
-Index: src/lib/protos.h
-===================================================================
---- src/lib/protos.h (révision 8005)
-+++ src/lib/protos.h (copie de travail)
-@@ -252,13 +252,6 @@
- void init_signals (void terminate(int sig));
- void init_stack_dump (void);
-
--/* Used to debug database lock
-- * which job takes the main DB access
-- */
--extern DLL_IMP_EXP utime_t _db_lock_time;
--extern DLL_IMP_EXP int _db_lock_recurse_count;
--extern DLL_IMP_EXP pthread_t _db_lock_threadid;
--
- /* scan.c */
- void strip_leading_space (char *str);
- void strip_trailing_junk (char *str);
-Index: src/lib/signal.c
-===================================================================
---- src/lib/signal.c (révision 8005)
-+++ src/lib/signal.c (copie de travail)
-@@ -72,22 +72,6 @@
- }
- }
-
--/*
-- * Global variables to get information about lock/unlock db access
-- */
--utime_t _db_lock_time = 0;
--int _db_lock_recurse_count = 0;
--pthread_t _db_lock_threadid;
--
--static void print_lock_dbg(FILE *fp)
--{
-- char buf[128];
-- bstrutime(buf, sizeof(buf), _db_lock_time);
--
-- fprintf(fp, "lock info: recurse_count=%i threadid=0x%x time=%s\n",
-- _db_lock_recurse_count, (int)_db_lock_threadid, buf);
--}
--
- /* defined in jcr.c */
- extern void _print_jcr_dbg(FILE *fp);
-
+++ /dev/null
-This patch change the FileId type from 32 to 64 bits. The 2.4.x (and previous) default type
-don't permit to backup more than 2^32 files. (~ 4,000,000,000 files)
-
-You will have to upgrade the catalog. It will take x2 space, so be sure to check your available
-space before.
-
- cd <bacula-source>
- patch -p0 < patches/testing/fileid64.patch
- ./configure <your options>
- make
- ...
- make install
-
- ./src/cats/update_bacula_tables
-
-Index: src/cats/update_postgresql_tables.in
-===================================================================
---- src/cats/update_postgresql_tables.in (révision 7513)
-+++ src/cats/update_postgresql_tables.in (copie de travail)
-@@ -12,9 +12,12 @@
- if $bindir/psql -f - -d ${db_name} $* <<END-OF-DATA
-
- -- Create a table like Job for long term statistics
-+BEGIN;
- CREATE TABLE jobstat (LIKE job);
--
-+ALTER TABLE file ALTER fileid TYPE bigint ;
-+ALTER TABLE basefiles ALTER fileid TYPE bigint;
- UPDATE version SET versionid=11;
-+COMMIT;
-
- vacuum analyse;
-
-Index: src/cats/cats.h
-===================================================================
---- src/cats/cats.h (révision 7513)
-+++ src/cats/cats.h (copie de travail)
-@@ -747,7 +747,7 @@
- * In principle, the only field that really should need to be
- * 64 bits is the FileId_t
- */
--typedef uint32_t FileId_t;
-+typedef uint64_t FileId_t;
- typedef uint32_t DBId_t; /* general DB id type */
- typedef uint32_t JobId_t;
-
-Index: src/cats/make_postgresql_tables.in
-===================================================================
---- src/cats/make_postgresql_tables.in (révision 7514)
-+++ src/cats/make_postgresql_tables.in (copie de travail)
-@@ -29,7 +29,7 @@
-
- CREATE TABLE file
- (
-- fileid serial not null,
-+ fileid bigserial not null,
- fileindex integer not null default 0,
- jobid integer not null,
- pathid integer not null,
-@@ -295,7 +295,7 @@
- (
- baseid serial not null,
- jobid integer not null,
-- fileid integer not null,
-+ fileid bigint not null,
- fileindex integer ,
- basejobid integer ,
- primary key (baseid)
-Index: src/cats/update_mysql_tables.in
-===================================================================
---- src/cats/update_mysql_tables.in (révision 7513)
-+++ src/cats/update_mysql_tables.in (copie de travail)
-@@ -14,7 +14,8 @@
-
- -- Create a table like Job for long term statistics
- CREATE TABLE JobStat (LIKE Job);
--
-+ALTER TABLE File CHANGE FileId FileId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT;
-+ALTER TABLE BaseFiles CHANGE FileId FileId BIGINT UNSIGNED NOT NULL;
- DELETE FROM Version;
- INSERT INTO Version (VersionId) VALUES (11);
-
-Index: src/cats/make_mysql_tables.in
-===================================================================
---- src/cats/make_mysql_tables.in (révision 7514)
-+++ src/cats/make_mysql_tables.in (copie de travail)
-@@ -29,7 +29,7 @@
-
-
- CREATE TABLE File (
-- FileId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-+ FileId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
- FileIndex INTEGER UNSIGNED DEFAULT 0,
- JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
- PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
-@@ -272,7 +272,7 @@
- BaseId INTEGER UNSIGNED AUTO_INCREMENT,
- BaseJobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
- JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
-- FileId INTEGER UNSIGNED NOT NULL REFERENCES File,
-+ FileId BIGINT UNSIGNED NOT NULL REFERENCES File,
- FileIndex INTEGER UNSIGNED,
- PRIMARY KEY(BaseId)
- );
+++ /dev/null
-Index: src/stored/match_bsr.c
-===================================================================
---- src/stored/match_bsr.c (révision 8116)
-+++ src/stored/match_bsr.c (copie de travail)
-@@ -36,15 +36,6 @@
-
- /*
- * ***FIXME***
-- * find_smallest_volfile needs to be fixed to only look at items that
-- * are not marked as done. Otherwise, it can find a bsr
-- * that has already been consumed, and this will cause the
-- * bsr to be used, thus we may seek back and re-read the
-- * same records, causing an error. This deficiency must
-- * be fixed. For the moment, it has been kludged in
-- * read_record.c to avoid seeking back if find_next_bsr
-- * returns a bsr pointing to a smaller address (file/block).
-- *
- * Also for efficiency, once a bsr is done, it really should be
- * delinked from the bsr chain. This will avoid the above
- * problem and make traversal of the bsr chain more efficient.
-@@ -255,68 +246,88 @@
- }
-
- /*
-- * ***FIXME***
-- * This routine needs to be fixed to only look at items that
-- * are not marked as done. Otherwise, it can find a bsr
-- * that has already been consumed, and this will cause the
-- * bsr to be used, thus we may seek back and re-read the
-- * same records, causing an error. This deficiency must
-- * be fixed. For the moment, it has been kludged in
-- * read_record.c to avoid seeking back if find_next_bsr
-- * returns a bsr pointing to a smaller address (file/block).
-+ * Get the smallest file number from this volfile part
-+ * Don't use "done" elements
- */
--static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr)
-+static bool get_smallest_volfile(BSR_VOLFILE *vf, uint32_t *ret)
- {
-- BSR *return_bsr = found_bsr;
-- BSR_VOLFILE *vf;
-- BSR_VOLBLOCK *vb;
-- uint32_t found_bsr_sfile, bsr_sfile;
-- uint32_t found_bsr_sblock, bsr_sblock;
-+ bool ok=false;
-+ uint32_t min_val=0;
-
-- /* Find the smallest file in the found_bsr */
-- vf = found_bsr->volfile;
-- found_bsr_sfile = vf->sfile;
-- while ( (vf=vf->next) ) {
-- if (vf->sfile < found_bsr_sfile) {
-- found_bsr_sfile = vf->sfile;
-+ for (; vf ; vf = vf->next) {
-+ if (!vf->done) {
-+ if (ok) {
-+ min_val = MIN(min_val, vf->sfile);
-+ } else {
-+ min_val = vf->sfile;
-+ ok=true;
-+ }
- }
- }
-+ *ret = min_val;
-+ return ok;
-+}
-
-- /* Find the smallest file in the bsr */
-- vf = bsr->volfile;
-- bsr_sfile = vf->sfile;
-- while ( (vf=vf->next) ) {
-- if (vf->sfile < bsr_sfile) {
-- bsr_sfile = vf->sfile;
-+/*
-+ * Get the smallest block number from this volblock part
-+ * Don't use "done" elements
-+ */
-+static bool get_smallest_volblock(BSR_VOLBLOCK *vb, uint32_t *ret)
-+{
-+ bool ok=false;
-+ uint32_t min_val=0;
-+
-+ for (; vb ; vb = vb->next) {
-+ if (!vb->done) {
-+ if (ok) {
-+ min_val = MIN(min_val, vb->sblock);
-+ } else {
-+ min_val = vb->sblock;
-+ ok=true;
-+ }
- }
- }
-+ *ret = min_val;
-+ return ok;
-+}
-+
-+/*
-+ *
-+ */
-+static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr)
-+{
-+ BSR *return_bsr = found_bsr;
-+ uint32_t found_bsr_sfile=0, bsr_sfile=0;
-+ uint32_t found_bsr_sblock=0, bsr_sblock=0;
-+
-+ if (!get_smallest_volfile(found_bsr->volfile, &found_bsr_sfile)) {
-+ return bsr; /* found_bsr seems to be done...*/
-+ }
-+
-+ if (!get_smallest_volfile(bsr->volfile, &bsr_sfile)) {
-+ return found_bsr; /* bsr seems to be done... */
-+ }
-
- /* if the bsr file is less than the found_bsr file, return bsr */
- if (found_bsr_sfile > bsr_sfile) {
- return_bsr = bsr;
- } else if (found_bsr_sfile == bsr_sfile) {
-- /* Files are equal */
-- /* find smallest block in found_bsr */
-- vb = found_bsr->volblock;
-- found_bsr_sblock = vb->sblock;
-- while ( (vb=vb->next) ) {
-- if (vb->sblock < found_bsr_sblock) {
-- found_bsr_sblock = vb->sblock;
-- }
-+ /* Files are equal, use block to find the smallest */
-+ if (!get_smallest_volblock(found_bsr->volblock, &found_bsr_sblock)) {
-+ return bsr; /* Should not be there */
- }
-- /* Find smallest block in bsr */
-- vb = bsr->volblock;
-- bsr_sblock = vb->sblock;
-- while ( (vb=vb->next) ) {
-- if (vb->sblock < bsr_sblock) {
-- bsr_sblock = vb->sblock;
-- }
-+
-+ if (!get_smallest_volblock(bsr->volblock, &bsr_sblock)) {
-+ return found_bsr; /* Should not be there */
- }
-+
- /* Compare and return the smallest */
- if (found_bsr_sblock > bsr_sblock) {
- return_bsr = bsr;
- }
- }
-+ Dmsg5(dbglevel, "find_smallest_volfile bsr=0x%p %i > %i | %i > %i\n",
-+ return_bsr, found_bsr_sfile, bsr_sfile, found_bsr_sblock, bsr_sblock);
- return return_bsr;
- }
-
-@@ -386,8 +397,6 @@
- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
- goto no_match;
- }
-- Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
-- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-
- if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
- Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n",
-@@ -411,6 +420,9 @@
- Dmsg3(dbglevel, "match on findex=%d. bsr=%d,%d\n",
- rec->FileIndex, bsr->FileIndex->findex, bsr->FileIndex->findex2);
-
-+ Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
-+ rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-+
- if (!match_fileregex(bsr, rec, jcr)) {
- Dmsg1(dbglevel, "Fail on fileregex='%s'\n", bsr->fileregex);
- goto no_match;
-@@ -607,14 +619,7 @@
-
- static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done)
- {
-- /*
-- * Currently block matching does not work correctly for disk
-- * files in all cases, so it is "turned off" by the following
-- * return statement.
-- */
-- return 1;
-
--
- if (!volblock) {
- return 1; /* no specification matches all */
- }
-@@ -622,8 +627,9 @@
- if (rec->state & REC_ISTAPE) {
- return 1; /* All File records OK for this match */
- }
--// Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
--// volblock->sblock, volblock->eblock, rec->Block);
-+ Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
-+ volblock->sblock, volblock->eblock, rec->Block);
-+
- if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
- return 1;
- }
-Index: src/stored/read_record.c
-===================================================================
---- src/stored/read_record.c (révision 8116)
-+++ src/stored/read_record.c (copie de travail)
-@@ -261,8 +261,8 @@
- Dmsg2(100, "All done=(file:block) %u:%u\n", dev->file, dev->block_num);
- break;
- } else if (rec->match_stat == 0) { /* no match */
-- Dmsg4(100, "BSR no match: clear rem=%d FI=%d before set_eof pos %u:%u\n",
-- rec->remainder, rec->FileIndex, dev->file, dev->block_num);
-+ Dmsg7(100, "BSR no match: clear rem=%d FI=%d rec->Block=%d dev->LastBlock=%d dev->EndBlock=%d before set_eof pos %u:%u\n",
-+ rec->remainder, rec->FileIndex, rec->Block, dev->LastBlock, dev->EndBlock, dev->file, dev->block_num);
- rec->remainder = 0;
- rec->state &= ~REC_PARTIAL_RECORD;
- if (try_repositioning(jcr, rec, dcr)) {
-@@ -346,6 +346,9 @@
- */
- if (dev->file > bsr->volfile->sfile ||
- (dev->file == bsr->volfile->sfile && dev->block_num > bsr->volblock->sblock)) {
-+ Dmsg4(dbglvl, _("Reposition from (file:block) %u:%u to %u:%u\n"),
-+ dev->file, dev->block_num, bsr->volfile->sfile,
-+ bsr->volblock->sblock);
- return false;
- }
- if (verbose) {
+++ /dev/null
-Index: ReleaseNotes
-===================================================================
---- ReleaseNotes (revision 8456)
-+++ ReleaseNotes (working copy)
-@@ -6,8 +6,7 @@
- This Director and Storage daemon must be upgraded at the same time,
- but they should be compatible with all 2.4.x File daemons, unless you
- use some of the new features that affect the FD. In other words, you should
--not have to upgrade all your File daemons when you upgrade. There is
--no database upgrade needed from version 2.4.x. However, the next
-+not have to upgrade all your File daemons when you upgrade. However, the next
- BETA release will require a database upgrade.
-
- ================== Warning !!!!!! ==========================
-@@ -15,19 +14,18 @@
- New Catalog format :
- --------------------
-
--This BETA release of Bacula uses a new catalog format. We provide a set of
--script that permit to convert a 2.4.x (version 10) catalog to 2.5.x (version
--11). If you are using already a 2.5 version, you need to drop the JobHistory
--table before upgrading your catalog (if you are using the new "long term
--statistics" module, you can upgrade this table like with the Job table, see
--upgrade_<database>_table script).
-+This BETA release of Bacula uses a new catalog version. We provide a set of
-+scripts that permit to convert a 2.4.x (version 10) catalog to 2.5.x (version
-+11). If you are already using a 2.5 version with the new "long term statistics"
-+module, you can copy data from the JobHistory to the new JobHisto table, see
-+upgrade_<database>_table script.
-
--The upgrade operation will convert an essential field of the File table, and
--this operation will take TIME and will DOUBLE THE SIZE of your
--catalog temporarily. Depending on your catalog backend, you won't be able to run jobs
--during this period. For example, a 3 million files catalog will take 2mins to
--upgrade on a normal machine. Don't forget to backup it before executing the
--script.
-+The upgrade operation will convert the FileId index field of the File table
-+from 32 bits to 64 bits.. This operation will take TIME and will *temporarily*
-+DOUBLE THE SIZE of your catalog. Bacula must be shutdown during this update,
-+so, you won't be able to run jobs during this period. For example, a 3 million
-+files catalog will take 2mins to upgrade on a normal machine. Don't forget to
-+BACKUP IT before executing the script.
-
-
- New configure option :
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (revision 8456)
-+++ src/dird/job.c (working copy)
-@@ -860,6 +860,7 @@
- jcr->jr.JobStatus = jcr->JobStatus;
- jcr->jr.JobFiles = jcr->JobFiles;
- jcr->jr.JobBytes = jcr->JobBytes;
-+ jcr->jr.ReadBytes = jcr->ReadBytes;
- jcr->jr.VolSessionId = jcr->VolSessionId;
- jcr->jr.VolSessionTime = jcr->VolSessionTime;
- jcr->jr.JobErrors = jcr->Errors;
-Index: src/dird/ua_prune.c
-===================================================================
---- src/dird/ua_prune.c (revision 8456)
-+++ src/dird/ua_prune.c (working copy)
-@@ -194,12 +194,12 @@
- utime_t now = (utime_t)time(NULL);
-
- db_lock(ua->db);
-- Mmsg(query, "DELETE FROM JobHistory WHERE JobTDate < %s",
-+ Mmsg(query, "DELETE FROM JobHisto WHERE JobTDate < %s",
- edit_int64(now - retention, ed1));
- db_sql_query(ua->db, query.c_str(), NULL, NULL);
- db_unlock(ua->db);
-
-- ua->info_msg(_("Pruned Jobs from JobHistory catalog.\n"));
-+ ua->info_msg(_("Pruned Jobs from JobHisto catalog.\n"));
-
- return true;
- }
-Index: src/cats/sql_update.c
-===================================================================
---- src/cats/sql_update.c (revision 8456)
-+++ src/cats/sql_update.c (working copy)
-@@ -136,13 +136,7 @@
- utime_t now = (utime_t)time(NULL);
- edit_uint64(now - age, ed1);
-
-- Mmsg(mdb->cmd,
-- "INSERT INTO JobHistory "
-- "SELECT * "
-- "FROM Job "
-- "WHERE JobStatus IN ('T', 'f', 'A', 'E') "
-- "AND JobId NOT IN (SELECT JobId FROM JobHistory) "
-- "AND JobTDate < %s ", ed1);
-+ Mmsg(mdb->cmd, fill_jobhisto, ed1);
- QUERY_DB(jcr, mdb, mdb->cmd); /* TODO: get a message ? */
- return sql_affected_rows(mdb);
- }
-@@ -161,7 +155,7 @@
- time_t ttime;
- struct tm tm;
- int stat;
-- char ed1[30], ed2[30], ed3[50];
-+ char ed1[30], ed2[30], ed3[50], ed4[50];
- btime_t JobTDate;
- char PriorJobId[50];
-
-@@ -187,10 +181,11 @@
- db_lock(mdb);
- Mmsg(mdb->cmd,
- "UPDATE Job SET JobStatus='%c',EndTime='%s',"
--"ClientId=%u,JobBytes=%s,JobFiles=%u,JobErrors=%u,VolSessionId=%u,"
-+"ClientId=%u,JobBytes=%s,ReadBytes=%s,JobFiles=%u,JobErrors=%u,VolSessionId=%u,"
- "VolSessionTime=%u,PoolId=%u,FileSetId=%u,JobTDate=%s,"
- "RealEndTime='%s',PriorJobId=%s WHERE JobId=%s",
- (char)(jr->JobStatus), dt, jr->ClientId, edit_uint64(jr->JobBytes, ed1),
-+ edit_uint64(jr->ReadBytes, ed4),
- jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime,
- jr->PoolId, jr->FileSetId, edit_uint64(JobTDate, ed2),
- rdt,
-Index: src/cats/drop_postgresql_tables.in
-===================================================================
---- src/cats/drop_postgresql_tables.in (revision 8456)
-+++ src/cats/drop_postgresql_tables.in (working copy)
-@@ -11,7 +11,7 @@
- drop table jobmedia;
- drop table file;
- drop table job;
--drop table jobhistory;
-+drop table jobhisto;
- drop table media;
- drop table client;
- drop table pool;
-Index: src/cats/update_postgresql_tables.in
-===================================================================
---- src/cats/update_postgresql_tables.in (revision 8456)
-+++ src/cats/update_postgresql_tables.in (working copy)
-@@ -11,13 +11,28 @@
-
- if $bindir/psql -f - -d ${db_name} $* <<END-OF-DATA
-
-+-- The alter table operation can be faster with a big maintenance_work_mem
-+-- Uncomment and adapt this value to your environment
-+-- SET maintenance_work_mem = '1GB';
-+
-+BEGIN;
-+ALTER TABLE file ALTER fileid TYPE bigint ;
-+ALTER TABLE basefiles ALTER fileid TYPE bigint;
-+ALTER TABLE job ADD COLUMN readbytes bigint default 0;
-+ALTER TABLE media ADD COLUMN ActionOnPurge smallint default 0;
-+ALTER TABLE pool ADD COLUMN ActionOnPurge smallint default 0;
-+
- -- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (LIKE Job);
-+CREATE TABLE JobHisto (LIKE Job);
-+CREATE INDEX jobhisto_idx ON JobHisto ( starttime );
-
- UPDATE Version SET VersionId=11;
-+COMMIT;
-
-+-- If you have already this table, you can remove it with:
-+-- DROP TABLE JobHistory;
-+
- -- vacuum analyse;
--
- END-OF-DATA
- then
- echo "Update of Bacula PostgreSQL tables succeeded."
-Index: src/cats/make_sqlite3_tables.in
-===================================================================
---- src/cats/make_sqlite3_tables.in (revision 8456)
-+++ src/cats/make_sqlite3_tables.in (working copy)
-@@ -64,6 +64,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -76,13 +77,13 @@
- CREATE INDEX inx6 ON Job (Name);
-
- -- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (
-+CREATE TABLE JobHisto (
- JobId INTEGER,
- Job VARCHAR(128) NOT NULL,
- Name VARCHAR(128) NOT NULL,
- Type CHAR(1) NOT NULL,
- Level CHAR(1) NOT NULL,
-- ClientId INTEGER REFERENCES Client DEFAULT 0,
-+ ClientId INTEGER DEFAULT 0,
- JobStatus CHAR(1) NOT NULL,
- SchedTime DATETIME NOT NULL,
- StartTime DATETIME DEFAULT 0,
-@@ -93,16 +94,16 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-+ PoolId INTEGER UNSIGNED DEFAULT 0,
-+ FileSetId INTEGER UNSIGNED DEFAULT 0,
-+ PriorJobId INTEGER UNSIGNED DEFAULT 0,
- PurgedFiles TINYINT DEFAULT 0,
-- HasBase TINYINT DEFAULT 0,
-- PRIMARY KEY(JobId)
-+ HasBase TINYINT DEFAULT 0
- );
--CREATE INDEX inx61 ON JobHistory (Name);
-+CREATE INDEX inx61 ON JobHisto (StartTime);
-
- CREATE TABLE Location (
- LocationId INTEGER,
-@@ -183,6 +184,7 @@
- VolStatus VARCHAR(20) NOT NULL,
- Enabled TINYINT DEFAULT 1,
- Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
- VolRetention BIGINT UNSIGNED DEFAULT 0,
- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-@@ -256,6 +258,7 @@
- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
- AutoPrune TINYINT DEFAULT 0,
- Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
- PoolType VARCHAR(20) NOT NULL,
- LabelType TINYINT DEFAULT 0,
- LabelFormat VARCHAR(128) NOT NULL,
-@@ -383,7 +386,7 @@
-
-
- -- Initialize Version
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (VersionId) VALUES (11);
-
-
- PRAGMA default_cache_size = 100000;
-Index: src/cats/cats.h
-===================================================================
---- src/cats/cats.h (revision 8456)
-+++ src/cats/cats.h (working copy)
-@@ -88,7 +88,7 @@
- #if defined(BUILDING_CATS)
- #ifdef HAVE_SQLITE
-
--#define BDB_VERSION 10
-+#define BDB_VERSION 11
-
- #include <sqlite.h>
-
-@@ -208,7 +208,7 @@
- #ifdef HAVE_SQLITE3
-
-
--#define BDB_VERSION 10
-+#define BDB_VERSION 11
-
- #include <sqlite3.h>
-
-@@ -334,7 +334,7 @@
-
- #ifdef HAVE_MYSQL
-
--#define BDB_VERSION 10
-+#define BDB_VERSION 11
-
- #include <mysql.h>
-
-@@ -417,7 +417,7 @@
-
- #ifdef HAVE_POSTGRESQL
-
--#define BDB_VERSION 10
-+#define BDB_VERSION 11
-
- #include <libpq-fe.h>
-
-@@ -531,7 +531,7 @@
-
- #ifdef HAVE_DBI
-
--#define BDB_VERSION 10
-+#define BDB_VERSION 11
-
- #include <dbi/dbi.h>
-
-@@ -790,6 +790,7 @@
- uint32_t JobErrors;
- uint32_t JobMissingFiles;
- uint64_t JobBytes;
-+ uint64_t ReadBytes;
- int PurgedFiles;
- int HasBase;
-
-Index: src/cats/update_sqlite3_tables.in
-===================================================================
---- src/cats/update_sqlite3_tables.in (revision 8456)
-+++ src/cats/update_sqlite3_tables.in (working copy)
-@@ -15,10 +15,15 @@
- db_name=@db_name@
-
- ${bindir}/${sqlite} $* ${db_name}.db <<END-OF-DATA
-+-- Can be replaced by
-+-- ALTER TABLE Job ADD COLUMN (ReadBytes BIGINT UNSIGNED DEFAULT 0);
-+
- BEGIN TRANSACTION;
-+CREATE TEMPORARY TABLE job_backup AS SELECT * FROM Job;
-+DROP TABLE Job;
-
---- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (
-+CREATE TABLE Job
-+(
- JobId INTEGER,
- Job VARCHAR(128) NOT NULL,
- Name VARCHAR(128) NOT NULL,
-@@ -35,6 +40,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -42,12 +48,180 @@
- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
- PurgedFiles TINYINT DEFAULT 0,
- HasBase TINYINT DEFAULT 0,
-- PRIMARY KEY(JobId)
-+ PRIMARY KEY(JobId)
- );
--CREATE INDEX inx61 ON JobHistory (Name);
-+CREATE INDEX inx6 ON Job (Name);
-
-+INSERT INTO Job (JobId, Job, Name, Type, Level, ClientId, JobStatus,
-+SchedTime, StartTime, EndTime, RealEndTime, JobTDate, VolSessionId,
-+VolSessionTime, JobFiles, JobBytes, JobErrors, JobMissingFiles,
-+PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase) SELECT
-+JobId, Job, Name, Type, Level, ClientId, JobStatus, SchedTime, StartTime,
-+EndTime, RealEndTime, JobTDate, VolSessionId, VolSessionTime, JobFiles,
-+JobBytes, JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId,
-+PurgedFiles, HasBase FROM Job_backup;
-+
-+DROP TABLE Job_backup;
-+
-+
-+-- ----------------------------------------------------------------
-+-- New ActionOnPurge field
-+
-+CREATE TEMPORARY TABLE pool_backup AS SELECT * FROM Pool;
-+DROP TABLE Pool;
-+
-+CREATE TABLE Pool (
-+ PoolId INTEGER,
-+ Name VARCHAR(128) NOT NULL,
-+ NumVols INTEGER UNSIGNED DEFAULT 0,
-+ MaxVols INTEGER UNSIGNED DEFAULT 0,
-+ UseOnce TINYINT DEFAULT 0,
-+ UseCatalog TINYINT DEFAULT 1,
-+ AcceptAnyVolume TINYINT DEFAULT 0,
-+ VolRetention BIGINT UNSIGNED DEFAULT 0,
-+ VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-+ MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-+ AutoPrune TINYINT DEFAULT 0,
-+ Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
-+ PoolType VARCHAR(20) NOT NULL,
-+ LabelType TINYINT DEFAULT 0,
-+ LabelFormat VARCHAR(128) NOT NULL,
-+ Enabled TINYINT DEFAULT 1,
-+ ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ NextPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ MigrationHighBytes BIGINT UNSIGNED DEFAULT 0,
-+ MigrationLowBytes BIGINT UNSIGNED DEFAULT 0,
-+ MigrationTime BIGINT UNSIGNED DEFAULT 0,
-+ UNIQUE (Name),
-+ PRIMARY KEY (PoolId)
-+ );
-+
-+INSERT INTO Pool (PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog,
-+AcceptAnyVolume, VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles,
-+MaxVolBytes, AutoPrune, Recycle, PoolType, LabelType,
-+LabelFormat, Enabled, ScratchPoolId, RecyclePoolId, NextPoolId,
-+MigrationHighBytes, MigrationLowBytes, MigrationTime)
-+SELECT PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog, AcceptAnyVolume,
-+VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles, MaxVolBytes, AutoPrune,
-+Recycle, PoolType, LabelType, LabelFormat, Enabled,
-+ScratchPoolId, RecyclePoolId, NextPoolId, MigrationHighBytes,
-+MigrationLowBytes, MigrationTime FROM pool_backup;
-+
-+DROP TABLE pool_backup;
-+
-+-- ----------------------------------------------------------------
-+-- New ActionOnPurge field
-+
-+CREATE TEMPORARY TABLE media_backup AS SELECT * FROM Media;
-+DROP TABLE Media;
-+
-+CREATE TABLE Media (
-+ MediaId INTEGER,
-+ VolumeName VARCHAR(128) NOT NULL,
-+ Slot INTEGER DEFAULT 0,
-+ PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ MediaType VARCHAR(128) NOT NULL,
-+ MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0,
-+ LabelType TINYINT DEFAULT 0,
-+ FirstWritten DATETIME DEFAULT 0,
-+ LastWritten DATETIME DEFAULT 0,
-+ LabelDate DATETIME DEFAULT 0,
-+ VolJobs INTEGER UNSIGNED DEFAULT 0,
-+ VolFiles INTEGER UNSIGNED DEFAULT 0,
-+ VolBlocks INTEGER UNSIGNED DEFAULT 0,
-+ VolMounts INTEGER UNSIGNED DEFAULT 0,
-+ VolBytes BIGINT UNSIGNED DEFAULT 0,
-+ VolParts INTEGER UNSIGNED DEFAULT 0,
-+ VolErrors INTEGER UNSIGNED DEFAULT 0,
-+ VolWrites INTEGER UNSIGNED DEFAULT 0,
-+ VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
-+ VolStatus VARCHAR(20) NOT NULL,
-+ Enabled TINYINT DEFAULT 1,
-+ Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
-+ VolRetention BIGINT UNSIGNED DEFAULT 0,
-+ VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-+ MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-+ InChanger TINYINT DEFAULT 0,
-+ StorageId INTEGER UNSIGNED REFERENCES Storage DEFAULT 0,
-+ DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0,
-+ MediaAddressing TINYINT DEFAULT 0,
-+ VolReadTime BIGINT UNSIGNED DEFAULT 0,
-+ VolWriteTime BIGINT UNSIGNED DEFAULT 0,
-+ EndFile INTEGER UNSIGNED DEFAULT 0,
-+ EndBlock INTEGER UNSIGNED DEFAULT 0,
-+ LocationId INTEGER UNSIGNED REFERENCES Location DEFAULT 0,
-+ RecycleCount INTEGER UNSIGNED DEFAULT 0,
-+ InitialWrite DATETIME DEFAULT 0,
-+ ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ Comment TEXT,
-+ PRIMARY KEY(MediaId)
-+ );
-+
-+CREATE INDEX inx8 ON Media (PoolId);
-+
-+INSERT INTO Media (
-+ MediaId, VolumeName, Slot, PoolId, MediaType, MediaTypeId,
-+ LabelType, FirstWritten, LastWritten, LabelDate, VolJobs,
-+ VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors,
-+ VolWrites, VolCapacityBytes, VolStatus, Enabled, Recycle,
-+ VolRetention, VolUseDuration, MaxVolJobs,
-+ MaxVolFiles, MaxVolBytes, InChanger, StorageId, DeviceId,
-+ MediaAddressing, VolReadTime, VolWriteTime, EndFile, EndBlock,
-+ LocationId, RecycleCount, InitialWrite, ScratchPoolId,
-+ RecyclePoolId, Comment)
-+SELECT MediaId, VolumeName, Slot, PoolId, MediaType, MediaTypeId,
-+ LabelType, FirstWritten, LastWritten, LabelDate, VolJobs,
-+ VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors,
-+ VolWrites, VolCapacityBytes, VolStatus, Enabled, Recycle,
-+ VolRetention, VolUseDuration, MaxVolJobs,
-+ MaxVolFiles, MaxVolBytes, InChanger, StorageId, DeviceId,
-+ MediaAddressing, VolReadTime, VolWriteTime, EndFile, EndBlock,
-+ LocationId, RecycleCount, InitialWrite, ScratchPoolId,
-+ RecyclePoolId, Comment FROM media_backup;
-+
-+DROP TABLE media_backup;
-+
- UPDATE Version SET VersionId=11;
--
- COMMIT;
-
-+-- If you have already this table, you can remove it with:
-+-- DROP TABLE JobHistory;
-+
-+-- Create a table like Job for long term statistics
-+CREATE TABLE JobHisto (
-+ JobId INTEGER,
-+ Job VARCHAR(128) NOT NULL,
-+ Name VARCHAR(128) NOT NULL,
-+ Type CHAR NOT NULL,
-+ Level CHAR NOT NULL,
-+ ClientId INTEGER REFERENCES Client DEFAULT 0,
-+ JobStatus CHAR NOT NULL,
-+ SchedTime DATETIME NOT NULL,
-+ StartTime DATETIME DEFAULT 0,
-+ EndTime DATETIME DEFAULT 0,
-+ RealEndTime DATETIME DEFAULT 0,
-+ JobTDate BIGINT UNSIGNED DEFAULT 0,
-+ VolSessionId INTEGER UNSIGNED DEFAULT 0,
-+ VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-+ JobFiles INTEGER UNSIGNED DEFAULT 0,
-+ JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
-+ JobErrors INTEGER UNSIGNED DEFAULT 0,
-+ JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-+ PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-+ PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-+ PurgedFiles TINYINT DEFAULT 0,
-+ HasBase TINYINT DEFAULT 0
-+ );
-+CREATE INDEX inx61 ON JobHisto (StartTime);
-+
- END-OF-DATA
-Index: src/cats/make_postgresql_tables.in
-===================================================================
---- src/cats/make_postgresql_tables.in (revision 8456)
-+++ src/cats/make_postgresql_tables.in (working copy)
-@@ -15,7 +15,7 @@
- );
-
- ALTER TABLE filename ALTER COLUMN name SET STATISTICS 1000;
--CREATE INDEX filename_name_idx on filename (name);
-+CREATE UNIQUE INDEX filename_name_idx on filename (name);
-
- CREATE TABLE path
- (
-@@ -25,11 +25,11 @@
- );
-
- ALTER TABLE path ALTER COLUMN path SET STATISTICS 1000;
--CREATE INDEX path_name_idx on path (path);
-+CREATE UNIQUE INDEX path_name_idx on path (path);
-
- CREATE TABLE file
- (
-- fileid serial not null,
-+ fileid bigserial not null,
- fileindex integer not null default 0,
- jobid integer not null,
- pathid integer not null,
-@@ -74,6 +74,7 @@
- volsessiontime integer default 0,
- jobfiles integer default 0,
- jobbytes bigint default 0,
-+ readbytes bigint default 0,
- joberrors integer default 0,
- jobmissingfiles integer default 0,
- poolid integer default 0,
-@@ -87,8 +88,10 @@
- CREATE INDEX job_name_idx on job (name);
-
- -- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (LIKE Job);
-+CREATE TABLE JobHisto (LIKE Job);
-+CREATE INDEX jobhisto_idx ON jobhisto ( starttime );
-
-+
- CREATE TABLE Location (
- LocationId serial not null,
- Location text not null,
-@@ -154,6 +157,7 @@
- 'Error','Busy','Used','Cleaning','Scratch')),
- enabled smallint default 1,
- recycle smallint default 0,
-+ ActionOnPurge smallint default 0,
- volretention bigint default 0,
- voluseduration bigint default 0,
- maxvoljobs integer default 0,
-@@ -229,6 +233,7 @@
- maxvolbytes bigint default 0,
- autoprune smallint default 0,
- recycle smallint default 0,
-+ ActionOnPurge smallint default 0,
- pooltype text
- check (pooltype in ('Backup','Copy','Cloned','Archive','Migration','Scratch')),
- labeltype integer default 0,
-@@ -300,7 +305,7 @@
- (
- baseid serial not null,
- jobid integer not null,
-- fileid integer not null,
-+ fileid bigint not null,
- fileindex integer ,
- basejobid integer ,
- primary key (baseid)
-@@ -377,7 +382,7 @@
- INSERT INTO Status (JobStatus,JobStatusLong) VALUES
- ('i', 'Doing batch insert file records');
-
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (VersionId) VALUES (11);
-
- -- Make sure we have appropriate permissions
-
-Index: src/cats/update_sqlite_tables.in
-===================================================================
---- src/cats/update_sqlite_tables.in (revision 8456)
-+++ src/cats/update_sqlite_tables.in (working copy)
-@@ -17,9 +17,11 @@
- ${bindir}/${sqlite} $* ${db_name}.db <<END-OF-DATA
- BEGIN TRANSACTION;
-
---- Create a table like Job for long term statistics
-+CREATE TEMPORARY TABLE job_backup AS SELECT * FROM Job;
-+DROP TABLE Job;
-
--CREATE TABLE JobHistory (
-+CREATE TABLE Job
-+(
- JobId INTEGER,
- Job VARCHAR(128) NOT NULL,
- Name VARCHAR(128) NOT NULL,
-@@ -36,6 +38,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -43,12 +46,182 @@
- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
- PurgedFiles TINYINT DEFAULT 0,
- HasBase TINYINT DEFAULT 0,
-- PRIMARY KEY(JobId)
-+ PRIMARY KEY(JobId)
- );
--CREATE INDEX inx61 ON JobHistory (Name);
-+CREATE INDEX inx6 ON Job (Name);
-
-+INSERT INTO Job (JobId, Job, Name, Type, Level, ClientId, JobStatus,
-+SchedTime, StartTime, EndTime, RealEndTime, JobTDate, VolSessionId,
-+VolSessionTime, JobFiles, JobBytes, JobErrors, JobMissingFiles,
-+PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase) SELECT
-+JobId, Job, Name, Type, Level, ClientId, JobStatus, SchedTime, StartTime,
-+EndTime, RealEndTime, JobTDate, VolSessionId, VolSessionTime, JobFiles,
-+JobBytes, JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId,
-+PurgedFiles, HasBase FROM Job_backup;
-+
-+DROP TABLE Job_backup;
-+
-+-- ----------------------------------------------------------------
-+-- New ActionOnPurge field
-+
-+CREATE TEMPORARY TABLE pool_backup AS SELECT * FROM Pool;
-+DROP TABLE Pool;
-+
-+CREATE TABLE Pool (
-+ PoolId INTEGER,
-+ Name VARCHAR(128) NOT NULL,
-+ NumVols INTEGER UNSIGNED DEFAULT 0,
-+ MaxVols INTEGER UNSIGNED DEFAULT 0,
-+ UseOnce TINYINT DEFAULT 0,
-+ UseCatalog TINYINT DEFAULT 1,
-+ AcceptAnyVolume TINYINT DEFAULT 0,
-+ VolRetention BIGINT UNSIGNED DEFAULT 0,
-+ VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-+ MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-+ AutoPrune TINYINT DEFAULT 0,
-+ Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
-+ PoolType VARCHAR(20) NOT NULL,
-+ LabelType TINYINT DEFAULT 0,
-+ LabelFormat VARCHAR(128) NOT NULL,
-+ Enabled TINYINT DEFAULT 1,
-+ ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ NextPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ MigrationHighBytes BIGINT UNSIGNED DEFAULT 0,
-+ MigrationLowBytes BIGINT UNSIGNED DEFAULT 0,
-+ MigrationTime BIGINT UNSIGNED DEFAULT 0,
-+ UNIQUE (Name),
-+ PRIMARY KEY (PoolId)
-+ );
-+
-+INSERT INTO Pool (PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog,
-+AcceptAnyVolume, VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles,
-+MaxVolBytes, AutoPrune, Recycle, PoolType, LabelType,
-+LabelFormat, Enabled, ScratchPoolId, RecyclePoolId, NextPoolId,
-+MigrationHighBytes, MigrationLowBytes, MigrationTime)
-+SELECT PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog, AcceptAnyVolume,
-+VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles, MaxVolBytes, AutoPrune,
-+Recycle, PoolType, LabelType, LabelFormat, Enabled,
-+ScratchPoolId, RecyclePoolId, NextPoolId, MigrationHighBytes,
-+MigrationLowBytes, MigrationTime FROM pool_backup;
-+
-+DROP TABLE pool_backup;
-+
-+-- ----------------------------------------------------------------
-+-- New ActionOnPurge field
-+
-+CREATE TEMPORARY TABLE media_backup AS SELECT * FROM Media;
-+DROP TABLE Media;
-+
-+CREATE TABLE Media (
-+ MediaId INTEGER,
-+ VolumeName VARCHAR(128) NOT NULL,
-+ Slot INTEGER DEFAULT 0,
-+ PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ MediaType VARCHAR(128) NOT NULL,
-+ MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0,
-+ LabelType TINYINT DEFAULT 0,
-+ FirstWritten DATETIME DEFAULT 0,
-+ LastWritten DATETIME DEFAULT 0,
-+ LabelDate DATETIME DEFAULT 0,
-+ VolJobs INTEGER UNSIGNED DEFAULT 0,
-+ VolFiles INTEGER UNSIGNED DEFAULT 0,
-+ VolBlocks INTEGER UNSIGNED DEFAULT 0,
-+ VolMounts INTEGER UNSIGNED DEFAULT 0,
-+ VolBytes BIGINT UNSIGNED DEFAULT 0,
-+ VolParts INTEGER UNSIGNED DEFAULT 0,
-+ VolErrors INTEGER UNSIGNED DEFAULT 0,
-+ VolWrites INTEGER UNSIGNED DEFAULT 0,
-+ VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
-+ VolStatus VARCHAR(20) NOT NULL,
-+ Enabled TINYINT DEFAULT 1,
-+ Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
-+ VolRetention BIGINT UNSIGNED DEFAULT 0,
-+ VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-+ MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-+ MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-+ InChanger TINYINT DEFAULT 0,
-+ StorageId INTEGER UNSIGNED REFERENCES Storage DEFAULT 0,
-+ DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0,
-+ MediaAddressing TINYINT DEFAULT 0,
-+ VolReadTime BIGINT UNSIGNED DEFAULT 0,
-+ VolWriteTime BIGINT UNSIGNED DEFAULT 0,
-+ EndFile INTEGER UNSIGNED DEFAULT 0,
-+ EndBlock INTEGER UNSIGNED DEFAULT 0,
-+ LocationId INTEGER UNSIGNED REFERENCES Location DEFAULT 0,
-+ RecycleCount INTEGER UNSIGNED DEFAULT 0,
-+ InitialWrite DATETIME DEFAULT 0,
-+ ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ Comment TEXT,
-+ PRIMARY KEY(MediaId)
-+ );
-+
-+CREATE INDEX inx8 ON Media (PoolId);
-+
-+INSERT INTO Media (
-+ MediaId, VolumeName, Slot, PoolId, MediaType, MediaTypeId,
-+ LabelType, FirstWritten, LastWritten, LabelDate, VolJobs,
-+ VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors,
-+ VolWrites, VolCapacityBytes, VolStatus, Enabled, Recycle,
-+ VolRetention, VolUseDuration, MaxVolJobs,
-+ MaxVolFiles, MaxVolBytes, InChanger, StorageId, DeviceId,
-+ MediaAddressing, VolReadTime, VolWriteTime, EndFile, EndBlock,
-+ LocationId, RecycleCount, InitialWrite, ScratchPoolId,
-+ RecyclePoolId, Comment)
-+SELECT MediaId, VolumeName, Slot, PoolId, MediaType, MediaTypeId,
-+ LabelType, FirstWritten, LastWritten, LabelDate, VolJobs,
-+ VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors,
-+ VolWrites, VolCapacityBytes, VolStatus, Enabled, Recycle,
-+ VolRetention, VolUseDuration, MaxVolJobs,
-+ MaxVolFiles, MaxVolBytes, InChanger, StorageId, DeviceId,
-+ MediaAddressing, VolReadTime, VolWriteTime, EndFile, EndBlock,
-+ LocationId, RecycleCount, InitialWrite, ScratchPoolId,
-+ RecyclePoolId, Comment FROM media_backup;
-+
-+DROP TABLE media_backup;
-+
-+-- ----------------------------------------------------------------
-+
- UPDATE Version SET VersionId=11;
-
- COMMIT;
-
-+-- If you have already this table, you can remove it with:
-+-- DROP TABLE JobHistory;
-+
-+-- Create a table like Job for long term statistics
-+CREATE TABLE JobHisto (
-+ JobId INTEGER,
-+ Job VARCHAR(128) NOT NULL,
-+ Name VARCHAR(128) NOT NULL,
-+ Type CHAR NOT NULL,
-+ Level CHAR NOT NULL,
-+ ClientId INTEGER REFERENCES Client DEFAULT 0,
-+ JobStatus CHAR NOT NULL,
-+ SchedTime DATETIME NOT NULL,
-+ StartTime DATETIME DEFAULT 0,
-+ EndTime DATETIME DEFAULT 0,
-+ RealEndTime DATETIME DEFAULT 0,
-+ JobTDate BIGINT UNSIGNED DEFAULT 0,
-+ VolSessionId INTEGER UNSIGNED DEFAULT 0,
-+ VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-+ JobFiles INTEGER UNSIGNED DEFAULT 0,
-+ JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
-+ JobErrors INTEGER UNSIGNED DEFAULT 0,
-+ JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-+ PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-+ FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-+ PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-+ PurgedFiles TINYINT DEFAULT 0,
-+ HasBase TINYINT DEFAULT 0
-+ );
-+CREATE INDEX inx61 ON JobHisto (StartTime);
-+
- END-OF-DATA
-Index: src/cats/update_mysql_tables.in
-===================================================================
---- src/cats/update_mysql_tables.in (revision 8456)
-+++ src/cats/update_mysql_tables.in (working copy)
-@@ -12,16 +12,50 @@
- if $bindir/mysql $* -f <<END-OF-DATA
- USE ${db_name};
-
---- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (LIKE Job);
--
- -- Fix bad index on Media table
--DROP INDEX inx8;
-+DROP INDEX inx8 ON Media;
- CREATE UNIQUE INDEX inx8 ON Media (VolumeName(128));
-+ALTER TABLE File CHANGE FileId FileId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT;
-+ALTER TABLE BaseFiles CHANGE FileId FileId BIGINT UNSIGNED NOT NULL;
-+ALTER TABLE Job ADD ReadBytes BIGINT UNSIGNED DEFAULT 0 AFTER JobBytes;
-+ALTER TABLE Media ADD ActionOnPurge TINYINT DEFAULT 0 AFTER Recycle;
-+ALTER TABLE Pool ADD ActionOnPurge TINYINT DEFAULT 0 AFTER Recycle;
-
- DELETE FROM Version;
- INSERT INTO Version (VersionId) VALUES (11);
-
-+-- If you have already this table, you can remove it with:
-+-- DROP TABLE JobHistory;
-+
-+-- Create a table like Job for long term statistics
-+CREATE TABLE JobHisto (
-+ JobId INTEGER UNSIGNED NOT NULL,
-+ Job TINYBLOB NOT NULL,
-+ Name TINYBLOB NOT NULL,
-+ Type BINARY(1) NOT NULL,
-+ Level BINARY(1) NOT NULL,
-+ ClientId INTEGER DEFAULT 0,
-+ JobStatus BINARY(1) NOT NULL,
-+ SchedTime DATETIME DEFAULT 0,
-+ StartTime DATETIME DEFAULT 0,
-+ EndTime DATETIME DEFAULT 0,
-+ RealEndTime DATETIME DEFAULT 0,
-+ JobTDate BIGINT UNSIGNED DEFAULT 0,
-+ VolSessionId INTEGER UNSIGNED DEFAULT 0,
-+ VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-+ JobFiles INTEGER UNSIGNED DEFAULT 0,
-+ JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
-+ JobErrors INTEGER UNSIGNED DEFAULT 0,
-+ JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-+ PoolId INTEGER UNSIGNED DEFAULT 0,
-+ FileSetId INTEGER UNSIGNED DEFAULT 0,
-+ PriorJobId INTEGER UNSIGNED DEFAULT 0,
-+ PurgedFiles TINYINT DEFAULT 0,
-+ HasBase TINYINT DEFAULT 0,
-+ INDEX (StartTime)
-+ );
-+
- END-OF-DATA
- then
- echo "Update of Bacula MySQL tables succeeded."
-Index: src/cats/make_sqlite_tables.in
-===================================================================
---- src/cats/make_sqlite_tables.in (revision 8456)
-+++ src/cats/make_sqlite_tables.in (working copy)
-@@ -64,6 +64,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-@@ -76,13 +77,13 @@
- CREATE INDEX inx6 ON Job (Name);
-
- -- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (
-+CREATE TABLE JobHisto (
- JobId INTEGER,
- Job VARCHAR(128) NOT NULL,
- Name VARCHAR(128) NOT NULL,
- Type CHAR(1) NOT NULL,
- Level CHAR(1) NOT NULL,
-- ClientId INTEGER REFERENCES Client DEFAULT 0,
-+ ClientId INTEGER DEFAULT 0,
- JobStatus CHAR(1) NOT NULL,
- SchedTime DATETIME NOT NULL,
- StartTime DATETIME DEFAULT 0,
-@@ -93,16 +94,16 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-+ PoolId INTEGER UNSIGNED DEFAULT 0,
-+ FileSetId INTEGER UNSIGNED DEFAULT 0,
-+ PriorJobId INTEGER UNSIGNED DEFAULT 0,
- PurgedFiles TINYINT DEFAULT 0,
-- HasBase TINYINT DEFAULT 0,
-- PRIMARY KEY(JobId)
-+ HasBase TINYINT DEFAULT 0
- );
--CREATE INDEX inx61 ON JobHistory (Name);
-+CREATE INDEX inx61 ON JobHisto (StartTime);
-
- CREATE TABLE Location (
- LocationId INTEGER,
-@@ -183,6 +184,7 @@
- VolStatus VARCHAR(20) NOT NULL,
- Enabled TINYINT DEFAULT 1,
- Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
- VolRetention BIGINT UNSIGNED DEFAULT 0,
- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-@@ -256,6 +258,7 @@
- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
- AutoPrune TINYINT DEFAULT 0,
- Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
- PoolType VARCHAR(20) NOT NULL,
- LabelType TINYINT DEFAULT 0,
- LabelFormat VARCHAR(128) NOT NULL,
-@@ -383,7 +386,7 @@
-
-
- -- Initialize Version
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (VersionId) VALUES (11);
-
-
- PRAGMA default_synchronous = OFF;
-Index: src/cats/sql_get.c
-===================================================================
---- src/cats/sql_get.c (revision 8456)
-+++ src/cats/sql_get.c (working copy)
-@@ -297,13 +297,13 @@
- Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime,"
- "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
- "Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId,"
--"SchedTime,RealEndTime "
-+"SchedTime,RealEndTime,ReadBytes "
- "FROM Job WHERE Job='%s'", jr->Job);
- } else {
- Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime,"
- "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
- "Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId,"
--"SchedTime,RealEndTime "
-+"SchedTime,RealEndTime,ReadBytes "
- "FROM Job WHERE JobId=%s",
- edit_int64(jr->JobId, ed1));
- }
-@@ -341,6 +341,7 @@
- jr->FileSetId = str_to_int64(row[17]);
- bstrncpy(jr->cSchedTime, row[3]!=NULL?row[18]:"", sizeof(jr->cSchedTime));
- bstrncpy(jr->cRealEndTime, row[3]!=NULL?row[19]:"", sizeof(jr->cRealEndTime));
-+ jr->ReadBytes = str_to_int64(row[20]);
- jr->StartTime = str_to_utime(jr->cStartTime);
- jr->SchedTime = str_to_utime(jr->cSchedTime);
- jr->EndTime = str_to_utime(jr->cEndTime);
-Index: src/cats/sql_cmds.c
-===================================================================
---- src/cats/sql_cmds.c (revision 8456)
-+++ src/cats/sql_cmds.c (working copy)
-@@ -44,6 +44,26 @@
- #include "bacula.h"
- #include "cats.h"
-
-+
-+/* For sql_update.c db_update_stats */
-+const char *fill_jobhisto =
-+ "INSERT INTO JobHisto ("
-+ "JobId, Job, Name, Type, Level, ClientId, JobStatus, "
-+ "SchedTime, StartTime, EndTime, RealEndTime, JobTDate, "
-+ "VolSessionId, VolSessionTime, JobFiles, JobBytes, ReadBytes, "
-+ "JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, "
-+ "PurgedFiles, HasBase ) "
-+ "SELECT "
-+ "JobId, Job, Name, Type, Level, ClientId, JobStatus, "
-+ "SchedTime, StartTime, EndTime, RealEndTime, JobTDate, "
-+ "VolSessionId, VolSessionTime, JobFiles, JobBytes, ReadBytes, "
-+ "JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, "
-+ "PurgedFiles, HasBase "
-+ "FROM Job "
-+ "WHERE JobStatus IN ('T', 'f', 'A', 'E') "
-+ "AND JobId NOT IN (SELECT JobId FROM JobHisto) "
-+ "AND JobTDate < %s ";
-+
- /* For ua_update.c */
- const char *list_pool = "SELECT * FROM Pool WHERE PoolId=%s";
-
-Index: src/cats/drop_mysql_tables.in
-===================================================================
---- src/cats/drop_mysql_tables.in (revision 8456)
-+++ src/cats/drop_mysql_tables.in (working copy)
-@@ -16,7 +16,7 @@
- DROP TABLE IF EXISTS File;
- DROP TABLE IF EXISTS Client;
- DROP TABLE IF EXISTS Job;
--DROP TABLE IF EXISTS JobHistory;
-+DROP TABLE IF EXISTS JobHisto;
- DROP TABLE IF EXISTS Media;
- DROP TABLE IF EXISTS JobMedia;
- DROP TABLE IF EXISTS Pool;
-Index: src/cats/sql_cmds.h
-===================================================================
---- src/cats/sql_cmds.h (revision 8456)
-+++ src/cats/sql_cmds.h (working copy)
-@@ -26,7 +26,7 @@
- Switzerland, email:ftf@fsfeurope.org.
- */
-
--
-+extern const char CATS_IMP_EXP *fill_jobhisto;
- extern const char CATS_IMP_EXP *client_backups;
- extern const char CATS_IMP_EXP *list_pool;
- extern const char CATS_IMP_EXP *drop_deltabs[];
-Index: src/cats/grant_postgresql_privileges.in
-===================================================================
---- src/cats/grant_postgresql_privileges.in (revision 8456)
-+++ src/cats/grant_postgresql_privileges.in (working copy)
-@@ -32,7 +32,7 @@
- grant all on location to ${db_user};
- grant all on locationlog to ${db_user};
- grant all on log to ${db_user};
--grant all on jobhistory to ${db_user};
-+grant all on jobhisto to ${db_user};
-
- -- for sequences on those tables
-
-Index: src/cats/make_mysql_tables.in
-===================================================================
---- src/cats/make_mysql_tables.in (revision 8456)
-+++ src/cats/make_mysql_tables.in (working copy)
-@@ -29,7 +29,7 @@
-
-
- CREATE TABLE File (
-- FileId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-+ FileId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
- FileIndex INTEGER UNSIGNED DEFAULT 0,
- JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
- PathId INTEGER UNSIGNED NOT NULL REFERENCES Path,
-@@ -104,6 +104,7 @@
- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
- JobFiles INTEGER UNSIGNED DEFAULT 0,
- JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
- JobErrors INTEGER UNSIGNED DEFAULT 0,
- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
- PoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
-@@ -116,7 +117,33 @@
- );
-
- -- Create a table like Job for long term statistics
--CREATE TABLE JobHistory (LIKE Job);
-+CREATE TABLE JobHisto (
-+ JobId INTEGER UNSIGNED NOT NULL,
-+ Job TINYBLOB NOT NULL,
-+ Name TINYBLOB NOT NULL,
-+ Type BINARY(1) NOT NULL,
-+ Level BINARY(1) NOT NULL,
-+ ClientId INTEGER DEFAULT 0,
-+ JobStatus BINARY(1) NOT NULL,
-+ SchedTime DATETIME DEFAULT 0,
-+ StartTime DATETIME DEFAULT 0,
-+ EndTime DATETIME DEFAULT 0,
-+ RealEndTime DATETIME DEFAULT 0,
-+ JobTDate BIGINT UNSIGNED DEFAULT 0,
-+ VolSessionId INTEGER UNSIGNED DEFAULT 0,
-+ VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-+ JobFiles INTEGER UNSIGNED DEFAULT 0,
-+ JobBytes BIGINT UNSIGNED DEFAULT 0,
-+ ReadBytes BIGINT UNSIGNED DEFAULT 0,
-+ JobErrors INTEGER UNSIGNED DEFAULT 0,
-+ JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-+ PoolId INTEGER UNSIGNED DEFAULT 0,
-+ FileSetId INTEGER UNSIGNED DEFAULT 0,
-+ PriorJobId INTEGER UNSIGNED DEFAULT 0,
-+ PurgedFiles TINYINT DEFAULT 0,
-+ HasBase TINYINT DEFAULT 0,
-+ INDEX (StartTime)
-+ );
-
- CREATE TABLE Location (
- LocationId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-@@ -190,6 +217,7 @@
- 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
- Enabled TINYINT DEFAULT 1,
- Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
- VolRetention BIGINT UNSIGNED DEFAULT 0,
- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-@@ -229,6 +257,7 @@
- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
- AutoPrune TINYINT DEFAULT 0,
- Recycle TINYINT DEFAULT 0,
-+ ActionOnPurge TINYINT DEFAULT 0,
- PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch') NOT NULL,
- LabelType TINYINT DEFAULT 0,
- LabelFormat TINYBLOB,
-@@ -269,7 +298,7 @@
- BaseId INTEGER UNSIGNED AUTO_INCREMENT,
- BaseJobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
- JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
-- FileId INTEGER UNSIGNED NOT NULL REFERENCES File,
-+ FileId BIGINT UNSIGNED NOT NULL REFERENCES File,
- FileIndex INTEGER UNSIGNED,
- PRIMARY KEY(BaseId)
- );
-@@ -333,7 +362,7 @@
- );
-
- -- Initialize Version
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (VersionId) VALUES (11);
-
- END-OF-DATA
- then
-Index: src/bc_types.h
-===================================================================
---- src/bc_types.h (revision 8456)
-+++ src/bc_types.h (working copy)
-@@ -57,7 +57,7 @@
- * In principle, the only field that really should need to be
- * 64 bits is the FileId_t
- */
--typedef uint32_t FileId_t;
-+typedef uint64_t FileId_t;
- typedef uint32_t DBId_t; /* general DB id type */
- typedef uint32_t JobId_t;
-
+++ /dev/null
-Index: src/cats/postgresql.c
-===================================================================
---- src/cats/postgresql.c (revision 8452)
-+++ src/cats/postgresql.c (working copy)
-@@ -132,6 +132,34 @@
- return mdb;
- }
-
-+/* Check that the database correspond to the encoding we want */
-+static bool check_database_encoding(JCR *jcr, B_DB *mdb)
-+{
-+ SQL_ROW row;
-+ int ret=false;
-+
-+ if (!db_sql_query(mdb, "SELECT getdatabaseencoding()", NULL, NULL)) {
-+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-+ return false;
-+ }
-+
-+ if (mdb->num_rows == 1) {
-+ 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 {
-+ ret = bstrcmp(row[0], "SQL_ASCII") ;
-+ if (!ret) {
-+ Mmsg(mdb->errmsg,
-+ _("Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n"),
-+ mdb->db_name, row[0]);
-+ Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-+ }
-+ }
-+ }
-+ return ret;
-+}
-+
- /*
- * Now actually open the database. This can generate errors,
- * which are returned in the errmsg
-@@ -147,7 +175,7 @@
- #ifdef xxx
- if (!PQisthreadsafe()) {
- Jmsg(jcr, M_ABORT, 0, _("PostgreSQL configuration problem. "
-- "PostgreSQL library is not thread safe. Connot continue.\n"));
-+ "PostgreSQL library is not thread safe. Cannot continue.\n"));
- }
- #endif
- P(mutex);
-@@ -219,6 +247,9 @@
- */
- sql_query(mdb, "set standard_conforming_strings=on");
-
-+ /* check that encoding is SQL_ASCII */
-+ check_database_encoding(jcr, mdb);
-+
- V(mutex);
- return 1;
- }