]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Attempt to correct problems with restores with autochangers and
authorKern Sibbald <kern@sibbald.com>
Sun, 9 Mar 2008 21:17:42 +0000 (21:17 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 9 Mar 2008 21:17:42 +0000 (21:17 +0000)
     use counts going negative
kes  Rework SD status command and implement API for bat. Implements
     header, runing waitreservation, devices, volumes, spooling,
     and terminated status keywords.
     .status storage=xxx <keyword>
kes  Clarify TLS error message by adding double quotes around name.
kes  Simplify SD/FD status code by putting api flag in STATUS_PKT

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

bacula/src/dird/dird_conf.h
bacula/src/dird/jobq.c
bacula/src/filed/status.c
bacula/src/lib/bnet.c
bacula/src/lib/status.h
bacula/src/stored/spool.c
bacula/src/stored/status.c
bacula/technotes-2.3

index 879ae17f8abeea8ada37a72b6ae2065bfa609fd9..2fad99e1572dfe8597030c89731fff70b0b2004e 100644 (file)
@@ -290,6 +290,7 @@ public:
    alist *device;                     /* Alternate devices for this Storage */
    uint32_t MaxConcurrentJobs;        /* Maximume concurrent jobs */
    uint32_t NumConcurrentJobs;        /* number of concurrent jobs running */
+   uint32_t NumConcurrentReadJobs;    /* number of jobs reading */
    char *tls_ca_certfile;             /* TLS CA Certificate File */
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Client Certificate File */
index 308acd77307b378da3f8f44bd505cebba34b39ae..f9f91515a81bbd161005e4c8f8c909b02fde6074 100644 (file)
@@ -56,8 +56,8 @@ extern "C" void *sched_wait(void *arg);
 
 static int  start_server(jobq_t *jq);
 static bool acquire_resources(JCR *jcr);
-
-
+static void dec_read_store(JCR *jcr);
+static void dec_write_store(JCR *jcr);
 
 /*
  * Initialize a job queue
@@ -477,16 +477,8 @@ void *jobq_server(void *arg)
           *  put into the ready queue.
           */
          if (jcr->acquired_resource_locks) {
-            if (jcr->rstore) {
-               jcr->rstore->NumConcurrentJobs--;
-               Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-               ASSERT(jcr->rstore->NumConcurrentJobs >= 0);
-            }
-            if (jcr->wstore) {
-               jcr->wstore->NumConcurrentJobs--;
-               Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-               ASSERT(jcr->wstore->NumConcurrentJobs >= 0);
-            }
+            dec_read_store(jcr);
+            dec_write_store(jcr);
             jcr->client->NumConcurrentJobs--;
             jcr->job->NumConcurrentJobs--;
             jcr->acquired_resource_locks = false;
@@ -692,13 +684,16 @@ static bool acquire_resources(JCR *jcr)
    }
    if (jcr->rstore) {
       Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
-      if (jcr->rstore->NumConcurrentJobs == 0 &&
+      if (jcr->rstore->NumConcurrentReadJobs == 0 &&
           jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) {
          /* Simple case, first job */
-         jcr->rstore->NumConcurrentJobs = 1;
+         jcr->rstore->NumConcurrentReadJobs = 1;
+         jcr->rstore->NumConcurrentJobs++;
          Dmsg0(200, "Set rncj=1\n");
       /* We can do this only if multi-drive autochanger */
-//    } else if (jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) {
+//    } else if (jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs
+//       && jcr->rstore->NumConcurrentReadJobs < jcr->rstore->MaxConcurrentReadJobs) {
+//       jcr->rstore->NumConcurrentReadJobs++;
 //       jcr->rstore->NumConcurrentJobs++;
 //       Dmsg1(200, "Inc rncj=%d\n", jcr->rstore->NumConcurrentJobs);
       } else {
@@ -719,9 +714,7 @@ static bool acquire_resources(JCR *jcr)
          jcr->wstore->NumConcurrentJobs++;
          Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
       } else if (jcr->rstore) {
-         jcr->rstore->NumConcurrentJobs--;        /* back out rstore */
-         Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-         ASSERT(jcr->rstore->NumConcurrentJobs >= 0);
+         dec_read_store(jcr);
          skip_this_jcr = true;
       } else {
          Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
@@ -737,16 +730,8 @@ static bool acquire_resources(JCR *jcr)
       jcr->client->NumConcurrentJobs++;
    } else {
       /* Back out previous locks */
-      if (jcr->wstore) {
-         jcr->wstore->NumConcurrentJobs--;
-         Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-         ASSERT(jcr->wstore->NumConcurrentJobs >= 0);
-      }
-      if (jcr->rstore) {
-         jcr->rstore->NumConcurrentJobs--;  
-         Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-         ASSERT(jcr->rstore->NumConcurrentJobs >= 0);
-      }
+      dec_write_store(jcr);
+      dec_read_store(jcr);
       set_jcr_job_status(jcr, JS_WaitClientRes);
       return false;
    }
@@ -754,16 +739,8 @@ static bool acquire_resources(JCR *jcr)
       jcr->job->NumConcurrentJobs++;
    } else {
       /* Back out previous locks */
-      if (jcr->wstore) {
-         jcr->wstore->NumConcurrentJobs--;
-         Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-         ASSERT(jcr->wstore->NumConcurrentJobs >= 0);
-      }
-      if (jcr->rstore) {
-         jcr->rstore->NumConcurrentJobs--;
-         Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-         ASSERT(jcr->rstore->NumConcurrentJobs >= 0);
-      }
+      dec_write_store(jcr);
+      dec_read_store(jcr);
       jcr->client->NumConcurrentJobs--;
       set_jcr_job_status(jcr, JS_WaitJobRes);
       return false;
@@ -772,3 +749,23 @@ static bool acquire_resources(JCR *jcr)
    jcr->acquired_resource_locks = true;
    return true;
 }
+
+static void dec_read_store(JCR *jcr)
+{
+   if (jcr->rstore) {
+      jcr->rstore->NumConcurrentReadJobs--;    /* back out rstore */
+      jcr->rstore->NumConcurrentJobs--;        /* back out rstore */
+      Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+      ASSERT(jcr->rstore->NumConcurrentReadJobs >= 0);
+      ASSERT(jcr->rstore->NumConcurrentJobs >= 0);
+   }
+}
+
+static void dec_write_store(JCR *jcr)
+{
+   if (jcr->wstore) {
+      jcr->wstore->NumConcurrentJobs--;
+      Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+      ASSERT(jcr->wstore->NumConcurrentJobs >= 0);
+   }
+}
index 9358f16c417da7ef002245bb376075124d04606d..345a58d2aac08c12eeff7c093fa024c4425f20b3 100644 (file)
@@ -41,9 +41,9 @@
 extern void *start_heap;
 
 /* Forward referenced functions */
-static void  list_terminated_jobs(STATUS_PKT *sp, bool api);
-static void  list_running_jobs(STATUS_PKT *sp, bool api);
-static void  list_status_header(STATUS_PKT *sp, bool api);
+static void  list_terminated_jobs(STATUS_PKT *sp);
+static void  list_running_jobs(STATUS_PKT *sp);
+static void  list_status_header(STATUS_PKT *sp);
 static void sendit(const char *msg, int len, STATUS_PKT *sp);
 static const char *level_to_str(int level);
 
@@ -69,12 +69,12 @@ extern VSSClient *g_pVSSClient;
  */
 void output_status(STATUS_PKT *sp)
 {
-   list_status_header(sp, false /*no api*/);
-   list_running_jobs(sp, false /*no api*/);
-   list_terminated_jobs(sp, false /*no api*/);
+   list_status_header(sp);
+   list_running_jobs(sp);
+   list_terminated_jobs(sp);
 }
 
-static void  list_status_header(STATUS_PKT *sp, bool api)
+static void  list_status_header(STATUS_PKT *sp)
 {
    POOL_MEM msg(PM_MESSAGE);
    char b1[32], b2[32], b3[32], b4[32], b5[35];
@@ -145,7 +145,7 @@ static void  list_status_header(STATUS_PKT *sp, bool api)
    sendit(msg.c_str(), len, sp);
 }
 
-static void  list_running_jobs(STATUS_PKT *sp, bool api)
+static void  list_running_jobs(STATUS_PKT *sp)
 {
    int sec, bps;
    POOL_MEM msg(PM_MESSAGE);
@@ -158,7 +158,7 @@ static void  list_running_jobs(STATUS_PKT *sp, bool api)
     * List running jobs
     */
    Dmsg0(1000, "Begin status jcr loop.\n");
-   if (!api) {
+   if (!sp->api) {
       len = Mmsg(msg, _("\nRunning Jobs:\n"));
       sendit(msg.c_str(), len, sp);
    }
@@ -216,7 +216,7 @@ static void  list_running_jobs(STATUS_PKT *sp, bool api)
    }
    endeach_jcr(njcr);
 
-   if (!api) {
+   if (!sp->api) {
       if (!found) {
          len = Mmsg(msg, _("No Jobs running.\n"));
          sendit(msg.c_str(), len, sp);
@@ -226,24 +226,24 @@ static void  list_running_jobs(STATUS_PKT *sp, bool api)
 }
   
 
-static void list_terminated_jobs(STATUS_PKT *sp, bool api)
+static void list_terminated_jobs(STATUS_PKT *sp)
 {
    char dt[MAX_TIME_LENGTH], b1[30], b2[30];
    char level[10];
    struct s_last_job *je;
    const char *msg;
 
-   if (!api) {
+   if (!sp->api) {
       msg =  _("\nTerminated Jobs:\n");
       sendit(msg, strlen(msg), sp);
    }
 
    if (last_jobs->size() == 0) {
-      if (!api) sendit(_("====\n"), 5, sp);
+      if (!sp->api) sendit(_("====\n"), 5, sp);
       return;
    }
    lock_last_jobs_list();
-   if (!api) {
+   if (!sp->api) {
       msg =  _(" JobId  Level    Files      Bytes   Status   Finished        Name \n");
       sendit(msg, strlen(msg), sp);
       msg = _("======================================================================\n");
@@ -294,7 +294,7 @@ static void list_terminated_jobs(STATUS_PKT *sp, bool api)
             *p = 0;
          }
       }
-      if (api) {
+      if (sp->api) {
          bsnprintf(buf, sizeof(buf), _("%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"),
             je->JobId,
             level,
@@ -313,7 +313,7 @@ static void list_terminated_jobs(STATUS_PKT *sp, bool api)
       }
       sendit(buf, strlen(buf), sp);
    }
-   if (!api) sendit(_("====\n"), 5, sp);
+   if (!sp->api) sendit(_("====\n"), 5, sp);
    unlock_last_jobs_list();
 }
 
@@ -344,6 +344,7 @@ int status_cmd(JCR *jcr)
 
    user->fsend("\n");
    sp.bs = user;
+   sp.api = false;                         /* no API output */
    output_status(&sp);
 
    user->signal(BNET_EOD);
@@ -389,11 +390,14 @@ int qstatus_cmd(JCR *jcr)
          dir->fsend(DotStatusJob, job->JobId, job->JobStatus, job->Errors);
       }
    } else if (strcasecmp(cmd, "header") == 0) {
-       list_status_header(&sp, true/*api*/);
+       sp.api = true;
+       list_status_header(&sp);
    } else if (strcasecmp(cmd, "running") == 0) {
-       list_running_jobs(&sp, true/*api*/);
+       sp.api = true;
+       list_running_jobs(&sp);
    } else if (strcasecmp(cmd, "terminated") == 0) {
-       list_terminated_jobs(&sp, true/*api*/);
+       sp.api = true;
+       list_terminated_jobs(&sp);
    } else {
       pm_strcpy(&jcr->errmsg, dir->msg);
       Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg);
index a220cce15219ed5ed3d075f1af706d1d5037c273..163e172a00c989c5397a902abb3b1be5e3fccf92 100644 (file)
@@ -305,7 +305,7 @@ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
       }
    } else {
       if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) {
-         Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), 
+         Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"), 
                bsock->host());
          goto err;
       }
index 55106b61842fab96c31d0200af318da3550ae727..c7c2a934d97497b87846ec62eaff39d792b56e37 100644 (file)
@@ -48,6 +48,7 @@ public:
   BSOCK *bs;                       /* used on Unix machines */
   void *context;                   /* Win32 */
   void (*callback)(const char *msg, int len, void *context);  /* Win32 */
+  bool api;                        /* set if we want API output */
 
   /* Methods */
   STATUS_PKT() { memset(this, 0, sizeof(STATUS_PKT)); };
index 34a1da2d3843b42a23ebde486482c82ec302e17c..b8c06918ea1777788d4fe3ab5b2884cc80a63087 100644 (file)
@@ -99,8 +99,6 @@ void list_spool_stats(void sendit(const char *msg, int len, void *sarg), void *a
    
       sendit(msg.c_str(), len, arg);
    }
-   len = Mmsg(msg, "====\n");
-   sendit(msg.c_str(), len, arg);
 }
 
 bool begin_data_spool(DCR *dcr)
index 5a82b753aedd48cf83473cd16a99a4dea47e8f09..b1fb76e893dd9d06bb94c129ee7f19dbc4d348a8 100644 (file)
@@ -59,6 +59,7 @@ static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp);
 static void sendit(const char *msg, int len, void *arg);
 
 static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp);
+static void send_device_status(DEVICE *dev, STATUS_PKT *sp);
 static void list_terminated_jobs(STATUS_PKT *sp);
 static void list_running_jobs(STATUS_PKT *sp);
 static void list_jobs_waiting_on_reservation(STATUS_PKT *sp);
@@ -99,10 +100,10 @@ void output_status(STATUS_PKT *sp)
 
 
    len = Mmsg(msg, _("In Use Volume status:\n"));
-   sendit(msg, len, sp);
+   if (!sp->api) sendit(msg, len, sp);
 
    list_volumes(sendit, (void *)sp);
-   sendit("====\n\n", 6, sp);
+   if (!sp->api) sendit("====\n\n", 6, sp);
 
 #ifdef xxx
    if (debug_level > 10) {
@@ -113,6 +114,7 @@ void output_status(STATUS_PKT *sp)
 #endif
 
    list_spool_stats(sendit, (void *)sp);
+   if (!sp->api) sendit("====\n\n", 6, sp);
 }
 
 
@@ -127,7 +129,7 @@ static void list_devices(STATUS_PKT *sp)
    int bpb;
 
    len = Mmsg(msg, _("\nDevice status:\n"));
-   sendit(msg, len, sp);
+   if (!sp->api) sendit(msg, len, sp);
 
    foreach_res(changer, R_AUTOCHANGER) {
       len = Mmsg(msg, _("Autochanger \"%s\" with devices:\n"),
@@ -206,7 +208,7 @@ static void list_devices(STATUS_PKT *sp)
          }
       }
    }
-   sendit("====\n\n", 6, sp);
+   if (!sp->api) sendit("====\n\n", 6, sp);
 }
 
 static void list_status_header(STATUS_PKT *sp)
@@ -320,58 +322,66 @@ static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp)
       }
    }
    if (debug_level > 1) {
-      len = Mmsg(msg, _("Configured device capabilities:\n"));
-      sendit(msg, len, sp);
+      send_device_status(dev, sp);
+   }
+}
 
-      len = Mmsg(msg, "%sEOF %sBSR %sBSF %sFSR %sFSF %sEOM %sREM %sRACCESS %sAUTOMOUNT %sLABEL %sANONVOLS %sALWAYSOPEN\n",
-         dev->capabilities & CAP_EOF ? "" : "!", 
-         dev->capabilities & CAP_BSR ? "" : "!", 
-         dev->capabilities & CAP_BSF ? "" : "!", 
-         dev->capabilities & CAP_FSR ? "" : "!", 
-         dev->capabilities & CAP_FSF ? "" : "!", 
-         dev->capabilities & CAP_EOM ? "" : "!", 
-         dev->capabilities & CAP_REM ? "" : "!", 
-         dev->capabilities & CAP_RACCESS ? "" : "!",
-         dev->capabilities & CAP_AUTOMOUNT ? "" : "!", 
-         dev->capabilities & CAP_LABEL ? "" : "!", 
-         dev->capabilities & CAP_ANONVOLS ? "" : "!", 
-         dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
-      sendit(msg, len, sp);
+static void send_device_status(DEVICE *dev, STATUS_PKT *sp)
+{
+   POOL_MEM msg(PM_MESSAGE);
+   int len;
 
-      len = Mmsg(msg, _("Device state:\n"));
-      sendit(msg, len, sp);
+   len = Mmsg(msg, _("Configured device capabilities:\n"));
+   sendit(msg, len, sp);
 
-      len = Mmsg(msg, "%sOPENED %sTAPE %sLABEL %sMALLOC %sAPPEND %sREAD %sEOT %sWEOT %sEOF %sNEXTVOL %sSHORT %sMOUNTED\n", 
-         dev->is_open() ? "" : "!", 
-         dev->is_tape() ? "" : "!", 
-         dev->is_labeled() ? "" : "!", 
-         dev->state & ST_MALLOC ? "" : "!", 
-         dev->can_append() ? "" : "!", 
-         dev->can_read() ? "" : "!", 
-         dev->at_eot() ? "" : "!", 
-         dev->state & ST_WEOT ? "" : "!", 
-         dev->at_eof() ? "" : "!", 
-         dev->state & ST_NEXTVOL ? "" : "!", 
-         dev->state & ST_SHORT ? "" : "!", 
-         dev->state & ST_MOUNTED ? "" : "!");
-      sendit(msg, len, sp);
+   len = Mmsg(msg, "%sEOF %sBSR %sBSF %sFSR %sFSF %sEOM %sREM %sRACCESS %sAUTOMOUNT %sLABEL %sANONVOLS %sALWAYSOPEN\n",
+      dev->capabilities & CAP_EOF ? "" : "!", 
+      dev->capabilities & CAP_BSR ? "" : "!", 
+      dev->capabilities & CAP_BSF ? "" : "!", 
+      dev->capabilities & CAP_FSR ? "" : "!", 
+      dev->capabilities & CAP_FSF ? "" : "!", 
+      dev->capabilities & CAP_EOM ? "" : "!", 
+      dev->capabilities & CAP_REM ? "" : "!", 
+      dev->capabilities & CAP_RACCESS ? "" : "!",
+      dev->capabilities & CAP_AUTOMOUNT ? "" : "!", 
+      dev->capabilities & CAP_LABEL ? "" : "!", 
+      dev->capabilities & CAP_ANONVOLS ? "" : "!", 
+      dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
+   sendit(msg, len, sp);
 
-      len = Mmsg(msg, _("num_writers=%d block=%d\n\n"), dev->num_writers, dev->blocked());
-      sendit(msg, len, sp);
+   len = Mmsg(msg, _("Device state:\n"));
+   sendit(msg, len, sp);
 
-      len = Mmsg(msg, _("Device parameters:\n"));
-      sendit(msg, len, sp);
+   len = Mmsg(msg, "%sOPENED %sTAPE %sLABEL %sMALLOC %sAPPEND %sREAD %sEOT %sWEOT %sEOF %sNEXTVOL %sSHORT %sMOUNTED\n", 
+      dev->is_open() ? "" : "!", 
+      dev->is_tape() ? "" : "!", 
+      dev->is_labeled() ? "" : "!", 
+      dev->state & ST_MALLOC ? "" : "!", 
+      dev->can_append() ? "" : "!", 
+      dev->can_read() ? "" : "!", 
+      dev->at_eot() ? "" : "!", 
+      dev->state & ST_WEOT ? "" : "!", 
+      dev->at_eof() ? "" : "!", 
+      dev->state & ST_NEXTVOL ? "" : "!", 
+      dev->state & ST_SHORT ? "" : "!", 
+      dev->state & ST_MOUNTED ? "" : "!");
+   sendit(msg, len, sp);
 
-      len = Mmsg(msg, _("Archive name: %s Device name: %s\n"), dev->archive_name(),
-         dev->name());
-      sendit(msg, len, sp);
+   len = Mmsg(msg, _("num_writers=%d block=%d\n\n"), dev->num_writers, dev->blocked());
+   sendit(msg, len, sp);
 
-      len = Mmsg(msg, _("File=%u block=%u\n"), dev->file, dev->block_num);
-      sendit(msg, len, sp);
+   len = Mmsg(msg, _("Device parameters:\n"));
+   sendit(msg, len, sp);
 
-      len = Mmsg(msg, _("Min block=%u Max block=%u\n"), dev->min_block_size, dev->max_block_size);
-      sendit(msg, len, sp);
-   }
+   len = Mmsg(msg, _("Archive name: %s Device name: %s\n"), dev->archive_name(),
+      dev->name());
+   sendit(msg, len, sp);
+
+   len = Mmsg(msg, _("File=%u block=%u\n"), dev->file, dev->block_num);
+   sendit(msg, len, sp);
+
+   len = Mmsg(msg, _("Min block=%u Max block=%u\n"), dev->min_block_size, dev->max_block_size);
+   sendit(msg, len, sp);
 }
 
 static void list_running_jobs(STATUS_PKT *sp)
@@ -386,7 +396,7 @@ static void list_running_jobs(STATUS_PKT *sp)
    POOL_MEM msg(PM_MESSAGE);
 
    len = Mmsg(msg, _("\nRunning Jobs:\n"));
-   sendit(msg, len, sp);
+   if (!sp->api) sendit(msg, len, sp);
 
    foreach_jcr(jcr) {
       if (jcr->JobStatus == JS_WaitFD) {
@@ -463,9 +473,9 @@ static void list_running_jobs(STATUS_PKT *sp)
 
    if (!found) {
       len = Mmsg(msg, _("No Jobs running.\n"));
-      sendit(msg, len, sp);
+      if (!sp->api) sendit(msg, len, sp);
    }
-   sendit("====\n", 5, sp);
+   if (!sp->api) sendit("====\n", 5, sp);
 }
 
 static void list_jobs_waiting_on_reservation(STATUS_PKT *sp)
@@ -475,7 +485,7 @@ static void list_jobs_waiting_on_reservation(STATUS_PKT *sp)
    int len;
 
    len = Mmsg(msg, _("\nJobs waiting to reserve a drive:\n"));
-   sendit(msg, len, sp);
+   if (!sp->api) sendit(msg, len, sp);
 
    foreach_jcr(jcr) {
       if (!jcr->reserve_msgs) {
@@ -485,7 +495,7 @@ static void list_jobs_waiting_on_reservation(STATUS_PKT *sp)
    }
    endeach_jcr(jcr);
 
-   sendit("====\n", 5, sp);
+   if (!sp->api) sendit("====\n", 5, sp);
 }
 
 
@@ -497,16 +507,16 @@ static void list_terminated_jobs(STATUS_PKT *sp)
    const char *msg;
 
    msg =  _("\nTerminated Jobs:\n");
-   sendit(msg, strlen(msg), sp);
+   if (!sp->api) sendit(msg, strlen(msg), sp);
    if (last_jobs->size() == 0) {
-      sendit("====\n", 5, sp);
+      if (!sp->api) sendit("====\n", 5, sp);
       return;
    }
    lock_last_jobs_list();
    msg =  _(" JobId  Level    Files      Bytes   Status   Finished        Name \n");
-   sendit(msg, strlen(msg), sp);
+   if (!sp->api) sendit(msg, strlen(msg), sp);
    msg =  _("===================================================================\n");
-   sendit(msg, strlen(msg), sp);
+   if (!sp->api) sendit(msg, strlen(msg), sp);
    foreach_dlist(je, last_jobs) {
       char JobName[MAX_NAME_LENGTH];
       const char *termstat;
@@ -552,17 +562,27 @@ static void list_terminated_jobs(STATUS_PKT *sp)
             *p = 0;
          }
       }
-      bsnprintf(buf, sizeof(buf), _("%6d  %-6s %8s %10s  %-7s  %-8s %s\n"),
-         je->JobId,
-         level,
-         edit_uint64_with_commas(je->JobFiles, b1),
-         edit_uint64_with_suffix(je->JobBytes, b2),
-         termstat,
-         dt, JobName);
+      if (sp->api) {
+         bsnprintf(buf, sizeof(buf), _("%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"),
+            je->JobId,
+            level,
+            edit_uint64_with_commas(je->JobFiles, b1),
+            edit_uint64_with_suffix(je->JobBytes, b2),
+            termstat,
+            dt, JobName);
+      } else {
+         bsnprintf(buf, sizeof(buf), _("%6d  %-6s %8s %10s  %-7s  %-8s %s\n"),
+            je->JobId,
+            level,
+            edit_uint64_with_commas(je->JobFiles, b1),
+            edit_uint64_with_suffix(je->JobBytes, b2),
+            termstat,
+            dt, JobName);
+      }  
       sendit(buf, strlen(buf), sp);
    }
    unlock_last_jobs_list();
-   sendit("====\n", 5, sp);
+   if (!sp->api) sendit("====\n", 5, sp);
 }
 
 /*
@@ -650,14 +670,14 @@ static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp)
  */
 bool status_cmd(JCR *jcr)
 {
-   BSOCK *bs = jcr->dir_bsock;
+   BSOCK *dir = jcr->dir_bsock;
    STATUS_PKT sp;
 
-   bs->fsend("\n");
-   sp.bs = bs;
+   dir->fsend("\n");
+   sp.bs = dir;
    output_status(&sp);
-   bs->signal(BNET_EOD);
-   return 1;
+   dir->signal(BNET_EOD);
+   return true;
 }
 
 /*
@@ -666,33 +686,58 @@ bool status_cmd(JCR *jcr)
 bool qstatus_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   POOL_MEM time;
+   POOL_MEM cmd;
    JCR *njcr;
    s_last_job* job;
+   STATUS_PKT sp;
 
-   if (sscanf(dir->msg, qstatus, time.c_str()) != 1) {
+   sp.bs = dir;
+   if (sscanf(dir->msg, qstatus, cmd.c_str()) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
       Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg);
       dir->fsend(_("3900 Bad .status command, missing argument.\n"));
       dir->signal(BNET_EOD);
       return false;
    }
-   unbash_spaces(time);
+   unbash_spaces(cmd);
+
+   Dmsg1(000, "cmd=%s\n", cmd.c_str());
 
-   if (strcmp(time.c_str(), "current") == 0) {
-      dir->fsend(OKqstatus, time.c_str());
+   if (strcmp(cmd.c_str(), "current") == 0) {
+      dir->fsend(OKqstatus, cmd.c_str());
       foreach_jcr(njcr) {
          if (njcr->JobId != 0) {
             dir->fsend(DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
          }
       }
       endeach_jcr(njcr);
-   } else if (strcmp(time.c_str(), "last") == 0) {
-      dir->fsend(OKqstatus, time.c_str());
+   } else if (strcmp(cmd.c_str(), "last") == 0) {
+      dir->fsend(OKqstatus, cmd.c_str());
       if ((last_jobs) && (last_jobs->size() > 0)) {
          job = (s_last_job*)last_jobs->last();
          dir->fsend(DotStatusJob, job->JobId, job->JobStatus, job->Errors);
       }
+   } else if (strcasecmp(cmd.c_str(), "header") == 0) {
+       sp.api = true;
+       list_status_header(&sp);
+   } else if (strcasecmp(cmd.c_str(), "running") == 0) {
+       sp.api = true;
+       list_running_jobs(&sp);
+   } else if (strcasecmp(cmd.c_str(), "waitreservation") == 0) {
+       sp.api = true;
+       list_jobs_waiting_on_reservation(&sp);
+   } else if (strcasecmp(cmd.c_str(), "devices") == 0) {
+       sp.api = true;
+       list_devices(&sp);
+   } else if (strcasecmp(cmd.c_str(), "volumes") == 0) {
+       sp.api = true;
+       list_volumes(sendit, &sp);
+   } else if (strcasecmp(cmd.c_str(), "spooling") == 0) {
+       sp.api = true;
+       list_spool_stats(sendit, &sp);
+   } else if (strcasecmp(cmd.c_str(), "terminated") == 0) {
+       sp.api = true;
+       list_terminated_jobs(&sp);
    } else {
       pm_strcpy(jcr->errmsg, dir->msg);
       Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg);
index a05b692c5ca7190b18eee8097e4e8396f75d9ef6..7b93ba75b81d7bd0573392718fd85de3b64d0dd8 100644 (file)
@@ -2,6 +2,14 @@
 
 General:
 09Mar08
+kes  Attempt to correct problems with restores with autochangers and
+     use counts going negative 
+kes  Rework SD status command and implement API for bat. Implements
+     header, runing waitreservation, devices, volumes, spooling,
+     and terminated status keywords.
+     .status storage=xxx <keyword>
+kes  Clarify TLS error message by adding double quotes around name.
+kes  Simplify SD/FD status code by putting api flag in STATUS_PKT
 kes  Pass jcr to tls routines so debug messages can be handled better.
 kes  Rework jobq resource allocation code, and possibly fix a bug
      that caused reference counts to get out of sync.