Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License
+ version 2 as amended with additional clauses defined in the
+ file LICENSE in the main source directory.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
/* Arguments to open_dev() */
enum {
- OPEN_READ_WRITE = 0,
+ CREATE_READ_WRITE = 1,
+ OPEN_READ_WRITE,
OPEN_READ_ONLY,
OPEN_WRITE_ONLY
};
#define ST_NEXTVOL (1<<13) /* Start writing on next volume */
#define ST_SHORT (1<<14) /* Short block read */
#define ST_MOUNTED (1<<15) /* the device is mounted to the mount point */
-#define ST_OFFLINE (1<<16) /* set offline by operator */
+#define ST_MEDIA (1<<16) /* Media found in mounted device */
+#define ST_OFFLINE (1<<17) /* set offline by operator */
+#define ST_PART_SPOOLED (1<<18) /* spooling part */
/* dev_blocked states (mutually exclusive) */
enum {
int weof_dev(DEVICE *dev, int num);
bool rewind_dev(DEVICE *dev);
+class DCR; /* forward reference */
/*
* Device structure definition. There is one of these for
* each physical device. Everything here is "global" to
/* New access control in process of being implemented */
brwlock_t lock; /* New mutual exclusion lock */
- int use_count; /* usage count on this device */
+ int use_count; /* usage count on this device 0 or 1 */
int fd; /* file descriptor */
int capabilities; /* capabilities mask */
int state; /* state mask */
int mode; /* read/write modes */
int openmode; /* parameter passed to open_dev (useful to reopen the device) */
bool autoselect; /* Autoselect in autochanger */
+ bool open_nowait; /* If set, don't wait on open */
int label_type; /* Bacula/ANSI/IBM label types */
- uint32_t drive_index; /* Autochanger drive index */
+ uint32_t drive_index; /* Autochanger drive index (base 0) */
+ int32_t Slot; /* Slot currently in drive (base 1) */
POOLMEM *dev_name; /* Physical device name */
POOLMEM *prt_name; /* Name used for display purposes */
char *errmsg; /* nicely edited error message */
uint64_t max_file_size; /* max file size to put in one file on volume */
uint64_t volume_capacity; /* advisory capacity */
uint64_t max_spool_size; /* maximum spool file size */
- uint64_t spool_size; /* current spool size */
+ uint64_t spool_size; /* current spool size for this device */
uint32_t max_rewind_wait; /* max secs to allow for rewind */
uint32_t max_open_wait; /* max secs to allow for open */
uint32_t max_open_vols; /* max simultaneous open volumes */
uint64_t max_part_size; /* max part size */
uint64_t part_size; /* current part size */
- uint32_t part; /* current part number */
+ uint32_t part; /* current part number (starts at 0) */
uint64_t part_start; /* current part start address (relative to the whole volume) */
- uint32_t num_parts; /* number of parts (total) */
+ uint32_t num_parts; /* number of parts WRITTEN on the DVD */
uint64_t free_space; /* current free space on medium (without the current part) */
int free_space_errno; /* indicates:
* - free_space_errno == 0: ignore free_space.
* - free_space_errno < 0: an error occured.
* - free_space_errno > 0: free_space is valid. */
+ bool truncating; /* if set, we are currently truncating the DVD */
+
utime_t vol_poll_interval; /* interval between polling Vol mount */
DEVRES *device; /* pointer to Device Resource */
VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */
VOLUME_LABEL VolHdr; /* Actual volume label */
- uint64_t PoolId; /* DB PoolId */
char pool_name[MAX_NAME_LENGTH]; /* pool name */
char pool_type[MAX_NAME_LENGTH]; /* pool type */
int num_wait;
/* Methods */
- int is_tape() const;
- int is_file() const;
- int is_fifo() const;
- int is_dvd() const;
- int is_open() const;
- int is_offline() const;
- int is_labeled() const;
- int is_busy() const; /* either reading or writing */
- int at_eof() const;
- int at_eom() const;
- int at_eot() const;
- int can_append() const;
- int can_read() const;
+ int is_autochanger() const { return capabilities & CAP_AUTOCHANGER; }
+ int requires_mount() const { return capabilities & CAP_REQMOUNT; }
+ int is_tape() const { return state & ST_TAPE; }
+ int is_file() const { return state & ST_FILE; }
+ int is_fifo() const { return state & ST_FIFO; }
+ int is_dvd() const { return state & ST_DVD; }
+ int is_open() const { return state & ST_OPENED; }
+ int is_offline() const { return state & ST_OFFLINE; }
+ int is_labeled() const { return state & ST_LABEL; }
+ int is_mounted() const { return state & ST_MOUNTED; }
+ int is_part_spooled() const { return state & ST_PART_SPOOLED; }
+ int have_media() const { return state & ST_MEDIA; }
+ int is_short_block() const { return state & ST_SHORT; }
+ int is_busy() const { return (state & ST_READ) || num_writers || reserved_device; }
+ int at_eof() const { return state & ST_EOF; }
+ int at_eot() const { return state & ST_EOT; }
+ int at_weot() const { return state & ST_WEOT; }
+ int can_append() const { return state & ST_APPEND; }
+ /*
+ * can_write() is meant for checking at the end of a job to see
+ * if we still have a tape (perhaps not if at end of tape
+ * and the job is canceled).
+ */
+ int can_write() const { return is_open() && can_append() &&
+ is_labeled() && !at_weot(); }
+ int can_read() const { return state & ST_READ; }
bool can_steal_lock() const { return dev_blocked &&
(dev_blocked == BST_UNMOUNTED ||
dev_blocked == BST_WAITING_FOR_SYSOP ||
dev_blocked == BST_WAITING_FOR_SYSOP ||
dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); };
bool weof() { return !weof_dev(this, 1); };
+ bool fsr(int num); /* in dev.c */
+ bool fsf(int num); /* in dev.c */
bool rewind() { return rewind_dev(this); };
const char *strerror() const;
const char *archive_name() const;
const char *name() const;
const char *print_name() const; /* Name for display purposes */
- void set_eof(); /* in dev.c */
- void set_eot(); /* in dev.c */
+ void set_ateof(); /* in dev.c */
+ void set_ateot(); /* in dev.c */
+ void set_eot() { state |= ST_EOT; };
+ void set_eof() { state |= ST_EOF; };
void set_append() { state |= ST_APPEND; };
- void set_label() { state |= ST_LABEL; };
+ void set_labeled() { state |= ST_LABEL; };
void set_read() { state |= ST_READ; };
void set_offline() { state |= ST_OFFLINE; };
+ void set_opened() { state |= ST_OPENED; };
+ void set_mounted() { state |= ST_MOUNTED; };
+ void set_media() { state |= ST_MEDIA; };
+ void set_short_block() { state |= ST_SHORT; };
+ void set_part_spooled(int val) { if (val) state |= ST_PART_SPOOLED; \
+ else state &= ~ST_PART_SPOOLED; };
+ void set_mounted(int val) { if (val) state |= ST_MOUNTED; \
+ else state &= ~ST_MOUNTED; };
void clear_append() { state &= ~ST_APPEND; };
void clear_read() { state &= ~ST_READ; };
- void clear_label() { state &= ~ST_LABEL; };
+ void clear_labeled() { state &= ~ST_LABEL; };
void clear_offline() { state &= ~ST_OFFLINE; };
void clear_eot() { state &= ~ST_EOT; };
+ void clear_eof() { state &= ~ST_EOF; };
+ void clear_opened() { state &= ~ST_OPENED; };
+ void clear_mounted() { state &= ~ST_MOUNTED; };
+ void clear_media() { state &= ~ST_MEDIA; };
+ void clear_short_block() { state &= ~ST_SHORT; };
+
+ void block(int why); /* in dev.c */
+ void unblock(); /* in dev.c */
+ void close(); /* in dev.c */
+ int open(DCR *dcr, int mode); /* in dev.c */
+
+
+ void set_blocked(int block) { dev_blocked = block; };
+ int get_blocked() const { return dev_blocked; };
+ const char *print_blocked() const; /* in dev.c */
+ bool is_blocked() const { return dev_blocked != BST_NOT_BLOCKED; };
+
+private:
+ void set_mode(int omode); /* in dev.c */
+ void open_tape_device(DCR *dcr, int omode); /* in dev.c */
+ void open_file_device(int omode); /* in dev.c */
+ void open_dvd_device(DCR *dcr, int omode); /* in dev.c */
+
};
/* Note, these return int not bool! */
-inline int DEVICE::is_tape() const { return state & ST_TAPE; }
-inline int DEVICE::is_file() const { return state & ST_FILE; }
-inline int DEVICE::is_fifo() const { return state & ST_FIFO; }
-inline int DEVICE::is_dvd() const { return state & ST_DVD; }
-inline int DEVICE::is_open() const { return state & ST_OPENED; }
-inline int DEVICE::is_offline() const { return state & ST_OFFLINE; }
-inline int DEVICE::is_labeled() const { return state & ST_LABEL; }
-inline int DEVICE::is_busy() const { return state & ST_READ || num_writers || reserved_device; }
-inline int DEVICE::at_eof() const { return state & ST_EOF; }
-inline int DEVICE::at_eot() const { return state & ST_EOT; }
-inline int DEVICE::can_append() const { return state & ST_APPEND; }
-inline int DEVICE::can_read() const { return state & ST_READ; }
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; }
bool WroteVol; /* set if Volume written */
bool NewFile; /* set when EOF written */
bool reserved_device; /* set if reserve done */
+ bool any_volume; /* Any OK for dir_find_next... */
uint32_t VolFirstIndex; /* First file index this Volume */
uint32_t VolLastIndex; /* Last file index this Volume */
uint32_t FileIndex; /* Current File Index */
uint32_t StartFile; /* Start write file */
uint32_t StartBlock; /* Start write block */
uint32_t EndBlock; /* Ending block written */
- int64_t spool_size; /* Current spool size */
- int64_t max_spool_size; /* Max job spool size */
- uint64_t PoolId; /* PoolId from DB */
+ int64_t job_spool_size; /* Current job spool size */
+ int64_t max_job_spool_size; /* Max job spool size */
char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
char pool_name[MAX_NAME_LENGTH]; /* pool name */
char pool_type[MAX_NAME_LENGTH]; /* pool type */
char media_type[MAX_NAME_LENGTH]; /* media type */
char dev_name[MAX_NAME_LENGTH]; /* dev name */
+ int Copy; /* identical copy number */
+ int Stripe; /* RAIT stripe */
VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */
};
+/*
+ * Volume reservation class -- see reserve.c
+ */
+class VOLRES {
+public:
+ dlink link;
+ char *vol_name;
+ DEVICE *dev;
+ DCR *dcr;
+};
+
/* Get some definition of function to position
* to the end of the medium in MTEOM. System