]> git.sur5r.net Git - bacula/bacula/commitdiff
20Feb06
authorKern Sibbald <kern@sibbald.com>
Mon, 20 Feb 2006 20:04:01 +0000 (20:04 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 20 Feb 2006 20:04:01 +0000 (20:04 +0000)
- Note. Your database must be updated, or you must create
  a new database. I have not yet incremented the database level.
- Add Location table.
- Add LocationId, DeviceId, and MediaTypeId to Media record.
18Feb06
- Implement create/get mac record in database for adding extended
  Migration data to the job record.
- Add new MAC table to update/make database scripts.
- Return Storage name used when getting VolumeNames for a job.
- Change bsr file keyword Storage to Device, which is more accurate.
- Ensure that Mac records are pruned/purged.
- Tweak SD tools to deal with changing media type.
- Integrate more dev.c subroutines as methods (e.g. strerror, bsr, ...)
- Pass pointer to dcr pointer to acquire_device_for_read() so
  that the subroutine can switch devices, and hence dcrs.
- Modify the multiple MediaType read code to re-use the same
  dcr when switching devices. This makes the code much more
  robust.
- Integrate patch from Karl Hakimian that reads JobIds, FileIndexes
  from a table for restore.
- Add Storage name to VolParams, but it really should be Device.

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

49 files changed:
bacula/kernstodo
bacula/kes-1.39
bacula/patches/dvd+rw-tools-6.1.bacula.patch [new file with mode: 0644]
bacula/src/cats/cats.h
bacula/src/cats/make_mysql_tables.in
bacula/src/cats/make_postgresql_tables.in
bacula/src/cats/make_sqlite3_tables.in
bacula/src/cats/make_sqlite_tables.in
bacula/src/cats/protos.h
bacula/src/cats/sql_create.c
bacula/src/cats/sql_get.c
bacula/src/cats/update_mysql_tables.in
bacula/src/cats/update_postgresql_tables.in
bacula/src/cats/update_sqlite3_tables.in
bacula/src/cats/update_sqlite_tables.in
bacula/src/dird/bsr.c
bacula/src/dird/mac.c
bacula/src/dird/sql_cmds.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_purge.c
bacula/src/dird/ua_restore.c
bacula/src/stored/Makefile.in
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/bcopy.c
bacula/src/stored/bextract.c
bacula/src/stored/block.c
bacula/src/stored/bls.c
bacula/src/stored/bscan.c
bacula/src/stored/bsr.h
bacula/src/stored/btape.c
bacula/src/stored/butil.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/dircmd.c
bacula/src/stored/dvd.c
bacula/src/stored/label.c
bacula/src/stored/mac.c
bacula/src/stored/mount.c
bacula/src/stored/parse_bsr.c
bacula/src/stored/protos.h
bacula/src/stored/read.c
bacula/src/stored/read_record.c
bacula/src/stored/reserve.c
bacula/src/stored/reserve.h
bacula/src/stored/spool.c
bacula/src/stored/stored.c
bacula/src/version.h

index df9fc31983fb1655aa6d1cc7549258f88d9d8153..45a1ce7c33cda99b084cf89f2ed3186068635bfd 100644 (file)
@@ -1,5 +1,5 @@
                     Kern's ToDo List
-                     08 February 2006
+                     17 February 2006
 
 Major development:      
 Project                     Developer
@@ -20,6 +20,9 @@ Priority:
   directive).
 
 For 1.39:
+- Keep same dcr when switching device ...
+- Job retention period in a Pool (and hence Volume).  The job would
+  then be migrated.
 - Detect resource deadlock in Migrate when same job wants to read
   and write the same device.
 - Make hardlink code at line 240 of find_one.c use binary search.
@@ -1280,4 +1283,3 @@ Block Position: 0
   even defined).
 - Make sure Maximum Volumes is respected in Pools when adding
   Volumes (e.g. when pulling a Scratch volume).
-
index 9e3c3d8711d7544db4b36583fd885f21f6e70e45..7c254d35461a08ad1b8bf101a2b4816f6a7842fb 100644 (file)
@@ -4,6 +4,28 @@
 General:
 
 Changes to 1.39.5
+20Feb06
+- Note!!! Your database must be updated, or you must create 
+  a new database. I have not yet incremented the database level.
+- Add Location table. 
+- Add LocationId, DeviceId, and MediaTypeId to Media record.
+18Feb06
+- Implement create/get mac record in database for adding extended
+  Migration data to the job record.
+- Add new MAC table to update/make database scripts.
+- Return Storage name used when getting VolumeNames for a job.
+- Change bsr file keyword Storage to Device, which is more accurate.
+- Ensure that Mac records are pruned/purged.
+- Tweak SD tools to deal with changing media type.
+- Integrate more dev.c subroutines as methods (e.g. strerror, bsr, ...)
+- Pass pointer to dcr pointer to acquire_device_for_read() so
+  that the subroutine can switch devices, and hence dcrs.
+- Modify the multiple MediaType read code to re-use the same
+  dcr when switching devices. This makes the code much more
+  robust.
+- Integrate patch from Karl Hakimian that reads JobIds, FileIndexes
+  from a table for restore.
+- Add Storage name to VolParams, but it really should be Device.
 14Feb06
 - Add disk-changer to scripts directory + configure/Makefile
 - Eliminate PoolId from jcr -- it is in jcr->jr.PoolId
diff --git a/bacula/patches/dvd+rw-tools-6.1.bacula.patch b/bacula/patches/dvd+rw-tools-6.1.bacula.patch
new file mode 100644 (file)
index 0000000..6785f7f
--- /dev/null
@@ -0,0 +1,85 @@
+--- dvd+rw-tools-6.1.old/growisofs.c   2006-01-26 22:16:54.000000000 +0100
++++ dvd+rw-tools-6.1/growisofs.c       2006-02-15 00:00:44.000000000 +0100
+@@ -355,12 +355,17 @@
+  * - Treat only x73xx OPC errors as fatal;
+  * - Fix typo in -speed scaling code;
+  * - permit tracksize to be not divisible by 32KB in DAO mode;
++ * 6.1.1: (by Nicolas Boichat, Bacula project)
++ * - Allow session to cross 4GB boundary regardless of medium type
++ *   (don't need to have a DL media)
++ * - Add a -F option (used instead of -M or -Z), which displays next_session
++ *   offset and capacity (free space = next_session - capacity).
+  */
+ #define PRINT_VERSION(cmd)    do {                    \
+     char *s=strrchr((cmd),'/');                               \
+     s ? s++ : (s=(cmd));                              \
+     printf ("* %.*sgrowisofs by <appro@fy.chalmers.se>,"\
+-          " version 6.1,\n",(int)(s-(cmd)),(cmd));    \
++          " version 6.1.1,\n",(int)(s-(cmd)),(cmd));  \
+ } while (0)
\f
+ #define _LARGEFILE_SOURCE 
+@@ -2329,6 +2334,18 @@
+               else          in_device = argv[++i];
+               dev_found = 'Z';
+           }
++          else if (argv[i][1] == 'F')
++          {   if (len > 2) in_device = argv[i]+2;
++              else         in_device = argv[++i];
++              dev_found = 'F';
++              dry_run = 1; /* NEVER write anything with -F */
++          }
++          else if (!strncmp(opt,"-free-space",11))
++          {   if (len > 11) in_device = opt+11;
++              else          in_device = argv[++i];
++              dev_found = 'F';
++              dry_run = 1; /* NEVER write anything with -F */
++          }
+           else if (!strcmp(opt,"-poor-man"))
+           {   if (poor_man<0) poor_man = 1;
+               continue;
+@@ -2542,7 +2559,9 @@
+               fprintf (stderr,"    you most likely want to use -Z option.\n"), 
+               exit (FATAL_START(errno));
+-          if (dev_found == 'M')
++              if ((dev_found == 'M') || 
++                      ((dev_found == 'F') && !(mmc_profile&0x10000)) && (saved_descriptors[0].type[0] || saved_descriptors[0].type[1] || saved_descriptors[0].type[2]))
++                              /* -F : The medium is not blank, there is a fs on it (the_buffer[0,1 or 2] != 0), so compute next_session. */
+           {   if (memcmp (saved_descriptors[0].type,"\1CD001",6))
+                   fprintf (stderr,":-( %s doesn't look like isofs...\n",
+                               in_device), exit(FATAL_START(EMEDIUMTYPE));
+@@ -2565,7 +2584,7 @@
+                       exit(FATAL_START(EINVAL));
+               }
+               else if (next_session > (0x200000-0x5000)) /* 4GB/2K-40MB/2K */
+-                  if ((mmc_profile&0xFFFF)!=0x2B || !no_4gb_check)
++                  if (!no_4gb_check)
+                       fprintf (stderr,":-( next session would cross 4GB "
+                                       "boundary, aborting...\n"),
+                       exit (FATAL_START(ENOSPC));
+@@ -2608,7 +2627,7 @@
+       exit (FATAL_START(EINVAL));
+     if (imgfd<0)
+-    { if (mkisofs_argc==1)
++    { if ((mkisofs_argc==1) && (dev_found != 'F'))
+           fprintf (stderr,"%s: no mkisofs options specified, "
+                           "aborting...\n",argv[0]),
+           exit (FATAL_START(EINVAL));
+@@ -2880,6 +2899,15 @@
+       }
+     }
++      if (dev_found == 'F') {
++              off64_t capacity = 0;
++              printf("next_session=%lld\n", next_session*CD_BLOCK);
++              if (ioctl_handle!=INVALID_HANDLE)
++                      capacity = get_capacity (ioctl_handle);
++              printf("capacity=%lld\n", capacity);
++              exit(0);
++      }
++
+     if (imgfd>=0)
+     { quiet--;
+       if (builtin_dd (imgfd,out_fd,next_session*CD_BLOCK) < 0)
index 12e7a9b3bea3142ec05724c3a43d59755b79a78c..25d5b53ea4b8e7d38067ca7865f7a21fcfb3f273 100644 (file)
@@ -546,6 +546,8 @@ struct JOB_DBR {
    uint32_t JobErrors;
    uint32_t JobMissingFiles;
    uint64_t JobBytes;
+   int PurgedFiles;
+   int HasBase;
 
    /* Note, FirstIndex, LastIndex, Start/End File and Block
     * are only used in the JobMedia record.
@@ -565,6 +567,33 @@ struct JOB_DBR {
    faddr_t rec_addr;
 };
 
+/* 
+ * Suplementary record for Migration, archive, copy jobs
+ */
+/* MAC record */
+struct MAC_DBR {
+   JobId_t JobId;                     /* Id of this job */
+   JobId_t OriginalJobId;             /* Id of job migrated, copied or archived */
+   /* 
+    * The following are the actual values for this job. This
+    *  is needed because the values in the corresponding Job
+    *  record were set to the values of the original backup job.
+    */
+   int JobType;                       /* Actual job type */
+   int JobLevel;                      /* Actual job level */
+   time_t SchedTime;                  /* Actual time job scheduled */
+   time_t StartTime;                  /* Actual Job start time */
+   time_t EndTime;                    /* Actual Job termination time */
+   utime_t JobTDate;                  /* Actual Backup time/date in seconds */
+
+   char cSchedTime[MAX_TIME_LENGTH];
+   char cStartTime[MAX_TIME_LENGTH];
+   char cEndTime[MAX_TIME_LENGTH];
+
+};
+
+
+
 /* Job Media information used to create the media records
  * for each Volume used for the job.
  */
@@ -588,6 +617,7 @@ struct JOBMEDIA_DBR {
 struct VOL_PARAMS {
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    char MediaType[MAX_NAME_LENGTH];   /* Media Type */
+   char Storage[MAX_NAME_LENGTH];     /* Storage name */
    uint32_t VolIndex;                 /* Volume seqence no. */
    uint32_t FirstIndex;               /* First index this Volume */
    uint32_t LastIndex;                /* Last index this Volume */
@@ -595,6 +625,7 @@ struct VOL_PARAMS {
    uint32_t EndFile;                  /* End file on Volume */
    uint32_t StartBlock;               /* start block on tape */
    uint32_t EndBlock;                 /* last block */
+   int32_t Slot;                      /* Slot */
 // uint32_t Copy;                     /* identical copy */
 // uint32_t Stripe;                   /* RAIT strip number */
 };
index ca4fb29f961b7e565483e5c933298672fd4b7c9c..7e4aeae7b882fb7ae2a06efb695f0dd933cb2469 100644 (file)
@@ -112,6 +112,19 @@ CREATE TABLE Job (
    INDEX (Name(128))
    );
 
+CREATE TABLE MAC (
+   JobId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   OriginalJobId INTEGER UNSIGNED NOT NULL,
+   JobType BINARY(1) NOT NULL,
+   JobLevel BINARY(1) NOT NULL,
+   SchedTime DATETIME NOT NULL,
+   StartTime DATETIME NOT NULL,
+   EndTime DATETIME NOT NULL,
+   JobTDate BIGINT UNSIGNED NOT NULL,
+   PRIMARY KEY(JobId)
+   );
+
+
 # 
 CREATE TABLE FileSet (
    FileSetId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -145,6 +158,7 @@ CREATE TABLE Media (
    Slot INTEGER NOT NULL DEFAULT 0,
    PoolId INTEGER UNSIGNED NOT NULL REFERENCES Pool,
    MediaType TINYBLOB NOT NULL,
+   MediaTypeId INTEGER UNSIGNED NOT NULL REFERENCES MediaType,
    LabelType TINYINT NOT NULL DEFAULT 0,
    FirstWritten DATETIME NOT NULL,
    LastWritten DATETIME NOT NULL,
@@ -168,11 +182,13 @@ CREATE TABLE Media (
    MaxVolBytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
    InChanger TINYINT NOT NULL DEFAULT 0,
    StorageId INTEGER UNSIGNED NOT NULL REFERENCES Storage,
+   DeviceId INTEGER UNSIGNED NOT NULL REFERENCES Device,
    MediaAddressing TINYINT NOT NULL DEFAULT 0,
    VolReadTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
    VolWriteTime BIGINT UNSIGNED NOT NULL DEFAULT 0,
    EndFile INTEGER UNSIGNED NOT NULL DEFAULT 0,
    EndBlock INTEGER UNSIGNED NOT NULL DEFAULT 0,
+   LocationId INTEGER UNSIGNED NOT NULL REFERENCES Location,
    PRIMARY KEY(MediaId),
    INDEX (PoolId)
    );
index be0e9f5840ae962d9990a55f5fd88204fb1c38f9..cf13ce73176439e5b499ec386214a42cf903446b 100644 (file)
@@ -76,6 +76,19 @@ CREATE TABLE job
 
 CREATE INDEX job_name_idx on job (name);
 
+CREATE TABLE MAC (
+    JobId            serial      not null,
+    OriginalJobId     serial     not null,
+    JobType          char(1)     not null,
+    JobLevel         char(1)     not null,
+    schedtime        timestamp   without time zone not null,
+    starttime        timestamp   without time zone,
+    endtime          timestamp   without time zone,
+    jobtdate         bigint      not null,
+    primary key (jobid)
+);
+
+
 CREATE TABLE fileset
 (
     filesetid        serial      not null,
@@ -113,6 +126,7 @@ CREATE TABLE media
     slot             integer     not null default 0,
     poolid           integer     not null,
     mediatype        text        not null,
+    mediatypeid       integer    not null,
     labeltype        integer     not null default 0,
     firstwritten      timestamp   without time zone,
     lastwritten       timestamp   without time zone,
@@ -138,11 +152,13 @@ CREATE TABLE media
     maxvolbytes       bigint     not null default 0,
     inchanger        smallint    not null default 0,
     StorageId        integer              default 0,
+    DeviceId         integer              default 0,
     mediaaddressing   smallint   not null default 0,
     volreadtime       bigint     not null default 0,
     volwritetime      bigint     not null default 0,
     endfile          integer     not null default 0,
     endblock         bigint      not null default 0,
+    LocationId       integer              default 0,
     primary key (mediaid)
 );
 
index 6f54ff397ebe377504ddb5ee861750f757012112..38ed334dff0f47371d93e6b988728a337506a4c7 100644 (file)
@@ -73,6 +73,19 @@ CREATE TABLE Job (
 
 CREATE INDEX inx6 ON Job (Name);
 
+CREATE TABLE MAC (
+   JobId INTEGER,
+   OriginalJobId INTEGER,
+   JobType CHAR NOT NULL,
+   JobLevel CHAR NOT NULL,
+   SchedTime DATETIME NOT NULL,
+   StartTime DATETIME DEFAULT 0,
+   EndTime DATETIME DEFAULT 0,
+   JobTDate BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobId)
+   );
+
+
 CREATE TABLE FileSet (
    FileSetId INTEGER,
    FileSet VARCHAR(128) NOT NULL,
@@ -106,6 +119,7 @@ CREATE TABLE Media (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
    LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
@@ -128,11 +142,13 @@ CREATE TABLE Media (
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
    StorageId INTEGER UNSIGNED REFERENCES Storage,        
+   DeviceId INTEGER UNSIGNED REFERENCES Device,
    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,
    PRIMARY KEY(MediaId)
    );
 
@@ -313,7 +329,6 @@ INSERT INTO Version (VersionId) VALUES (9);
 
 PRAGMA default_synchronous = OFF;
 PRAGMA default_cache_size = 10000;
-PRAGMA synchronous = NORMAL;
 
 END-OF-DATA
 
index 25afc6b7f2a2c911b374903460889354cf76efa4..38ed334dff0f47371d93e6b988728a337506a4c7 100644 (file)
@@ -73,6 +73,19 @@ CREATE TABLE Job (
 
 CREATE INDEX inx6 ON Job (Name);
 
+CREATE TABLE MAC (
+   JobId INTEGER,
+   OriginalJobId INTEGER,
+   JobType CHAR NOT NULL,
+   JobLevel CHAR NOT NULL,
+   SchedTime DATETIME NOT NULL,
+   StartTime DATETIME DEFAULT 0,
+   EndTime DATETIME DEFAULT 0,
+   JobTDate BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobId)
+   );
+
+
 CREATE TABLE FileSet (
    FileSetId INTEGER,
    FileSet VARCHAR(128) NOT NULL,
@@ -106,6 +119,7 @@ CREATE TABLE Media (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
    LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
@@ -128,11 +142,13 @@ CREATE TABLE Media (
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
    StorageId INTEGER UNSIGNED REFERENCES Storage,        
+   DeviceId INTEGER UNSIGNED REFERENCES Device,
    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,
    PRIMARY KEY(MediaId)
    );
 
index 6841dffdcf44786060d3d28828ae4c9a9a3758da..464af82d1b69b2663315754041b204a3ee1a2fa2 100644 (file)
@@ -43,7 +43,8 @@ void db_end_transaction(JCR *jcr, B_DB *mdb);
 
 /* create.c */
 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
-int db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
+bool db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
+bool db_create_mac_record(JCR *jcr, B_DB *db, MAC_DBR *mr);
 int db_create_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *media_dbr);
 int db_create_client_record(JCR *jcr, B_DB *db, CLIENT_DBR *cr);
 bool db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr);
@@ -67,7 +68,8 @@ bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime,
 /* get.c */
 bool db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
-int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
+bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr);
+bool db_get_mac_record(JCR *jcr, B_DB *mdb, MAC_DBR *mr);
 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames);
 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr);
 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr);
index 8f0609815657402856413855ee0adaad5388984c..a3a877da1010e8eb19b5b793bb5ce2cfc5a7f5b5 100644 (file)
@@ -53,16 +53,16 @@ extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
 
 
 /* Create a new record for the Job
- * Returns: 0 on failure
- *          1 on success
+ * Returns: false on failure
+ *          true  on success
  */
-int
+bool
 db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 {
    char dt[MAX_TIME_LENGTH];
    time_t stime;
    struct tm tm;
-   int stat;
+   bool ok;
    utime_t JobTDate;
    char ed1[30];
 
@@ -86,15 +86,65 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
       Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
             mdb->cmd, sql_strerror(mdb));
       jr->JobId = 0;
-      stat = 0;
+      ok = false;
    } else {
       jr->JobId = sql_insert_id(mdb, N_("Job"));
-      stat = 1;
+      ok = true;
    }
    db_unlock(mdb);
-   return stat;
+   return ok;
+}
+
+/* Create a new migration, archive, copy
+ * Returns: false on failure
+ *          true  on success
+ */
+bool
+db_create_mac_record(JCR *jcr, B_DB *mdb, MAC_DBR *mr)
+{
+   char schedt[MAX_TIME_LENGTH], sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
+   time_t stime;
+   struct tm tm;
+   bool ok;
+   utime_t JobTDate;
+   char ed1[30], ed2[30];
+
+   db_lock(mdb);
+
+   stime = mr->SchedTime;
+   ASSERT(stime != 0);
+
+   localtime_r(&stime, &tm);
+   strftime(schedt, sizeof(schedt), "%Y-%m-%d %T", &tm);
+   JobTDate = (utime_t)stime;
+   localtime_r(&mr->StartTime, &tm);
+   strftime(sdt, sizeof(sdt), "%Y-%m-%d %T", &tm);
+   localtime_r(&mr->EndTime, &tm);
+   strftime(edt, sizeof(edt), "%Y-%m-%d %T", &tm);
+
+   /* Must create it */
+   Mmsg(mdb->cmd,
+"INSERT INTO MAC (OriginaJobId,JobType,JobLevel,SchedTime,"
+"StartTime,EndTime,JobTDate) VALUES "
+"('%s','%c','%c','%s','%s','%s',%s)",
+           edit_int64(mr->OriginalJobId, ed1),
+           (char)(mr->JobType), (char)(mr->JobLevel),
+           schedt, sdt, edt, edit_uint64(JobTDate, ed2));
+
+   if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
+      Mmsg2(&mdb->errmsg, _("Create DB MAC record %s failed. ERR=%s\n"),
+            mdb->cmd, sql_strerror(mdb));
+      mr->JobId = 0;
+      ok = false;
+   } else {
+      mr->JobId = sql_insert_id(mdb, N_("Job"));
+      ok = true;
+   }
+   db_unlock(mdb);
+   return ok;
 }
 
+
 /* Create a JobMedia record for medium used this job
  * Returns: false on failure
  *          true  on success
@@ -391,11 +441,11 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
 
    /* Must create it */
    Mmsg(mdb->cmd,
-"INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes,"
-"Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
+"INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
+"VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
-"EndFile,EndBlock,LabelType,StorageId) "
-"VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s)",
+"EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId) "
+"VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,0,0)",
           mr->VolumeName,
           mr->MediaType, mr->PoolId,
           edit_uint64(mr->MaxVolBytes,ed1),
index c461cba6b5983b6d3d2f3524eebec8964aae1deb..f2bd3d9dd9152b40984d4f870c7ea44a0b507049 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -257,10 +257,10 @@ static int db_get_path_record(JCR *jcr, B_DB *mdb)
 
 /*
  * Get Job record for given JobId or Job name
- * Returns: 0 on failure
- *          1 on success
+ * Returns: false on failure
+ *          true  on success
  */
-int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
+bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 {
    SQL_ROW row;
    char ed1[50];
@@ -281,13 +281,13 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 
    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
       db_unlock(mdb);
-      return 0;                       /* failed */
+      return false;                   /* failed */
    }
    if ((row = sql_fetch_row(mdb)) == NULL) {
       Mmsg1(mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1));
       sql_free_result(mdb);
       db_unlock(mdb);
-      return 0;                       /* failed */
+      return false;                   /* failed */
    }
 
    jr->VolSessionId = str_to_uint64(row[0]);
@@ -306,10 +306,51 @@ int db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
    bstrncpy(jr->Name, row[13]!=NULL?row[13]:"", sizeof(jr->Name));
    sql_free_result(mdb);
 
+   db_unlock(mdb);
+   return true;
+}
+
+/*
+ * Get MAC record for given JobId
+ * Returns: false on failure
+ *          true  on success
+ */
+bool db_get_mac_record(JCR *jcr, B_DB *mdb, MAC_DBR *mr)
+{
+   SQL_ROW row;
+   char ed1[50];
+
+   db_lock(mdb);
+   Mmsg(mdb->cmd, "SELECT OriginalJobId,JobType,JobLevel,"
+"SchedTime,StartTime,EndTime,JobTDate"
+"FROM MAC WHERE JobId=%s", 
+      edit_int64(mr->JobId, ed1));
+
+   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
+      db_unlock(mdb);
+      return 0;                       /* failed */
+   }
+   if ((row = sql_fetch_row(mdb)) == NULL) {
+      Mmsg1(mdb->errmsg, _("No MAC record found for JobId %s\n"), ed1);
+      sql_free_result(mdb);
+      db_unlock(mdb);
+      return false;                   /* failed */
+   }
+
+   mr->OriginalJobId = str_to_int64(row[0]);
+   mr->JobType = (int)*row[1];
+   mr->JobLevel = (int)*row[2];
+   bstrncpy(mr->cSchedTime, row[3]!=NULL?row[3]:"", sizeof(mr->cSchedTime));
+   bstrncpy(mr->cStartTime, row[4]!=NULL?row[4]:"", sizeof(mr->cStartTime));
+   bstrncpy(mr->cEndTime, row[5]!=NULL?row[5]:"", sizeof(mr->cEndTime));
+   mr->JobTDate = str_to_int64(row[6]);
+   sql_free_result(mdb);
+
    db_unlock(mdb);
    return 1;
 }
 
+
 /*
  * Find VolumeNames for a given JobId
  *  Returns: 0 on error or no Volumes found
@@ -386,7 +427,8 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
    db_lock(mdb);
    Mmsg(mdb->cmd,
 "SELECT VolumeName,MediaType,FirstIndex,LastIndex,StartFile,"
-"JobMedia.EndFile,StartBlock,JobMedia.EndBlock,Copy,Stripe"
+"JobMedia.EndFile,StartBlock,JobMedia.EndBlock,Copy,Stripe,"
+"Slot,StorageId"
 " FROM JobMedia,Media WHERE JobMedia.JobId=%s"
 " AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId",
         edit_int64(JobId, ed1));
@@ -394,14 +436,16 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
    Dmsg1(130, "VolNam=%s\n", mdb->cmd);
    if (QUERY_DB(jcr, mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
-      Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
+      Dmsg1(200, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
          Mmsg1(mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId);
          stat = 0;
       } else {
          stat = mdb->num_rows;
+         DBId_t *SId;
          if (stat > 0) {
             *VolParams = Vols = (VOL_PARAMS *)malloc(stat * sizeof(VOL_PARAMS));
+            SId = (DBId_t *)malloc(stat * sizeof(DBId_t));
          }
          for (i=0; i < stat; i++) {
             if ((row = sql_fetch_row(mdb)) == NULL) {
@@ -410,6 +454,7 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
                stat = 0;
                break;
             } else {
+               DBId_t StorageId;
                bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH);
                bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH);
                Vols[i].FirstIndex = str_to_uint64(row[2]);
@@ -420,6 +465,21 @@ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS
                Vols[i].EndBlock = str_to_uint64(row[7]);
 //             Vols[i].Copy = str_to_uint64(row[8]);
 //             Vols[i].Stripe = str_to_uint64(row[9]);
+               Vols[i].Slot = str_to_uint64(row[10]);
+               StorageId = str_to_uint64(row[11]);
+               Vols[i].Storage[0] = 0;
+               SId[i] = StorageId;
+            }
+         }
+         for (i=0; i < stat; i++) {
+            if (SId[i] != 0) {
+               Mmsg(mdb->cmd, "SELECT Name from Storage WHERE StorageId=%s",
+                  edit_int64(SId[i], ed1));
+               if (QUERY_DB(jcr, mdb, mdb->cmd)) {
+                  if ((row = sql_fetch_row(mdb)) != NULL) {
+                     bstrncpy(Vols[i].Storage, row[0], MAX_NAME_LENGTH);
+                  }
+               }
             }
          }
       }
index 6fcafa766d554b104d10bd13b2d520ac41d58da9..bb3123f4a1dbb5033b949b9a18b3a303ce0b7a24 100755 (executable)
@@ -1,9 +1,9 @@
 #!/bin/sh
 #
-# Shell script to update MySQL tables from version 1.36 to 1.38  
+# Shell script to update MySQL tables from version 1.38 to 1.39  
 #
 echo " "
-echo "This script will update a Bacula MySQL database from version 8 to 9"
+echo "This script will update a Bacula MySQL database from version 9 to 9"
 echo "Depending on the size of your database,"
 echo "this script may take several minutes to run."
 echo " "
@@ -12,80 +12,29 @@ bindir=@SQL_BINDIR@
 if $bindir/mysql $* -f <<END-OF-DATA
 USE bacula;
 
-ALTER TABLE Media 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;
-
-ALTER TABLE JobMedia ADD COLUMN Copy INTEGER UNSIGNED NOT NULL DEFAULT 0;
-ALTER TABLE JobMedia ADD COLUMN Stripe INTEGER UNSIGNED NOT NULL DEFAULT 0;
-
-
-CREATE TABLE MediaType (
-   MediaTypeId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-   MediaType VARCHAR(128) NOT NULL,
-   ReadOnly TINYINT DEFAULT 0,
-   PRIMARY KEY(MediaTypeId)
+ALTER TABLE Media ADD COLUMN MediaTypeId INTEGER UNSIGNED DEFAULT 0 REFERENCES MediaType;
+ALTER TABLE Media ADD COLUMN DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device;
+ALTER TABLE Media ADD COLUMN LocationId INTEGER UNSIGNED DEFAULT 0 REFERENCES Location;
+
+
+CREATE TABLE MAC (
+   JobId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   OriginalJobId INTEGER UNSIGNED NOT NULL,
+   JobType BINARY(1) NOT NULL,
+   JobLevel BINARY(1) NOT NULL,
+   SchedTime DATETIME NOT NULL,
+   StartTime DATETIME NOT NULL,
+   EndTime DATETIME NOT NULL,
+   JobTDate BIGINT UNSIGNED NOT NULL,
+   PRIMARY KEY(JobId)
    );
 
-CREATE TABLE Storage (
-   StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
+CREATE TABLE Location (
+   LocationId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
+   Location TINYBLOB NOT NULL,
+   PRIMARY KEY(LocationId)
    );
 
-CREATE TABLE Device (
-   DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-   Name VARCHAR(128) NOT NULL,
-   MediaTypeId INTEGER UNSIGNED NOT NULL REFERENCES MediaType,
-   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 Status (
-   JobStatus CHAR(1) BINARY NOT NULL,
-   JobStatusLong BLOB, 
-   PRIMARY KEY (JobStatus)
-   );
-
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('C', 'Created, not yet running'),
-   ('R', 'Running'),
-   ('B', 'Blocked'),
-   ('T', 'Completed successfully'),
-   ('E', 'Terminated with errors'),
-   ('e', 'Non-fatal error'),
-   ('f', 'Fatal error'),
-   ('D', 'Verify found differences'),
-   ('A', 'Canceled by user'),
-   ('F', 'Waiting for Client'),
-   ('S', 'Waiting for Storage daemon'),
-   ('m', 'Waiting for new media'),
-   ('M', 'Waiting for media mount'),
-   ('s', 'Waiting for storage resource'),
-   ('j', 'Waiting for job resource'),
-   ('c', 'Waiting for client resource'),
-   ('d', 'Waiting on maximum jobs'),
-   ('t', 'Waiting on start time'),
-   ('p', 'Waiting on higher priority jobs');
-
 
 DELETE FROM Version;
 INSERT INTO Version (VersionId) VALUES (9);
index e98062f51bdf026e50c9960e24684e551c4f2304..847559241f72e0994e45499091c7ade76ed04cd1 100755 (executable)
@@ -1,9 +1,9 @@
 #!/bin/sh
 #
-# Shell script to update PostgreSQL tables from version 1.36 to 1.38
+# Shell script to update PostgreSQL tables from version 1.38 to 1.39
 #
 echo " "
-echo "This script will update a Bacula PostgreSQL database from version 8 to 9"
+echo "This script will update a Bacula PostgreSQL database from version 9 to 9"
 echo "Depending on the size of your database,"
 echo "this script may take several minutes to run."
 echo " "
@@ -11,115 +11,33 @@ bindir=@SQL_BINDIR@
 
 if $bindir/psql -f - -d bacula $* <<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;
-UPDATE pool SET NextPoolId=0;
-ALTER TABLE pool ADD COLUMN MigrationHighBytes BIGINT;
-UPDATE pool SET MigrationHighBytes=0;
-ALTER TABLE pool ADD COLUMN MigrationLowBytes  BIGINT;
-UPDATE pool SET MigrationLowBytes=0;
-ALTER TABLE pool ADD COLUMN MigrationTime      BIGINT;
-UPDATE pool SET MigrationTime=0;
-
-
-ALTER TABLE jobmedia ADD COLUMN Copy integer;
-UPDATE jobmedia SET Copy=0;
-ALTER TABLE jobmedia ADD COLUMN Stripe integer;
-UPDATE jobmedia SET Stripe=0;
-
-
-ALTER TABLE media ADD COLUMN volparts integer;
-UPDATE media SET volparts=0;
-ALTER TABLE media ALTER COLUMN volparts SET NOT NULL;
-
-CREATE TABLE MediaType (
-   MediaTypeId SERIAL,
-   MediaType TEXT NOT NULL,
-   ReadOnly INTEGER DEFAULT 0,
-   PRIMARY KEY(MediaTypeId)
+ALTER TABLE media ADD COLUMN DeviceId integer;
+UPDATE media SET DeviceId=0;
+ALTER TABLE media ADD COLUMN MediaTypeId integer;
+UPDATE media SET MediaTypeId=0;
+ALTER TABLE media ADD COLUMN LocationId integer;
+UPDATE media SET LocationId=0;
+
+
+CREATE TABLE MAC (
+    JobId            serial      not null,
+    OriginalJobId     serial     not null,
+    JobType          char(1)     not null,
+    JobLevel         char(1)     not null,
+    SchedTime        timestamp   without time zone not null,
+    StartTime        timestamp   without time zone,
+    EndTime          timestamp   without time zone,
+    JobTDate         bigint      not null,
+    primary key (JobId)
+);
+
+CREATE TABLE Location (
+   LocationId SERIAL,
+   Location TEXT NOT NULL,
+   PRIMARY KEY(LocationId)
    );
 
-CREATE TABLE Device (
-   DeviceId SERIAL,
-   Name TEXT NOT NULL,
-   MediaTypeId INTEGER NOT NULL,
-   StorageId INTEGER,
-   DevMounts INTEGER NOT NULL DEFAULT 0,
-   DevReadBytes BIGINT NOT NULL DEFAULT 0,
-   DevWriteBytes BIGINT NOT NULL DEFAULT 0,
-   DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0,
-   DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0,
-   DevReadTime BIGINT NOT NULL DEFAULT 0,
-   DevWriteTime BIGINT NOT NULL DEFAULT 0,
-   DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0,
-   DevWriteTimeSinceCleaning BIGINT DEFAULT 0,
-   CleaningDate TIMESTAMP WITHOUT TIME ZONE,
-   CleaningPeriod BIGINT NOT NULL DEFAULT 0,
-   PRIMARY KEY(DeviceId)
-   );
-
-CREATE TABLE Storage (
-   StorageId SERIAL,
-   Name TEXT NOT NULL,
-   AutoChanger INTEGER DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
-CREATE TABLE Status (
-   JobStatus CHAR(1) NOT NULL,
-   JobStatusLong TEXT, 
-   PRIMARY KEY (JobStatus)
-   );
-
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('C', 'Created, not yet running');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('R', 'Running');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('B', 'Blocked');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('T', 'Completed successfully');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('E', 'Terminated with errors');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('e', 'Non-fatal error');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('f', 'Fatal error');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('D', 'Verify found differences');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('A', 'Canceled by user');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('F', 'Waiting for Client');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('S', 'Waiting for Storage daemon');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('m', 'Waiting for new media');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('M', 'Waiting for media mount');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('s', 'Waiting for storage resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('j', 'Waiting for job resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('c', 'Waiting for client resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('d', 'Waiting on maximum jobs');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('t', 'Waiting on start time');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('p', 'Waiting on higher priority jobs');
-
 
-DELETE FROM version;
 INSERT INTO version (versionId) VALUES (9);
 
 vacuum;
index 37be54689a249a16d939eeccc6f783000e4a1e8d..019132840641eaa05f6ff5548daabd4d5b74b0ad 100755 (executable)
@@ -1,9 +1,9 @@
 #!/bin/sh
 #
-# shell script to update SQLite from version 1.36 to 1.38
+# shell script to update SQLite from version 1.38 to 1.39
 #
 echo " "
-echo "This script will update a Bacula SQLite database from version 8 to 9"
+echo "This script will update a Bacula SQLite database from version 9 to 9"
 echo "Depending on the size of your database,"
 echo "this script may take several minutes to run."
 echo " "
@@ -14,12 +14,14 @@ sqlite=@DB_NAME@
 
 ${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
 BEGIN TRANSACTION;
+
 CREATE TEMPORARY TABLE Media_backup (
    MediaId INTEGER UNSIGNED AUTOINCREMENT,
    VolumeName VARCHAR(128) NOT NULL,
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
    LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
@@ -42,23 +44,26 @@ CREATE TEMPORARY TABLE Media_backup (
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
    StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DeviceId INTEGER UNSIGNED REFERENCES Device,
    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,
    PRIMARY KEY(MediaId)
    );
 
 INSERT INTO Media_backup SELECT 
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, 0, FirstWritten, LastWritten,
+   MediaType, LabelType, 0, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
-   VolMounts, VolBytes, 0, VolErrors, VolWrites,
+   VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
-   MaxVolFiles, MaxVolBytes, InChanger, 0, MediaAddressing,
-   VolReadTime, VolWriteTime, EndFile, EndBlock
+   MaxVolFiles, MaxVolBytes, InChanger, 
+   StorageId, 0, MediaAddressing,
+   VolReadTime, VolWriteTime, EndFile, EndBlock, 0
    FROM Media;
 
 
@@ -70,6 +75,7 @@ CREATE TABLE Media (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
    LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
@@ -92,243 +98,51 @@ CREATE TABLE Media (
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
    StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DeviceId INTEGER UNSIGNED REFERENCES Device,
    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,
    PRIMARY KEY(MediaId)
    );
 
 INSERT INTO Media (
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, LabelType, FirstWritten, LastWritten,
+   MediaType, MediaTypeId, LabelType, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
    VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes,
-   InChanger, StorageId, MediaAddressing,
+   InChanger, StorageId, DeviceId, MediaAddressing,
    VolReadTime, VolWriteTime,      
-   EndFile, EndBlock)
+   EndFile, EndBlock, LocationId)
    SELECT * FROM Media_backup;
 
 DROP TABLE Media_backup;
 CREATE INDEX inx8 ON Media (PoolId);
 
 
-CREATE TEMPORARY TABLE JobMedia_backup (
-   JobMediaId INTEGER,
-   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
-   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
-   FirstIndex INTEGER UNSIGNED NOT NULL,
-   LastIndex INTEGER UNSIGNED NOT NULL,
-   StartFile INTEGER UNSIGNED DEFAULT 0,
-   EndFile INTEGER UNSIGNED DEFAULT 0,
-   StartBlock INTEGER UNSIGNED DEFAULT 0,
-   EndBlock INTEGER UNSIGNED DEFAULT 0,
-   VolIndex INTEGER UNSIGNED DEFAULT 0,
-   Copy     INTEGER UNSIGNED DEFAULT 0,
-   Stripe   INTEGER UNSIGNED DEFAULT 0,
-   PRIMARY KEY(JobMediaId) 
-   );
-
-INSERT INTO JobMedia_backup SELECT
-   JobMediaId, JobId, MediaId,
-   FirstIndex, LastIndex, StartFile,
-   EndFile, StartBlock, EndBlock,
-   VolIndex, 0, 0 
-   FROM JobMedia;
-
-DROP TABLE JobMedia;
-
-CREATE TABLE JobMedia (
-   JobMediaId INTEGER,
-   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
-   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
-   FirstIndex INTEGER UNSIGNED NOT NULL,
-   LastIndex INTEGER UNSIGNED NOT NULL,
-   StartFile INTEGER UNSIGNED DEFAULT 0,
-   EndFile INTEGER UNSIGNED DEFAULT 0,
-   StartBlock INTEGER UNSIGNED DEFAULT 0,
-   EndBlock INTEGER UNSIGNED DEFAULT 0,
-   VolIndex INTEGER UNSIGNED DEFAULT 0,
-   Copy     INTEGER UNSIGNED DEFAULT 0,
-   Stripe   INTEGER UNSIGNED DEFAULT 0,
-   PRIMARY KEY(JobMediaId) 
-   );
-
-INSERT INTO JobMedia (
-   JobMediaId, JobId, MediaId,
-   FirstIndex, LastIndex, StartFile,
-   EndFile, StartBlock, EndBlock,
-   VolIndex, Copy, Stripe)
-   SELECT * FROM JobMedia_backup;
-
-DROP TABLE JobMedia_backup;
-
-CREATE TEMPORARY TABLE Pool_backup (
-   PoolId INTEGER,
-   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,
-   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_backup SELECT 
-   PoolId, Name, NumVols, MaxVols,
-   UseOnce, UseCatalog, AcceptAnyVolume,
-   VolRetention, VolUseDuration, MaxVolJobs,
-   MaxVolFiles, MaxVolBytes, AutoPrune,
-   Recycle, PoolType, 0, LabelFormat,
-   Enabled, ScratchPoolId, RecyclePoolId,
-   0, 0, 0, 0
-   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,
-   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)
+CREATE TABLE MAC (
+   JobId INTEGER,
+   OriginalJobId INTEGER,
+   JobType CHAR NOT NULL,
+   JobLevel CHAR NOT NULL,
+   SchedTime DATETIME NOT NULL,
+   StartTime DATETIME DEFAULT 0,
+   EndTime DATETIME DEFAULT 0,
+   JobTDate BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobId)
    );
 
-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 * FROM Pool_backup;
-
-DROP TABLE Pool_backup;
-
-CREATE TABLE MediaType (
-   MediaTypeId INTEGER,
-   MediaType VARCHAR(128) NOT NULL,
-   ReadOnly TINYINT DEFAULT 0,
-   PRIMARY KEY(MediaTypeId)
-   );
-
-CREATE TABLE Storage (
-   StorageId INTEGER,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
-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 Status (
-   JobStatus CHAR(1) NOT NULL,
-   JobStatusLong BLOB, 
-   PRIMARY KEY (JobStatus)
+CREATE TABLE Location (
+   LocationId INTEGER,
+   Location VARCHAR(128) NOT NULL,
+   PRIMARY KEY(LocationId)
    );
-
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('C', 'Created, not yet running');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('R', 'Running');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('B', 'Blocked');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('T', 'Completed successfully');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('E', 'Terminated with errors');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('e', 'Non-fatal error');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('f', 'Fatal error');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('D', 'Verify found differences');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('A', 'Canceled by user');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('F', 'Waiting for Client');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('S', 'Waiting for Storage daemon');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('m', 'Waiting for new media');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('M', 'Waiting for media mount');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('s', 'Waiting for storage resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('j', 'Waiting for job resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('c', 'Waiting for client resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('d', 'Waiting on maximum jobs');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('t', 'Waiting on start time');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('p', 'Waiting on higher priority jobs');
-
 
 DELETE FROM Version;
 INSERT INTO Version (VersionId) VALUES (9);
index 37be54689a249a16d939eeccc6f783000e4a1e8d..019132840641eaa05f6ff5548daabd4d5b74b0ad 100755 (executable)
@@ -1,9 +1,9 @@
 #!/bin/sh
 #
-# shell script to update SQLite from version 1.36 to 1.38
+# shell script to update SQLite from version 1.38 to 1.39
 #
 echo " "
-echo "This script will update a Bacula SQLite database from version 8 to 9"
+echo "This script will update a Bacula SQLite database from version 9 to 9"
 echo "Depending on the size of your database,"
 echo "this script may take several minutes to run."
 echo " "
@@ -14,12 +14,14 @@ sqlite=@DB_NAME@
 
 ${bindir}/${sqlite} $* bacula.db <<END-OF-DATA
 BEGIN TRANSACTION;
+
 CREATE TEMPORARY TABLE Media_backup (
    MediaId INTEGER UNSIGNED AUTOINCREMENT,
    VolumeName VARCHAR(128) NOT NULL,
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
    LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
@@ -42,23 +44,26 @@ CREATE TEMPORARY TABLE Media_backup (
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
    StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DeviceId INTEGER UNSIGNED REFERENCES Device,
    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,
    PRIMARY KEY(MediaId)
    );
 
 INSERT INTO Media_backup SELECT 
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, 0, FirstWritten, LastWritten,
+   MediaType, LabelType, 0, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
-   VolMounts, VolBytes, 0, VolErrors, VolWrites,
+   VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
-   MaxVolFiles, MaxVolBytes, InChanger, 0, MediaAddressing,
-   VolReadTime, VolWriteTime, EndFile, EndBlock
+   MaxVolFiles, MaxVolBytes, InChanger, 
+   StorageId, 0, MediaAddressing,
+   VolReadTime, VolWriteTime, EndFile, EndBlock, 0
    FROM Media;
 
 
@@ -70,6 +75,7 @@ CREATE TABLE Media (
    Slot INTEGER DEFAULT 0,
    PoolId INTEGER UNSIGNED REFERENCES Pool NOT NULL,
    MediaType VARCHAR(128) NOT NULL,
+   MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL,
    LabelType TINYINT DEFAULT 0,
    FirstWritten DATETIME DEFAULT 0,
    LastWritten DATETIME DEFAULT 0,
@@ -92,243 +98,51 @@ CREATE TABLE Media (
    MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
    InChanger TINYINT DEFAULT 0,
    StorageId INTEGER UNSIGNED REFERENCES Storage,
+   DeviceId INTEGER UNSIGNED REFERENCES Device,
    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,
    PRIMARY KEY(MediaId)
    );
 
 INSERT INTO Media (
    MediaId, VolumeName, Slot, PoolId,
-   MediaType, LabelType, FirstWritten, LastWritten,
+   MediaType, MediaTypeId, LabelType, FirstWritten, LastWritten,
    LabelDate, VolJobs, VolFiles, VolBlocks,
    VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
    VolCapacityBytes, VolStatus, Recycle,
    VolRetention, VolUseDuration, MaxVolJobs,
    MaxVolFiles, MaxVolBytes,
-   InChanger, StorageId, MediaAddressing,
+   InChanger, StorageId, DeviceId, MediaAddressing,
    VolReadTime, VolWriteTime,      
-   EndFile, EndBlock)
+   EndFile, EndBlock, LocationId)
    SELECT * FROM Media_backup;
 
 DROP TABLE Media_backup;
 CREATE INDEX inx8 ON Media (PoolId);
 
 
-CREATE TEMPORARY TABLE JobMedia_backup (
-   JobMediaId INTEGER,
-   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
-   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
-   FirstIndex INTEGER UNSIGNED NOT NULL,
-   LastIndex INTEGER UNSIGNED NOT NULL,
-   StartFile INTEGER UNSIGNED DEFAULT 0,
-   EndFile INTEGER UNSIGNED DEFAULT 0,
-   StartBlock INTEGER UNSIGNED DEFAULT 0,
-   EndBlock INTEGER UNSIGNED DEFAULT 0,
-   VolIndex INTEGER UNSIGNED DEFAULT 0,
-   Copy     INTEGER UNSIGNED DEFAULT 0,
-   Stripe   INTEGER UNSIGNED DEFAULT 0,
-   PRIMARY KEY(JobMediaId) 
-   );
-
-INSERT INTO JobMedia_backup SELECT
-   JobMediaId, JobId, MediaId,
-   FirstIndex, LastIndex, StartFile,
-   EndFile, StartBlock, EndBlock,
-   VolIndex, 0, 0 
-   FROM JobMedia;
-
-DROP TABLE JobMedia;
-
-CREATE TABLE JobMedia (
-   JobMediaId INTEGER,
-   JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
-   MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL,
-   FirstIndex INTEGER UNSIGNED NOT NULL,
-   LastIndex INTEGER UNSIGNED NOT NULL,
-   StartFile INTEGER UNSIGNED DEFAULT 0,
-   EndFile INTEGER UNSIGNED DEFAULT 0,
-   StartBlock INTEGER UNSIGNED DEFAULT 0,
-   EndBlock INTEGER UNSIGNED DEFAULT 0,
-   VolIndex INTEGER UNSIGNED DEFAULT 0,
-   Copy     INTEGER UNSIGNED DEFAULT 0,
-   Stripe   INTEGER UNSIGNED DEFAULT 0,
-   PRIMARY KEY(JobMediaId) 
-   );
-
-INSERT INTO JobMedia (
-   JobMediaId, JobId, MediaId,
-   FirstIndex, LastIndex, StartFile,
-   EndFile, StartBlock, EndBlock,
-   VolIndex, Copy, Stripe)
-   SELECT * FROM JobMedia_backup;
-
-DROP TABLE JobMedia_backup;
-
-CREATE TEMPORARY TABLE Pool_backup (
-   PoolId INTEGER,
-   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,
-   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_backup SELECT 
-   PoolId, Name, NumVols, MaxVols,
-   UseOnce, UseCatalog, AcceptAnyVolume,
-   VolRetention, VolUseDuration, MaxVolJobs,
-   MaxVolFiles, MaxVolBytes, AutoPrune,
-   Recycle, PoolType, 0, LabelFormat,
-   Enabled, ScratchPoolId, RecyclePoolId,
-   0, 0, 0, 0
-   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,
-   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)
+CREATE TABLE MAC (
+   JobId INTEGER,
+   OriginalJobId INTEGER,
+   JobType CHAR NOT NULL,
+   JobLevel CHAR NOT NULL,
+   SchedTime DATETIME NOT NULL,
+   StartTime DATETIME DEFAULT 0,
+   EndTime DATETIME DEFAULT 0,
+   JobTDate BIGINT UNSIGNED DEFAULT 0,
+   PRIMARY KEY(JobId)
    );
 
-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 * FROM Pool_backup;
-
-DROP TABLE Pool_backup;
-
-CREATE TABLE MediaType (
-   MediaTypeId INTEGER,
-   MediaType VARCHAR(128) NOT NULL,
-   ReadOnly TINYINT DEFAULT 0,
-   PRIMARY KEY(MediaTypeId)
-   );
-
-CREATE TABLE Storage (
-   StorageId INTEGER,
-   Name VARCHAR(128) NOT NULL,
-   AutoChanger TINYINT DEFAULT 0,
-   PRIMARY KEY(StorageId)
-   );
-
-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 Status (
-   JobStatus CHAR(1) NOT NULL,
-   JobStatusLong BLOB, 
-   PRIMARY KEY (JobStatus)
+CREATE TABLE Location (
+   LocationId INTEGER,
+   Location VARCHAR(128) NOT NULL,
+   PRIMARY KEY(LocationId)
    );
-
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('C', 'Created, not yet running');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('R', 'Running');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('B', 'Blocked');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('T', 'Completed successfully');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('E', 'Terminated with errors');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('e', 'Non-fatal error');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('f', 'Fatal error');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('D', 'Verify found differences');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('A', 'Canceled by user');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('F', 'Waiting for Client');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('S', 'Waiting for Storage daemon');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('m', 'Waiting for new media');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('M', 'Waiting for media mount');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('s', 'Waiting for storage resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('j', 'Waiting for job resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('c', 'Waiting for client resource');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('d', 'Waiting on maximum jobs');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('t', 'Waiting on start time');
-INSERT INTO Status (JobStatus,JobStatusLong) VALUES
-   ('p', 'Waiting on higher priority jobs');
-
 
 DELETE FROM Version;
 INSERT INTO Version (VersionId) VALUES (9);
index 96ff865de5254dbf5918c12d9853ebaad3f25d70..2321580aa26ba71086b43590a7c954c2b5b8475a 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 /*
-   Copyright (C) 2002-2005 Kern Sibbald
+   Copyright (C) 2002-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -53,6 +53,27 @@ static void free_findex(RBSR_FINDEX *fi)
    }
 }
 
+/* 
+ * Get storage device name from Storage resource
+ */
+static bool get_storage_device(char *device, char *storage)
+{
+   STORE *store;
+   if (storage[0] == 0) {
+      return false;
+   }
+   store = (STORE *)GetResWithName(R_STORAGE, storage);    
+   if (!store) {
+      return false;
+   }
+   DEVICE *dev = (DEVICE *)(store->device->first());
+   if (!dev) {
+      return false;
+   }
+   bstrncpy(device, dev->hdr.name, MAX_NAME_LENGTH);
+   return true;
+}
+
 /*
  * Our data structures were not designed completely
  *  correctly, so the file indexes cover the full
@@ -278,6 +299,7 @@ static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
    bool first = true;
    char *p;
    JobId_t JobId;
+   char device[MAX_NAME_LENGTH];
    RBSR *bsr;
    if (*rx.JobIds == 0) {
       for (bsr=rx.bsr; bsr; bsr=bsr->next) {
@@ -293,6 +315,12 @@ static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
             }
             fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
             fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
+            if (get_storage_device(device, bsr->VolParams[i].Storage)) {
+               fprintf(fd, "Device=\"%s\"\n", device);
+            }
+            if (bsr->VolParams[i].Slot > 0) {
+               fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
+            }
             fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
             fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
             if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
@@ -346,6 +374,12 @@ static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
             }
             fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
             fprintf(fd, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType);
+            if (get_storage_device(device, bsr->VolParams[i].Storage)) {
+               fprintf(fd, "Device=\"%s\"\n", device);
+            }
+            if (bsr->VolParams[i].Slot > 0) {
+               fprintf(fd, "Slot=%d\n", bsr->VolParams[i].Slot);
+            }
             fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
             fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
             if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
index aeaeca655a51c1ac0f38ea5a85dba64d103b2067..d0425523771c7aa7e80ffd7d322b39b1064b3879 100644 (file)
@@ -189,10 +189,18 @@ bool do_mac(JCR *jcr)
       return false;
    }
 
+   /* 
+    * Target jcr is the new Job that corresponds to the original
+    *  target job. It "runs" at the same time as the current 
+    *  migration job and becomes a new backup job that replaces
+    *  the original backup job.  Most operations on the current
+    *  migration jcr are also done on the target jcr.
+    */
    tjcr = jcr->target_jcr = new_jcr(sizeof(JCR), dird_free_jcr);
    memcpy(&tjcr->target_jr, &jcr->target_jr, sizeof(tjcr->target_jr));
-   set_jcr_defaults(tjcr, tjob);
 
+   /* Turn the tjcr into a "real" job */
+   set_jcr_defaults(tjcr, tjob);
    if (!setup_job(tjcr)) {
       return false;
    }
@@ -219,6 +227,9 @@ bool do_mac(JCR *jcr)
       return false;
    }
 
+   /* Check Migration time and High/Low water marks */
+   /* ***FIXME*** */
+
    /* If pool storage specified, use it for restore */
    copy_storage(tjcr, pool->storage);
 
index db289413b9afac139cf121fffdd96199de1d86dd..065aeba85bc587127b7a0fb77a75659dd6936afb 100644 (file)
@@ -47,6 +47,7 @@ const char *del_File     = "DELETE FROM File WHERE JobId=%s";
 const char *upd_Purged   = "UPDATE Job Set PurgedFiles=1 WHERE JobId=%s";
 const char *cnt_DelCand  = "SELECT count(*) FROM DelCandidates";
 const char *del_Job      = "DELETE FROM Job WHERE JobId=%s";
+const char *del_MAC      = "DELETE FROM MAC WHERE JobId=%s";
 const char *del_JobMedia = "DELETE FROM JobMedia WHERE JobId=%s";
 const char *cnt_JobMedia = "SELECT count(*) FROM JobMedia WHERE MediaId=%s";
 const char *sel_JobMedia = "SELECT JobId FROM JobMedia WHERE MediaId=%s";
@@ -395,3 +396,6 @@ const char *uar_jobid_fileindex_from_dir =
    "GROUP BY File.FileIndex ";
 #endif
  
+/* Query to get list of files from table -- presuably built by an external program */
+const char *uar_jobid_fileindex_from_table = 
+   "SELECT JobId, FileIndex from %s";
index 6ab82d7ff22b81203aab62115cc374acb29f66de..1edb832d9558a77ba6c71fec85f16e7a7d5b80ae 100644 (file)
@@ -1237,9 +1237,11 @@ static void do_job_delete(UAContext *ua, JobId_t JobId)
 
    Mmsg(query, "DELETE FROM Job WHERE JobId=%s", edit_int64(JobId, ed1));
    db_sql_query(ua->db, query, NULL, (void *)NULL);
-   Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(JobId, ed1));
+   Mmsg(query, "DELETE FROM MAC WHERE JobId=%s", ed1);
    db_sql_query(ua->db, query, NULL, (void *)NULL);
-   Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", edit_int64(JobId, ed1));
+   Mmsg(query, "DELETE FROM File WHERE JobId=%s", ed1);
+   db_sql_query(ua->db, query, NULL, (void *)NULL);
+   Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", ed1);
    db_sql_query(ua->db, query, NULL, (void *)NULL);
    free_pool_memory(query);
    bsendmsg(ua, _("Job %s and associated records deleted from the catalog.\n"), edit_int64(JobId, ed1));
index 5a2d1189ff6b41b65e63e946d99ef4bac316d214..5661d1db7235c823445071d3557f9b7e13349881 100644 (file)
@@ -405,6 +405,10 @@ static int purge_jobs_from_client(UAContext *ua, CLIENT *client)
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       Dmsg1(050, "Delete Job sql=%s\n", query);
 
+      Mmsg(query, "DELETE FROM MAC WHERE JobId=%s", ed1);
+      db_sql_query(ua->db, query, NULL, (void *)NULL);
+      Dmsg1(050, "Delete MAC sql=%s\n", query);
+
       Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", ed1);
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       Dmsg1(050, "Delete JobMedia sql=%s\n", query);
@@ -523,6 +527,8 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr)
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       Mmsg(query, "DELETE FROM Job WHERE JobId=%s", ed1);
       db_sql_query(ua->db, query, NULL, (void *)NULL);
+      Mmsg(query, "DELETE FROM MAC WHERE JobId=%s", ed1);
+      db_sql_query(ua->db, query, NULL, (void *)NULL);
       Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", ed1);
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       Dmsg1(050, "Del sql=%s\n", query);
index 5db990706f41e514c2e650136c4dd3d035bbbf4c..9fd21a4e7264d47024e8682312d86a8458b7aac4 100644 (file)
@@ -44,6 +44,7 @@ extern char *uar_sel_all_temp1,  *uar_sel_fileset, *uar_mediatype;
 extern char *uar_jobid_fileindex, *uar_dif,        *uar_sel_all_temp;
 extern char *uar_count_files,     *uar_jobids_fileindex;
 extern char *uar_jobid_fileindex_from_dir;
+extern char *uar_jobid_fileindex_from_table;
 
 
 
@@ -69,6 +70,7 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b
 static int get_client_name(UAContext *ua, RESTORE_CTX *rx);
 static int get_date(UAContext *ua, char *date, int date_len);
 static int count_handler(void *ctx, int num_fields, char **row);
+static bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table);
 
 /*
  *   Restore files
@@ -229,6 +231,15 @@ static void free_rx(RESTORE_CTX *rx)
    free_name_list(&rx->name_list);
 }
 
+static bool has_value(UAContext *ua, int i)
+{
+   if (!ua->argv[i]) {
+      bsendmsg(ua, _("Missing value for keyword: %s\n"), ua->argk[i]);
+      return false;
+   }
+   return true;
+}
+
 static int get_client_name(UAContext *ua, RESTORE_CTX *rx)
 {
    /* If no client name specified yet, get it now */
@@ -237,6 +248,9 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx)
       /* try command line argument */
       int i = find_arg_with_value(ua, N_("client"));
       if (i >= 0) {
+         if (!has_value(ua, i)) {
+            return 0;
+         }
          bstrncpy(rx->ClientName, ua->argv[i], sizeof(rx->ClientName));
          return 1;
       }
@@ -249,14 +263,6 @@ static int get_client_name(UAContext *ua, RESTORE_CTX *rx)
    return 1;
 }
 
-static bool has_value(UAContext *ua, int i)
-{
-   if (!ua->argv[i]) {
-      bsendmsg(ua, _("Missing value for keyword: %s\n"), ua->argk[i]);
-      return false;
-   }
-   return true;
-}
 
 /*
  * The first step in the restore process is for the user to
@@ -695,6 +701,10 @@ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, b
       }
       fclose(ffd);
       break;
+   case '?':
+      p++;
+      insert_table_into_findex_list(ua, rx, p);
+      break;
    default:
       if (dir) {
          insert_dir_into_findex_list(ua, rx, ua->cmd, date);
@@ -783,6 +793,36 @@ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *di
    return true;
 }
 
+/*
+ * Get the JobId and FileIndexes of all files in the specified table
+ */
+static bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table)
+{
+   char ed1[50];
+
+   strip_trailing_junk(table);
+   Mmsg(rx->query, uar_jobid_fileindex_from_table, table);
+
+   rx->found = false;
+   /* Find and insert jobid and File Index */
+   if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) {
+      bsendmsg(ua, _("Query failed: %s. ERR=%s\n"),
+         rx->query, db_strerror(ua->db));
+   }
+   if (!rx->found) {
+      bsendmsg(ua, _("No table found: %s\n"), table);
+      return true;
+   }
+   /*
+    * Find the MediaTypes for this JobId and add to the name_list
+    */
+   Mmsg(rx->query, uar_mediatype, edit_int64(rx->JobId, ed1));
+   if (!db_sql_query(ua->db, rx->query, unique_name_list_handler, (void *)&rx->name_list)) {
+      bsendmsg(ua, "%s", db_strerror(ua->db));
+      return false;
+   }
+   return true;
+}
 
 static void split_path_and_filename(RESTORE_CTX *rx, char *name)
 {
index e09428754571e96678d67591a4ecae815df05cc3..ba70f04ef69b53cf94d6230722d101981afe085d 100644 (file)
@@ -23,16 +23,7 @@ first_rule: all
 dummy:
 
 # bacula-sd
-SVRSRCS = stored.c ansi_label.c \
-         autochanger.c acquire.c append.c \
-         askdir.c authenticate.c \
-         block.c butil.c dev.c \
-         device.c dircmd.c dvd.c ebcdic.c fd_cmds.c job.c \
-         label.c mac.c match_bsr.c mount.c parse_bsr.c \
-         pythonsd.c read.c read_record.c record.c \
-         reserve.c scan.c \
-         spool.c status.c stored_conf.c wait.c
-SVROBJS = stored.o ansi_label.o \
+SDOBJS =  stored.o ansi_label.o \
          autochanger.o acquire.o append.o \
          askdir.o authenticate.o \
          block.o butil.o dev.o \
@@ -43,39 +34,37 @@ SVROBJS = stored.o ansi_label.o \
          spool.o status.o stored_conf.o wait.o
 
 # btape
-TAPESRCS = btape.c block.c butil.c dev.c device.c label.c \
-          ansi_label.c dvd.c ebcdic.c \
-          acquire.c mount.c record.c read_record.c \
-          stored_conf.c match_bsr.c parse_bsr.c spool.c
 TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o read_record.o \
+          reserve.o \
           stored_conf.o match_bsr.o parse_bsr.o scan.o spool.o wait.o
 
 # bls
 BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
          ansi_label.o dvd.o ebcdic.o \
          autochanger.o acquire.o mount.o parse_bsr.o record.o  \
-         read_record.o scan.o stored_conf.o spool.o wait.o
+         read_record.o reserve.o scan.o stored_conf.o spool.o wait.o
 
 # bextract
 BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
-          pythonsd.o \
-          read_record.o scan.o stored_conf.o spool.o wait.o
+          pythonsd.o read_record.o reserve.o \
+          scan.o stored_conf.o spool.o wait.o
 
 # bscan
 SCNOBJS = bscan.o block.o device.o dev.o label.o \
          ansi_label.o dvd.o ebcdic.o \
          autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-         butil.o read_record.o scan.o stored_conf.o spool.o wait.o
+         butil.o read_record.o scan.o reserve.o stored_conf.o spool.o wait.o
 
 # bcopy
 COPYOBJS = bcopy.o block.o device.o dev.o label.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-          butil.o read_record.o scan.o stored_conf.o spool.o wait.o
+          butil.o read_record.o reserve.o \
+          scan.o stored_conf.o spool.o wait.o
 
 
 
@@ -98,13 +87,13 @@ all: Makefile bacula-sd @STATIC_SD@ bls bextract bscan btape bcopy
        @echo "===== Make of stored is good ===="
        @echo " "
 
-bacula-sd: $(SVROBJS) ../lib/libbac.a
-       $(CXX) $(WLDFLAGS) $(LDFLAGS) -L../lib -o $@ $(SVROBJS) $(FDLIBS) \
+bacula-sd: $(SDOBJS) ../lib/libbac.a
+       $(CXX) $(WLDFLAGS) $(LDFLAGS) -L../lib -o $@ $(SDOBJS) $(FDLIBS) \
          -lbac -lm $(PYTHON_LIBS) $(DLIB) $(LIBS) $(WRAPLIBS) \
          $(GETTEXT_LIBS) $(OPENSSL_LIBS)
 
-static-bacula-sd: $(SVROBJS) ../lib/libbac.a
-       $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -o $@ $(SVROBJS) $(FDLIBS) \
+static-bacula-sd: $(SDOBJS) ../lib/libbac.a
+       $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -o $@ $(SDOBJS) $(FDLIBS) \
         -lbac -lm $(PYTHON_LIBS) $(DLIB) $(LIBS) $(WRAPLIBS) \
         $(GETTEXT_LIBS) $(OPENSSL_LIBS)
        strip $@
index 0d779b9855ef0e19da2c78b419a333965592ab9f..4d32968cfc13a05e5d2ea2f6a69d478404b9bca0 100644 (file)
@@ -23,6 +23,9 @@
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
+/* Forward referenced functions */
+static void detach_dcr_from_dev(DCR *dcr);
+
 
 /*********************************************************************
  * Acquire device for reading. 
  *  Returns: NULL if failed for any reason
  *           dcr  if successful
  */
-DCR *acquire_device_for_read(DCR *dcr)
+bool acquire_device_for_read(DCR *dcr)
 {
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
-   bool vol_ok = false;
+   bool ok = false;
    bool tape_previously_mounted;
    bool tape_initially_mounted;
    VOL_LIST *vol;
@@ -69,13 +72,68 @@ DCR *acquire_device_for_read(DCR *dcr)
    bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
    bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
    dcr->VolCatInfo.Slot = vol->Slot;
-   Dmsg4(100, "===== Vol=%s MT=%s Slt=%d Dev-MT=%s\n", dcr->VolumeName,        
-      dcr->media_type, vol->Slot, dev->device->media_type);
-
-   if (strcmp(dcr->media_type, dev->device->media_type) != 0) {
-      Dmsg2(000, "Wrong MT have=%s want=%s\n", dev->device->media_type,
-         dcr->media_type);
-      Dmsg1(000, "New storage=%s\n", vol->storage);
+    
+   /*
+    * If the MediaType requested for this volume is not the
+    *  same as the current drive, we attempt to find the same
+    *  device that was used to write the orginal volume.  If
+    *  found, we switch to using that device.
+    */
+   Dmsg2(100, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
+   if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
+      RCTX rctx;
+      DIRSTORE *store;
+      int stat;
+      memset(&rctx, 0, sizeof(RCTX));
+      rctx.jcr = jcr;
+      jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
+      rctx.any_drive = true;
+      rctx.device_name = vol->device;
+      store = new DIRSTORE;
+      memset(store, 0, sizeof(DIRSTORE));
+      store->name[0] = 0; /* No dir name */
+      bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
+      bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
+      bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
+      store->append = false;
+      rctx.store = store;
+      
+      /*
+       * Note, if search_for_device() succeeds, we get a new_dcr,
+       *  which we do not use except for the dev info.
+       */
+      stat = search_res_for_device(rctx);
+      release_msgs(jcr);              /* release queued messages */
+      if (stat == 1) {
+         DCR *new_dcr = jcr->read_dcr;
+         dev->unblock();
+         detach_dcr_from_dev(dcr);    /* release old device */
+         /* Copy important info from the new dcr */
+         dev = dcr->dev = new_dcr->dev; 
+         jcr->read_dcr = dcr; 
+         dcr->device = new_dcr->device;
+         dcr->max_job_spool_size = dcr->device->max_job_spool_size;
+         if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
+            dev->attached_dcrs->append(dcr);  /* attach dcr to device */
+         }
+         new_dcr->VolumeName[0] = 0;
+         free_dcr(new_dcr);
+         dev->block(BST_DOING_ACQUIRE); 
+         Jmsg(jcr, M_INFO, 0, _("Media Type change.  New device %s chosen.\n"),
+            dev->print_name());
+         bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
+         bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
+         dcr->VolCatInfo.Slot = vol->Slot;
+         bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
+         bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
+      } else if (stat == 0) {   /* device busy */
+         Dmsg1(000, "Device %s is busy.\n", vol->device);
+      } else {
+         /* error */
+         Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
+            vol->VolumeName);
+         goto get_out;
+      }
    }
 
    init_device_wait_timers(dcr);
@@ -106,12 +164,12 @@ DCR *acquire_device_for_read(DCR *dcr)
       if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
          if (dev->dev_errno == EIO) {   /* no tape loaded */
            Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed (EIO): ERR=%s\n"),
-                 dev->print_name(), dcr->VolumeName, strerror_dev(dev));
+                 dev->print_name(), dcr->VolumeName, dev->bstrerror());
             goto default_path;
          }
          
          Jmsg3(jcr, M_FATAL, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
-             dev->print_name(), dcr->VolumeName, strerror_dev(dev));
+             dev->print_name(), dcr->VolumeName, dev->bstrerror());
          goto get_out;
       }
       Dmsg1(100, "opened dev %s OK\n", dev->print_name());
@@ -122,7 +180,7 @@ DCR *acquire_device_for_read(DCR *dcr)
       vol_label_status = read_dev_volume_label(dcr);
       switch (vol_label_status) {
       case VOL_OK:
-         vol_ok = true;
+         ok = true;
          memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
          break;                    /* got it */
       case VOL_IO_ERROR:
@@ -175,7 +233,7 @@ default_path:
       } /* end switch */
       break;
    } /* end for loop */
-   if (!vol_ok) {
+   if (!ok) {
       Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
             dev->print_name());
       goto get_out;
@@ -197,10 +255,7 @@ get_out:
    }
    V(dev->mutex);
    dev->unblock();
-   if (!vol_ok) {
-      dcr = NULL;
-   }
-   return dcr;
+   return ok;
 }
 
 
@@ -497,16 +552,12 @@ static void remove_dcr_from_dcrs(DCR *dcr)
 }
 #endif
 
-/*
- * Free up all aspects of the given dcr -- i.e. dechain it,
- *  release allocated memory, zap pointers, ...
- */
-void free_dcr(DCR *dcr)
+static void detach_dcr_from_dev(DCR *dcr)
 {
-   JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
 
    if (dcr->reserved_device) {
+      dcr->reserved_device = false;
       lock_device(dev);
       dev->reserved_device--;
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
@@ -523,10 +574,24 @@ void free_dcr(DCR *dcr)
    }
 
    /* Detach this dcr only if the dev is initialized */
-   if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
-      dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
+   if (dcr->dev->fd != 0 && dcr->jcr && dcr->jcr->JobType != JT_SYSTEM) {
+      dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
    }
+   free_unused_volume(dcr);           /* free unused vols attached to this dcr */
+   pthread_cond_broadcast(&dcr->dev->wait_next_vol);
+   pthread_cond_broadcast(&wait_device_release);
+}
+
+/*
+ * Free up all aspects of the given dcr -- i.e. dechain it,
+ *  release allocated memory, zap pointers, ...
+ */
+void free_dcr(DCR *dcr)
+{
+
+   detach_dcr_from_dev(dcr);
+
    if (dcr->block) {
       free_block(dcr->block);
    }
@@ -536,8 +601,5 @@ void free_dcr(DCR *dcr)
    if (dcr->jcr) {
       dcr->jcr->dcr = NULL;
    }
-   free_unused_volume(dcr);           /* free unused vols attached to this dcr */
    free(dcr);
-   pthread_cond_broadcast(&dev->wait_next_vol);
-   pthread_cond_broadcast(&wait_device_release);
 }
index 89517246c8af344f14898520f74b1ec09f26224c..eeae53420bd481965aec63da5ae870ba0f4ca95a 100644 (file)
@@ -93,7 +93,7 @@ bool do_append_data(JCR *jcr)
     */
    if (!write_session_label(dcr, SOS_LABEL)) {
       Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
-         strerror_dev(dev));
+         dev->bstrerror());
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       ok = false;
    }
@@ -203,9 +203,9 @@ bool do_append_data(JCR *jcr)
                        rec.remainder);
             if (!write_block_to_device(dcr)) {
                Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
-                  dev->print_name(), strerror_dev(dev));
+                  dev->print_name(), dev->bstrerror());
                Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
-                     dev->print_name(), strerror_dev(dev));
+                     dev->print_name(), dev->bstrerror());
                ok = false;
                break;
             }
@@ -261,7 +261,7 @@ bool do_append_data(JCR *jcr)
    if (ok || dev->can_write()) {
       if (!write_session_label(dcr, EOS_LABEL)) {
          Jmsg1(jcr, M_FATAL, 0, _("Error writting end session label. ERR=%s\n"),
-               strerror_dev(dev));
+               dev->bstrerror());
          set_jcr_job_status(jcr, JS_ErrorTerminated);
          ok = false;
       }
@@ -272,7 +272,7 @@ bool do_append_data(JCR *jcr)
       /* Flush out final partial block of this session */
       if (!write_block_to_device(dcr)) {
          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+               dev->print_name(), dev->bstrerror());
          Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
          ok = false;
       }
index 15766ac356e195d345c2b7ad3d13eb89c48250a6..b072bd9a935b6dcba88be5c7c2cc297c723badb1 100644 (file)
@@ -190,8 +190,8 @@ int main (int argc, char *argv[])
    free_jcr(in_jcr);
    free_jcr(out_jcr);
 
-   term_dev(in_dev);
-   term_dev(out_dev);
+   in_dev->term();
+   out_dev->term();
    return 0;
 }
 
@@ -231,16 +231,16 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
                        rec->remainder);
             if (!write_block_to_device(out_jcr->dcr)) {
                Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n",
-                  out_dev->print_name(), strerror_dev(out_dev));
+                  out_dev->print_name(), out_dev->bstrerror());
                Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
-                     strerror_dev(out_dev));
+                     out_dev->bstrerror());
             }
          }
          if (!write_block_to_device(out_jcr->dcr)) {
             Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n",
-               out_dev->print_name(), strerror_dev(out_dev));
+               out_dev->print_name(), out_dev->bstrerror());
             Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
-                  strerror_dev(out_dev));
+                  out_dev->bstrerror());
          }
          break;
       case EOM_LABEL:
@@ -261,9 +261,9 @@ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec)
                  rec->remainder);
       if (!write_block_to_device(out_jcr->dcr)) {
          Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n",
-            out_dev->print_name(), strerror_dev(out_dev));
+            out_dev->print_name(), out_dev->bstrerror());
          Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
-               strerror_dev(out_dev));
+               out_dev->bstrerror());
          break;
       }
    }
@@ -279,9 +279,6 @@ bool    dir_create_jobmedia_record(DCR *dcr) { return 1; }
 bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
-VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
-bool    free_volume(DEVICE *dev) { return true; }
-void    free_unused_volume(DCR *dcr) { }
 
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
index 45cef4547c6f7eda7e3d5392b0ab4de6e0c7acfa..4d1cf2051d1c2fb84264cb29ae5ab6621346de63 100644 (file)
@@ -246,7 +246,7 @@ static void do_extract(char *devname)
    release_device(dcr);
    free_attr(attr);
    free_jcr(jcr);
-   term_dev(dev);
+   dev->term();
 
    printf(_("%u files restored.\n"), num_files);
    return;
@@ -469,9 +469,6 @@ bool    dir_create_jobmedia_record(DCR *dcr) { return 1; }
 bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
-VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
-bool    free_volume(DEVICE *dev) { return true; }
-void    free_unused_volume(DCR *dcr) { }
 
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
index a7e7fe1cf443db4d3f4527a8e09136c5452e11d0..d1d7b2669d7db30d84128d061da24ae6728a5cb2 100644 (file)
@@ -480,7 +480,7 @@ bool write_block_to_dev(DCR *dcr)
       if (weof_dev(dev, 1) != 0) {            /* write eof */
          Dmsg0(190, "WEOF error in max file size.\n");
          Jmsg(jcr, M_FATAL, 0, _("Unable to write EOF. ERR=%s\n"), 
-            strerror_dev(dev));
+            dev->bstrerror());
          terminate_writing_volume(dcr);
          dev->dev_errno = ENOSPC;
          return false;
@@ -626,7 +626,7 @@ static void reread_last_block(DCR *dcr)
               be.strerror(dev->dev_errno));
       }
       /* Backspace over record */
-      if (ok && !bsr_dev(dev, 1)) {
+      if (ok && !dev->bsr(1)) {
          berrno be;
          ok = false;
          Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"), 
@@ -637,7 +637,7 @@ static void reread_last_block(DCR *dcr)
           *    rewind(), but if we do that, higher levels in cleaning up, will
           *    most likely write the EOS record over the beginning of the
           *    tape.  The rewind *is* done later in mount.c when another
-          *    tape is requested. Note, the clrerror_dev() call in bsr_dev()
+          *    tape is requested. Note, the clrerror_dev() call in bsr()
           *    calls ioctl(MTCERRSTAT), which *should* fix the problem.
           */
       }
@@ -801,7 +801,7 @@ static bool do_dvd_size_checks(DCR *dcr)
       
       if (dvd_open_next_part(dcr) < 0) {
          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
-                dev->print_name(), strerror_dev(dev));
+                dev->print_name(), dev->bstrerror());
          dev->dev_errno = EIO;
          return false;
       }
@@ -911,7 +911,7 @@ reread:
         (dev->part < dev->num_parts)) {
       if (dvd_open_next_part(dcr) < 0) {
          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+               dev->print_name(), dev->bstrerror());
          dev->dev_errno = EIO;
          return false;
       }
@@ -994,8 +994,8 @@ reread:
       /* Attempt to reposition to re-read the block */
       if (dev->is_tape()) {
          Dmsg0(200, "BSR for reread; block too big for buffer.\n");
-         if (!bsr_dev(dev, 1)) {
-            Jmsg(jcr, M_ERROR, 0, "%s", strerror_dev(dev));
+         if (!dev->bsr(1)) {
+            Jmsg(jcr, M_ERROR, 0, "%s", dev->bstrerror());
             block->read_len = 0;
             return false;
          }
index ed150125790b5e83e0d9183c74ccce59551dc7b8..d0e317340afa9d86249a491036c5d797611063f6 100644 (file)
@@ -253,7 +253,7 @@ static void do_close(JCR *jcr)
    free_record(rec);
    free_block(block);
    free_jcr(jcr);
-   term_dev(dev);
+   dev->term();
 }
 
 
@@ -435,9 +435,6 @@ bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
 int     generate_job_event(JCR *jcr, const char *event) { return 1; }
-VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
-bool    free_volume(DEVICE *dev) { return true; }
-void    free_unused_volume(DCR *dcr) { }
        
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
index ab47d88fe9ba5d88342ec20b3b70ecef50c5e323..d88a10991a5f37662e2bfa0c7ad3d7f004144caa 100644 (file)
@@ -292,7 +292,7 @@ int main (int argc, char *argv[])
    }
 
    free_jcr(bjcr);
-   term_dev(dev);
+   dev->term();
    return 0;
 }
 
@@ -1246,9 +1246,6 @@ bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
 int     generate_job_event(JCR *jcr, const char *event) { return 1; }
-VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
-bool    free_volume(DEVICE *dev) { return true; }
-void    free_unused_volume(DCR *dcr) { }
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
 {
index 9f43a847072abd85dc0b7035f233bb9cf26fb172..b7f49a623b91bcccac3a4171c361acf3729003b3 100644 (file)
@@ -33,7 +33,7 @@ struct VOL_LIST {
    VOL_LIST *next;
    char VolumeName[MAX_NAME_LENGTH];
    char MediaType[MAX_NAME_LENGTH];
-   char storage[MAX_NAME_LENGTH];   /* ***FIXME*** use alist here */
+   char device[MAX_NAME_LENGTH];   /* ***FIXME*** use alist here */
    int Slot;
    uint32_t start_file;
 };
@@ -52,7 +52,7 @@ struct BSR_VOLUME {
    BSR_VOLUME *next;
    char VolumeName[MAX_NAME_LENGTH];
    char MediaType[MAX_NAME_LENGTH];
-   char storage[MAX_NAME_LENGTH];   /* ***FIXME*** use alist here */
+   char device[MAX_NAME_LENGTH];   /* ***FIXME*** use alist here */
    int32_t       Slot;                /* Slot */
 };
 
index aca4acc047fd7579ddf994d5ac47f3052401231d..c8979749be3b2b45f13b04caae36a0eb712a0ce5 100644 (file)
@@ -303,7 +303,7 @@ static void terminate_btape(int stat)
    jcr = NULL;
 
    if (dev) {
-      term_dev(dev);
+      dev->term();
    }
 
    if (debug_level > 10)
@@ -363,7 +363,7 @@ static void labelcmd()
 
    if (!dev->is_open()) {
       if (!first_open_device(dcr)) {
-         Pmsg1(0, _("Device open failed. ERR=%s\n"), strerror_dev(dev));
+         Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror());
       }
    }
    dev->rewind(dcr);
@@ -388,13 +388,13 @@ static void readlabelcmd()
       Pmsg0(0, _("Volume label read correctly.\n"));
       break;
    case VOL_IO_ERROR:
-      Pmsg1(0, _("I/O error on device: ERR=%s"), strerror_dev(dev));
+      Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
       break;
    case VOL_NAME_ERROR:
       Pmsg0(0, _("Volume name error\n"));
       break;
    case VOL_CREATE_ERROR:
-      Pmsg1(0, _("Error creating label. ERR=%s"), strerror_dev(dev));
+      Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror());
       break;
    case VOL_VERSION_ERROR:
       Pmsg0(0, _("Volume version error.\n"));
@@ -421,7 +421,7 @@ static void loadcmd()
 {
 
    if (!load_dev(dev)) {
-      Pmsg1(0, _("Bad status from load. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror());
    } else
       Pmsg1(0, _("Loaded %s\n"), dev->print_name());
 }
@@ -432,7 +432,7 @@ static void loadcmd()
 static void rewindcmd()
 {
    if (!dev->rewind(dcr)) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       clrerror_dev(dev, -1);
    } else {
       Pmsg1(0, _("Rewound %s\n"), dev->print_name());
@@ -462,7 +462,7 @@ static void weofcmd()
    }
 
    if ((stat = weof_dev(dev, num)) < 0) {
-      Pmsg2(0, _("Bad status from weof %d. ERR=%s\n"), stat, strerror_dev(dev));
+      Pmsg2(0, _("Bad status from weof %d. ERR=%s\n"), stat, dev->bstrerror());
       return;
    } else {
       if (num==1) {
@@ -484,7 +484,7 @@ static void weofcmd()
 static void eomcmd()
 {
    if (!dev->eod()) {
-      Pmsg1(0, "%s", strerror_dev(dev));
+      Pmsg1(0, "%s", dev->bstrerror());
       return;
    } else {
       Pmsg0(0, _("Moved to end of medium.\n"));
@@ -514,7 +514,7 @@ static void bsfcmd()
    }
 
    if (!dev->bsf(num)) {
-      Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror());
    } else {
       Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s");
    }
@@ -532,8 +532,8 @@ static void bsrcmd()
    if (num <= 0) {
       num = 1;
    }
-   if (!bsr_dev(dev, num)) {
-      Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), strerror_dev(dev));
+   if (!dev->bsr(num)) {
+      Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror());
    } else {
       Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s");
    }
@@ -700,18 +700,18 @@ static int re_read_block_test()
       weofcmd();
    }
    if (!dev->bsf(1)) {
-      Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    if (dev_cap(dev, CAP_TWOEOF)) {
       if (!dev->bsf(1)) {
-         Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
+         Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror());
          goto bail_out;
       }
    }
    Pmsg0(0, _("Backspaced over EOF OK.\n"));
-   if (!bsr_dev(dev, 1)) {
-      Pmsg1(0, _("Backspace record failed! ERR=%s\n"), strerror_dev(dev));
+   if (!dev->bsr(1)) {
+      Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg0(0, _("Backspace record OK.\n"));
@@ -772,7 +772,7 @@ static int write_read_test()
    block = dcr->block;
    rec = new_record();
    if (!dev->rewind(dcr)) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    rec->data = check_pool_memory_size(rec->data, block->buf_len);
@@ -814,7 +814,7 @@ static int write_read_test()
       weofcmd();
    }
    if (!dev->rewind(dcr)) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    } else {
       Pmsg0(0, _("Rewind OK.\n"));
@@ -884,7 +884,7 @@ static int position_test()
    empty_block(block);
    rec = new_record();
    if (!dev->rewind(dcr)) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    rec->data = check_pool_memory_size(rec->data, block->buf_len);
@@ -926,7 +926,7 @@ static int position_test()
       weofcmd();
    }
    if (!dev->rewind(dcr)) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    } else {
       Pmsg0(0, _("Rewind OK.\n"));
@@ -970,7 +970,7 @@ static int position_test()
          continue;
       }
       Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
-      if (!reposition_dev(dev, file, blk)) {
+      if (!dev->reposition(file, blk)) {
          Pmsg0(0, _("Reposition error.\n"));
          goto bail_out;
       }
@@ -1194,7 +1194,7 @@ try_again:
     */
    bmicrosleep(sleep_time, 0);
    if (!dev->rewind(dcr) || weof_dev(dev,1) < 0) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       clrerror_dev(dev, -1);
       Pmsg0(-1, _("\nThe test failed, probably because you need to put\n"
                 "a longer sleep time in the mtx-script in the load) case.\n"
@@ -1206,7 +1206,7 @@ try_again:
    }
 
    if ((status = weof_dev(dev, 1)) < 0) {
-      Pmsg2(0, _("Bad status from weof %d. ERR=%s\n"), status, strerror_dev(dev));
+      Pmsg2(0, _("Bad status from weof %d. ERR=%s\n"), status, dev->bstrerror());
       goto bail_out;
    } else {
       Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name());
@@ -1274,7 +1274,7 @@ test_again:
    rewindcmd();
    Pmsg0(0, _("Now forward spacing 1 file.\n"));
    if (!dev->fsf(1)) {
-      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"),
@@ -1286,7 +1286,7 @@ test_again:
 
    Pmsg0(0, _("Now forward spacing 2 files.\n"));
    if (!dev->fsf(2)) {
-      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"),
@@ -1299,7 +1299,7 @@ test_again:
    rewindcmd();
    Pmsg0(0, _("Now forward spacing 4 files.\n"));
    if (!dev->fsf(4)) {
-      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"),
@@ -1317,7 +1317,7 @@ test_again:
    Pmsg0(-1, "\n");
    Pmsg0(0, _("Now forward spacing 1 more file.\n"));
    if (!dev->fsf(1)) {
-      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
    }
    Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"),
       dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!"));
@@ -1464,7 +1464,7 @@ static void fsfcmd()
       num = 1;
    }
    if (!dev->fsf(num)) {
-      Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror());
       return;
    }
    if (num == 1) {
@@ -1486,7 +1486,7 @@ static void fsrcmd()
       num = 1;
    }
    if (!dev->fsr(num)) {
-      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror());
       return;
    }
    if (num == 1) {
@@ -1593,7 +1593,7 @@ static void scancmd()
          clrerror_dev(dev, -1);
          Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
             dev->dev_name, be.strerror());
-         Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, strerror_dev(dev));
+         Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), stat, dev->bstrerror());
          if (blocks > 0) {
             if (blocks==1) {
                printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file);
@@ -1670,7 +1670,7 @@ static void scan_blocks()
    tot_files = dev->file;
    for (;;) {
       if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
-         Dmsg1(100, "!read_block(): ERR=%s\n", strerror_dev(dev));
+         Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
          if (dev->state & ST_EOT) {
             if (blocks > 0) {
                if (blocks==1) {
@@ -1709,7 +1709,7 @@ static void scan_blocks()
             printf(_("Short block read.\n"));
             continue;
          }
-         printf(_("Error reading block. ERR=%s\n"), strerror_dev(dev));
+         printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
          goto bail_out;
       }
       if (block->block_len != block_size) {
@@ -1755,7 +1755,7 @@ static void statcmd()
 {
    int debug = debug_level;
    debug_level = 30;
-   Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), strerror_dev(dev));
+   Pmsg2(0, _("Device status: %u. ERR=%s\n"), status_dev(dev), dev->bstrerror());
 #ifdef xxxx
    dump_volume_label(dev);
 #endif
@@ -1851,7 +1851,7 @@ static void fillcmd()
    if (!write_session_label(dcr, SOS_LABEL)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
-         strerror_dev(dev));
+         dev->bstrerror());
       ok = false;
    }
    Pmsg0(-1, _("Wrote Start of Session label.\n"));
@@ -1972,7 +1972,7 @@ static void fillcmd()
          set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
       if (!write_session_label(dcr, EOS_LABEL)) {
-         Pmsg1(000, _("Error writting end session label. ERR=%s\n"), strerror_dev(dev));
+         Pmsg1(000, _("Error writting end session label. ERR=%s\n"), dev->bstrerror());
          ok = false;
       }
       /* Write out final block of this session */
@@ -2137,13 +2137,13 @@ static void do_unfill()
    read_records(dcr, quickie_cb, my_mount_next_read_volume);
    Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
          last_file, last_block_num);
-   if (!reposition_dev(dev, last_file, last_block_num)) {
-      Pmsg1(-1, _("Reposition error. ERR=%s\n"), strerror_dev(dev));
+   if (!dev->reposition(last_file, last_block_num)) {
+      Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
    if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
-      Pmsg1(-1, _("Error reading block: ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    if (compare_blocks(last_block, block)) {
@@ -2188,13 +2188,13 @@ static void do_unfill()
     * on the previous tape.
     */
    Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num);
-   if (!reposition_dev(dev, 0, 1)) {
-      Pmsg1(-1, _("Reposition error. ERR=%s\n"), strerror_dev(dev));
+   if (!dev->reposition(0, 1)) {
+      Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
    if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
-      Pmsg1(-1, _("Error reading block: ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    if (compare_blocks(first_block, block)) {
@@ -2204,13 +2204,13 @@ static void do_unfill()
    /* Now find and compare the last block */
    Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num,
          last_file, last_block_num);
-   if (!reposition_dev(dev, last_file, last_block_num)) {
-      Pmsg1(-1, _("Reposition error. ERR=%s\n"), strerror_dev(dev));
+   if (!dev->reposition(last_file, last_block_num)) {
+      Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
    if (!read_block_from_device(dcr, NO_BLOCK_NUMBER_CHECK)) {
-      Pmsg1(-1, _("Error reading block: ERR=%s\n"), strerror_dev(dev));
+      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    if (compare_blocks(last_block, block)) {
@@ -2337,7 +2337,7 @@ static int flush_block(DEV_BLOCK *block, int dump)
       } else {
          /* Full test in progress */
          if (!fixup_device_block_write_error(jcr->dcr)) {
-            Pmsg1(000, _("Cannot fixup device error. %s\n"), strerror_dev(dev));
+            Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror());
             ok = false;
             unlock_device(dev);
             return 0;
@@ -2765,7 +2765,3 @@ static void set_volume_name(const char *VolName, int volnum)
    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
    dcr->VolCatInfo.Slot = volnum;
 }
-
-VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
-bool    free_volume(DEVICE *dev) { return true; }
-void    free_unused_volume(DCR *dcr) { }
index f6b54c4107760e11efd166cb83fb4d3ed0d7c3db..44f190761fb94f402b2dc999697f9af5e8b9b579 100644 (file)
@@ -93,6 +93,7 @@ JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
    pm_strcpy(jcr->fileset_md5, "Dummy.fileset.md5");
 
    init_autochangers();
+   init_volume_list();
 
    dcr = setup_to_access_device(jcr, dev_name, VolumeName, mode);
    if (!dcr) {
index 820bd43dd10d78759225c60414b3d6e3240046f3..a00a6e25ea74af9c1b922601350f704d8525074a 100644 (file)
@@ -131,7 +131,6 @@ init_dev(JCR *jcr, DEVRES *device)
 
    dev = (DEVICE *)malloc(sizeof(DEVICE));
    memset(dev, 0, sizeof(DEVICE));
-   dev->state = ST_MALLOC;
 
    /* Copy user supplied device parameters from Resource */
    dev->dev_name = get_memory(strlen(device->device_name)+1);
@@ -139,6 +138,7 @@ init_dev(JCR *jcr, DEVRES *device)
    dev->prt_name = get_memory(strlen(device->device_name) + strlen(device->hdr.name) + 20);
    /* We edit "Resource-name" (physical-name) */
    Mmsg(dev->prt_name, "\"%s\" (%s)", device->hdr.name, device->device_name);
+   Dmsg1(400, "Allocate dev=%s\n", dev->print_name());
    dev->capabilities = device->cap_bits;
    dev->min_block_size = device->min_block_size;
    dev->max_block_size = device->max_block_size;
@@ -162,7 +162,9 @@ init_dev(JCR *jcr, DEVRES *device)
    if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
       dev->vol_poll_interval = 60;
    }
+   /* Link the dev and device structures together */
    dev->device = device;
+   device->dev = dev;
 
    if (dev->is_fifo()) {
       dev->capabilities |= CAP_STREAM; /* set stream device */
@@ -1391,41 +1393,40 @@ bool DEVICE::fsr(int num)
  *   Returns:  false on failure
  *             true  on success
  */
-bool
-bsr_dev(DEVICE *dev, int num)
+bool DEVICE::bsr(int num)
 {
    struct mtop mt_com;
    int stat;
 
-   if (dev->fd < 0) {
-      dev->dev_errno = EBADF;
-      Mmsg0(dev->errmsg, _("Bad call to bsr_dev. Device not open\n"));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+   if (fd < 0) {
+      dev_errno = EBADF;
+      Mmsg0(errmsg, _("Bad call to bsr_dev. Device not open\n"));
+      Emsg0(M_FATAL, 0, errmsg);
       return false;
    }
 
-   if (!dev->is_tape()) {
+   if (!is_tape()) {
       return false;
    }
 
-   if (!dev->has_cap(CAP_BSR)) {
-      Mmsg1(dev->errmsg, _("ioctl MTBSR not permitted on %s.\n"), dev->print_name());
+   if (!has_cap(CAP_BSR)) {
+      Mmsg1(errmsg, _("ioctl MTBSR not permitted on %s.\n"), print_name());
       return false;
    }
 
    Dmsg0(29, "bsr_dev\n");
-   dev->block_num -= num;
-   dev->state &= ~(ST_EOF|ST_EOT|ST_EOF);
+   block_num -= num;
+   state &= ~(ST_EOF|ST_EOT|ST_EOF);
    mt_com.mt_op = MTBSR;
    mt_com.mt_count = num;
-   stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
+   stat = ioctl(fd, MTIOCTOP, (char *)&mt_com);
    if (stat < 0) {
       berrno be;
-      clrerror_dev(dev, MTBSR);
-      Mmsg2(dev->errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"),
-         dev->print_name(), be.strerror());
+      clrerror_dev(this, MTBSR);
+      Mmsg2(errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"),
+         print_name(), be.strerror());
    }
-   update_pos_dev(dev);
+   update_pos_dev(this);
    return stat == 0;
 }
 
@@ -1434,59 +1435,58 @@ bsr_dev(DEVICE *dev, int num)
  * Returns: false on failure
  *          true  on success
  */
-bool
-reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
+bool DEVICE::reposition(uint32_t rfile, uint32_t rblock)
 {
-   if (dev->fd < 0) {
-      dev->dev_errno = EBADF;
-      Mmsg0(dev->errmsg, _("Bad call to reposition_dev. Device not open\n"));
-      Emsg0(M_FATAL, 0, dev->errmsg);
+   if (fd < 0) {
+      dev_errno = EBADF;
+      Mmsg0(errmsg, _("Bad call to reposition. Device not open\n"));
+      Emsg0(M_FATAL, 0, errmsg);
       return false;
    }
 
-   if (!dev->is_tape()) {
-      off_t pos = (((off_t)file)<<32) + (off_t)block;
+   if (!is_tape()) {
+      off_t pos = (((off_t)rfile)<<32) + (off_t)rblock;
       Dmsg1(100, "===== lseek_dev to %d\n", (int)pos);
-      if (lseek_dev(dev, pos, SEEK_SET) == (off_t)-1) {
+      if (lseek_dev(this, pos, SEEK_SET) == (off_t)-1) {
          berrno be;
-         dev->dev_errno = errno;
-         Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
-            dev->print_name(), be.strerror());
+         dev_errno = errno;
+         Mmsg2(errmsg, _("lseek_dev error on %s. ERR=%s.\n"),
+            print_name(), be.strerror());
          return false;
       }
-      dev->file = file;
-      dev->block_num = block;
-      dev->file_addr = pos;
+      file = rfile;
+      block_num = rblock;
+      file_addr = pos;
       return true;
    }
-   Dmsg4(100, "reposition_dev from %u:%u to %u:%u\n",
-      dev->file, dev->block_num, file, block);
-   if (file < dev->file) {
+   Dmsg4(100, "reposition from %u:%u to %u:%u\n",
+      file, block_num, rfile, rblock);
+   if (rfile < file) {
       Dmsg0(100, "Rewind\n");
-      if (!dev->rewind(NULL)) {
+      if (!rewind(NULL)) {
          return false;
       }
    }
-   if (file > dev->file) {
-      Dmsg1(100, "fsf %d\n", file-dev->file);
-      if (!dev->fsf(file-dev->file)) {
-         Dmsg1(100, "fsf failed! ERR=%s\n", strerror_dev(dev));
+   if (rfile > file) {
+      Dmsg1(100, "fsf %d\n", rfile-file);
+      if (!fsf(rfile-file)) {
+         Dmsg1(100, "fsf failed! ERR=%s\n", bstrerror());
          return false;
       }
-      Dmsg2(100, "wanted_file=%d at_file=%d\n", file, dev->file);
+      Dmsg2(100, "wanted_file=%d at_file=%d\n", rfile, file);
    }
-   if (block < dev->block_num) {
-      Dmsg2(100, "wanted_blk=%d at_blk=%d\n", block, dev->block_num);
+   if (rblock < block_num) {
+      Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num);
       Dmsg0(100, "bsf 1\n");
-      dev->bsf(1);
+      bsf(1);
       Dmsg0(100, "fsf_dev 1\n");
-      dev->fsf(1);
-      Dmsg2(100, "wanted_blk=%d at_blk=%d\n", block, dev->block_num);
+      fsf(1);
+      Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num);
    }
-   if (dev->has_cap(CAP_POSITIONBLOCKS) && block > dev->block_num) {
+   if (has_cap(CAP_POSITIONBLOCKS) && rblock > block_num) {
       /* Ignore errors as Bacula can read to the correct block */
-      Dmsg1(100, "fsr %d\n", block-dev->block_num);
-      return dev->fsr(block-dev->block_num);
+      Dmsg1(100, "fsr %d\n", rblock-block_num);
+      return fsr(rblock-block_num);
    }
    return true;
 }
@@ -1541,18 +1541,6 @@ weof_dev(DEVICE *dev, int num)
    return stat;
 }
 
-/*
- * Return string message with last error in English
- *  Be careful not to call this routine from within dev.c
- *  while editing an Mmsg() or you will end up in a recursive
- *  loop creating a Segmentation Violation.
- */
-char *
-strerror_dev(DEVICE *dev)
-{
-   return dev->errmsg;
-}
-
 
 /*
  * If implemented in system, clear the tape
@@ -1672,15 +1660,6 @@ clrerror_dev(DEVICE *dev, int func)
 #endif
 }
 
-/*
- * Flush buffer contents
- *  No longer used.
- */
-int flush_dev(DEVICE *dev)
-{
-   return 1;
-}
-
 /*
  * Close the device
  */
@@ -1999,41 +1978,35 @@ uint32_t dev_file(DEVICE *dev)
 /*
  * Free memory allocated for the device
  */
-void
-term_dev(DEVICE *dev)
+void DEVICE::term(void)
 {
-   if (!dev) {
-      dev->dev_errno = EBADF;
-      Mmsg0(dev->errmsg, _("Bad call to term_dev. Device not open\n"));
-      Emsg0(M_FATAL, 0, dev->errmsg);
-      return;
-   }
-   Dmsg1(29, "term_dev: %s\n", dev->print_name());
-   dev->close();
-   if (dev->dev_name) {
-      free_memory(dev->dev_name);
-      dev->dev_name = NULL;
-   }
-   if (dev->prt_name) {
-      free_memory(dev->prt_name);
-      dev->prt_name = NULL;
-   }
-   if (dev->errmsg) {
-      free_pool_memory(dev->errmsg);
-      dev->errmsg = NULL;
-   }
-   pthread_mutex_destroy(&dev->mutex);
-   pthread_cond_destroy(&dev->wait);
-   pthread_cond_destroy(&dev->wait_next_vol);
-   pthread_mutex_destroy(&dev->spool_mutex);
-   rwl_destroy(&dev->lock);
-   if (dev->attached_dcrs) {
-      delete dev->attached_dcrs;
-      dev->attached_dcrs = NULL;
-   }
-   if (dev->state & ST_MALLOC) {
-      free((char *)dev);
-   }
+   Dmsg1(900, "term dev: %s\n", print_name());
+   close();
+   if (dev_name) {
+      free_memory(dev_name);
+      dev_name = NULL;
+   }
+   if (prt_name) {
+      free_memory(prt_name);
+      prt_name = NULL;
+   }
+   if (errmsg) {
+      free_pool_memory(errmsg);
+      errmsg = NULL;
+   }
+   pthread_mutex_destroy(&mutex);
+   pthread_cond_destroy(&wait);
+   pthread_cond_destroy(&wait_next_vol);
+   pthread_mutex_destroy(&spool_mutex);
+   rwl_destroy(&lock);
+   if (attached_dcrs) {
+      delete attached_dcrs;
+      attached_dcrs = NULL;
+   }
+   if (device) {
+      device->dev = NULL;
+   }
+   free((char *)this);
 }
 
 /*
index 76e8cdfb48c6620d762e0a5b4f7ec8d00a7407d5..72a960704401acd6e0bbacb0c510f09d7380c625 100644 (file)
@@ -339,13 +339,15 @@ public:
    void clear_mounted() { state &= ~ST_MOUNTED; };
    void clear_media() { state &= ~ST_MEDIA; };
    void clear_short_block() { state &= ~ST_SHORT; };
-   void clear_freespace_ok() { state &= ~ST_FREESPACE_OK; }
+   void clear_freespace_ok() { state &= ~ST_FREESPACE_OK; };
+   char *bstrerror(void) { return errmsg; };
 
    void block(int why);          /* in dev.c */
    void unblock();               /* in dev.c */
    void close();                 /* in dev.c */
    bool truncate(DCR *dcr);      /* in dev.c */
    int open(DCR *dcr, int mode); /* in dev.c */
+   void term(void);              /* in dev.c */
    bool rewind(DCR *dcr);        /* in dev.c */
    bool mount(int timeout);      /* in dev.c */
    bool unmount(int timeout);    /* in dev.c */
@@ -356,7 +358,9 @@ public:
    bool eod();                   /* in dev.c */
    bool fsr(int num);            /* in dev.c */
    bool fsf(int num);            /* in dev.c */
+   bool bsr(int num);            /* in dev.c */
    bool scan_dir_for_volume(DCR *dcr); /* in scan.c */
+   bool reposition(uint32_t rfile, uint32_t rblock); /* in dev.c */
 
    void set_blocked(int block) { dev_blocked = block; };
    int  get_blocked() const { return dev_blocked; };
index a5b3dae44ead5c317fe06d149de8246d8c311652..30f6c403f6309a6ec211397ea79ff1236a62dff6 100644 (file)
@@ -293,9 +293,9 @@ bool open_device(DCR *dcr)
        * (when there is no DVD, or when the one inserted is a wrong one) */
       if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
-            dev->print_name(), strerror_dev(dev));
+            dev->print_name(), dev->bstrerror());
          Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"), 
-            dev->print_name(), strerror_dev(dev));
+            dev->print_name(), dev->bstrerror());
       }
       return false;
    }
index 5c6817972a85e8c85ce5b7c9a10d0ebd09d5be9a..a371688fe336aeed6cea6487d8323b5a531a23a3 100644 (file)
@@ -441,7 +441,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
    case VOL_IO_ERROR:
    case VOL_NO_LABEL:
       if (!write_new_volume_label_to_dev(dcr, newname, poolname)) {
-         bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
+         bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
          break;
       }
       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
@@ -450,7 +450,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
          newname, dev->print_name());
       break;
    case VOL_NO_MEDIA:
-      bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
+      bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
       break;
    default:
       bnet_fsend(dir, _("3913 Cannot label Volume. "
@@ -606,7 +606,7 @@ static bool mount_cmd(JCR *jcr)
             /* We freed the device, so reopen it and wake any waiting threads */
             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
-                  strerror_dev(dev));
+                  dev->bstrerror());
                if (dev->dev_blocked == BST_UNMOUNTED) {
                   /* We blocked the device, so unblock it */
                   Dmsg0(100, "Unmounted. Unblocking device\n");
@@ -659,7 +659,7 @@ static bool mount_cmd(JCR *jcr)
             } else if (dev->is_tape()) {
                if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
-                     strerror_dev(dev));
+                     dev->bstrerror());
                   break;
                }
                read_label(dcr);
@@ -676,7 +676,7 @@ static bool mount_cmd(JCR *jcr)
                   bnet_fsend(dir, _("3002 Device %s is mounted.\n"), 
                      dev->print_name());
                } else {
-                  bnet_fsend(dir, _("3907 %s"), strerror_dev(dev));
+                  bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
                } 
             } else { /* must be file */
                bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
index fd411fffaff6ddca6b05b39d110672fe49b6e5d4..828425691106fb5cf6cb87db20df1e0287a9bdf2 100644 (file)
@@ -703,7 +703,7 @@ bool dvd_close_job(DCR *dcr)
          update the part number. */
       if (ok && (dvd_open_next_part(dcr) < 0)) {
          Jmsg2(jcr, M_FATAL, 0, _("Unable to write part %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+               dev->print_name(), dev->bstrerror());
          dev->dev_errno = EIO;
          ok = false;
       }
index 72340278f83c366c8795e1ff6293fa2cd6538036..612c2b4b97a006f37f42662f464b238f4ff9855d 100644 (file)
@@ -102,7 +102,7 @@ int read_dev_volume_label(DCR *dcr)
 
    if (!dev->rewind(dcr)) {
       Mmsg(jcr->errmsg, _("Couldn't rewind device %s: ERR=%s\n"), 
-         dev->print_name(), strerror_dev(dev));
+         dev->print_name(), dev->bstrerror());
       Dmsg1(30, "return VOL_NO_MEDIA: %s", jcr->errmsg);
       return VOL_NO_MEDIA;
    }
@@ -141,14 +141,14 @@ int read_dev_volume_label(DCR *dcr)
    if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
       Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula "
            "labeled Volume, because: ERR=%s"), NPRT(VolName), 
-           dev->print_name(), strerror_dev(dev));
+           dev->print_name(), dev->bstrerror());
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (!read_record_from_block(block, record)) {
       Mmsg(jcr->errmsg, _("Could not read Volume label from block.\n"));
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (!unser_volume_label(dev, record)) {
       Mmsg(jcr->errmsg, _("Could not unserialize Volume label: ERR=%s\n"),
-         strerror_dev(dev));
+         dev->bstrerror());
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (strcmp(dev->VolHdr.Id, BaculaId) != 0 &&
               strcmp(dev->VolHdr.Id, OldBaculaId) != 0) {
@@ -309,7 +309,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
    if (!dev->rewind(dcr)) {
       free_volume(dev);
       memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
-      Dmsg2(30, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), strerror_dev(dev));
+      Dmsg2(30, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), dev->bstrerror());
       if (!forge_on) {
          goto bail_out;
       }
@@ -338,7 +338,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
    /* Temporarily mark in append state to enable writing */
    dev->set_append();
    if (!write_record_to_block(dcr->block, dcr->rec)) {
-      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), strerror_dev(dev));
+      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
       goto bail_out;
    } else {
       Dmsg2(30, "Wrote label of %d bytes to %s\n", dcr->rec->data_len, dev->print_name());
@@ -346,7 +346,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
 
    Dmsg0(99, "Call write_block_to_dev()\n");
    if (!write_block_to_dev(dcr)) {
-      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), strerror_dev(dev));
+      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
       goto bail_out;
    }
    Dmsg0(99, " Wrote block to device\n");
@@ -401,12 +401,12 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
    if (!dev_cap(dev, CAP_STREAM)) {
       if (!dev->rewind(dcr)) {
          Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+               dev->print_name(), dev->bstrerror());
       }
       if (recycle) {
          if (!dev->truncate(dcr)) {
             Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s: ERR=%s\n"),
-                  dev->print_name(), strerror_dev(dev));
+                  dev->print_name(), dev->bstrerror());
          }
       }
 
@@ -428,7 +428,7 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
       Dmsg1(200, "Attempt to write to device fd=%d.\n", dev->fd);
       if (!write_block_to_dev(dcr)) {
          Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s: ERR=%s\n"),
-            dev->print_name(), strerror_dev(dev));
+            dev->print_name(), dev->bstrerror());
          Dmsg0(200, "===ERROR write block to dev\n");
          return false;
       }
index 5e51f453f642a91e8bfc42d06e61c4ab8ce1c629..aedbf100b45d05dd2e53ac8651a45cc8cb705be3 100644 (file)
@@ -96,7 +96,7 @@ bail_out:
       /* Flush out final partial block of this session */
       if (!write_block_to_device(jcr->dcr)) {
          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+               dev->print_name(), dev->bstrerror());
          Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
          ok = false;
       }
@@ -172,9 +172,9 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       if (!write_block_to_device(jcr->dcr)) {
          DEVICE *dev = jcr->dcr->dev;
          Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
-            dev->print_name(), strerror_dev(dev));
+            dev->print_name(), dev->bstrerror());
          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+               dev->print_name(), dev->bstrerror());
          return false;
       }
    }
index 9387bc36129510339964336adebba880e5691dc8..8b86db484be6ff9e20f644f6155960e68700a10a 100644 (file)
@@ -335,7 +335,7 @@ read_volume:
          dcr->VolumeName);
       if (!dev->eod()) {
          Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"),
-            dev->print_name(), strerror_dev(dev));
+            dev->print_name(), dev->bstrerror());
          mark_volume_in_error(dcr);
          goto mount_next_vol;
       }
index c6eec08a18447a56cb80050d6c0290ad75dad6ec..1bd1fa37ba91c84068acccc326c26e66bfb2ad35 100755 (executable)
@@ -29,7 +29,7 @@ typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
 
 static BSR *store_vol(LEX *lc, BSR *bsr);
 static BSR *store_mediatype(LEX *lc, BSR *bsr);
-static BSR *store_storage(LEX *lc, BSR *bsr);
+static BSR *store_device(LEX *lc, BSR *bsr);
 static BSR *store_client(LEX *lc, BSR *bsr);
 static BSR *store_job(LEX *lc, BSR *bsr);
 static BSR *store_jobid(LEX *lc, BSR *bsr);
@@ -72,9 +72,9 @@ struct kw_items items[] = {
    {"exclude", store_exclude},
    {"volfile", store_volfile},
    {"volblock", store_volblock},
-   {"stream",  store_stream},
-   {"slot",    store_slot},
-   {"storage",    store_storage},
+   {"stream",   store_stream},
+   {"slot",     store_slot},
+   {"device",   store_device},
    {NULL, NULL}
 
 };
@@ -270,8 +270,8 @@ static BSR *store_mediatype(LEX *lc, BSR *bsr)
    return bsr;
 }
 
-/* Shove the Storage name in each Volume in the current bsr */
-static BSR *store_storage(LEX *lc, BSR *bsr)
+/* Shove the Device name in each Volume in the current bsr */
+static BSR *store_device(LEX *lc, BSR *bsr)
 {
    int token;
 
@@ -280,13 +280,13 @@ static BSR *store_storage(LEX *lc, BSR *bsr)
       return NULL;
    }
    if (!bsr->volume) {
-      Emsg1(M_ERROR,0, _("Storage %s in bsr at inappropriate place.\n"),
+      Emsg1(M_ERROR,0, _("Device \"%s\" in bsr at inappropriate place.\n"),
          lc->str);
       return bsr;
    }
    BSR_VOLUME *bv;
    for (bv=bsr->volume; bv; bv=bv->next) {
-      bstrncpy(bv->storage, lc->str, sizeof(bv->storage));
+      bstrncpy(bv->device, lc->str, sizeof(bv->device));
    }
    return bsr;
 }
@@ -707,7 +707,7 @@ void dump_volume(BSR_VOLUME *volume)
    if (volume) {
       Pmsg1(-1, _("VolumeName  : %s\n"), volume->VolumeName);
       Pmsg1(-1, _("  MediaType : %s\n"), volume->MediaType);
-      Pmsg1(-1, _("  Storage   : %s\n"), volume->storage);
+      Pmsg1(-1, _("  Device    : %s\n"), volume->device);
       Pmsg1(-1, _("  Slot      : %d\n"), volume->Slot);
       dump_volume(volume->next);
    }
@@ -904,7 +904,7 @@ void create_restore_volume_list(JCR *jcr)
             vol = new_restore_volume();
             bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName));
             bstrncpy(vol->MediaType,  bsrvol->MediaType,  sizeof(vol->MediaType));
-            bstrncpy(vol->storage, bsrvol->storage, sizeof(vol->storage));
+            bstrncpy(vol->device, bsrvol->device, sizeof(vol->device));
             vol->Slot = bsrvol->Slot;
             vol->start_file = sfile;
             if (add_restore_volume(jcr, vol)) {
index 9c8d3b4791638cca5f790465005dc507a3a31d3c..7b7da1390e08cbd97e4c2d317972b2c0ad06b6df 100644 (file)
@@ -23,7 +23,7 @@ uint32_t new_VolSessionId();
 
 /* From acquire.c */
 DCR     *acquire_device_for_append(DCR *dcr);
-DCR     *acquire_device_for_read(DCR *dcr);
+bool     acquire_device_for_read(DCR *dcr);
 bool     release_device(DCR *dcr);
 DCR     *new_dcr(JCR *jcr, DEVICE *dev);
 void     free_dcr(DCR *dcr);
@@ -98,11 +98,9 @@ uint32_t status_dev(DEVICE *dev);
 bool     eod_dev(DEVICE *dev);
 bool     fsf_dev(DEVICE *dev, int num);
 bool     bsf_dev(DEVICE *dev, int num);
-bool     bsr_dev(DEVICE *dev, int num);
 void     attach_jcr_to_device(DEVICE *dev, JCR *jcr);
 void     detach_jcr_from_device(DEVICE *dev, JCR *jcr);
 JCR     *next_attached_jcr(DEVICE *dev, JCR *jcr);
-bool     reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
 void     init_device_wait_timers(DCR *dcr);
 void     init_jcr_device_wait_timers(JCR *jcr);
 bool     double_dev_wait_time(DEVICE *dev);
@@ -221,6 +219,8 @@ void    list_volumes(BSOCK *user);
 bool    is_volume_in_use(DCR *dcr);
 void    send_drive_reserve_messages(JCR *jcr, BSOCK *user);
 bool    find_suitable_device_for_job(JCR *jcr, RCTX &rctx);
+int     search_res_for_device(RCTX &rctx);
+void    release_msgs(JCR *jcr);
 
 
 /* From spool.c */
index 633cea29fab810a996d16c2aedf65dcaafc8cd44..412b4a20b73e214a2f15ed4ad03b38479ee81663 100644 (file)
@@ -75,7 +75,7 @@ bool do_read_data(JCR *jcr)
    /* Send end of data to FD */
    bnet_sig(fd, BNET_EOD);
 
-   if (!release_device(dcr)) {
+   if (!release_device(jcr->read_dcr)) {
       ok = false;
    }
 
index c6e77c0f1aff0883a1721881e81a33bbbfa43a58..f450574132e785bd752de366be731631f27b92c6 100644 (file)
@@ -86,6 +86,11 @@ bool read_records(DCR *dcr,
                break;
             }
             jcr->mount_next_volume = false;
+            /*  
+             * The Device can change at the end of a tape, so refresh it
+             *   from the dcr.
+             */
+            dev = dcr->dev;
             /*
              * We just have a new tape up, now read the label (first record)
              *  and pass it off to the callback routine, then continue
@@ -280,7 +285,7 @@ static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev)
       Dmsg4(300, "Try_Reposition from (file:block) %u:%u to %u:%u\n",
             dev->file, dev->block_num, bsr->volfile->sfile,
             bsr->volblock->sblock);
-      reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
+      dev->reposition(bsr->volfile->sfile, bsr->volblock->sblock);
       rec->Block = 0;
    }
    return false;
@@ -304,7 +309,7 @@ static BSR *position_to_first_file(JCR *jcr, DEVICE *dev)
             bsr->volfile->sfile, bsr->volblock->sblock);
          Dmsg2(300, "Forward spacing to file:block %u:%u.\n",
             bsr->volfile->sfile, bsr->volblock->sblock);
-         reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
+         dev->reposition(bsr->volfile->sfile, bsr->volblock->sblock);
       }
    }
    return bsr;
index 362eccac70fcde422a4a69fec4f8430f305a107a..dd38158e44bc8b23a58d73682e8468f2af8a2f05 100644 (file)
@@ -33,13 +33,11 @@ static pthread_mutex_t search_lock = PTHREAD_MUTEX_INITIALIZER;
 
 /* Forward referenced functions */
 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
-static int search_res_for_device(RCTX &rctx);
 static int reserve_device(RCTX &rctx);
 static bool reserve_device_for_read(DCR *dcr);
 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
 static bool use_storage_cmd(JCR *jcr);
 static void queue_reserve_message(JCR *jcr);
-static void release_msgs(JCR *jcr);
 
 /* Requests from the Director daemon */
 static char use_storage[]  = "use storage=%127s media_type=%127s "
@@ -180,6 +178,7 @@ bail_out:
 void free_unused_volume(DCR *dcr)
 {
    VOLRES *vol;
+
    P(vol_list_lock);
    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
       if (vol->dcr == dcr && (vol->dev == NULL || 
@@ -342,6 +341,7 @@ static bool use_storage_cmd(JCR *jcr)
     */
    if (ok) {
       bool first = true;           /* print wait message once */
+      rctx.notify_dir = true;
       for ( ; !job_canceled(jcr); ) {
          P(search_lock);           /* only one thread at a time */
          while ((msg = (char *)msgs->pop())) {
@@ -450,11 +450,14 @@ all_done:
    return ok;
 }
 
-static void release_msgs(JCR *jcr)
+void release_msgs(JCR *jcr)
 {
    alist *msgs = jcr->reserve_msgs;
    char *msg;
 
+   if (!msgs) {
+      return;
+   }
    P(search_lock);
    while ((msg = (char *)msgs->pop())) {
       free(msg);
@@ -510,7 +513,7 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
  * Search for a particular storage device with particular storage
  *  characteristics (MediaType).
  */
-static int search_res_for_device(RCTX &rctx) 
+int search_res_for_device(RCTX &rctx) 
 {
    AUTOCHANGER *changer;
    BSOCK *dir = rctx.jcr->dir_bsock;
@@ -538,10 +541,14 @@ static int search_res_for_device(RCTX &rctx)
                Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
                   rctx.jcr->read_dcr->dev->reserved_device);
             }
-            pm_strcpy(dev_name, rctx.device->hdr.name);
-            bash_spaces(dev_name);
-            ok = bnet_fsend(dir, OK_device, dev_name.c_str());  /* Return real device name */
-            Dmsg1(100, ">dird changer: %s", dir->msg);
+            if (rctx.notify_dir) {
+               pm_strcpy(dev_name, rctx.device->hdr.name);
+               bash_spaces(dev_name);
+               ok = bnet_fsend(dir, OK_device, dev_name.c_str());  /* Return real device name */
+               Dmsg1(100, ">dird changer: %s", dir->msg);
+            } else {
+               ok = true;
+            }
             return ok ? 1 : -1;
          }
       }
@@ -557,10 +564,13 @@ static int search_res_for_device(RCTX &rctx)
             if (stat != 1) {
                return stat;
             }
-            Dmsg1(220, "Got: %s", dir->msg);
-            bash_spaces(rctx.device_name);
-            ok = bnet_fsend(dir, OK_device, rctx.device_name);
-            Dmsg1(100, ">dird dev: %s", dir->msg);
+            if (rctx.notify_dir) {
+               bash_spaces(rctx.device_name);
+               ok = bnet_fsend(dir, OK_device, rctx.device_name);
+               Dmsg1(100, ">dird dev: %s", dir->msg);
+            } else {
+               ok = true;
+            }
             return ok ? 1 : -1;
          }
       }
index 78e35c897b101d59357414e87d9972b6dd4bd9ee..38e77dbdc892f5e2700cec9f8d127232e731f8ca 100644 (file)
@@ -56,5 +56,6 @@ public:
    bool have_volume;                  /* Have DIR suggested vol name */
    bool suitable_device;              /* at least one device is suitable */
    bool autochanger_only;             /* look at autochangers only */
+   bool notify_dir;                   /* Notify DIR about device */
    char VolumeName[MAX_NAME_LENGTH];  /* Vol name suggested by DIR */
 };
index cd73dea27b6df7b41a0e040d8df0c1cfd43f6054..9cf930447b916eabdd81a7e5cd91efec16eb8e53 100644 (file)
@@ -246,7 +246,7 @@ static bool despool_data(DCR *dcr, bool commit)
       ok = write_block_to_device(dcr);
       if (!ok) {
          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
-               dcr->dev->print_name(), strerror_dev(dcr->dev));
+               dcr->dev->print_name(), dcr->dev->bstrerror());
       }
       Dmsg3(800, "Write block ok=%d FI=%d LI=%d\n", ok, block->FirstIndex, block->LastIndex);
    }
index 095a9ab2f437132d2521490227c4b4fed9f2541b..71d180a6bfd39c49648edda0ccc4efe1786b7c25 100644 (file)
@@ -449,7 +449,7 @@ void *device_initialization(void *arg)
 
    foreach_res(device, R_DEVICE) {
       Dmsg1(90, "calling init_dev %s\n", device->device_name);
-      device->dev = dev = init_dev(NULL, device);
+      dev = init_dev(NULL, device);
       Dmsg1(10, "SD init done %s\n", device->device_name);
       if (!dev) {
          Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name);
@@ -548,7 +548,8 @@ void terminate_stored(int sig)
       Dmsg1(10, "Term device %s\n", device->device_name);
       if (device->dev) {
          free_volume(device->dev);
-         term_dev(device->dev);
+         device->dev->term();
+         device->dev = NULL;
       } else {
          Dmsg1(10, "No dev structure %s\n", device->device_name);
       }
index 1b91bd96f789d35d4043a2dba892eacdbdfef927..0870424a324937ba02da22175e32f1da2e4c9bd9 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "1.39.5"
-#define BDATE   "14 February 2006"
-#define LSMDATE "14Feb06"
+#define BDATE   "20 February 2006"
+#define LSMDATE "20Feb06"
 
 /* Debug flags */
 #undef  DEBUG