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