From 3f9da320dd4ba421088ab683b370ba088faffe0f Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 26 Dec 2012 10:10:26 +0100 Subject: [PATCH] Pull SD files from master --- bacula/src/stored/askdir.c | 100 ++++++++-------- bacula/src/stored/job.c | 2 +- bacula/src/stored/status.c | 232 ++++++++++++++++++++++++------------- 3 files changed, 201 insertions(+), 133 deletions(-) diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index e48c00d14e..9a899275ab 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -36,6 +36,8 @@ #include "bacula.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ +static const int dbglvl = 200; + /* Requests sent to the Director */ static char Find_media[] = "CatReq Job=%s FindMedia=%d pool_name=%s media_type=%s\n"; static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n"; @@ -106,7 +108,7 @@ bool dir_update_device(JCR *jcr, DEVICE *dev) dev->is_tape()?100000:1, dev->autoselect, 0, ChangerName.c_str(), MediaType.c_str(), VolumeName.c_str()); - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(dbglvl, ">dird: %s\n", dir->msg); return ok; } @@ -135,7 +137,7 @@ bool dir_update_changer(JCR *jcr, AUTOCHANGER *changer) "*", /* ChangerName */ MediaType.c_str(), /* MediaType */ "*"); /* VolName */ - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(dbglvl, ">dird: %s\n", dir->msg); return ok; } #endif @@ -173,12 +175,12 @@ static bool do_get_volume_info(DCR *dcr) dcr->setVolCatInfo(false); if (dir->recv() <= 0) { - Dmsg0(200, "getvolname error bnet_recv\n"); + Dmsg0(dbglvl, "getvolname error bnet_recv\n"); Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); return false; } memset(&vol, 0, sizeof(vol)); - Dmsg1(100, "msg); + Dmsg1(dbglvl, "msg); n = sscanf(dir->msg, OK_media, vol.VolCatName, &vol.VolCatJobs, &vol.VolCatFiles, &vol.VolCatBlocks, &vol.VolCatBytes, @@ -190,7 +192,7 @@ static bool do_get_volume_info(DCR *dcr) &vol.EndFile, &vol.EndBlock, &vol.VolCatParts, &vol.LabelType, &vol.VolMediaId); if (n != 22) { - Dmsg3(100, "Bad response from Dir fields=%d, len=%d: %s", + Dmsg3(dbglvl, "Bad response from Dir fields=%d, len=%d: %s", n, dir->msglen, dir->msg); Mmsg(jcr->errmsg, _("Error getting Volume info: %s"), dir->msg); return false; @@ -201,7 +203,7 @@ static bool do_get_volume_info(DCR *dcr) bstrncpy(dcr->VolumeName, vol.VolCatName, sizeof(dcr->VolumeName)); dcr->VolCatInfo = vol; /* structure assignment */ - Dmsg2(100, "do_reqest_vol_info return true slot=%d Volume=%s\n", + Dmsg2(dbglvl, "do_reqest_vol_info return true slot=%d Volume=%s\n", vol.Slot, vol.VolCatName); return true; } @@ -219,19 +221,19 @@ static bool do_get_volume_info(DCR *dcr) */ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { - JCR *jcr = dcr->jcr; - BSOCK *dir = jcr->dir_bsock; + JCR *jcr = dcr->jcr; + BSOCK *dir = jcr->dir_bsock; - P(vol_info_mutex); - dcr->setVolCatName(dcr->VolumeName); - bash_spaces(dcr->getVolCatName()); - dir->fsend(Get_Vol_Info, jcr->Job, dcr->getVolCatName(), - writing==GET_VOL_INFO_FOR_WRITE?1:0); - Dmsg1(100, ">dird %s", dir->msg); - unbash_spaces(dcr->getVolCatName()); - bool ok = do_get_volume_info(dcr); - V(vol_info_mutex); - return ok; + P(vol_info_mutex); + dcr->setVolCatName(dcr->VolumeName); + bash_spaces(dcr->getVolCatName()); + dir->fsend(Get_Vol_Info, jcr->Job, dcr->getVolCatName(), + writing==GET_VOL_INFO_FOR_WRITE?1:0); + Dmsg1(dbglvl, ">dird %s", dir->msg); + unbash_spaces(dcr->getVolCatName()); + bool ok = do_get_volume_info(dcr); + V(vol_info_mutex); + return ok; } @@ -255,7 +257,7 @@ bool dir_find_next_appendable_volume(DCR *dcr) bool rtn; char lastVolume[MAX_NAME_LENGTH]; - Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", + Dmsg2(dbglvl, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", dcr->is_reserved(), dcr->VolumeName); /* @@ -273,33 +275,33 @@ bool dir_find_next_appendable_volume(DCR *dcr) dir->fsend(Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type); unbash_spaces(dcr->media_type); unbash_spaces(dcr->pool_name); - Dmsg1(100, ">dird %s", dir->msg); + Dmsg1(dbglvl, ">dird %s", dir->msg); if (do_get_volume_info(dcr)) { /* Give up if we get the same volume name twice */ if (lastVolume[0] && strcmp(lastVolume, dcr->VolumeName) == 0) { - Dmsg1(100, "Got same vol = %s\n", lastVolume); + Dmsg1(dbglvl, "Got same vol = %s\n", lastVolume); break; } bstrncpy(lastVolume, dcr->VolumeName, sizeof(lastVolume)); if (dcr->can_i_write_volume()) { - Dmsg1(100, "Call reserve_volume for write. Vol=%s\n", dcr->VolumeName); + Dmsg1(dbglvl, "Call reserve_volume for write. Vol=%s\n", dcr->VolumeName); if (reserve_volume(dcr, dcr->VolumeName) == NULL) { - Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName, + Dmsg2(dbglvl, "Could not reserve volume %s on %s\n", dcr->VolumeName, dcr->dev->print_name()); continue; } - Dmsg1(100, "dir_find_next_appendable_volume return true. vol=%s\n", + Dmsg1(dbglvl, "dir_find_next_appendable_volume return true. vol=%s\n", dcr->VolumeName); rtn = true; goto get_out; } else { - Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName); + Dmsg1(dbglvl, "Volume %s is in use.\n", dcr->VolumeName); /* If volume is not usable, it is in use by someone else */ dcr->set_found_in_use(); continue; } } - Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index, + Dmsg2(dbglvl, "No vol. index %d return false. dev=%s\n", vol_index, dcr->dev->print_name()); break; } @@ -342,7 +344,7 @@ bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten) /* Lock during Volume update */ P(vol_info_mutex); - Dmsg1(100, "Update cat VolBytes=%lld\n", vol->VolCatBytes); + Dmsg1(dbglvl, "Update cat VolBytes=%lld\n", vol->VolCatBytes); /* Just labeled or relabeled the tape */ if (label) { bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus)); @@ -365,13 +367,13 @@ bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten) edit_int64(vol->VolWriteTime, ed4), edit_uint64(vol->VolFirstWritten, ed5), vol->VolCatParts); - Dmsg1(100, ">dird %s", dir->msg); + Dmsg1(dbglvl, ">dird %s", dir->msg); /* Do not lock device here because it may be locked from label */ if (!jcr->is_canceled()) { if (!do_get_volume_info(dcr)) { Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg); - Dmsg2(100, _("Didn't get vol info vol=%s: ERR=%s"), + Dmsg2(dbglvl, _("Didn't get vol info vol=%s: ERR=%s"), vol->VolCatName, jcr->errmsg); goto bail_out; } @@ -403,7 +405,7 @@ bool dir_create_jobmedia_record(DCR *dcr, bool zero) /* Throw out records where FI is zero -- i.e. nothing done */ if (!zero && dcr->VolFirstIndex == 0 && (dcr->StartBlock != 0 || dcr->EndBlock != 0)) { - Dmsg0(100, "JobMedia FI=0 StartBlock!=0 record suppressed\n"); + Dmsg0(dbglvl, "JobMedia FI=0 StartBlock!=0 record suppressed\n"); return true; } @@ -424,16 +426,16 @@ bool dir_create_jobmedia_record(DCR *dcr, bool zero) dcr->Copy, dcr->Stripe, edit_uint64(dcr->VolMediaId, ed1)); } - Dmsg1(100, ">dird %s", dir->msg); + Dmsg1(dbglvl, ">dird %s", dir->msg); if (dir->recv() <= 0) { - Dmsg0(190, "create_jobmedia error bnet_recv\n"); + Dmsg0(dbglvl, "create_jobmedia error bnet_recv\n"); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"), dir->bstrerror()); return false; } - Dmsg1(100, "msg); + Dmsg1(dbglvl, "msg); if (strcmp(dir->msg, OK_create) != 0) { - Dmsg1(130, "Bad response from Dir: %s\n", dir->msg); + Dmsg1(dbglvl, "Bad response from Dir: %s\n", dir->msg); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: %s\n"), dir->msg); return false; } @@ -512,7 +514,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) if (job_canceled(jcr)) { return false; } - Dmsg0(400, "enter dir_ask_sysop_to_create_appendable_volume\n"); + Dmsg0(dbglvl, "enter dir_ask_sysop_to_create_appendable_volume\n"); ASSERT(dev->blocked()); for ( ;; ) { if (job_canceled(jcr)) { @@ -538,16 +540,16 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) dcr->pool_name, dcr->media_type); Jmsg(jcr, M_MOUNT, 0, "%s", dev->errmsg); - Dmsg1(100, "%s", dev->errmsg); + Dmsg1(dbglvl, "%s", dev->errmsg); } } jcr->sendJobStatus(JS_WaitMedia); stat = wait_for_sysop(dcr); - Dmsg1(100, "Back from wait_for_sysop stat=%d\n", stat); + Dmsg1(dbglvl, "Back from wait_for_sysop stat=%d\n", stat); if (dev->poll) { - Dmsg1(100, "Poll timeout in create append vol on device %s\n", dev->print_name()); + Dmsg1(dbglvl, "Poll timeout in create append vol on device %s\n", dev->print_name()); continue; } @@ -556,7 +558,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"), dev->print_name(), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - Dmsg1(100, "Gave up waiting on device %s\n", dev->print_name()); + Dmsg1(dbglvl, "Gave up waiting on device %s\n", dev->print_name()); return false; /* exceeded maximum waits */ } continue; @@ -567,12 +569,12 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); return false; } - Dmsg1(100, "Someone woke me for device %s\n", dev->print_name()); + Dmsg1(dbglvl, "Someone woke me for device %s\n", dev->print_name()); } get_out: jcr->sendJobStatus(JS_Running); - Dmsg0(100, "leave dir_ask_sysop_to_mount_create_appendable_volume\n"); + Dmsg0(dbglvl, "leave dir_ask_sysop_to_mount_create_appendable_volume\n"); return true; } @@ -594,7 +596,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, int mode) DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; - Dmsg0(400, "enter dir_ask_sysop_to_mount_volume\n"); + Dmsg0(dbglvl, "enter dir_ask_sysop_to_mount_volume\n"); if (!dcr->VolumeName[0]) { Mmsg0(dev->errmsg, _("Cannot request another volume: no volume name given.\n")); return false; @@ -637,17 +639,17 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, int mode) dev->print_name(), dcr->pool_name, dcr->media_type); - Dmsg3(400, "Mount \"%s\" on device \"%s\" for Job %s\n", + Dmsg3(dbglvl, "Mount \"%s\" on device \"%s\" for Job %s\n", dcr->VolumeName, dev->print_name(), jcr->Job); } jcr->sendJobStatus(JS_WaitMount); stat = wait_for_sysop(dcr); /* wait on device */ - Dmsg1(100, "Back from wait_for_sysop stat=%d\n", stat); + Dmsg1(dbglvl, "Back from wait_for_sysop stat=%d\n", stat); if (dev->poll) { - Dmsg1(400, "Poll timeout in mount vol on device %s\n", dev->print_name()); - Dmsg1(400, "Blocked=%s\n", dev->print_blocked()); + Dmsg1(dbglvl, "Poll timeout in mount vol on device %s\n", dev->print_name()); + Dmsg1(dbglvl, "Blocked=%s\n", dev->print_blocked()); goto get_out; } @@ -656,7 +658,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, int mode) Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"), dev->print_name(), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); - Dmsg1(400, "Gave up waiting on device %s\n", dev->print_name()); + Dmsg1(dbglvl, "Gave up waiting on device %s\n", dev->print_name()); return false; /* exceeded maximum waits */ } continue; @@ -667,12 +669,12 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, int mode) Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); return false; } - Dmsg1(400, "Someone woke me for device %s\n", dev->print_name()); + Dmsg1(dbglvl, "Someone woke me for device %s\n", dev->print_name()); break; } get_out: jcr->sendJobStatus(JS_Running); - Dmsg0(400, "leave dir_ask_sysop_to_mount_volume\n"); + Dmsg0(dbglvl, "leave dir_ask_sysop_to_mount_volume\n"); return true; } diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 578f296cd3..9d8cd7cab2 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -97,7 +97,7 @@ bool job_cmd(JCR *jcr) return false; } jcr->rerunning = (rerunning) ? true : false; - Dmsg3(100, "==== rerunning=%d VolSesId=%d VolSesTime=%d\n", jcr->rerunning, + Dmsg3(100, "rerunning=%d VolSesId=%d VolSesTime=%d\n", jcr->rerunning, jcr->VolSessionId, jcr->VolSessionTime); /* * Since this job could be rescheduled, we diff --git a/bacula/src/stored/status.c b/bacula/src/stored/status.c index 1b6843ab5a..320d4ed976 100644 --- a/bacula/src/stored/status.c +++ b/bacula/src/stored/status.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2003-2010 Free Software Foundation Europe e.V. + Copyright (C) 2003-2012 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -37,7 +37,7 @@ #include "stored.h" #include "lib/status.h" -/* Exported variables */ +/* Imported functions */ /* Imported variables */ extern BSOCK *filed_chan; @@ -102,18 +102,43 @@ void output_status(STATUS_PKT *sp) list_volumes(sendit, (void *)sp); if (!sp->api) sendit("====\n\n", 6, sp); -#ifdef xxx - if (debug_level > 10) { - bs->fsend(_("====\n\n")); - dump_resource(R_DEVICE, resources[R_DEVICE-r_first].res_head, sendit, user); - bs->fsend(_("====\n\n")); - } -#endif list_spool_stats(sendit, (void *)sp); if (!sp->api) sendit("====\n\n", 6, sp); + } +static void list_resources(STATUS_PKT *sp) +{ +#ifdef when_working + POOL_MEM msg(PM_MESSAGE); + int len; + + len = Mmsg(msg, _("\nSD Resources:\n")); + if (!sp->api) sendit(msg, len, sp); + dump_resource(R_DEVICE, resources[R_DEVICE-r_first], sp); + if (!sp->api) sendit("====\n\n", 6, sp); +#endif +} + +#ifdef xxxx +static find_device(char *devname) +{ + foreach_res(device, R_DEVICE) { + if (strcasecmp(device->hdr.name, devname) == 0) { + found = true; + break; + } + } + if (!found) { + foreach_res(changer, R_AUTOCHANGER) { + if (strcasecmp(changer->hdr.name, devname) == 0) { + break; + } + } + } +} +#endif static void list_devices(STATUS_PKT *sp) { @@ -143,21 +168,24 @@ static void list_devices(STATUS_PKT *sp) } } } + + foreach_res(device, R_DEVICE) { dev = device->dev; if (dev && dev->is_open()) { if (dev->is_labeled()) { - len = Mmsg(msg, _("Device %s is mounted with:\n" + len = Mmsg(msg, _("\nDevice %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n"), dev->print_name(), + dev->blocked()?_("waiting for"):_("mounted with"), dev->VolHdr.VolumeName, - dev->pool_name[0]?dev->pool_name:"*unknown*", + dev->pool_name[0]?dev->pool_name:_("*unknown*"), dev->device->media_type); sendit(msg, len, sp); } else { - len = Mmsg(msg, _("Device %s open but no Bacula volume is currently mounted.\n"), + len = Mmsg(msg, _("\nDevice %s open but no Bacula volume is currently mounted.\n"), dev->print_name()); sendit(msg, len, sp); } @@ -196,14 +224,16 @@ static void list_devices(STATUS_PKT *sp) } else { if (dev) { - len = Mmsg(msg, _("Device %s is not open.\n"), dev->print_name()); + len = Mmsg(msg, _("\nDevice %s is not open.\n"), dev->print_name()); sendit(msg, len, sp); send_blocked_status(dev, sp); } else { - len = Mmsg(msg, _("Device \"%s\" is not open or does not exist.\n"), device->hdr.name); + len = Mmsg(msg, _("\nDevice \"%s\" is not open or does not exist.\n"), device->hdr.name); sendit(msg, len, sp); } } + + if (!sp->api) sendit("==\n", 4, sp); } if (!sp->api) sendit("====\n\n", 6, sp); } @@ -237,6 +267,21 @@ static void list_status_header(STATUS_PKT *sp) (int)sizeof(boffset_t), (int)sizeof(size_t), (int)sizeof(int32_t), (int)sizeof(int64_t), (int)DEVELOPER_MODE, (int)BEEF); sendit(msg, len, sp); + if (bplugin_list->size() > 0) { + Plugin *plugin; + int len; + pm_strcpy(msg, " Plugin: "); + foreach_alist(plugin, bplugin_list) { + len = pm_strcat(msg, plugin->file); + if (len > 80) { + pm_strcat(msg, "\n "); + } else { + pm_strcat(msg, " "); + } + } + len = pm_strcat(msg, "\n"); + sendit(msg.c_str(), len, sp); + } } static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp) @@ -260,33 +305,30 @@ static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp) break; case BST_WAITING_FOR_SYSOP: { - dlist *dcrs = dev->attached_dcrs; + DCR *dcr; bool found_jcr = false; - - if (dcrs != NULL) { - DCR *dcr; - for (dcr = (DCR *)dcrs->first(); dcr != NULL; dcr = (DCR *)dcrs->next(dcr)) { - if (dcr->jcr->JobStatus == JS_WaitMount) { - len = Mmsg(msg, _(" Device is BLOCKED waiting for mount of volume \"%s\",\n" - " Pool: %s\n" - " Media type: %s\n"), - dcr->VolumeName, - dcr->pool_name, - dcr->media_type); - sendit(msg, len, sp); - found_jcr = true; - } else if (dcr->jcr->JobStatus == JS_WaitMedia) { - len = Mmsg(msg, _(" Device is BLOCKED waiting to create a volume for:\n" - " Pool: %s\n" - " Media type: %s\n"), - dcr->pool_name, - dcr->media_type); - sendit(msg, len, sp); - found_jcr = true; - } + dev->dlock(); + foreach_dlist(dcr, dev->attached_dcrs) { + if (dcr->jcr->JobStatus == JS_WaitMount) { + len = Mmsg(msg, _(" Device is BLOCKED waiting for mount of volume \"%s\",\n" + " Pool: %s\n" + " Media type: %s\n"), + dcr->VolumeName, + dcr->pool_name, + dcr->media_type); + sendit(msg, len, sp); + found_jcr = true; + } else if (dcr->jcr->JobStatus == JS_WaitMedia) { + len = Mmsg(msg, _(" Device is BLOCKED waiting to create a volume for:\n" + " Pool: %s\n" + " Media type: %s\n"), + dcr->pool_name, + dcr->media_type); + sendit(msg, len, sp); + found_jcr = true; } } - + dev->dunlock(); if (!found_jcr) { len = Mmsg(msg, _(" Device is BLOCKED waiting for media.\n")); sendit(msg, len, sp); @@ -307,15 +349,12 @@ static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp) /* Send autochanger slot status */ if (dev->is_autochanger()) { if (dev->get_slot() > 0) { - len = Mmsg(msg, _(" Slot %d is loaded in drive %d.\n"), - dev->get_slot(), dev->drive_index); + len = Mmsg(msg, _(" Slot %d %s loaded in drive %d.\n"), + dev->get_slot(), dev->is_open()?"is": "was last", dev->drive_index); sendit(msg, len, sp); - } else if (dev->get_slot() == 0) { + } else if (dev->get_slot() <= 0) { len = Mmsg(msg, _(" Drive %d is not loaded.\n"), dev->drive_index); sendit(msg, len, sp); - } else { - len = Mmsg(msg, _(" Drive %d status unknown.\n"), dev->drive_index); - sendit(msg, len, sp); } } if (debug_level > 1) { @@ -328,28 +367,28 @@ static void send_device_status(DEVICE *dev, STATUS_PKT *sp) POOL_MEM msg(PM_MESSAGE); int len; - len = Mmsg(msg, _("Configured device capabilities:\n")); - 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); + if (debug_level > 5) { + len = Mmsg(msg, _("Configured device capabilities:\n")); + 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, _("Device state:\n")); sendit(msg, len, sp); - - len = Mmsg(msg, "%sOPENED %sTAPE %sLABEL %sMALLOC %sAPPEND %sREAD %sEOT %sWEOT %sEOF %sNEXTVOL %sSHORT %sMOUNTED\n", + 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() ? "" : "!", @@ -363,35 +402,50 @@ static void send_device_status(DEVICE *dev, STATUS_PKT *sp) dev->state & ST_SHORT ? "" : "!", dev->state & ST_MOUNTED ? "" : "!"); sendit(msg, len, sp); - - len = Mmsg(msg, _("num_writers=%d reserved=%d block=%d\n\n"), dev->num_writers, + len = Mmsg(msg, _(" num_writers=%d reserves=%d block=%d\n"), dev->num_writers, dev->num_reserved(), dev->blocked()); sendit(msg, len, sp); - len = Mmsg(msg, _("Device parameters:\n")); + len = Mmsg(msg, _("Attached Jobs: ")); sendit(msg, len, sp); + DCR *dcr = NULL; + bool found = false; + dev->dlock(); + foreach_dlist(dcr, dev->attached_dcrs) { + if (dcr->jcr) { + if (found) { + sendit(",", 1, sp); + } + len = Mmsg(msg, "%d", (int)dcr->jcr->JobId); + sendit(msg, len, sp); + found = true; + } + } + dev->dunlock(); + sendit("\n", 1, sp); - len = Mmsg(msg, _("Archive name: %s Device name: %s\n"), dev->archive_name(), + len = Mmsg(msg, _("Device parameters:\n")); + 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); + 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); + 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) { bool found = false; - int bps, sec; + int avebps, bps, sec; JCR *jcr; DCR *dcr, *rdcr; char JobName[MAX_NAME_LENGTH]; - char b1[30], b2[30], b3[30]; + char b1[50], b2[50], b3[50], b4[50]; int len; POOL_MEM msg(PM_MESSAGE); + time_t now = time(NULL); len = Mmsg(msg, _("\nRunning Jobs:\n")); if (!sp->api) sendit(msg, len, sp); @@ -442,16 +496,27 @@ static void list_running_jobs(STATUS_PKT *sp) dcr->spooling, dcr->despooling, dcr->despool_wait); sendit(msg, len, sp); } - sec = time(NULL) - jcr->run_time; + if (jcr->last_time == 0) { + jcr->last_time = jcr->run_time; + } + sec = now - jcr->last_time; if (sec <= 0) { sec = 1; } - bps = jcr->JobBytes / sec; - len = Mmsg(msg, _(" Files=%s Bytes=%s Bytes/sec=%s\n"), + bps = (jcr->JobBytes - jcr->LastJobBytes) / sec; + if (jcr->LastRate == 0) { + jcr->LastRate = bps; + } + avebps = (jcr->LastRate + bps) / 2; + len = Mmsg(msg, _(" Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n"), edit_uint64_with_commas(jcr->JobFiles, b1), edit_uint64_with_commas(jcr->JobBytes, b2), - edit_uint64_with_commas(bps, b3)); + edit_uint64_with_commas(avebps, b3), + edit_uint64_with_commas(bps, b4)); sendit(msg, len, sp); + jcr->LastRate = avebps; + jcr->LastJobBytes = jcr->JobBytes; + jcr->last_time = now; found = true; #ifdef DEBUG if (jcr->file_bsock) { @@ -695,8 +760,7 @@ bool qstatus_cmd(JCR *jcr) 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->fsend(_("3900 No arg in .status command: %s\n"), jcr->errmsg); dir->signal(BNET_EOD); return false; } @@ -704,7 +768,7 @@ bool qstatus_cmd(JCR *jcr) Dmsg1(200, "cmd=%s\n", cmd.c_str()); - if (strcmp(cmd.c_str(), "current") == 0) { + if (strcasecmp(cmd.c_str(), "current") == 0) { dir->fsend(OKqstatus, cmd.c_str()); foreach_jcr(njcr) { if (njcr->JobId != 0) { @@ -712,7 +776,7 @@ bool qstatus_cmd(JCR *jcr) } } endeach_jcr(njcr); - } else if (strcmp(cmd.c_str(), "last") == 0) { + } else if (strcasecmp(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(); @@ -739,10 +803,12 @@ bool qstatus_cmd(JCR *jcr) } else if (strcasecmp(cmd.c_str(), "terminated") == 0) { sp.api = true; list_terminated_jobs(&sp); + } else if (strcasecmp(cmd.c_str(), "resources") == 0) { + sp.api = true; + list_resources(&sp); } else { pm_strcpy(jcr->errmsg, dir->msg); - Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg); - dir->fsend(_("3900 Bad .status command, wrong argument.\n")); + dir->fsend(_("3900 Unknown arg in .status command: %s\n"), jcr->errmsg); dir->signal(BNET_EOD); return false; } -- 2.39.5