]> git.sur5r.net Git - bacula/bacula/commitdiff
Restore from multiple simultaneous backups
authorKern Sibbald <kern@sibbald.com>
Mon, 26 Aug 2002 13:33:53 +0000 (13:33 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 26 Aug 2002 13:33:53 +0000 (13:33 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@122 91ce42f0-d328-0410-95d8-f526ca767f89

17 files changed:
bacula/Makefile.in
bacula/kernstodo
bacula/src/cats/sql_get.c
bacula/src/filed/filed_conf.c
bacula/src/filed/filed_conf.h
bacula/src/filed/restore.c
bacula/src/lib/bnet.c
bacula/src/lib/mem_pool.c
bacula/src/stored/bls.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/dircmd.c
bacula/src/stored/protos.h
bacula/src/stored/read.c
bacula/src/stored/record.c
bacula/src/version.h

index 6c3a64a7ac276ba8ef607b631df4a68ffd0bff47..9cc7c3b3c2e59954e76da60b99bb9cfc379b6d13 100755 (executable)
@@ -34,7 +34,7 @@ MKDIR = $(srcdir)/autoconf/mkinstalldirs
 all: Makefile
        @for I in ${subdirs}; \
          do (cd $$I; echo "==>Entering directory `pwd`"; \
-             $(MAKE) $@ || (echo ""; echo ""; echo "   ====== Error in `pwd` ======"; \
+             $(MAKE) $@ || (echo ""; echo ""; echo -e "  \a\a ====== Error in `pwd` ======\a\a"; \
                            echo ""; echo "";)); \
        done
 
@@ -45,7 +45,7 @@ depend:
 bacula-fd: Makefile       
        @for I in ${FDsubdirs}; \
          do (cd $$I; echo "==>Entering directory `pwd`"; \
-             $(MAKE) all || (echo ""; echo ""; echo "   ====== Error in `pwd` ======"; \
+             $(MAKE) all || (echo ""; echo ""; echo -e "  \a\a ====== Error in `pwd` ======\a\a"; \
                            echo ""; echo "";)); \
        done
 
index df56c94e79ebcbd9e2711088d1e1ba77f23d93da..1556594d58edd41f837637b3e747602821f2b1d6 100644 (file)
@@ -1,5 +1,5 @@
                  Kern's ToDo List
-                  20 August 2002
+                  26 August 2002
 
 Irix conversion notes:
 - no uuencode
@@ -28,13 +28,10 @@ From Chuck:
 --sd.conf password does not match dir.conf storage password
 =======
 
-- In restore job, print some summary information at end, such
-  as rate, ... job status, ...
 - After unmount, if restore job started, ask to mount.
-- Fix db_update_fileset in cats/sql_get.c
+- Fix db_get_fileset in cats/sql_get.c for multiple records.
 - Fix start/end blocks for File
 - Add new code to scheduler.c and run_conf.c
-- Problem with len at 362 in tree.c
 - Volume Bytes shows bytes on last volume written in Job summary.
 - Fix catalog filename truncation in sql_get and sql_create. Use
   only a single filename split routine.
@@ -451,3 +448,7 @@ Done: (see kernsdone for more)
 - Get correct block/file information in Catalog, pay attention to change of media.
 - Write better dump of Messages resource.
 - Authentication between SD and FD
+- In restore job, print some summary information at end, such
+  as rate, ... job status, ...
+- Problem with len at 362 in tree.c
+
index 8e7e6bac542e2328095fd8a84717ebd5a6c5a021..a32c524cec688f088f6722e6a255930735495b25 100644 (file)
@@ -100,7 +100,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr)
     */
    fnl = p - l;
    if (fnl > 255) {
-      Emsg1(M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l);
+      Jmsg1(mdb->jcr, M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l);
       fnl = 255;
    }
    if (fnl > 0) {
@@ -114,7 +114,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr)
 
    pnl = l - fname;    
    if (pnl > 255) {
-      Emsg1(M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), fname);
+      Jmsg1(mdb->jcr, M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), fname);
       pnl = 255;
    }
    strncpy(spath, fname, pnl);
@@ -122,7 +122,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr)
 
    if (pnl == 0) {
       Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), fname);
-      Emsg0(M_ERROR, 0, mdb->errmsg);
+      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       spath[0] = ' ';
       spath[1] = 0;
       pnl = 1;
@@ -176,12 +176,13 @@ File.FilenameId=%d", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
        *  filename if the file is linked.   ????????
        */
       if (mdb->num_rows > 1) {
-         Emsg1(M_WARNING, 0, _("get_file_record want 1 got rows=%d\n"), mdb->num_rows);
-         Emsg1(M_ERROR, 0, "%s", mdb->cmd);
+         Jmsg1(mdb->jcr, M_WARNING, 0, _("get_file_record want 1 got rows=%d\n"), mdb->num_rows);
+         Jmsg1(mdb->jcr, M_ERROR, 0, "%s", mdb->cmd);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, "Error fetching row: %s\n", sql_strerror(mdb));
+            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            fdbr->FileId = (FileId_t)strtod(row[0], NULL);
            strncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
@@ -220,19 +221,18 @@ static int db_get_filename_record(B_DB *mdb, char *fname)
 
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Filename!: %d\n"), (int)(mdb->num_rows));
-         Emsg1(M_WARNING, 0, _("get_filename_record want 1 got rows=%d\n"), mdb->num_rows);
-         Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
+         Jmsg(mdb->jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-            Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
+            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            FilenameId = atoi(row[0]);
            if (FilenameId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
                  mdb->cmd, FilenameId); 
-               Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
+               Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
               FilenameId = 0;
            }
         }
@@ -272,14 +272,17 @@ static int db_get_path_record(B_DB *mdb, char *path)
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Path!: %s\n"), 
            edit_uint64(mdb->num_rows, ed1));
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            PathId = atoi(row[0]);
            if (PathId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %d\n"),
                  mdb->cmd, PathId); 
+               Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
               PathId = 0;
            } else {
               /* Cache path */
@@ -325,6 +328,7 @@ FROM Job WHERE JobId=%d", jr->JobId);
    }
    if ((row = sql_fetch_row(mdb)) == NULL) {
       Mmsg1(&mdb->errmsg, _("No Job found for JobId %d\n"), jr->JobId);
+      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       sql_free_result(mdb);
       db_unlock(mdb);
       return 0;                      /* failed */
@@ -371,12 +375,14 @@ AND JobMedia.MediaId=Media.MediaId", JobId);
       Dmsg1(130, "Num rows=%d\n", mdb->num_rows);
       if (mdb->num_rows <= 0) {
          Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d"), JobId);
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         stat = 0;
       } else {
         stat = mdb->num_rows;
         for (i=0; i < stat; i++) {
            if ((row = sql_fetch_row(mdb)) == NULL) {
                Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb));
+               Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
               stat = 0;
               break;
            } else {
@@ -441,6 +447,7 @@ int db_get_pool_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
       stat = 1;
    } else {
       Mmsg(&mdb->errmsg, _("Pool id select failed: ERR=%s\n"), sql_strerror(mdb));
+      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       stat = 0;
    }
    db_unlock(mdb);
@@ -479,9 +486,11 @@ PoolType, LabelFormat FROM Pool WHERE Pool.Name='%s'", pdbr->Name);
         char ed1[30];
          Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"), 
            edit_uint64(mdb->num_rows, ed1));
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            pdbr->PoolId = atoi(row[0]);
            strcpy(pdbr->Name, row[1]);
@@ -538,9 +547,11 @@ int db_get_fileset_record(B_DB *mdb, FILESET_DBR *fsr)
          Mmsg1(&mdb->errmsg, _("Got %s FileSets expected only one!\n"), 
            edit_uint64(mdb->num_rows, ed1));
         sql_data_seek(mdb, mdb->num_rows-1);
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if ((row = sql_fetch_row(mdb)) == NULL) {
-         Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+         Mmsg1(&mdb->errmsg, _("Error fetching row get_fileset: %s\n"), sql_strerror(mdb));
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else {
         fsr->FileSetId = atoi(row[0]);
         strcpy(fsr->FileSet, row[1]);
@@ -602,6 +613,7 @@ int db_get_media_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
       stat = 1;
    } else {
       Mmsg(&mdb->errmsg, _("Media id select failed: ERR=%s\n"), sql_strerror(mdb));
+      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       stat = 0;
    }
    db_unlock(mdb);
@@ -644,9 +656,11 @@ FROM Media WHERE VolumeName='%s'", mr->VolumeName);
         char ed1[30];
          Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"), 
            edit_uint64(mdb->num_rows, ed1));
+         Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
+            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            /* return values */
            mr->MediaId = atoi(row[0]);
index 6d2fcd2d9d0d4ab4aa4945396484659d621eaa5b..ff0ed75c57a8267046f3924bd97169463c4d82b0 100644 (file)
@@ -77,6 +77,7 @@ static struct res_items cli_items[] = {
    {"workingdirectory",  store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, 
    {"piddirectory",  store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, 
    {"subsysdirectory",  store_dir,  ITEM(res_client.subsys_directory), 0, ITEM_REQUIRED, 0}, 
+   {"maximumconcurrentjobs", store_pint, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1},
    {"messages",      store_res, ITEM(res_client.messages), R_MSGS, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
index 56a3ef98273b7e2ad6086af840edc1319e92af36..40c28ba361a9c9eb2b1615c076f310bb07e69a08 100644 (file)
 /*
  * Resource codes -- they must be sequential for indexing   
  */
-#define R_FIRST                      1001
+#define R_FIRST                       1001
 
-#define R_DIRECTOR                   1001
-#define R_CLIENT                     1002
-#define R_MSGS                       1003
+#define R_DIRECTOR                    1001
+#define R_CLIENT                      1002
+#define R_MSGS                        1003
 
-#define R_LAST                       R_MSGS
+#define R_LAST                        R_MSGS
 
 /*
  * Some resource attributes
  */
-#define R_NAME                       1020
-#define R_ADDRESS                    1021
-#define R_PASSWORD                   1022
-#define R_TYPE                       1023
+#define R_NAME                        1020
+#define R_ADDRESS                     1021
+#define R_PASSWORD                    1022
+#define R_TYPE                        1023
 
 
 /* Definition of the contents of each Resource */
 struct s_res_dir {
-   RES  hdr;
-   char *password;                   /* Director password */
-   char *address;                    /* Director address or zero */
+   RES   hdr;
+   char *password;                    /* Director password */
+   char *address;                     /* Director address or zero */
 };
 typedef struct s_res_dir DIRRES;
 
 struct s_res_client {
-   RES  hdr;
-   int  FDport;                      /* where we listen for Directors */ 
+   RES   hdr;
+   int   FDport;                      /* where we listen for Directors */ 
    char *working_directory;
    char *pid_directory;
    char *subsys_directory;
    struct s_res_msgs *messages;       /* daemon message handler */
+   int MaxConcurrentJobs;
 };
 typedef struct s_res_client CLIENT;
 
@@ -69,9 +70,9 @@ typedef struct s_res_client CLIENT;
  * resource structure definitions.
  */
 union u_res {
-   struct s_res_dir    res_dir;
-   struct s_res_client res_client;
-   struct s_res_msgs   res_msgs;
+   struct s_res_dir     res_dir;
+   struct s_res_client  res_client;
+   struct s_res_msgs    res_msgs;
    RES hdr;
 };
 
index 67a3e8d6cc3df37670a55df45595bc7c87fc7ffe..46c73a7ced4ae3d72d7a0786c03488e9b21bd745 100644 (file)
@@ -143,16 +143,17 @@ void do_restore(JCR *jcr)
          *    Link name (if file linked i.e. FT_LNK)
          *
          */
+         Dmsg1(100, "Attr: %s\n", sd->msg);
          if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) {
-            Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg);
-            Dmsg0(0, "\nError scanning header\n");
+            Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), sd->msg);
+            Dmsg1(000, "\nError scanning attributes. %s\n", sd->msg);
            goto bail_out;
         }
-         Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
+         Dmsg2(100, "Got Attr: FilInx=%d type=%d\n", record_file_index, type);
         if (record_file_index != file_index) {
             Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"),
               file_index, record_file_index);
-            Dmsg0(0, "File index error\n");
+            Dmsg0(000, "File index error\n");
            goto bail_out;
         }
         ap = sd->msg;
index 48aa1ee65014105ff93026e456d7af062e29556c..312edad2c7aa2ede2b143cd48242e3c52d7e973a 100644 (file)
@@ -661,7 +661,7 @@ term_bsock(BSOCK *bsock)
       free_pool_memory(bsock->msg);
       bsock->msg = NULL;
    } else {
-      ASSERT(1=0);                   /* double close */
+      ASSERT(1==0);                  /* double close */
    }
    if (bsock->errmsg) {
       free_pool_memory(bsock->errmsg);
index 2af3a7b8b678f26da3bb270c4587ca67290cc9ea..c5443ac354106df71cedfcc37a6a88ac300de21c 100644 (file)
@@ -195,10 +195,13 @@ void free_pool_memory(POOLMEM *obuf)
    if (pool == 0) {
       free((char *)buf);             /* free nonpooled memory */
    } else {                          /* otherwise link it to the free pool chain */
+#ifdef DEBUG
       struct abufhead *next;
+      /* Don't let him free the same buffer twice */
       for (next=pool_ctl[pool].free_buf; next; next=next->next) {
         ASSERT(next != buf);  /* attempt to free twice */
       }
+#endif
       buf->next = pool_ctl[pool].free_buf;
       pool_ctl[pool].free_buf = buf;
    }
index 63fef7f34c5445fee88aaf150b003b30f7e175ad..aa12351914a0ac45850d100c7abbc152b87f6495 100644 (file)
@@ -511,10 +511,12 @@ Warning, this Volume is a continuation of Volume %s\n",
       record = 0;
       for (rec->state=0; !is_block_empty(rec); ) {
         if (!read_record_from_block(block, rec)) {
-            Dmsg2(30, "!read-break. stat=%s blk=%d\n", rec_state_to_str(rec), 
-                 block->BlockNumber);
+            Dmsg3(10, "!read-break. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
+                 block->BlockNumber, rec->remainder);
            break;
         }
+         Dmsg3(10, "read-OK. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), 
+                 block->BlockNumber, rec->remainder);
         /*
          * At this point, we have at least a record header.
          *  Now decide if we want this record or not, but remember
index 7882e678b7e956aabd29daeace0ba454832dc88d..80c6315de248a7267a9048fd0fe473ca38cee15c 100644 (file)
@@ -144,10 +144,12 @@ init_dev(DEVICE *dev, char *dev_name)
    dev->errmsg = get_pool_memory(PM_EMSG);
    *dev->errmsg = 0;
 
+#ifdef NEW_LOCK
    if ((errstat=rwl_init(&dev->lock)) != 0) {
       Mmsg1(&dev->errmsg, _("Unable to initialize dev lock. ERR=%s\n"), strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
+#endif
 
    if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) {
       dev->dev_errno = errstat;
@@ -1073,7 +1075,9 @@ term_dev(DEVICE *dev)
       free_pool_memory(dev->errmsg);
       dev->errmsg = NULL;
    }
+#ifdef NEW_LOCK
    rwl_destroy(&dev->lock);
+#endif
    pthread_mutex_destroy(&dev->mutex);
    pthread_cond_destroy(&dev->wait);
    pthread_cond_destroy(&dev->wait_next_vol);
index a6c263ab187b14efdc0269c23e4b8c1a9877dbe3..4173fafe3fbfe0ef7c83a294199e50346b54bcf6 100644 (file)
@@ -110,11 +110,19 @@ typedef struct s_volume_catalog_info {
 } VOLUME_CAT_INFO;
 
 
+typedef struct s_steal_lock {
+   pthread_t         no_wait_id;      /* id of no wait thread */
+   int               dev_blocked;     /* state */
+} bsteal_lock_t;
+
+
 /* Device structure definition */
 typedef struct s_device {
    struct s_device *next;             /* pointer to next open device */
    void *attached_jcrs;               /* attached JCR list */
+#ifdef NEW_LOCK
    brwlock_t lock;                    /* new device locking mechanism */
+#endif
    pthread_mutex_t mutex;             /* access control */
    pthread_cond_t wait;               /* thread wait variable */
    pthread_cond_t wait_next_vol;      /* wait for tape to be mounted */
index 24adab2ebe6e0f08ab6b1481f591088ae2de2a51..9af8ce96f173e357e831d06b44d827d92407f045 100644 (file)
@@ -301,6 +301,33 @@ void unblock_device(DEVICE *dev)
 #endif
 }
 
+void steal_device_lock(DEVICE *dev, bsteal_lock_t *hold, int state)
+{
+#ifndef NEW_LOCK
+   hold->dev_blocked = dev->dev_blocked;
+   hold->no_wait_id = dev->no_wait_id;
+   dev->dev_blocked = state;
+   dev->no_wait_id = pthread_self();
+   V(dev->mutex);
+#endif
+}
+
+void return_device_lock(DEVICE *dev, bsteal_lock_t *hold)          
+{
+#ifndef NEW_LOCK
+   P(dev->mutex);
+   dev->dev_blocked = hold->dev_blocked;
+   dev->no_wait_id = hold->no_wait_id;
+#endif
+}
+
+
+
+/* ==================================================================
+ *  New device locking code.  It is not currently used.
+ * ==================================================================
+ */
+
 /*
  * New device locking scheme 
  */
@@ -344,7 +371,6 @@ void _unlock_device(char *file, int line, DEVICE *dev)
 void new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state)
 {
 #ifdef NEW_LOCK
-   P(dev->lock.mutex);
    hold->state = dev->dev_blocked;
    hold->writer_id = dev->lock.writer_id;
    dev->dev_blocked = state;
@@ -359,6 +385,5 @@ void new_return_device_lock(DEVICE *dev, brwsteal_t *hold)
    P(dev->lock.mutex);
    dev->dev_blocked = hold->state;
    dev->lock.writer_id = hold->writer_id;
-   V(dev->lock.mutex);
 #endif
 }
index 759dd2fa2a700caaba49cd02986c379e69d061fc..45b1a5c4deee24ea1a0dbb6da9e0cee1874e313f 100644 (file)
@@ -254,10 +254,48 @@ static int label_cmd(JCR *jcr)
       }
       UnlockRes();
       if (found) {
+#ifdef NEW_LOCK
+        int label_it = FALSE;
+        brwsteal_t hold;
+#endif
         /******FIXME**** compare MediaTypes */
         jcr->device = device;
         dev = device->dev;
 
+#ifdef NEW_LOCK
+        P(dev->lock.mutex);
+        if (!(dev->state & ST_OPENED)) {
+           label_it = TRUE;
+        } else if (dev->dev_blocked && 
+                   dev->dev_blocked != BST_DOING_ACQUIRE) {  /* device blocked? */
+           label_it = TRUE;
+        } else if (dev->state & ST_READ || dev->num_writers) {
+           if (dev->state & ST_READ) {
+                bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"),
+                  dev_name(dev));
+           } else {
+                bnet_fsend(dir, _("3902 Device %s is busy with %d writer(s).\n"),
+                  dev_name(dev), dev->num_writers);
+           }
+        } else {                     /* device not being used */
+           label_it = TRUE;
+        }
+        if (label_it) {
+           new_steal_device_lock(dev, &hold, BST_WRITING_LABEL);
+           if (!(dev->state & ST_OPENED)) {
+              if (open_dev(dev, volname, READ_WRITE) < 0) {
+                  bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev));
+              } else {
+                 label_volume_if_ok(jcr, dev, volname, poolname);
+                 force_close_dev(dev);
+              }
+           } else {
+              label_volume_if_ok(jcr, dev, volname, poolname);
+           }
+           new_return_device_lock(dev, &hold);
+        }
+        V(dev->lock.mutex);
+#else
         P(dev->mutex);
         if (!(dev->state & ST_OPENED)) {
            if (open_dev(dev, volname, READ_WRITE) < 0) {
@@ -281,6 +319,7 @@ static int label_cmd(JCR *jcr)
            label_volume_if_ok(jcr, dev, volname, poolname);
         }
         V(dev->mutex);
+#endif
       } else {
          bnet_fsend(dir, _("3999 Device %s not found\n"), dname);
       }
@@ -307,19 +346,12 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolnam
 {
    BSOCK *dir = jcr->dir_bsock;
    DEV_BLOCK *block;
-   brwsteal_t hold;
 #ifndef NEW_LOCK
-   int blocked;
-   pthread_t no_wait_id;
+   bsteal_lock_t hold;
    
-   blocked = dev->dev_blocked;       /* save any prev blocked state */
-   dev->dev_blocked = BST_WRITING_LABEL;
-   no_wait_id = dev->no_wait_id;
-   dev->no_wait_id = pthread_self();  /* let us use the tape */
+   steal_device_lock(dev, &hold, BST_WRITING_LABEL);
 #endif
    
-   new_steal_device_lock(dev, &hold, BST_WRITING_LABEL);
-   V(dev->mutex);
    strcpy(jcr->VolumeName, vname);
    block = new_block(dev);
    switch (read_dev_volume_label(jcr, dev, block)) {               
@@ -343,11 +375,8 @@ Unknown status %d from read_volume_label()\n"), jcr->label_status);
         break;
    }
    free_block(block);
-   P(dev->mutex);
-   new_return_device_lock(dev, &hold);
 #ifndef NEW_LOCK
-   dev->dev_blocked = blocked;       /* reset blocked state */
-   dev->no_wait_id = no_wait_id;      /* reset blocking thread id */
+   return_device_lock(dev, &hold);
 #endif
 }
 
@@ -362,18 +391,11 @@ static int read_label(JCR *jcr, DEVICE *dev)
    int stat;
    BSOCK *dir = jcr->dir_bsock;
    DEV_BLOCK *block;
-   brwsteal_t hold;
 #ifndef NEW_LOCK
-   int blocked;
-   pthread_t no_wait_id;
+   bsteal_lock_t hold;
    
-   blocked = dev->dev_blocked;       /* save any prev blocked state */
-   no_wait_id = dev->no_wait_id;
-   dev->dev_blocked = BST_DOING_ACQUIRE;
-   dev->no_wait_id = pthread_self();  /* let us use the tape */
+   steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
 #endif
-   new_steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
-   V(dev->mutex);                    /* release lock */
    
    jcr->VolumeName[0] = 0;
    block = new_block(dev);
@@ -390,11 +412,8 @@ static int read_label(JCR *jcr, DEVICE *dev)
         break;
    }
    free_block(block);
-   P(dev->mutex);
-   new_return_device_lock(dev, &hold);
 #ifndef NEW_LOCK
-   dev->dev_blocked = blocked;       /* reset blocked state */
-   dev->no_wait_id = no_wait_id;      /* reset blocking thread id */
+   return_device_lock(dev, &hold);
 #endif
    return stat;
 }
index c43d312de584b250b5feeda029941350384f9f5d..495cdc4cea7f0f71c0094ceb904276fdd4ae9771 100644 (file)
 uint32_t new_VolSessionId();
 
 /* From acquire.c */
-int      acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int      acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int      ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int      release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
 
 /* From askdir.c */
-int     dir_get_volume_info(JCR *jcr);
-int     dir_find_next_appendable_volume(JCR *jcr);
-int     dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
-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);
+int    dir_find_next_appendable_volume(JCR *jcr);
+int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
+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(DEVICE *dev, DEV_BLOCK *block);
-int     read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
-int     read_block_from_dev(DEVICE *dev, 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(DEVICE *dev, DEV_BLOCK *block);
+int    read_block_from_device(DEVICE *dev, DEV_BLOCK *block);
+int    read_block_from_dev(DEVICE *dev, DEV_BLOCK *block);
 
 
 /* From dev.c */
-DEVICE  *init_dev(DEVICE *dev, char *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);
+DEVICE *init_dev(DEVICE *dev, char *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);
 
 
 /* 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);
-void     block_device(DEVICE *dev, int state);
-void     unblock_device(DEVICE *dev);
-void     lock_device(DEVICE *dev);
-void     unlock_device(DEVICE *dev);
-int      fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int     open_device(DEVICE *dev);
+void    block_device(DEVICE *dev, int state);
+void    unblock_device(DEVICE *dev);
+void    lock_device(DEVICE *dev);
+void    unlock_device(DEVICE *dev);
+void    steal_device_lock(DEVICE *dev, bsteal_lock_t *hold, int state);
+void    return_device_lock(DEVICE *dev, bsteal_lock_t *hold);
+int     fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
 void _lock_device(char *file, int line, DEVICE *dev);
 void _lock_device(char *file, int line, DEVICE *dev, int state);
 void _unlock_device(char *file, int line, DEVICE *dev);
@@ -109,38 +111,38 @@ void  new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state);
 void  new_return_device_lock(DEVICE *dev, brwsteal_t *hold);
 
 /* 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 fdmsg.c */
-int      bget_msg(BSOCK *sock);
+int     bget_msg(BSOCK *sock);
 
 /* 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);
-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);
+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);
+             SESSION_LABEL *sesrec);
 
 /* 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);
+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);
 
 
 /* From parse_bsr.c */
@@ -155,8 +157,8 @@ extern void create_vol_list(JCR *jcr);
 /* From record.c */
 char   *FI_to_ascii(int fi);
 char   *stream_to_ascii(int stream);
-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);
index 59851434f0d15a2f4609735020d77abf3373e33f..35e2abe6266ad201e3035fe6d27f97c88f070b22 100644 (file)
@@ -80,7 +80,6 @@ int do_read_data(JCR *jcr)
 
    block = new_block(dev);
 
-
    create_vol_list(jcr);
 
    Dmsg1(20, "Found %d volumes names to restore.\n", jcr->NumVolumes);
@@ -223,10 +222,13 @@ int do_read_data(JCR *jcr)
         ds->msglen = rec->data_len;
          Dmsg1(40, ">filed: send %d bytes data.\n", ds->msglen);
         if (!bnet_send(ds)) {
-            Dmsg0(0, "Error sending to FD\n");
+            Dmsg1(000, "Error sending to FD. ERR=%s\n", bnet_strerror(ds));
+            Dmsg1(100, "Hdr=%s\n", hdr);
+            Dmsg1(100, "data=%s\n", ds->msg);
             Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"),
               bnet_strerror(ds));
            ok = FALSE;
+           break;
         }
       }
    }
index eebb5af25ba07a5b9690e4d13a89defac246d787..9ada74bda1267d07944b79df1049535ef18d19e7 100644 (file)
@@ -328,8 +328,16 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
       block->binbuf -= RECHDR_LENGTH;
       remlen -= RECHDR_LENGTH;
 
-      /*    
-       * if Stream is negative, it means that this is a continuation
+      /* If we are looking for more (remainder!=0), we reject anything
+       *  where the VolSessionId and VolSessionTime don't agree
+       */
+      if (rec->remainder && (rec->VolSessionId != VolSessionId || 
+                            rec->VolSessionTime != VolSessionTime)) {
+        rec->state |= REC_NO_MATCH;
+        return 0;                 /* This is from some other Session */
+      }
+
+      /* if Stream is negative, it means that this is a continuation
        * of a previous partially written record.
        */
       if (Stream < 0) {              /* continuation record? */
@@ -338,9 +346,7 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
         rec->state |= REC_CONTINUATION;
          if (!rec->remainder) {       /* if we didn't read previously */
            rec->data_len = 0;        /* return data as if no continuation */
-        } else if (rec->VolSessionId != VolSessionId || 
-                   rec->VolSessionTime != VolSessionTime ||
-                   rec->Stream != -Stream) {
+        } else if (rec->Stream != -Stream) {
            rec->state |= REC_NO_MATCH;
            return 0;                 /* This is from some other Session */
         }
index 1c9b489b999aee6e13cb50cd525972634bc89615..66e77a2ca858d39a26e1f6f38891f4a18eca5fef 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.25"
 #define VSTRING "1"
-#define DATE    "24 August 2002"
-#define LSMDATE "24Aug02"
+#define DATE    "26 August 2002"
+#define LSMDATE "26Aug02"
 
 /* Debug flags */
 #define DEBUG 1