From 94f101780514377a9a0ff64a495cfea37ddbfb0a Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 18 Jan 2003 12:19:20 +0000 Subject: [PATCH] Phase 1 -- FIFO storage device git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@304 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/acquire.c | 10 +- bacula/src/stored/askdir.c | 5 +- bacula/src/stored/block.c | 4 +- bacula/src/stored/dev.c | 24 +++-- bacula/src/stored/dev.h | 192 +++++++++++++++++++----------------- bacula/src/stored/dircmd.c | 6 +- bacula/src/stored/label.c | 107 +++++++++----------- bacula/src/stored/mount.c | 88 ++++++++++------- bacula/src/stored/protos.h | 155 ++++++++++++++--------------- bacula/src/stored/stored.c | 2 +- bacula/src/version.h | 4 +- 11 files changed, 313 insertions(+), 284 deletions(-) diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index dce2e54c69..42f7c1e2e3 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -6,7 +6,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2002-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -227,8 +227,8 @@ int release_device(JCR *jcr, DEVICE *dev) Dmsg1(100, "release_device device is %s\n", dev_is_tape(dev)?"tape":"disk"); if (dev->state & ST_READ) { dev->state &= ~ST_READ; /* clear read bit */ - if (!dev_is_tape(dev) || !(dev->capabilities & CAP_ALWAYSOPEN)) { - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } close_dev(dev); @@ -256,8 +256,8 @@ int release_device(JCR *jcr, DEVICE *dev) Dmsg0(200, "dir_update_vol_info. Release0\n"); dir_update_volume_info(jcr, &dev->VolCatInfo, 0); /* send Volume info to Director */ - if (!dev_is_tape(dev) || !(dev->capabilities & CAP_ALWAYSOPEN)) { - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } close_dev(dev); diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 1f9dfe812f..4f49443f51 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -98,7 +98,7 @@ static int do_request_volume_info(JCR *jcr) strcpy(jcr->VolumeName, vol->VolCatName); /* set desired VolumeName */ Dmsg2(200, "do_reqest_vol_info got slot=%d Volume=%s\n", - vol->Slot, vol->VolCatName); + vol->Slot, vol->VolCatName); return 1; } @@ -280,8 +280,7 @@ int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev) * removable media, return now, otherwise wait * for the operator to mount the media. */ - if (jcr->VolumeName[0] && !(dev->capabilities & CAP_REM) && - dev->capabilities & CAP_LABEL) { + if (jcr->VolumeName[0] && !dev_cap(dev, CAP_REM) && dev_cap(dev, CAP_LABEL)) { Dmsg0(190, "Return 1 from mount without wait.\n"); return 1; } diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 7652d6c6f1..53dfe824ec 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -9,7 +9,7 @@ * */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -399,7 +399,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) * then re-read it and verify that the block number is * correct. */ - if (dev->state & ST_TAPE && dev->capabilities & CAP_BSR) { + if (dev->state & ST_TAPE && dev_cap(dev, CAP_BSR)) { /* Now back up over what we wrote and read the last block */ if (bsf_dev(dev, 1) != 0 || bsf_dev(dev, 1) != 0) { diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 424936f4ee..695acd5541 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -29,7 +29,7 @@ * Version $Id$ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -224,7 +224,7 @@ open_dev(DEVICE *dev, char *VolName, int mode) dev->use_count++; Mmsg2(&dev->errmsg, _("WARNING!!!! device %s opened %d times!!!\n"), dev->dev_name, dev->use_count); - Emsg0(M_WARNING, 0, dev->errmsg); + Emsg1(M_WARNING, 0, "%s", dev->errmsg); return dev->fd; } if (VolName) { @@ -237,14 +237,22 @@ open_dev(DEVICE *dev, char *VolName, int mode) if (dev->state & (ST_TAPE|ST_FIFO)) { int timeout; Dmsg0(29, "open_dev: device is tape\n"); - if (mode == READ_WRITE) { + if (mode == OPEN_READ_WRITE) { dev->mode = O_RDWR | O_BINARY; - } else { + } else if (mode == OPEN_READ_ONLY) { dev->mode = O_RDONLY | O_BINARY; + } else if (mode == OPEN_WRITE_ONLY) { + dev->mode = O_WRONLY | O_BINARY; + } else { + Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n")); } timeout = dev->max_open_wait; errno = 0; + /* If busy retry each second for max_open_wait seconds */ while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) { + if (errno == EAGAIN) { + continue; + } if (errno == EBUSY && timeout-- > 0) { Dmsg2(100, "Device %s busy. ERR=%s\n", dev->dev_name, strerror(errno)); sleep(1); @@ -274,10 +282,14 @@ open_dev(DEVICE *dev, char *VolName, int mode) } pm_strcat(&archive_name, VolName); Dmsg1(29, "open_dev: device is disk %s\n", archive_name); - if (mode == READ_WRITE) { + if (mode == OPEN_READ_WRITE) { dev->mode = O_CREAT | O_RDWR | O_BINARY; - } else { + } else if (mode == OPEN_READ_ONLY) { dev->mode = O_RDONLY | O_BINARY; + } else if (mode == OPEN_WRITE_ONLY) { + dev->mode = O_WRONLY | O_BINARY; + } else { + Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n")); } if ((dev->fd = open(archive_name, dev->mode, MODE_RW)) < 0) { dev->dev_errno = errno; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 10ca3577d6..4ad06c7348 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -6,7 +6,7 @@ * */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,9 +31,9 @@ /* #define NEW_LOCK 1 */ -#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev)) +#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev)) #define new_lock_device_state(dev,state) _new_lock_device(__FILE__, __LINE__, (dev), (state)) -#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev)) +#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev)) #define lock_device(d) _lock_device(__FILE__, __LINE__, (d)) #define unlock_device(d) _unlock_device(__FILE__, __LINE__, (d)) @@ -45,57 +45,65 @@ /* Arguments to open_dev() */ #define READ_WRITE 0 #define READ_ONLY 1 +#define OPEN_READ_WRITE 0 +#define OPEN_READ_ONLY 1 +#define OPEN_WRITE_ONLY 2 /* Generic status bits returned from status_dev() */ -#define MT_TAPE (1<<0) /* is tape device */ -#define MT_EOF (1<<1) /* just read EOF */ -#define MT_BOT (1<<2) /* at beginning of tape */ -#define MT_EOT (1<<3) /* end of tape reached */ -#define MT_SM (1<<4) /* DDS setmark */ -#define MT_EOD (1<<5) /* DDS at end of data */ -#define MT_WR_PROT (1<<6) /* tape write protected */ -#define MT_ONLINE (1<<7) /* tape online */ -#define MT_DR_OPEN (1<<8) /* tape door open */ -#define MT_IM_REP_EN (1<<9) /* immediate report enabled */ +#define MT_TAPE (1<<0) /* is tape device */ +#define MT_EOF (1<<1) /* just read EOF */ +#define MT_BOT (1<<2) /* at beginning of tape */ +#define MT_EOT (1<<3) /* end of tape reached */ +#define MT_SM (1<<4) /* DDS setmark */ +#define MT_EOD (1<<5) /* DDS at end of data */ +#define MT_WR_PROT (1<<6) /* tape write protected */ +#define MT_ONLINE (1<<7) /* tape online */ +#define MT_DR_OPEN (1<<8) /* tape door open */ +#define MT_IM_REP_EN (1<<9) /* immediate report enabled */ +/* Test capabilities */ +#define dev_cap(dev, cap) ((dev)->capabilities & (cap)) + /* Bits for device capabilities */ -#define CAP_EOF 0x0001 /* has MTWEOF */ -#define CAP_BSR 0x0002 /* has MTBSR */ -#define CAP_BSF 0x0004 /* has MTBSF */ -#define CAP_FSR 0x0008 /* has MTFSR */ -#define CAP_FSF 0x0010 /* has MTFSF */ -#define CAP_EOM 0x0020 /* has MTEOM */ -#define CAP_REM 0x0040 /* is removable media */ -#define CAP_RACCESS 0x0080 /* is random access device */ -#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */ -#define CAP_LABEL 0x0200 /* Label blank tapes */ -#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */ -#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */ +#define CAP_EOF 0x0001 /* has MTWEOF */ +#define CAP_BSR 0x0002 /* has MTBSR */ +#define CAP_BSF 0x0004 /* has MTBSF */ +#define CAP_FSR 0x0008 /* has MTFSR */ +#define CAP_FSF 0x0010 /* has MTFSF */ +#define CAP_EOM 0x0020 /* has MTEOM */ +#define CAP_REM 0x0040 /* is removable media */ +#define CAP_RACCESS 0x0080 /* is random access device */ +#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */ +#define CAP_LABEL 0x0200 /* Label blank tapes */ +#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */ +#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */ #define CAP_AUTOCHANGER 0x1000 /* AutoChanger */ #define CAP_OFFLINEUNMOUNT 0x2000 /* Offline before unmount */ -#define CAP_STREAM 0x4000 /* Stream device */ +#define CAP_STREAM 0x4000 /* Stream device */ +/* Test state */ +#define dev_state(dev, state) ((dev)->state & (state)) /* Device state bits */ -#define ST_OPENED 0x0001 /* set when device opened */ -#define ST_TAPE 0x0002 /* is a tape device */ -#define ST_FILE 0x0004 /* is a file device */ -#define ST_FIFO 0x0008 /* is a fifo device */ -#define ST_PROG 0x0010 /* is a program device */ -#define ST_LABEL 0x0020 /* label found */ +#define ST_OPENED 0x0001 /* set when device opened */ +#define ST_TAPE 0x0002 /* is a tape device */ +#define ST_FILE 0x0004 /* is a file device */ +#define ST_FIFO 0x0008 /* is a fifo device */ +#define ST_PROG 0x0010 /* is a program device */ +#define ST_LABEL 0x0020 /* label found */ #define ST_MALLOC 0x0040 /* dev packet malloc'ed in init_dev() */ -#define ST_APPEND 0x0080 /* ready for Bacula append */ -#define ST_READ 0x0100 /* ready for Bacula read */ -#define ST_EOT 0x0200 /* at end of tape */ -#define ST_WEOT 0x0400 /* Got EOT on write */ -#define ST_EOF 0x0800 /* Read EOF i.e. zero bytes */ -#define ST_NEXTVOL 0x1000 /* Start writing on next volume */ -#define ST_SHORT 0x2000 /* Short block read */ +#define ST_APPEND 0x0080 /* ready for Bacula append */ +#define ST_READ 0x0100 /* ready for Bacula read */ +#define ST_EOT 0x0200 /* at end of tape */ +#define ST_WEOT 0x0400 /* Got EOT on write */ +#define ST_EOF 0x0800 /* Read EOF i.e. zero bytes */ +#define ST_NEXTVOL 0x1000 /* Start writing on next volume */ +#define ST_SHORT 0x2000 /* Short block read */ /* dev_blocked states (mutually exclusive) */ #define BST_NOT_BLOCKED 0 /* not blocked */ -#define BST_UNMOUNTED 1 /* User unmounted device */ +#define BST_UNMOUNTED 1 /* User unmounted device */ #define BST_WAITING_FOR_SYSOP 2 /* Waiting for operator to mount tape */ #define BST_DOING_ACQUIRE 3 /* Opening/validating/moving tape */ #define BST_WRITING_LABEL 4 /* Labeling a tape */ @@ -104,71 +112,71 @@ /* Volume Catalog Information structure definition */ typedef struct s_volume_catalog_info { /* Media info for the current Volume */ - uint32_t VolCatJobs; /* number of jobs on this Volume */ - uint32_t VolCatFiles; /* Number of files */ - uint32_t VolCatBlocks; /* Number of blocks */ - uint64_t VolCatBytes; /* Number of bytes written */ - uint32_t VolCatMounts; /* Number of mounts this volume */ - uint32_t VolCatErrors; /* Number of errors this volume */ - uint32_t VolCatWrites; /* Number of writes this volume */ - uint32_t VolCatReads; /* Number of reads this volume */ - uint32_t VolCatRecycles; /* Number of recycles this volume */ - int32_t Slot; /* Slot in changer */ - uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */ - uint32_t VolCatMaxFiles; /* Maximum files to write to volume */ - uint64_t VolCatMaxBytes; /* Max bytes to write to volume */ + uint32_t VolCatJobs; /* number of jobs on this Volume */ + uint32_t VolCatFiles; /* Number of files */ + uint32_t VolCatBlocks; /* Number of blocks */ + uint64_t VolCatBytes; /* Number of bytes written */ + uint32_t VolCatMounts; /* Number of mounts this volume */ + uint32_t VolCatErrors; /* Number of errors this volume */ + uint32_t VolCatWrites; /* Number of writes this volume */ + uint32_t VolCatReads; /* Number of reads this volume */ + uint32_t VolCatRecycles; /* Number of recycles this volume */ + int32_t Slot; /* Slot in changer */ + uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */ + uint32_t VolCatMaxFiles; /* Maximum files to write to volume */ + uint64_t VolCatMaxBytes; /* Max bytes to write to volume */ uint64_t VolCatCapacityBytes; /* capacity estimate */ - char VolCatStatus[20]; /* Volume status */ + char VolCatStatus[20]; /* Volume status */ char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */ } VOLUME_CAT_INFO; typedef struct s_steal_lock { - pthread_t no_wait_id; /* id of no wait thread */ - int dev_blocked; /* state */ + pthread_t no_wait_id; /* id of no wait thread */ + int dev_blocked; /* state */ } bsteal_lock_t; /* Device structure definition */ typedef struct s_device { - struct s_device *next; /* pointer to next open device */ - void *attached_jcrs; /* attached JCR list */ + struct s_device *next; /* pointer to next open device */ + void *attached_jcrs; /* attached JCR list */ #ifdef NEW_LOCK - brwlock_t lock; /* new device locking mechanism */ + brwlock_t lock; /* new device locking mechanism */ #endif - pthread_mutex_t mutex; /* access control */ - pthread_cond_t wait; /* thread wait variable */ + pthread_mutex_t mutex; /* access control */ + 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 dev_blocked; /* set if we must wait (i.e. change tape) */ - int num_waiting; /* number of threads waiting */ - int num_writers; /* number of writing threads */ - int use_count; /* usage count on this device */ - int fd; /* file descriptor */ - int capabilities; /* capabilities mask */ - int state; /* state mask */ - int dev_errno; /* Our own errno */ - int mode; /* read/write modes */ - char *dev_name; /* device name */ - char *errmsg; /* nicely edited error message */ - uint32_t block_num; /* current block number base 0 */ - uint32_t file; /* current file number base 0 */ - uint64_t file_addr; /* Current file read/write address */ - uint32_t EndBlock; /* last block written */ - uint32_t EndFile; /* last file written */ - uint32_t min_block_size; /* min block size */ - uint32_t max_block_size; /* max block size */ - uint32_t max_volume_jobs; /* max jobs to put on one volume */ - uint64_t max_volume_files; /* max files to put on one volume */ - uint64_t max_volume_size; /* max bytes to put on one volume */ - uint64_t max_file_size; /* max file size to put in one file on volume */ - uint64_t volume_capacity; /* advisory capacity */ - uint32_t max_rewind_wait; /* max secs to allow for rewind */ - uint32_t max_open_wait; /* max secs to allow for open */ - void *device; /* pointer to Device Resource */ - - VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */ - VOLUME_LABEL VolHdr; /* Actual volume label */ + pthread_t no_wait_id; /* this thread must not wait */ + int dev_blocked; /* set if we must wait (i.e. change tape) */ + int num_waiting; /* number of threads waiting */ + int num_writers; /* number of writing threads */ + int use_count; /* usage count on this device */ + int fd; /* file descriptor */ + int capabilities; /* capabilities mask */ + int state; /* state mask */ + int dev_errno; /* Our own errno */ + int mode; /* read/write modes */ + char *dev_name; /* device name */ + char *errmsg; /* nicely edited error message */ + uint32_t block_num; /* current block number base 0 */ + uint32_t file; /* current file number base 0 */ + uint64_t file_addr; /* Current file read/write address */ + uint32_t EndBlock; /* last block written */ + uint32_t EndFile; /* last file written */ + uint32_t min_block_size; /* min block size */ + uint32_t max_block_size; /* max block size */ + uint32_t max_volume_jobs; /* max jobs to put on one volume */ + uint64_t max_volume_files; /* max files to put on one volume */ + uint64_t max_volume_size; /* max bytes to put on one volume */ + uint64_t max_file_size; /* max file size to put in one file on volume */ + uint64_t volume_capacity; /* advisory capacity */ + uint32_t max_rewind_wait; /* max secs to allow for rewind */ + uint32_t max_open_wait; /* max secs to allow for open */ + void *device; /* pointer to Device Resource */ + + VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */ + VOLUME_LABEL VolHdr; /* Actual volume label */ } DEVICE; @@ -207,7 +215,7 @@ typedef struct s_device { * dependent. Arrgggg! */ #ifndef MTEOM -#ifdef MTSEOD +#ifdef MTSEOD #define MTEOM MTSEOD #endif #ifdef MTEOD diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index aaed0fea09..961c8bd2a1 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -19,7 +19,7 @@ * */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -565,7 +565,7 @@ static int unmount_cmd(JCR *jcr) } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) { Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting, dev->dev_blocked); - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } force_close_dev(dev); @@ -594,7 +594,7 @@ static int unmount_cmd(JCR *jcr) } else { /* device not being used */ Dmsg0(90, "Device not in use, unmounting\n"); block_device(dev, BST_UNMOUNTED); - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } force_close_dev(dev); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 06863b33a5..60505c4fe0 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -8,7 +8,7 @@ * Version $Id$ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,7 +31,6 @@ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ -static int create_volume_label(DEVICE *dev, char *VolName); static void create_volume_label_record(JCR *jcr, DEVICE *dev, DEV_RECORD *rec); extern char my_name[]; @@ -193,34 +192,31 @@ int unser_volume_label(DEVICE *dev, DEV_RECORD *rec) /* Unserialize the record into the Volume Header */ rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Volume_Label); ser_begin(rec->data, SER_LENGTH_Volume_Label); -#define Fld(x) (dev->VolHdr.x) - unser_string(Fld(Id)); + unser_string(dev->VolHdr.Id); + unser_uint32(dev->VolHdr.VerNum); - unser_uint32(Fld(VerNum)); - - if (Fld(VerNum) >= 11) { - unser_btime(Fld(label_btime)); - unser_btime(Fld(write_btime)); + if (dev->VolHdr.VerNum >= 11) { + unser_btime(dev->VolHdr.label_btime); + unser_btime(dev->VolHdr.write_btime); } else { /* old way */ - unser_float64(Fld(label_date)); - unser_float64(Fld(label_time)); + unser_float64(dev->VolHdr.label_date); + unser_float64(dev->VolHdr.label_time); } - unser_float64(Fld(write_date)); /* Unused with VerNum >= 11 */ - unser_float64(Fld(write_time)); /* Unused with VerNum >= 11 */ + unser_float64(dev->VolHdr.write_date); /* Unused with VerNum >= 11 */ + unser_float64(dev->VolHdr.write_time); /* Unused with VerNum >= 11 */ - unser_string(Fld(VolName)); - unser_string(Fld(PrevVolName)); - unser_string(Fld(PoolName)); - unser_string(Fld(PoolType)); - unser_string(Fld(MediaType)); + unser_string(dev->VolHdr.VolName); + unser_string(dev->VolHdr.PrevVolName); + unser_string(dev->VolHdr.PoolName); + unser_string(dev->VolHdr.PoolType); + unser_string(dev->VolHdr.MediaType); - unser_string(Fld(HostName)); - unser_string(Fld(LabelProg)); - unser_string(Fld(ProgVersion)); - unser_string(Fld(ProgDate)); + unser_string(dev->VolHdr.HostName); + unser_string(dev->VolHdr.LabelProg); + unser_string(dev->VolHdr.ProgVersion); + unser_string(dev->VolHdr.ProgDate); ser_end(rec->data, SER_LENGTH_Volume_Label); -#undef Fld Dmsg0(90, "ser_read_vol\n"); if (debug_level >= 90) { dump_volume_label(dev); @@ -272,48 +268,46 @@ static void create_volume_label_record(JCR *jcr, DEVICE *dev, DEV_RECORD *rec) rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Volume_Label); ser_begin(rec->data, SER_LENGTH_Volume_Label); -#define Fld(x) (dev->VolHdr.x) - ser_string(Fld(Id)); + ser_string(dev->VolHdr.Id); - ser_uint32(Fld(VerNum)); + ser_uint32(dev->VolHdr.VerNum); - if (Fld(VerNum >= 11)) { - ser_btime(Fld(label_btime)); - Fld(write_btime) = get_current_btime(); - ser_btime(Fld(write_btime)); - Fld(write_date) = 0; - Fld(write_time) = 0; + if (dev->VolHdr.VerNum >= 11) { + ser_btime(dev->VolHdr.label_btime); + dev->VolHdr.write_btime = get_current_btime(); + ser_btime(dev->VolHdr.write_btime); + dev->VolHdr.write_date = 0; + dev->VolHdr.write_time = 0; } else { /* OLD WAY DEPRECATED */ - ser_float64(Fld(label_date)); - ser_float64(Fld(label_time)); + ser_float64(dev->VolHdr.label_date); + ser_float64(dev->VolHdr.label_time); get_current_time(&dt); - Fld(write_date) = dt.julian_day_number; - Fld(write_time) = dt.julian_day_fraction; + dev->VolHdr.write_date = dt.julian_day_number; + dev->VolHdr.write_time = dt.julian_day_fraction; } - ser_float64(Fld(write_date)); /* 0 if VerNum >= 11 */ - ser_float64(Fld(write_time)); /* 0 if VerNum >= 11 */ + ser_float64(dev->VolHdr.write_date); /* 0 if VerNum >= 11 */ + ser_float64(dev->VolHdr.write_time); /* 0 if VerNum >= 11 */ - ser_string(Fld(VolName)); - ser_string(Fld(PrevVolName)); - ser_string(Fld(PoolName)); - ser_string(Fld(PoolType)); - ser_string(Fld(MediaType)); + ser_string(dev->VolHdr.VolName); + ser_string(dev->VolHdr.PrevVolName); + ser_string(dev->VolHdr.PoolName); + ser_string(dev->VolHdr.PoolType); + ser_string(dev->VolHdr.MediaType); - ser_string(Fld(HostName)); - ser_string(Fld(LabelProg)); - ser_string(Fld(ProgVersion)); - ser_string(Fld(ProgDate)); + ser_string(dev->VolHdr.HostName); + ser_string(dev->VolHdr.LabelProg); + ser_string(dev->VolHdr.ProgVersion); + ser_string(dev->VolHdr.ProgDate); ser_end(rec->data, SER_LENGTH_Volume_Label); rec->data_len = ser_length(rec->data); - rec->FileIndex = Fld(LabelType); + rec->FileIndex = dev->VolHdr.LabelType; rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; rec->Stream = jcr->NumVolumes; Dmsg2(100, "Created Vol label rec: FI=%s len=%d\n", FI_to_ascii(rec->FileIndex), rec->data_len); -#undef Fld } @@ -322,7 +316,7 @@ static void create_volume_label_record(JCR *jcr, DEVICE *dev, DEV_RECORD *rec) * Returns: 0 on error * 1 on success */ -static int create_volume_label(DEVICE *dev, char *VolName) +void create_volume_label(DEVICE *dev, char *VolName) { struct date_time dt; DEVRES *device = (DEVRES *)dev->device; @@ -367,7 +361,6 @@ static int create_volume_label(DEVICE *dev, char *VolName) if (debug_level >= 90) { dump_volume_label(dev); } - return 1; } /* @@ -390,9 +383,7 @@ int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *Poo Dmsg0(99, "write_volume_label()\n"); - if (!create_volume_label(dev, VolName)) { - return 0; - } + create_volume_label(dev, VolName); strcpy(dev->VolHdr.MediaType, device->media_type); bstrncpy(dev->VolHdr.VolName, VolName, sizeof(dev->VolHdr.VolName)); bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName)); @@ -654,7 +645,7 @@ int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec) if (label->VerNum >= 11) { unser_btime(label->write_btime); } else { - unser_float64(label->write_date); + unser_float64(label->write_date); } unser_float64(label->write_time); unser_string(label->PoolName); @@ -746,9 +737,9 @@ JobStatus : %c\n\ bstrftime(dt, sizeof(dt), btime_to_unix(label.write_btime)); Pmsg1(-1, _("Date written : %s\n"), dt); } else { - dt.julian_day_number = label.write_date; - dt.julian_day_fraction = label.write_time; - tm_decode(&dt, &tm); + dt.julian_day_number = label.write_date; + dt.julian_day_fraction = label.write_time; + tm_decode(&dt, &tm); Pmsg5(-1, _("\ Date written : %04d-%02d-%02d at %02d:%02d\n"), tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 4b1091abe2..e87833ae27 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -74,8 +74,8 @@ mount_next_vol: dev->state &= ~ST_LABEL; /* label not yet read */ jcr->VolumeName[0] = 0; - if (!dev_is_tape(dev) || !(dev->capabilities & CAP_ALWAYSOPEN)) { - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (!dev_is_tape(dev) || !dev_cap(dev, CAP_ALWAYSOPEN)) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } close_dev(dev); @@ -83,7 +83,7 @@ mount_next_vol: /* If we have not closed the device, then at least rewind the tape */ if (dev->state & ST_OPENED) { - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } if (!rewind_dev(dev)) { @@ -102,7 +102,7 @@ mount_next_vol: Dmsg0(100, "did not find next volume. Must ask.\n"); } Dmsg2(100, "After find_next_append. Vol=%s Slot=%d\n", - jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); + jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); release = 1; /* release if we "recurse" */ /* @@ -125,6 +125,7 @@ mount_next_vol: jcr->VolFirstFile = jcr->JobFiles; /* first update of Vol FileIndex */ for ( ;; ) { + int vol_label_status; autochanger = autoload_device(jcr, dev, 1, NULL); if (autochanger) { ask = 0; /* if autochange no need to ask sysop */ @@ -138,10 +139,13 @@ mount_next_vol: /* Open device */ for ( ; !(dev->state & ST_OPENED); ) { - if (open_dev(dev, jcr->VolCatInfo.VolCatName, READ_WRITE) < 0) { - if (dev->dev_errno == EAGAIN || dev->dev_errno == EBUSY) { - sleep(30); - } + int mode; + if (dev_cap(dev, CAP_STREAM)) { + mode = OPEN_WRITE_ONLY; + } else { + mode = OPEN_READ_WRITE; + } + if (open_dev(dev, jcr->VolCatInfo.VolCatName, mode) < 0) { Jmsg2(jcr, M_FATAL, 0, _("Unable to open device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); return 0; @@ -152,7 +156,18 @@ mount_next_vol: * Now make sure we have the right tape mounted */ read_volume: - switch (read_dev_volume_label(jcr, dev, block)) { + /* + * If we are writing to a stream device, ASSUME the volume label + * is correct. + */ + if (dev_cap(dev, CAP_STREAM)) { + vol_label_status = VOL_OK; + create_volume_label(dev, jcr->VolumeName); + dev->VolHdr.LabelType = PRE_LABEL; + } else { + vol_label_status = read_dev_volume_label(jcr, dev, block); + } + switch (vol_label_status) { case VOL_OK: Dmsg1(100, "Vol OK name=%s\n", jcr->VolumeName); memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(jcr->VolCatInfo)); @@ -187,7 +202,7 @@ read_volume: case VOL_IO_ERROR: Dmsg1(500, "Vol NO_LABEL or IO_ERROR name=%s\n", jcr->VolumeName); /* If permitted, create a label */ - if (dev->capabilities & CAP_LABEL) { + if (dev_cap(dev, CAP_LABEL)) { Dmsg0(100, "Create volume label\n"); if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName, jcr->pool_name)) { @@ -235,34 +250,37 @@ mount_error: dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */ write_volume_label_to_block(jcr, dev, block); /* - * Write the block now to ensure we have write permission. + * If we are not dealing with a streaming device, + * write the block now to ensure we have write permission. * It is better to find out now rather than later. */ - dev->VolCatInfo.VolCatBytes = 0; - if (!rewind_dev(dev)) { - Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - } - if (recycle) { - if (!truncate_dev(dev)) { - Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s. ERR=%s\n"), + if (!dev_cap(dev, CAP_STREAM)) { + dev->VolCatInfo.VolCatBytes = 0; + if (!rewind_dev(dev)) { + Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s. ERR=%s\n"), dev_name(dev), strerror_dev(dev)); } - } - /* Attempt write to check write permission */ - if (!write_block_to_dev(jcr, dev, block)) { - Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s. ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - goto mount_next_vol; - } - if (!rewind_dev(dev)) { - Jmsg2(jcr, M_ERROR, 0, _("Unable to rewind device %s. ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - goto mount_next_vol; - } + if (recycle) { + if (!truncate_dev(dev)) { + Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s. ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + } + } + /* Attempt write to check write permission */ + if (!write_block_to_dev(jcr, dev, block)) { + Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s. ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + goto mount_next_vol; + } + if (!rewind_dev(dev)) { + Jmsg2(jcr, M_ERROR, 0, _("Unable to rewind device %s. ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + goto mount_next_vol; + } - /* Recreate a correct volume label and return it in the block */ - write_volume_label_to_block(jcr, dev, block); + /* Recreate a correct volume label and return it in the block */ + write_volume_label_to_block(jcr, dev, block); + } /* Set or reset Volume statistics */ dev->VolCatInfo.VolCatJobs = 0; dev->VolCatInfo.VolCatFiles = 0; @@ -380,7 +398,7 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) * Handle autoloaders here. If we cannot autoload it, we * will return FALSE to ask the sysop. */ - if (writing && dev->capabilities && CAP_AUTOCHANGER && slot <= 0) { + if (writing && dev_cap(dev, CAP_AUTOCHANGER) && slot <= 0) { if (dir) { return 0; /* For user, bail out right now */ } @@ -411,7 +429,7 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) /* If bad status or tape we want is not loaded, load it. */ if (status != 0 || loaded != slot) { - if (dev->capabilities & CAP_OFFLINEUNMOUNT) { + if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } /* We are going to load a new tape, so close the device */ diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index bbd11998e5..db1aa18cee 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -28,82 +28,82 @@ uint32_t new_VolSessionId(); /* From acquire.c */ -int 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); +int 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); -int read_block_from_device(DEVICE *dev, DEV_BLOCK *block); -int read_block_from_dev(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); +int read_block_from_device(DEVICE *dev, DEV_BLOCK *block); +int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block); /* 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); DEVICE *setup_to_access_device(JCR *jcr, int read_access); -void display_error_status(DEVICE *dev); +void display_error_status(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); +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); /* 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); @@ -119,39 +119,40 @@ void new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state); void new_return_device_lock(DEVICE *dev, brwsteal_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 fdmsg.c */ -int bget_msg(BSOCK *sock); +int bget_msg(BSOCK *sock); /* 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); -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 autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir); +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 autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir); /* From parse_bsr.c */ @@ -166,11 +167,11 @@ extern void create_vol_list(JCR *jcr); /* 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, diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index 91b360891b..6abd69bf5e 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -10,7 +10,7 @@ * */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/version.h b/bacula/src/version.h index 0f5a984c52..7398b4a59d 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.29" #define VSTRING "1" -#define DATE "17 January 2003" -#define LSMDATE "17Jan03" +#define DATE "18 January 2003" +#define LSMDATE "18Jan03" /* Debug flags */ #define DEBUG 1 -- 2.39.5