/*
- Bacula® - The Network Backup Solution
+ Bacula(R) - The Network Backup Solution
- Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2017 Kern Sibbald
- The main author of Bacula is Kern Sibbald, with contributions from many
- others, a complete list can be found in the file AUTHORS.
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
You may use this file and others of this release according to the
license defined in the LICENSE file, which includes the Affero General
Public License, v3.0 ("AGPLv3") and some additional permissions and
terms pursuant to its AGPLv3 Section 7.
- Bacula® is a registered trademark of Kern Sibbald.
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
*/
/*
* Bacula File Daemon Status routines
*
* Kern Sibbald, August MMI
- *
*/
#include "bacula.h"
static char OKqstatus[] = "2000 OK .status\n";
static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n";
-#if defined(HAVE_WIN32)
-static int privs = 0;
-#endif
-#ifdef WIN32_VSS
-#include "vss.h"
-#define VSS " VSS"
-extern VSSClient *g_pVSSClient;
-#else
-#define VSS ""
-#endif
-
/*
* General status generator
*/
list_terminated_jobs(sp); /* defined in lib/status.h */
}
-#if defined(HAVE_LZO)
-static const bool have_lzo = true;
-#else
-static const bool have_lzo = false;
-#endif
+static void api_list_status_header(STATUS_PKT *sp)
+{
+ char *p;
+ char buf[300];
+ OutputWriter wt(sp->api_opts);
+ *buf = 0;
+
+ wt.start_group("header");
+ wt.get_output(
+ OT_STRING, "name", my_name,
+ OT_STRING, "version", VERSION " (" BDATE ")",
+ OT_STRING, "uname", HOST_OS " " DISTNAME " " DISTVER,
+ OT_UTIME, "started", daemon_start_time,
+ OT_INT, "jobs_run", num_jobs_run,
+ OT_INT, "jobs_running",job_count(),
+ OT_STRING, "winver", buf,
+ OT_INT64, "debug", debug_level,
+ OT_INT, "trace", get_trace(),
+ OT_INT64, "bwlimit", me->max_bandwidth_per_job,
+ OT_PLUGINS, "plugins", b_plugin_list,
+ OT_END);
+ p = wt.end_group();
+ sendit(p, strlen(p), sp);
+}
static void list_status_header(STATUS_PKT *sp)
{
POOL_MEM msg(PM_MESSAGE);
char b1[32], b2[32], b3[32], b4[32], b5[35];
+ int64_t memused = (char *)sbrk(0)-(char *)start_heap;
int len;
char dt[MAX_TIME_LENGTH];
- len = Mmsg(msg, _("%s Version: %s (%s) %s %s %s %s\n"),
- my_name, VERSION, BDATE, VSS, HOST_OS,
+ if (sp->api) {
+ api_list_status_header(sp);
+ return;
+ }
+
+ len = Mmsg(msg, _("%s %sVersion: %s (%s) %s %s %s\n"),
+ my_name, "", VERSION, BDATE, HOST_OS,
DISTNAME, DISTVER);
sendit(msg.c_str(), len, sp);
bstrftime_nc(dt, sizeof(dt), daemon_start_time);
len = Mmsg(msg, _("Daemon started %s. Jobs: run=%d running=%d.\n"),
dt, num_jobs_run, job_count());
sendit(msg.c_str(), len, sp);
-#if defined(HAVE_WIN32)
- char buf[300];
- if (GetWindowsVersionString(buf, sizeof(buf))) {
- len = Mmsg(msg, "%s\n", buf);
- sendit(msg.c_str(), len, sp);
- }
- if (debug_level > 0) {
- if (!privs) {
- privs = enable_backup_privileges(NULL, 1);
- }
- len = Mmsg(msg, "VSS %s, Priv 0x%x\n", g_pVSSClient?"enabled":"disabled", privs);
- sendit(msg.c_str(), len, sp);
- len = Mmsg(msg, "APIs=%sOPT,%sATP,%sLPV,%sCFA,%sCFW,\n",
- p_OpenProcessToken?"":"!",
- p_AdjustTokenPrivileges?"":"!",
- p_LookupPrivilegeValue?"":"!",
- p_CreateFileA?"":"!",
- p_CreateFileW?"":"!");
- sendit(msg.c_str(), len, sp);
- len = Mmsg(msg, " %sWUL,%sWMKD,%sGFAA,%sGFAW,%sGFAEA,%sGFAEW,%sSFAA,%sSFAW,%sBR,%sBW,%sSPSP,\n",
- p_wunlink?"":"!",
- p_wmkdir?"":"!",
- p_GetFileAttributesA?"":"!",
- p_GetFileAttributesW?"":"!",
- p_GetFileAttributesExA?"":"!",
- p_GetFileAttributesExW?"":"!",
- p_SetFileAttributesA?"":"!",
- p_SetFileAttributesW?"":"!",
- p_BackupRead?"":"!",
- p_BackupWrite?"":"!",
- p_SetProcessShutdownParameters?"":"!");
- sendit(msg.c_str(), len, sp);
- len = Mmsg(msg, " %sWC2MB,%sMB2WC,%sFFFA,%sFFFW,%sFNFA,%sFNFW,%sSCDA,%sSCDW,\n",
- p_WideCharToMultiByte?"":"!",
- p_MultiByteToWideChar?"":"!",
- p_FindFirstFileA?"":"!",
- p_FindFirstFileW?"":"!",
- p_FindNextFileA?"":"!",
- p_FindNextFileW?"":"!",
- p_SetCurrentDirectoryA?"":"!",
- p_SetCurrentDirectoryW?"":"!");
- sendit(msg.c_str(), len, sp);
- len = Mmsg(msg, " %sGCDA,%sGCDW,%sGVPNW,%sGVNFVMPW,%sLZO\n",
- p_GetCurrentDirectoryA?"":"!",
- p_GetCurrentDirectoryW?"":"!",
- p_GetVolumePathNameW?"":"!",
- p_GetVolumeNameForVolumeMountPointW?"":"!",
- have_lzo?"":"!");
- sendit(msg.c_str(), len, sp);
- }
-#endif
len = Mmsg(msg, _(" Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
- edit_uint64_with_commas((char *)sbrk(0)-(char *)start_heap, b1),
+ edit_uint64_with_commas(memused, b1),
edit_uint64_with_commas(sm_bytes, b2),
edit_uint64_with_commas(sm_max_bytes, b3),
edit_uint64_with_commas(sm_buffers, b4),
len = Mmsg(msg, _(" Sizes: boffset_t=%d size_t=%d debug=%s trace=%d "
"mode=%d,%d bwlimit=%skB/s\n"),
sizeof(boffset_t), sizeof(size_t),
- edit_uint64(debug_level, b2), get_trace(), (int)DEVELOPER_MODE, (int)BEEF,
+ edit_uint64(debug_level, b2), get_trace(), (int)DEVELOPER_MODE, 0,
edit_uint64_with_commas(me->max_bandwidth_per_job/1024, b1));
sendit(msg.c_str(), len, sp);
- if (bplugin_list->size() > 0) {
+ if (b_plugin_list && b_plugin_list->size() > 0) {
Plugin *plugin;
int len;
pm_strcpy(msg, " Plugin: ");
- foreach_alist(plugin, bplugin_list) {
+ foreach_alist(plugin, b_plugin_list) {
len = pm_strcat(msg, plugin->file);
/* Print plugin version when debug activated */
if (debug_level > 0 && plugin->pinfo) {
*/
static void list_running_jobs_plain(STATUS_PKT *sp)
{
- int total_sec, inst_sec, total_bps, inst_bps;
+ int total_sec, inst_sec;
+ uint64_t total_bps, inst_bps;
POOL_MEM msg(PM_MESSAGE);
- char b1[50], b2[50], b3[50], b4[50], b5[50];
+ char b1[50], b2[50], b3[50], b4[50], b5[50], b6[50];
int len;
bool found = false;
JCR *njcr;
Dmsg0(1000, "Begin status jcr loop.\n");
len = Mmsg(msg, _("\nRunning Jobs:\n"));
sendit(msg.c_str(), len, sp);
- const char *vss = "";
-#ifdef WIN32_VSS
- if (g_pVSSClient && g_pVSSClient->IsInitialized()) {
- vss = "VSS ";
- }
-#endif
foreach_jcr(njcr) {
bstrftime_nc(dt, sizeof(dt), njcr->start_time);
if (njcr->JobId == 0) {
- len = Mmsg(msg, _("Director connected at: %s\n"), dt);
+ len = Mmsg(msg, _("Director connected %sat: %s\n"),
+ (njcr->dir_bsock && njcr->dir_bsock->tls)?_("using TLS "):"",
+ dt);
} else {
len = Mmsg(msg, _("JobId %d Job %s is running.\n"),
njcr->JobId, njcr->Job);
sendit(msg.c_str(), len, sp);
- len = Mmsg(msg, _(" %s%s %s Job started: %s\n"),
- vss, job_level_to_str(njcr->getJobLevel()),
+ len = Mmsg(msg, _(" %s %s Job started: %s\n"),
+ job_level_to_str(njcr->getJobLevel()),
job_type_to_str(njcr->getJobType()), dt);
}
sendit(msg.c_str(), len, sp);
/* total bps (AveBytes/sec) since start of job */
total_bps = njcr->JobBytes / total_sec;
len = Mmsg(msg, _(" Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s Errors=%d\n"
- " Bwlimit=%s\n"),
+ " Bwlimit=%s ReadBytes=%s\n"),
edit_uint64_with_commas(njcr->JobFiles, b1),
edit_uint64_with_commas(njcr->JobBytes, b2),
edit_uint64_with_commas(total_bps, b3),
edit_uint64_with_commas(inst_bps, b4),
- njcr->JobErrors, edit_uint64_with_commas(njcr->max_bandwidth, b5));
+ njcr->JobErrors, edit_uint64_with_commas(njcr->max_bandwidth, b5),
+ edit_uint64_with_commas(njcr->ReadBytes, b6));
sendit(msg.c_str(), len, sp);
if (njcr->is_JobType(JT_RESTORE) && njcr->ExpectedFiles > 0) {
found = true;
if (njcr->store_bsock) {
- len = Mmsg(msg, " SDReadSeqNo=%" lld " fd=%d\n",
- njcr->store_bsock->read_seqno, njcr->store_bsock->m_fd);
+ len = Mmsg(msg, " SDReadSeqNo=%" lld " fd=%d SDtls=%d\n",
+ njcr->store_bsock->read_seqno, njcr->store_bsock->m_fd,
+ (njcr->store_bsock->tls)?1:0);
sendit(msg.c_str(), len, sp);
} else {
len = Mmsg(msg, _(" SDSocket closed.\n"));
sendit(_("====\n"), 5, sp);
}
+/*
+ * List running jobs for Bat or Bweb in a format
+ * simpler to parse. Be careful when changing this
+ * subroutine.
+ */
static void list_running_jobs_api(STATUS_PKT *sp)
{
+ OutputWriter ow(sp->api_opts);
int sec, bps;
- POOL_MEM msg(PM_MESSAGE);
- char b1[32], b2[32], b3[32];
- int len;
+ char *p;
JCR *njcr;
- char dt[MAX_TIME_LENGTH];
- /*
- * List running jobs for Bat/Bweb (simple to parse)
- */
- int vss = 0;
-#ifdef WIN32_VSS
- if (g_pVSSClient && g_pVSSClient->IsInitialized()) {
- vss = 1;
- }
-#endif
+
+ /* API v1, edit with comma, space before the name, sometime ' ' as separator */
+
foreach_jcr(njcr) {
- bstrutime(dt, sizeof(dt), njcr->start_time);
+ p = ow.get_output(OT_CLEAR, OT_START_OBJ, OT_END);
+
if (njcr->JobId == 0) {
- len = Mmsg(msg, "DirectorConnected=%s\n", dt);
+ ow.get_output(OT_UTIME, "DirectorConnected", njcr->start_time,
+ OT_INT, "DirTLS", (njcr->dir_bsock && njcr->dir_bsock->tls)?1:0,
+ OT_END);
} else {
- len = Mmsg(msg, "JobId=%d\n Job=%s\n",
- njcr->JobId, njcr->Job);
- sendit(msg.c_str(), len, sp);
- len = Mmsg(msg," VSS=%d\n Level=%c\n JobType=%c\n JobStarted=%s\n",
- vss, njcr->getJobLevel(),
- njcr->getJobType(), dt);
+ ow.get_output(OT_INT32, "JobId", njcr->JobId,
+ OT_STRING, "Job", njcr->Job,
+ OT_JOBLEVEL,"Level", njcr->getJobLevel(),
+ OT_JOBTYPE, "Type", njcr->getJobType(),
+ OT_JOBSTATUS, "Status", njcr->getJobStatus(),
+ OT_UTIME, "StartTime", njcr->start_time,
+ OT_END);
+
}
- sendit(msg.c_str(), len, sp);
+ sendit(p, strlen(p), sp);
if (njcr->JobId == 0) {
continue;
}
sec = 1;
}
bps = (int)(njcr->JobBytes / sec);
- len = Mmsg(msg, " Files=%s\n Bytes=%s\n Bytes/sec=%s\n Errors=%d\n",
- edit_uint64(njcr->JobFiles, b1),
- edit_uint64(njcr->JobBytes, b2),
- edit_uint64(bps, b3),
- njcr->JobErrors);
- sendit(msg.c_str(), len, sp);
- len = Mmsg(msg, " Files Examined=%s\n",
- edit_uint64(njcr->num_files_examined, b1));
- sendit(msg.c_str(), len, sp);
+ ow.get_output(OT_CLEAR,
+ OT_INT32, "JobFiles", njcr->JobFiles,
+ OT_SIZE, "JobBytes", njcr->JobBytes,
+ OT_INT, "Bytes/sec", bps,
+ OT_INT, "Errors", njcr->JobErrors,
+ OT_INT64, "Bwlimit", njcr->max_bandwidth,
+ OT_SIZE, "ReadBytes", njcr->ReadBytes,
+ OT_END);
+
+ ow.get_output(OT_INT32, "Files Examined", njcr->num_files_examined, OT_END);
+
+ if (njcr->is_JobType(JT_RESTORE) && njcr->ExpectedFiles > 0) {
+ ow.get_output(OT_INT32, "Expected Files", njcr->ExpectedFiles,
+ OT_INT32, "Percent Complete", 100*(njcr->num_files_examined/njcr->ExpectedFiles),
+ OT_END);
+ }
+
+ sendit(p, strlen(p), sp);
+ ow.get_output(OT_CLEAR, OT_END);
+
if (njcr->JobFiles > 0) {
njcr->lock();
- len = Mmsg(msg, " Processing file=%s\n", njcr->last_fname);
+ ow.get_output(OT_STRING, "Processing file", njcr->last_fname, OT_END);
njcr->unlock();
- sendit(msg.c_str(), len, sp);
}
if (njcr->store_bsock) {
- len = Mmsg(msg, " SDReadSeqNo=%" lld "\n fd=%d\n",
- njcr->store_bsock->read_seqno, njcr->store_bsock->m_fd);
- sendit(msg.c_str(), len, sp);
+ ow.get_output(OT_INT64, "SDReadSeqNo", (int64_t)njcr->store_bsock->read_seqno,
+ OT_INT, "fd", njcr->store_bsock->m_fd,
+ OT_INT, "SDtls", (njcr->store_bsock->tls)?1:0,
+ OT_END);
} else {
- len = Mmsg(msg, _(" SDSocket=closed\n"));
- sendit(msg.c_str(), len, sp);
+ ow.get_output(OT_STRING, "SDSocket", "closed", OT_END);
}
+ ow.get_output(OT_END_OBJ, OT_END);
+ sendit(p, strlen(p), sp);
}
endeach_jcr(njcr);
}