]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/status.c
Fix compilation warnings with GCC 6.1
[bacula/bacula] / bacula / src / filed / status.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *  Bacula File Daemon Status routines
21  *
22  *    Kern Sibbald, August MMI
23  *
24  */
25
26 #include "bacula.h"
27 #include "filed.h"
28 #include "lib/status.h"
29
30 extern void *start_heap;
31
32 extern bool GetWindowsVersionString(char *buf, int maxsiz);
33
34
35 /* Forward referenced functions */
36 static void  list_running_jobs(STATUS_PKT *sp);
37 static void  list_status_header(STATUS_PKT *sp);
38
39 /* Static variables */
40 static char qstatus1[] = ".status %127s\n";
41 static char qstatus2[] = ".status %127s api=%d api_opts=%127s";
42
43 static char OKqstatus[]   = "2000 OK .status\n";
44 static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n";
45
46 #define VSS ""
47
48 /*
49  * General status generator
50  */
51 void output_status(STATUS_PKT *sp)
52 {
53    list_status_header(sp);
54    list_running_jobs(sp);
55    list_terminated_jobs(sp);    /* defined in lib/status.h */
56 }
57
58 #if defined(HAVE_LZO)
59 static const bool have_lzo = true;
60 #else
61 static const bool have_lzo = false;
62 #endif
63
64
65 static void  list_status_header(STATUS_PKT *sp)
66 {
67    POOL_MEM msg(PM_MESSAGE);
68    char b1[32], b2[32], b3[32], b4[32], b5[35];
69    int len;
70    char dt[MAX_TIME_LENGTH];
71
72    len = Mmsg(msg, _("%s %sVersion: %s (%s) %s %s %s %s\n"),
73               my_name, "", VERSION, BDATE, VSS, HOST_OS,
74               DISTNAME, DISTVER);
75    sendit(msg.c_str(), len, sp);
76    bstrftime_nc(dt, sizeof(dt), daemon_start_time);
77    len = Mmsg(msg, _("Daemon started %s. Jobs: run=%d running=%d.\n"),
78         dt, num_jobs_run, job_count());
79    sendit(msg.c_str(), len, sp);
80    len = Mmsg(msg, _(" Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
81          edit_uint64_with_commas((char *)sbrk(0)-(char *)start_heap, b1),
82          edit_uint64_with_commas(sm_bytes, b2),
83          edit_uint64_with_commas(sm_max_bytes, b3),
84          edit_uint64_with_commas(sm_buffers, b4),
85          edit_uint64_with_commas(sm_max_buffers, b5));
86    sendit(msg.c_str(), len, sp);
87    len = Mmsg(msg, _(" Sizes: boffset_t=%d size_t=%d debug=%s trace=%d "
88                      "mode=%d bwlimit=%skB/s\n"),
89               sizeof(boffset_t), sizeof(size_t),
90               edit_uint64(debug_level, b2), get_trace(), (int)DEVELOPER_MODE,
91               edit_uint64_with_commas(me->max_bandwidth_per_job/1024, b1));
92    sendit(msg.c_str(), len, sp);
93    if (b_plugin_list && b_plugin_list->size() > 0) {
94       Plugin *plugin;
95       int len;
96       pm_strcpy(msg, " Plugin: ");
97       foreach_alist(plugin, b_plugin_list) {
98          len = pm_strcat(msg, plugin->file);
99          /* Print plugin version when debug activated */
100          if (debug_level > 0 && plugin->pinfo) {
101             pInfo *info = (pInfo *)plugin->pinfo;
102             pm_strcat(msg, "(");
103             pm_strcat(msg, NPRT(info->plugin_version));
104             len = pm_strcat(msg, ")");
105          }
106          if (len > 80) {
107             pm_strcat(msg, "\n   ");
108          } else {
109             pm_strcat(msg, " ");
110          }
111       }
112       len = pm_strcat(msg, "\n");
113       sendit(msg.c_str(), len, sp);
114    }
115 }
116
117 /*
118  * List running jobs in for humans.
119  */
120 static void  list_running_jobs_plain(STATUS_PKT *sp)
121 {
122    int total_sec, inst_sec;
123    uint64_t total_bps, inst_bps;
124    POOL_MEM msg(PM_MESSAGE);
125    char b1[50], b2[50], b3[50], b4[50], b5[50], b6[50];
126    int len;
127    bool found = false;
128    JCR *njcr;
129    time_t now = time(NULL);
130    char dt[MAX_TIME_LENGTH];
131
132    Dmsg0(1000, "Begin status jcr loop.\n");
133    len = Mmsg(msg, _("\nRunning Jobs:\n"));
134    sendit(msg.c_str(), len, sp);
135    const char *vss = "";
136    foreach_jcr(njcr) {
137       bstrftime_nc(dt, sizeof(dt), njcr->start_time);
138       if (njcr->JobId == 0) {
139          len = Mmsg(msg, _("Director connected %sat: %s\n"),
140                     (njcr->dir_bsock && njcr->dir_bsock->tls)?_("using TLS "):"",
141                     dt);
142       } else {
143          len = Mmsg(msg, _("JobId %d Job %s is running.\n"),
144                     njcr->JobId, njcr->Job);
145          sendit(msg.c_str(), len, sp);
146          len = Mmsg(msg, _("    %s%s %s Job started: %s\n"),
147                     vss, job_level_to_str(njcr->getJobLevel()),
148                     job_type_to_str(njcr->getJobType()), dt);
149       }
150       sendit(msg.c_str(), len, sp);
151       if (njcr->JobId == 0) {
152          continue;
153       }
154       if (njcr->last_time == 0) {
155          njcr->last_time = njcr->start_time;
156       }
157       total_sec = now - njcr->start_time;
158       inst_sec = now - njcr->last_time;
159       if (total_sec <= 0) {
160          total_sec = 1;
161       }
162       if (inst_sec <= 0) {
163          inst_sec = 1;
164       }
165       /* Instanteous bps not smoothed */
166       inst_bps = (njcr->JobBytes - njcr->LastJobBytes) / inst_sec;
167       if (njcr->LastRate <= 0) {
168          njcr->LastRate = inst_bps;
169       }
170       /* Smooth the instantaneous bps a bit */
171       inst_bps = (2 * njcr->LastRate + inst_bps) / 3;
172       /* total bps (AveBytes/sec) since start of job */
173       total_bps = njcr->JobBytes / total_sec;
174       len = Mmsg(msg,  _("    Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s Errors=%d\n"
175                          "    Bwlimit=%s ReadBytes=%s\n"),
176            edit_uint64_with_commas(njcr->JobFiles, b1),
177            edit_uint64_with_commas(njcr->JobBytes, b2),
178            edit_uint64_with_commas(total_bps, b3),
179            edit_uint64_with_commas(inst_bps, b4),
180            njcr->JobErrors, edit_uint64_with_commas(njcr->max_bandwidth, b5),
181            edit_uint64_with_commas(njcr->ReadBytes, b6));
182       sendit(msg.c_str(), len, sp);
183
184       if (njcr->is_JobType(JT_RESTORE) && njcr->ExpectedFiles > 0) {
185          len = Mmsg(msg, _("    Files: Restored=%s Expected=%s Completed=%d%%\n"),
186             edit_uint64_with_commas(njcr->num_files_examined, b1),
187             edit_uint64_with_commas(njcr->ExpectedFiles, b2),
188             (100*njcr->num_files_examined)/njcr->ExpectedFiles);
189       } else {
190          len = Mmsg(msg, _("    Files: Examined=%s Backed up=%s\n"),
191             edit_uint64_with_commas(njcr->num_files_examined, b1),
192             edit_uint64_with_commas(njcr->JobFiles, b2));
193       }
194       /* Update only every 10 seconds */
195       if (now - njcr->last_time > 10) {
196          njcr->LastRate = inst_bps;
197          njcr->LastJobBytes = njcr->JobBytes;
198          njcr->last_time = now;
199       }
200       sendit(msg.c_str(), len, sp);
201       if (njcr->JobFiles > 0) {
202          njcr->lock();
203          len = Mmsg(msg, _("    Processing file: %s\n"), njcr->last_fname);
204          njcr->unlock();
205          sendit(msg.c_str(), len, sp);
206       }
207
208       found = true;
209       if (njcr->store_bsock) {
210          len = Mmsg(msg, "    SDReadSeqNo=%" lld " fd=%d SDtls=%d\n",
211                     njcr->store_bsock->read_seqno, njcr->store_bsock->m_fd,
212                     (njcr->store_bsock->tls)?1:0);
213          sendit(msg.c_str(), len, sp);
214       } else {
215          len = Mmsg(msg, _("    SDSocket closed.\n"));
216          sendit(msg.c_str(), len, sp);
217       }
218    }
219    endeach_jcr(njcr);
220
221    if (!found) {
222       len = Mmsg(msg, _("No Jobs running.\n"));
223       sendit(msg.c_str(), len, sp);
224    }
225    sendit(_("====\n"), 5, sp);
226 }
227
228 static void  list_running_jobs(STATUS_PKT *sp)
229 {
230    list_running_jobs_plain(sp);
231 }
232
233 /*
234  * Status command from Director
235  */
236 int status_cmd(JCR *jcr)
237 {
238    BSOCK *user = jcr->dir_bsock;
239    STATUS_PKT sp;
240
241    user->fsend("\n");
242    sp.bs = user;
243    sp.api = false;                         /* no API output */
244    output_status(&sp);
245
246    user->signal(BNET_EOD);
247    return 1;
248 }
249
250 /*
251  * .status command from Director
252  */
253 int qstatus_cmd(JCR *jcr)
254 {
255    BSOCK *dir = jcr->dir_bsock;
256    POOLMEM *cmd;
257    JCR *njcr;
258    s_last_job* job;
259    STATUS_PKT sp;
260
261    sp.bs = dir;
262    cmd = get_memory(dir->msglen+1);
263
264    if (sscanf(dir->msg, qstatus2, cmd, &sp.api, sp.api_opts) != 3) {
265       if (sscanf(dir->msg, qstatus1, cmd) != 1) {
266          pm_strcpy(&jcr->errmsg, dir->msg);
267          Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg);
268          dir->fsend(_("2900 Bad .status command, missing argument.\n"));
269          dir->signal(BNET_EOD);
270          free_memory(cmd);
271          return 0;
272       }
273    }
274    unbash_spaces(cmd);
275
276    if (strcasecmp(cmd, "current") == 0) {
277       dir->fsend(OKqstatus, cmd);
278       foreach_jcr(njcr) {
279          if (njcr->JobId != 0) {
280             dir->fsend(DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
281          }
282       }
283       endeach_jcr(njcr);
284    } else if (strcasecmp(cmd, "last") == 0) {
285       dir->fsend(OKqstatus, cmd);
286       if ((last_jobs) && (last_jobs->size() > 0)) {
287          job = (s_last_job*)last_jobs->last();
288          dir->fsend(DotStatusJob, job->JobId, job->JobStatus, job->Errors);
289       }
290    } else if (strcasecmp(cmd, "header") == 0) {
291        sp.api = true;
292        list_status_header(&sp);
293    } else if (strcasecmp(cmd, "running") == 0) {
294        sp.api = true;
295        list_running_jobs(&sp);
296    } else if (strcasecmp(cmd, "terminated") == 0) {
297        sp.api = MAX(sp.api, 1);
298        list_terminated_jobs(&sp); /* defined in lib/status.h */
299    } else {
300       pm_strcpy(&jcr->errmsg, dir->msg);
301       Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg);
302       dir->fsend(_("2900 Bad .status command, wrong argument.\n"));
303       dir->signal(BNET_EOD);
304       free_memory(cmd);
305       return 0;
306    }
307
308    dir->signal(BNET_EOD);
309    free_memory(cmd);
310    return 1;
311 }