1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2013-2013 Planets Communications B.V.
5 Copyright (C) 2013-2016 Bareos GmbH & Co. KG
6
7 This program is Free Software; you can redistribute it and/or
8 modify it under the terms of version three of the GNU Affero General Public
9 License as published by the Free Software Foundation, which is
10 listed in the file LICENSE.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21 */
22 /*
23 * Marco van Wieringen, November 2013
24 */
25 /**
26 * @file
27 * SCSI Tape Alert Storage daemon Plugin
28 */
29 #include "include/bareos.h"
30 #include "stored/stored.h"
31 #include "lib/scsi_tapealert.h"
32
33 using namespace storagedaemon;
34
35 #define PLUGIN_LICENSE "Bareos AGPLv3"
36 #define PLUGIN_AUTHOR "Marco van Wieringen"
37 #define PLUGIN_DATE "November 2013"
38 #define PLUGIN_VERSION "1"
39 #define PLUGIN_DESCRIPTION "SCSI Tape Alert Storage Daemon Plugin"
40 #define PLUGIN_USAGE "(No usage yet)"
41
42 /**
43 * Forward referenced functions
44 */
45 static bRC newPlugin(bpContext* ctx);
46 static bRC freePlugin(bpContext* ctx);
47 static bRC getPluginValue(bpContext* ctx, psdVariable var, void* value);
48 static bRC setPluginValue(bpContext* ctx, psdVariable var, void* value);
49 static bRC handlePluginEvent(bpContext* ctx, bsdEvent* event, void* value);
50 static bRC handle_tapealert_readout(void* value);
51
52 /**
53 * Pointers to Bareos functions
54 */
55 static bsdFuncs* bfuncs = NULL;
56 static bsdInfo* binfo = NULL;
57
58 static genpInfo pluginInfo = {sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION,
59 SD_PLUGIN_MAGIC, PLUGIN_LICENSE,
60 PLUGIN_AUTHOR, PLUGIN_DATE,
61 PLUGIN_VERSION, PLUGIN_DESCRIPTION,
62 PLUGIN_USAGE};
63
64 static psdFuncs pluginFuncs = {sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION,
65
66 /*
67 * Entry points into plugin
68 */
69 newPlugin, /* new plugin instance */
70 freePlugin, /* free plugin instance */
71 getPluginValue, setPluginValue,
72 handlePluginEvent};
73
74 static int const debuglevel = 200;
75
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79
80 /**
81 * loadPlugin() and unloadPlugin() are entry points that are
82 * exported, so Bareos can directly call these two entry points
83 * they are common to all Bareos plugins.
84 *
85 * External entry point called by Bareos to "load the plugin
86 */
loadPlugin(bsdInfo * lbinfo,bsdFuncs * lbfuncs,genpInfo ** pinfo,psdFuncs ** pfuncs)87 bRC loadPlugin(bsdInfo* lbinfo,
88 bsdFuncs* lbfuncs,
89 genpInfo** pinfo,
90 psdFuncs** pfuncs)
91 {
92 bfuncs = lbfuncs; /* set Bareos funct pointers */
93 binfo = lbinfo;
94 Dmsg2(debuglevel, "scsitapealert-sd: Loaded: size=%d version=%d\n",
95 bfuncs->size, bfuncs->version);
96 *pinfo = &pluginInfo; /* return pointer to our info */
97 *pfuncs = &pluginFuncs; /* return pointer to our functions */
98
99 return bRC_OK;
100 }
101
102 /**
103 * External entry point to unload the plugin
104 */
unloadPlugin()105 bRC unloadPlugin() { return bRC_OK; }
106
107 #ifdef __cplusplus
108 }
109 #endif
110
111 /**
112 * The following entry points are accessed through the function
113 * pointers we supplied to Bareos. Each plugin type (dir, fd, sd)
114 * has its own set of entry points that the plugin must define.
115 *
116 * Create a new instance of the plugin i.e. allocate our private storage
117 */
newPlugin(bpContext * ctx)118 static bRC newPlugin(bpContext* ctx)
119 {
120 int JobId = 0;
121
122 bfuncs->getBareosValue(ctx, bsdVarJobId, (void*)&JobId);
123 Dmsg1(debuglevel, "scsitapealert-sd: newPlugin JobId=%d\n", JobId);
124
125 /*
126 * Only register plugin events we are interested in.
127 */
128 bfuncs->registerBareosEvents(
129 ctx, 6, bsdEventVolumeLoad, bsdEventLabelVerified, bsdEventReadError,
130 bsdEventWriteError, bsdEventVolumeUnload, bsdEventDeviceRelease);
131
132 return bRC_OK;
133 }
134
135 /**
136 * Free a plugin instance, i.e. release our private storage
137 */
freePlugin(bpContext * ctx)138 static bRC freePlugin(bpContext* ctx)
139 {
140 int JobId = 0;
141
142 bfuncs->getBareosValue(ctx, bsdVarJobId, (void*)&JobId);
143 Dmsg1(debuglevel, "scsitapealert-sd: freePlugin JobId=%d\n", JobId);
144
145 return bRC_OK;
146 }
147
148 /**
149 * Return some plugin value (none defined)
150 */
getPluginValue(bpContext * ctx,psdVariable var,void * value)151 static bRC getPluginValue(bpContext* ctx, psdVariable var, void* value)
152 {
153 Dmsg1(debuglevel, "scsitapealert-sd: getPluginValue var=%d\n", var);
154
155 return bRC_OK;
156 }
157
158 /**
159 * Set a plugin value (none defined)
160 */
setPluginValue(bpContext * ctx,psdVariable var,void * value)161 static bRC setPluginValue(bpContext* ctx, psdVariable var, void* value)
162 {
163 Dmsg1(debuglevel, "scsitapealert-sd: setPluginValue var=%d\n", var);
164
165 return bRC_OK;
166 }
167
168 /**
169 * Handle an event that was generated in Bareos
170 */
handlePluginEvent(bpContext * ctx,bsdEvent * event,void * value)171 static bRC handlePluginEvent(bpContext* ctx, bsdEvent* event, void* value)
172 {
173 switch (event->eventType) {
174 case bsdEventLabelVerified:
175 case bsdEventReadError:
176 case bsdEventWriteError:
177 case bsdEventVolumeUnload:
178 return handle_tapealert_readout(value);
179 default:
180 Dmsg1(debuglevel, "scsitapealert-sd: Unknown event %d\n",
181 event->eventType);
182 return bRC_Error;
183 }
184
185 return bRC_OK;
186 }
187
188 static pthread_mutex_t tapealert_operation_mutex = PTHREAD_MUTEX_INITIALIZER;
189
handle_tapealert_readout(void * value)190 static bRC handle_tapealert_readout(void* value)
191 {
192 DeviceControlRecord* dcr;
193 Device* dev;
194 DeviceResource* device;
195 uint64_t flags;
196
197 /*
198 * Unpack the arguments passed in.
199 */
200 dcr = (DeviceControlRecord*)value;
201 if (!dcr) { return bRC_Error; }
202 dev = dcr->dev;
203 if (!dev) { return bRC_Error; }
204 device = dev->device;
205 if (!device) { return bRC_Error; }
206
207 /*
208 * See if drive tapealert is enabled.
209 */
210 if (!device->drive_tapealert_enabled) {
211 Dmsg1(debuglevel,
212 "scsitapealert-sd: tapealert is not enabled on device %s\n",
213 dev->dev_name);
214 return bRC_OK;
215 }
216
217 Dmsg1(debuglevel, "scsitapealert-sd: checking for tapealerts on device %s\n",
218 dev->dev_name);
219 P(tapealert_operation_mutex);
220 GetTapealertFlags(dev->fd(), dev->dev_name, &flags);
221 V(tapealert_operation_mutex);
222
223 Dmsg1(debuglevel,
224 "scsitapealert-sd: checking for tapealerts on device %s DONE\n",
225 dev->dev_name);
226 Dmsg1(debuglevel, "scsitapealert-sd: flags: %ld \n", flags);
227
228 if (flags) {
229 Dmsg1(
230 debuglevel,
231 "scsitapealert-sd: tapealerts on device %s, calling UpdateTapeAlerts\n",
232 dev->dev_name);
233 bfuncs->UpdateTapeAlert(dcr, flags);
234 }
235
236 return bRC_OK;
237 }
238