]> git.sur5r.net Git - bacula/bacula/commitdiff
- Add back JobId index for MySQL as default -- speeds up
authorKern Sibbald <kern@sibbald.com>
Sat, 19 Feb 2005 15:29:48 +0000 (15:29 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 19 Feb 2005 15:29:48 +0000 (15:29 +0000)
  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.

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

23 files changed:
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_postgresql_tables.in
bacula/src/cats/make_sqlite3_tables.in
bacula/src/cats/make_sqlite_tables.in
bacula/src/cats/update_mysql_tables.in
bacula/src/cats/update_postgresql_tables.in
bacula/src/cats/update_sqlite3_tables.in
bacula/src/cats/update_sqlite_tables.in
bacula/src/dird/backup.c
bacula/src/dird/fd_cmds.c
bacula/src/dird/jobq.c
bacula/src/dird/sql_cmds.c
bacula/src/filed/job.c
bacula/src/lib/address_conf.c
bacula/src/lib/address_conf.h
bacula/src/lib/scan.c
bacula/src/stored/butil.c
bacula/src/stored/dev.c
bacula/src/stored/job.c
bacula/src/stored/protos.h
bacula/src/stored/stored.c
bacula/src/stored/stored_conf.c
bacula/src/version.h

index 8877617421fa32f125003efb822b05aaa70aa4de..6f7d0b6d68dda4edd16ecf4bef7e94aa33c0473c 100644 (file)
@@ -32,6 +32,7 @@ CREATE TABLE File (
    LStat TINYBLOB NOT NULL,
    MD5 TINYBLOB NOT NULL,
    PRIMARY KEY(FileId),
+   INDEX (JobId),
    INDEX (FilenameId, PathId)
    );
 
@@ -40,13 +41,10 @@ CREATE TABLE File (
 #  to the above File table if your Verifies are
 #  too slow.
 #
-#  INDEX (JobId),
 #  INDEX (PathId),
 #  INDEX (FilenameId),
 #  INDEX (JobId, PathId, FilenameId)
 #
-# Adding an index on JobId can speed up pruning
-#
 
 CREATE TABLE Job (
    JobId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -127,6 +125,7 @@ CREATE TABLE Media (
    MaxVolFiles INTEGER UNSIGNED NOT NULL DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
    InChanger TINYINT NOT NULL DEFAULT 0,
+   StorageId INTEGER UNSIGNED DEFAULT 0 REFERENCES Storage,
    MediaAddressing TINYINT NOT NULL DEFAULT 0,
    VolReadTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
@@ -192,6 +191,10 @@ CREATE TABLE Pool (
    Enabled TINYINT DEFAULT 1,
    ScratchPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
    RecyclePoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
+   NextPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool,
+   MigrationHighBytes BIGINT UNSIGNED DEFAULT 0,
+   MigrationLowBytes BIGINT UNSIGNED DEFAULT 0,
+   MigrationTime BIGINT UNSIGNED DEFAULT 0,
    UNIQUE (Name(128)),
    PRIMARY KEY (PoolId)
    );
index 93cfb786e05d5b6cd95f00ad3faa9f3dac998c25..97ab2806336a8694cd48666936ed35bed23d9756 100644 (file)
@@ -135,6 +135,7 @@ CREATE TABLE media
     maxvolfiles       integer    not null default 0,
     maxvolbytes       bigint     not null default 0,
     inchanger        smallint    not null default 0,
+    StorageId        integer              default 0,
     mediaaddressing   smallint   not null default 0,
     volreadtime       bigint     not null default 0,
     volwritetime      bigint     not null default 0,
@@ -200,8 +201,12 @@ CREATE TABLE pool
     labeltype        integer     not null default 0,
     labelformat       text       not null,
     enabled          smallint    not null default 1,
-    scratchpoolid     integer,                      
-    recyclepoolid     integer,
+    scratchpoolid     integer default 0,
+    recyclepoolid     integer default 0,
+    NextPoolId       integer default 0,
+    MigrationHighBytes BIGINT DEFAULT 0,
+    MigrationLowBytes  BIGINT DEFAULT 0,
+    MigrationTime      BIGINT DEFAULT 0,
     primary key (poolid)
 );
 
index fdaee106753e7123563b2dd03376a2460a3872d4..7bd3bd4b9763dd2a0e55eb54ede6bf544b7c0d6f 100644 (file)
@@ -191,6 +191,10 @@ CREATE TABLE Pool (
    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)
    );
index fdaee106753e7123563b2dd03376a2460a3872d4..7bd3bd4b9763dd2a0e55eb54ede6bf544b7c0d6f 100644 (file)
@@ -191,6 +191,10 @@ CREATE TABLE Pool (
    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)
    );
index d088d834691315323101c417f66c2143cf04094d..aeb5cde41894528832bcbd5cc033e9f32f8fe89e 100755 (executable)
@@ -13,9 +13,15 @@ if $bindir/mysql $* -f <<END-OF-DATA
 USE bacula;
 
 ALTER TABLE Media ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0;
-ALTER TABLE Pool  ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0;
+ALTER TABLE Media ADD COLUMN StorageId INTEGER UNSIGNED DEFAULT 0 REFERENCES Storage;
 ALTER TABLE Media ADD COLUMN VolParts INTEGER UNSIGNED NOT NULL DEFAULT 0;
 
+ALTER TABLE Pool  ADD COLUMN LabelType INTEGER UNSIGNED NOT NULL DEFAULT 0;
+ALTER TABLE Pool  ADD COLUMN NextPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool;
+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;
+
 CREATE TABLE MediaType (
    MediaTypeId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    MediaType VARCHAR(128) NOT NULL,
index 0c93be606211eb771d6dea492e28acd64ad7ae4f..c8e7eec63222d9db52e0a793a081b58d0e11dd66 100755 (executable)
@@ -15,9 +15,21 @@ if $bindir/psql $* -f - <<END-OF-DATA
 ALTER TABLE media ADD COLUMN labeltype integer;
 UPDATE media SET labeltype=0;
 ALTER TABLE media ALTER COLUMN labeltype SET NOT NULL;
+ALTER TABLE media ADD COLUMN StorageId integer;
+UPDATE media SET StorageId=0;
+
 ALTER TABLE pool ADD COLUMN labeltype integer;
 UPDATE pool set labeltype=0;
 ALTER TABLE pool ALTER COLUMN labeltype SET NOT NULL;
+ALTER TABLE pool ADD COLUMN NextPoolId       integer;
+ALTER TABLE pool SET NextPoolId=0;
+ALTER TABLE pool ADD COLUMN MigrationHighBytes BIGINT;
+ALTER TABLE pool SET MigrationHighBytes=0;
+ALTER TABLE pool ADD COLUMN MigrationLowBytes  BIGINT;
+ALTER TABLE pool SET MigrationLowBytes=0;
+ALTER TABLE pool ADD COLUMN MigrationTime      BIGINT;
+ALTER TABLE pool SET MigrationTime=0;
+
 
 ALTER TABLE media ADD COLUMN volparts integer;
 UPDATE media SET volparts=0;
index f5cf32813f233830c04fa3ea26bd556da21c93ac..fc863e19d990e67f4cd1f47495da551bd6128c04 100755 (executable)
@@ -1,9 +1,9 @@
 #!/bin/sh
 #
-# shell script to update SQLite from version 1.34 to 1.35.5
+# shell script to update SQLite from version 1.36 to 1.37.3
 #
 echo " "
-echo "This script will update a Bacula SQLite database from version 7 to 8"
+echo "This script will update a Bacula SQLite database from version 8 to 9"
 echo "Depending on the size of your database,"
 echo "this script may take several minutes to run."
 echo " "
@@ -40,6 +40,7 @@ CREATE TEMPORARY TABLE Media_backup (
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
    MediaAddressing TINYINT DEFAULT 0,
    VolReadTime BIGINT UNSIGNED DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED DEFAULT 0,
@@ -55,7 +56,7 @@ INSERT INTO Media_backup SELECT
    VolMounts, VolBytes, 0, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
-   MaxVolFiles, MaxVolBytes, InChanger, MediaAddressing,
+   MaxVolFiles, MaxVolBytes, InChanger, 0, MediaAddressing,
    VolReadTime, VolWriteTime, EndFile, EndBlock
    FROM Media;
 
@@ -89,6 +90,7 @@ CREATE TABLE Media (
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
    MediaAddressing TINYINT DEFAULT 0,
    VolReadTime BIGINT UNSIGNED DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED DEFAULT 0,
@@ -105,7 +107,7 @@ INSERT INTO Media (
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes,
-   InChanger, MediaAddressing,
+   InChanger, StorageId, MediaAddressing,
    VolReadTime, VolWriteTime,      
    EndFile, EndBlock)
    SELECT * FROM Media_backup;
@@ -133,6 +135,10 @@ CREATE TEMPORARY TABLE Pool_backup (
    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)
    );
@@ -143,7 +149,8 @@ INSERT INTO Pool_backup SELECT
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes, AutoPrune,
    Recycle, PoolType, 0, LabelFormat,
-   Enabled, ScratchPoolId, RecyclePoolId
+   Enabled, ScratchPoolId, RecyclePoolId,
+   0, 0, 0, 0
    FROM Pool;
 
 DROP TABLE Pool;
@@ -169,6 +176,10 @@ CREATE TABLE Pool (
    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)
    );
@@ -179,11 +190,46 @@ INSERT INTO Pool (
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes, AutoPrune,
    Recycle, PoolType, LabelType, LabelFormat,
-   Enabled, ScratchPoolId, RecyclePoolId )
+   Enabled, ScratchPoolId, RecyclePoolId,
+   NextPoolId, MigrationHighBytes, 
+   MigrationLowBytes, MigrationTime )
    SELECT * FROM Pool_backup;
 
 DROP TABLE Pool_backup;
 
+CREATE TABLE MediaType (
+   MediaTypeId INTERGER,
+   MediaType VARCHAR(128) NOT NULL,
+   ReadOnly TINYINT DEFAULT 0,
+   PRIMARY KEY(MediaTypeId)
+   );
+
+CREATE TABLE Device (
+   DeviceId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DevMounts INTEGER UNSIGNED DEFAULT 0,
+   DevReadBytes BIGINT UNSIGNED DEFAULT 0,
+   DevWriteBytes BIGINT UNSIGNED DEFAULT 0,
+   DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevReadTime BIGINT UNSIGNED DEFAULT 0,
+   DevWriteTime BIGINT UNSIGNED DEFAULT 0,
+   DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0,
+   CleaningDate DATETIME DEFAULT 0,
+   CleaningPeriod BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(DeviceId)
+   );
+
+CREATE TABLE Storage (
+   StorageId INTEGER,
+   Name VARCHAR(128) NOT NULL,
+   AutoChanger TINYINT DEFAULT 0,
+   PRIMARY KEY(StorageId)
+   );
+
 COMMIT;
 
 END-OF-DATA
index 4675ba1e31bbde9c596dd53a16526772c915059c..fc863e19d990e67f4cd1f47495da551bd6128c04 100755 (executable)
@@ -40,6 +40,7 @@ CREATE TEMPORARY TABLE Media_backup (
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
    MediaAddressing TINYINT DEFAULT 0,
    VolReadTime BIGINT UNSIGNED DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED DEFAULT 0,
@@ -55,7 +56,7 @@ INSERT INTO Media_backup SELECT
    VolMounts, VolBytes, 0, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
-   MaxVolFiles, MaxVolBytes, InChanger, MediaAddressing,
+   MaxVolFiles, MaxVolBytes, InChanger, 0, MediaAddressing,
    VolReadTime, VolWriteTime, EndFile, EndBlock
    FROM Media;
 
@@ -89,6 +90,7 @@ CREATE TABLE Media (
    MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
+   StorageId INTEGER UNSIGNED REFERENCES Storage,
    MediaAddressing TINYINT DEFAULT 0,
    VolReadTime BIGINT UNSIGNED DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED DEFAULT 0,
@@ -105,7 +107,7 @@ INSERT INTO Media (
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes,
-   InChanger, MediaAddressing,
+   InChanger, StorageId, MediaAddressing,
    VolReadTime, VolWriteTime,      
    EndFile, EndBlock)
    SELECT * FROM Media_backup;
@@ -133,6 +135,10 @@ CREATE TEMPORARY TABLE Pool_backup (
    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)
    );
@@ -143,7 +149,8 @@ INSERT INTO Pool_backup SELECT
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes, AutoPrune,
    Recycle, PoolType, 0, LabelFormat,
-   Enabled, ScratchPoolId, RecyclePoolId
+   Enabled, ScratchPoolId, RecyclePoolId,
+   0, 0, 0, 0
    FROM Pool;
 
 DROP TABLE Pool;
@@ -169,6 +176,10 @@ CREATE TABLE Pool (
    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)
    );
@@ -179,7 +190,9 @@ INSERT INTO Pool (
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes, AutoPrune,
    Recycle, PoolType, LabelType, LabelFormat,
-   Enabled, ScratchPoolId, RecyclePoolId )
+   Enabled, ScratchPoolId, RecyclePoolId,
+   NextPoolId, MigrationHighBytes, 
+   MigrationLowBytes, MigrationTime )
    SELECT * FROM Pool_backup;
 
 DROP TABLE Pool_backup;
index b2736bf6457ee5c4b281dd1ed80e6e3167cf1cad..991f0ca98fc4ef04f553e8cc8b8ef708e629aa61 100644 (file)
@@ -46,7 +46,7 @@ static char storaddr[]  = "storage address=%s port=%d ssl=%d\n";
 static char OKbackup[]   = "2000 OK backup\n";
 static char OKstore[]    = "2000 OK storage\n";
 static char EndJob[]     = "2800 End Job TermCode=%d JobFiles=%u "
-                           "ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n";
+                           "ReadBytes=%lld JobBytes=%lld Errors=%u\n";
 
 
 /* Forward referenced functions */
index e4be6d4c3657cb237c58a68c5e2ed31b0de81ed9..24e13e6e2d7f2d1bf44c4f050e7d596f0b39f95b 100644 (file)
@@ -186,6 +186,19 @@ void get_level_since_time(JCR *jcr, char *since, int since_len)
    Dmsg2(100, "Level=%c last start time=%s\n", jcr->JobLevel, jcr->stime);
 }
 
+static void send_since_time(JCR *jcr)
+{
+   BSOCK   *fd = jcr->file_bsock;
+   utime_t stime;
+   char ed1[50];
+
+   stime = str_to_utime(jcr->stime);
+   bnet_fsend(fd, levelcmd, "since_utime ", edit_uint64(stime, ed1), 0);
+   while (bget_dirmsg(fd) >= 0) {  /* allow him to poll us to sync clocks */
+      Jmsg(jcr, M_INFO, 0, "%s\n", fd->msg);
+   }
+}
+
 
 /*
  * Send level command to FD.
@@ -194,8 +207,6 @@ void get_level_since_time(JCR *jcr, char *since, int since_len)
 int send_level_command(JCR *jcr)
 {
    BSOCK   *fd = jcr->file_bsock;
-   utime_t stime;
-   char ed1[50];
    /*
     * Send Level command to File daemon
     */
@@ -209,12 +220,12 @@ int send_level_command(JCR *jcr)
       bnet_fsend(fd, levelcmd, "full", " ", 0);
       break;
    case L_DIFFERENTIAL:
+      bnet_fsend(fd, levelcmd, "differential", " ", 0);
+      send_since_time(jcr);
+      break;
    case L_INCREMENTAL:
-      stime = str_to_utime(jcr->stime);
-      bnet_fsend(fd, levelcmd, "since_utime ", edit_uint64(stime, ed1), 0);
-      while (bget_dirmsg(fd) >= 0) {  /* allow him to poll us to sync clocks */
-         Jmsg(jcr, M_INFO, 0, "%s\n", fd->msg);
-      }
+      bnet_fsend(fd, levelcmd, "incremental", " ", 0);
+      send_since_time(jcr);
       break;
    case L_SINCE:
    default:
index 1a9954c8c30d1b8c7d80c43eb5ce48779bdc0785..1345e30398ccd3c3c92a1881b637770b705f3f7d 100755 (executable)
@@ -46,7 +46,8 @@ extern JCR *jobs;
 extern "C" void *jobq_server(void *arg);
 extern "C" void *sched_wait(void *arg);
 
-static int   start_server(jobq_t *jq);
+static int  start_server(jobq_t *jq);
+static bool acquire_resources(JCR *jcr);
 
 
 
@@ -530,7 +531,7 @@ void *jobq_server(void *arg)
        *  move it to the ready queue
        */
       Dmsg0(2300, "Done check ready, now check wait queue.\n");
-      while (!jq->waiting_jobs->empty() && !jq->quit) {
+      if (!jq->waiting_jobs->empty() && !jq->quit) {
         int Priority;
         je = (jobq_item_t *)jq->waiting_jobs->first();
         jobq_item_t *re = (jobq_item_t *)jq->running_jobs->first();
@@ -548,79 +549,22 @@ void *jobq_server(void *arg)
         for ( ; je;  ) {
            /* je is current job item on the queue, jn is the next one */
            JCR *jcr = je->jcr;
-           bool skip_this_jcr = false;
            jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
+
             Dmsg3(2300, "Examining Job=%d JobPri=%d want Pri=%d\n",
               jcr->JobId, jcr->JobPriority, Priority);
+
            /* Take only jobs of correct Priority */
            if (jcr->JobPriority != Priority) {
               set_jcr_job_status(jcr, JS_WaitPriority);
               break;
            }
-           if (jcr->JobType == JT_RESTORE || jcr->JobType == JT_VERIFY) {
-              /* Let only one Restore/verify job run at a time regardless of MaxConcurrentJobs */
-              if (jcr->store->NumConcurrentJobs == 0) {
-                 jcr->store->NumConcurrentJobs = 1;
-              } else {
-                 set_jcr_job_status(jcr, JS_WaitStoreRes);
-                 je = jn;            /* point to next waiting job */
-                 continue;
-              }
-           /* We are not doing a Restore or Verify */
-           } else if (jcr->store->NumConcurrentJobs == 0 &&
-                      jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
-               /* Simple case, first job */
-               jcr->store->NumConcurrentJobs = 1;
-           } else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
-              /*
-               * At this point, we already have at least one Job running
-               *  for this Storage daemon, so we must ensure that there
-               *  is no Volume conflict. In general, it should be OK, if
-               *  all Jobs pull from the same Pool, so we check the Pools.
-               */
-               JCR *njcr;
-               lock_jcr_chain();
-               for (njcr=jobs; njcr; njcr=njcr->next) {
-                  if (njcr->JobId == 0 || njcr == jcr) {
-                     continue;
-                  }
-                  if (njcr->pool != jcr->pool) {
-                     skip_this_jcr = true;
-                     break;
-                  }
-               }
-               unlock_jcr_chain();
-               if (!skip_this_jcr) {
-                  jcr->store->NumConcurrentJobs++;
-               }
-           } else {
-              skip_this_jcr = true;
-           }
-           if (skip_this_jcr) {
-              set_jcr_job_status(jcr, JS_WaitStoreRes);
-              je = jn;               /* point to next waiting job */
-              continue;
-           }
 
-           if (jcr->client->NumConcurrentJobs < jcr->client->MaxConcurrentJobs) {
-              jcr->client->NumConcurrentJobs++;
-           } else {
-              /* Back out previous locks */
-              jcr->store->NumConcurrentJobs--;
-              set_jcr_job_status(jcr, JS_WaitClientRes);
-              je = jn;               /* point to next waiting job */
-              continue;
-           }
-           if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
-              jcr->job->NumConcurrentJobs++;
-           } else {
-              /* Back out previous locks */
-              jcr->store->NumConcurrentJobs--;
-              jcr->client->NumConcurrentJobs--;
-              set_jcr_job_status(jcr, JS_WaitJobRes);
-              je = jn;               /* Point to next waiting job */
+           if (!acquire_resources(jcr)) {
+              je = jn;            /* point to next waiting job */
               continue;
            }
+
            /* Got all locks, now remove it from wait queue and append it
             *   to the ready queue
             */
@@ -630,8 +574,9 @@ void *jobq_server(void *arg)
             Dmsg1(2300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
            je = jn;                  /* Point to next waiting job */
         } /* end for loop */
-        break;
-      } /* end while loop */
+
+      } /* end if */
+
       Dmsg0(2300, "Done checking wait queue.\n");
       /*
        * If no more ready work and we are asked to quit, then do it
@@ -665,19 +610,9 @@ void *jobq_server(void *arg)
          *   important, release the lock so that a job that has
          *   terminated can give us the resource.
          */
-        if ((stat = pthread_mutex_unlock(&jq->mutex)) != 0) {
-           berrno be;
-            Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_unlock: ERR=%s\n", be.strerror(stat));
-           jq->num_workers--;
-           return NULL;
-        }
+        V(jq->mutex);
         bmicrosleep(2, 0);              /* pause for 2 seconds */
-        if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) {
-           berrno be;
-            Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_lock: ERR=%s\n", be.strerror(stat));
-           jq->num_workers--;
-           return NULL;
-        }
+        P(jq->mutex);
         /* Recompute work as something may have changed in last 2 secs */
         work = !jq->ready_jobs->empty() || !jq->waiting_jobs->empty();
       }
@@ -685,10 +620,83 @@ void *jobq_server(void *arg)
    } /* end of big for loop */
 
    Dmsg0(200, "unlock mutex\n");
-   if ((stat = pthread_mutex_unlock(&jq->mutex)) != 0) {
-      berrno be;
-      Jmsg1(NULL, M_ERROR, 0, "pthread_mutex_unlock: ERR=%s\n", be.strerror(stat));
-   }
+   V(jq->mutex);
    Dmsg0(2300, "End jobq_server\n");
    return NULL;
 }
+
+/*
+ * See if we can acquire all the necessary resources for the job (JCR)
+ *
+ *  Returns: true  if successful
+ *          false if resource failure
+ */
+static bool acquire_resources(JCR *jcr)
+{
+   bool skip_this_jcr = false;
+
+   if (jcr->JobType == JT_RESTORE || jcr->JobType == JT_VERIFY) {
+      /* 
+       * Let only one Restore/verify job run at a time regardless
+       *   of MaxConcurrentJobs.
+       */ 
+      if (jcr->store->NumConcurrentJobs == 0) {
+        jcr->store->NumConcurrentJobs = 1;
+      } else {
+        set_jcr_job_status(jcr, JS_WaitStoreRes);
+        return false;
+      }
+   /* We are not doing a Restore or Verify */
+   } else if (jcr->store->NumConcurrentJobs == 0 &&
+             jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
+       /* Simple case, first job */
+       jcr->store->NumConcurrentJobs = 1;
+   } else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
+      /*
+       * At this point, we already have at least one Job running
+       *  for this Storage daemon, so we must ensure that there
+       *  is no Volume conflict. In general, it should be OK, if
+       *  all Jobs pull from the same Pool, so we check the Pools.
+       */
+       JCR *njcr;
+       lock_jcr_chain();
+       for (njcr=jobs; njcr; njcr=njcr->next) {
+         if (njcr->JobId == 0 || njcr == jcr) {
+            continue;
+         }
+         if (njcr->pool != jcr->pool) {
+            skip_this_jcr = true;
+            break;
+         }
+       }
+       unlock_jcr_chain();
+       if (!skip_this_jcr) {
+         jcr->store->NumConcurrentJobs++;
+       }
+   } else {
+      skip_this_jcr = true;
+   }
+   if (skip_this_jcr) {
+      set_jcr_job_status(jcr, JS_WaitStoreRes);
+      return false;
+   }
+
+   if (jcr->client->NumConcurrentJobs < jcr->client->MaxConcurrentJobs) {
+      jcr->client->NumConcurrentJobs++;
+   } else {
+      /* Back out previous locks */
+      jcr->store->NumConcurrentJobs--;
+      set_jcr_job_status(jcr, JS_WaitClientRes);
+      return false;
+   }
+   if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
+      jcr->job->NumConcurrentJobs++;
+   } else {
+      /* Back out previous locks */
+      jcr->store->NumConcurrentJobs--;
+      jcr->client->NumConcurrentJobs--;
+      set_jcr_job_status(jcr, JS_WaitJobRes);
+      return false;
+   }
+   return true;
+}
index b33bbd24d1c7770891ebcfaff4c9cf638da2b614..a4913ab88797a4b88229372a95ae7c4a776cf7fa 100644 (file)
@@ -147,7 +147,7 @@ const char *select_verify_del =
 const char *select_restore_del =
    "SELECT DISTINCT DelCandidates.JobId "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND delCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%u "
    "AND Job.Type='R')";
@@ -158,7 +158,7 @@ const char *select_restore_del =
 const char *select_admin_del =
    "SELECT DISTINCT DelCandidates.JobId "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND delCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%u "
    "AND Job.Type='D')";
index 6690d949c8c68fff8504f98dd4b50b0227aee19b..8b055faa225229b15b242c039140b1822b606d5d 100644 (file)
@@ -1110,8 +1110,6 @@ static int level_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
    POOLMEM *level, *buf = NULL;
-   struct tm tm;
-   time_t mtime;
    int mtime_only;
 
    level = get_memory(dir->msglen+1);
@@ -1125,26 +1123,14 @@ static int level_cmd(JCR *jcr)
    /* Full backup requested? */
    } else if (strcmp(level, "full") == 0) {
       jcr->JobLevel = L_FULL;
-   /*
-    * Backup requested since <date> <time>
-    *  This form is also used for incremental and differential
-    *  This code is deprecated.  See since_utime for new code.
-    */
-   } else if (strcmp(level, "since") == 0) {
-      jcr->JobLevel = L_SINCE;
-      if (sscanf(dir->msg, "level = since %d-%d-%d %d:%d:%d mtime_only=%d",
-                &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
-                &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &mtime_only) != 7) {
-        goto bail_out;
-      }
-      tm.tm_year -= 1900;
-      tm.tm_mon  -= 1;
-      tm.tm_wday = tm.tm_yday = 0;
-      tm.tm_isdst = -1;
-      mtime = mktime(&tm);
-      Dmsg2(100, "Got since time: %s mtime_only=%d\n", ctime(&mtime), mtime_only);
-      jcr->incremental = 1;          /* set incremental or decremental backup */
-      jcr->mtime = mtime;            /* set since time */
+   } else if (strcmp(level, "differential") == 0) {
+      jcr->JobLevel = L_DIFFERENTIAL;
+      free_memory(level);
+      return 1;
+   } else if (strcmp(level, "incremental") == 0) {
+      jcr->JobLevel = L_INCREMENTAL;
+      free_memory(level);
+      return 1;   
    /*
     * We get his UTC since time, then sync the clocks and correct it
     *  to agree with our clock.
@@ -1153,7 +1139,6 @@ static int level_cmd(JCR *jcr)
       buf = get_memory(dir->msglen+1);
       utime_t since_time, adj;
       btime_t his_time, bt_start, rt=0, bt_adj=0;
-      jcr->JobLevel = L_SINCE;
       if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
                 buf, &mtime_only) != 2) {
         goto bail_out;
index 0ae057a47e7049fe39bf045d98a0a4c65daaa553..81fe37a800b05f8042f268d6e81f90269b240d81 100644 (file)
@@ -207,7 +207,7 @@ const char *IPADDR::build_address_str(char *buf, int blen)
 
 const char *build_addresses_str(dlist *addrs, char *buf, int blen)
 {
-   if (addrs->size() == 0) {
+   if (!addrs || addrs->size() == 0) {
       bstrncpy(buf, "", blen);
       return buf;
    }
@@ -231,12 +231,20 @@ const char *get_first_address(dlist * addrs, char *outputbuf, int outlen)
 
 int get_first_port_net_order(dlist * addrs)
 {
-   return ((IPADDR *)(addrs->first()))->get_port_net_order();
+   if (!addrs) {
+      return 0;
+   } else {
+      return ((IPADDR *)(addrs->first()))->get_port_net_order();
+   }
 }
 
 int get_first_port_host_order(dlist * addrs)
 {
-   return ((IPADDR *)(addrs->first()))->get_port_host_order();
+   if (!addrs) {
+      return 0;
+   } else {
+      return ((IPADDR *)(addrs->first()))->get_port_host_order();
+   }
 }
 
 void init_default_addresses(dlist **out, int port)
index 6145a3fb4f7a3f455ce5511c8eaac36c9b6746a9..9ded23ec5b7fe22567cb9b9c7c74c63d49e65e75 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 /*
-   Copyright (C) 2004 Kern Sibbald and John Walker
+   Copyright (C) 2004-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
index 1e54ec95afdbe2bea6b1a0ece21a104b08abe061..856ae5296da0991168eba984a8f1463f4fbb8b92 100644 (file)
@@ -292,7 +292,7 @@ void split_path_and_filename(const char *fname, POOLMEM **path, int *pnl,
 }
 
 /*
- * Extremely simple sscanf. Handles only %(u,d,ld,lu,lld,llu,c,nns)
+ * Extremely simple sscanf. Handles only %(u,d,ld,qd,qu,lu,lld,llu,c,nns)
  */
 const int BIG = 1000;
 int bsscanf(const char *buf, const char *fmt, ...)
index 4e52652fad2df23605dcc7551e2195c6b1908125..619e69909ccd654050cc0bb52e97d6b4f0063118 100644 (file)
@@ -151,7 +151,7 @@ static DCR *setup_to_access_device(JCR *jcr, char *dev_name, const char *VolumeN
       return NULL;
    }
 
-   dev = init_dev(NULL, device);
+   dev = init_dev(jcr, NULL, device);
    if (!dev) {
       Jmsg1(jcr, M_FATAL, 0, _("Cannot init device %s\n"), dev_name);
       return NULL;
index 32017d375c02a45b09645ab1033c8da9af2588ab..339007acdbd398cf2c16b85d02554c14d668dbff 100644 (file)
@@ -101,7 +101,7 @@ static void update_free_space_dev(DEVICE* dev);
  *
  */
 DEVICE *
-init_dev(DEVICE *dev, DEVRES *device)
+init_dev(JCR *jcr, DEVICE *dev, DEVRES *device)
 {
    struct stat statp;
    bool tape, fifo;
@@ -114,7 +114,7 @@ init_dev(DEVICE *dev, DEVRES *device)
       if (dev) {
         dev->dev_errno = errno;
       }
-      Jmsg2(NULL, M_FATAL, 0, _("Unable to stat device %s: ERR=%s\n"), 
+      Jmsg2(jcr, M_FATAL, 0, _("Unable to stat device %s: ERR=%s\n"), 
         device->device_name, be.strerror());
       return NULL;
    }
@@ -132,7 +132,7 @@ init_dev(DEVICE *dev, DEVRES *device)
       if (dev) {
         dev->dev_errno = ENODEV;
       }
-      Emsg2(M_FATAL, 0, _("%s is an unknown device type. Must be tape or directory. st_mode=%x\n"),
+      Jmsg2(jcr, M_FATAL, 0, _("%s is an unknown device type. Must be tape or directory. st_mode=%x\n"),
         device->device_name, statp.st_mode);
       return NULL;
    }
@@ -188,26 +188,26 @@ init_dev(DEVICE *dev, DEVRES *device)
       if (stat(device->mount_point, &statp) < 0) {
         berrno be;
         dev->dev_errno = errno;
-         Jmsg2(NULL, M_FATAL, 0, _("Unable to stat mount point %s: ERR=%s\n"), 
+         Jmsg2(jcr, M_FATAL, 0, _("Unable to stat mount point %s: ERR=%s\n"), 
            device->mount_point, be.strerror());
         return NULL;
       }
       if (!device->mount_command || !device->unmount_command) {
-         Jmsg0(NULL, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
+         Jmsg0(jcr, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
       }
       if (!device->write_part_command) {
-         Jmsg0(NULL, M_ERROR_TERM, 0, _("Write part command must be defined for a device which requires mount.\n"));
+         Jmsg0(jcr, M_ERROR_TERM, 0, _("Write part command must be defined for a device which requires mount.\n"));
       }
       dev->state |= ST_DVD;
    }
 
    if (dev->max_block_size > 1000000) {
-      Emsg3(M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
+      Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
         dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
       dev->max_block_size = 0;
    }
    if (dev->max_block_size % TAPE_BSIZE != 0) {
-      Emsg2(M_WARNING, 0, _("Max block size %u not multiple of device %s block size.\n"),
+      Jmsg2(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size.\n"),
         dev->max_block_size, dev->dev_name);
    }
 
@@ -218,31 +218,31 @@ init_dev(DEVICE *dev, DEVRES *device)
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+      Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
+      Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
+      Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
+      Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
    }
    if ((errstat = rwl_init(&dev->lock)) != 0) {
       berrno be;
       dev->dev_errno = errstat;
       Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
-      Emsg0(M_ERROR_TERM, 0, dev->errmsg);
+      Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
    }
 
    dev->fd = -1;
index f4dd92ac782ec4aef57e699b8033e0e13983b5b6..ff52ecf69f8f65e57c3ceebe8d30b0910dfcb23b 100644 (file)
@@ -283,6 +283,9 @@ static bool use_device_cmd(JCR *jcr)
            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_FATAL, 0, _("\n"
                   "     Archive \"%s\" requested by DIR could not be opened or does not exist.\n"),
@@ -307,7 +310,7 @@ static bool use_device_cmd(JCR *jcr)
               ok = reserve_device_for_read(jcr, device->dev);
            }
            if (!ok) {
-               bnet_fsend(dir, _("Could not get dcr for device: %s\n"), dev_name.c_str());
+               bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), dev_name.c_str());
               free_dcr(jcr->dcr);
               return false;
            }
@@ -361,8 +364,13 @@ bool query_cmd(JCR *jcr)
       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 &&
-            device->dev) {
+        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;
+           }  
            DEVICE *dev = device->dev;
            POOL_MEM VolumeName, MediaType;
            UnlockRes();
index b94363a825192c7dff2ceb4226230b8cb13316a2..7afa0e8b97e007b3add8b32c88e2735fa781660f 100644 (file)
@@ -85,7 +85,7 @@ void    display_tape_error_status(JCR *jcr, DEVICE *dev);
 
 
 /* From dev.c */
-DEVICE  *init_dev(DEVICE *dev, DEVRES *device);
+DEVICE  *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
 int      open_dev(DEVICE *dev, char *VolName, int mode);
 off_t    lseek_dev(DEVICE *dev, off_t offset, int whence);
 int      open_first_part(DEVICE *dev);
index afe1ee9d42d4e96b2d6656ba4d7e48ce5bef2c22..27766d8c207ffa84217f55bcfb1c21746476af1a 100644 (file)
@@ -308,7 +308,7 @@ void *device_allocation(void *arg)
 
    foreach_res(device, R_DEVICE) {
       Dmsg1(90, "calling init_dev %s\n", device->device_name);
-      device->dev = init_dev(NULL, device);
+      device->dev = init_dev(NULL, NULL, device);
       Dmsg1(10, "SD init done %s\n", device->device_name);
       if (!device->dev) {
          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
index 90979fb3eaa266eff4c9cffb13660851e96b8cd3..dd2fa42415ffee89e54fc7205d9e7cee99cf5151 100644 (file)
@@ -159,7 +159,7 @@ RES_TABLE resources[] = {
    {"device",        dev_items,     R_DEVICE},
    {"messages",      msgs_items,    R_MSGS},
    {"autochanger",   changer_items, R_AUTOCHANGER},
-   {NULL,            NULL,          0}
+   {NULL,           NULL,          0}
 };
 
 
@@ -177,7 +177,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       return;
    }
    sendit(sock, "dump_resource type=%d\n", type);
-   if (type < 0) {                    /* no recursion */
+   if (type < 0) {                   /* no recursion */
       type = - type;
       recurse = 0;
    }
@@ -187,36 +187,40 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       break;
    case R_STORAGE:
       sendit(sock, "Storage: name=%s SDaddr=%s SDport=%d SDDport=%d HB=%s\n",
-           res->res_store.hdr.name,
-           NPRT(get_first_address(res->res_store.sdaddrs, buf, sizeof(buf))),
-           get_first_port_host_order(res->res_store.sdaddrs),
-           get_first_port_host_order(res->res_store.sddaddrs),
-           edit_utime(res->res_store.heartbeat_interval, buf, sizeof(buf)));
-          foreach_dlist(p, res->res_store.sdaddrs) {
-                sendit(sock, "        SDaddr=%s SDport=%d\n",
-                             p->get_address(buf, sizeof(buf)), p->get_port_host_order());
-          }
-          foreach_dlist(p, res->res_store.sddaddrs) {
-                sendit(sock, "        SDDaddr=%s SDDport=%d\n",
-                             p->get_address(buf, sizeof(buf)), p->get_port_host_order());
-          }
+            res->res_store.hdr.name,
+            NPRT(get_first_address(res->res_store.sdaddrs, buf, sizeof(buf))),
+            get_first_port_host_order(res->res_store.sdaddrs),
+            get_first_port_host_order(res->res_store.sddaddrs),
+            edit_utime(res->res_store.heartbeat_interval, buf, sizeof(buf)));
+      if (res->res_store.sdaddrs) {
+        foreach_dlist(p, res->res_store.sdaddrs) {
+            sendit(sock, "        SDaddr=%s SDport=%d\n",
+                  p->get_address(buf, sizeof(buf)), p->get_port_host_order());
+        }
+      }
+      if (res->res_store.sddaddrs) {
+        foreach_dlist(p, res->res_store.sddaddrs) {
+            sendit(sock, "        SDDaddr=%s SDDport=%d\n",
+                  p->get_address(buf, sizeof(buf)), p->get_port_host_order());
+        }
+      }
       break;
    case R_DEVICE:
       sendit(sock, "Device: name=%s MediaType=%s Device=%s LabelType=%d\n",
-         res->res_dev.hdr.name,
-         res->res_dev.media_type, res->res_dev.device_name,
-         res->res_dev.label_type);
+        res->res_dev.hdr.name,
+        res->res_dev.media_type, res->res_dev.device_name,
+        res->res_dev.label_type);
       sendit(sock, "        rew_wait=%d min_bs=%d max_bs=%d\n",
-         res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-         res->res_dev.max_block_size);
+        res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
+        res->res_dev.max_block_size);
       sendit(sock, "        max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-         res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-         res->res_dev.max_volume_size);
+        res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
+        res->res_dev.max_volume_size);
       sendit(sock, "        max_file_size=%" lld " capacity=%" lld "\n",
-         res->res_dev.max_file_size, res->res_dev.volume_capacity);
+        res->res_dev.max_file_size, res->res_dev.volume_capacity);
       sendit(sock, "         spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
       sendit(sock, "         max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-         res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
+        res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
       bstrncpy(buf, "        ", sizeof(buf));
       if (res->res_dev.cap_bits & CAP_EOF) {
          bstrncat(buf, "CAP_EOF ", sizeof(buf));
@@ -263,8 +267,8 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
    case R_AUTOCHANGER:
       DEVRES *dev;
       sendit(sock, "Changer: name=%s Changer_devname=%s Changer_cmd=%s\n",
-         res->res_changer.hdr.name,
-         res->res_changer.changer_name, res->res_changer.changer_command);
+        res->res_changer.hdr.name,
+        res->res_changer.changer_name, res->res_changer.changer_command);
       foreach_alist(dev, res->res_changer.device) {
          sendit(sock, "   --->Device: name=%s\n", dev->hdr.name);
       }
@@ -314,77 +318,81 @@ void free_resource(RES *sres, int type)
    switch (type) {
    case R_DIRECTOR:
       if (res->res_dir.password) {
-         free(res->res_dir.password);
+        free(res->res_dir.password);
       }
       if (res->res_dir.address) {
-         free(res->res_dir.address);
+        free(res->res_dir.address);
       }
       break;
    case R_AUTOCHANGER:
       if (res->res_changer.changer_name) {
-         free(res->res_changer.changer_name);
+        free(res->res_changer.changer_name);
       }
       if (res->res_changer.changer_command) {
-         free(res->res_changer.changer_command);
+        free(res->res_changer.changer_command);
+      }
+      if (res->res_changer.device) {
+        delete res->res_changer.device;
       }
+      break; 
    case R_STORAGE:
       if (res->res_store.sdaddrs) {
-         free_addresses(res->res_store.sdaddrs);
+        free_addresses(res->res_store.sdaddrs);
       }
       if (res->res_store.sddaddrs) {
-         free_addresses(res->res_store.sddaddrs);
+        free_addresses(res->res_store.sddaddrs);
       }
       if (res->res_store.working_directory) {
-         free(res->res_store.working_directory);
+        free(res->res_store.working_directory);
       }
       if (res->res_store.pid_directory) {
-         free(res->res_store.pid_directory);
+        free(res->res_store.pid_directory);
       }
       if (res->res_store.subsys_directory) {
-         free(res->res_store.subsys_directory);
+        free(res->res_store.subsys_directory);
       }
       break;
    case R_DEVICE:
       if (res->res_dev.media_type) {
-         free(res->res_dev.media_type);
+        free(res->res_dev.media_type);
       }
       if (res->res_dev.device_name) {
-         free(res->res_dev.device_name);
+        free(res->res_dev.device_name);
       }
       if (res->res_dev.changer_name) {
-         free(res->res_dev.changer_name);
+        free(res->res_dev.changer_name);
       }
       if (res->res_dev.changer_command) {
-         free(res->res_dev.changer_command);
+        free(res->res_dev.changer_command);
       }
       if (res->res_dev.alert_command) {
-         free(res->res_dev.alert_command);
+        free(res->res_dev.alert_command);
       }
       if (res->res_dev.spool_directory) {
-         free(res->res_dev.spool_directory);
+        free(res->res_dev.spool_directory);
       }
       if (res->res_dev.mount_point) {
-         free(res->res_dev.mount_point);
+        free(res->res_dev.mount_point);
       }
       if (res->res_dev.mount_command) {
-         free(res->res_dev.mount_command);
+        free(res->res_dev.mount_command);
       }
       if (res->res_dev.unmount_command) {
-         free(res->res_dev.unmount_command);
+        free(res->res_dev.unmount_command);
       }
       if (res->res_dev.write_part_command) {
-         free(res->res_dev.write_part_command);
+        free(res->res_dev.write_part_command);
       }
       if (res->res_dev.free_space_command) {
-         free(res->res_dev.free_space_command);
+        free(res->res_dev.free_space_command);
       }
       break;
    case R_MSGS:
       if (res->res_msgs.mail_cmd) {
-         free(res->res_msgs.mail_cmd);
+        free(res->res_msgs.mail_cmd);
       }
       if (res->res_msgs.operator_cmd) {
-         free(res->res_msgs.operator_cmd);
+        free(res->res_msgs.operator_cmd);
       }
       free_msgs_res((MSGS *)res);  /* free message resource */
       res = NULL;
@@ -418,10 +426,10 @@ void save_resource(int type, RES_ITEM *items, int pass)
     */
    for (i=0; items[i].name; i++) {
       if (items[i].flags & ITEM_REQUIRED) {
-         if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
+        if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
             Emsg2(M_ERROR_TERM, 0, _("\"%s\" item is required in \"%s\" resource, but not found.\n"),
-              items[i].name, resources[rindex]);
-          }
+             items[i].name, resources[rindex]);
+         }
       }
       /* If this triggers, take a look at lib/parse_conf.h */
       if (i >= MAX_RES_ITEMS) {
@@ -440,37 +448,37 @@ void save_resource(int type, RES_ITEM *items, int pass)
       case R_DIRECTOR:
       case R_DEVICE:
       case R_MSGS:
-         break;
+        break;
 
       /* Resources containing a resource or an alist */
       case R_STORAGE:
-         if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+        if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find Storage resource \"%s\"\n", res_all.res_dir.hdr.name);
-         }
-         res->res_store.messages = res_all.res_store.messages;
-         break;
+        }
+        res->res_store.messages = res_all.res_store.messages;
+        break;
       case R_AUTOCHANGER:
-         if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) {
+        if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) {
             Emsg1(M_ERROR_TERM, 0, "Cannot find AutoChanger resource %s\n",
-                  res_all.res_changer.hdr.name);
-         }
-         /* we must explicitly copy the device alist pointer */
-         res->res_changer.device   = res_all.res_changer.device;
-         break;
+                 res_all.res_changer.hdr.name);
+        }
+        /* we must explicitly copy the device alist pointer */
+        res->res_changer.device   = res_all.res_changer.device;
+        break;
       default:
          printf("Unknown resource type %d\n", type);
-         error = 1;
-         break;
+        error = 1;
+        break;
       }
 
 
       if (res_all.res_dir.hdr.name) {
-         free(res_all.res_dir.hdr.name);
-         res_all.res_dir.hdr.name = NULL;
+        free(res_all.res_dir.hdr.name);
+        res_all.res_dir.hdr.name = NULL;
       }
       if (res_all.res_dir.hdr.desc) {
-         free(res_all.res_dir.hdr.desc);
-         res_all.res_dir.hdr.desc = NULL;
+        free(res_all.res_dir.hdr.desc);
+        res_all.res_dir.hdr.desc = NULL;
       }
       return;
    }
@@ -478,45 +486,45 @@ void save_resource(int type, RES_ITEM *items, int pass)
    /* The following code is only executed on pass 1 */
    switch (type) {
       case R_DIRECTOR:
-         size = sizeof(DIRRES);
-         break;
+        size = sizeof(DIRRES);
+        break;
       case R_STORAGE:
-         size = sizeof(STORES);
-         break;
+        size = sizeof(STORES);
+        break;
       case R_DEVICE:
-         size = sizeof(DEVRES);
-         break;
+        size = sizeof(DEVRES);
+        break;
       case R_MSGS:
-         size = sizeof(MSGS);
-         break;
+        size = sizeof(MSGS);
+        break;
       case R_AUTOCHANGER:
-         size = sizeof(AUTOCHANGER);
-         break;
+        size = sizeof(AUTOCHANGER);
+        break;
       default:
          printf("Unknown resource type %d\n", type);
-         error = 1;
-         size = 1;
-         break;
+        error = 1;
+        size = 1;
+        break;
    }
    /* Common */
    if (!error) {
       res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       if (!res_head[rindex]) {
-         res_head[rindex] = (RES *)res; /* store first entry */
+        res_head[rindex] = (RES *)res; /* store first entry */
       } else {
-         RES *next;
-         /* Add new res to end of chain */
-         for (next=res_head[rindex]; next->next; next=next->next) {
-            if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
-               Emsg2(M_ERROR_TERM, 0,
+        RES *next;
+        /* Add new res to end of chain */
+        for (next=res_head[rindex]; next->next; next=next->next) {
+           if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+              Emsg2(M_ERROR_TERM, 0,
                   _("Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n"),
-                  resources[rindex].name, res->res_dir.hdr.name);
-            }
-         }
-         next->next = (RES *)res;
+                 resources[rindex].name, res->res_dir.hdr.name);
+           }
+        }
+        next->next = (RES *)res;
          Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
-               res->res_dir.hdr.name);
+              res->res_dir.hdr.name);
       }
    }
 }
index 638e86f7dff8ed29b51c989ce6a1ceba18abc71d..698129b2c1a53788882f4bfd81da8ba830fac4b0 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.3"
-#define BDATE   "10 February 2005"
-#define LSMDATE "10Feb05"
+#define VERSION "1.37.4"
+#define BDATE   "18 February 2005"
+#define LSMDATE "18Feb05"
 
 /* Debug flags */
 #undef  DEBUG