2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
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.
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.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Routines for getting and displaying tape alerts
23 * Written by Kern Sibbald, October MMXVI
27 #include "bacula.h" /* pull in global headers */
28 #include "stored.h" /* pull in Storage Deamon headers */
30 #include "tape_alert_msgs.h"
32 static const int dbglvl = 120;
34 #define MAX_MSG 54 /* Maximum alert message number */
36 void alert_callback(void *ctx, const char *short_msg, const char *long_msg,
37 char *Volume, int severity, int flags, int alertno, utime_t alert_time)
39 DCR *dcr = (DCR *)ctx;
41 DEVICE *dev = dcr->dev;
55 if (flags & TA_DISABLE_DRIVE) {
57 Jmsg(jcr, M_WARNING, 0, _("Disabled Device %s due to tape alert=%d.\n"),
58 dev->print_name(), alertno);
59 Tmsg2(dbglvl, _("Disabled Device %s due to tape alert=%d.\n"),
60 dev->print_name(), alertno);
62 if (flags & TA_DISABLE_VOLUME) {
63 dev->setVolCatStatus("Disabled");
64 dev->VolCatInfo.VolEnabled = false;
65 dir_update_volume_info(dcr, false, true);
66 Jmsg(jcr, M_WARNING, 0, _("Disabled Volume \"%s\" due to tape alert=%d.\n"),
68 Tmsg2(dbglvl, _("Disabled Volume \"%s\" due to tape alert=%d.\n"),
71 Jmsg(jcr, type, (utime_t)alert_time, _("Alert: Volume=\"%s\" alert=%d: ERR=%s\n"),
72 Volume, alertno, long_msg);
75 bool tape_dev::get_tape_alerts(DCR *dcr)
79 if (!job_canceled(jcr) && dcr->device->alert_command &&
80 dcr->device->control_name) {
85 ALERT *alert, *rmalert;
87 const char *fmt = "TapeAlert[%d]";
90 alert_list = New(alist(10));
92 alertcmd = get_pool_memory(PM_FNAME);
93 alertcmd = edit_device_codes(dcr, alertcmd, dcr->device->alert_command, "");
94 /* Wait maximum 5 minutes */
95 bpipe = open_bpipe(alertcmd, 60 * 5, "r");
98 alert = (ALERT *)malloc(sizeof(ALERT));
99 memset(alert->alerts, 0, sizeof(alert->alerts));
100 alert->Volume = bstrdup(getVolCatName());
101 alert->alert_time = (utime_t)time(NULL);
102 while (fgets(line, (int)sizeof(line), bpipe->rfd)) {
104 if (bsscanf(line, fmt, &alertno) == 1) {
106 if (nalerts+1 > (int)sizeof(alert->alerts)) {
109 alert->alerts[nalerts++] = alertno;
114 status = close_bpipe(bpipe);
116 /* Maintain First in, last out list */
117 if (alert_list->size() > 8) {
118 rmalert = (ALERT *)alert_list->last();
119 free(rmalert->Volume);
123 alert_list->prepend(alert);
128 free_pool_memory(alertcmd);
135 Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
136 alertcmd, be.bstrerror(status));
137 Tmsg2(10, _("3997 Bad alert command: %s: ERR=%s.\n"),
138 alertcmd, be.bstrerror(status));
141 Dmsg1(400, "alert status=%d\n", status);
142 free_pool_memory(alertcmd);
144 if (!dcr->device->alert_command) {
145 Dmsg1(dbglvl, "Cannot do tape alerts: no Alert Command specified for device %s\n",
147 Tmsg1(dbglvl, "Cannot do tape alerts: no Alert Command specified for device %s\n",
151 if (!dcr->device->control_name) {
152 Dmsg1(dbglvl, "Cannot do tape alerts: no Control Device specified for device %s\n",
154 Tmsg1(dbglvl, "Cannot do tape alerts: no Control Device specified for device %s\n",
163 * Print desired tape alert messages
165 void tape_dev::show_tape_alerts(DCR *dcr, alert_list_type list_type,
166 alert_list_which which, alert_cb alert_callback)
175 Dmsg1(dbglvl, "There are %d alerts.\n", alert_list->size());
178 foreach_alist(alert, alert_list) {
179 for (i=0; i<(int)sizeof(alert->alerts) && alert->alerts[i]; i++) {
180 code = alert->alerts[i];
181 Dmsg4(dbglvl, "Volume=%s alert=%d severity=%c flags=0x%x\n", alert->Volume, code,
182 ta_errors[code].severity, (int)ta_errors[code].flags);
183 alert_callback(dcr, ta_errors[code].short_msg, long_msg[code],
184 alert->Volume, ta_errors[code].severity,
185 ta_errors[code].flags, code, (utime_t)alert->alert_time);
187 if (which == list_last) {
193 foreach_alist(alert, alert_list) {
194 for (i=0; i<(int)sizeof(alert->alerts) && alert->alerts[i]; i++) {
195 code = alert->alerts[i];
196 Dmsg4(dbglvl, "Volume=%s severity=%c flags=0x%x alert=%s\n", alert->Volume,
197 ta_errors[code].severity, (int)ta_errors[code].flags,
198 ta_errors[code].short_msg);
199 alert_callback(dcr, ta_errors[code].short_msg, long_msg[code],
200 alert->Volume, ta_errors[code].severity,
201 ta_errors[code].flags, code, (utime_t)alert->alert_time);
203 if (which == list_last) {
213 * Delete alert list returning number deleted
215 int tape_dev::delete_alerts()
221 foreach_alist(alert, alert_list) {
225 alert_list->destroy();