]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut new SD lock + restore buffer bug fix
authorKern Sibbald <kern@sibbald.com>
Sun, 25 Aug 2002 21:50:28 +0000 (21:50 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 25 Aug 2002 21:50:28 +0000 (21:50 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@121 91ce42f0-d328-0410-95d8-f526ca767f89

24 files changed:
bacula/src/cats/bdb.c
bacula/src/cats/mysql.c
bacula/src/cats/sqlite.c
bacula/src/dird/restore.c
bacula/src/dird/ua_restore.c
bacula/src/lib/bnet.c
bacula/src/lib/bnet_server.c
bacula/src/lib/cram-md5.c
bacula/src/lib/mem_pool.c
bacula/src/lib/message.c
bacula/src/lib/rwlock.h
bacula/src/stored/acquire.c
bacula/src/stored/authenticate.c
bacula/src/stored/block.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/job.c
bacula/src/stored/parse_bsr.c
bacula/src/stored/protos.h
bacula/src/stored/read.c
bacula/src/stored/record.c

index dea6aff1270f77ce4c6194184a375c7b9e9efe7a..c19fdc5b79ce840b4bdad5bc88438ed71ea46a76 100644 (file)
@@ -142,13 +142,14 @@ db_open_database(B_DB *mdb)
    char *dbf;
    int fd, badctl;
    off_t filend;
+   int errstat;
 
    Dmsg1(200, "db_open_database() %s\n", mdb->db_name);
 
    P(mutex);
 
-   if (rwl_init(&mdb->lock) != 0) {
-      Mmsg1(&mdb->errmsg, "Unable to initialize DB lock. ERR=%s\n", strerror(errno));
+   if ((errstat=rwl_init(&mdb->lock)) != 0) {
+      Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), strerror(errstat));
       V(mutex);
       return 0;
    }
@@ -158,7 +159,7 @@ db_open_database(B_DB *mdb)
    mdb->cfd = open(dbf, O_CREAT|O_RDWR, 0600); 
    free_memory(dbf);
    if (mdb->cfd < 0) {
-      Mmsg2(&mdb->errmsg, "Unable to open Catalog DB control file %s: ERR=%s\n"
+      Mmsg2(&mdb->errmsg, _("Unable to open Catalog DB control file %s: ERR=%s\n")
         dbf, strerror(errno));
       V(mutex);
       return 0;
@@ -213,12 +214,12 @@ db_open_database(B_DB *mdb)
    badctl = 0;
    lseek(mdb->cfd, 0, SEEK_SET);      /* seek to begining of control file */
    if (read(mdb->cfd, &mdb->control, sizeof(mdb->control)) != sizeof(mdb->control)) {
-      Mmsg1(&mdb->errmsg, "Error reading catalog DB control file. ERR=%s\n", strerror(errno));
+      Mmsg1(&mdb->errmsg, _("Error reading catalog DB control file. ERR=%s\n"), strerror(errno));
       badctl = 1;
    } else if (mdb->control.bdb_version != BDB_VERSION) {
-      Mmsg2(&mdb->errmsg, "Error, catalog DB control file wrong version. \
+      Mmsg2(&mdb->errmsg, _("Error, catalog DB control file wrong version. \
 Wanted %d, got %d\n\
-Please reinitialize the working directory.\n", 
+Please reinitialize the working directory.\n")
         BDB_VERSION, mdb->control.bdb_version);
       badctl = 1;
    }
index 89539ccc646da6bc755038b4cd2d9f5709ddf2a5..b4f139f65bf41a15b003aeef68d3d431db9f3f6a 100644 (file)
@@ -96,6 +96,8 @@ db_init_database(void *jcr, char *db_name, char *db_user, char *db_password)
 int
 db_open_database(B_DB *mdb)
 {
+   int errstat;
+
    P(mutex);
    if (mdb->connected) {
       V(mutex);
@@ -103,8 +105,9 @@ db_open_database(B_DB *mdb)
    }
    mdb->connected = FALSE;
 
-   if (rwl_init(&mdb->lock) != 0) {
-      Mmsg1(&mdb->errmsg, "Unable to initialize DB lock. ERR=%s\n", strerror(errno));
+   if ((errstat=rwl_init(&mdb->lock)) != 0) {
+      Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), 
+           strerror(errstat));
       V(mutex);
       return 0;
    }
index 4628f698c8bd4dc82580f6d8b0b3e22a59953393..1e9781906ecaa0a82b09cf191ad9a94ca28bc628 100644 (file)
@@ -100,6 +100,7 @@ db_open_database(B_DB *mdb)
    char *db_name;
    int len;
    struct stat statbuf;
+   int errstat;
 
    P(mutex);
    if (mdb->connected) {
@@ -108,8 +109,9 @@ db_open_database(B_DB *mdb)
    }
    mdb->connected = FALSE;
 
-   if (rwl_init(&mdb->lock) != 0) {
-      Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), strerror(errno));
+   if ((errstat=rwl_init(&mdb->lock)) != 0) {
+      Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), 
+           strerror(errstat));
       V(mutex);
       return 0;
    }
index 1cae3457ca1cec4462ac4ae2017d8abeb077df6a..8414843c52298aa2b3899c493cd797e8eaf715b9 100644 (file)
@@ -69,7 +69,6 @@ static int send_bootstrap_file(JCR *jcr);
  */
 int do_restore(JCR *jcr) 
 {
-   char dt[MAX_TIME_LENGTH];
    BSOCK   *fd;
    JOB_DBR rjr;                      /* restore job record */
    int ok = FALSE;
@@ -129,10 +128,7 @@ int do_restore(JCR *jcr)
       
 
    /* Print Job Start message */
-   bstrftime(dt, sizeof(dt), jcr->start_time);
-   Jmsg(jcr, M_INFO, 0, _("%s Start Restore Job %s Name=%s, Client=%s, FileSet=%s\n"), 
-      dt, jcr->Job, jcr->job->hdr.name, jcr->client->hdr.name, 
-      jcr->fileset->hdr.name);
+   Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job);
 
    /*
     * Open a message channel connection with the Storage
index 97104ebe643846d9398e4b64062dc3f155ad0acf..be073043d2c5f4c104139b2bc6a9ae26fbc8c3fe 100644 (file)
@@ -225,7 +225,11 @@ int restorecmd(UAContext *ua, char *cmd)
    free_tree(tree.root);             /* free the directory tree */
 
    if (bsr->JobId) {
-      complete_bsr(ua, bsr);         /* find Vol, SessId, SessTime from JobIds */
+      if (!complete_bsr(ua, bsr)) {   /* find Vol, SessId, SessTime from JobIds */
+         bsendmsg(ua, _("Unable to construct a valid BSR. Cannot continue.\n"));
+        free_bsr(bsr);
+        return 0;
+      }
 //    print_bsr(ua, bsr);
       write_bsr_file(ua, bsr);
    } else {
@@ -1117,7 +1121,9 @@ static void free_name_list(NAME_LIST *name_list)
    for (i=0; i < name_list->num_ids; i++) {
       free(name_list->name[i]);
    }
-   free(name_list->name);
+   if (name_list->name) {
+      free(name_list->name);
+   }
    name_list->max_ids = 0;
    name_list->num_ids = 0;
 }
@@ -1135,6 +1141,12 @@ static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, JobI
       return;
    }
 
+   if (name_list->num_ids == 0) {
+      bsendmsg(ua, _("No MediaType found for your JobIds.\n"));
+      ji->store = select_storage_resource(ua);
+      return;
+   }
+
    start_prompt(ua, _("The defined Storage resources are:\n"));
    LockRes();
    while ((store = (STORE *)GetNextRes(R_STORAGE, (RES *)store))) {
index 670bdd4d5acbceba88058831f36f9701c6033662..48aa1ee65014105ff93026e456d7af062e29556c 100644 (file)
@@ -657,10 +657,24 @@ bnet_close(BSOCK *bsock)
 void
 term_bsock(BSOCK *bsock)
 {
-   free_pool_memory(bsock->msg);
-   free_pool_memory(bsock->errmsg);
-   free(bsock->who);
-   free(bsock->host);
+   if (bsock->msg) {
+      free_pool_memory(bsock->msg);
+      bsock->msg = NULL;
+   } else {
+      ASSERT(1=0);                   /* double close */
+   }
+   if (bsock->errmsg) {
+      free_pool_memory(bsock->errmsg);
+      bsock->errmsg = NULL;
+   }
+   if (bsock->who) {
+      free(bsock->who);
+      bsock->who = NULL;
+   }
+   if (bsock->host) {
+      free(bsock->host);
+      bsock->host = NULL;
+   }
    free(bsock);
 }
  
index 1c2150226e9765a5e714e50159b85941e77048e9..0b9f6ebee29e8334edcf3551e89c22e9c6275e0e 100644 (file)
@@ -201,7 +201,7 @@ bnet_bind(int port)
       sleep(5);
    }
    listen(sockfd, 1);                /* tell system we are ready */
-   return init_bsock(sockfd, _("Server socket"), _("client"), port);
+   return init_bsock(NULL, sockfd, _("Server socket"), _("client"), port);
 }
 
 /*
@@ -290,7 +290,7 @@ bnet_accept(BSOCK *bsock, char *who)
       strcpy(buf, who);
       strcat(buf, ": ");
       strcat(buf, caller);
-      bs = init_bsock(newsockfd, "client", buf, bsock->port);
+      bs = init_bsock(NULL, newsockfd, "client", buf, bsock->port);
       free(buf);
       return bs;                     /* return new BSOCK */
    }
index f1658044e9f5039aa9d382b793526e0b8db17bf9..f40b35dffff0d5c8fac9e98658abeb50d25f0c3b 100644 (file)
@@ -57,7 +57,7 @@ int cram_md5_auth(BSOCK *bs, char *password)
    bin_to_base64(host, (char *)hmac, 16);
    ok = strcmp(bs->msg, host) == 0;
    if (ok) {
-      Dmsg3(399, "Authenticate %s: wanted %s, got %s\n", 
+      Dmsg3(99, "Authenticate %s: wanted %s, got %s\n", 
             ok ? "OK" : "NOT OK", host, bs->msg);
    } else {
       Dmsg3(99, "Authenticate %s: wanted %s, got %s\n", 
@@ -82,6 +82,7 @@ int cram_md5_get_auth(BSOCK *bs, char *password)
       return 0;
    }
    if (sscanf(bs->msg, "auth cram-md5 %s", chal) != 1) {
+     Dmsg1(99, "Wanted auth cram... Got: %s\n", bs->msg);
      sleep(5);
      return 0;
    }
index 9eddd47ad156afabba40afea7dd2abe085e33a68..2af3a7b8b678f26da3bb270c4587ca67290cc9ea 100644 (file)
@@ -195,6 +195,10 @@ void free_pool_memory(POOLMEM *obuf)
    if (pool == 0) {
       free((char *)buf);             /* free nonpooled memory */
    } else {                          /* otherwise link it to the free pool chain */
+      struct abufhead *next;
+      for (next=pool_ctl[pool].free_buf; next; next=next->next) {
+        ASSERT(next != buf);  /* attempt to free twice */
+      }
       buf->next = pool_ctl[pool].free_buf;
       pool_ctl[pool].free_buf = buf;
    }
index 003b76a0a451c01e7e20b0900a7df3b3305e9192..09d58ec275ef405595f1dcfb01c4ab67d3b452b7 100755 (executable)
@@ -461,7 +461,7 @@ void close_msg(void *vjcr)
    if (msgs == NULL) {
       return;
    }
-   Dmsg1(050, "close msg resource at 0x%x\n", msgs);
+   Dmsg1(150, "begin close msg resource at 0x%x\n", msgs);
    cmd = get_pool_memory(PM_MESSAGE);
    for (d=msgs->dest_chain; d; ) {
       if (d->fd) {
@@ -521,6 +521,7 @@ rem_temp_file:
 
    free_msgs_res(msgs);
    msgs = NULL;
+   Dmsg0(150, "end close msg resource\n");
 }
 
 /*
index 6e2a5942389c4cd2250d17737990bc1ec08a309a..4b7ca78852c03f7f7aa0196d0b38833514ca3f05 100644 (file)
@@ -45,6 +45,12 @@ typedef struct s_rwlock_tag {
    int               w_wait;          /* writers waiting */
 } brwlock_t;
 
+typedef struct s_rwsteal_tag {
+   pthread_t         writer_id;       /* writer's thread id */
+   int               state;
+} brwsteal_t;
+
+
 #define RWLOCK_VALID  0xfacade
 
 #define RWL_INIIALIZER \
index 8ec4bb3766c0add199a05f97e991ec5bc6b0b209..9c39b0391fd468c2def6e0170db5e5a899fd621f 100644 (file)
@@ -41,9 +41,11 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 {
    int stat;
 
+   new_lock_device_state(dev, BST_DOING_ACQUIRE);
    lock_device(dev);
    if (dev->state & ST_READ || dev->num_writers > 0) {
       Jmsg(jcr, M_FATAL, 0, _("Device %s is busy.\n"), dev_name(dev));
+      new_unlock_device(dev);
       unlock_device(dev);
       return 0;
    }
@@ -51,9 +53,12 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    block_device(dev, BST_DOING_ACQUIRE);
    unlock_device(dev);
    stat = ready_dev_for_read(jcr, dev, block); 
+#ifndef NEW_LOCK
    P(dev->mutex); 
    unblock_device(dev);
    V(dev->mutex);
+#endif
+   new_unlock_device(dev);
    return stat;
 }
 
@@ -69,6 +74,7 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    int release = 0;
    int do_mount = 0;
 
+   new_lock_device_state(dev, BST_DOING_ACQUIRE);
    lock_device(dev);
    Dmsg1(190, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
 
@@ -91,6 +97,7 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
         if (dev->num_writers != 0) {
             Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing with another Volume.\n"), dev_name(dev));
            unlock_device(dev);
+           new_unlock_device(dev);
            return 0;
         }
         /* Wrong tape mounted, release it, then fall through to get correct one */
@@ -102,6 +109,7 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       if (dev->state & ST_READ) {
          Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev));
         unlock_device(dev);
+        new_unlock_device(dev);
         return 0;
       } 
       ASSERT(dev->num_writers == 0);
@@ -114,13 +122,18 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       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));
+#ifndef NEW_LOCK
         P(dev->mutex);
         unblock_device(dev);
         unlock_device(dev);
+#endif
+        new_unlock_device(dev);
         return 0;
       }
+#ifndef NEW_LOCK
       P(dev->mutex);
       unblock_device(dev);
+#endif
    }
 
    dev->num_writers++;
@@ -133,6 +146,7 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    }
    attach_jcr_to_device(dev, jcr);    /* attach jcr to device */
    unlock_device(dev);
+   new_unlock_device(dev);
    return 1;                         /* got it */
 }
 
@@ -143,7 +157,10 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
  */
 int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 {
+#ifndef NEW_LOCK
    P(dev->mutex);
+#endif
+   new_lock_device(dev);
    Dmsg1(100, "release_device device is %s\n", dev_is_tape(dev)?"tape":"disk");
    if (dev->state & ST_READ) {
       dev->state &= ~ST_READ;        /* clear read bit */
@@ -183,7 +200,10 @@ int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       Jmsg1(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s not in use.\n"), dev_name(dev));
    }
    detach_jcr_from_device(dev, jcr);
+#ifndef NEW_LOCK
    V(dev->mutex);
+#endif
+   new_unlock_device(dev);
    return 1;
 }
 
index be18fb9ca0f6020b653c7371f45d218a518e640e..1709705960e3f3c6379dc17cef1c60d827e5e92c 100644 (file)
@@ -39,15 +39,15 @@ static char OK_hello[]  = "3000 OK Hello\n";
  */
 static int authenticate(int rcode, BSOCK *bs)
 {
-   char *name;
+   POOLMEM *name;
    DIRRES *director = NULL;
 
    if (rcode != R_DIRECTOR) {
       Emsg1(M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode);
       return 0;
    }
-   name = (char *) get_pool_memory(PM_MESSAGE);
-   name = (char *) check_pool_memory_size(name, bs->msglen);
+   name = get_pool_memory(PM_MESSAGE);
+   name = check_pool_memory_size(name, bs->msglen);
 
    if (sscanf(bs->msg, "Hello Director %127s calling\n", name) != 1) {
       Emsg1(M_FATAL, 0, _("Bad Hello command from Director: %s\n"), bs->msg);
index 22ad24def51ff1406b922573a24dfbfde674664a..312c3ab65b6b085b81f9bc96a258fb2c2e056c42 100644 (file)
@@ -240,10 +240,12 @@ static int unser_block_header(DEVICE *dev, DEV_BLOCK *block)
 int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 {
    int stat = 1;
+   new_lock_device(dev);
    lock_device(dev);
    if (!write_block_to_dev(dev, block)) {
        stat = fixup_device_block_write_error(jcr, dev, block);
    }
+   new_unlock_device(dev);
    unlock_device(dev);
    return stat;
 }
@@ -368,8 +370,10 @@ int read_block_from_device(DEVICE *dev, DEV_BLOCK *block)
 {
    int stat;
    Dmsg0(90, "Enter read_block_from_device\n");
+   new_lock_device(dev);
    lock_device(dev);
    stat = read_block_from_dev(dev, block);
+   new_unlock_device(dev);
    unlock_device(dev);
    Dmsg0(90, "Leave read_block_from_device\n");
    return stat;
index b2db38f144d8a469497da94a68f5e55a84b21721..63fef7f34c5445fee88aaf150b003b30f7e175ad 100644 (file)
@@ -270,7 +270,7 @@ static void do_setup(char *infname)
    }
 
    pm_strcpy(&jcr->VolumeName, VolName);
-   Dmsg1(000, "Volume=%s\n", jcr->VolumeName);
+   Dmsg1(100, "Volume=%s\n", jcr->VolumeName);
    if (!acquire_device_for_read(jcr, dev, block)) {
       Emsg0(M_ERROR, 0, dev->errmsg);
       exit(1);
index 4f5773f2b0287f2671e220cba4f7c0f9785270d5..7882e678b7e956aabd29daeace0ba454832dc88d 100644 (file)
@@ -138,12 +138,17 @@ init_dev(DEVICE *dev, char *dev_name)
    if (tape) {
       dev->state |= ST_TAPE;
    }
-   dev->dev_name = (char *) get_memory(strlen(dev_name)+1);
+   dev->dev_name = get_memory(strlen(dev_name)+1);
    strcpy(dev->dev_name, dev_name);
 
-   dev->errmsg = (char *) get_pool_memory(PM_EMSG);
+   dev->errmsg = get_pool_memory(PM_EMSG);
    *dev->errmsg = 0;
 
+   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);
+   }
+
    if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) {
       dev->dev_errno = errstat;
       Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
@@ -1068,6 +1073,7 @@ term_dev(DEVICE *dev)
       free_pool_memory(dev->errmsg);
       dev->errmsg = NULL;
    }
+   rwl_destroy(&dev->lock);
    pthread_mutex_destroy(&dev->mutex);
    pthread_cond_destroy(&dev->wait);
    pthread_cond_destroy(&dev->wait_next_vol);
index 908ea0201d7df8211b87086b38283e66422de502..a6c263ab187b14efdc0269c23e4b8c1a9877dbe3 100644 (file)
 #ifndef __DEV_H
 #define __DEV_H 1
 
+/* #define NEW_LOCK 1 */
+
+#define new_lock_device(dev)             _lock_device(__FILE__, __LINE__, (dev)) 
+#define new_lock_device_state(dev,state) _lock_device(__FILE__, __LINE__, (dev), (state))
+#define new_unlock_device(dev)           _unlock_device(__FILE__, __LINE__, (dev))
+
 /* Arguments to open_dev() */
 #define READ_WRITE 0
 #define READ_ONLY  1
@@ -108,6 +114,7 @@ typedef struct s_volume_catalog_info {
 typedef struct s_device {
    struct s_device *next;             /* pointer to next open device */
    void *attached_jcrs;               /* attached JCR list */
+   brwlock_t lock;                    /* new device locking mechanism */
    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 4f21e2fdb6fce3fed3542946bf5402f339b6d509..24adab2ebe6e0f08ab6b1481f591088ae2de2a51 100644 (file)
@@ -82,6 +82,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    if (stat & MT_EOD) {
       Dmsg0(190, "======= Got EOD ========\n");
 
+      new_lock_device_state(dev, BST_DOING_ACQUIRE);
       block_device(dev, BST_DOING_ACQUIRE);
 
       /* 
@@ -105,6 +106,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) {   /* send Volume info to Director */
          Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"),
            dev->VolCatInfo.VolCatName, jcr->Job);
+        new_unlock_device(dev);
         return 0;                    /* device locked */
       }
       Dmsg0(190, "Back from update_vol_info\n");
@@ -122,12 +124,16 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
       /* Unlock, but leave BLOCKED */
       unlock_device(dev);
       if (!mount_next_write_volume(jcr, dev, label_blk, 1)) {
+        new_unlock_device(dev);
+#ifndef NEW_LOCK
         P(dev->mutex);
+#endif
         unblock_device(dev);
         return 0;                    /* device locked */
       }
-
+#ifndef NEW_LOCK
       P(dev->mutex);                 /* lock again */
+#endif
 
       Jmsg(jcr, M_INFO, 0, _("New volume %s mounted on device %s\n"),
         jcr->VolumeName, dev_name(dev));
@@ -143,6 +149,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
          Pmsg1(0, "write_block_to_device Volume label failed. ERR=%s",
           strerror_dev(dev));
         free_block(label_blk);
+        new_unlock_device(dev);
         unblock_device(dev);
         return 0;                    /* device locked */
       }
@@ -153,6 +160,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
          Pmsg1(0, "write_block_to_device overflow block failed. ERR=%s",
           strerror_dev(dev));
         free_block(label_blk);
+        new_unlock_device(dev);
         unblock_device(dev);
         return 0;                    /* device locked */
       }
@@ -167,12 +175,14 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
         mjcr->VolFirstFile = mjcr->JobFiles;
         mjcr->run_time += time(NULL) - wait_time; /* correct run time */
       }
+      new_unlock_device(dev);
       unblock_device(dev);
       return 1;                               /* device locked */
    }
    if (label_blk) {
       free_block(label_blk);
    }
+   new_unlock_device(dev);
    return 0;                         /* device locked */
 }
 
@@ -198,11 +208,13 @@ int open_device(DEVICE *dev)
       return 0;
    }
 
+   new_lock_device(dev);
    lock_device(dev);
 
    /* Defer opening files */
    if (!dev_is_tape(dev)) {
       Dmsg0(129, "Device is file, deferring open.\n");
+      new_unlock_device(dev);
       unlock_device(dev);
       return 1;
    }
@@ -211,17 +223,18 @@ int open_device(DEVICE *dev)
       Dmsg0(129, "Opening device.\n");
       if (open_dev(dev, NULL, READ_WRITE) < 0) {
          Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
+        new_unlock_device(dev);
         unlock_device(dev);
         return 0;
       }
    }
    Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
 
+   new_unlock_device(dev);
    unlock_device(dev);
    return 1;
 }
 
-
 /* 
  * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
  * must wait. The no_wait_id thread is out obtaining a new volume
@@ -229,8 +242,8 @@ int open_device(DEVICE *dev)
  */
 void lock_device(DEVICE *dev)
 {
+#ifndef NEW_LOCK
    int stat;
-
    Dmsg1(190, "lock %d\n", dev->dev_blocked);
    P(dev->mutex);
    if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
@@ -244,12 +257,15 @@ void lock_device(DEVICE *dev)
       }
       dev->num_waiting--;            /* no longer waiting */
    }
+#endif
 }
 
 void unlock_device(DEVICE *dev) 
 {
+#ifndef NEW_LOCK
    Dmsg0(190, "unlock\n");
    V(dev->mutex);
+#endif
 }
 
 /* 
@@ -262,10 +278,12 @@ void unlock_device(DEVICE *dev)
  */
 void block_device(DEVICE *dev, int state)
 {
+#ifndef NEW_LOCK
    Dmsg1(190, "block set %d\n", state);
    ASSERT(dev->dev_blocked == BST_NOT_BLOCKED);
    dev->dev_blocked = state;         /* make other threads wait */
    dev->no_wait_id = pthread_self();  /* allow us to continue */
+#endif
 }
 
 /*
@@ -273,10 +291,74 @@ void block_device(DEVICE *dev, int state)
  */
 void unblock_device(DEVICE *dev)
 {
+#ifndef NEW_LOCK
    Dmsg1(190, "unblock %d\n", dev->dev_blocked);
    ASSERT(dev->dev_blocked);
    dev->dev_blocked = BST_NOT_BLOCKED;
    if (dev->num_waiting > 0) {
       pthread_cond_broadcast(&dev->wait); /* wake them up */
    }
+#endif
+}
+
+/*
+ * New device locking scheme 
+ */
+void _lock_device(char *file, int line, DEVICE *dev)
+{
+#ifdef NEW_LOCK
+   int errstat;
+   if ((errstat=rwl_writelock(&dev->lock)) != 0) {
+      e_msg(file, line, M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
+          strerror(errstat));
+   }
+#endif
+}    
+
+void _lock_device(char *file, int line, DEVICE *dev, int state)
+{
+#ifdef NEW_LOCK
+   int errstat;
+   if ((errstat=rwl_writelock(&dev->lock)) != 0) {
+      e_msg(file, line, M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
+          strerror(errstat));
+   }
+   dev->dev_blocked = state;
+#endif
+}    
+
+void _unlock_device(char *file, int line, DEVICE *dev)
+{
+#ifdef NEW_LOCK
+   int errstat;
+   if (dev->lock.w_active == 1) {
+      dev->dev_blocked = BST_NOT_BLOCKED;
+   }
+   if ((errstat=rwl_writeunlock(&dev->lock)) != 0) {
+      e_msg(file, line, M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n",
+          strerror(errstat));
+   }
+#endif
+}    
+
+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;
+   dev->lock.writer_id = pthread_self();
+   V(dev->lock.mutex);
+#endif
+}
+
+void new_return_device_lock(DEVICE *dev, brwsteal_t *hold)          
+{
+#ifdef NEW_LOCK
+   P(dev->lock.mutex);
+   dev->dev_blocked = hold->state;
+   dev->lock.writer_id = hold->writer_id;
+   V(dev->lock.mutex);
+#endif
 }
index 26bd3cbffa113e2f351b9bd2e8ff7700bde16e71..759dd2fa2a700caaba49cd02986c379e69d061fc 100644 (file)
@@ -257,6 +257,7 @@ static int label_cmd(JCR *jcr)
         /******FIXME**** compare MediaTypes */
         jcr->device = device;
         dev = device->dev;
+
         P(dev->mutex);
         if (!(dev->state & ST_OPENED)) {
            if (open_dev(dev, volname, READ_WRITE) < 0) {
@@ -306,15 +307,19 @@ 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;
    
    blocked = dev->dev_blocked;       /* save any prev blocked state */
-   no_wait_id = dev->no_wait_id;
    dev->dev_blocked = BST_WRITING_LABEL;
+   no_wait_id = dev->no_wait_id;
    dev->no_wait_id = pthread_self();  /* let us use the tape */
-   V(dev->mutex);                    /* release lock */
+#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)) {               
@@ -339,8 +344,11 @@ Unknown status %d from read_volume_label()\n"), jcr->label_status);
    }
    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 */
+#endif
 }
 
 
@@ -351,16 +359,20 @@ Unknown status %d from read_volume_label()\n"), jcr->label_status);
  */
 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;
-   int stat;
    
    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 */
+#endif
+   new_steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
    V(dev->mutex);                    /* release lock */
    
    jcr->VolumeName[0] = 0;
@@ -379,8 +391,11 @@ static int read_label(JCR *jcr, DEVICE *dev)
    }
    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 */
+#endif
    return stat;
 }
 
@@ -436,6 +451,7 @@ static int mount_cmd(JCR *jcr)
               if (dev->dev_blocked == BST_UNMOUNTED) {
                   Dmsg0(90, "Unmounted unblocking device\n");
                  read_label(jcr, dev);
+                 new_unlock_device(dev);
                  unblock_device(dev);
               } else {
                   Dmsg0(90, "Unmounted waiting for mount attempt to wake thread\n");
@@ -571,6 +587,7 @@ static int unmount_cmd(JCR *jcr)
 
         } else {                     /* device not being used */
             Dmsg0(90, "Device not in use, unmounting\n");
+           new_lock_device_state(dev, BST_UNMOUNTED);
            block_device(dev, BST_UNMOUNTED);
            if (dev->capabilities & CAP_OFFLINEUNMOUNT) {
               offline_dev(dev);
index 68aec7c356cb5b738693af24057630414a4b6312..1181641bed46df5f0af078df8fe216eb3a5dbbcc 100644 (file)
@@ -308,6 +308,7 @@ void stored_free_jcr(JCR *jcr)
 {
    if (jcr->file_bsock) {
       bnet_close(jcr->file_bsock);
+      jcr->file_bsock = NULL;
    }
    if (jcr->pool_name) {
       free_memory(jcr->pool_name);
index 7daab8c21ce39f1c5748ddc75194780f2a75a0c8..ca141da4b9e2e44c91aa48d9a8a5d6120f6366df 100755 (executable)
@@ -698,6 +698,9 @@ void create_vol_list(JCR *jcr)
    jcr->CurVolume = 1;
    if (jcr->bsr) {
       BSR *bsr = jcr->bsr;
+      if (!bsr->volume || !bsr->volume->VolumeName) {
+        return;
+      }
       strcpy(jcr->VolumeName, bsr->volume->VolumeName); /* setup first volume */
       for ( ; bsr; bsr=bsr->next) {
         BSR_VOLUME *bsrvol = bsr->volume;
index 62872c20057b1a55e8a4bfba7456149d016037c8..c43d312de584b250b5feeda029941350384f9f5d 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);
+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);
+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 */
@@ -150,8 +155,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 5f9fdaa931ed34828137d4f75b4f2cebdfe8b55d..59851434f0d15a2f4609735020d77abf3373e33f 100644 (file)
@@ -95,6 +95,7 @@ int do_read_data(JCR *jcr)
    }
 
    rec = new_record();
+   free_pool_memory(rec->data);
    rec->data = ds->msg;               /* use socket message buffer */
    hdr = get_pool_memory(PM_MESSAGE);
 
@@ -207,6 +208,7 @@ int do_read_data(JCR *jcr)
         if (!bnet_fsend(ds, rec_header, rec->VolSessionId, rec->VolSessionTime,
                rec->FileIndex, rec->Stream, rec->data_len)) {
             Dmsg1(30, ">filed: Error Hdr=%s\n", ds->msg);
+           hdr = ds->msg;
            ds->msg = rec->data;
            ok = FALSE;
            break;
@@ -214,7 +216,8 @@ int do_read_data(JCR *jcr)
             Dmsg1(30, ">filed: Hdr=%s\n", ds->msg);
         }
 
-        ds->msg = rec->data;             /* restore data record address */
+        hdr = ds->msg;               /* restore hdr buffer */
+        ds->msg = rec->data;         /* restore data record address */
 
         /* Send data record to File daemon */
         ds->msglen = rec->data_len;
@@ -235,6 +238,7 @@ int do_read_data(JCR *jcr)
    }
    free_pool_memory(hdr);
    free_block(block);
+   rec->data = NULL;                 /* previously released */
    free_record(rec);
    free_vol_list(jcr);
    Dmsg0(30, "Done reading.\n");
index 2183f49817119d763a31978456ad5a7c7c04d2db..eebb5af25ba07a5b9690e4d13a89defac246d787 100644 (file)
@@ -107,7 +107,9 @@ DEV_RECORD *new_record(void)
 void free_record(DEV_RECORD *rec) 
 {
    Dmsg0(150, "Enter free_record.\n");
-   free_pool_memory(rec->data);
+   if (rec->data) {
+      free_pool_memory(rec->data);
+   }
    Dmsg0(150, "Data buf is freed.\n");
    free_pool_memory((POOLMEM *)rec);
    Dmsg0(150, "Leave free_record.\n");