]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement selecting another Volume if busy + cleanup spool messages
authorKern Sibbald <kern@sibbald.com>
Sat, 13 Mar 2004 08:03:03 +0000 (08:03 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 13 Mar 2004 08:03:03 +0000 (08:03 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1129 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/cats/sql_find.c
bacula/src/console/conio.c
bacula/src/dird/scheduler.c
bacula/src/lib/bnet.c
bacula/src/lib/message.c
bacula/src/stored/append.c
bacula/src/stored/askdir.c
bacula/src/stored/protos.h
bacula/src/stored/spool.c
bacula/src/stored/status.c

index 925b063edce7e1c416bd960862c1a3b9658f509d..6ba773dbe01d1a89adc029ab744f88db0a3823a1 100644 (file)
@@ -250,8 +250,8 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr
           "FirstWritten,LastWritten,VolStatus,InChanger "
           "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
           "%s " 
-          "%s LIMIT 1",
-         mr->PoolId, mr->MediaType, mr->VolStatus, changer, order);
+          "%s LIMIT %d",
+         mr->PoolId, mr->MediaType, mr->VolStatus, changer, order, item);
    }
    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
       db_unlock(mdb);
index fee692718ece3edeeb8c5a5f3ec41c464c34c79e..7447ead95e44beaa45364eab00605c762aad0e5a 100755 (executable)
@@ -834,11 +834,13 @@ static void rawmode(FILE *input)
 
    if (!termtype) {
       printf("Cannot get terminal type.\n");
-      exit(1);
+      normode();
+      _exit(1);
    }
    if (tgetent(term_buffer, termtype) < 0) {
       printf("Cannot get terminal termcap entry.\n");
-      exit(1);
+      normode();
+      _exit(1);
    }
    t_width = t_height = -1;
    t_width = tgetnum("co") - 1;
@@ -989,7 +991,8 @@ static void sigintcatcher(int sig)
 {
    brkflg++;
    if (brkflg > 1) {
-      exit(1);
+      normode();
+      _exit(1);
    }
    signal(SIGINT, sigintcatcher);
 }
index 1595999efa317568bf98c5f261a3895e2273dfd5..bb9008b01eab7e18acf389e7cc2e23dd4ccbd6ba 100644 (file)
@@ -32,7 +32,7 @@
 #include "bacula.h"
 #include "dird.h"
 
-/* #define PHIL */
+/* #define SCHED_DEBUG */
 
 
 /* Local variables */
@@ -315,7 +315,7 @@ static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
     *  do run any job scheduled less than a minute ago.
     */
    if (((runtime - run->last_run) < 61) || ((runtime+59) < now)) {
-#ifdef PHIL
+#ifdef SCHED_DEBUG
       char dt[50], dt1[50], dt2[50];
       bstrftime_nc(dt, sizeof(dt), runtime);  
       bstrftime_nc(dt1, sizeof(dt1), run->last_run);
@@ -352,15 +352,17 @@ static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
       jobs_to_run->append(je);
       dump_job(je, "Appended job");
    }
+#ifdef SCHED_DEBUG
    foreach_dlist(ji, jobs_to_run) {
       dump_job(ji, "Run queue");
    }
    Dmsg0(000, "End run queue\n");
+#endif
 }
 
 static void dump_job(job_item *ji, char *msg) 
 {
-#ifdef PHIL 
+#ifdef SCHED_DEBUG
    char dt[MAX_TIME_LENGTH];
    int save_debug = debug_level;
    debug_level = 200;
index a95d1e5cb44bfb1157b15c9f8fad5770e7980d59..0cc4ccbd47ba7ffa0b9a968f95db12b9a801d032 100644 (file)
@@ -92,7 +92,7 @@ static int32_t write_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
    if (bsock->spool) {
       nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
       if (nwritten != nbytes) {
-         Jmsg1(bsock->jcr, M_ERROR, 0, _("Spool write error. ERR=%s\n"), strerror(errno));
+         Jmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"), strerror(errno));
          Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
         return -1;
       }
@@ -296,14 +296,14 @@ int bnet_despool_to_bsock(BSOCK *bsock)
         nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
         if (nbytes != (size_t)bsock->msglen) {
             Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
-            Jmsg1(bsock->jcr, M_ERROR, 0, _("fread error. ERR=%s\n"), strerror(errno));
+            Jmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), strerror(errno));
            return 0;
         }
       }
       bnet_send(bsock);
    }
    if (ferror(bsock->spool_fd)) {
-      Jmsg1(bsock->jcr, M_ERROR, 0, _("fread error. ERR=%s\n"), strerror(errno));
+      Jmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), strerror(errno));
       return 0;
    }
    return 1;
index c8f9aac557ea908212749300e6ef6657baf1fd08..a5d49d1bd66b1c52f661ff599d2b1c60dee9c630 100755 (executable)
@@ -555,6 +555,7 @@ void dispatch_message(JCR *jcr, int type, int level, char *msg)
 
     if (type == M_ABORT || type == M_ERROR_TERM) {
        fputs(msg, stdout);        /* print this here to INSURE that it is printed */
+       fflush(stdout);
 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
        MessageBox(NULL, msg, "Bacula", MB_OK);
 #endif
@@ -1118,11 +1119,11 @@ again:
       pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2);
       goto again;
    }
-   P(msg_queue_mutex);
    item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + strlen(pool_buf) + 1);
    item->type = type;
    item->level = level;
    strcpy(item->msg, pool_buf);  
+   P(msg_queue_mutex);
    jcr->msg_queue->append(item);
    V(msg_queue_mutex);
    free_memory(pool_buf);
index 9375fd8f7cf7a813a5f77453b56ef298ac177afe..cffb98a4ad744ad5e1ee916d1555785d03dd3131 100644 (file)
@@ -185,7 +185,7 @@ int do_append_data(JCR *jcr)
            if (!write_block_to_device(jcr->dcr, block)) {
                Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
                  dev_name(dev), strerror_dev(dev));
-               Jmsg(jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
+               Jmsg(jcr, M_FATAL, 0, _("Fatal device error: ERR=%s\n"),
                     strerror_dev(dev));
               ok = false;
               break;
index ca692e7636dc7545b7ea6440605458e1905a105e..d8ae98f0cd871261c08d7ead8a48bfb6d643eb1f 100644 (file)
@@ -149,10 +149,44 @@ int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing)
 int dir_find_next_appendable_volume(JCR *jcr)
 {
     BSOCK *dir = jcr->dir_bsock;
+    JCR *njcr;
 
     Dmsg0(200, "dir_find_next_appendable_volume\n");
-    bnet_fsend(dir, Find_media, jcr->Job, 1);
-    return do_get_volume_info(jcr);
+    for (int vol_index=1;  vol_index < 3; vol_index++) {
+       bnet_fsend(dir, Find_media, jcr->Job, vol_index);
+       if (do_get_volume_info(jcr)) {
+          Dmsg1(200, "Got possible Vol=%s\n", jcr->VolumeName);
+         bool found = false;
+         /* 
+          * Walk through all jobs and see if the volume is   
+          *  already mounted. If so, try a different one.
+          * This would be better done by walking through  
+          *  all the devices.
+          */
+         lock_jcr_chain();
+         foreach_jcr(njcr) {
+            if (jcr == njcr) {
+               continue;             /* us */
+            }
+            if (strcmp(jcr->VolumeName, njcr->VolumeName) == 0) {
+               found = true;
+                Dmsg1(200, "Vol in use by JobId=%u\n", njcr->JobId);
+               free_locked_jcr(njcr);
+               break;
+            }
+            free_locked_jcr(njcr);
+         }
+         unlock_jcr_chain();
+         if (!found) {
+             Dmsg0(200, "dir_find_next_appendable_volume return true\n");
+            return true;             /* Got good Volume */
+         }
+       } else {
+         break;
+       }
+    }
+    Dmsg0(200, "dir_find_next_appendable_volume return false\n");
+    return false;
 }
 
     
index 4fd66f71f50e05652800346a5569bf746e8fe312..a81ccb3cd2a4682316db22e089ec9a300ef98f85 100644 (file)
@@ -210,3 +210,5 @@ bool        commit_attribute_spool    (JCR *jcr);
 bool   write_block_to_spool_file (DCR *dcr, DEV_BLOCK *block);
 bool   open_spool_file           (JCR *jcr, BSOCK *bs);
 bool   close_spool_file          (JCR *jcr, BSOCK *bs);
+void   list_spool_stats          (BSOCK *bs);
+
index 367d897a25190ab2c9fa581d8ad016ff9db75c1b..6647df43a75d099fa63027c8cef82f22e0c9c8e6 100644 (file)
 
 /* Forward referenced subroutines */
 static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name);
-static int open_data_spool_file(JCR *jcr);
-static int close_data_spool_file(JCR *jcr);
+static bool open_data_spool_file(JCR *jcr);
+static bool close_data_spool_file(JCR *jcr);
 static bool despool_data(DCR *dcr);
-static int read_block_from_spool_file(DCR *dcr, DEV_BLOCK *block);
+static int  read_block_from_spool_file(DCR *dcr, DEV_BLOCK *block);
+
+struct spool_stats_t {
+   uint32_t data_jobs;               /* current jobs spooling data */
+   uint32_t attr_jobs;               
+   uint32_t total_data_jobs;         /* total jobs to have spooled data */
+   uint32_t total_attr_jobs;
+   uint64_t max_data_size;           /* max data size */
+   uint64_t max_attr_size;
+   uint64_t data_size;               /* current data size (all jobs running) */
+   uint64_t attr_size;
+};
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+spool_stats_t spool_stats;
 
+/* 
+ * Header for data spool record */
 struct spool_hdr {
-   int32_t  FirstIndex;
-   int32_t  LastIndex;
-   uint32_t len;
+   int32_t  FirstIndex;              /* FirstIndex for buffer */
+   int32_t  LastIndex;               /* LastIndex for buffer */
+   uint32_t len;                     /* length of next buffer */
 };
 
 enum {
@@ -47,6 +63,17 @@ enum {
    RB_OK
 };
 
+void list_spool_stats(BSOCK *bs)
+{
+   char ed1[30], ed2[30];
+   bnet_fsend(bs, "Data spooling: %d active jobs %s bytes; %d total jobs %s max bytes/job.\n",
+      spool_stats.data_jobs, edit_uint64_with_commas(spool_stats.data_size, ed1),
+      spool_stats.total_data_jobs, edit_uint64_with_commas(spool_stats.max_data_size, ed2));
+   bnet_fsend(bs, "Attr spooling: %d active jobs; %d total jobs %s max bytes/job.\n",
+      spool_stats.attr_jobs, 
+      spool_stats.total_attr_jobs, edit_uint64_with_commas(spool_stats.max_attr_size, ed2));
+}
+
 bool begin_data_spool(JCR *jcr)
 {
    bool stat = true;
@@ -56,6 +83,10 @@ bool begin_data_spool(JCR *jcr)
       stat = open_data_spool_file(jcr);
       if (stat) {
         jcr->dcr->spooling = true;
+         Jmsg(jcr, M_INFO, 0, _("Spooling data ...\n"));
+        P(mutex);
+        spool_stats.data_jobs++;
+        V(mutex);
       }
    }
    return stat;
@@ -98,7 +129,7 @@ static void make_unique_data_spool_filename(JCR *jcr, POOLMEM **name)
 }
 
 
-static int open_data_spool_file(JCR *jcr)
+static bool open_data_spool_file(JCR *jcr)
 {
    POOLMEM *name  = get_pool_memory(PM_MESSAGE);
    int spool_fd;
@@ -108,19 +139,25 @@ static int open_data_spool_file(JCR *jcr)
       jcr->dcr->spool_fd = spool_fd;
       jcr->spool_attributes = true;
    } else {
-      Jmsg(jcr, M_ERROR, 0, "open data spool file %s failed: ERR=%s\n", name, strerror(errno));
+      Jmsg(jcr, M_ERROR, 0, _("Open data spool file %s failed: ERR=%s\n"), name, strerror(errno));
       free_pool_memory(name);
-      return 0;
+      return false;
     }
     Dmsg1(100, "Created spool file: %s\n", name);
     free_pool_memory(name);
-    return 1;
+    return true;
 }
 
-static int close_data_spool_file(JCR *jcr)
+static bool close_data_spool_file(JCR *jcr)
 {
     POOLMEM *name  = get_pool_memory(PM_MESSAGE);
 
+    P(mutex);
+    spool_stats.data_jobs--;
+    spool_stats.total_data_jobs++;
+    spool_stats.data_size -= jcr->dcr->spool_size;
+    V(mutex);
+
     make_unique_data_spool_filename(jcr, &name);
     close(jcr->dcr->spool_fd);
     jcr->dcr->spool_fd = -1;
@@ -128,7 +165,7 @@ static int close_data_spool_file(JCR *jcr)
     unlink(name);
     Dmsg1(100, "Deleted spool file: %s\n", name);
     free_pool_memory(name);
-    return 1;
+    return true;
 }
 
 static bool despool_data(DCR *dcr)
@@ -176,15 +213,19 @@ static bool despool_data(DCR *dcr)
 
    lseek(rdcr->spool_fd, 0, SEEK_SET); /* rewind */
    if (ftruncate(rdcr->spool_fd, 0) != 0) {
+      Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file error. ERR=%s\n"), 
+        strerror(errno));
       Dmsg1(000, "Bad return from ftruncate. ERR=%s\n", strerror(errno));
       ok = false;
    }
 
+   P(mutex);
+   spool_stats.data_size -= dcr->spool_size;
+   V(mutex);
    P(dcr->dev->spool_mutex);
    dcr->dev->spool_size -= dcr->spool_size;
    dcr->spool_size = 0;              /* zap size in input dcr */
    V(dcr->dev->spool_mutex);
-
    free_memory(rdev->dev_name);
    free_pool_memory(rdev->errmsg);
    free(rdev);
@@ -216,23 +257,23 @@ static int read_block_from_spool_file(DCR *dcr, DEV_BLOCK *block)
       return RB_EOT;
    } else if (stat != (ssize_t)rlen) {
       if (stat == -1) {
-         Jmsg(dcr->jcr, M_FATAL, 0, "Spool read error. ERR=%s\n", strerror(errno));
+         Jmsg(dcr->jcr, M_FATAL, 0, _("Spool header read error. ERR=%s\n"), strerror(errno));
       } else {
          Dmsg2(000, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
-         Jmsg2(dcr->jcr, M_FATAL, 0, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
+         Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool header read error. Wanted %u bytes, got %u\n"), rlen, stat);
       }
       return RB_ERROR;
    }
    rlen = hdr.len;
    if (rlen > block->buf_len) {
       Dmsg2(000, "Spool block too big. Max %u bytes, got %u\n", block->buf_len, rlen);
-      Jmsg2(dcr->jcr, M_FATAL, 0, "Spool block too big. Max %u bytes, got %u\n", block->buf_len, rlen);
+      Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool block too big. Max %u bytes, got %u\n"), block->buf_len, rlen);
       return RB_ERROR;
    }
    stat = read(dcr->spool_fd, (char *)block->buf, (size_t)rlen);
    if (stat != (ssize_t)rlen) {
-      Dmsg2(000, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
-      Jmsg2(dcr->jcr, M_FATAL, 0, "Spool read error. Wanted %u bytes, got %u\n", rlen, stat);
+      Dmsg2(000, "Spool data read error. Wanted %u bytes, got %u\n", rlen, stat);
+      Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool data read error. Wanted %u bytes, got %u\n"), rlen, stat);
       return RB_ERROR;
    }
    /* Setup write pointers */
@@ -262,7 +303,6 @@ bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
 
    ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
    if (block->binbuf <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */
-      Dmsg0(100, "return write_block_to_dev no data to write\n");
       return true;
    }
 
@@ -276,6 +316,12 @@ bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
       despool = true;
    }
    V(dcr->dev->spool_mutex);
+   P(mutex);
+   spool_stats.data_size += hlen + wlen;
+   if (spool_stats.data_size > spool_stats.max_data_size) {
+      spool_stats.max_data_size = spool_stats.data_size;
+   }
+   V(mutex);
    if (despool) {
       char ec1[30], ec2[30], ec3[30], ec4[30];
       Dmsg4(100, "Despool in write_block_to_spool_file max_size=%s size=%s "
@@ -284,15 +330,17 @@ bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
            edit_uint64_with_commas(dcr->spool_size, ec2),
            edit_uint64_with_commas(dcr->dev->max_spool_size, ec3),
            edit_uint64_with_commas(dcr->dev->spool_size, ec4));
-      despool = false;
+      Jmsg(dcr->jcr, M_INFO, 0, _("User specified spool size reached. Despooling ...\n"));
       if (!despool_data(dcr)) {
          Dmsg0(000, "Bad return from despool in write_block.\n");
         return false;
       }
+      /* Despooling cleard these variables so reset them */
       P(dcr->dev->spool_mutex);
       dcr->spool_size += hlen + wlen;
       dcr->dev->spool_size += hlen + wlen;
       V(dcr->dev->spool_mutex);
+      Jmsg(dcr->jcr, M_INFO, 0, _("Spooling data again ...\n"));
    }  
 
    hdr.FirstIndex = block->FirstIndex;
@@ -302,8 +350,12 @@ bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
    /* Write header */
    for ( ;; ) {
       stat = write(dcr->spool_fd, (char*)&hdr, (size_t)hlen);
+      if (stat == -1) {
+         Jmsg(dcr->jcr, M_INFO, 0, _("Error writing header to spool file. ERR=%s\n"), strerror(errno));
+      }
       if (stat != (ssize_t)hlen) {
         if (!despool_data(dcr)) {
+            Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
            return false;
         }
         if (retry++ > 1) {
@@ -317,8 +369,12 @@ bool write_block_to_spool_file(DCR *dcr, DEV_BLOCK *block)
    /* Write data */
    for ( ;; ) {
       stat = write(dcr->spool_fd, block->buf, (size_t)wlen);
+      if (stat == -1) {
+         Jmsg(dcr->jcr, M_INFO, 0, _("Error writing data to spool file. ERR=%s\n"), strerror(errno));
+      }
       if (stat != (ssize_t)wlen) {
         if (!despool_data(dcr)) {
+            Jmsg(dcr->jcr, M_FATAL, 0, _("Fatal despooling error."));
            return false;
         }
         if (retry++ > 1) {
@@ -374,7 +430,7 @@ bool commit_attribute_spool(JCR *jcr)
 
 static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd)
 {
-   Mmsg(name, "%s/%s.spool.%s.%d", working_directory, my_name,
+   Mmsg(name, "%s/%s.attr.spool.%s.%d", working_directory, my_name,
       jcr->Job, fd);
 }
 
@@ -385,10 +441,13 @@ bool open_spool_file(JCR *jcr, BSOCK *bs)
     make_unique_spool_filename(jcr, &name, bs->fd);
     bs->spool_fd = fopen(mp_chr(name), "w+");
     if (!bs->spool_fd) {
-       Jmsg(jcr, M_ERROR, 0, "fopen spool file %s failed: ERR=%s\n", name, strerror(errno));
+       Jmsg(jcr, M_ERROR, 0, _("fopen attr spool file %s failed: ERR=%s\n"), name, strerror(errno));
        free_pool_memory(name);
        return false;
     }
+    P(mutex);
+    spool_stats.attr_jobs++;
+    V(mutex);
     free_pool_memory(name);
     return true;
 }
@@ -396,7 +455,19 @@ bool open_spool_file(JCR *jcr, BSOCK *bs)
 bool close_spool_file(JCR *jcr, BSOCK *bs)
 {
     POOLMEM *name  = get_pool_memory(PM_MESSAGE);
-
+    ssize_t size;
+     
+    fseek(bs->spool_fd, 0, SEEK_END);
+    size = ftell(bs->spool_fd);
+    P(mutex);
+    if (size > 0) {
+       if (spool_stats.attr_size + size > spool_stats.max_attr_size) {
+         spool_stats.max_attr_size = spool_stats.attr_size + size;
+       } 
+    }
+    spool_stats.attr_jobs--;
+    spool_stats.total_attr_jobs++;
+    V(mutex);
     make_unique_spool_filename(jcr, &name, bs->fd);
     fclose(bs->spool_fd);
     unlink(mp_chr(name));
index 45a5dd7f10d39697a9b9930b077754fa265c3ff1..18b08018fdd31bb13ef0d0b8dbc620bc03900254 100644 (file)
@@ -172,6 +172,8 @@ int status_cmd(JCR *jcr)
 #endif
    bnet_fsend(user, "====\n");
 
+   list_spool_stats(user);
+
    bnet_sig(user, BNET_EOD);
    return 1;
 }