/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
*
*/
-
#ifndef __DEV_H
#define __DEV_H 1
B_DVD_DEV,
B_FIFO_DEV,
B_VTAPE_DEV, /* change to B_TAPE_DEV after init */
+ B_FTP_DEV,
B_VTL_DEV
};
char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */
};
-
class DEVRES; /* Device resource defined in stored_conf.h */
class DCR; /* forward reference */
class VOLRES; /* forward reference */
* each physical device. Everything here is "global" to
* that device and effects all jobs using the device.
*/
-class DEVICE {
-private:
+class DEVICE: public SMARTALLOC {
+protected:
int m_fd; /* file descriptor */
+private:
int m_blocked; /* set if we must wait (i.e. change tape) */
int m_count; /* Mutex use count -- DEBUG only */
int m_num_reserved; /* counter of device reservations */
bool m_load; /* set when Volume must be loaded */
public:
+ DEVICE() {};
+ virtual ~DEVICE() {};
DEVICE * volatile swap_dev; /* Swap vol from this device */
dlist *attached_dcrs; /* attached DCR list */
bthread_mutex_t m_mutex; /* access control */
bthread_mutex_t spool_mutex; /* mutex for updating spool_size */
bthread_mutex_t acquire_mutex; /* mutex for acquire code */
+ pthread_mutex_t read_acquire_mutex; /* mutex for acquire read code */
pthread_cond_t wait; /* thread wait variable */
pthread_cond_t wait_next_vol; /* wait for tape to be mounted */
pthread_t no_wait_id; /* this thread must not wait */
int is_removable() const { return capabilities & CAP_REM; }
int is_tape() const { return (dev_type == B_TAPE_DEV ||
dev_type == B_VTAPE_DEV); }
- int is_file() const { return dev_type == B_FILE_DEV; }
+ int is_ftp() const { return dev_type == B_FTP_DEV; }
+ int is_file() const { return (dev_type == B_FILE_DEV); }
int is_fifo() const { return dev_type == B_FIFO_DEV; }
int is_dvd() const { return dev_type == B_DVD_DEV; }
int is_vtl() const { return dev_type == B_VTL_DEV; }
void clear_volhdr(); /* in dev.c */
void close(); /* in dev.c */
void close_part(DCR *dcr); /* in dev.c */
- bool truncate(DCR *dcr); /* in dev.c */
- int open(DCR *dcr, int mode); /* in dev.c */
+ bool open(DCR *dcr, int mode); /* in dev.c */
void term(void); /* in dev.c */
ssize_t read(void *buf, size_t len); /* in dev.c */
ssize_t write(const void *buf, size_t len); /* in dev.c */
- bool rewind(DCR *dcr); /* in dev.c */
bool mount(int timeout); /* in dev.c */
bool unmount(int timeout); /* in dev.c */
void edit_mount_codes(POOL_MEM &omsg, const char *imsg); /* in dev.c */
bool scan_dir_for_volume(DCR *dcr); /* in scan.c */
bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); /* in dev.c */
void clrerror(int func); /* in dev.c */
- boffset_t lseek(DCR *dcr, boffset_t offset, int whence); /* in dev.c */
- bool update_pos(DCR *dcr); /* in dev.c */
void set_slot(int32_t slot); /* in dev.c */
void clear_slot(); /* in dev.c */
int fd() const { return m_fd; };
/* low level operations */
- void init_backend();
- int (*d_open)(const char *pathname, int flags, ...);
- int (*d_close)(int fd);
- int (*d_ioctl)(int fd, ioctl_req_t request, ...);
- ssize_t (*d_read)(int fd, void *buffer, size_t count);
- ssize_t (*d_write)(int fd, const void *buffer, size_t count);
-
+ virtual int d_ioctl(int fd, ioctl_req_t request, char *mt_com=NULL);
+ virtual int d_open(const char *pathname, int flags);
+ virtual int d_close(int fd);
+ virtual ssize_t d_read(int fd, void *buffer, size_t count);
+ virtual ssize_t d_write(int fd, const void *buffer, size_t count);
+ virtual boffset_t lseek(DCR *dcr, boffset_t offset, int whence);
+ virtual bool update_pos(DCR *dcr);
+ virtual bool rewind(DCR *dcr);
+ virtual bool truncate(DCR *dcr);
+ virtual void open_device(DCR *dcr, int omode);
/*
* Locking and blocking calls
*/
#ifdef SD_DEBUG_LOCK
- void _r_dlock(const char *, int, bool locked=false); /* in lock.c */
- void _r_dunlock(const char *, int); /* in lock.c */
- void _dlock(const char *, int); /* in lock.c */
- void _dunlock(const char *, int); /* in lock.c */
+ void dbg_rLock(const char *, int, bool locked=false); /* in lock.c */
+ void dbg_rUnlock(const char *, int); /* in lock.c */
+ void dbg_Lock(const char *, int); /* in lock.c */
+ void dbg_Unlock(const char *, int); /* in lock.c */
+ void dbg_Lock_acquire(const char *, int); /* in lock.c */
+ void dbg_Unlock_acquire(const char *, int); /* in lock.c */
+ void dbg_Lock_read_acquire(const char *, int); /* in lock.c */
+ void dbg_Unlock_read_acquire(const char *, int); /* in lock.c */
#else
- void r_dlock(bool locked=false); /* in lock.c */
- void r_dunlock() { dunlock(); }
- void dlock() { P(m_mutex); }
- void dunlock() { V(m_mutex); }
+ void rLock(bool locked=false); /* in lock.c */
+ void rUnlock(); /* in lock.c */
+ void Lock(); /* in lock.c */
+ void Unlock(); /* in lock.c */
+ void Lock_acquire(); /* in lock.c */
+ void Unlock_acquire(); /* in lock.c */
+ void Lock_read_acquire(); /* in lock.c */
+ void Unlock_read_acquire(); /* in lock.c */
+ void Lock_VolCatInfo(); /* in lock.c */
+ void Unlock_VolCatInfo(); /* in lock.c */
#endif
+ int init_mutex(); /* in lock.c */
+ int init_acquire_mutex(); /* in lock.c */
+ int init_read_acquire_mutex(); /* in lock.c */
+ int init_volcat_mutex(); /* in lock.c */
+ int init_adata_mutex(); /* in lock.c */
+ void set_mutex_priorities(); /* in lock.c */
+ int next_vol_timedwait(const struct timespec *timeout); /* in lock.c */
void dblock(int why); /* in lock.c */
void dunblock(bool locked=false); /* in lock.c */
bool is_device_unmounted(); /* in lock.c */
void set_mode(int omode); /* in dev.c */
void open_tape_device(DCR *dcr, int omode); /* in dev.c */
void open_file_device(DCR *dcr, int omode); /* in dev.c */
- void open_dvd_device(DCR *dcr, int omode); /* in dev.c */
};
inline const char *DEVICE::strerror() const { return errmsg; }
inline const char *DEVICE::archive_name() const { return dev_name; }
inline const char *DEVICE::print_name() const { return prt_name; }
+
+#define CHECK_BLOCK_NUMBERS true
+#define NO_BLOCK_NUMBER_CHECK false
+
/*
* Device Context (or Control) Record.
* There is one of these records for each Job that is using
class DCR {
private:
bool m_dev_locked; /* set if dev already locked */
+ int m_dev_lock; /* non-zero if rLock already called */
bool m_reserved; /* set if reserved device */
bool m_found_in_use; /* set if a volume found in use */
dlink dev_link; /* link to attach to dev */
JCR *jcr; /* pointer to JCR */
bthread_mutex_t m_mutex; /* access control */
+ pthread_mutex_t r_mutex; /* rLock pre-mutex */
DEVICE * volatile dev; /* pointer to device */
DEVRES *device; /* pointer to device resource */
DEV_BLOCK *block; /* pointer to block */
VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */
/* Methods */
+ void set_dev(DEVICE *ndev) { dev = ndev; };
+ void inc_dev_lock() { m_dev_lock++; };
+ void dec_dev_lock() { m_dev_lock--; };
bool found_in_use() const { return m_found_in_use; };
void set_found_in_use() { m_found_in_use = true; };
void clear_found_in_use() { m_found_in_use = false; };
bool is_reserved() const { return m_reserved; };
bool is_dev_locked() { return m_dev_locked; }
-#ifdef SD_DEBUG_LOCK
- void _dlock(const char *, int); /* in lock.c */
- void _dunlock(const char *, int); /* in lock.c */
-#else
- void dlock() { dev->dlock(); m_dev_locked = true; }
- void dunlock() { m_dev_locked = false; dev->dunlock(); }
-#endif
- void dblock(int why) { dev->dblock(why); }
void setVolCatInfo(bool valid) { VolCatInfo.is_valid = valid; };
bool haveVolCatInfo() const { return VolCatInfo.is_valid; };
void setVolCatName(const char *name) {
};
char *getVolCatName() { return VolCatInfo.VolCatName; };
+ /* Methods in lock.c */
+ void dblock(int why) { dev->dblock(why); }
+#ifdef SD_DEBUG_LOCK
+ void dbg_mLock(const char *, int, bool locked); /* in lock.c */
+ void dbg_mUnlock(const char *, int); /* in lock.c */
+#else
+ void mLock(bool locked);
+ void mUnlock();
+#endif
+
+ /* Methods in record.c */
+ bool write_record(DEV_RECORD *rec);
/* Methods in reserve.c */
void clear_reserved();
bool do_unload();
bool do_load(bool is_writing);
bool is_tape_position_ok();
+
+ /* Methods in block.c */
+ bool write_block_to_device();
+ bool write_block_to_dev();
+ bool read_block_from_device(bool check_block_numbers);
+ bool read_block_from_dev(bool check_block_numbers);
+
+ /* Methods in label.c */
+ bool rewrite_volume_label(bool recycle);
+
};
/*