1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
5 Copyright (C) 2011-2012 Planets Communications B.V.
6 Copyright (C) 2013-2021 Bareos GmbH & Co. KG
7
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
11 in the file LICENSE.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23 /*
24 * Kern Sibbald, MM
25 */
26 /**
27 * @file
28 * low level operations on device (storage device)
29 *
30 * NOTE!!!! None of these routines are reentrant. You must
31 * use dev->rLock() and dev->Unlock() at a higher level,
32 * or use the xxx_device() equivalents. By moving the
33 * thread synchronization to a higher level, we permit
34 * the higher level routines to "seize" the device and
35 * to carry out operations without worrying about who
36 * set what lock (i.e. race conditions).
37 *
38 * Note, this is the device dependent code, and may have
39 * to be modified for each system, but is meant to
40 * be as "generic" as possible.
41 *
42 * The purpose of this code is to develop a SIMPLE Storage
43 * daemon. More complicated coding (double buffering, writer
44 * thread, ...) is left for a later version.
45 */
46
47 /*
48 * Handling I/O errors and end of tape conditions are a bit tricky.
49 * This is how it is currently done when writing.
50 * On either an I/O error or end of tape,
51 * we will stop writing on the physical device (no I/O recovery is
52 * attempted at least in this daemon). The state flag will be sent
53 * to include ST_EOT, which is ephemeral, and ST_WEOT, which is
54 * persistent. Lots of routines clear ST_EOT, but ST_WEOT is
55 * cleared only when the problem goes away. Now when ST_WEOT
56 * is set all calls to WriteBlockToDevice() call the fix_up
57 * routine. In addition, all threads are blocked
58 * from writing on the tape by calling lock_dev(), and thread other
59 * than the first thread to hit the EOT will block on a condition
60 * variable. The first thread to hit the EOT will continue to
61 * be able to read and write the tape (he sort of tunnels through
62 * the locking mechanism -- see lock_dev() for details).
63 *
64 * Now presumably somewhere higher in the chain of command
65 * (device.c), someone will notice the EOT condition and
66 * get a new tape up, get the tape label read, and mark
67 * the label for rewriting. Then this higher level routine
68 * will write the unwritten buffer to the new volume.
69 * Finally, he will release
70 * any blocked threads by doing a broadcast on the condition
71 * variable. At that point, we should be totally back in
72 * business with no lost data.
73 */
74
75 #include "include/bareos.h"
76 #include "stored/block.h"
77 #include "stored/stored.h"
78 #include "stored/autochanger.h"
79 #include "stored/bsr.h"
80 #include "stored/device_control_record.h"
81 #include "stored/jcr_private.h"
82 #include "stored/sd_backends.h"
83 #include "lib/btimers.h"
84 #include "include/jcr.h"
85 #include "lib/berrno.h"
86
87 #ifndef HAVE_DYNAMIC_SD_BACKENDS
88 # ifdef HAVE_GFAPI
89 # include "backends/gfapi_device.h"
90 # endif
91 # ifdef HAVE_BAREOSSD_DROPLET_DEVICE
92 # include "backends/chunked_device.h"
93 # include "backends/droplet_device.h"
94 # endif
95 # ifdef HAVE_RADOS
96 # include "backends/rados_device.h"
97 # endif
98 # ifdef HAVE_CEPHFS
99 # include "backends/cephfs_device.h"
100 # endif
101 # include "backends/generic_tape_device.h"
102 # ifdef HAVE_WIN32
103 # include "backends/win32_tape_device.h"
104 # include "backends/win32_fifo_device.h"
105 # else
106 # include "backends/unix_tape_device.h"
107 # include "backends/unix_fifo_device.h"
108 # endif
109 #endif /* HAVE_DYNAMIC_SD_BACKENDS */
110
111 #ifdef HAVE_WIN32
112 # include "backends/win32_file_device.h"
113 #else
114 # include "backends/unix_file_device.h"
115 #endif
116
117 #ifndef O_NONBLOCK
118 # define O_NONBLOCK 0
119 #endif
120
121 namespace storagedaemon {
122
mode_to_str(DeviceMode mode)123 const char* Device::mode_to_str(DeviceMode mode)
124 {
125 static const char* modes[] = {"CREATE_READ_WRITE", "OPEN_READ_WRITE",
126 "OPEN_READ_ONLY", "OPEN_WRITE_ONLY"};
127
128
129 int idx = static_cast<int>(mode);
130
131 if (idx < 1 || idx > 4) {
132 static char buf[100];
133 Bsnprintf(buf, sizeof(buf), "BAD mode=%d", idx);
134 return buf;
135 }
136
137 return modes[idx - 1];
138 }
139
140
141 /**
142 * Fabric to allocate and initialize the Device structure
143 *
144 * Note, for a tape, the device->archive_device_string is the device name
145 * (e.g. /dev/nst0), and for a file, the device name
146 * is the directory in which the file will be placed.
147 */
148
FactoryCreateDevice(JobControlRecord * jcr,DeviceResource * device_resource)149 Device* FactoryCreateDevice(JobControlRecord* jcr,
150 DeviceResource* device_resource)
151 {
152 Dmsg1(400, "max_block_size in device_resource res is %u\n",
153 device_resource->max_block_size);
154
155 /*
156 * If no device type specified, try to guess
157 */
158 if (device_resource->dev_type == DeviceType::B_UNKNOWN_DEV) {
159 struct stat statp;
160 /*
161 * Check that device is available
162 */
163 if (stat(device_resource->archive_device_string, &statp) < 0) {
164 BErrNo be;
165 Jmsg2(jcr, M_ERROR, 0, _("Unable to stat device %s: ERR=%s\n"),
166 device_resource->archive_device_string, be.bstrerror());
167 return nullptr;
168 }
169 if (S_ISDIR(statp.st_mode)) {
170 device_resource->dev_type = DeviceType::B_FILE_DEV;
171 } else if (S_ISCHR(statp.st_mode)) {
172 device_resource->dev_type = DeviceType::B_TAPE_DEV;
173 } else if (S_ISFIFO(statp.st_mode)) {
174 device_resource->dev_type = DeviceType::B_FIFO_DEV;
175 } else if (!BitIsSet(CAP_REQMOUNT, device_resource->cap_bits)) {
176 Jmsg2(jcr, M_ERROR, 0,
177 _("%s is an unknown device type. Must be tape or directory, "
178 "st_mode=%04o\n"),
179 device_resource->archive_device_string, (statp.st_mode & ~S_IFMT));
180 return nullptr;
181 }
182 }
183
184 Device* dev = nullptr;
185
186 switch (device_resource->dev_type) {
187 /*
188 * When using dynamic loading use the InitBackendDevice() function
189 * for any type of device not being of the type file.
190 */
191 #ifndef HAVE_DYNAMIC_SD_BACKENDS
192 # ifdef HAVE_GFAPI
193 case DeviceType::B_GFAPI_DEV:
194 dev = new gfapi_device;
195 break;
196 # endif
197 # ifdef HAVE_BAREOSSD_DROPLET_DEVICE
198 case DeviceType::B_DROPLET_DEV:
199 dev = new DropletDevice;
200 break;
201 # endif
202 # ifdef HAVE_RADOS
203 case DeviceType::B_RADOS_DEV:
204 dev = new rados_device;
205 break;
206 # endif
207 # ifdef HAVE_CEPHFS
208 case DeviceType::B_CEPHFS_DEV:
209 dev = new cephfs_device;
210 break;
211 # endif
212 # ifdef HAVE_WIN32
213 case DeviceType::B_TAPE_DEV:
214 dev = new win32_tape_device;
215 break;
216 case DeviceType::B_FIFO_DEV:
217 dev = new win32_fifo_device;
218 break;
219 # else
220 case DeviceType::B_TAPE_DEV:
221 dev = new unix_tape_device;
222 break;
223 case DeviceType::B_FIFO_DEV:
224 dev = new unix_fifo_device;
225 break;
226 # endif
227 #endif /* HAVE_DYNAMIC_SD_BACKENDS */
228 #ifdef HAVE_WIN32
229 case DeviceType::B_FILE_DEV:
230 dev = new win32_file_device;
231 break;
232 #else
233 case DeviceType::B_FILE_DEV:
234 dev = new unix_file_device;
235 break;
236 #endif
237 default:
238 #ifdef HAVE_DYNAMIC_SD_BACKENDS
239 dev = InitBackendDevice(jcr, device_resource->dev_type);
240 if (!dev) {
241 try {
242 Jmsg2(jcr, M_ERROR, 0,
243 _("Initialization of dynamic %s device \"%s\" with archive "
244 "device \"%s\" failed. Backend "
245 "library might be missing or backend directory incorrect.\n"),
246 device_type_to_name_mapping.at(device_resource->dev_type),
247 device_resource->resource_name_,
248 device_resource->archive_device_string);
249 } catch (const std::out_of_range&) {
250 // device_resource->dev_type could exceed limits of map
251 }
252 return nullptr;
253 }
254 #endif
255 break;
256 }
257
258 if (!dev) {
259 Jmsg2(jcr, M_ERROR, 0, _("%s has an unknown device type %d\n"),
260 device_resource->archive_device_string, device_resource->dev_type);
261 return nullptr;
262 }
263 dev->InvalidateSlotNumber(); /* unknown */
264
265 /*
266 * Copy user supplied device parameters from Resource
267 */
268 dev->archive_device_string
269 = GetMemory(strlen(device_resource->archive_device_string) + 1);
270 PmStrcpy(dev->archive_device_string, device_resource->archive_device_string);
271 if (device_resource->device_options) {
272 dev->dev_options = GetMemory(strlen(device_resource->device_options) + 1);
273 PmStrcpy(dev->dev_options, device_resource->device_options);
274 }
275 dev->prt_name = GetMemory(strlen(device_resource->archive_device_string)
276 + strlen(device_resource->resource_name_) + 20);
277
278
279 Mmsg(dev->prt_name, "\"%s\" (%s)", device_resource->resource_name_,
280 device_resource->archive_device_string);
281 Dmsg1(400, "Allocate dev=%s\n", dev->print_name());
282 CopySetBits(CAP_MAX, device_resource->cap_bits, dev->capabilities);
283
284
285 dev->min_block_size = device_resource->min_block_size;
286 dev->max_block_size = device_resource->max_block_size;
287 dev->max_volume_size = device_resource->max_volume_size;
288 dev->max_file_size = device_resource->max_file_size;
289 dev->max_concurrent_jobs = device_resource->max_concurrent_jobs;
290 dev->volume_capacity = device_resource->volume_capacity;
291 dev->max_rewind_wait = device_resource->max_rewind_wait;
292 dev->max_open_wait = device_resource->max_open_wait;
293 dev->max_open_vols = device_resource->max_open_vols;
294 dev->vol_poll_interval = device_resource->vol_poll_interval;
295 dev->max_spool_size = device_resource->max_spool_size;
296 dev->drive = device_resource->drive;
297 dev->drive_index = device_resource->drive_index;
298 dev->autoselect = device_resource->autoselect;
299 dev->norewindonclose = device_resource->norewindonclose;
300 dev->dev_type = device_resource->dev_type;
301 dev->device_resource = device_resource;
302
303 device_resource->dev = dev;
304
305 if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
306 dev->vol_poll_interval = 60;
307 }
308
309 if (dev->IsFifo()) { dev->SetCap(CAP_STREAM); }
310
311 /*
312 * If the device requires mount :
313 * - Check that the mount point is available
314 * - Check that (un)mount commands are defined
315 */
316 if (dev->IsFile() && dev->RequiresMount()) {
317 struct stat statp;
318 if (!device_resource->mount_point
319 || stat(device_resource->mount_point, &statp) < 0) {
320 BErrNo be;
321 dev->dev_errno = errno;
322 Jmsg2(jcr, M_ERROR_TERM, 0, _("Unable to stat mount point %s: ERR=%s\n"),
323 device_resource->mount_point, be.bstrerror());
324 }
325
326 if (!device_resource->mount_command || !device_resource->unmount_command) {
327 Jmsg0(jcr, M_ERROR_TERM, 0,
328 _("Mount and unmount commands must defined for a device which "
329 "requires mount.\n"));
330 }
331 }
332
333 if (dev->min_block_size
334 > (dev->max_block_size == 0 ? DEFAULT_BLOCK_SIZE : dev->max_block_size)) {
335 Jmsg(jcr, M_ERROR_TERM, 0, _("Min block size > max on device %s\n"),
336 dev->print_name());
337 }
338 if (dev->max_block_size > MAX_BLOCK_LENGTH) {
339 Jmsg3(jcr, M_ERROR, 0,
340 _("Block size %u on device %s is too large, using default %u\n"),
341 dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE);
342 dev->max_block_size = 0;
343 }
344 if (dev->max_block_size % TAPE_BSIZE != 0) {
345 Jmsg3(jcr, M_WARNING, 0,
346 _("Max block size %u not multiple of device %s block size=%d.\n"),
347 dev->max_block_size, dev->print_name(), TAPE_BSIZE);
348 }
349 if (dev->max_volume_size != 0
350 && dev->max_volume_size < (dev->max_block_size << 4)) {
351 Jmsg(jcr, M_ERROR_TERM, 0,
352 _("Max Vol Size < 8 * Max Block Size for device %s\n"),
353 dev->print_name());
354 }
355
356 dev->errmsg = GetPoolMemory(PM_EMSG);
357 *dev->errmsg = 0;
358
359 int errstat;
360
361 if ((errstat = dev->InitMutex()) != 0) {
362 BErrNo be;
363 dev->dev_errno = errstat;
364 Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"),
365 be.bstrerror(errstat));
366 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
367 }
368
369 if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) {
370 BErrNo be;
371 dev->dev_errno = errstat;
372 Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"),
373 be.bstrerror(errstat));
374 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
375 }
376
377 if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
378 BErrNo be;
379 dev->dev_errno = errstat;
380 Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"),
381 be.bstrerror(errstat));
382 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
383 }
384
385 if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
386 BErrNo be;
387 dev->dev_errno = errstat;
388 Mmsg1(dev->errmsg, _("Unable to init spool mutex: ERR=%s\n"),
389 be.bstrerror(errstat));
390 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
391 }
392
393 if ((errstat = dev->InitAcquireMutex()) != 0) {
394 BErrNo be;
395 dev->dev_errno = errstat;
396 Mmsg1(dev->errmsg, _("Unable to init acquire mutex: ERR=%s\n"),
397 be.bstrerror(errstat));
398 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
399 }
400
401 if ((errstat = dev->InitReadAcquireMutex()) != 0) {
402 BErrNo be;
403 dev->dev_errno = errstat;
404 Mmsg1(dev->errmsg, _("Unable to init read acquire mutex: ERR=%s\n"),
405 be.bstrerror(errstat));
406 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
407 }
408
409 dev->ClearOpened();
410 dev->attached_dcrs.clear();
411 Dmsg2(100, "FactoryCreateDevice: tape=%d archive_device_string=%s\n",
412 dev->IsTape(), dev->archive_device_string);
413 dev->initiated = true;
414 Dmsg3(100, "dev=%s dev_max_bs=%u max_bs=%u\n", dev->archive_device_string,
415 dev->device_resource->max_block_size, dev->max_block_size);
416
417 return dev;
418 }
419
420 /**
421 * This routine initializes the device wait timers
422 */
InitDeviceWaitTimers(DeviceControlRecord * dcr)423 void InitDeviceWaitTimers(DeviceControlRecord* dcr)
424 {
425 Device* dev = dcr->dev;
426 JobControlRecord* jcr = dcr->jcr;
427
428 /* ******FIXME******* put these on config variables */
429 dev->min_wait = 60 * 60;
430 dev->max_wait = 24 * 60 * 60;
431 dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
432 dev->wait_sec = dev->min_wait;
433 dev->rem_wait_sec = dev->wait_sec;
434 dev->num_wait = 0;
435 dev->poll = false;
436
437 jcr->impl->device_wait_times.min_wait = 60 * 60;
438 jcr->impl->device_wait_times.max_wait = 24 * 60 * 60;
439 jcr->impl->device_wait_times.max_num_wait
440 = 9; /* 5 waits =~ 1 day, then 1 day at a time */
441 jcr->impl->device_wait_times.wait_sec = jcr->impl->device_wait_times.min_wait;
442 jcr->impl->device_wait_times.rem_wait_sec
443 = jcr->impl->device_wait_times.wait_sec;
444 jcr->impl->device_wait_times.num_wait = 0;
445 }
446
InitJcrDeviceWaitTimers(JobControlRecord * jcr)447 void InitJcrDeviceWaitTimers(JobControlRecord* jcr)
448 {
449 /* ******FIXME******* put these on config variables */
450 jcr->impl->device_wait_times.min_wait = 60 * 60;
451 jcr->impl->device_wait_times.max_wait = 24 * 60 * 60;
452 jcr->impl->device_wait_times.max_num_wait
453 = 9; /* 5 waits =~ 1 day, then 1 day at a time */
454 jcr->impl->device_wait_times.wait_sec = jcr->impl->device_wait_times.min_wait;
455 jcr->impl->device_wait_times.rem_wait_sec
456 = jcr->impl->device_wait_times.wait_sec;
457 jcr->impl->device_wait_times.num_wait = 0;
458 }
459
460 /**
461 * The dev timers are used for waiting on a particular device
462 *
463 * Returns: true if time doubled
464 * false if max time expired
465 */
DoubleDevWaitTime(Device * dev)466 bool DoubleDevWaitTime(Device* dev)
467 {
468 dev->wait_sec *= 2; /* Double wait time */
469 if (dev->wait_sec > dev->max_wait) { /* But not longer than maxtime */
470 dev->wait_sec = dev->max_wait;
471 }
472 dev->num_wait++;
473 dev->rem_wait_sec = dev->wait_sec;
474 if (dev->num_wait >= dev->max_num_wait) { return false; }
475 return true;
476 }
477
478 /**
479 * Set the block size of the device.
480 * If the volume block size is zero, we set the max block size to what is
481 * configured in the device resource i.e. dev->device->max_block_size.
482 *
483 * If dev->device->max_block_size is zero, do nothing and leave
484 * dev->max_block_size as it is.
485 */
SetBlocksizes(DeviceControlRecord * dcr)486 void Device::SetBlocksizes(DeviceControlRecord* dcr)
487 {
488 Device* dev = this;
489 JobControlRecord* jcr = dcr->jcr;
490 uint32_t max_bs;
491
492 Dmsg4(100,
493 "Device %s has dev->device->max_block_size of %u and "
494 "dev->max_block_size of %u, dcr->VolMaxBlocksize is %u\n",
495 dev->print_name(), dev->device_resource->max_block_size,
496 dev->max_block_size, dcr->VolMaxBlocksize);
497
498 if (dcr->VolMaxBlocksize == 0 && dev->device_resource->max_block_size != 0) {
499 Dmsg2(100,
500 "setting dev->max_block_size to "
501 "dev->device_resource->max_block_size=%u "
502 "on device %s because dcr->VolMaxBlocksize is 0\n",
503 dev->device_resource->max_block_size, dev->print_name());
504 dev->min_block_size = dev->device_resource->min_block_size;
505 dev->max_block_size = dev->device_resource->max_block_size;
506 } else if (dcr->VolMaxBlocksize != 0) {
507 dev->min_block_size = dcr->VolMinBlocksize;
508 dev->max_block_size = dcr->VolMaxBlocksize;
509 }
510
511 /*
512 * Sanity check
513 */
514 if (dev->max_block_size == 0) {
515 max_bs = DEFAULT_BLOCK_SIZE;
516 } else {
517 max_bs = dev->max_block_size;
518 }
519
520 if (dev->min_block_size > max_bs) {
521 Jmsg(jcr, M_ERROR_TERM, 0, _("Min block size > max on device %s\n"),
522 dev->print_name());
523 }
524
525 if (dev->max_block_size > MAX_BLOCK_LENGTH) {
526 Jmsg3(jcr, M_ERROR, 0,
527 _("Block size %u on device %s is too large, using default %u\n"),
528 dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE);
529 dev->max_block_size = 0;
530 }
531
532 if (dev->max_block_size % TAPE_BSIZE != 0) {
533 Jmsg3(jcr, M_WARNING, 0,
534 _("Max block size %u not multiple of device %s block size=%d.\n"),
535 dev->max_block_size, dev->print_name(), TAPE_BSIZE);
536 }
537
538 if (dev->max_volume_size != 0
539 && dev->max_volume_size < (dev->max_block_size << 4)) {
540 Jmsg(jcr, M_ERROR_TERM, 0,
541 _("Max Vol Size < 8 * Max Block Size for device %s\n"),
542 dev->print_name());
543 }
544
545 Dmsg3(100, "set minblocksize to %d, maxblocksize to %d on device %s\n",
546 dev->min_block_size, dev->max_block_size, dev->print_name());
547
548 /*
549 * If blocklen is not dev->max_block_size create a new block with the right
550 * size. (as header is always dev->label_block_size which is preset with
551 * DEFAULT_BLOCK_SIZE)
552 */
553 if (dcr->block) {
554 if (dcr->block->buf_len != dev->max_block_size) {
555 Dmsg2(100, "created new block of buf_len: %u on device %s\n",
556 dev->max_block_size, dev->print_name());
557 FreeBlock(dcr->block);
558 dcr->block = new_block(dev);
559 Dmsg2(100,
560 "created new block of buf_len: %u on device %s, freeing block\n",
561 dcr->block->buf_len, dev->print_name());
562 }
563 }
564 }
565
566 /**
567 * Set the block size of the device to the label_block_size
568 * to read labels as we want to always use that blocksize when
569 * writing volume labels
570 */
SetLabelBlocksize(DeviceControlRecord * dcr)571 void Device::SetLabelBlocksize(DeviceControlRecord* dcr)
572 {
573 Device* dev = this;
574 Dmsg3(100,
575 "setting minblocksize to %u, "
576 "maxblocksize to label_block_size=%u, on device %s\n",
577 dev->device_resource->label_block_size,
578 dev->device_resource->label_block_size, dev->print_name());
579
580 dev->min_block_size = dev->device_resource->label_block_size;
581 dev->max_block_size = dev->device_resource->label_block_size;
582 /*
583 * If blocklen is not dev->max_block_size create a new block with the right
584 * size (as header is always label_block_size)
585 */
586 if (dcr->block) {
587 if (dcr->block->buf_len != dev->max_block_size) {
588 FreeBlock(dcr->block);
589 dcr->block = new_block(dev);
590 Dmsg2(100, "created new block of buf_len: %u on device %s\n",
591 dcr->block->buf_len, dev->print_name());
592 }
593 }
594 }
595
596 /**
597 * Open the device with the operating system and
598 * initialize buffer pointers.
599 *
600 * Returns: true on success
601 * false on error
602 *
603 * Note, for a tape, the VolName is the name we give to the
604 * volume (not really used here), but for a file, the
605 * VolName represents the name of the file to be created/opened.
606 * In the case of a file, the full name is the device name
607 * (archive_name) with the VolName concatenated.
608 */
open(DeviceControlRecord * dcr,DeviceMode omode)609 bool Device::open(DeviceControlRecord* dcr, DeviceMode omode)
610 {
611 char preserve[ST_BYTES];
612
613 ClearAllBits(ST_MAX, preserve);
614 if (IsOpen()) {
615 if (open_mode == omode) {
616 return true;
617 } else {
618 d_close(fd);
619 ClearOpened();
620 Dmsg0(100, "Close fd for mode change.\n");
621
622 if (BitIsSet(ST_LABEL, state)) SetBit(ST_LABEL, preserve);
623 if (BitIsSet(ST_APPENDREADY, state)) SetBit(ST_APPENDREADY, preserve);
624 if (BitIsSet(ST_READREADY, state)) SetBit(ST_READREADY, preserve);
625 }
626 }
627
628 if (dcr) {
629 dcr->setVolCatName(dcr->VolumeName);
630 VolCatInfo = dcr->VolCatInfo; /* structure assign */
631 }
632
633 Dmsg4(100, "open dev: type=%d archive_device_string=%s vol=%s mode=%s\n",
634 dev_type, print_name(), getVolCatName(), mode_to_str(omode));
635
636 ClearBit(ST_LABEL, state);
637 ClearBit(ST_APPENDREADY, state);
638 ClearBit(ST_READREADY, state);
639 ClearBit(ST_EOT, state);
640 ClearBit(ST_WEOT, state);
641 ClearBit(ST_EOF, state);
642
643 label_type = B_BAREOS_LABEL;
644
645 /*
646 * We are about to open the device so let any plugin know we are.
647 */
648 if (dcr && GeneratePluginEvent(dcr->jcr, bSdEventDeviceOpen, dcr) != bRC_OK) {
649 Dmsg0(100, "open_dev: bSdEventDeviceOpen failed\n");
650 return false;
651 }
652
653 Dmsg1(100, "call OpenDevice mode=%s\n", mode_to_str(omode));
654 OpenDevice(dcr, omode);
655
656 /*
657 * Reset any important state info
658 */
659 CopySetBits(ST_MAX, preserve, state);
660
661 Dmsg2(100, "preserve=%08o fd=%d\n", preserve, fd);
662
663 return fd >= 0;
664 }
665
set_mode(DeviceMode mode)666 void Device::set_mode(DeviceMode mode)
667 {
668 switch (mode) {
669 case DeviceMode::CREATE_READ_WRITE:
670 oflags = O_CREAT | O_RDWR | O_BINARY;
671 break;
672 case DeviceMode::OPEN_READ_WRITE:
673 oflags = O_RDWR | O_BINARY;
674 break;
675 case DeviceMode::OPEN_READ_ONLY:
676 oflags = O_RDONLY | O_BINARY;
677 break;
678 case DeviceMode::OPEN_WRITE_ONLY:
679 oflags = O_WRONLY | O_BINARY;
680 break;
681 default:
682 Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n"));
683 }
684 }
685
686 /**
687 * Open a device.
688 */
OpenDevice(DeviceControlRecord * dcr,DeviceMode omode)689 void Device::OpenDevice(DeviceControlRecord* dcr, DeviceMode omode)
690 {
691 PoolMem archive_name(PM_FNAME);
692
693 GetAutochangerLoadedSlot(dcr);
694
695 /*
696 * Handle opening of File Archive (not a tape)
697 */
698 PmStrcpy(archive_name, archive_device_string);
699
700 /*
701 * If this is a virtual autochanger (i.e. changer_res != NULL) we simply use
702 * the device name, assuming it has been appropriately setup by the
703 * "autochanger".
704 */
705 if (!device_resource->changer_res
706 || device_resource->changer_command[0] == 0) {
707 if (VolCatInfo.VolCatName[0] == 0) {
708 Mmsg(errmsg, _("Could not open file device %s. No Volume name given.\n"),
709 print_name());
710 ClearOpened();
711 return;
712 }
713
714 if (!IsPathSeparator(
715 archive_name.c_str()[strlen(archive_name.c_str()) - 1])) {
716 PmStrcat(archive_name, "/");
717 }
718 PmStrcat(archive_name, getVolCatName());
719 }
720
721 mount(dcr, 1); /* do mount if required */
722
723 open_mode = omode;
724 set_mode(omode);
725
726 Dmsg3(100, "open archive: mode=%s open(%s, %08o, 0640)\n", mode_to_str(omode),
727 archive_name.c_str(), oflags);
728
729 if ((fd = d_open(archive_name.c_str(), oflags, 0640)) < 0) {
730 BErrNo be;
731 dev_errno = errno;
732 if (dev_errno == 0) {
733 Mmsg2(errmsg, _("Could not open: %s\n"), archive_name.c_str());
734 } else {
735 Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(),
736 be.bstrerror());
737 }
738 Dmsg1(100, "open failed: %s", errmsg);
739 }
740
741 if (fd >= 0) {
742 dev_errno = 0;
743 file = 0;
744 file_addr = 0;
745 }
746
747 Dmsg1(100, "open dev: disk fd=%d opened\n", fd);
748 }
749
750 /**
751 * Rewind the device.
752 *
753 * Returns: true on success
754 * false on failure
755 */
rewind(DeviceControlRecord * dcr)756 bool Device::rewind(DeviceControlRecord* dcr)
757 {
758 Dmsg3(400, "rewind res=%d fd=%d %s\n", NumReserved(), fd, print_name());
759
760 /*
761 * Remove EOF/EOT flags
762 */
763 ClearBit(ST_EOT, state);
764 ClearBit(ST_EOF, state);
765 ClearBit(ST_WEOT, state);
766
767 block_num = file = 0;
768 file_size = 0;
769 file_addr = 0;
770
771 if (fd < 0) { return false; }
772
773 if (IsFifo() || IsVtl()) { return true; }
774
775 if (d_lseek(dcr, (boffset_t)0, SEEK_SET) < 0) {
776 BErrNo be;
777 dev_errno = errno;
778 Mmsg2(errmsg, _("lseek error on %s. ERR=%s"), print_name(), be.bstrerror());
779 return false;
780 }
781
782 return true;
783 }
784
785 /**
786 * Called to indicate that we have just read an EOF from the device.
787 */
SetAteof()788 void Device::SetAteof()
789 {
790 SetEof();
791 file_addr = 0;
792 file_size = 0;
793 block_num = 0;
794 }
795
796 /**
797 * Called to indicate we are now at the end of the volume, and writing is not
798 * possible.
799 */
SetAteot()800 void Device::SetAteot()
801 {
802 /*
803 * Make volume effectively read-only
804 */
805 SetBit(ST_EOF, state);
806 SetBit(ST_EOT, state);
807 SetBit(ST_WEOT, state);
808 ClearAppend();
809 }
810
811 /**
812 * Position device to end of medium (end of data)
813 *
814 * Returns: true on succes
815 * false on error
816 */
eod(DeviceControlRecord * dcr)817 bool Device::eod(DeviceControlRecord* dcr)
818 {
819 boffset_t pos;
820
821 if (fd < 0) {
822 dev_errno = EBADF;
823 Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), print_name());
824 return false;
825 }
826
827 if (IsVtl()) { return true; }
828
829 Dmsg0(100, "Enter eod\n");
830 if (AtEot()) { return true; }
831
832 ClearEof(); /* remove EOF flag */
833
834 block_num = file = 0;
835 file_size = 0;
836 file_addr = 0;
837
838 pos = d_lseek(dcr, (boffset_t)0, SEEK_END);
839 Dmsg1(200, "====== Seek to %lld\n", pos);
840
841 if (pos >= 0) {
842 UpdatePos(dcr);
843 SetEot();
844 return true;
845 }
846
847 dev_errno = errno;
848 BErrNo be;
849 Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(),
850 be.bstrerror());
851 Dmsg0(100, errmsg);
852
853 return false;
854 }
855
856 /**
857 * Set the position of the device.
858 *
859 * Returns: true on succes
860 * false on error
861 */
UpdatePos(DeviceControlRecord * dcr)862 bool Device::UpdatePos(DeviceControlRecord* dcr)
863 {
864 boffset_t pos;
865 bool ok = true;
866
867 if (!IsOpen()) {
868 dev_errno = EBADF;
869 Mmsg0(errmsg, _("Bad device call. Device not open\n"));
870 Emsg1(M_FATAL, 0, "%s", errmsg);
871 return false;
872 }
873
874 if (IsFifo() || IsVtl()) { return true; }
875
876 file = 0;
877 file_addr = 0;
878 pos = d_lseek(dcr, (boffset_t)0, SEEK_CUR);
879 if (pos < 0) {
880 BErrNo be;
881 dev_errno = errno;
882 Pmsg1(000, _("Seek error: ERR=%s\n"), be.bstrerror());
883 Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(),
884 be.bstrerror());
885 ok = false;
886 } else {
887 file_addr = pos;
888 block_num = (uint32_t)pos;
889 file = (uint32_t)(pos >> 32);
890 }
891
892 return ok;
893 }
894
StatusDev()895 char* Device::StatusDev()
896 {
897 char* status;
898
899 status = (char*)malloc(BMT_BYTES);
900 ClearAllBits(BMT_MAX, status);
901
902 if (BitIsSet(ST_EOT, state) || BitIsSet(ST_WEOT, state)) {
903 SetBit(BMT_EOD, status);
904 Pmsg0(-20, " EOD");
905 }
906
907 if (BitIsSet(ST_EOF, state)) {
908 SetBit(BMT_EOF, status);
909 Pmsg0(-20, " EOF");
910 }
911
912 SetBit(BMT_ONLINE, status);
913 SetBit(BMT_BOT, status);
914
915 return status;
916 }
917
OfflineOrRewind()918 bool Device::OfflineOrRewind()
919 {
920 if (fd < 0) { return false; }
921 if (HasCap(CAP_OFFLINEUNMOUNT)) {
922 return offline();
923 } else {
924 /*
925 * Note, this rewind probably should not be here (it wasn't
926 * in prior versions of Bareos), but on FreeBSD, this is
927 * needed in the case the tape was "frozen" due to an error
928 * such as backspacing after writing and EOF. If it is not
929 * done, all future references to the drive get and I/O error.
930 */
931 clrerror(MTREW);
932 return rewind(NULL);
933 }
934 }
935
SetSlotNumber(slot_number_t slot)936 void Device::SetSlotNumber(slot_number_t slot)
937 {
938 slot_ = slot;
939 if (vol) { vol->InvalidateSlotNumber(); }
940 }
941
InvalidateSlotNumber()942 void Device::InvalidateSlotNumber()
943 {
944 slot_ = kInvalidSlotNumber;
945 if (vol) { vol->SetSlotNumber(kInvalidSlotNumber); }
946 }
947
948 /**
949 * Reposition the device to file, block
950 *
951 * Returns: false on failure
952 * true on success
953 */
Reposition(DeviceControlRecord * dcr,uint32_t rfile,uint32_t rblock)954 bool Device::Reposition(DeviceControlRecord* dcr,
955 uint32_t rfile,
956 uint32_t rblock)
957 {
958 if (!IsOpen()) {
959 dev_errno = EBADF;
960 Mmsg0(errmsg, _("Bad call to Reposition. Device not open\n"));
961 Emsg0(M_FATAL, 0, errmsg);
962 return false;
963 }
964
965 if (IsFifo() || IsVtl()) { return true; }
966
967 boffset_t pos = (((boffset_t)rfile) << 32) | rblock;
968 Dmsg1(100, "===== lseek to %d\n", (int)pos);
969 if (d_lseek(dcr, pos, SEEK_SET) == (boffset_t)-1) {
970 BErrNo be;
971 dev_errno = errno;
972 Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(),
973 be.bstrerror());
974 return false;
975 }
976 file = rfile;
977 block_num = rblock;
978 file_addr = pos;
979 return true;
980 }
981
982 /**
983 * Set to unload the current volume in the drive.
984 */
SetUnload()985 void Device::SetUnload()
986 {
987 if (!unload_ && VolHdr.VolumeName[0] != 0) {
988 unload_ = true;
989 memcpy(UnloadVolName, VolHdr.VolumeName, sizeof(UnloadVolName));
990 }
991 }
992
993 /**
994 * Clear volume header.
995 */
ClearVolhdr()996 void Device::ClearVolhdr()
997 {
998 Dmsg1(100, "Clear volhdr vol=%s\n", VolHdr.VolumeName);
999 VolHdr = Volume_Label{};
1000 setVolCatInfo(false);
1001 }
1002
1003 /**
1004 * Close the device.
1005 */
close(DeviceControlRecord * dcr)1006 bool Device::close(DeviceControlRecord* dcr)
1007 {
1008 // Called with dcr=nullptr on termination (from destructor) .
1009
1010 bool retval = true;
1011 int status;
1012 Dmsg1(100, "close_dev %s\n", print_name());
1013
1014 if (!IsOpen()) {
1015 Dmsg2(100, "device %s already closed vol=%s\n", print_name(),
1016 VolHdr.VolumeName);
1017 goto bail_out; /* already closed */
1018 }
1019
1020 if (!norewindonclose) { OfflineOrRewind(); }
1021
1022 switch (dev_type) {
1023 case DeviceType::B_VTL_DEV:
1024 case DeviceType::B_TAPE_DEV:
1025 UnlockDoor();
1026 /*
1027 * Fall through wanted
1028 */
1029 default:
1030 status = d_close(fd);
1031 if (status < 0) {
1032 BErrNo be;
1033
1034 Mmsg2(errmsg, _("Unable to close device %s. ERR=%s\n"), print_name(),
1035 be.bstrerror());
1036 dev_errno = errno;
1037 retval = false;
1038 }
1039 break;
1040 }
1041
1042 unmount(dcr, 1); /* do unmount if required */
1043
1044 /*
1045 * Clean up device packet so it can be reused.
1046 */
1047 ClearOpened();
1048
1049 ClearBit(ST_LABEL, state);
1050 ClearBit(ST_READREADY, state);
1051 ClearBit(ST_APPENDREADY, state);
1052 ClearBit(ST_EOT, state);
1053 ClearBit(ST_WEOT, state);
1054 ClearBit(ST_EOF, state);
1055 ClearBit(ST_MOUNTED, state);
1056 ClearBit(ST_MEDIA, state);
1057 ClearBit(ST_SHORT, state);
1058
1059 label_type = B_BAREOS_LABEL;
1060 file = block_num = 0;
1061 file_size = 0;
1062 file_addr = 0;
1063 EndFile = EndBlock = 0;
1064 open_mode = DeviceMode::kUndefined;
1065 ClearVolhdr();
1066 VolCatInfo = VolumeCatalogInfo{};
1067 if (tid) {
1068 StopThreadTimer(tid);
1069 tid = 0;
1070 }
1071
1072 /*
1073 * We closed the device so let any plugin know we did.
1074 */
1075 if (dcr) { GeneratePluginEvent(dcr->jcr, bSdEventDeviceClose, dcr); }
1076
1077 bail_out:
1078 return retval;
1079 }
1080
1081
1082 /**
1083 * Mount the device.
1084 * If timeout, wait until the mount command returns 0.
1085 * If !timeout, try to mount the device only once.
1086 */
mount(DeviceControlRecord * dcr,int timeout)1087 bool Device::mount(DeviceControlRecord* dcr, int timeout)
1088 {
1089 bool retval = true;
1090 Dmsg0(190, "Enter mount\n");
1091
1092 if (IsMounted()) { return true; }
1093
1094 retval = MountBackend(dcr, timeout);
1095
1096 /*
1097 * When the mount command succeeded sent a
1098 * bSdEventDeviceMount plugin event so any plugin
1099 * that want to do something can do things now.
1100 */
1101 if (retval
1102 && GeneratePluginEvent(dcr->jcr, bSdEventDeviceMount, dcr) != bRC_OK) {
1103 retval = false;
1104 }
1105
1106 /*
1107 * Mark the device mounted if we succeed.
1108 */
1109 if (retval) { SetMounted(); }
1110
1111 return retval;
1112 }
1113
1114 /**
1115 * Unmount the device
1116 * If timeout, wait until the unmount command returns 0.
1117 * If !timeout, try to unmount the device only once.
1118 */
unmount(DeviceControlRecord * dcr,int timeout)1119 bool Device::unmount(DeviceControlRecord* dcr, int timeout)
1120 {
1121 bool retval = true;
1122 Dmsg0(100, "Enter unmount\n");
1123
1124 /*
1125 * See if the device is mounted.
1126 */
1127 if (!IsMounted()) { return true; }
1128
1129 /*
1130 * Before running the unmount program sent a
1131 * bSdEventDeviceUnmount plugin event so any plugin
1132 * that want to do something can do things now.
1133 */
1134 if (dcr
1135 && GeneratePluginEvent(dcr->jcr, bSdEventDeviceUnmount, dcr) != bRC_OK) {
1136 retval = false;
1137 goto bail_out;
1138 }
1139
1140 retval = UnmountBackend(dcr, timeout);
1141
1142 /*
1143 * Mark the device unmounted if we succeed.
1144 */
1145 if (retval) { ClearMounted(); }
1146
1147 bail_out:
1148 return retval;
1149 }
1150
1151 /**
1152 * Edit codes into (Un)MountCommand
1153 * %% = %
1154 * %a = archive device name
1155 * %m = mount point
1156 *
1157 * omsg = edited output message
1158 * imsg = input string containing edit codes (%x)
1159 *
1160 */
EditMountCodes(PoolMem & omsg,const char * imsg)1161 void Device::EditMountCodes(PoolMem& omsg, const char* imsg)
1162 {
1163 const char* p;
1164 const char* str;
1165 char add[20];
1166
1167 PoolMem archive_name(PM_FNAME);
1168
1169 omsg.c_str()[0] = 0;
1170 Dmsg1(800, "EditMountCodes: %s\n", imsg);
1171 for (p = imsg; *p; p++) {
1172 if (*p == '%') {
1173 switch (*++p) {
1174 case '%':
1175 str = "%";
1176 break;
1177 case 'a':
1178 str = archive_device_string;
1179 break;
1180 case 'm':
1181 str = device_resource->mount_point;
1182 break;
1183 default:
1184 add[0] = '%';
1185 add[1] = *p;
1186 add[2] = 0;
1187 str = add;
1188 break;
1189 }
1190 } else {
1191 add[0] = *p;
1192 add[1] = 0;
1193 str = add;
1194 }
1195 Dmsg1(1900, "add_str %s\n", str);
1196 PmStrcat(omsg, (char*)str);
1197 Dmsg1(1800, "omsg=%s\n", omsg.c_str());
1198 }
1199 }
1200
1201 /**
1202 * Return the last timer interval (ms) or 0 if something goes wrong
1203 */
GetTimerCount()1204 btime_t Device::GetTimerCount()
1205 {
1206 btime_t temp = last_timer;
1207 last_timer = GetCurrentBtime();
1208 temp = last_timer - temp; /* get elapsed time */
1209
1210 return (temp > 0) ? temp : 0; /* take care of skewed clock */
1211 }
1212
1213 /**
1214 * Read from device.
1215 */
read(void * buf,size_t len)1216 ssize_t Device::read(void* buf, size_t len)
1217 {
1218 ssize_t read_len;
1219
1220 GetTimerCount();
1221
1222 read_len = d_read(fd, buf, len);
1223
1224 last_tick = GetTimerCount();
1225
1226 DevReadTime += last_tick;
1227 VolCatInfo.VolReadTime += last_tick;
1228
1229 if (read_len > 0) { /* skip error */
1230 DevReadBytes += read_len;
1231 }
1232
1233 return read_len;
1234 }
1235
1236 /**
1237 * Write to device.
1238 */
write(const void * buf,size_t len)1239 ssize_t Device::write(const void* buf, size_t len)
1240 {
1241 ssize_t write_len;
1242
1243 GetTimerCount();
1244
1245 write_len = d_write(fd, buf, len);
1246
1247 last_tick = GetTimerCount();
1248
1249 DevWriteTime += last_tick;
1250 VolCatInfo.VolWriteTime += last_tick;
1251
1252 if (write_len > 0) { /* skip error */
1253 DevWriteBytes += write_len;
1254 }
1255
1256 return write_len;
1257 }
1258
1259 /**
1260 * Return the resource name for the device
1261 */
name() const1262 const char* Device::name() const { return device_resource->resource_name_; }
1263
~Device()1264 Device::~Device()
1265 {
1266 Dmsg1(900, "term dev: %s\n", print_name());
1267
1268 if (archive_device_string) {
1269 FreeMemory(archive_device_string);
1270 archive_device_string = nullptr;
1271 }
1272 if (dev_options) {
1273 FreeMemory(dev_options);
1274 dev_options = nullptr;
1275 }
1276 if (prt_name) {
1277 FreeMemory(prt_name);
1278 prt_name = nullptr;
1279 }
1280 if (errmsg) {
1281 FreePoolMemory(errmsg);
1282 errmsg = nullptr;
1283 }
1284 pthread_mutex_destroy(&mutex_);
1285 pthread_cond_destroy(&wait);
1286 pthread_cond_destroy(&wait_next_vol);
1287 pthread_mutex_destroy(&spool_mutex);
1288 // RwlDestroy(&lock);
1289 attached_dcrs.clear();
1290
1291 if (device_resource && device_resource->dev == this) {
1292 device_resource->dev = nullptr;
1293 }
1294 }
1295
CanStealLock() const1296 bool Device::CanStealLock() const
1297 {
1298 return blocked_
1299 && (blocked_ == BST_UNMOUNTED || blocked_ == BST_WAITING_FOR_SYSOP
1300 || blocked_ == BST_UNMOUNTED_WAITING_FOR_SYSOP);
1301 }
1302
waiting_for_mount() const1303 bool Device::waiting_for_mount() const
1304 {
1305 return (blocked_ == BST_UNMOUNTED || blocked_ == BST_WAITING_FOR_SYSOP
1306 || blocked_ == BST_UNMOUNTED_WAITING_FOR_SYSOP);
1307 }
1308
IsBlocked() const1309 bool Device::IsBlocked() const { return blocked_ != BST_NOT_BLOCKED; }
1310
1311 } /* namespace storagedaemon */
1312