/*
Bacula® - The Network Backup Solution
- Copyright (C) 2003-2007 Free Software Foundation Europe e.V.
+ Copyright (C) 2003-2008 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.
/* Forward referenced functions */
-static void send_blocked_status(DEVICE *dev, void sendit(const char *msg, int len, void *sarg), void *arg);
-static void list_terminated_jobs(void sendit(const char *msg, int len, void *sarg), void *arg);
-static void list_running_jobs(void sendit(const char *msg, int len, void *sarg), void *arg);
-static void list_jobs_waiting_on_reservation(void sendit(const char *msg, int len, void *sarg), void *arg);
+static void sendit(const char *msg, int len, BSOCK *bs);
+static void sendit(POOL_MEM &msg, int len, BSOCK *bs);
+static void sendit(const char *msg, int len, void *arg);
+
+static void send_blocked_status(DEVICE *dev, BSOCK *bs);
+static void list_terminated_jobs(BSOCK *bs);
+static void list_running_jobs(BSOCK *bs);
+static void list_jobs_waiting_on_reservation(BSOCK *bs);
+static void list_status_header(BSOCK *bs);
+static void list_devices(BSOCK *bs);
static const char *level_to_str(int level);
/*
* Status command from Director
*/
-void output_status(void sendit(const char *msg, int len, void *sarg), void *arg)
+void output_status(BSOCK *bs)
{
- DEVRES *device;
- AUTOCHANGER *changer;
- DEVICE *dev;
- char dt[MAX_TIME_LENGTH];
- char b1[35], b2[35], b3[35], b4[35], b5[35];
- POOLMEM *msg;
- int bpb;
+ POOL_MEM msg(PM_MESSAGE);
int len;
- msg = get_pool_memory(PM_MESSAGE);
-
- len = Mmsg(msg, _("%s Version: %s (%s) %s %s %s\n"),
- my_name, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
- sendit(msg, len, arg);
-
- bstrftime_nc(dt, sizeof(dt), daemon_start_time);
-
-
- len = Mmsg(msg, _("Daemon started %s, %d Job%s run since started.\n"),
- dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
- sendit(msg, len, arg);
-
- 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(sm_bytes, b2),
- edit_uint64_with_commas(sm_max_bytes, b3),
- edit_uint64_with_commas(sm_buffers, b4),
- edit_uint64_with_commas(sm_max_buffers, b5));
- sendit(msg, len, arg);
- len = Mmsg(msg, "Sizes: boffset_t=%d size_t=%d int32_t=%d int64_t=%d\n",
- (int)sizeof(boffset_t), (int)sizeof(size_t), (int)sizeof(int32_t),
- (int)sizeof(int64_t));
- sendit(msg, len, arg);
+ list_status_header(bs);
/*
* List running jobs
*/
- list_running_jobs(sendit, arg);
+ list_running_jobs(bs);
/*
* List jobs stuck in reservation system
*/
- list_jobs_waiting_on_reservation(sendit, arg);
+ list_jobs_waiting_on_reservation(bs);
/*
* List terminated jobs
*/
- list_terminated_jobs(sendit, arg);
+ list_terminated_jobs(bs);
/*
* List devices
*/
+ list_devices(bs);
+
+
+ len = Mmsg(msg, _("In Use Volume status:\n"));
+ sendit(msg, len, bs);
+
+ list_volumes(sendit, (void *)bs);
+ sendit("====\n\n", 6, bs);
+
+#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 *)bs);
+}
+
+
+static void list_devices(BSOCK *bs)
+{
+ DEVRES *device;
+ AUTOCHANGER *changer;
+ DEVICE *dev;
+ char b1[35], b2[35], b3[35];
+ POOL_MEM msg(PM_MESSAGE);
+ int len;
+ int bpb;
+
len = Mmsg(msg, _("\nDevice status:\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
foreach_res(changer, R_AUTOCHANGER) {
len = Mmsg(msg, _("Autochanger \"%s\" with devices:\n"),
changer->hdr.name);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
foreach_alist(device, changer->device) {
if (device->dev) {
len = Mmsg(msg, " %s\n", device->dev->print_name());
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else {
len = Mmsg(msg, " %s\n", device->hdr.name);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
}
}
dev->VolHdr.VolumeName,
dev->pool_name[0]?dev->pool_name:"*unknown*",
dev->device->media_type);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else {
len = Mmsg(msg, _("Device %s open but no Bacula volume is currently mounted.\n"),
dev->print_name());
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
- send_blocked_status(dev, sendit, arg);
+ send_blocked_status(dev, bs);
if (dev->can_append()) {
bpb = dev->VolCatInfo.VolCatBlocks;
if (bpb <= 0) {
edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
edit_uint64_with_commas(bpb, b3));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else { /* reading */
bpb = dev->VolCatInfo.VolCatReads;
if (bpb <= 0) {
edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1),
edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2),
edit_uint64_with_commas(bpb, b3));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
len = Mmsg(msg, _(" Positioned at File=%s Block=%s\n"),
edit_uint64_with_commas(dev->file, b1),
edit_uint64_with_commas(dev->block_num, b2));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else {
if (dev) {
len = Mmsg(msg, _("Device %s is not open.\n"), dev->print_name());
- sendit(msg, len, arg);
- send_blocked_status(dev, sendit, arg);
+ sendit(msg, len, bs);
+ send_blocked_status(dev, bs);
} else {
len = Mmsg(msg, _("Device \"%s\" is not open or does not exist.\n"), device->hdr.name);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
}
}
- sendit("====\n\n", 6, arg);
- len = Mmsg(msg, _("In Use Volume status:\n"));
- sendit(msg, len, arg);
- list_volumes(sendit, arg);
- sendit("====\n\n", 6, arg);
+ sendit("====\n\n", 6, bs);
+}
-#ifdef xxx
- if (debug_level > 10) {
- user->fsend(_("====\n\n"));
- dump_resource(R_DEVICE, resources[R_DEVICE-r_first].res_head, sendit, user);
- user->fsend(_("====\n\n"));
- }
-#endif
+static void list_status_header(BSOCK *bs)
+{
+ char dt[MAX_TIME_LENGTH];
+ char b1[35], b2[35], b3[35], b4[35], b5[35];
+ POOL_MEM msg(PM_MESSAGE);
+ int len;
+
+ len = Mmsg(msg, _("%s Version: %s (%s) %s %s %s\n"),
+ my_name, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
+ sendit(msg, len, bs);
- list_spool_stats(sendit, arg);
+ bstrftime_nc(dt, sizeof(dt), daemon_start_time);
+
+
+ len = Mmsg(msg, _("Daemon started %s, %d Job%s run since started.\n"),
+ dt, num_jobs_run, num_jobs_run == 1 ? "" : "s");
+ sendit(msg, len, bs);
- free_pool_memory(msg);
+ 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(sm_bytes, b2),
+ edit_uint64_with_commas(sm_max_bytes, b3),
+ edit_uint64_with_commas(sm_buffers, b4),
+ edit_uint64_with_commas(sm_max_buffers, b5));
+ sendit(msg, len, bs);
+ len = Mmsg(msg, "Sizes: boffset_t=%d size_t=%d int32_t=%d int64_t=%d\n",
+ (int)sizeof(boffset_t), (int)sizeof(size_t), (int)sizeof(int32_t),
+ (int)sizeof(int64_t));
+ sendit(msg, len, bs);
}
-static void send_blocked_status(DEVICE *dev, void sendit(const char *msg, int len, void *sarg), void *arg)
+static void send_blocked_status(DEVICE *dev, BSOCK *bs)
{
- char *msg;
+ POOL_MEM msg(PM_MESSAGE);
int len;
- msg = (char *)get_pool_memory(PM_MESSAGE);
-
if (!dev) {
len = Mmsg(msg, _("No DEVICE structure.\n\n"));
- sendit(msg, len, arg);
- free_pool_memory(msg);
+ sendit(msg, len, bs);
return;
}
switch (dev->blocked()) {
case BST_UNMOUNTED:
len = Mmsg(msg, _(" Device is BLOCKED. User unmounted.\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
break;
case BST_UNMOUNTED_WAITING_FOR_SYSOP:
len = Mmsg(msg, _(" Device is BLOCKED. User unmounted during wait for media/mount.\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
break;
case BST_WAITING_FOR_SYSOP:
{
dcr->VolumeName,
dcr->pool_name,
dcr->media_type);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
found_jcr = true;
} else if (dcr->jcr->JobStatus == JS_WaitMedia) {
len = Mmsg(msg, _(" Device is BLOCKED waiting to create a volume for:\n"
" Media type: %s\n"),
dcr->pool_name,
dcr->media_type);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
found_jcr = true;
}
}
if (!found_jcr) {
len = Mmsg(msg, _(" Device is BLOCKED waiting for media.\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
}
break;
case BST_DOING_ACQUIRE:
len = Mmsg(msg, _(" Device is being initialized.\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
break;
case BST_WRITING_LABEL:
len = Mmsg(msg, _(" Device is blocked labeling a Volume.\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
break;
default:
break;
if (dev->Slot > 0) {
len = Mmsg(msg, _(" Slot %d is loaded in drive %d.\n"),
dev->Slot, dev->drive_index);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else if (dev->Slot == 0) {
len = Mmsg(msg, _(" Drive %d is not loaded.\n"), dev->drive_index);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else {
len = Mmsg(msg, _(" Drive %d status unknown.\n"), dev->drive_index);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
}
if (debug_level > 1) {
len = Mmsg(msg, _("Configured device capabilities:\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, "%sEOF %sBSR %sBSF %sFSR %sFSF %sEOM %sREM %sRACCESS %sAUTOMOUNT %sLABEL %sANONVOLS %sALWAYSOPEN\n",
dev->capabilities & CAP_EOF ? "" : "!",
dev->capabilities & CAP_LABEL ? "" : "!",
dev->capabilities & CAP_ANONVOLS ? "" : "!",
dev->capabilities & CAP_ALWAYSOPEN ? "" : "!");
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, _("Device state:\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, "%sOPENED %sTAPE %sLABEL %sMALLOC %sAPPEND %sREAD %sEOT %sWEOT %sEOF %sNEXTVOL %sSHORT %sMOUNTED\n",
dev->is_open() ? "" : "!",
dev->state & ST_NEXTVOL ? "" : "!",
dev->state & ST_SHORT ? "" : "!",
dev->state & ST_MOUNTED ? "" : "!");
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, _("num_writers=%d block=%d\n\n"), dev->num_writers, dev->blocked());
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, _("Device parameters:\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, _("Archive name: %s Device name: %s\n"), dev->archive_name(),
dev->name());
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, _("File=%u block=%u\n"), dev->file, dev->block_num);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len = Mmsg(msg, _("Min block=%u Max block=%u\n"), dev->min_block_size, dev->max_block_size);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
-
- free_pool_memory(msg);
}
-static void list_running_jobs(void sendit(const char *msg, int len, void *sarg), void *arg)
+static void list_running_jobs(BSOCK *bs)
{
bool found = false;
int bps, sec;
JCR *jcr;
DCR *dcr, *rdcr;
char JobName[MAX_NAME_LENGTH];
- char *msg, b1[30], b2[30], b3[30];
+ char b1[30], b2[30], b3[30];
int len;
-
- msg = (char *)get_pool_memory(PM_MESSAGE);
+ POOL_MEM msg(PM_MESSAGE);
len = Mmsg(msg, _("\nRunning Jobs:\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
foreach_jcr(jcr) {
if (jcr->JobStatus == JS_WaitFD) {
len = Mmsg(msg, _("%s Job %s waiting for Client connection.\n"),
job_type_to_str(jcr->JobType), jcr->Job);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
dcr = jcr->dcr;
rdcr = jcr->read_dcr;
rdcr->pool_name,
rdcr->dev?rdcr->dev->print_name():
rdcr->device->device_name);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
if (dcr && dcr->device) {
len = Mmsg(msg, _("Writing: %s %s job %s JobId=%d Volume=\"%s\"\n"
dcr->pool_name,
dcr->dev?dcr->dev->print_name():
dcr->device->device_name);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
len= Mmsg(msg, _(" spooling=%d despooling=%d despool_wait=%d\n"),
dcr->spooling, dcr->despooling, dcr->despool_wait);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
sec = time(NULL) - jcr->run_time;
if (sec <= 0) {
edit_uint64_with_commas(jcr->JobFiles, b1),
edit_uint64_with_commas(jcr->JobBytes, b2),
edit_uint64_with_commas(bps, b3));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
found = true;
#ifdef DEBUG
if (jcr->file_bsock) {
edit_uint64_with_commas(jcr->file_bsock->read_seqno, b1),
jcr->file_bsock->in_msg_no, jcr->file_bsock->out_msg_no,
jcr->file_bsock->m_fd);
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
} else {
len = Mmsg(msg, _(" FDSocket closed\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
#endif
}
if (!found) {
len = Mmsg(msg, _("No Jobs running.\n"));
- sendit(msg, len, arg);
+ sendit(msg, len, bs);
}
- sendit("====\n", 5, arg);
-
- free_pool_memory(msg);
+ sendit("====\n", 5, bs);
}
-static void list_jobs_waiting_on_reservation(void sendit(const char *msg, int len, void *sarg), void *arg)
+static void list_jobs_waiting_on_reservation(BSOCK *bs)
{
JCR *jcr;
- char *msg;
+ POOL_MEM msg(PM_MESSAGE);
+ int len;
- msg = _("\nJobs waiting to reserve a drive:\n");
- sendit(msg, strlen(msg), arg);
+ len = Mmsg(msg, _("\nJobs waiting to reserve a drive:\n"));
+ sendit(msg, len, bs);
foreach_jcr(jcr) {
if (!jcr->reserve_msgs) {
continue;
}
- send_drive_reserve_messages(jcr, sendit, arg);
+ send_drive_reserve_messages(jcr, sendit, bs);
}
endeach_jcr(jcr);
- sendit("====\n", 5, arg);
+ sendit("====\n", 5, bs);
}
-static void list_terminated_jobs(void sendit(const char *msg, int len, void *sarg), void *arg)
+static void list_terminated_jobs(BSOCK *bs)
{
char dt[MAX_TIME_LENGTH], b1[30], b2[30];
char level[10];
const char *msg;
msg = _("\nTerminated Jobs:\n");
- sendit(msg, strlen(msg), arg);
+ sendit(msg, strlen(msg), bs);
if (last_jobs->size() == 0) {
- sendit("====\n", 5, arg);
+ sendit("====\n", 5, bs);
return;
}
lock_last_jobs_list();
msg = _(" JobId Level Files Bytes Status Finished Name \n");
- sendit(msg, strlen(msg), arg);
+ sendit(msg, strlen(msg), bs);
msg = _("===================================================================\n");
- sendit(msg, strlen(msg), arg);
+ sendit(msg, strlen(msg), bs);
foreach_dlist(je, last_jobs) {
char JobName[MAX_NAME_LENGTH];
const char *termstat;
edit_uint64_with_suffix(je->JobBytes, b2),
termstat,
dt, JobName);
- sendit(buf, strlen(buf), arg);
+ sendit(buf, strlen(buf), bs);
}
unlock_last_jobs_list();
- sendit("====\n", 5, arg);
+ sendit("====\n", 5, bs);
}
/*
/*
* Send to Director
*/
-static void dir_sendit(const char *msg, int len, void *arg)
+static void sendit(const char *msg, int len, BSOCK *bs)
+{
+ memcpy(bs->msg, msg, len+1);
+ bs->msglen = len+1;
+ bs->send();
+}
+
+static void sendit(const char *msg, int len, void *arg)
{
- BSOCK *user = (BSOCK *)arg;
+ BSOCK *bs = (BSOCK *)arg;
+ memcpy(bs->msg, msg, len+1);
+ bs->msglen = len+1;
+ bs->send();
+}
- memcpy(user->msg, msg, len+1);
- user->msglen = len+1;
- user->send();
+static void sendit(POOL_MEM &msg, int len, BSOCK *bs)
+{
+ memcpy(bs->msg, msg.c_str(), len+1);
+ bs->msglen = len+1;
+ bs->send();
}
+
/*
* Status command from Director
*/
bool status_cmd(JCR *jcr)
{
- BSOCK *user = jcr->dir_bsock;
-
- user->fsend("\n");
- output_status(dir_sendit, (void *)user);
+ BSOCK *bs = jcr->dir_bsock;
- user->signal(BNET_EOD);
+ bs->fsend("\n");
+ output_status(bs);
+ bs->signal(BNET_EOD);
return 1;
}
#if defined(HAVE_WIN32)
int bacstat = 0;
+/* Return a one line status for the tray monitor */
char *bac_status(char *buf, int buf_len)
{
JCR *njcr;