Dmsg1(300, "Write block of %u bytes\n", wlen);
if ((uint32_t)(stat=write(dev->fd, block->buf, (size_t)wlen)) != wlen) {
/* We should check for errno == ENOSPC, BUT many
- * devices simply report EIO when it is full.
- * with a little more thought we may be able to check
+ * devices simply report EIO when the volume is full.
+ * With a little more thought we may be able to check
* capacity and distinguish real errors and EOT
* conditions. In any case, we probably want to
* simulate an End of Medium.
*/
- clrerror_dev(dev, -1);
-
- if (dev->dev_errno == 0) {
- dev->dev_errno = ENOSPC; /* out of space */
- }
-
- Dmsg4(10, "=== Write error. size=%u rtn=%d errno=%d: ERR=%s\n",
- wlen, stat, dev->dev_errno, strerror(dev->dev_errno));
-
if (stat == -1) {
+ clrerror_dev(dev, -1);
+ if (dev->dev_errno == 0) {
+ dev->dev_errno = ENOSPC; /* out of space */
+ }
Jmsg(jcr, M_ERROR, 0, _("Write error on device %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
} else {
+ dev->dev_errno = ENOSPC; /* out of space */
Jmsg3(jcr, M_INFO, 0, _("End of medium on device %s. Write of %u bytes got %d.\n"),
dev->dev_name, wlen, stat);
}
+
+ Dmsg4(10, "=== Write error. size=%u rtn=%d errno=%d: ERR=%s\n",
+ wlen, stat, dev->dev_errno, strerror(dev->dev_errno));
+
block->write_failed = true;
dev->EndBlock = dev->block_num;
dev->EndFile = dev->file;
dev->block_num++;
block->BlockNumber++;
-
Dmsg2(190, "write_block: wrote block %d bytes=%d\n", dev->block_num,
wlen);
empty_block(block);
static void rrcmd();
static void eodcmd();
static void fillcmd();
+static void qfillcmd();
static void statcmd();
static void unfillcmd();
static int flush_block(DEV_BLOCK *block, int dump);
int blocks, tot_blocks, tot_files;
int block_size;
uint64_t bytes;
+ char ec1[50];
blocks = block_size = tot_blocks = 0;
}
update_pos_dev(dev);
tot_files = dev->file - tot_files;
- printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
+ printf("Total files=%d, blocks=%d, bytes = %s\n", tot_files, tot_blocks,
+ edit_uint64_with_commas(bytes, ec1));
}
uint32_t block_size;
uint64_t bytes;
DEV_BLOCK *block;
+ char ec1[50];
block = new_block(dev);
blocks = block_size = tot_blocks = 0;
bail_out:
free_block(block);
tot_files = dev->file - tot_files;
- printf("Total files=%d, blocks=%d, bytes = %" lld "\n", tot_files, tot_blocks, bytes);
+ printf("Total files=%d, blocks=%d, bytes = %s\n", tot_files, tot_blocks,
+ edit_uint64_with_commas(bytes, ec1));
}
Pmsg0(000, _("Done with reread of fill data.\n"));
}
-
/*
* We are called here from "unfill" for each record on the tape.
*/
}
+/*
+ * First we label the tape, then we fill
+ * it with data get a new tape and write a few blocks.
+ */
+static void qfillcmd()
+{
+ DEV_BLOCK *block;
+ DEV_RECORD *rec;
+ int i, count;
+
+ Pmsg0(0, "Test writing blocks of 64512 bytes to tape.\n");
+
+ get_cmd("How many blocks do you want to write? (1000): ");
+
+ count = atoi(cmd);
+ if (count <= 0) {
+ count = 1000;
+ }
+
+ sm_check(__FILE__, __LINE__, False);
+ block = new_block(dev);
+ rec = new_record();
+
+ i = block->buf_len - 100;
+ ASSERT (i > 0);
+ rec->data = check_pool_memory_size(rec->data, i);
+ memset(rec->data, i & 0xFF, i);
+ rec->data_len = i;
+ rewindcmd();
+ Pmsg1(0, "Begin writing %d blocks to tape ...\n", count);
+ for (i=0; i < count; i++) {
+ if (i % 100 == 0) {
+ printf("+");
+ }
+ if (!write_record_to_block(block, rec)) {
+ Pmsg0(0, _("Error writing record to block.\n"));
+ goto bail_out;
+ }
+ if (!write_block_to_dev(jcr, dev, block)) {
+ Pmsg0(0, _("Error writing block to device.\n"));
+ goto bail_out;
+ }
+ }
+ printf("\n");
+ weofcmd();
+ weofcmd();
+ rewindcmd();
+ scan_blocks();
+
+bail_out:
+ sm_check(__FILE__, __LINE__, False);
+ free_record(rec);
+ free_block(block);
+ sm_check(__FILE__, __LINE__, False);
+
+}
+
+
+
struct cmdstruct { char *key; void (*func)(); char *help; };
static struct cmdstruct commands[] = {
{"bsf", bsfcmd, "backspace file"},
{"weof", weofcmd, "write an EOF on the tape"},
{"wr", wrcmd, "write a single Bacula block"},
{"rr", rrcmd, "read a single record"},
+ {"qfill", qfillcmd, "quick fill command"},
};
#define comsize (sizeof(commands)/sizeof(struct cmdstruct))
}
if (errno == ENOTTY || errno == ENOSYS) { /* Function not implemented */
switch (func) {
- case -1:
- Emsg0(M_ABORT, 0, "Got ENOTTY on read/write!\n");
- break;
- case MTWEOF:
- msg = "WTWEOF";
- dev->capabilities &= ~CAP_EOF; /* turn off feature */
- break;
+ case -1:
+ Emsg0(M_ABORT, 0, "Got ENOTTY on read/write!\n");
+ break;
+ case MTWEOF:
+ msg = "WTWEOF";
+ dev->capabilities &= ~CAP_EOF; /* turn off feature */
+ break;
#ifdef MTEOM
- case MTEOM:
- msg = "WTEOM";
- dev->capabilities &= ~CAP_EOM; /* turn off feature */
- break;
+ case MTEOM:
+ msg = "WTEOM";
+ dev->capabilities &= ~CAP_EOM; /* turn off feature */
+ break;
#endif
- case MTFSF:
- msg = "MTFSF";
- dev->capabilities &= ~CAP_FSF; /* turn off feature */
- break;
- case MTBSF:
- msg = "MTBSF";
- dev->capabilities &= ~CAP_BSF; /* turn off feature */
- break;
- case MTFSR:
- msg = "MTFSR";
- dev->capabilities &= ~CAP_FSR; /* turn off feature */
- break;
- case MTBSR:
- msg = "MTBSR";
- dev->capabilities &= ~CAP_BSR; /* turn off feature */
- break;
- default:
- msg = "Unknown";
- break;
+ case MTFSF:
+ msg = "MTFSF";
+ dev->capabilities &= ~CAP_FSF; /* turn off feature */
+ break;
+ case MTBSF:
+ msg = "MTBSF";
+ dev->capabilities &= ~CAP_BSF; /* turn off feature */
+ break;
+ case MTFSR:
+ msg = "MTFSR";
+ dev->capabilities &= ~CAP_FSR; /* turn off feature */
+ break;
+ case MTBSR:
+ msg = "MTBSR";
+ dev->capabilities &= ~CAP_BSR; /* turn off feature */
+ break;
+ default:
+ msg = "Unknown";
+ break;
}
if (msg != NULL) {
dev->dev_errno = ENOSYS;
#define block_device(d, s) _block_device(__FILE__, __LINE__, (d), s)
#define unblock_device(d) _unblock_device(__FILE__, __LINE__, (d))
#define steal_device_lock(d, p, s) _steal_device_lock(__FILE__, __LINE__, (d), (p), s)
-#define return_device_lock(d, p) _return_device_lock(__FILE__, __LINE__, (d), (p))
+#define give_back_device_lock(d, p) _give_back_device_lock(__FILE__, __LINE__, (d), (p))
/* Arguments to open_dev() */
#define READ_WRITE 0
* Enter with device blocked by us but not locked
* Exit with device locked, and blocked by previous owner
*/
-void _return_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
+void _give_back_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
{
Dmsg4(100, "return lock. old=%d new=%d from %s:%d\n",
dev->dev_blocked, hold->dev_blocked, file, line);
dev->dev_blocked = hold->dev_blocked;
dev->no_wait_id = hold->no_wait_id;
}
-
/* See what we have for a Volume */
switch (read_dev_volume_label(jcr, dev, block)) {
- case VOL_NAME_ERROR:
- case VOL_VERSION_ERROR:
- case VOL_LABEL_ERROR:
- case VOL_OK:
- if (!relabel) {
- bnet_fsend(dir, _(
- "3911 Cannot label Volume because it is already labeled: %s\n"),
- dev->VolHdr.VolName);
- break;
- }
- /* Relabel request. If oldname matches, continue */
- if (strcmp(oldname, dev->VolHdr.VolName) != 0) {
- bnet_fsend(dir, _("Wrong volume mounted.\n"));
- break;
- }
- /* Fall through wanted! */
- case VOL_IO_ERROR:
- case VOL_NO_LABEL:
- if (!write_volume_label_to_dev(jcr, jcr->device, newname, poolname)) {
- bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
- break;
- }
- strcpy(jcr->VolumeName, newname);
- bnet_fsend(dir, _("3000 OK label. Volume=%s Device=%s\n"),
- newname, dev->dev_name);
+ case VOL_NAME_ERROR:
+ case VOL_VERSION_ERROR:
+ case VOL_LABEL_ERROR:
+ case VOL_OK:
+ if (!relabel) {
+ bnet_fsend(dir, _(
+ "3911 Cannot label Volume because it is already labeled: %s\n"),
+ dev->VolHdr.VolName);
+ break;
+ }
+ /* Relabel request. If oldname matches, continue */
+ if (strcmp(oldname, dev->VolHdr.VolName) != 0) {
+ bnet_fsend(dir, _("Wrong volume mounted.\n"));
break;
- case VOL_NO_MEDIA:
+ }
+ /* Fall through wanted! */
+ case VOL_IO_ERROR:
+ case VOL_NO_LABEL:
+ if (!write_volume_label_to_dev(jcr, jcr->device, newname, poolname)) {
bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
break;
- default:
- bnet_fsend(dir, _("3913 Cannot label Volume. \
+ }
+ strcpy(jcr->VolumeName, newname);
+ bnet_fsend(dir, _("3000 OK label. Volume=%s Device=%s\n"),
+ newname, dev->dev_name);
+ break;
+ case VOL_NO_MEDIA:
+ bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
+ break;
+ default:
+ bnet_fsend(dir, _("3913 Cannot label Volume. \
Unknown status %d from read_volume_label()\n"), jcr->label_status);
- break;
+ break;
}
bail_out:
free_block(block);
- return_device_lock(dev, &hold);
+ give_back_device_lock(dev, &hold);
+
+ return;
}
block = new_block(dev);
dev->state &= ~ST_LABEL; /* force read of label */
switch (read_dev_volume_label(jcr, dev, block)) {
- case VOL_OK:
- bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolName);
- stat = 1;
- break;
- default:
- bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s\n"),
- dev->dev_name, jcr->errmsg);
- stat = 0;
- break;
+ case VOL_OK:
+ bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolName);
+ stat = 1;
+ break;
+ default:
+ bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s\n"),
+ dev->dev_name, jcr->errmsg);
+ stat = 0;
+ break;
}
free_block(block);
- return_device_lock(dev, &hold);
+ give_back_device_lock(dev, &hold);
return stat;
}
P(dev->mutex); /* Use P to avoid indefinite block */
switch (dev->dev_blocked) { /* device blocked? */
DEV_BLOCK *block;
- case BST_WAITING_FOR_SYSOP:
- /* Someone is waiting, wake him */
- Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
+ case BST_WAITING_FOR_SYSOP:
+ /* Someone is waiting, wake him */
+ Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
+ dev->dev_blocked = BST_MOUNT;
+ pthread_cond_signal(&dev->wait_next_vol);
+ bnet_fsend(dir, "3001 OK mount. Device=%s\n", dev->dev_name);
+ break;
+
+ case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+ case BST_UNMOUNTED:
+ /* We freed the device, so reopen it and wake any waiting threads */
+ if (open_dev(dev, NULL, READ_WRITE) < 0) {
+ bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
+ strerror_dev(dev));
+ break;
+ }
+ block = new_block(dev);
+ read_dev_volume_label(jcr, dev, block);
+ free_block(block);
+ if (dev->dev_blocked == BST_UNMOUNTED) {
+ Dmsg0(100, "Unmounted. Unblocking device\n");
+ read_label(jcr, dev);
+ unblock_device(dev);
+ } else {
+ Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
dev->dev_blocked = BST_MOUNT;
pthread_cond_signal(&dev->wait_next_vol);
- bnet_fsend(dir, "3001 OK mount. Device=%s\n", dev->dev_name);
- break;
+ }
+ if (dev->state & ST_LABEL) {
+ bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
+ dev->dev_name, dev->VolHdr.VolName);
+ } else {
+ bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
+ "Try unmounting and remounting the Volume.\n"),
+ dev->dev_name);
+ }
+ break;
+
+ case BST_DOING_ACQUIRE:
+ bnet_fsend(dir, _("3001 Device %s is mounted; doing acquire.\n"),
+ dev->dev_name);
+ break;
- case BST_UNMOUNTED_WAITING_FOR_SYSOP:
- case BST_UNMOUNTED:
- /* We freed the device, so reopen it and wake any waiting threads */
+ case BST_WRITING_LABEL:
+ bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), dev->dev_name);
+ break;
+
+ case BST_NOT_BLOCKED:
+ if (dev->state & ST_OPENED) {
+ if (dev->state & ST_LABEL) {
+ bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
+ dev->dev_name, dev->VolHdr.VolName);
+ } else {
+ bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
+ "Try unmounting and remounting the Volume.\n"),
+ dev->dev_name);
+ }
+ } else {
+ if (!dev_is_tape(dev)) {
+ bnet_fsend(dir, _("3906 cannot mount non-tape.\n"));
+ break;
+ }
if (open_dev(dev, NULL, READ_WRITE) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
strerror_dev(dev));
break;
}
- block = new_block(dev);
- read_dev_volume_label(jcr, dev, block);
- free_block(block);
- if (dev->dev_blocked == BST_UNMOUNTED) {
- Dmsg0(100, "Unmounted. Unblocking device\n");
- read_label(jcr, dev);
- unblock_device(dev);
- } else {
- Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
- dev->dev_blocked = BST_MOUNT;
- pthread_cond_signal(&dev->wait_next_vol);
- }
+ read_label(jcr, dev);
if (dev->state & ST_LABEL) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
dev->dev_name, dev->VolHdr.VolName);
"Try unmounting and remounting the Volume.\n"),
dev->dev_name);
}
- break;
-
- case BST_DOING_ACQUIRE:
- bnet_fsend(dir, _("3001 Device %s is mounted; doing acquire.\n"),
- dev->dev_name);
- break;
-
- case BST_WRITING_LABEL:
- bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), dev->dev_name);
- break;
-
- case BST_NOT_BLOCKED:
- if (dev->state & ST_OPENED) {
- if (dev->state & ST_LABEL) {
- bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
- dev->dev_name, dev->VolHdr.VolName);
- } else {
- bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
- "Try unmounting and remounting the Volume.\n"),
- dev->dev_name);
- }
- } else {
- if (!dev_is_tape(dev)) {
- bnet_fsend(dir, _("3906 cannot mount non-tape.\n"));
- break;
- }
- if (open_dev(dev, NULL, READ_WRITE) < 0) {
- bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
- strerror_dev(dev));
- break;
- }
- read_label(jcr, dev);
- if (dev->state & ST_LABEL) {
- bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
- dev->dev_name, dev->VolHdr.VolName);
- } else {
- bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
- "Try unmounting and remounting the Volume.\n"),
- dev->dev_name);
- }
- }
- break;
+ }
+ break;
- default:
- bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
- break;
+ default:
+ bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
+ break;
}
V(dev->mutex);
} else {
} else { /* device not being used */
Dmsg0(90, "Device not in use, unmounting\n");
- block_device(dev, BST_UNMOUNTED);
+ /* On FreeBSD, I am having ASSERT() failures in block_device()
+ * and I can only imagine that the thread id that we are
+ * leaving in no_wait_id is being re-used. So here,
+ * we simply do it by hand. Gross, but maybe a solutions
+ */
+ /* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
+ dev->dev_blocked = BST_UNMOUNTED;
+ dev->no_wait_id = 0;
open_dev(dev, NULL, 0); /* fake open for close */
offline_or_rewind_dev(dev);
force_close_dev(dev);
uint32_t new_VolSessionId();
/* From acquire.c */
-DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int release_device(JCR *jcr, DEVICE *dev);
+DEVICE *acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int release_device(JCR *jcr, DEVICE *dev);
/* From askdir.c */
-int dir_get_volume_info(JCR *jcr, int writing);
-int dir_find_next_appendable_volume(JCR *jcr);
-int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
-int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
-int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
-int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
-int dir_send_job_status(JCR *jcr);
-int dir_create_jobmedia_record(JCR *jcr);
+int dir_get_volume_info(JCR *jcr, int writing);
+int dir_find_next_appendable_volume(JCR *jcr);
+int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel);
+int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev);
+int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev);
+int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec);
+int dir_send_job_status(JCR *jcr);
+int dir_create_jobmedia_record(JCR *jcr);
/* authenticate.c */
-int authenticate_director(JCR *jcr);
-int authenticate_filed(JCR *jcr);
+int authenticate_director(JCR *jcr);
+int authenticate_filed(JCR *jcr);
/* From block.c */
-void dump_block(DEV_BLOCK *b, char *msg);
+void dump_block(DEV_BLOCK *b, char *msg);
DEV_BLOCK *new_block(DEVICE *dev);
-void init_block_write(DEV_BLOCK *block);
-void empty_block(DEV_BLOCK *block);
-void free_block(DEV_BLOCK *block);
-int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void init_block_write(DEV_BLOCK *block);
+void empty_block(DEV_BLOCK *block);
+void free_block(DEV_BLOCK *block);
+int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
#define CHECK_BLOCK_NUMBERS true
#define NO_BLOCK_NUMBER_CHECK false
-int read_block_from_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
-int read_block_from_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
+int read_block_from_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
+int read_block_from_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool check_block_numbers);
/* From butil.c -- utilities for SD tool programs */
-void print_ls_output(char *fname, char *link, int type, struct stat *statp);
+void print_ls_output(char *fname, char *link, int type, struct stat *statp);
JCR *setup_jcr(char *name, char *device, BSR *bsr, char *VolumeName);
DEVICE *setup_to_access_device(JCR *jcr, int read_access);
-void display_tape_error_status(JCR *jcr, DEVICE *dev);
+void display_tape_error_status(JCR *jcr, DEVICE *dev);
DEVRES *find_device_res(char *device_name, int read_access);
/* From dev.c */
-DEVICE *init_dev(DEVICE *dev, DEVRES *device);
-int open_dev(DEVICE *dev, char *VolName, int mode);
-void close_dev(DEVICE *dev);
-void force_close_dev(DEVICE *dev);
-int truncate_dev(DEVICE *dev);
-void term_dev(DEVICE *dev);
-char * strerror_dev(DEVICE *dev);
-void clrerror_dev(DEVICE *dev, int func);
-int update_pos_dev(DEVICE *dev);
-int rewind_dev(DEVICE *dev);
-int load_dev(DEVICE *dev);
-int offline_dev(DEVICE *dev);
-int flush_dev(DEVICE *dev);
-int weof_dev(DEVICE *dev, int num);
-int write_block(DEVICE *dev);
-int write_dev(DEVICE *dev, char *buf, size_t len);
-int read_dev(DEVICE *dev, char *buf, size_t len);
-int status_dev(DEVICE *dev, uint32_t *status);
-int eod_dev(DEVICE *dev);
-int fsf_dev(DEVICE *dev, int num);
-int fsr_dev(DEVICE *dev, int num);
-int bsf_dev(DEVICE *dev, int num);
-int bsr_dev(DEVICE *dev, int num);
-void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
-int dev_can_write(DEVICE *dev);
-int offline_or_rewind_dev(DEVICE *dev);
+DEVICE *init_dev(DEVICE *dev, DEVRES *device);
+int open_dev(DEVICE *dev, char *VolName, int mode);
+void close_dev(DEVICE *dev);
+void force_close_dev(DEVICE *dev);
+int truncate_dev(DEVICE *dev);
+void term_dev(DEVICE *dev);
+char * strerror_dev(DEVICE *dev);
+void clrerror_dev(DEVICE *dev, int func);
+int update_pos_dev(DEVICE *dev);
+int rewind_dev(DEVICE *dev);
+int load_dev(DEVICE *dev);
+int offline_dev(DEVICE *dev);
+int flush_dev(DEVICE *dev);
+int weof_dev(DEVICE *dev, int num);
+int write_block(DEVICE *dev);
+int write_dev(DEVICE *dev, char *buf, size_t len);
+int read_dev(DEVICE *dev, char *buf, size_t len);
+int status_dev(DEVICE *dev, uint32_t *status);
+int eod_dev(DEVICE *dev);
+int fsf_dev(DEVICE *dev, int num);
+int fsr_dev(DEVICE *dev, int num);
+int bsf_dev(DEVICE *dev, int num);
+int bsr_dev(DEVICE *dev, int num);
+void attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR *next_attached_jcr(DEVICE *dev, JCR *jcr);
+int dev_can_write(DEVICE *dev);
+int offline_or_rewind_dev(DEVICE *dev);
/* Get info about device */
-char * dev_name(DEVICE *dev);
-char * dev_vol_name(DEVICE *dev);
+char * dev_name(DEVICE *dev);
+char * dev_vol_name(DEVICE *dev);
uint32_t dev_block(DEVICE *dev);
uint32_t dev_file(DEVICE *dev);
-int dev_is_tape(DEVICE *dev);
+int dev_is_tape(DEVICE *dev);
/* From device.c */
-int open_device(DEVICE *dev);
-int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int open_device(DEVICE *dev);
+int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
void _lock_device(char *file, int line, DEVICE *dev);
void _unlock_device(char *file, int line, DEVICE *dev);
void _block_device(char *file, int line, DEVICE *dev, int state);
void _unblock_device(char *file, int line, DEVICE *dev);
void _steal_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
-void _return_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
-
-/* don't use */
-void _new_lock_device(char *file, int line, DEVICE *dev);
-void _new_lock_device(char *file, int line, DEVICE *dev, int state);
-void _new_unlock_device(char *file, int line, DEVICE *dev);
-void new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state);
-void new_return_device_lock(DEVICE *dev, brwsteal_t *hold);
+void _give_back_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
/* From dircmd.c */
-void *connection_request(void *arg);
+void *connection_request(void *arg);
/* From fd_cmds.c */
-void run_job(JCR *jcr);
+void run_job(JCR *jcr);
/* From job.c */
-void stored_free_jcr(JCR *jcr);
-void connection_from_filed(void *arg);
-void handle_filed_connection(BSOCK *fd, char *job_name);
+void stored_free_jcr(JCR *jcr);
+void connection_from_filed(void *arg);
+void handle_filed_connection(BSOCK *fd, char *job_name);
/* From label.c */
-int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
-void create_volume_label(DEVICE *dev, char *VolName);
-int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
-int write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
-int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
-void dump_volume_label(DEVICE *dev);
-void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-int unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void create_session_label(JCR *jcr, DEV_RECORD *rec, int label);
+void create_volume_label(DEVICE *dev, char *VolName);
+int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName);
+int write_session_label(JCR *jcr, DEV_BLOCK *block, int label);
+int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+void dump_volume_label(DEVICE *dev);
+void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+int unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
/* From match_bsr.c */
int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
- SESSION_LABEL *sesrec);
+ SESSION_LABEL *sesrec);
/* From mount.c */
-int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release);
-int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
+int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release);
+int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
/* From autochanger.c */
-int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir);
-int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir);
-void invalidate_slot_in_catalog(JCR *jcr);
+int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir);
+int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir);
+void invalidate_slot_in_catalog(JCR *jcr);
/* From parse_bsr.c */
/* From record.c */
char *FI_to_ascii(int fi);
char *stream_to_ascii(int stream, int fi);
-int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
DEV_RECORD *new_record();
-void free_record(DEV_RECORD *rec);
+void free_record(DEV_RECORD *rec);
/* From read_record.c */
int read_records(JCR *jcr, DEVICE *dev,
/* */
#define VERSION "1.31"
#define VSTRING "1"
-#define BDATE "02 Jun 2003"
-#define LSMDATE "02Jun03"
+#define BDATE "03 Jun 2003"
+#define LSMDATE "03Jun03"
/* Debug flags */
#define DEBUG 1