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-2018 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 * Definitions for using the Device functions in Bareos Tape and File storage access
29 */
30
31 /**
32 * Some details of how volume and device reservations work
33 *
34 * class VolumeReservationItem:
35 * SetInUse() volume being used on current drive
36 * ClearInUse() no longer being used. Can be re-used or moved.
37 * SetSwapping() set volume being moved to another drive
38 * IsSwapping() volume is being moved to another drive
39 * ClearSwapping() volume normal
40 *
41 * class Device:
42 * SetLoad() set to load volume
43 * needs_load() volume must be loaded (i.e. SetLoad done)
44 * clear_load() load done.
45 * SetUnload() set to unload volume
46 * needs_unload() volume must be unloaded
47 * ClearUnload() volume unloaded
48 *
49 * reservations are temporary until the drive is acquired
50 * IncReserved() increments num of reservations
51 * DecReserved() decrements num of reservations
52 * NumReserved() number of reservations
53 *
54 * class DeviceControlRecord:
55 * SetReserved() sets local reserve flag and calls dev->IncReserved()
56 * ClearReserved() clears local reserve flag and calls dev->DecReserved()
57 * IsReserved() returns local reserved flag
58 * UnreserveDevice() much more complete unreservation
59 */
60
61 #ifndef BAREOS_STORED_DEV_H_
62 #define BAREOS_STORED_DEV_H_ 1
63
64
65 #include "stored/record.h"
66 #include "stored/lock.h"
67 #include "stored/block.h"
68 #include "lib/bsys.h"
69
70 namespace storagedaemon
71 {
72
73
74 /**
75 * Return values from WaitForSysop()
76 */
77 enum {
78 W_ERROR = 1,
79 W_TIMEOUT,
80 W_POLL,
81 W_MOUNT,
82 W_WAKE
83 };
84
85 /**
86 * Arguments to open_dev()
87 */
88 enum {
89 CREATE_READ_WRITE = 1,
90 OPEN_READ_WRITE,
91 OPEN_READ_ONLY,
92 OPEN_WRITE_ONLY
93 };
94
95 /**
96 * Device types
97 */
98 enum {
99 B_FILE_DEV = 1,
100 B_TAPE_DEV,
101 B_FIFO_DEV,
102 B_VTL_DEV,
103 B_GFAPI_DEV,
104 B_DROPLET_DEV,
105 B_RADOS_DEV,
106 B_CEPHFS_DEV,
107 B_ELASTO_DEV
108 };
109
110 /**
111 * IO directions
112 */
113 enum {
114 IO_DIRECTION_NONE = 0,
115 IO_DIRECTION_IN,
116 IO_DIRECTION_OUT,
117 IO_DIRECTION_INOUT
118 };
119
120 /**
121 * Generic status bits returned from StatusDev()
122 */
123 enum {
124 BMT_TAPE = 0, /**< Is tape device */
125 BMT_EOF = 1, /**< Just read EOF */
126 BMT_BOT = 2, /**< At beginning of tape */
127 BMT_EOT = 3, /**< End of tape reached */
128 BMT_SM = 4, /**< DDS setmark */
129 BMT_EOD = 5, /**< DDS at end of data */
130 BMT_WR_PROT = 6, /**< Tape write protected */
131 BMT_ONLINE = 7, /**< Tape online */
132 BMT_DR_OPEN = 8, /**< Tape door open */
133 BMT_IM_REP_EN = 9 /**< Immediate report enabled */
134 };
135
136 /**
137 * Keep this set to the last entry in the enum.
138 */
139 #define BMT_MAX BMT_IM_REP_EN
140
141 /**
142 * Make sure you have enough bits to store all above bit fields.
143 */
144 #define BMT_BYTES NbytesForBits(BMT_MAX + 1)
145
146 /**
147 * Bits for device capabilities
148 */
149 enum {
150 CAP_EOF = 0, /**< Has MTWEOF */
151 CAP_BSR = 1, /**< Has MTBSR */
152 CAP_BSF = 2, /**< Has MTBSF */
153 CAP_FSR = 3, /**< Has MTFSR */
154 CAP_FSF = 4, /**< Has MTFSF */
155 CAP_EOM = 5, /**< Has MTEOM */
156 CAP_REM = 6, /**< Is removable media */
157 CAP_RACCESS = 7, /**< Is random access device */
158 CAP_AUTOMOUNT = 8, /**< Read device at start to see what is there */
159 CAP_LABEL = 9, /**< Label blank tapes */
160 CAP_ANONVOLS = 10, /**< Mount without knowing volume name */
161 CAP_ALWAYSOPEN = 11, /**< Always keep device open */
162 CAP_AUTOCHANGER = 12, /**< AutoChanger */
163 CAP_OFFLINEUNMOUNT = 13, /**< Offline before unmount */
164 CAP_STREAM = 14, /**< Stream device */
165 CAP_BSFATEOM = 15, /**< Backspace file at EOM */
166 CAP_FASTFSF = 16, /**< Fast forward space file */
167 CAP_TWOEOF = 17, /**< Write two eofs for EOM */
168 CAP_CLOSEONPOLL = 18, /**< Close device on polling */
169 CAP_POSITIONBLOCKS = 19, /**< Use block positioning */
170 CAP_MTIOCGET = 20, /**< Basic support for fileno and blkno */
171 CAP_REQMOUNT = 21, /**< Require mount/unmount */
172 CAP_CHECKLABELS = 22, /**< Check for ANSI/IBM labels */
173 CAP_BLOCKCHECKSUM = 23, /**< Create/test block checksum */
174 CAP_IOERRATEOM = 24, /**< IOError at EOM */
175 CAP_IBMLINTAPE = 25, /**< Using IBM lin_tape driver */
176 CAP_ADJWRITESIZE = 26 /**< Adjust write size to min/max */
177 };
178
179 /**
180 * Keep this set to the last entry in the enum.
181 */
182 constexpr int CAP_MAX = CAP_ADJWRITESIZE;
183
184 /**
185 * Make sure you have enough bits to store all above bit fields.
186 */
187 constexpr int CAP_BYTES = NbytesForBits(CAP_MAX + 1);
188
189 /**
190 * Device state bits
191 */
192 enum {
193 ST_LABEL = 0, /**< Label found */
194 ST_MALLOC = 1, /**< Dev packet malloc'ed in InitDev() */
195 ST_APPENDREADY = 2, /**< Ready for Bareos append */
196 ST_READREADY = 3, /**< Ready for Bareos read */
197 ST_EOT = 4, /**< At end of tape */
198 ST_WEOT = 5, /**< Got EOT on write */
199 ST_EOF = 6, /**< Read EOF i.e. zero bytes */
200 ST_NEXTVOL = 7, /**< Start writing on next volume */
201 ST_SHORT = 8, /**< Short block read */
202 ST_MOUNTED = 9, /**< The device is mounted to the mount point */
203 ST_MEDIA = 10, /**< Media found in mounted device */
204 ST_OFFLINE = 11, /**< Set offline by operator */
205 ST_PART_SPOOLED = 12, /**< Spooling part */
206 ST_CRYPTOKEY = 13 /**< The device has a crypto key loaded */
207 };
208
209 /**
210 * Keep this set to the last entry in the enum.
211 */
212 #define ST_MAX ST_CRYPTOKEY
213
214 /**
215 * Make sure you have enough bits to store all above bit fields.
216 */
217 #define ST_BYTES NbytesForBits(ST_MAX + 1)
218
219 /**
220 * Volume Catalog Information structure definition
221 */
222 struct VolumeCatalogInfo {
223 /*
224 * Media info for the current Volume
225 */
226 uint32_t VolCatJobs; /**< number of jobs on this Volume */
227 uint32_t VolCatFiles; /**< Number of files */
228 uint32_t VolCatBlocks; /**< Number of blocks */
229 uint64_t VolCatBytes; /**< Number of bytes written */
230 uint32_t VolCatMounts; /**< Number of mounts this volume */
231 uint32_t VolCatErrors; /**< Number of errors this volume */
232 uint32_t VolCatWrites; /**< Number of writes this volume */
233 uint32_t VolCatReads; /**< Number of reads this volume */
234 uint64_t VolCatRBytes; /**< Number of bytes read */
235 uint32_t VolCatRecycles; /**< Number of recycles this volume */
236 uint32_t EndFile; /**< Last file number */
237 uint32_t EndBlock; /**< Last block number */
238 int32_t LabelType; /**< Bareos/ANSI/IBM */
239 int32_t Slot; /**< >0=Slot loaded, 0=nothing, -1=unknown */
240 uint32_t VolCatMaxJobs; /**< Maximum Jobs to write to volume */
241 uint32_t VolCatMaxFiles; /**< Maximum files to write to volume */
242 uint64_t VolCatMaxBytes; /**< Max bytes to write to volume */
243 uint64_t VolCatCapacityBytes; /**< capacity estimate */
244 btime_t VolReadTime; /**< time spent reading */
245 btime_t VolWriteTime; /**< time spent writing this Volume */
246 int64_t VolMediaId; /**< MediaId */
247 utime_t VolFirstWritten; /**< Time of first write */
248 utime_t VolLastWritten; /**< Time of last write */
249 bool InChanger; /**< Set if vol in current magazine */
250 bool is_valid; /**< set if this data is valid */
251 char VolCatStatus[20]; /**< Volume status */
252 char VolCatName[MAX_NAME_LENGTH]; /**< Desired volume to mount */
253 char VolEncrKey[MAX_NAME_LENGTH]; /**< Encryption Key needed to read the media */
254 uint32_t VolMinBlocksize; /**< Volume Minimum Blocksize */
255 uint32_t VolMaxBlocksize; /**< Volume Maximum Blocksize */
256 };
257
258 struct BlockSizes {
259 uint32_t max_block_size;
260 uint32_t min_block_size;
261 };
262
263 class DeviceResource; /* Forward reference Device resource defined in stored_conf.h */
264 class DeviceControlRecord; /* Forward reference */
265 class VolumeReservationItem; /* Forward reference */
266
267 /**
268 * Device specific status information either returned via Device::DeviceStatus()
269 * method of via bsdEventDriveStatus and bsdEventVolumeStatus plugin events.
270 */
271 typedef struct DeviceStatusTrigger {
272 DeviceResource *device;
273 POOLMEM *status;
274 int status_length;
275 } bsdDevStatTrig;
276
277 /*
278 * Device structure definition.
279 *
280 * There is one of these for each physical device. Everything here is "global" to
281 * that device and effects all jobs using the device.
282 */
283 class Device: public SmartAlloc {
284 protected:
285 int fd_; /**< File descriptor */
286 private:
287 int blocked_; /**< Set if we must wait (i.e. change tape) */
288 int count_; /**< Mutex use count -- DEBUG only */
289 int num_reserved_; /**< Counter of device reservations */
290 slot_number_t slot_; /**< Slot loaded in drive or -1 if none */
291 pthread_t pid_; /**< Thread that locked -- DEBUG only */
292 bool unload_; /**< Set when Volume must be unloaded */
293 bool load_; /**< Set when Volume must be loaded */
294
295 public:
296 Device();
~Device()297 virtual ~Device() {}
298 Device * volatile swap_dev; /**< Swap vol from this device */
299 dlist *attached_dcrs; /**< Attached DeviceControlRecord list */
300 bthread_mutex_t mutex_; /**< Access control */
301 bthread_mutex_t spool_mutex; /**< Mutex for updating spool_size */
302 bthread_mutex_t acquire_mutex; /**< Mutex for acquire code */
303 pthread_mutex_t read_acquire_mutex; /**< Mutex for acquire read code */
304 pthread_cond_t wait; /**< Thread wait variable */
305 pthread_cond_t wait_next_vol; /**< Wait for tape to be mounted */
306 pthread_t no_wait_id; /**< This thread must not wait */
307 int dev_prev_blocked; /**< Previous blocked state */
308 int num_waiting; /**< Number of threads waiting */
309 int num_writers; /**< Number of writing threads */
310 char capabilities[CAP_BYTES]; /**< Capabilities mask */
311 char state[ST_BYTES]; /**< State mask */
312 int dev_errno; /**< Our own errno */
313 int oflags; /**< Read/write flags */
314 int open_mode; /**< Parameter passed to open_dev (useful to reopen the device) */
315 int dev_type; /**< Device type */
316 bool autoselect; /**< Autoselect in autochanger */
317 bool norewindonclose; /**< Don't rewind tape drive on close */
318 bool initiated; /**< Set when InitDev() called */
319 int label_type; /**< Bareos/ANSI/IBM label types */
320 drive_number_t drive; /**< Autochanger logical drive number (base 0) */
321 drive_number_t drive_index; /**< Autochanger physical drive index (base 0) */
322 POOLMEM *dev_name; /**< Physical device name */
323 POOLMEM *dev_options; /**< Device specific options */
324 POOLMEM *prt_name; /**< Name used for display purposes */
325 char *errmsg; /**< Nicely edited error message */
326 uint32_t block_num; /**< Current block number base 0 */
327 uint32_t LastBlock; /**< Last DeviceBlock number written to Volume */
328 uint32_t file; /**< Current file number base 0 */
329 uint64_t file_addr; /**< Current file read/write address */
330 uint64_t file_size; /**< Current file size */
331 uint32_t EndBlock; /**< Last block written */
332 uint32_t EndFile; /**< Last file written */
333 uint32_t min_block_size; /**< Min block size currently set */
334 uint32_t max_block_size; /**< Max block size currently set */
335 uint32_t max_concurrent_jobs; /**< Maximum simultaneous jobs this drive */
336 uint64_t max_volume_size; /**< Max bytes to put on one volume */
337 uint64_t max_file_size; /**< Max file size to put in one file on volume */
338 uint64_t volume_capacity; /**< Advisory capacity */
339 uint64_t max_spool_size; /**< Maximum spool file size */
340 uint64_t spool_size; /**< Current spool size for this device */
341 uint32_t max_rewind_wait; /**< Max secs to allow for rewind */
342 uint32_t max_open_wait; /**< Max secs to allow for open */
343 uint32_t max_open_vols; /**< Max simultaneous open volumes */
344
345 utime_t vol_poll_interval; /**< Interval between polling Vol mount */
346 DeviceResource *device; /**< Pointer to Device Resource */
347 VolumeReservationItem *vol; /**< Pointer to Volume reservation item */
348 btimer_t *tid; /**< Timer id */
349
350 VolumeCatalogInfo VolCatInfo; /**< Volume Catalog Information */
351 VOLUME_LABEL VolHdr; /**< Actual volume label */
352 char pool_name[MAX_NAME_LENGTH]; /**< Pool name */
353 char pool_type[MAX_NAME_LENGTH]; /**< Pool type */
354
355 char UnloadVolName[MAX_NAME_LENGTH]; /**< Last wrong Volume mounted */
356 bool poll; /**< Set to poll Volume */
357 /* Device wait times ***FIXME*** look at durations */
358 int min_wait;
359 int max_wait;
360 int max_num_wait;
361 int wait_sec;
362 int rem_wait_sec;
363 int num_wait;
364
365 btime_t last_timer; /**< Used by read/write/seek to get stats (usec) */
366 btime_t last_tick; /**< Contains last read/write time (usec) */
367
368 btime_t DevReadTime;
369 btime_t DevWriteTime;
370 uint64_t DevWriteBytes;
371 uint64_t DevReadBytes;
372
373 /* Methods */
374 btime_t GetTimerCount(); /**< Return the last timer interval (ms) */
375
HasCap(int cap)376 bool HasCap(int cap) const { return BitIsSet(cap, capabilities) ; }
ClearCap(int cap)377 void ClearCap(int cap) { ClearBit(cap, capabilities); }
SetCap(int cap)378 void SetCap(int cap) { SetBit(cap, capabilities); }
DoChecksum()379 bool DoChecksum() const { return BitIsSet(CAP_BLOCKCHECKSUM, capabilities); }
IsAutochanger()380 bool IsAutochanger() const { return BitIsSet(CAP_AUTOCHANGER, capabilities); }
RequiresMount()381 bool RequiresMount() const { return BitIsSet(CAP_REQMOUNT, capabilities); }
IsRemovable()382 bool IsRemovable() const { return BitIsSet(CAP_REM, capabilities); }
IsTape()383 bool IsTape() const { return (dev_type == B_TAPE_DEV); }
IsFile()384 bool IsFile() const { return (dev_type == B_FILE_DEV ||
385 dev_type == B_GFAPI_DEV ||
386 dev_type == B_DROPLET_DEV ||
387 dev_type == B_RADOS_DEV ||
388 dev_type == B_CEPHFS_DEV ||
389 dev_type == B_ELASTO_DEV); }
IsFifo()390 bool IsFifo() const { return dev_type == B_FIFO_DEV; }
IsVtl()391 bool IsVtl() const { return dev_type == B_VTL_DEV; }
IsOpen()392 bool IsOpen() const { return fd_ >= 0; }
IsOffline()393 bool IsOffline() const { return BitIsSet(ST_OFFLINE, state); }
IsLabeled()394 bool IsLabeled() const { return BitIsSet(ST_LABEL, state); }
IsMounted()395 bool IsMounted() const { return BitIsSet(ST_MOUNTED, state); }
IsUnmountable()396 bool IsUnmountable() const { return ((IsFile() && IsRemovable())); }
NumReserved()397 int NumReserved() const { return num_reserved_; }
is_part_spooled()398 bool is_part_spooled() const { return BitIsSet(ST_PART_SPOOLED, state); }
have_media()399 bool have_media() const { return BitIsSet(ST_MEDIA, state); }
IsShortBlock()400 bool IsShortBlock() const { return BitIsSet(ST_SHORT, state); }
IsBusy()401 bool IsBusy() const { return BitIsSet(ST_READREADY, state) || num_writers || NumReserved(); }
AtEof()402 bool AtEof() const { return BitIsSet(ST_EOF, state); }
AtEot()403 bool AtEot() const { return BitIsSet(ST_EOT, state); }
AtWeot()404 bool AtWeot() const { return BitIsSet(ST_WEOT, state); }
CanAppend()405 bool CanAppend() const { return BitIsSet(ST_APPENDREADY, state); }
IsCryptoEnabled()406 bool IsCryptoEnabled() const { return BitIsSet(ST_CRYPTOKEY, state); }
407
408 /**
409 * CanWrite() is meant for checking at the end of a job to see
410 * if we still have a tape (perhaps not if at end of tape
411 * and the job is canceled).
412 */
CanWrite()413 bool CanWrite() const { return IsOpen() && CanAppend() &&
414 IsLabeled() && !AtWeot(); }
CanRead()415 bool CanRead() const { return BitIsSet(ST_READREADY, state); }
416 bool CanStealLock() const;
417 bool waiting_for_mount() const;
MustUnload()418 bool MustUnload() const { return unload_; }
must_load()419 bool must_load() const { return load_; }
420 const char *strerror() const;
421 const char *archive_name() const;
422 const char *name() const;
423 const char *print_name() const; /**< Name for display purposes */
SetEot()424 void SetEot() { SetBit(ST_EOT, state); }
SetEof()425 void SetEof() { SetBit(ST_EOF, state); }
SetAppend()426 void SetAppend() { SetBit(ST_APPENDREADY, state); }
SetLabeled()427 void SetLabeled() { SetBit(ST_LABEL, state); }
SetRead()428 inline void SetRead() { SetBit(ST_READREADY, state); }
set_offline()429 void set_offline() { SetBit(ST_OFFLINE, state); }
SetMounted()430 void SetMounted() { SetBit(ST_MOUNTED, state); }
set_media()431 void set_media() { SetBit(ST_MEDIA, state); }
SetShortBlock()432 void SetShortBlock() { SetBit(ST_SHORT, state); }
SetCryptoEnabled()433 void SetCryptoEnabled() { SetBit(ST_CRYPTOKEY, state); }
SetPartSpooled(int val)434 void SetPartSpooled(int val) {
435 if (val)
436 SetBit(ST_PART_SPOOLED, state);
437 else
438 ClearBit(ST_PART_SPOOLED, state);
439 }
IsVolumeToUnload()440 bool IsVolumeToUnload() const { \
441 return unload_ && strcmp(VolHdr.VolumeName, UnloadVolName) == 0; }
SetLoad()442 void SetLoad() { load_ = true; }
IncReserved()443 void IncReserved() { num_reserved_++; }
DecReserved()444 void DecReserved() { num_reserved_--; ASSERT(num_reserved_>=0); }
ClearAppend()445 void ClearAppend() { ClearBit(ST_APPENDREADY, state); }
ClearRead()446 void ClearRead() { ClearBit(ST_READREADY, state); }
ClearLabeled()447 void ClearLabeled() { ClearBit(ST_LABEL, state); }
clear_offline()448 void clear_offline() { ClearBit(ST_OFFLINE, state); }
ClearEot()449 void ClearEot() { ClearBit(ST_EOT, state); }
ClearEof()450 void ClearEof() { ClearBit(ST_EOF, state); }
ClearOpened()451 void ClearOpened() { fd_ = -1; }
ClearMounted()452 void ClearMounted() { ClearBit(ST_MOUNTED, state); }
clear_media()453 void clear_media() { ClearBit(ST_MEDIA, state); }
ClearShortBlock()454 void ClearShortBlock() { ClearBit(ST_SHORT, state); }
ClearCryptoEnabled()455 void ClearCryptoEnabled() { ClearBit(ST_CRYPTOKEY, state); }
ClearUnload()456 void ClearUnload() { unload_ = false; UnloadVolName[0] = 0; }
clear_load()457 void clear_load() { load_ = false; }
bstrerror(void)458 char *bstrerror(void) { return errmsg; }
print_errmsg()459 char *print_errmsg() { return errmsg; }
GetSlot()460 slot_number_t GetSlot() const { return slot_; }
setVolCatInfo(bool valid)461 void setVolCatInfo(bool valid) { VolCatInfo.is_valid = valid; }
haveVolCatInfo()462 bool haveVolCatInfo() const { return VolCatInfo.is_valid; }
setVolCatName(const char * name)463 void setVolCatName(const char *name) {
464 bstrncpy(VolCatInfo.VolCatName, name, sizeof(VolCatInfo.VolCatName));
465 setVolCatInfo(false);
466 }
getVolCatName()467 char *getVolCatName() { return VolCatInfo.VolCatName; }
468
469 const char *mode_to_str(int mode);
470 void SetUnload();
471 void ClearVolhdr();
472 bool close(DeviceControlRecord *dcr);
473 bool open(DeviceControlRecord *dcr, int mode);
474 void term();
475 ssize_t read(void *buf, size_t len);
476 ssize_t write(const void *buf, size_t len);
477 bool mount(DeviceControlRecord *dcr, int timeout);
478 bool unmount(DeviceControlRecord *dcr, int timeout);
479 void EditMountCodes(PoolMem &omsg, const char *imsg);
480 bool OfflineOrRewind();
481 bool ScanDirForVolume(DeviceControlRecord *dcr);
482 void SetSlot(slot_number_t slot);
483 void ClearSlot();
484
485 void SetBlocksizes(DeviceControlRecord* dcr);
486 void SetLabelBlocksize(DeviceControlRecord* dcr);
487
GetFile()488 uint32_t GetFile() const { return file; }
GetBlockNum()489 uint32_t GetBlockNum() const { return block_num; }
fd()490 int fd() const { return fd_; }
491
492 /*
493 * Tape specific operations.
494 */
offline()495 virtual bool offline() { return true; }
weof(int num)496 virtual bool weof(int num) { return true; }
fsf(int num)497 virtual bool fsf(int num) { return true; }
bsf(int num)498 virtual bool bsf(int num) { return false; }
fsr(int num)499 virtual bool fsr(int num) { return false; }
bsr(int num)500 virtual bool bsr(int num) { return false; }
LoadDev()501 virtual bool LoadDev() { return true; }
LockDoor()502 virtual void LockDoor() {};
UnlockDoor()503 virtual void UnlockDoor() {};
clrerror(int func)504 virtual void clrerror(int func) {};
SetOsDeviceParameters(DeviceControlRecord * dcr)505 virtual void SetOsDeviceParameters(DeviceControlRecord *dcr) {};
GetOsTapeFile()506 virtual int32_t GetOsTapeFile() { return -1; }
507
508 /*
509 * Generic operations.
510 */
511 virtual void OpenDevice(DeviceControlRecord *dcr, int omode);
512 virtual char *StatusDev();
513 virtual bool eod(DeviceControlRecord *dcr);
514 virtual void SetAteof();
515 virtual void SetAteot();
516 virtual bool rewind(DeviceControlRecord *dcr);
517 virtual bool UpdatePos(DeviceControlRecord *dcr);
518 virtual bool Reposition(DeviceControlRecord *dcr, uint32_t rfile, uint32_t rblock);
MountBackend(DeviceControlRecord * dcr,int timeout)519 virtual bool MountBackend(DeviceControlRecord *dcr, int timeout) { return true; }
UnmountBackend(DeviceControlRecord * dcr,int timeout)520 virtual bool UnmountBackend(DeviceControlRecord *dcr, int timeout) { return true; }
DeviceStatus(bsdDevStatTrig * dst)521 virtual bool DeviceStatus(bsdDevStatTrig *dst) { return false; }
lseek(DeviceControlRecord * dcr,boffset_t offset,int whence)522 boffset_t lseek(DeviceControlRecord *dcr, boffset_t offset, int whence) { return d_lseek(dcr, offset, whence); }
truncate(DeviceControlRecord * dcr)523 bool truncate(DeviceControlRecord *dcr) { return d_truncate(dcr); }
flush(DeviceControlRecord * dcr)524 bool flush(DeviceControlRecord *dcr) { return d_flush(dcr); };
525
526 /*
527 * Low level operations
528 */
529 virtual int d_ioctl(int fd, ioctl_req_t request, char *mt_com = NULL) = 0;
530 virtual int d_open(const char *pathname, int flags, int mode) = 0;
531 virtual int d_close(int fd) = 0;
532 virtual ssize_t d_read(int fd, void *buffer, size_t count) = 0;
533 virtual ssize_t d_write(int fd, const void *buffer, size_t count) = 0;
534 virtual boffset_t d_lseek(DeviceControlRecord *dcr, boffset_t offset, int whence) = 0;
535 virtual bool d_truncate(DeviceControlRecord *dcr) = 0;
d_flush(DeviceControlRecord * dcr)536 virtual bool d_flush(DeviceControlRecord *dcr) { return true; };
537
538 /*
539 * Locking and blocking calls
540 */
541 #ifdef SD_DEBUG_LOCK
542 void dbg_rLock(const char *, int, bool locked = false);
543 void dbg_rUnlock(const char *, int);
544 void dbg_Lock(const char *, int);
545 void dbg_Unlock(const char *, int);
546 void dbg_Lock_acquire(const char *, int);
547 void dbg_Unlock_acquire(const char *, int);
548 void dbg_Lock_read_acquire(const char *, int);
549 void dbg_Unlock_read_acquire(const char *, int);
550 #else
551 void rLock(bool locked = false);
552 void rUnlock();
553 void Lock();
554 void Unlock();
555 void Lock_acquire();
556 void Unlock_acquire();
557 void Lock_read_acquire();
558 void Unlock_read_acquire();
559 void Lock_VolCatInfo();
560 void Unlock_VolCatInfo();
561 #endif
562 int InitMutex();
563 int InitAcquireMutex();
564 int InitReadAcquireMutex();
565 int init_volcat_mutex();
566 void SetMutexPriorities();
567 int NextVolTimedwait(const struct timespec *timeout);
568 void dblock(int why);
569 void dunblock(bool locked = false);
570 bool IsDeviceUnmounted();
SetBlocked(int block)571 void SetBlocked(int block) { blocked_ = block; }
572 bool IsBlocked() const;
blocked()573 int blocked() const { return blocked_; }
574 const char *print_blocked() const;
575
576 protected:
577 void set_mode(int mode);
578 };
579
strerror()580 inline const char *Device::strerror() const { return errmsg; }
archive_name()581 inline const char *Device::archive_name() const { return dev_name; }
print_name()582 inline const char *Device::print_name() const { return prt_name; }
583
584 #define CHECK_BLOCK_NUMBERS true
585 #define NO_BLOCK_NUMBER_CHECK false
586
587 enum get_vol_info_rw {
588 GET_VOL_INFO_FOR_WRITE,
589 GET_VOL_INFO_FOR_READ
590 };
591
592 /**
593 * Device Context (or Control) Record.
594 *
595 * There is one of these records for each Job that is using
596 * the device. Items in this record are "local" to the Job and
597 * do not affect other Jobs. Note, a job can have multiple
598 * DCRs open, each pointing to a different device.
599 *
600 * Normally, there is only one JobControlRecord thread per DeviceControlRecord. However, the
601 * big and important exception to this is when a Job is being
602 * canceled. At that time, there may be two threads using the
603 * same DeviceControlRecord. Consequently, when creating/attaching/detaching
604 * and freeing the DeviceControlRecord we must lock it (mutex_).
605 */
606 class DeviceControlRecord : public SmartAlloc {
607 private:
608 bool dev_locked_; /**< Set if dev already locked */
609 int dev_lock_; /**< Non-zero if rLock already called */
610 bool reserved_; /**< Set if reserved device */
611 bool found_in_use_; /**< Set if a volume found in use */
612 bool will_write_; /**< Set if DeviceControlRecord will be used for writing */
613
614 public:
615 dlink dev_link; /**< Link to attach to dev */
616 JobControlRecord *jcr; /**< Pointer to JobControlRecord */
617 bthread_mutex_t mutex_; /**< Access control */
618 pthread_mutex_t r_mutex; /**< rLock pre-mutex */
619 Device * volatile dev; /**< Pointer to device */
620 DeviceResource *device; /**< Pointer to device resource */
621 DeviceBlock *block; /**< Pointer to current block */
622 DeviceRecord *rec; /**< Pointer to record being processed */
623 DeviceRecord *before_rec; /**< Pointer to record before translation */
624 DeviceRecord *after_rec; /**< Pointer to record after translation */
625 pthread_t tid; /**< Thread running this dcr */
626 int spool_fd; /**< Fd if spooling */
627 bool spool_data; /**< Set to spool data */
628 bool spooling; /**< Set when actually spooling */
629 bool despooling; /**< Set when despooling */
630 bool despool_wait; /**< Waiting for despooling */
631 bool NewVol; /**< Set if new Volume mounted */
632 bool WroteVol; /**< Set if Volume written */
633 bool NewFile; /**< Set when EOF written */
634 bool reserved_volume; /**< Set if we reserved a volume */
635 bool any_volume; /**< Any OK for dir_find_next... */
636 bool attached_to_dev; /**< Set when attached to dev */
637 bool keep_dcr; /**< Do not free dcr in release_dcr */
638 uint32_t autodeflate; /**< Try to autodeflate streams */
639 uint32_t autoinflate; /**< Try to autoinflate streams */
640 uint32_t VolFirstIndex; /**< First file index this Volume */
641 uint32_t VolLastIndex; /**< Last file index this Volume */
642 uint32_t FileIndex; /**< Current File Index */
643 uint32_t EndFile; /**< End file written */
644 uint32_t StartFile; /**< Start write file */
645 uint32_t StartBlock; /**< Start write block */
646 uint32_t EndBlock; /**< Ending block written */
647 int64_t VolMediaId; /**< MediaId */
648 int64_t job_spool_size; /**< Current job spool size */
649 int64_t max_job_spool_size; /**< Max job spool size */
650 uint32_t VolMinBlocksize; /**< Minimum Blocksize */
651 uint32_t VolMaxBlocksize; /**< Maximum Blocksize */
652 char VolumeName[MAX_NAME_LENGTH]; /**< Volume name */
653 char pool_name[MAX_NAME_LENGTH]; /**< Pool name */
654 char pool_type[MAX_NAME_LENGTH]; /**< Pool type */
655 char media_type[MAX_NAME_LENGTH]; /**< Media type */
656 char dev_name[MAX_NAME_LENGTH]; /**< Dev name */
657 int Copy; /**< Identical copy number */
658 int Stripe; /**< RAIT stripe */
659 VolumeCatalogInfo VolCatInfo; /**< Catalog info for desired volume */
660
661 /*
662 * Constructor/Destructor.
663 */
664 DeviceControlRecord();
~DeviceControlRecord()665 virtual ~DeviceControlRecord() {};
666
667 /*
668 * Methods
669 */
SetDev(Device * ndev)670 void SetDev(Device *ndev) { dev = ndev; }
SetFoundInUse()671 void SetFoundInUse() { found_in_use_ = true; }
SetWillWrite()672 void SetWillWrite() { will_write_ = true; }
setVolCatInfo(bool valid)673 void setVolCatInfo(bool valid) { VolCatInfo.is_valid = valid; }
674
ClearFoundInUse()675 void ClearFoundInUse() { found_in_use_ = false; }
clear_will_write()676 void clear_will_write() { will_write_ = false; }
677
IsReserved()678 bool IsReserved() const { return reserved_; }
IsDevLocked()679 bool IsDevLocked() { return dev_locked_; }
IsWriting()680 bool IsWriting() const { return will_write_; }
681
IncDevLock()682 void IncDevLock() { dev_lock_++; }
DecDevLock()683 void DecDevLock() { dev_lock_--; }
FoundInUse()684 bool FoundInUse() const { return found_in_use_; }
685
haveVolCatInfo()686 bool haveVolCatInfo() const { return VolCatInfo.is_valid; }
setVolCatName(const char * name)687 void setVolCatName(const char *name) {
688 bstrncpy(VolCatInfo.VolCatName, name, sizeof(VolCatInfo.VolCatName));
689 setVolCatInfo(false);
690 }
getVolCatName()691 char *getVolCatName() { return VolCatInfo.VolCatName; }
692
693 /*
694 * Methods in askdir.c
695 */
696 virtual DeviceControlRecord *get_new_spooling_dcr();
DirFindNextAppendableVolume()697 virtual bool DirFindNextAppendableVolume() { return true; }
DirUpdateVolumeInfo(bool label,bool update_LastWritten)698 virtual bool DirUpdateVolumeInfo(bool label, bool update_LastWritten) { return true; }
DirCreateJobmediaRecord(bool zero)699 virtual bool DirCreateJobmediaRecord(bool zero) { return true; }
DirUpdateFileAttributes(DeviceRecord * record)700 virtual bool DirUpdateFileAttributes(DeviceRecord *record) { return true; }
701 virtual bool DirAskSysopToMountVolume(int mode);
DirAskSysopToCreateAppendableVolume()702 virtual bool DirAskSysopToCreateAppendableVolume() { return true; }
703 virtual bool DirGetVolumeInfo(enum get_vol_info_rw writing);
704
705 /*
706 * Methods in lock.c
707 */
dblock(int why)708 void dblock(int why) { dev->dblock(why); }
709 #ifdef SD_DEBUG_LOCK
710 void dbg_mLock(const char *, int, bool locked);
711 void dbg_mUnlock(const char *, int);
712 #else
713 void mLock(bool locked);
714 void mUnlock();
715 #endif
716
717 /*
718 * Methods in record.c
719 */
720 bool WriteRecord();
721
722 /*
723 * Methods in reserve.c
724 */
725 void ClearReserved();
726 void SetReserved();
727 void UnreserveDevice();
728
729 /*
730 * Methods in vol_mgr.c
731 */
732 bool Can_i_use_volume();
733 bool Can_i_write_volume();
734
735 /*
736 * Methods in mount.c
737 */
738 bool MountNextWriteVolume();
739 bool MountNextReadVolume();
740 void MarkVolumeInError();
741 void mark_volume_not_inchanger();
742 int TryAutolabel(bool opened);
743 bool find_a_volume();
744 bool IsSuitableVolumeMounted();
745 bool is_eod_valid();
746 int CheckVolumeLabel(bool &ask, bool &autochanger);
747 void ReleaseVolume();
748 void DoSwapping(bool IsWriting);
749 bool DoUnload();
750 bool DoLoad(bool IsWriting);
751 bool IsTapePositionOk();
752
753 /*
754 * Methods in block.c
755 */
756 bool WriteBlockToDevice();
757 bool WriteBlockToDev();
758
759 enum ReadStatus {
760 Error = 0,
761 Ok,
762 EndOfFile,
763 EndOfTape
764 };
765
766 ReadStatus ReadBlockFromDevice(bool check_block_numbers);
767 ReadStatus ReadBlockFromDev(bool check_block_numbers);
768
769 /*
770 * Methods in label.c
771 */
772 bool RewriteVolumeLabel(bool recycle);
773 };
774
775 class StorageDaemonDeviceControlRecord : public DeviceControlRecord {
776 public:
777 /*
778 * Virtual Destructor.
779 */
~StorageDaemonDeviceControlRecord()780 ~StorageDaemonDeviceControlRecord() {};
781
782 /*
783 * Methods overriding default implementations.
784 */
785 bool DirFindNextAppendableVolume() override;
786 bool DirUpdateVolumeInfo(bool label, bool update_LastWritten) override;
787 bool DirCreateJobmediaRecord(bool zero) override;
788 bool DirUpdateFileAttributes(DeviceRecord *record) override;
789 bool DirAskSysopToMountVolume(int mode) override;
790 bool DirAskSysopToCreateAppendableVolume() override;
791 bool DirGetVolumeInfo(enum get_vol_info_rw writing) override;
792 DeviceControlRecord *get_new_spooling_dcr() override;
793 };
794
795 class BTAPE_DCR : public DeviceControlRecord {
796 public:
797 /*
798 * Virtual Destructor.
799 */
~BTAPE_DCR()800 ~BTAPE_DCR() {};
801
802 /*
803 * Methods overriding default implementations.
804 */
805 bool DirFindNextAppendableVolume() override;
806 bool DirCreateJobmediaRecord(bool zero) override;
807 bool DirAskSysopToMountVolume(int mode) override;
808 bool DirAskSysopToCreateAppendableVolume() override;
809 DeviceControlRecord *get_new_spooling_dcr() override;
810 };
811
812 Device *InitDev(JobControlRecord *jcr, DeviceResource *device);
813 bool CanOpenMountedDev(Device *dev);
814 bool LoadDev(Device *dev);
815 int WriteBlock(Device *dev);
816 void AttachJcrToDevice(Device *dev, JobControlRecord *jcr);
817 void DetachJcrFromDevice(Device *dev, JobControlRecord *jcr);
818 JobControlRecord *next_attached_jcr(Device *dev, JobControlRecord *jcr);
819 void InitDeviceWaitTimers(DeviceControlRecord *dcr);
820 void InitJcrDeviceWaitTimers(JobControlRecord *jcr);
821 bool DoubleDevWaitTime(Device *dev);
822
823 /*
824 * Get some definition of function to position to the end of the medium in MTEOM. System dependent.
825 */
826 #ifndef MTEOM
827 #ifdef MTSEOD
828 #define MTEOM MTSEOD
829 #endif
830 #ifdef MTEOD
831 #undef MTEOM
832 #define MTEOM MTEOD
833 #endif
834 #endif
835
836 } /* namespace storagedaemon */
837
838 #endif
839