Skip to content

Commit

Permalink
Status storage should only show configured devices.
Browse files Browse the repository at this point in the history
When you do a status storage from the director to a defined storage on a
storage daemon you expect that it only shows you the actually configured
devices in the director and not all devices configured in the storage
daemon. For that to work we now send the list of devices (normally one)
that are configured in the director config and use that as the selection
criteria for showing the right devices only.
  • Loading branch information
Marco van Wieringen committed Nov 16, 2015
1 parent 1c77dd5 commit 99ba4af
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 23 deletions.
24 changes: 21 additions & 3 deletions src/dird/sd_cmds.c
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
Copyright (C) 2011-2012 Planets Communications B.V.
Copyright (C) 2013-2013 Bareos GmbH & Co. KG
Copyright (C) 2013-2015 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -53,7 +53,7 @@ static char canceljobcmd[] =
static char dotstatuscmd[] =
".status %s\n";
static char statuscmd[] =
"status\n";
"status %s\n";
static char bandwidthcmd[] =
"setbandwidth=%lld Job=%s\n";
static char pluginoptionscmd[] =
Expand Down Expand Up @@ -772,8 +772,26 @@ void do_native_storage_status(UAContext *ua, STORERES *store, char *cmd)
sd = ua->jcr->store_bsock;
if (cmd) {
sd->fsend(dotstatuscmd, cmd);

} else {
sd->fsend(statuscmd);
int cnt = 0;
DEVICERES *device;
POOL_MEM devicenames;

/*
* Build a list of devicenames that belong to this storage defintion.
*/
foreach_alist(device, store->device) {
if (cnt == 0) {
pm_strcpy(devicenames, device->name());
} else {
pm_strcat(devicenames, ",");
pm_strcat(devicenames, device->name());
}
}

bash_spaces(devicenames);
sd->fsend(statuscmd, devicenames.c_str());
}

while (sd->recv() >= 0) {
Expand Down
4 changes: 2 additions & 2 deletions src/stored/dir_cmd.c
Expand Up @@ -115,7 +115,7 @@ static char OKpluginoptions[] =
extern bool finish_cmd(JCR *jcr);
extern bool job_cmd(JCR *jcr);
extern bool nextrun_cmd(JCR *jcr);
extern bool qstatus_cmd(JCR *jcr);
extern bool dotstatus_cmd(JCR *jcr);
//extern bool query_cmd(JCR *jcr);
extern bool status_cmd(JCR *sjcr);
extern bool use_cmd(JCR *jcr);
Expand Down Expand Up @@ -190,7 +190,7 @@ static struct s_cmds cmds[] = {
{ "setdebug=", setdebug_cmd, false }, /* Set debug level */
{ "stats", stats_cmd, false },
{ "status", status_cmd, true },
{ ".status", qstatus_cmd, true },
{ ".status", dotstatus_cmd, true },
{ "unmount", unmount_cmd, false },
{ "use storage=", use_cmd, false },
{ NULL, NULL, false } /* list terminator */
Expand Down
7 changes: 7 additions & 0 deletions src/stored/protos.h
Expand Up @@ -162,6 +162,13 @@ void free_bsr(BSR *bsr);
void free_restore_volume_list(JCR *jcr);
void create_restore_volume_list(JCR *jcr);

/* status.c */
bool status_cmd(JCR *jcr);
bool dotstatus_cmd(JCR *jcr);
#if defined(HAVE_WIN32)
char *bareos_status(char *buf, int buf_len);
#endif

/* read.c */
bool do_read_data(JCR *jcr);

Expand Down
118 changes: 100 additions & 18 deletions src/stored/status.c
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2003-2012 Free Software Foundation Europe e.V.
Copyright (C) 2011-2012 Planets Communications B.V.
Copyright (C) 2013-2013 Bareos GmbH & Co. KG
Copyright (C) 2013-2015 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -38,10 +38,12 @@ extern BSOCK *filed_chan;
extern void *start_heap;

/* Static variables */
static char qstatus[] =
static char statuscmd[] =
"status %s\n";
static char dotstatuscmd[] =
".status %127s\n";

static char OKqstatus[] =
static char OKdotstatus[] =
"3000 OK .status\n";
static char DotStatusJob[] =
"JobId=%d JobStatus=%c JobErrors=%d\n";
Expand All @@ -61,14 +63,14 @@ 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);
static void list_status_header(STATUS_PKT *sp);
static void list_devices(JCR *jcr, STATUS_PKT *sp);
static void list_devices(JCR *jcr, STATUS_PKT *sp, const char *devicenames);

static const char *level_to_str(int level);

/*
* Status command from Director
*/
static void output_status(JCR *jcr, STATUS_PKT *sp)
static void output_status(JCR *jcr, STATUS_PKT *sp, const char *devicenames)
{
int len;
POOL_MEM msg(PM_MESSAGE);
Expand All @@ -93,7 +95,7 @@ static void output_status(JCR *jcr, STATUS_PKT *sp)
/*
* List devices
*/
list_devices(jcr, sp);
list_devices(jcr, sp, devicenames);

if (!sp->api) {
len = Mmsg(msg, _("Used Volume status:\n"));
Expand Down Expand Up @@ -152,7 +154,37 @@ static find_device(char *devname)
}
#endif

static void list_devices(JCR *jcr, STATUS_PKT *sp)
static bool need_to_list_device(const char *devicenames, const char *devicename)
{
char *cur, *bp;
POOL_MEM namelist;

/*
* Make a local copy that we can split on ','
*/
pm_strcpy(namelist, devicenames);

/*
* See if devicename is in the list.
*/
cur = namelist.c_str();
while (cur) {
bp = strchr(cur, ',');
if (bp) {
*bp++ = '\0';
}

if (bstrcasecmp(cur, devicename)) {
return true;
}

cur = bp;
}

return false;
}

static void list_devices(JCR *jcr, STATUS_PKT *sp, const char *devicenames)
{
int len;
int bpb;
Expand All @@ -168,6 +200,13 @@ static void list_devices(JCR *jcr, STATUS_PKT *sp)
}

foreach_res(changer, R_AUTOCHANGER) {
/*
* See if we need to list this autochanger.
*/
if (devicenames && !need_to_list_device(devicenames, changer->hdr.name)) {
continue;
}

len = Mmsg(msg, _("Autochanger \"%s\" with devices:\n"), changer->hdr.name);
sendit(msg, len, sp);

Expand All @@ -183,6 +222,30 @@ static void list_devices(JCR *jcr, STATUS_PKT *sp)
}

foreach_res(device, R_DEVICE) {
/*
* See if we need to check for devicenames at all.
*/
if (devicenames) {
/*
* See if this device is part of an autochanger.
*/
if (device->changer_res) {
/*
* See if we need to list this particular device part of the given autochanger.
*/
if (!need_to_list_device(devicenames, device->changer_res->hdr.name)) {
continue;
}
} else {
/*
* Try matching a non autochanger device.
*/
if (!need_to_list_device(devicenames, device->hdr.name)) {
continue;
}
}
}

dev = device->dev;
if (dev && dev->is_open()) {
if (dev->is_labeled()) {
Expand Down Expand Up @@ -226,8 +289,10 @@ static void list_devices(JCR *jcr, STATUS_PKT *sp)
len = Mmsg(msg, _("\nDevice %s open but no Bareos volume is currently mounted.\n"), dev->print_name());
sendit(msg, len, sp);
}

trigger_device_status_hook(jcr, device, sp, bsdEventDriveStatus);
send_blocked_status(dev, sp);

if (dev->can_append()) {
bpb = dev->VolCatInfo.VolCatBlocks;
if (bpb <= 0) {
Expand Down Expand Up @@ -255,10 +320,12 @@ static void list_devices(JCR *jcr, STATUS_PKT *sp)
edit_uint64_with_commas(bpb, b3));
sendit(msg, len, sp);
}

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, sp);

trigger_device_status_hook(jcr, device, sp, bsdEventVolumeStatus);
} else {
if (dev) {
Expand Down Expand Up @@ -877,48 +944,62 @@ static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp)
*/
bool status_cmd(JCR *jcr)
{
BSOCK *dir = jcr->dir_bsock;
POOL_MEM devicenames;
STATUS_PKT sp;
BSOCK *dir = jcr->dir_bsock;

dir->fsend("\n");
sp.bs = dir;
output_status(jcr, &sp);
devicenames.check_size(dir->msglen);
if (sscanf(dir->msg, statuscmd, devicenames.c_str()) != 1) {
pm_strcpy(jcr->errmsg, dir->msg);
dir->fsend(_("3900 No arg in status command: %s\n"), jcr->errmsg);
dir->signal(BNET_EOD);

return false;
}
unbash_spaces(devicenames);

dir->fsend("\n");
output_status(jcr, &sp, devicenames.c_str());
dir->signal(BNET_EOD);

return true;
}

/*
* .status command from Director
*/
bool qstatus_cmd(JCR *jcr)
bool dotstatus_cmd(JCR *jcr)
{
BSOCK *dir = jcr->dir_bsock;
POOL_MEM cmd;
JCR *njcr;
s_last_job* job;
POOL_MEM cmd;
STATUS_PKT sp;
s_last_job* job;
BSOCK *dir = jcr->dir_bsock;

sp.bs = dir;
if (sscanf(dir->msg, qstatus, cmd.c_str()) != 1) {
cmd.check_size(dir->msglen);
if (sscanf(dir->msg, dotstatuscmd, cmd.c_str()) != 1) {
pm_strcpy(jcr->errmsg, dir->msg);
dir->fsend(_("3900 No arg in .status command: %s\n"), jcr->errmsg);
dir->signal(BNET_EOD);

return false;
}
unbash_spaces(cmd);

Dmsg1(200, "cmd=%s\n", cmd.c_str());

if (bstrcasecmp(cmd.c_str(), "current")) {
dir->fsend(OKqstatus, cmd.c_str());
dir->fsend(OKdotstatus, cmd.c_str());
foreach_jcr(njcr) {
if (njcr->JobId != 0) {
dir->fsend(DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
}
}
endeach_jcr(njcr);
} else if (bstrcasecmp(cmd.c_str(), "last")) {
dir->fsend(OKqstatus, cmd.c_str());
dir->fsend(OKdotstatus, 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);
Expand All @@ -934,7 +1015,7 @@ bool qstatus_cmd(JCR *jcr)
list_jobs_waiting_on_reservation(&sp);
} else if (bstrcasecmp(cmd.c_str(), "devices")) {
sp.api = true;
list_devices(jcr, &sp);
list_devices(jcr, &sp, NULL);
} else if (bstrcasecmp(cmd.c_str(), "volumes")) {
sp.api = true;
list_volumes(sendit, &sp);
Expand All @@ -954,6 +1035,7 @@ bool qstatus_cmd(JCR *jcr)
return false;
}
dir->signal(BNET_EOD);

return true;
}

Expand Down

0 comments on commit 99ba4af

Please sign in to comment.