]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix Vol info update + add Drive and InChanger to Media rec
authorKern Sibbald <kern@sibbald.com>
Sat, 15 Nov 2003 20:25:58 +0000 (20:25 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 15 Nov 2003 20:25:58 +0000 (20:25 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@807 91ce42f0-d328-0410-95d8-f526ca767f89

34 files changed:
bacula/kernstodo
bacula/scripts/bacula.in
bacula/src/baconfig.h
bacula/src/cats/cats.h
bacula/src/cats/sql_list.c
bacula/src/dird/catreq.c
bacula/src/dird/ua_output.c
bacula/src/lib/alist.h
bacula/src/lib/bnet.c
bacula/src/lib/jcr.c
bacula/src/lib/signal.c
bacula/src/lib/watchdog.c
bacula/src/stored/acquire.c
bacula/src/stored/askdir.c
bacula/src/stored/autochanger.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/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/dircmd.c
bacula/src/stored/label.c
bacula/src/stored/match_bsr.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/stored/stored.c
bacula/src/tools/.cvsignore
bacula/src/tools/Makefile.in
bacula/src/tools/bsmtp.c
bacula/src/version.h

index 61ac53862377cd47e2adb0ac57b7ef9183c53fc7..2dd8c85eb8d328ae877c7ef19215e584436abdab 100644 (file)
@@ -47,6 +47,13 @@ For 1.33 Testing/Documentation:
                 
 
 For 1.33
+- do a "messages" before the first prompt in Console
+- Add a date and time stamp at the beginning of every line in the 
+  Job report (Volker Sauer).
+- Client does not show busy during Estimate command.
+- Volume problems occurs if you have valid volume, written, then it is
+  truncated. You get 12-Nov-2003 11:48 rufus-sd: kernsave.2003-11-12_11.48.09 Warning: mount.c:228 Volume on /tmp is not a Bacula labeled Volume, because:
+     block.c:640 Read zero bytes on device /tmp.
 - Implement Console mtx commands.
 - Look at 2Gb limit for SQLite.
 - Implement 3 Pools for a Job:
index 2952141c860be53b4c50094ae483b90bc2a50f43..1fbd1a98eef87a7f0033588034b5b18f75320bc2 100755 (executable)
@@ -182,63 +182,64 @@ failure() {
 case "$1" in
     start)
        [ -x ${BACBIN}/bacula-sd ] && {
-          echo "Starting the Storage daemon"
-          OPTIONS=''
-          if [ "${SD_USER}" != '' ]; then
-             OPTIONS="${OPTIONS} -u ${SD_USER}"
-          fi
+         echo "Starting the Storage daemon"
+         OPTIONS=''
+         if [ "${SD_USER}" != '' ]; then
+            OPTIONS="${OPTIONS} -u ${SD_USER}"
+         fi
 
-          if [ "${SD_GROUP}" != '' ]; then
-             OPTIONS="${OPTIONS} -g ${SD_GROUP}"
-          fi
+         if [ "${SD_GROUP}" != '' ]; then
+            OPTIONS="${OPTIONS} -g ${SD_GROUP}"
+         fi
 
-          ${BACBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACCFG}/bacula-sd.conf
+         ${BACBIN}/bacula-sd $2 ${OPTIONS} -v -c ${BACCFG}/bacula-sd.conf
        }
 
        [ -x ${BACBIN}/bacula-fd ] && {
-          echo "Starting the File daemon"
-          OPTIONS=''
-          if [ "${FD_USER}" != '' ]; then
-             OPTIONS="${OPTIONS} -u ${FD_USER}"
-          fi
+         echo "Starting the File daemon"
+         OPTIONS=''
+         if [ "${FD_USER}" != '' ]; then
+            OPTIONS="${OPTIONS} -u ${FD_USER}"
+         fi
 
-          if [ "${FD_GROUP}" != '' ]; then
-             OPTIONS="${OPTIONS} -g ${FD_GROUP}"
-          fi
+         if [ "${FD_GROUP}" != '' ]; then
+            OPTIONS="${OPTIONS} -g ${FD_GROUP}"
+         fi
 
-          ${BACBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACCFG}/bacula-fd.conf
+         ${BACBIN}/bacula-fd $2 ${OPTIONS} -v -c ${BACCFG}/bacula-fd.conf
        }
 
        [ -x ${BACBIN}/bacula-dir ] && { 
-                  sleep 2
-                  echo "Starting the Director daemon"
-          OPTIONS=''
-          if [ "${DIR_USER}" != '' ]; then
-             OPTIONS="${OPTIONS} -u ${DIR_USER}"
-          fi
-
-          if [ "${DIR_GROUP}" != '' ]; then
-             OPTIONS="${OPTIONS} -g ${DIR_GROUP}"
-          fi
-
-          ${BACBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACCFG}/bacula-dir.conf
+          sleep 2
+          echo "Starting the Director daemon"
+         OPTIONS=''
+         if [ "${DIR_USER}" != '' ]; then
+            OPTIONS="${OPTIONS} -u ${DIR_USER}"
+         fi
+
+         if [ "${DIR_GROUP}" != '' ]; then
+            OPTIONS="${OPTIONS} -g ${DIR_GROUP}"
+         fi
+
+         ${BACBIN}/bacula-dir $2 ${OPTIONS} -v -c ${BACCFG}/bacula-dir.conf
        }
        ;;
 
     stop)
-       [ -x ${BACBIN}/bacula-sd ] && {
-          echo "Stopping the Storage daemon"
-          killproc ${BACBIN}/bacula-sd ${SD_PORT}
+       # Stop the FD first so that SD will fail jobs and update catalog
+       [ -x ${BACBIN}/bacula-fd ] && {
+         echo "Stopping the File daemon"
+         killproc ${BACBIN}/bacula-fd ${FD_PORT}
        }
 
-       [ -x ${BACBIN}/bacula-fd ] && {
-          echo "Stopping the File daemon"
-          killproc ${BACBIN}/bacula-fd ${FD_PORT}
+       [ -x ${BACBIN}/bacula-sd ] && {
+         echo "Stopping the Storage daemon"
+         killproc ${BACBIN}/bacula-sd ${SD_PORT}
        }
 
        [ -x ${BACBIN}/bacula-dir ] && {
-                 echo "Stopping the Director daemon"
-          killproc ${BACBIN}/bacula-dir ${DIR_PORT}
+         echo "Stopping the Director daemon"
+         killproc ${BACBIN}/bacula-dir ${DIR_PORT}
        }
        echo
        ;;
index 123f0128efc49300669d5fa3db2bec3d00f4cfb5..b9c6cd9719aa991451e76117d4f956ca2cb13ca0 100644 (file)
@@ -434,7 +434,7 @@ extern int thr_setconcurrency(int);
 
 #ifdef HAVE_DARWIN_OS
 /* Apparently someone forgot to wrap getdomainname as a C function */
-extern "C" int getdomainname(char *name, size_t len);
+extern "C" int getdomainname(char *name, int len);
 
 /* Darwin lib fnmatch() doesn't work, so use our own */
 #undef HAVE_FNMATCH
index f4746db3c8c4da074dffd8fde03ebddb1842d244..62eedfc3a1142bf995d54300500b58884e1e593f 100644 (file)
@@ -57,70 +57,70 @@ struct sqlite {
    char dummy;
 };
 
-#define IS_NUM(x)            ((x) == 1)
-#define IS_NOT_NULL(x)       ((x) == 1)
+#define IS_NUM(x)             ((x) == 1)
+#define IS_NOT_NULL(x)        ((x) == 1)
 
 typedef struct s_sql_field {
-   char *name;                       /* name of column */
-   uint32_t length;                  /* length */
-   uint32_t max_length;              /* max length */
-   uint32_t type;                    /* type */
-   uint32_t flags;                   /* flags */
+   char *name;                        /* name of column */
+   uint32_t length;                   /* length */
+   uint32_t max_length;               /* max length */
+   uint32_t type;                     /* type */
+   uint32_t flags;                    /* flags */
 } SQL_FIELD;
 
 /*
  * This is the "real" definition that should only be
  * used inside sql.c and associated database interface
  * subroutines.
- *                   S Q L I T E
+ *                    S Q L I T E
  */
 typedef struct s_db {
-   BQUEUE bq;                        /* queue control */
-   brwlock_t lock;                   /* transaction lock */
+   BQUEUE bq;                         /* queue control */
+   brwlock_t lock;                    /* transaction lock */
    struct sqlite *db;
    char **result;
-   int nrow;                         /* nrow returned from sqlite */
-   int ncolumn;                      /* ncolum returned from sqlite */
-   int num_rows;                     /* used by code */
-   int row;                          /* seek row */
-   int have_insert_id;               /* do not have insert id */
-   int fields_defined;               /* set when fields defined */
-   int field;                        /* seek field */
-   SQL_FIELD **fields;               /* defined fields */
+   int nrow;                          /* nrow returned from sqlite */
+   int ncolumn;                       /* ncolum returned from sqlite */
+   int num_rows;                      /* used by code */
+   int row;                           /* seek row */
+   int have_insert_id;                /* do not have insert id */
+   int fields_defined;                /* set when fields defined */
+   int field;                         /* seek field */
+   SQL_FIELD **fields;                /* defined fields */
    int ref_count;
    char *db_name;
    char *db_user;
-   char *db_address;                 /* host name address */
-   char *db_socket;                  /* socket for local access */
+   char *db_address;                  /* host name address */
+   char *db_socket;                   /* socket for local access */
    char *db_password;
-   int db_port;                      /* port for host name address */
+   int  db_port;                      /* port for host name address */
    int connected;
-   char *sqlite_errmsg;              /* error message returned by sqlite */
-   POOLMEM *errmsg;                  /* nicely edited error message */
-   POOLMEM *cmd;                     /* SQL command string */
-   POOLMEM *cached_path;             /* cached path name */
-   int cached_path_len;              /* length of cached path */
-   uint32_t cached_path_id;          /* cached path id */
-   int transaction;                  /* transaction started */
-   int changes;                      /* changes during transaction */
-   POOLMEM *fname;                   /* Filename only */
-   POOLMEM *path;                    /* Path only */
-   POOLMEM *esc_name;                /* Escaped file/path name */
-   int fnl;                          /* file name length */
-   int pnl;                          /* path name length */
+   char *sqlite_errmsg;               /* error message returned by sqlite */
+   POOLMEM *errmsg;                   /* nicely edited error message */
+   POOLMEM *cmd;                      /* SQL command string */
+   POOLMEM *cached_path;              /* cached path name */
+   int cached_path_len;               /* length of cached path */
+   uint32_t cached_path_id;           /* cached path id */
+   int transaction;                   /* transaction started */
+   int changes;                       /* changes during transaction */
+   POOLMEM *fname;                    /* Filename only */
+   POOLMEM *path;                     /* Path only */
+   POOLMEM *esc_name;                 /* Escaped file/path name */
+   int fnl;                           /* file name length */
+   int pnl;                           /* path name length */
 } B_DB;
 
 
 /* 
  * "Generic" names for easier conversion   
  *
- *                   S Q L I T E
+ *                    S Q L I T E
  */
 #define sql_store_result(x)   x->result
 #define sql_free_result(x)    my_sqlite_free_table(x)
 #define sql_fetch_row(x)      my_sqlite_fetch_row(x)
 #define sql_query(x, y)       my_sqlite_query(x, y)
-#define sql_close(x)         sqlite_close((x)->db)  
+#define sql_close(x)          sqlite_close((x)->db)  
 #define sql_strerror(x)       (x)->sqlite_errmsg?(x)->sqlite_errmsg:"unknown"
 #define sql_num_rows(x)       (x)->nrow
 #define sql_data_seek(x, i)   (x)->row = i
@@ -129,7 +129,7 @@ typedef struct s_db {
 #define sql_field_seek(x, y)  my_sqlite_field_seek(x, y)
 #define sql_fetch_field(x)    my_sqlite_fetch_field(x)
 #define sql_num_fields(x)     (unsigned)((x)->ncolumn)
-#define SQL_ROW              char**   
+#define SQL_ROW               char**   
 
 
 
@@ -151,11 +151,11 @@ extern void my_sqlite_free_table(B_DB *mdb);
  * used inside sql.c and associated database interface
  * subroutines.
  *
- *                    M Y S Q L
+ *                     M Y S Q L
  */
 typedef struct s_db {
-   BQUEUE bq;                        /* queue control */
-   brwlock_t lock;                   /* transaction lock */
+   BQUEUE bq;                         /* queue control */
+   brwlock_t lock;                    /* transaction lock */
    MYSQL mysql;
    MYSQL *db;
    MYSQL_RES *result;
@@ -164,22 +164,22 @@ typedef struct s_db {
    char *db_name;
    char *db_user;
    char *db_password;
-   char *db_address;                 /* host address */
-   char *db_socket;                  /* socket for local access */
-   int db_port;                      /* port of host address */
-   int have_insert_id;               /* do have insert_id() */
+   char *db_address;                  /* host address */
+   char *db_socket;                   /* socket for local access */
+   int db_port;                       /* port of host address */
+   int have_insert_id;                /* do have insert_id() */
    int connected;
-   POOLMEM *errmsg;                  /* nicely edited error message */
-   POOLMEM *cmd;                     /* SQL command string */
+   POOLMEM *errmsg;                   /* nicely edited error message */
+   POOLMEM *cmd;                      /* SQL command string */
    POOLMEM *cached_path;
-   int cached_path_len;              /* length of cached path */
+   int cached_path_len;               /* length of cached path */
    uint32_t cached_path_id;
-   int changes;                      /* changes made to db */
-   POOLMEM *fname;                   /* Filename only */
-   POOLMEM *path;                    /* Path only */
-   POOLMEM *esc_name;                /* Escaped file/path name */
-   int fnl;                          /* file name length */
-   int pnl;                          /* path name length */
+   int changes;                       /* changes made to db */
+   POOLMEM *fname;                    /* Filename only */
+   POOLMEM *path;                     /* Path only */
+   POOLMEM *esc_name;                 /* Escaped file/path name */
+   int fnl;                           /* file name length */
+   int pnl;                           /* path name length */
 } B_DB;
 
 
@@ -188,7 +188,7 @@ typedef struct s_db {
 #define sql_free_result(x)    mysql_free_result((x)->result)
 #define sql_fetch_row(x)      mysql_fetch_row((x)->result)
 #define sql_query(x, y)       mysql_query((x)->db, y)
-#define sql_close(x)         mysql_close((x)->db)  
+#define sql_close(x)          mysql_close((x)->db)  
 #define sql_strerror(x)       mysql_error((x)->db)
 #define sql_num_rows(x)       mysql_num_rows((x)->result)
 #define sql_data_seek(x, i)   mysql_data_seek((x)->result, i)
@@ -197,8 +197,8 @@ typedef struct s_db {
 #define sql_field_seek(x, y)  mysql_field_seek((x)->result, y)
 #define sql_fetch_field(x)    mysql_fetch_field((x)->result)
 #define sql_num_fields(x)     mysql_num_fields((x)->result)
-#define SQL_ROW              MYSQL_ROW
-#define SQL_FIELD            MYSQL_FIELD
+#define SQL_ROW               MYSQL_ROW
+#define SQL_FIELD             MYSQL_FIELD
 
 #else  /* USE BACULA DB routines */
 
@@ -207,17 +207,17 @@ typedef struct s_db {
 /* Change this each time there is some incompatible
  * file format change!!!!
  */
-#define BDB_VERSION 12               /* file version number */
+#define BDB_VERSION 12                /* file version number */
 
 struct s_control {
-   int bdb_version;                  /* Version number */
-   uint32_t JobId;                   /* next Job Id */
-   uint32_t PoolId;                  /* next Pool Id */
-   uint32_t MediaId;                 /* next Media Id */
-   uint32_t JobMediaId;              /* next JobMedia Id */
-   uint32_t ClientId;                /* next Client Id */
-   uint32_t FileSetId;               /* nest FileSet Id */
-   time_t time;                      /* time file written */
+   int bdb_version;                   /* Version number */
+   uint32_t JobId;                    /* next Job Id */
+   uint32_t PoolId;                   /* next Pool Id */
+   uint32_t MediaId;                  /* next Media Id */
+   uint32_t JobMediaId;               /* next JobMedia Id */
+   uint32_t ClientId;                 /* next Client Id */
+   uint32_t FileSetId;                /* nest FileSet Id */
+   time_t time;                       /* time file written */
 };
 
 
@@ -225,23 +225,23 @@ struct s_control {
  *  Bacula internal DB
  */
 typedef struct s_db {
-   BQUEUE bq;                        /* queue control */
-/* pthread_mutex_t mutex;  */        /* single thread lock */
-   brwlock_t lock;                   /* transaction lock */
-   int ref_count;                    /* number of times opened */
-   struct s_control control;         /* control file structure */
-   int cfd;                          /* control file device */
-   FILE *jobfd;                      /* Jobs records file descriptor */
-   FILE *poolfd;                     /* Pool records fd */
-   FILE *mediafd;                    /* Media records fd */
-   FILE *jobmediafd;                 /* JobMedia records fd */
-   FILE *clientfd;                   /* Client records fd */
-   FILE *filesetfd;                  /* FileSet records fd */
-   char *db_name;                    /* name of database */
-   POOLMEM *errmsg;                  /* nicely edited error message */
-   POOLMEM *cmd;                     /* Command string */
+   BQUEUE bq;                         /* queue control */
+/* pthread_mutex_t mutex;  */         /* single thread lock */
+   brwlock_t lock;                    /* transaction lock */
+   int ref_count;                     /* number of times opened */
+   struct s_control control;          /* control file structure */
+   int cfd;                           /* control file device */
+   FILE *jobfd;                       /* Jobs records file descriptor */
+   FILE *poolfd;                      /* Pool records fd */
+   FILE *mediafd;                     /* Media records fd */
+   FILE *jobmediafd;                  /* JobMedia records fd */
+   FILE *clientfd;                    /* Client records fd */
+   FILE *filesetfd;                   /* FileSet records fd */
+   char *db_name;                     /* name of database */
+   POOLMEM *errmsg;                   /* nicely edited error message */
+   POOLMEM *cmd;                      /* Command string */
    POOLMEM *cached_path;
-   int cached_path_len;              /* length of cached path */
+   int cached_path_len;               /* length of cached path */
    uint32_t cached_path_id;
 } B_DB;
 
@@ -255,12 +255,12 @@ typedef struct s_db {
 #define DELETE_DB(jcr, db, cmd) DeleteDB(__FILE__, __LINE__, jcr, db, cmd)
 
 
-#else   /* not __SQL_C */
+#else    /* not __SQL_C */
 
 /* This is a "dummy" definition for use outside of sql.c
  */
-typedef struct s_db {    
-   int dummy;                        /* for SunOS compiler */
+typedef struct s_db {     
+   int dummy;                         /* for SunOS compiler */
 } B_DB;  
 
 #endif /*  __SQL_C */
@@ -269,7 +269,7 @@ extern uint32_t bacula_db_version;
 
 /* ***FIXME*** FileId_t should be uint64_t */
 typedef uint32_t FileId_t;
-typedef uint32_t DBId_t;             /* general DB id type */
+typedef uint32_t DBId_t;              /* general DB id type */
 typedef uint32_t JobId_t;
       
 #define faddr_t long
@@ -283,18 +283,18 @@ typedef uint32_t JobId_t;
 /* Job record */
 struct JOB_DBR {
    JobId_t JobId;
-   char Job[MAX_NAME_LENGTH];        /* Job unique name */
-   char Name[MAX_NAME_LENGTH];       /* Job base name */
-   int Type;                         /* actually char(1) */
-   int Level;                        /* actually char(1) */
-   int JobStatus;                    /* actually char(1) */
-   uint32_t ClientId;                /* Id of client */
-   uint32_t PoolId;                  /* Id of pool */
-   uint32_t FileSetId;               /* Id of FileSet */
-   time_t SchedTime;                 /* Time job scheduled */
-   time_t StartTime;                 /* Job start time */
-   time_t EndTime;                   /* Job termination time */
-   utime_t JobTDate;                 /* Backup time/date in seconds */
+   char Job[MAX_NAME_LENGTH];         /* Job unique name */
+   char Name[MAX_NAME_LENGTH];        /* Job base name */
+   int Type;                          /* actually char(1) */
+   int Level;                         /* actually char(1) */
+   int JobStatus;                     /* actually char(1) */
+   uint32_t ClientId;                 /* Id of client */
+   uint32_t PoolId;                   /* Id of pool */
+   uint32_t FileSetId;                /* Id of FileSet */
+   time_t SchedTime;                  /* Time job scheduled */
+   time_t StartTime;                  /* Job start time */
+   time_t EndTime;                    /* Job termination time */
+   utime_t JobTDate;                  /* Backup time/date in seconds */
    uint32_t VolSessionId;
    uint32_t VolSessionTime;
    uint32_t JobFiles;
@@ -305,8 +305,8 @@ struct JOB_DBR {
    /* Note, FirstIndex, LastIndex, Start/End File and Block
     * are only used in the JobMedia record.
     */
-   uint32_t FirstIndex;              /* First index this Volume */
-   uint32_t LastIndex;               /* Last index this Volume */
+   uint32_t FirstIndex;               /* First index this Volume */
+   uint32_t LastIndex;                /* Last index this Volume */
    uint32_t StartFile;
    uint32_t EndFile;
    uint32_t StartBlock;
@@ -324,28 +324,28 @@ struct JOB_DBR {
  */
 /* JobMedia record */
 struct JOBMEDIA_DBR {
-   uint32_t JobMediaId;              /* record id */
-   JobId_t  JobId;                   /* JobId */
-   uint32_t MediaId;                 /* MediaId */
-   uint32_t FirstIndex;              /* First index this Volume */
-   uint32_t LastIndex;               /* Last index this Volume */
-   uint32_t StartFile;               /* File for start of data */
-   uint32_t EndFile;                 /* End file on Volume */
-   uint32_t StartBlock;              /* start block on tape */
-   uint32_t EndBlock;                /* last block */
+   uint32_t JobMediaId;               /* record id */
+   JobId_t  JobId;                    /* JobId */
+   uint32_t MediaId;                  /* MediaId */
+   uint32_t FirstIndex;               /* First index this Volume */
+   uint32_t LastIndex;                /* Last index this Volume */
+   uint32_t StartFile;                /* File for start of data */
+   uint32_t EndFile;                  /* End file on Volume */
+   uint32_t StartBlock;               /* start block on tape */
+   uint32_t EndBlock;                 /* last block */
 };
 
 
 /* Volume Parameter structure */
 struct VOL_PARAMS {
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
-   uint32_t VolIndex;                /* Volume seqence no. */ 
-   uint32_t FirstIndex;              /* First index this Volume */
-   uint32_t LastIndex;               /* Last index this Volume */
-   uint32_t StartFile;               /* File for start of data */
-   uint32_t EndFile;                 /* End file on Volume */
-   uint32_t StartBlock;              /* start block on tape */
-   uint32_t EndBlock;                /* last block */
+   uint32_t VolIndex;                 /* Volume seqence no. */ 
+   uint32_t FirstIndex;               /* First index this Volume */
+   uint32_t LastIndex;                /* Last index this Volume */
+   uint32_t StartFile;                /* File for start of data */
+   uint32_t EndFile;                  /* End file on Volume */
+   uint32_t StartBlock;               /* start block on tape */
+   uint32_t EndBlock;                 /* last block */
 };
 
 
@@ -354,9 +354,9 @@ struct VOL_PARAMS {
  *  records (e.g. pathname, filename, fileattributes).
  */
 struct ATTR_DBR {
-   char *fname;                      /* full path & filename */
-   char *link;                       /* link if any */
-   char *attr;                       /* attributes statp */
+   char *fname;                       /* full path & filename */
+   char *link;                        /* link if any */
+   char *attr;                        /* attributes statp */
    uint32_t FileIndex;
    uint32_t Stream;
    JobId_t  JobId;
@@ -378,26 +378,26 @@ struct FILE_DBR {
    char LStat[256];
 /*   int Status; */
    char SIG[50];
-   int SigType;                      /* NO_SIG/MD5_SIG/SHA1_SIG */
+   int SigType;                       /* NO_SIG/MD5_SIG/SHA1_SIG */
 };
 
 /* Pool record -- same format as database */
 struct POOL_DBR {
    uint32_t PoolId;
-   char Name[MAX_NAME_LENGTH];       /* Pool name */
-   uint32_t NumVols;                 /* total number of volumes */
-   uint32_t MaxVols;                 /* max allowed volumes */
-   int UseOnce;                      /* set to use once only */
-   int UseCatalog;                   /* set to use catalog */
-   int AcceptAnyVolume;              /* set to accept any volume sequence */
-   int AutoPrune;                    /* set to prune automatically */
-   int Recycle;                      /* default Vol recycle flag */
-   utime_t  VolRetention;            /* retention period in seconds */
-   utime_t  VolUseDuration;          /* time in secs volume can be used */
-   uint32_t MaxVolJobs;              /* Max Jobs on Volume */
-   uint32_t MaxVolFiles;             /* Max files on Volume */
-   uint64_t MaxVolBytes;             /* Max bytes on Volume */
-   char PoolType[MAX_NAME_LENGTH];            
+   char Name[MAX_NAME_LENGTH];        /* Pool name */
+   uint32_t NumVols;                  /* total number of volumes */
+   uint32_t MaxVols;                  /* max allowed volumes */
+   int32_t UseOnce;                   /* set to use once only */
+   int32_t UseCatalog;                /* set to use catalog */
+   int32_t AcceptAnyVolume;           /* set to accept any volume sequence */
+   int32_t AutoPrune;                 /* set to prune automatically */
+   int32_t Recycle;                   /* default Vol recycle flag */
+   utime_t  VolRetention;             /* retention period in seconds */
+   utime_t  VolUseDuration;           /* time in secs volume can be used */
+   uint32_t MaxVolJobs;               /* Max Jobs on Volume */
+   uint32_t MaxVolFiles;              /* Max files on Volume */
+   uint64_t MaxVolBytes;              /* Max bytes on Volume */
+   char PoolType[MAX_NAME_LENGTH];             
    char LabelFormat[MAX_NAME_LENGTH];
    /* Extra stuff not in DB */
    faddr_t rec_addr;
@@ -405,34 +405,36 @@ struct POOL_DBR {
 
 /* Media record -- same as the database */
 struct MEDIA_DBR {
-   uint32_t MediaId;                 /* Unique volume id */
+   uint32_t MediaId;                  /* Unique volume id */
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    char MediaType[MAX_NAME_LENGTH];   /* Media type */
-   uint32_t PoolId;                  /* Pool id */
-   time_t   FirstWritten;            /* Time Volume first written */
-   time_t   LastWritten;             /* Time Volume last written */
-   time_t   LabelDate;               /* Date/Time Volume labeled */
-   uint32_t VolJobs;                 /* number of jobs on this medium */
-   uint32_t VolFiles;                /* Number of files */
-   uint32_t VolBlocks;               /* Number of blocks */
-   uint32_t VolMounts;               /* Number of times mounted */
-   uint32_t VolErrors;               /* Number of read/write errors */
-   uint32_t VolWrites;               /* Number of writes */
-   uint32_t VolReads;                /* Number of reads */
-   uint64_t VolBytes;                /* Number of bytes written */
-   uint64_t MaxVolBytes;             /* Max bytes to write to Volume */
-   uint64_t VolCapacityBytes;        /* capacity estimate */
-   utime_t  VolRetention;            /* Volume retention in seconds */
-   utime_t  VolUseDuration;          /* time in secs volume can be used */
-   uint32_t MaxVolJobs;              /* Max Jobs on Volume */
-   uint32_t MaxVolFiles;             /* Max files on Volume */
-   int     Recycle;                  /* recycle yes/no */
-   int32_t  Slot;                    /* slot in changer */
-   char VolStatus[20];               /* Volume status */
+   uint32_t PoolId;                   /* Pool id */
+   time_t   FirstWritten;             /* Time Volume first written */
+   time_t   LastWritten;              /* Time Volume last written */
+   time_t   LabelDate;                /* Date/Time Volume labeled */
+   uint32_t VolJobs;                  /* number of jobs on this medium */
+   uint32_t VolFiles;                 /* Number of files */
+   uint32_t VolBlocks;                /* Number of blocks */
+   uint32_t VolMounts;                /* Number of times mounted */
+   uint32_t VolErrors;                /* Number of read/write errors */
+   uint32_t VolWrites;                /* Number of writes */
+   uint32_t VolReads;                 /* Number of reads */
+   uint64_t VolBytes;                 /* Number of bytes written */
+   uint64_t MaxVolBytes;              /* Max bytes to write to Volume */
+   uint64_t VolCapacityBytes;         /* capacity estimate */
+   utime_t  VolRetention;             /* Volume retention in seconds */
+   utime_t  VolUseDuration;           /* time in secs volume can be used */
+   uint32_t MaxVolJobs;               /* Max Jobs on Volume */
+   uint32_t MaxVolFiles;              /* Max files on Volume */
+   int32_t  Recycle;                  /* recycle yes/no */
+   int32_t  Slot;                     /* slot in changer */
+   int32_t  Drive;                    /* drive in changer */
+   int32_t  InChanger;                /* Volume currently in changer */
+   char VolStatus[20];                /* Volume status */
    /* Extra stuff not in DB */
-   faddr_t rec_addr;                 /* found record address */
+   faddr_t rec_addr;                  /* found record address */
    /* Since the database returns times as strings, this is how we pass
-    *  them back.
+    *   them back.
     */
    char    cFirstWritten[MAX_TIME_LENGTH];  /* FirstWritten returned from DB */
    char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
@@ -441,12 +443,12 @@ struct MEDIA_DBR {
 
 /* Client record -- same as the database */
 struct CLIENT_DBR {
-   uint32_t ClientId;                /* Unique Client id */
+   uint32_t ClientId;                 /* Unique Client id */
    int AutoPrune;
    utime_t FileRetention;
    utime_t JobRetention;
-   char Name[MAX_NAME_LENGTH];       /* Client name */
-   char Uname[256];                  /* Uname for client */
+   char Name[MAX_NAME_LENGTH];        /* Client name */
+   char Uname[256];                   /* Uname for client */
 };
 
 /* Counter record as in database */
@@ -461,16 +463,16 @@ struct COUNTER_DBR {
 
 /* FileSet record -- same as the database */
 struct FILESET_DBR {
-   uint32_t FileSetId;               /* Unique FileSet id */
+   uint32_t FileSetId;                /* Unique FileSet id */
    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
-   char MD5[50];                     /* MD5 signature of include/exclude */
-   time_t CreateTime;                /* date created */
+   char MD5[50];                      /* MD5 signature of include/exclude */
+   time_t CreateTime;                 /* date created */
    /*
     * This is where we return CreateTime
     */
    char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
    /* Not in DB but returned by db_create_fileset() */
-   bool created;                     /* set when record newly created */
+   bool created;                      /* set when record newly created */
 };
 
 
index c74a41a4bdba01e5f18b18d8de400620d4e4aab0..8637c5c7b4cfa1dee6ff5f1e4ae65a3ddf05d5bd 100644 (file)
@@ -151,12 +151,12 @@ db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
       }
    } else {
       if (mdbr->VolumeName[0] != 0) {
-         Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,MediaType,VolStatus,"
-            "VolBytes,LastWritten,VolRetention,Recycle,Slot "
+         Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,"
+            "VolBytes,VolFiles,VolRetention,Recycle,Slot,MediaType,LastWritten "
             "FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
       } else {
-         Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,MediaType,VolStatus,"
-            "VolBytes,LastWritten,VolRetention,Recycle,Slot "
+         Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,"
+            "VolBytes,VolFiles,VolRetention,Recycle,Slot,MediaType,LastWritten "
             "FROM Media WHERE Media.PoolId=%u ORDER BY MediaId", mdbr->PoolId);
       }
    }
index db060bedefa87ce2ca1eec035a435a210ac022d5..b8b7ebd525dcc677e5fa599d8c5512a92d945a59 100644 (file)
@@ -47,7 +47,7 @@ static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d
 static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s\
  VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%" lld " VolMounts=%u\
  VolErrors=%u VolWrites=%u MaxVolBytes=%" lld " EndTime=%d VolStatus=%10s\
- Slot=%d relabel=%d\n";
+ Slot=%d relabel=%d Drive=%d InChanger=%d\n";
 
 static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia \
  FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u \
@@ -55,15 +55,33 @@ static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia \
 
 
 /* Responses  sent to Storage daemon */
-static char OK_media[] = "1000 OK VolName=%s VolJobs=%u VolFiles=%u\
- VolBlocks=%u VolBytes=%s VolMounts=%u VolErrors=%u VolWrites=%u\
- MaxVolBytes=%s VolCapacityBytes=%s VolStatus=%s Slot=%d\
MaxVolJobs=%u MaxVolFiles=%u\n";
+static char OK_media[] = "1000 OK VolName=%s VolJobs=%u VolFiles=%u"
+   " VolBlocks=%u VolBytes=%s VolMounts=%u VolErrors=%u VolWrites=%u"
+   " MaxVolBytes=%s VolCapacityBytes=%s VolStatus=%s Slot=%d"
  " MaxVolJobs=%u MaxVolFiles=%u Drive=%d InChanger=%d\n";
 
-static char OK_update[] = "1000 OK UpdateMedia\n";
+static char OK_create[] = "1000 OK CreateJobMedia\n";
 
-/* static char FileAttributes[] = "UpdCat Job=%127s FileAttributes "; */
 
+static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr) 
+{
+   int stat;
+   char ed1[50], ed2[50], ed3[50];
+
+   jcr->MediaId = mr->MediaId;
+   pm_strcpy(&jcr->VolumeName, mr->VolumeName);
+   bash_spaces(mr->VolumeName);
+   stat = bnet_fsend(sd, OK_media, mr->VolumeName, mr->VolJobs,
+      mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
+      mr->VolMounts, mr->VolErrors, mr->VolWrites, 
+      edit_uint64(mr->MaxVolBytes, ed2), 
+      edit_uint64(mr->VolCapacityBytes, ed3),
+      mr->VolStatus, mr->Slot, mr->MaxVolJobs, mr->MaxVolFiles,
+      mr->Drive, mr->InChanger);
+   unbash_spaces(mr->VolumeName);
+   Dmsg2(100, "Vol Info for %s: %s", jcr->Job, sd->msg);
+   return stat;
+}
 
 void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
 {
@@ -87,17 +105,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
        * Send Find Media response to Storage daemon 
        */
       if (ok) {
-        char ed1[50], ed2[50], ed3[50];
-        jcr->MediaId = mr.MediaId;
-        pm_strcpy(&jcr->VolumeName, mr.VolumeName);
-        bash_spaces(mr.VolumeName);
-        bnet_fsend(bs, OK_media, mr.VolumeName, mr.VolJobs,
-           mr.VolFiles, mr.VolBlocks, edit_uint64(mr.VolBytes, ed1),
-           mr.VolMounts, mr.VolErrors, mr.VolWrites, 
-           edit_uint64(mr.MaxVolBytes, ed2), 
-           edit_uint64(mr.VolCapacityBytes, ed3),
-           mr.VolStatus, mr.Slot, mr.MaxVolJobs, mr.MaxVolFiles);
-         Dmsg2(100, "Find media for %s: %s", jcr->Job, bs->msg);
+        send_volume_info_to_storage_daemon(jcr, bs, &mr);
       } else {
          bnet_fsend(bs, "1901 No Media.\n");
       }
@@ -113,9 +121,6 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       unbash_spaces(mr.VolumeName);
       if (db_get_media_record(jcr, jcr->db, &mr)) {
         char *reason = NULL;         /* detailed reason for rejection */
-        jcr->MediaId = mr.MediaId;
-         Dmsg1(120, "VolumeInfo MediaId=%d\n", jcr->MediaId);
-        pm_strcpy(&jcr->VolumeName, mr.VolumeName);
         /*                   
          * If we are reading, accept any volume (reason == NULL)
          * If we are writing, check if the Volume is valid 
@@ -151,18 +156,10 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
            }
         }
         if (reason == NULL) {
-           char ed1[50], ed2[50], ed3[50];
            /*
             * Send Find Media response to Storage daemon 
             */
-           bash_spaces(mr.VolumeName);
-           bnet_fsend(bs, OK_media, mr.VolumeName, mr.VolJobs,
-              mr.VolFiles, mr.VolBlocks, edit_uint64(mr.VolBytes, ed1),
-              mr.VolMounts, mr.VolErrors, mr.VolWrites, 
-              edit_uint64(mr.MaxVolBytes, ed2), 
-              edit_uint64(mr.VolCapacityBytes, ed3),
-              mr.VolStatus, mr.Slot, mr.MaxVolJobs, mr.MaxVolFiles);
-            Dmsg2(100, "Vol Info for %s: %s", jcr->Job, bs->msg);
+           send_volume_info_to_storage_daemon(jcr, bs, &mr);
         } else { 
            /* Not suitable volume */
             bnet_fsend(bs, "1998 Volume \"%s\" status is %s, %s.\n", mr.VolumeName, 
@@ -182,7 +179,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
    } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName, &sdmr.VolJobs,
       &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes, &sdmr.VolMounts, &sdmr.VolErrors,
       &sdmr.VolWrites, &sdmr.MaxVolBytes, &sdmr.LastWritten, &sdmr.VolStatus, 
-      &sdmr.Slot, &label) == 14) {
+      &sdmr.Slot, &label, &sdmr.Drive, &sdmr.InChanger) == 16) {
 
       db_lock(jcr->db);
       Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName,
@@ -215,23 +212,26 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
       mr.VolErrors   = sdmr.VolErrors;
       mr.VolWrites   = sdmr.VolWrites;
       mr.LastWritten = sdmr.LastWritten;
+      mr.Slot       = sdmr.Slot;
+      mr.Drive      = sdmr.Drive;
+      mr.InChanger   = sdmr.InChanger;
       bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
-      mr.Slot = sdmr.Slot;
 
       Dmsg2(200, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
       /*
-       * Write the modified record to the DB
+       * Check if it has expired, and if not update the DB. Note, if
+       *   Volume has expired, has_volume_expired() will update the DB.
        */
-      if (db_update_media_record(jcr, jcr->db, &mr)) {
-        bnet_fsend(bs, OK_update);
-         Dmsg0(190, "send OK\n");
+      if (has_volume_expired(jcr, &mr)) {
+        send_volume_info_to_storage_daemon(jcr, bs, &mr);
+      } else if (db_update_media_record(jcr, jcr->db, &mr)) {
+        send_volume_info_to_storage_daemon(jcr, bs, &mr);
       } else {
          Jmsg(jcr, M_ERROR, 0, _("Catalog error updating Media record. %s"),
            db_strerror(jcr->db));
          bnet_fsend(bs, "1992 Update Media error\n");
          Dmsg0(190, "send error\n");
       }
-      has_volume_expired(jcr, &mr);   /* if expired, change Media record */
       db_unlock(jcr->db);
 
    /*
@@ -251,7 +251,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg)
          bnet_fsend(bs, "1991 Update JobMedia error\n");
       } else {
          Dmsg0(100, "JobMedia record created\n");
-        bnet_fsend(bs, OK_update);
+        bnet_fsend(bs, OK_create);
       }
 
    } else {
index 05cee1db5912e960575e28cfb7fbadcfbe5005c1..31a91f36ac3c21e886f68f50aeb5958b1fa25c2d 100644 (file)
@@ -304,7 +304,7 @@ static int do_list_cmd(UAContext *ua, char *cmd, e_list_type llist)
       /* List MEDIA or VOLUMES */
       } else if (strcasecmp(ua->argk[i], _("media")) == 0 ||
                  strcasecmp(ua->argk[i], _("volumes")) == 0) {
-        int done = FALSE;
+        bool done = false;
         for (j=i+1; j<ua->argc; j++) {
             if (strcasecmp(ua->argk[j], _("job")) == 0 && ua->argv[j]) {
               bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
@@ -320,7 +320,7 @@ static int do_list_cmd(UAContext *ua, char *cmd, e_list_type llist)
            n = db_get_job_volume_names(ua->jcr, ua->db, jobid, &VolumeName);
             bsendmsg(ua, _("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName);
            free_pool_memory(VolumeName);
-           done = TRUE;
+           done = true;
         }
         /* if no job or jobid keyword found, then we list all media */
         if (!done) {
index 03ab5e3e91e0b160f1bcedc9bf3615836b2e75ca..8b6755405b4c73eb2819a8b0722938f90e7d8619 100644 (file)
@@ -20,6 +20,8 @@
    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
    MA 02111-1307, USA.
 
+   Kern Sibbald, June MMIII
+
  */
 
 /* 
@@ -52,7 +54,7 @@ inline void * alist::operator [](int index) const {
    return items[index];
 }
 
-/*                           
+/*                            
  * This allows us to do explicit initialization,
  *   allowing us to mix C++ classes inside malloc'ed
  *   C structures. Define before called in constructor.
index 0e04ffa22403280e2eeefc0c0a9d8e2382e053eb..c319f7c2cc656e5dd6d197d673dc5f94fc415708 100644 (file)
@@ -61,6 +61,7 @@ static int32_t read_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
         errno = 0;
         nread = read(bsock->fd, ptr, nleft);    
         if (bsock->timed_out || bsock->terminated) {
+            Dmsg1(000, "timed_out = %d\n", bsock->timed_out);
            return nread;
         }
       } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
@@ -474,6 +475,50 @@ bnet_wait_data_intr(BSOCK *bsock, int sec)
    }
 }
 
+#ifndef NETDB_INTERNAL
+#define NETDB_INTERNAL -1      /* See errno. */
+#endif
+#ifndef NETDB_SUCCESS
+#define NETDB_SUCCESS  0       /* No problem. */
+#endif
+#ifndef HOST_NOT_FOUND
+#define HOST_NOT_FOUND 1       /* Authoritative Answer Host not found. */
+#endif
+#ifndef TRY_AGAIN
+#define TRY_AGAIN      2       /* Non-Authoritative Host not found, or SERVERFAIL. */
+#endif
+#ifndef NO_RECOVERY
+#define NO_RECOVERY    3       /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
+#endif
+#ifndef NO_DATA
+#define NO_DATA        4       /* Valid name, no data record of requested type. */
+#endif
+
+extern int h_errno;            /* On error has one of the above */
+
+/*
+ * Get human readable error for gethostbyname()
+ */
+static char *gethost_strerror() 
+{
+   switch (h_errno) {
+   case NETDB_INTERNAL:
+      return strerror(errno);
+   case NETDB_SUCCESS:
+      return "No problem.";
+   case HOST_NOT_FOUND:
+      return "Authoritative answer Host not found.";
+   case TRY_AGAIN:
+      return "Non-authoritative Host not found, or ServerFail.";
+   case NO_RECOVERY:
+      return "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
+   case NO_DATA:
+      return "Valid name, no data record of resquested type.";
+   default:
+      return "Unknown error.";
+   }
+}
+
 
 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -497,7 +542,7 @@ static uint32_t *bget_host_ip(JCR *jcr, char *host)
       P(ip_mutex);
       if ((hp = gethostbyname(host)) == NULL) {
          Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for %s failed: ERR=%s\n", 
-              host, strerror(errno));
+              host, gethost_strerror());
         V(ip_mutex);
         return NULL;
       }
@@ -512,7 +557,7 @@ Wanted %d got %d bytes for s_addr.\n"), sizeof(inaddr.s_addr), hp->h_length);
         i++;
       }
       i++;
-      addr_list = (uint32_t *) malloc(sizeof(uint32_t) * i);
+      addr_list = (uint32_t *)malloc(sizeof(uint32_t) * i);
       i = 0;
       for (p = hp->h_addr_list; *p != 0; p++) {
         addr_list[i++] = (*(struct in_addr **)p)->s_addr;
index ad80a10cef707748f4ba579c44679d9e9a6d18ae..ee884d16345cae809c59e92af571a616dc55d157 100755 (executable)
@@ -189,7 +189,7 @@ void free_jcr(JCR *jcr)
 
    P(mutex);
    jcr->use_count--;                 /* decrement use count */
-   Dmsg2(200, "Dec jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
+   Dmsg3(200, "Dec jcr 0x%x use_count=%d jobid=%d\n", jcr, jcr->use_count, jcr->JobId);
    if (jcr->use_count > 0) {         /* if in use */
       V(mutex);
       Dmsg2(200, "jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
@@ -198,6 +198,7 @@ void free_jcr(JCR *jcr)
    remove_jcr(jcr);
    V(mutex);
 
+   Dmsg1(200, "End job=%d\n", jcr->JobId);
    if (jcr->daemon_free_jcr) {
       jcr->daemon_free_jcr(jcr);      /* call daemon free routine */
    }
index aea28d9453212b1757fbd4dfd33e1d128e829212..4561f4664cad1fb205c74f4768287b1273897d70 100644 (file)
@@ -65,6 +65,7 @@ static void signal_handler(int sig)
    if (already_dead) {
       _exit(1);
    }
+   Dmsg1(200, "sig=%d\n", sig);
    /* Ignore certain signals */
    if (sig == SIGCHLD || sig == SIGUSR2) {
       return;
@@ -138,7 +139,7 @@ static void signal_handler(int sig)
         waitpid(pid, NULL, 0);       /* wait for child to produce dump */
          fprintf(stderr, "Traceback complete, attempting cleanup ...\n");
          Dmsg0(500, "Done waitpid\n");
-        exit_handler(1);             /* clean up if possible */
+        exit_handler(sig);           /* clean up if possible */
          Dmsg0(500, "Done exit_handler\n");
       } else {
          Dmsg0(500, "Doing sleep\n");
@@ -148,7 +149,7 @@ static void signal_handler(int sig)
    }
 #endif
 
-   exit_handler(1);
+   exit_handler(sig);
 }
 
 /*
index 93ba92cee1114bfa5cc5f836ce72b42974d8306b..14fda2273b566fd3b420e4bbe555b994509f5568 100755 (executable)
@@ -133,6 +133,7 @@ static void *btimer_thread(void *arg)
         if (fd) {
            timer_start = fd->timer_start;
            if (timer_start && (watchdog_time - timer_start) > fd->timeout) {
+              fd->timer_start = 0;   /* turn off timer */
               fd->timed_out = TRUE;
               Jmsg(jcr, M_ERROR, 0, _(
 "Watchdog sending kill after %d secs to thread stalled reading Storage daemon.\n"),
@@ -144,6 +145,7 @@ static void *btimer_thread(void *arg)
         if (fd) {
            timer_start = fd->timer_start;
            if (timer_start && (watchdog_time - timer_start) > fd->timeout) {
+              fd->timer_start = 0;   /* turn off timer */
               fd->timed_out = TRUE;
               Jmsg(jcr, M_ERROR, 0, _(
 "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n"),
@@ -155,6 +157,7 @@ static void *btimer_thread(void *arg)
         if (fd) {
            timer_start = fd->timer_start;
            if (timer_start && (watchdog_time - timer_start) > fd->timeout) {
+              fd->timer_start = 0;   /* turn off timer */
               fd->timed_out = TRUE;
               Jmsg(jcr, M_ERROR, 0, _(
 "Watchdog sending kill after %d secs to thread stalled reading Director.\n"),
index 44e00b6bd7397ff1c76b306b08f6ccad263e81ae..85e1aef4aa611e6570ae6113ba0991696935f8a8 100644 (file)
@@ -53,17 +53,18 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    block_device(dev, BST_DOING_ACQUIRE);
    unlock_device(dev);
 
-   tape_previously_mounted = (dev->state & ST_READ) || (dev->state & ST_APPEND);
+   tape_previously_mounted = dev_state(dev, ST_READ) || dev_state(dev, ST_APPEND);
 
-   if (dev->state & ST_READ || dev->num_writers > 0) {
-      Jmsg1(jcr, M_FATAL, 0, _("Device %s is busy. Job canceled.\n"), dev_name(dev));
+   if (dev_state(dev, ST_READ) || dev->num_writers > 0) {
+      Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"), 
+           dev_name(dev), jcr->JobId);
       goto get_out;
    }
 
    /* Find next Volume, if any */
    vol = jcr->VolList;
    if (!vol) {
-      Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job canceled.\n"));
+      Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job %d canceled.\n"), jcr->JobId);
       goto get_out;
    }
    jcr->CurVolume++;
@@ -74,7 +75,7 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 
    for (i=0; i<5; i++) {
       if (job_canceled(jcr)) {
-         Mmsg0(&dev->errmsg, _("Job canceled.\n"));
+         Mmsg1(&dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
         goto get_out;                /* error return */
       }
       /*
@@ -178,7 +179,7 @@ DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    Dmsg1(190, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
             
 
-   if (dev->state & ST_APPEND) {
+   if (dev_state(dev, ST_APPEND)) {
       /* 
        * Device already in append mode  
        *
@@ -198,7 +199,7 @@ DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
            for ( ; d; d=d->next) {
               open_vols++;
            }
-           if (dev->state & ST_FILE && dev->max_open_vols > open_vols) {
+           if (dev_state(dev, ST_FILE) && dev->max_open_vols > open_vols) {
               d = init_dev(NULL, (DEVRES *)dev->device); /* init new device */
               d->prev = dev;                   /* chain in new device */
               d->next = dev->next;
@@ -235,7 +236,7 @@ DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
        }
    } else { 
       /* Not already in append mode, so mount the device */
-      if (dev->state & ST_READ) {
+      if (dev_state(dev, ST_READ)) {
          Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
         goto get_out;
       } 
@@ -245,8 +246,11 @@ DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 
    if (do_mount || recycle) {
       if (!mount_next_write_volume(jcr, dev, block, release)) {
-         Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
-           dev_name(dev));
+        if (!job_canceled(jcr)) {
+            /* Reduce "noise" -- don't print if job canceled */
+            Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
+              dev_name(dev));
+        }
         goto get_out;
       }
    }
@@ -279,7 +283,7 @@ int release_device(JCR *jcr, DEVICE *dev)
 {
    lock_device(dev);
    Dmsg1(100, "release_device device is %s\n", dev_is_tape(dev)?"tape":"disk");
-   if (dev->state & ST_READ) {
+   if (dev_state(dev, ST_READ)) {
       dev->state &= ~ST_READ;        /* clear read bit */
       if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) {
         offline_or_rewind_dev(dev);
@@ -288,11 +292,12 @@ int release_device(JCR *jcr, DEVICE *dev)
       /******FIXME**** send read volume usage statistics to director */
 
    } else if (dev->num_writers > 0) {
+      ASSERT(dev_state(dev, ST_APPEND));
       dev->num_writers--;
       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
       if (dev->num_writers == 0) {
         /* If we are the only writer, write EOF after job */
-        if (dev->state & ST_LABEL) {
+        if (dev_state(dev, ST_LABEL)) {
             Dmsg0(100, "dir_create_jobmedia_record. Release\n");
            if (!dir_create_jobmedia_record(jcr)) {
                Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
@@ -301,34 +306,32 @@ int release_device(JCR *jcr, DEVICE *dev)
            if (dev_can_write(dev)) {
               weof_dev(dev, 1);
            }
-           dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
            dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
            /* Note! do volume update before close, which zaps VolCatInfo */
-            Dmsg0(200, "dir_update_vol_info. Release0\n");
-           dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */
+            Dmsg0(100, "dir_update_vol_info. Release0\n");
+           dir_update_volume_info(jcr, dev, 0); /* send Volume info to Director */
         }
 
         if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) {
            offline_or_rewind_dev(dev);
            close_dev(dev);
         }
-      } else if (dev->state & ST_LABEL) {
+      } else if (dev_state(dev, ST_LABEL)) {
          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
         if (!dir_create_jobmedia_record(jcr)) {
             Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
               jcr->VolCatInfo.VolCatName, jcr->Job);
         }
-         Dmsg0(200, "dir_update_vol_info. Release1\n");
-        dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
+         Dmsg0(100, "dir_update_vol_info. Release1\n");
         dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
-        dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */
+        dir_update_volume_info(jcr, dev, 0); /* send Volume info to Director */
       }
    } else {
       Jmsg2(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s, Volume \"%s\" not in use.\n"), 
            dev_name(dev), NPRT(jcr->VolumeName));
    }
    detach_jcr_from_device(dev, jcr);
-   if (dev->prev && !(dev->state & ST_READ) && dev->num_writers == 0) {
+   if (dev->prev && !dev_state(dev, ST_READ) && dev->num_writers == 0) {
       P(mutex);
       unlock_device(dev);
       dev->prev->next = dev->next;    /* dechain */
index 392640505c6c631f133089d316c4836cc5126532..c89a91e213f08434d5be7917cb53221e48fcbbd8 100644 (file)
 /* Requests sent to the Director */
 static char Find_media[]   = "CatReq Job=%s FindMedia=%d\n";
 static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n";
-static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s\
- VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u\
- VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%d VolStatus=%s\
- Slot=%d relabel=%d\n";
-
-static char Create_job_media[] = "CatReq Job=%s CreateJobMedia \
- FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u \
- StartBlock=%u EndBlock=%u\n";
+static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s"
+   " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u"
+   " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%d VolStatus=%s"
+   " Slot=%d relabel=%d Drive=%d InChanger=%d\n";
+static char Create_job_media[] = "CatReq Job=%s CreateJobMedia" 
+   " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u" 
+   " StartBlock=%u EndBlock=%u\n";
 static char FileAttributes[] = "UpdCat Job=%s FileAttributes ";
 static char Job_status[]     = "3012 Job %s jobstatus %d\n";
 
 
 /* Responses received from the Director */
-static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%u\
- VolBlocks=%u VolBytes=%" lld " VolMounts=%u VolErrors=%u VolWrites=%u\
- MaxVolBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s\
- Slot=%d MaxVolJobs=%u MaxVolFiles=%u\n";
-static char OK_update[] = "1000 OK UpdateMedia\n";
+static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%u"
+   " VolBlocks=%u VolBytes=%" lld " VolMounts=%u VolErrors=%u VolWrites=%u"
+   " MaxVolBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s"
+   " Slot=%d MaxVolJobs=%u MaxVolFiles=%u Drive=%d InChanger=%d";
+
+static char OK_create[] = "1000 OK CreateJobMedia\n";
 
 /* Forward referenced functions */
 static int wait_for_sysop(JCR *jcr, DEVICE *dev, int wait_sec);
@@ -67,8 +67,11 @@ int dir_send_job_status(JCR *jcr)
  *   dir_get_volume_info()
  * and
  *   dir_find_next_appendable_volume()
+ * 
+ *  Returns: 1 on success and vol info in jcr->VolCatInfo
+ *          0 on failure
  */
-static int do_request_volume_info(JCR *jcr)
+static int do_get_volume_info(JCR *jcr)
 {
     BSOCK *dir = jcr->dir_bsock;
     VOLUME_CAT_INFO vol;
@@ -86,10 +89,11 @@ static int do_request_volume_info(JCR *jcr)
               &vol.VolCatMounts, &vol.VolCatErrors,
               &vol.VolCatWrites, &vol.VolCatMaxBytes,
               &vol.VolCatCapacityBytes, vol.VolCatStatus,
-              &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles) != 14) {
+              &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles,
+              &vol.Drive, &vol.InChanger) != 16) {
 
        Dmsg1(200, "Bad response from Dir: %s\n", dir->msg);
-       Mmsg(&jcr->errmsg, _("Error scanning Dir response: %s\n"), dir->msg);
+       Mmsg(&jcr->errmsg, _("Error getting Volume info: %s\n"), dir->msg);
        return 0;
     }
     unbash_spaces(vol.VolCatName);
@@ -121,7 +125,7 @@ int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing)
     bash_spaces(jcr->VolCatInfo.VolCatName);
     bnet_fsend(dir, Get_Vol_Info, jcr->Job, jcr->VolCatInfo.VolCatName, 
        writing==GET_VOL_INFO_FOR_WRITE?1:0);
-    return do_request_volume_info(jcr);
+    return do_get_volume_info(jcr);
 }
 
 
@@ -140,7 +144,7 @@ int dir_find_next_appendable_volume(JCR *jcr)
 
     Dmsg0(200, "dir_find_next_appendable_volume\n");
     bnet_fsend(dir, Find_media, jcr->Job, 1);
-    return do_request_volume_info(jcr);
+    return do_get_volume_info(jcr);
 }
 
     
@@ -148,16 +152,28 @@ int dir_find_next_appendable_volume(JCR *jcr)
  * After writing a Volume, send the updated statistics
  * back to the director.
  */
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int label)
+int dir_update_volume_info(JCR *jcr, DEVICE *dev, int label)
 {
    BSOCK *dir = jcr->dir_bsock;
    time_t EndTime = time(NULL);
    char ed1[50], ed2[50];
+   VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
 
    if (vol->VolCatName[0] == 0) {
       Jmsg0(jcr, M_ERROR, 0, _("NULL Volume name. This shouldn't happen!!!\n"));
       return 0;
    }
+   if (dev_state(dev, ST_READ)) {
+      Jmsg0(jcr, M_ERROR, 0, _("Attempt to update_volume_info in read mode!!!\n"));
+      return 0;
+   }
+   if (!dev_state(dev, ST_LABEL)) {
+      Jmsg0(jcr, M_ERROR, 0, _("Attempt to update_volume_info on non-labeled Volume!!!\n"));
+      return 0;
+   }
+
+   dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
+   Dmsg1(100, "Update cat VolFiles=%d\n", dev->file);
    /* Just labeled or relabeled the tape */
    if (label) {
       bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
@@ -169,22 +185,17 @@ int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int label)
       vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1),
       vol->VolCatMounts, vol->VolCatErrors,
       vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2), 
-      EndTime, vol->VolCatStatus, vol->Slot, label);
+      EndTime, vol->VolCatStatus, vol->Slot, label, vol->Drive, 
+      vol->InChanger);
    Dmsg1(120, "update_volume_data(): %s", dir->msg);
    unbash_spaces(vol->VolCatName);
-   if (bnet_recv(dir) <= 0) {
-      Dmsg0(190, "updateVolCatInfo error bnet_recv\n");
-      Jmsg(jcr, M_ERROR, 0, _("Error updating Volume info Vol=\"%s\": ERR=%s\n"), 
-          vol->VolCatName, bnet_strerror(dir));
-      return 0;
-   }
-   Dmsg1(120, "Updatevol: %s", dir->msg);
-   if (strcmp(dir->msg, OK_update) != 0) {
-      Dmsg1(130, "Bad response from Dir: %s\n", dir->msg);
-      Jmsg(jcr, M_ERROR, 0, _("Error updating Volume info Vol=\"%s\": %s\n"), 
-          vol->VolCatName, dir->msg);
+
+   if (!do_get_volume_info(jcr)) {
+      Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
       return 0;
    }
+   /* Update dev Volume info in case something changed (e.g. expired) */
+   memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo));
    return 1;
 }
 
@@ -212,7 +223,7 @@ int dir_create_jobmedia_record(JCR *jcr)
       return 0;
    }
    Dmsg1(120, "Create_jobmedia: %s", dir->msg);
-   if (strcmp(dir->msg, OK_update) != 0) {
+   if (strcmp(dir->msg, OK_create) != 0) {
       Dmsg1(130, "Bad response from Dir: %s\n", dir->msg);
       Jmsg(jcr, M_ERROR, 0, _("Error creating JobMedia record: %s\n"), dir->msg);
       return 0;
index a6a19870c99d6ffdf73302358d91e91f6a7caa7c..f9f269d1f4e04ae6dfe62046e8a32d26d0010b1b 100644 (file)
@@ -128,14 +128,19 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir)
    return rtn_stat;
 }
 
-void invalidate_slot_in_catalog(JCR *jcr)
+/*
+ * The Volume is not in the correct slot, so mark this 
+ *   Volume as not being in the Changer.
+ */
+void invalid_slot_in_catalog(JCR *jcr, DEVICE *dev)
 {
    Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n"
 "    Setting slot to zero in catalog.\n"),
        jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot);
-   jcr->VolCatInfo.Slot = 0; /* invalidate slot */
-   Dmsg0(200, "update vol info in mount\n");
-   dir_update_volume_info(jcr, &jcr->VolCatInfo, 1);  /* set slot */
+   jcr->VolCatInfo.InChanger = false;
+   dev->VolCatInfo.InChanger = false;
+   Dmsg0(100, "update vol info in mount\n");
+   dir_update_volume_info(jcr, dev, 1);  /* set new status */
 }
 
 /*
index fc9452c16a2c0d620f6ddbd8f1c6d565d6f2bc8f..9efa2a796503d7b98dee654daa37afe120b821fe 100644 (file)
@@ -254,7 +254,7 @@ static int record_cb(JCR *in_jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw  writing) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
+int    dir_update_volume_info(JCR *jcr, DEVICE *dev, int relabel) { return 1; }
 int    dir_create_jobmedia_record(JCR *jcr) { return 1; }
 int    dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; }
 int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
index 3b8d4794fdde839bcc0d1048305fff84f4d13171..1ac47c0700736eaea88c63f7ab05577f7f723e1f 100644 (file)
@@ -435,7 +435,7 @@ static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw  writing) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
+int    dir_update_volume_info(JCR *jcr, DEVICE *dev, int relabel) { return 1; }
 int    dir_create_jobmedia_record(JCR *jcr) { return 1; }
 int    dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; }
 int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
index e815e3cd8b4e2060dffe315cff0357991d2d2895..cecb013f57f217f2802c09cb4fa10cca492ddf97 100644 (file)
@@ -411,13 +411,16 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
            edit_uint64(max_cap, ed1),  dev->dev_name);
       block->write_failed = true;
       weof_dev(dev, 1);              /* end the tape */
+      /* Don't do update after second EOF or file count will be wrong */
+      Dmsg0(100, "dir_update_volume_info\n");
+      dir_update_volume_info(jcr, dev, 0);
       weof_dev(dev, 1);
       dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
       return 0;   
    }
 
    /* Limit maximum File size on volume to user specified value */
-   if (dev->state & ST_TAPE) {
+   if (dev_state(dev, ST_TAPE)) {
       if ((dev->max_file_size > 0) && 
          (dev->file_addr+block->binbuf) >= dev->max_file_size) {
 
@@ -426,10 +429,14 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
            block->write_failed = true;
            dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
+            Dmsg0(100, "dir_update_volume_info\n");
+           dir_update_volume_info(jcr, dev, 0);
            return 0;   
         }
 
         /* Do bookkeeping to handle EOF just written */
+         Dmsg0(100, "dir_update_volume_info\n");
+        dir_update_volume_info(jcr, dev, 0);
         if (!dir_create_jobmedia_record(jcr)) {
              Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
                  jcr->VolCatInfo.VolCatName, jcr->Job);
@@ -443,7 +450,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
            if (mjcr->JobId == 0) {
               continue;                 /* ignore console */
            }
-           mjcr->NewFile = true;
+           mjcr->NewFile = true;     /* set reminder to do set_new_file_params */
         }
         set_new_file_parameters(jcr, dev);
       }
@@ -485,6 +492,8 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 
       block->write_failed = true;
       weof_dev(dev,1);
+      Dmsg0(100, "dir_update_volume_info\n");
+      dir_update_volume_info(jcr, dev, 0);
       if (weof_dev(dev, 1) != 0) {        /* end the tape */
          Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
       }
@@ -552,7 +561,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    block->BlockNumber++;
 
    /* Update jcr values */
-   if (dev->state & ST_TAPE) {
+   if (dev_state(dev, ST_TAPE)) {
       jcr->EndBlock = dev->EndBlock;
       jcr->EndFile  = dev->EndFile;
    } else {
@@ -621,7 +630,7 @@ reread:
         dev->VolCatInfo.VolCatErrors++;   
       }
    } while (stat == -1 && (errno == EINTR || errno == EIO) && retry++ < 11);
-// Dmsg1(000, "read stat = %d\n", stat);
+// Dmsg1(100, "read stat = %d\n", stat);
    if (stat < 0) {
       Dmsg1(90, "Read device got: ERR=%s\n", strerror(errno));
       clrerror_dev(dev, -1);
index 6d26549f71cf091775af918eb8563672eefeb274..350d7b79110f461c3b13eff6368c88fd2e3ffcf4 100644 (file)
@@ -398,7 +398,7 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw  writing) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
+int    dir_update_volume_info(JCR *jcr, DEVICE *dev, int relabel) { return 1; }
 int    dir_create_jobmedia_record(JCR *jcr) { return 1; }
 int    dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; }
 int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
index 56f311f6bee713bfefcba76d454b049ef15bec5f..198325246512954c05943788aadba82950261df7 100644 (file)
@@ -1111,7 +1111,7 @@ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId)
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw  writing) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
+int    dir_update_volume_info(JCR *jcr, DEVICE *dev, int relabel) { return 1; }
 int    dir_create_jobmedia_record(JCR *jcr) { return 1; }
 int    dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) { return 1; }
 int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
index 445fd4667879fec70adc4b002ae78e7e4712356f..39df9d4911c754e4119da0d83d46e422b5d387d5 100644 (file)
@@ -1788,7 +1788,7 @@ get_cmd(char *prompt)
 
 /* Dummies to replace askdir.c */
 int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw  writing) { return 1;}
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
+int    dir_update_volume_info(JCR *jcr, DEVICE *dev, int relabel) { return 1; }
 int    dir_create_jobmedia_record(JCR *jcr) { return 1; }
 int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}
 int    dir_send_job_status(JCR *jcr) {return 1;}
index 997020c89c1c503bd76cfb26e08a49ed333049bd..f8e2f395eb296be03ac40c50e4727a58c8fca7d4 100644 (file)
@@ -1012,7 +1012,7 @@ weof_dev(DEVICE *dev, int num)
       return -1;
    }
 
-   if (!(dev->state & ST_TAPE)) {
+   if (!(dev_state(dev, ST_TAPE))) {
       return 0;
    }
    dev->state &= ~(ST_EOT | ST_EOF);  /* remove EOF/EOT flags */
index 797fa441b68dae7c631d65aa4c5c18cb0c70e753..53969ba5aa482ea536d93db56b0e73f4e27134c7 100644 (file)
@@ -125,6 +125,8 @@ struct VOLUME_CAT_INFO {
    uint64_t VolCatRBytes;             /* Number of bytes read */
    uint32_t VolCatRecycles;           /* Number of recycles this volume */
    int32_t  Slot;                     /* Slot in changer */
+   int32_t  Drive;                    /* Changer drive */
+   bool     InChanger;                /* Set if vol in current magazine */
    uint32_t VolCatMaxJobs;            /* Maximum Jobs to write to volume */
    uint32_t VolCatMaxFiles;           /* Maximum files to write to volume */
    uint64_t VolCatMaxBytes;           /* Max bytes to write to volume */
index 4fd675c1384d67490e031d623e56f63f5215c69a..0fad7a420f6f4374d8c217815598a7aa477e07e3 100644 (file)
@@ -106,13 +106,11 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
        return 0;
    }
 
-   strcpy(dev->VolCatInfo.VolCatStatus, "Full");
-   Dmsg2(200, "Call update_vol_info Stat=%s Vol=%s\n", 
+   bstrncpy(dev->VolCatInfo.VolCatStatus, "Full", sizeof(dev->VolCatInfo.VolCatStatus));
+   Dmsg2(100, "Call update_vol_info Stat=%s Vol=%s\n", 
       dev->VolCatInfo.VolCatStatus, dev->VolCatInfo.VolCatName);
-   dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
-   /* *****FIXME**** this needs to be done elsewhere */
    dev->VolCatInfo.VolCatJobs++;             /* increment number of jobs */
-   if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) {    /* send Volume info to Director */
+   if (!dir_update_volume_info(jcr, dev, 0)) {   /* send Volume info to Director */
       P(dev->mutex);
       unblock_device(dev);
       return 0;                   /* device locked */
@@ -201,7 +199,7 @@ void set_new_volume_parameters(JCR *jcr, DEVICE *dev)
       Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
    }
    /* Set new start/end positions */
-   if (dev->state & ST_TAPE) {
+   if (dev_state(dev, ST_TAPE)) {
       jcr->StartBlock = dev->block_num;
       jcr->StartFile = dev->file;
    } else {
@@ -217,14 +215,14 @@ void set_new_volume_parameters(JCR *jcr, DEVICE *dev)
 }
 
 /*
- * We are now in a new file, so reset the Volume parameters
+ * We are now in a new Volume file, so reset the Volume parameters
  *  concerning this job.  The global changes were made earlier
  *  in the dev structure.
  */
 void set_new_file_parameters(JCR *jcr, DEVICE *dev) 
 {
    /* Set new start/end positions */
-   if (dev->state & ST_TAPE) {
+   if (dev_state(dev, ST_TAPE)) {
       jcr->StartBlock = dev->block_num;
       jcr->StartFile = dev->file;
    } else {
index 4e456d84e50d144c37a7799cc0a36dbf0bc59342..cceb5cac516201280a2606dd95447df8f2714fb6 100644 (file)
@@ -322,8 +322,8 @@ static int do_label(JCR *jcr, int relabel)
                     dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) {
            label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
-        } else if (dev->state & ST_READ || dev->num_writers) {
-           if (dev->state & ST_READ) {
+        } else if (dev_state(dev, ST_READ) || dev->num_writers) {
+           if (dev_state(dev, ST_READ)) {
                 bnet_fsend(dir, _("3911 Device %s is busy with 1 reader.\n"),
                   dev_name(dev));
            } else {
@@ -519,7 +519,7 @@ static int mount_cmd(JCR *jcr)
                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
               dev->dev_blocked = BST_MOUNT;
            }
-           if (dev->state & ST_LABEL) {
+           if (dev_state(dev, ST_LABEL)) {
                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), 
                  dev->dev_name, dev->VolHdr.VolName);
            } else {
@@ -540,8 +540,8 @@ static int mount_cmd(JCR *jcr)
            break;
 
         case BST_NOT_BLOCKED:
-           if (dev->state & ST_OPENED) {
-              if (dev->state & ST_LABEL) {
+           if (dev_state(dev, ST_OPENED)) {
+              if (dev_state(dev, ST_LABEL)) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
                     dev->dev_name, dev->VolHdr.VolName);
               } else {
@@ -560,7 +560,7 @@ static int mount_cmd(JCR *jcr)
                  break;
               }
               read_label(jcr, dev);
-              if (dev->state & ST_LABEL) {
+              if (dev_state(dev, ST_LABEL)) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), 
                     dev->dev_name, dev->VolHdr.VolName);
               } else {
@@ -638,8 +638,8 @@ static int unmount_cmd(JCR *jcr)
             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
               dev_name(dev));
 
-        } else if (dev->state & ST_READ || dev->num_writers) {
-           if (dev->state & ST_READ) {
+        } else if (dev_state(dev, ST_READ) || dev->num_writers) {
+           if (dev_state(dev, ST_READ)) {
                 Dmsg0(90, "Device in read mode\n");
                 bnet_fsend(dir, _("3904 Device %s is busy with 1 reader.\n"),
                   dev_name(dev));
@@ -729,8 +729,8 @@ static int release_cmd(JCR *jcr)
             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"),
               dev_name(dev));
 
-        } else if (dev->state & ST_READ || dev->num_writers) {
-           if (dev->state & ST_READ) {
+        } else if (dev_state(dev, ST_READ) || dev->num_writers) {
+           if (dev_state(dev, ST_READ)) {
                 Dmsg0(90, "Device in read mode\n");
                 bnet_fsend(dir, _("3915 Device %s is busy with 1 reader.\n"),
                   dev_name(dev));
@@ -806,8 +806,8 @@ static int autochanger_cmd(JCR *jcr)
                     dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP)) {
            autochanger_list(jcr, dev, dir);
-        } else if (dev->state & ST_READ || dev->num_writers) {
-           if (dev->state & ST_READ) {
+        } else if (dev_state(dev, ST_READ) || dev->num_writers) {
+           if (dev_state(dev, ST_READ)) {
                 bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"),
                   dev_name(dev));
            } else {
index c62a4e69d7fbb67fe625f17b25719c3c2bb2bb1e..a92b259ccbb19012493d46b8b288ad447e275120 100644 (file)
@@ -65,7 +65,7 @@ int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    Dmsg3(100, "Enter read_volume_label device=%s vol=%s dev_Vol=%s\n", 
       dev_name(dev), VolName, dev->VolHdr.VolName);
 
-   if (dev->state & ST_LABEL) {       /* did we already read label? */
+   if (dev_state(dev, ST_LABEL)) {      /* did we already read label? */
       /* Compare Volume Names allow special wild card */
       if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
          Mmsg(&jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
@@ -131,6 +131,17 @@ because:\n   %s"), dev_name(dev), strerror_dev(dev));
       return jcr->label_status = VOL_VERSION_ERROR;
    }
 
+   /* We are looking for either an unused Bacula tape (PRE_LABEL) or
+    * a Bacula volume label (VOL_LABEL)
+    */
+   if (dev->VolHdr.LabelType != PRE_LABEL && dev->VolHdr.LabelType != VOL_LABEL) {
+      Mmsg(&jcr->errmsg, _("Volume on %s has bad Bacula label type: %x\n"), 
+         dev_name(dev), dev->VolHdr.LabelType);
+      return jcr->label_status = VOL_LABEL_ERROR;
+   }
+
+   dev->state |= ST_LABEL;           /* set has Bacula label */
+
    /* Compare Volume Names */
    Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolName);
    if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
@@ -147,16 +158,6 @@ because:\n   %s"), dev_name(dev), strerror_dev(dev));
    }
    Dmsg1(30, "Copy vol_name=%s\n", dev->VolHdr.VolName);
 
-   /* We are looking for either an unused Bacula tape (PRE_LABEL) or
-    * a Bacula volume label (VOL_LABEL)
-    */
-   if (dev->VolHdr.LabelType != PRE_LABEL && dev->VolHdr.LabelType != VOL_LABEL) {
-      Mmsg(&jcr->errmsg, _("Volume on %s has bad Bacula label type: %x\n"), 
-         dev_name(dev), dev->VolHdr.LabelType);
-      return jcr->label_status = VOL_LABEL_ERROR;
-   }
-
-   dev->state |= ST_LABEL;           /* set has Bacula label */
    if (debug_level >= 10) {
       dump_volume_label(dev);
    }
index 1098527c6b7ad437e4b68b8b575ba9d694024edd..79a5d78bccab3c5264ae65bf016a9f7e136df088 100755 (executable)
@@ -446,7 +446,7 @@ static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool d
    if (!(rec->state & REC_ISTAPE)) {
       return 1;                      /* All File records OK for this match */
    }
-// Dmsg3(000, "match_volfile: sfile=%d efile=%d recfile=%d\n",
+// Dmsg3(100, "match_volfile: sfile=%d efile=%d recfile=%d\n",
 //            volfile->sfile, volfile->efile, rec->File);
    if (volfile->sfile <= rec->File && volfile->efile >= rec->File) {
       return 1;
index 46368bb8be8a882f8ed1eb16ef28e604fb1da166..891cddf76161109b809018bc7e468bd9e4dee663 100644 (file)
@@ -59,7 +59,7 @@ mount_next_vol:
       return 0;
    }
    if (job_canceled(jcr)) {
-      Jmsg(jcr, M_FATAL, 0, _("Job canceled.\n"));
+      Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
       return 0;
    }
    autochanger = 0;
@@ -72,6 +72,7 @@ mount_next_vol:
 
    /* 
     * Get Director's idea of what tape we should have mounted. 
+    *   in jcr->VolCatInfo
     */
    Dmsg0(100, "Before dir_find_next\n");
    if (!dir_find_next_appendable_volume(jcr)) {
@@ -124,7 +125,7 @@ mount_next_vol:
       Dmsg1(100, "want vol=%s\n", jcr->VolumeName);
 
       /* Open device */
-      if  (!(dev->state & ST_OPENED)) {
+      if  (!(dev_state(dev, ST_OPENED))) {
          int mode;
          if (dev_cap(dev, CAP_STREAM)) {
             mode = OPEN_WRITE_ONLY;
@@ -153,6 +154,7 @@ read_volume:
       } else {
         vol_label_status = read_dev_volume_label(jcr, dev, block);
       }
+
       Dmsg2(100, "dirVol=%s dirStat=%s\n", jcr->VolumeName,
         jcr->VolCatInfo.VolCatStatus);
       /*
@@ -199,22 +201,28 @@ read_volume:
       case VOL_IO_ERROR:
         /* 
          * If permitted, we label the device, make sure we can do
-         *   it by checking that the VolCatBytes is zero => not labeled. 
+         *   it by checking that the VolCatBytes is zero => not labeled, 
+          *   once the Volume is labeled we don't want to label another
+         *   blank tape with the same name.  For disk, we go ahead and
+         *   label it anyway, because the OS insures that there is only
+         *   one Volume with that name.
          * As noted above, at this point jcr->VolCatInfo has what
          *   the Director wants and dev->VolCatInfo has info on the
          *   previous tape (or nothing).
          */
-        if (dev_cap(dev, CAP_LABEL) && jcr->VolCatInfo.VolCatBytes == 0) {
+        if (dev_cap(dev, CAP_LABEL) && (jcr->VolCatInfo.VolCatBytes == 0 ||
+              (!dev_is_tape(dev) && strcmp(jcr->VolCatInfo.VolCatStatus, 
+                                      "Recycle") == 0))) {
             Dmsg0(100, "Create volume label\n");
            if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName,
                   jcr->pool_name)) {
                Dmsg0(100, "!write_vol_label\n");
               goto mount_next_vol;
            }
-            Dmsg0(200, "dir_update_vol_info. Set Append\n");
+            Dmsg0(100, "dir_update_vol_info. Set Append\n");
             /* Copy Director's info into the device info */
            memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo));
-           dir_update_volume_info(jcr, &dev->VolCatInfo, 1);  /* indicate tape labeled */
+           dir_update_volume_info(jcr, dev, 1);  /* indicate tape labeled */
             Jmsg(jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
               jcr->VolumeName, dev_name(dev));
            goto read_volume;      /* read label we just wrote */
@@ -224,8 +232,7 @@ read_volume:
       default:
 mount_error:
         /* Send error message */
-         Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);                         
-         Dmsg0(100, "Default\n");
+         Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);                         
         ask = true;
         /* was - goto ask_again; */         
         goto mount_next_vol;
@@ -297,9 +304,9 @@ mount_error:
         dev->VolCatInfo.VolCatWrites = 1;
         dev->VolCatInfo.VolCatReads = 1;
       }
-      Dmsg0(200, "dir_update_vol_info. Set Append\n");
+      Dmsg0(100, "dir_update_vol_info. Set Append\n");
       bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus));
-      dir_update_volume_info(jcr, &dev->VolCatInfo, 1);  /* indicate doing relabel */
+      dir_update_volume_info(jcr, dev, 1);  /* indicate doing relabel */
       if (recycle) {
          Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\" on device %s, all previous data lost.\n"),
            jcr->VolumeName, dev_name(dev));
@@ -323,8 +330,8 @@ mount_error:
          Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
            jcr->VolumeName);
          bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
-         Dmsg0(200, "dir_update_vol_info. Set Error.\n");
-        dir_update_volume_info(jcr, &dev->VolCatInfo, 0);
+         Dmsg0(100, "dir_update_vol_info. Set Error.\n");
+        dir_update_volume_info(jcr, dev, 0);
         goto mount_next_vol;
       }
       /* *****FIXME**** we should do some checking for files too */
@@ -341,14 +348,14 @@ mount_error:
 The number of files mismatch! Volume=%u Catalog=%u\n"), 
                 dev_file(dev), dev->VolCatInfo.VolCatFiles);
             bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
-            Dmsg0(200, "dir_update_vol_info. Set Error.\n");
-           dir_update_volume_info(jcr, &dev->VolCatInfo, 0);
+            Dmsg0(100, "dir_update_vol_info. Set Error.\n");
+           dir_update_volume_info(jcr, dev, 0);
            goto mount_next_vol;
         }
       }
       dev->VolCatInfo.VolCatMounts++;     /* Update mounts */
-      Dmsg1(200, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
-      dir_update_volume_info(jcr, &dev->VolCatInfo, 0);
+      Dmsg1(100, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
+      dir_update_volume_info(jcr, dev, 0);
       /* Return an empty block */
       empty_block(block);            /* we used it for reading so set for write */
    }
index e84cfc1f15eb787141b5308f8f6ab29f74219e15..3e1d1560e5722b21d88546fa91f136546167ac5e 100644 (file)
 uint32_t new_VolSessionId();
 
 /* From acquire.c */
-DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int     acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int     release_device(JCR *jcr, DEVICE *dev);
+DEVICE  *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      release_device(JCR *jcr, DEVICE *dev);
 
 /* From askdir.c */
 enum get_vol_info_rw {
    GET_VOL_INFO_FOR_WRITE,
    GET_VOL_INFO_FOR_READ
 };
-int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw);
-int    dir_find_next_appendable_volume(JCR *jcr);
-int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int label);
-int    dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
-int    dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
-int    dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
-int    dir_send_job_status(JCR *jcr);
-int    dir_create_jobmedia_record(JCR *jcr);
+int     dir_get_volume_info(JCR *jcr, enum get_vol_info_rw);
+int     dir_find_next_appendable_volume(JCR *jcr);
+int     dir_update_volume_info(JCR *jcr, DEVICE *dev, int label);
+int     dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
+int     dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
+int     dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
+int     dir_send_job_status(JCR *jcr);
+int     dir_create_jobmedia_record(JCR *jcr);
 
 /* authenticate.c */
-int    authenticate_director(JCR *jcr);
-int    authenticate_filed(JCR *jcr);
+int     authenticate_director(JCR *jcr);
+int     authenticate_filed(JCR *jcr);
 
 /* From block.c */
-void   dump_block(DEV_BLOCK *b, char *msg);
+void    dump_block(DEV_BLOCK *b, char *msg);
 DEV_BLOCK *new_block(DEVICE *dev);
-void   init_block_write(DEV_BLOCK *block);
-void   empty_block(DEV_BLOCK *block);
-void   free_block(DEV_BLOCK *block);
-int    write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int    write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void   print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void    init_block_write(DEV_BLOCK *block);
+void    empty_block(DEV_BLOCK *block);
+void    free_block(DEV_BLOCK *block);
+int     write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void    print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
 
 #define CHECK_BLOCK_NUMBERS    true
 #define NO_BLOCK_NUMBER_CHECK  false
-int    read_block_from_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
-int    read_block_from_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
+int     read_block_from_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
+int     read_block_from_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
 
 /* From butil.c -- utilities for SD tool programs */
-void   print_ls_output(char *fname, char *link, int type, struct stat *statp);
+void    print_ls_output(char *fname, char *link, int type, struct stat *statp);
 JCR    *setup_jcr(char *name, char *device, BSR *bsr, char *VolumeName);
 DEVICE *setup_to_access_device(JCR *jcr, int read_access);
-void   display_tape_error_status(JCR *jcr, DEVICE *dev);
+void    display_tape_error_status(JCR *jcr, DEVICE *dev);
 DEVRES *find_device_res(char *device_name, int read_access);
 
 
 /* From dev.c */
-DEVICE *init_dev(DEVICE *dev, DEVRES *device);
-int     open_dev(DEVICE *dev, char *VolName, int mode);
-void    close_dev(DEVICE *dev);
-void    force_close_dev(DEVICE *dev);
-int     truncate_dev(DEVICE *dev);
-void    term_dev(DEVICE *dev);
-char *  strerror_dev(DEVICE *dev);
-void    clrerror_dev(DEVICE *dev, int func);
-int     update_pos_dev(DEVICE *dev);
-int     rewind_dev(DEVICE *dev);
-int     load_dev(DEVICE *dev);
-int     offline_dev(DEVICE *dev);
-int     flush_dev(DEVICE *dev);
-int     weof_dev(DEVICE *dev, int num);
-int     write_block(DEVICE *dev);
-int     write_dev(DEVICE *dev, char *buf, size_t len);
-int     read_dev(DEVICE *dev, char *buf, size_t len);
-int     status_dev(DEVICE *dev, uint32_t *status);
-int     eod_dev(DEVICE *dev);
-int     fsf_dev(DEVICE *dev, int num);
-int     fsr_dev(DEVICE *dev, int num);
-int     bsf_dev(DEVICE *dev, int num);
-int     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);
-int     dev_can_write(DEVICE *dev);
-int     offline_or_rewind_dev(DEVICE *dev);
-int     reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
+DEVICE  *init_dev(DEVICE *dev, DEVRES *device);
+int      open_dev(DEVICE *dev, char *VolName, int mode);
+void     close_dev(DEVICE *dev);
+void     force_close_dev(DEVICE *dev);
+int      truncate_dev(DEVICE *dev);
+void     term_dev(DEVICE *dev);
+char *   strerror_dev(DEVICE *dev);
+void     clrerror_dev(DEVICE *dev, int func);
+int      update_pos_dev(DEVICE *dev);
+int      rewind_dev(DEVICE *dev);
+int      load_dev(DEVICE *dev);
+int      offline_dev(DEVICE *dev);
+int      flush_dev(DEVICE *dev);
+int      weof_dev(DEVICE *dev, int num);
+int      write_block(DEVICE *dev);
+int      write_dev(DEVICE *dev, char *buf, size_t len);
+int      read_dev(DEVICE *dev, char *buf, size_t len);
+int      status_dev(DEVICE *dev, uint32_t *status);
+int      eod_dev(DEVICE *dev);
+int      fsf_dev(DEVICE *dev, int num);
+int      fsr_dev(DEVICE *dev, int num);
+int      bsf_dev(DEVICE *dev, int num);
+int      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);
+int      dev_can_write(DEVICE *dev);
+int      offline_or_rewind_dev(DEVICE *dev);
+int      reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
 
 
 /* Get info about device */
-char *  dev_name(DEVICE *dev);
-char *  dev_vol_name(DEVICE *dev);
+char *   dev_name(DEVICE *dev);
+char *   dev_vol_name(DEVICE *dev);
 uint32_t dev_block(DEVICE *dev);
 uint32_t dev_file(DEVICE *dev);
-int     dev_is_tape(DEVICE *dev);
+int      dev_is_tape(DEVICE *dev);
 
 /* From device.c */
-int     open_device(DEVICE *dev);
-int     fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int      open_device(DEVICE *dev);
+int      fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
 void _lock_device(char *file, int line, DEVICE *dev);
 void _unlock_device(char *file, int line, DEVICE *dev);
 void _block_device(char *file, int line, DEVICE *dev, int state);
@@ -126,65 +126,65 @@ void set_new_file_parameters(JCR *jcr, DEVICE *dev);
 int  device_is_unmounted(DEVICE *dev);
 
 /* From dircmd.c */
-void    *connection_request(void *arg); 
+void     *connection_request(void *arg); 
 
 
 /* From fd_cmds.c */
-void    run_job(JCR *jcr);
+void     run_job(JCR *jcr);
 
 /* From job.c */
-void    stored_free_jcr(JCR *jcr);
-void    connection_from_filed(void *arg);     
-void    handle_filed_connection(BSOCK *fd, char *job_name);
+void     stored_free_jcr(JCR *jcr);
+void     connection_from_filed(void *arg);     
+void     handle_filed_connection(BSOCK *fd, char *job_name);
 
 /* From label.c */
-int     read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void    create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
-void    create_volume_label(DEVICE *dev, char *VolName, char *PoolName);
-int     write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
-int     write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
-int     write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void    dump_volume_label(DEVICE *dev);
-void    dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-int     unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-int     unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int      read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void     create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
+void     create_volume_label(DEVICE *dev, char *VolName, char *PoolName);
+int      write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
+int      write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
+int      write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void     dump_volume_label(DEVICE *dev);
+void     dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+int      unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+int      unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
 
 /* From match_bsr.c */
-int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, 
-             SESSION_LABEL *sesrec);
-int match_bsr_block(BSR *bsr, DEV_BLOCK *block);
-void position_bsr_block(BSR *bsr, DEV_BLOCK *block);
-BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev);
-bool match_set_eof(BSR *bsr, DEV_RECORD *rec);
+int      match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, 
+              SESSION_LABEL *sesrec);
+int      match_bsr_block(BSR *bsr, DEV_BLOCK *block);
+void     position_bsr_block(BSR *bsr, DEV_BLOCK *block);
+BSR     *find_next_bsr(BSR *root_bsr, DEVICE *dev);
+bool     match_set_eof(BSR *bsr, DEV_RECORD *rec);
 
 /* From mount.c */
-int     mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release);
-int     mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void    release_volume(JCR *jcr, DEVICE *dev);
+int      mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release);
+int      mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void     release_volume(JCR *jcr, DEVICE *dev);
 
 /* From autochanger.c */
-int     autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir);
-int     autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir);
-void    invalidate_slot_in_catalog(JCR *jcr);
+int      autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir);
+int      autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir);
+void     invalidate_slot_in_catalog(JCR *jcr, DEVICE *dev);
 
 
 /* From parse_bsr.c */
-extern BSR *parse_bsr(JCR *jcr, char *lf);
-void dump_bsr(BSR *bsr, bool recurse);
-extern void free_bsr(BSR *bsr);
-extern VOL_LIST *new_vol();
-extern int add_vol(JCR *jcr, VOL_LIST *vol);
-extern void free_vol_list(JCR *jcr);
-extern void create_vol_list(JCR *jcr);
+BSR     *parse_bsr(JCR *jcr, char *lf);
+void     dump_bsr(BSR *bsr, bool recurse);
+void     free_bsr(BSR *bsr);
+VOL_LIST *new_vol();
+int      add_vol(JCR *jcr, VOL_LIST *vol);
+void     free_vol_list(JCR *jcr);
+void     create_vol_list(JCR *jcr);
 
 /* From record.c */
 char   *FI_to_ascii(int fi);
 char   *stream_to_ascii(int stream, int fi);
-int    write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int    can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int    read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); 
+int     write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int     can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int     read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); 
 DEV_RECORD *new_record();
-void   free_record(DEV_RECORD *rec);
+void    free_record(DEV_RECORD *rec);
 
 /* From read_record.c */
 int read_records(JCR *jcr,  DEVICE *dev, 
index 826b7fbd18b496758ea2ebe9d5cdb829109ee801..96ba176f9707a6f276968a3222859480b8a70f96 100644 (file)
@@ -107,48 +107,48 @@ int main (int argc, char *argv[])
 
    while ((ch = getopt(argc, argv, "c:d:fg:stu:v?")) != -1) {
       switch (ch) {
-         case 'c':                    /* configuration file */
-           if (configfile != NULL) {
-              free(configfile);
-           }
-           configfile = bstrdup(optarg);
-           break;
-
-         case 'd':                    /* debug level */
-           debug_level = atoi(optarg);
-           if (debug_level <= 0) {
-              debug_level = 1; 
-           }
-           break;
+      case 'c':                    /* configuration file */
+        if (configfile != NULL) {
+           free(configfile);
+        }
+        configfile = bstrdup(optarg);
+        break;
 
-         case 'f':                    /* run in foreground */
-           foreground = TRUE;
-           break;
+      case 'd':                    /* debug level */
+        debug_level = atoi(optarg);
+        if (debug_level <= 0) {
+           debug_level = 1; 
+        }
+        break;
 
-         case 'g':                    /* set group id */
-           gid = optarg;
-           break;
+      case 'f':                    /* run in foreground */
+        foreground = TRUE;
+        break;
 
-         case 's':                    /* no signals */
-           no_signals = TRUE;
-           break;
+      case 'g':                    /* set group id */
+        gid = optarg;
+        break;
 
-         case 't':
-           test_config = TRUE;
-           break;
+      case 's':                    /* no signals */
+        no_signals = TRUE;
+        break;
 
-         case 'u':                    /* set uid */
-           uid = optarg;
-           break;
+      case 't':
+        test_config = TRUE;
+        break;
 
-         case 'v':                    /* verbose */
-           verbose++;
-           break;
+      case 'u':                    /* set uid */
+        uid = optarg;
+        break;
 
-         case '?':
-        default:
-           usage();
+      case 'v':                    /* verbose */
+        verbose++;
+        break;
 
+      case '?':
+      default:
+        usage();
+        break;
       }  
    }
    argc -= optind;
@@ -335,16 +335,47 @@ void terminate_stored(int sig)
 {
    static int in_here = FALSE;
    DEVRES *device;
+   JCR *jcr;
 
    if (in_here) {                    /* prevent loops */
       exit(1);
    }
    in_here = TRUE;
 
+   if (sig == SIGTERM) {             /* normal shutdown request? */
+      /*
+       * This is a normal shutdown request. We wiffle through
+       *   all open jobs canceling them and trying to wake
+       *   them up so that they will report back the correct
+       *   volume status.
+       */
+      lock_jcr_chain();
+      for (jcr=NULL; (jcr=get_next_jcr(jcr)); ) {
+        BSOCK *fd;
+        free_locked_jcr(jcr);
+        if (jcr->JobId == 0) {
+           continue;                 /* ignore console */
+        }
+        set_jcr_job_status(jcr, JS_Canceled);
+        fd = jcr->file_bsock;  
+        if (fd) {
+           fd->timed_out = TRUE;
+            Dmsg1(100, "killing JobId=%d\n", jcr->JobId);
+           pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
+           if (jcr->device && jcr->device->dev && jcr->device->dev->dev_blocked) {
+              pthread_cond_signal(&jcr->device->dev->wait_next_vol);
+           }
+           bmicrosleep(0, 50000);
+         }
+      }
+      unlock_jcr_chain();
+      bmicrosleep(0, 500000);        /* give them 1/2 sec to clean up */
+   }
+
    delete_pid_file(me->pid_directory, "bacula-sd", me->SDport);
    stop_watchdog();
 
-   Dmsg0(200, "In terminate_stored()\n");
+   Dmsg1(200, "In terminate_stored() sig=%d\n", sig);
 
    LockRes();
    for (device=NULL; (device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device)); ) {
index 28a8201264454e8ddc8f6285881e13c006dc8b8d..e0747ab6956fbcfb82f3b2d6967442a93f94459f 100644 (file)
@@ -3,4 +3,5 @@ testls
 Makefile
 dbcheck
 smtp
+bsmtp
 testfind
index 9f735b05f2bfad27ce4939104c7f937747dd6e67..c820dfa35fbc946ba6d35805af2d520fab7c12ca 100644 (file)
@@ -36,7 +36,7 @@ EXTRAOBJS = @OBJLIST@
 .c.o:
        $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
 #-------------------------------------------------------------------------
-all: Makefile bsmtp dbcheck testfind testls
+all: Makefile bsmtp dbcheck testfind testls hammer
        @echo "==== Make of tools is good ===="
        @echo " "
 
@@ -54,8 +54,6 @@ testls: ../findlib/libfind.a ../lib/libbac.a testls.o
        $(CXX) -g $(LDFLAGS) -L. -L../lib -L../findlib -o $@ testls.o \
          $(LIBS) $(DLIB) -lfind -lbac -lm
 
-
 Makefile: $(srcdir)/Makefile.in $(topdir)/config.status
        cd $(topdir) \
          && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
index f851582e585872b481198c127abae81b752dfa17..87f761c3de206f5d0484b524e88827b51e3d17fb 100644 (file)
@@ -102,7 +102,7 @@ static void usage()
 {
    fprintf(stderr,
 "\n"
-"Usage: smtp [-f from] [-h mailhost] [-s subject] [-c copy] [recepient ...]\n"
+"Usage: bsmtp [-f from] [-h mailhost] [-s subject] [-c copy] [recepient ...]\n"
 "       -c          set the Cc: field\n"
 "       -dnn        set debug level to nn\n"
 "       -f          set the From: field\n"
index e81d5e77d6449bd9f3aee40eabc092317a98d6b0..66d98188d1c2396f04124a2a9b5017f6a6294b9b 100644 (file)
@@ -2,8 +2,8 @@
 #undef  VERSION
 #define VERSION "1.33"
 #define VSTRING "1"
-#define BDATE   "10 Nov 2003"
-#define LSMDATE "10Nov03"
+#define BDATE   "14 Nov 2003"
+#define LSMDATE "14Nov03"
 
 /* Debug flags */
 #undef  DEBUG