From 5d053cd3feecf861b237b260e3bd8a3e36eced79 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 9 Mar 2008 21:17:42 +0000 Subject: [PATCH] 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 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 | 1 + bacula/src/dird/jobq.c | 73 +++++++------ bacula/src/filed/status.c | 42 ++++---- bacula/src/lib/bnet.c | 2 +- bacula/src/lib/status.h | 1 + bacula/src/stored/spool.c | 2 - bacula/src/stored/status.c | 199 ++++++++++++++++++++++-------------- bacula/technotes-2.3 | 8 ++ 8 files changed, 191 insertions(+), 137 deletions(-) diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 879ae17f8a..2fad99e157 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -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 */ diff --git a/bacula/src/dird/jobq.c b/bacula/src/dird/jobq.c index 308acd7730..f9f91515a8 100644 --- a/bacula/src/dird/jobq.c +++ b/bacula/src/dird/jobq.c @@ -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); + } +} diff --git a/bacula/src/filed/status.c b/bacula/src/filed/status.c index 9358f16c41..345a58d2aa 100644 --- a/bacula/src/filed/status.c +++ b/bacula/src/filed/status.c @@ -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); diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index a220cce152..163e172a00 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -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; } diff --git a/bacula/src/lib/status.h b/bacula/src/lib/status.h index 55106b6184..c7c2a934d9 100644 --- a/bacula/src/lib/status.h +++ b/bacula/src/lib/status.h @@ -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)); }; diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c index 34a1da2d38..b8c06918ea 100644 --- a/bacula/src/stored/spool.c +++ b/bacula/src/stored/spool.c @@ -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) diff --git a/bacula/src/stored/status.c b/bacula/src/stored/status.c index 5a82b753ae..b1fb76e893 100644 --- a/bacula/src/stored/status.c +++ b/bacula/src/stored/status.c @@ -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); diff --git a/bacula/technotes-2.3 b/bacula/technotes-2.3 index a05b692c5c..7b93ba75b8 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -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 +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. -- 2.39.5