http://howtos.linux.com/guides/nag2/x-087-2-nfs.mountd.shtml
For 1.33
+- Add a regression test for dbcheck.
+- Add disk seeking on restore.
+- Add atime preservation.
- Allow for optional cancelling of SD and FD in case DIR
gets a fatal error. Requested by Jesse Guardiani <jesse@wingnet.net>
- Remove h_errno from bnet.c by including proper header.
- Look at ASSERT() at 384 src/lib/bnet.c
- Dates are wrong in restore list from Win32 FD.
- Dates are wrong in catalog from Win32 FD.
-
#define INC_KW_REPLACE 8 /* restore options */
#define INC_KW_READFIFO 9 /* Causes fifo data to be read */
#define INC_KW_PORTABLE 10
+#define INC_KW_MTIMEONLY 11
+#define INC_KW_KEEPATIME 12
/* Include keywords -- these are keywords that can appear
* in the options lists of an old include ( Include = compression= ...)
{"replace", INC_KW_REPLACE},
{"readfifo", INC_KW_READFIFO},
{"portable", INC_KW_PORTABLE},
+ {"mtimeonly", INC_KW_MTIMEONLY},
+ {"keepatime", INC_KW_KEEPATIME},
{NULL, 0}
};
{"no", INC_KW_READFIFO, "0"},
{"yes", INC_KW_PORTABLE, "p"},
{"no", INC_KW_PORTABLE, "0"},
+ {"yes", INC_KW_MTIMEONLY, "m"},
+ {"no", INC_KW_MTIMEONLY, "0"},
+ {"yes", INC_KW_KEEPATIME, "k"},
+ {"no", INC_KW_KEEPATIME, "0"},
{NULL, 0, 0}
};
jcr->compress_buf = get_memory(jcr->compress_buf_size);
Dmsg1(100, "set_find_options ff=%p\n", jcr->ff);
- set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime, jcr->mtime_only);
+ set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
Dmsg0(110, "start find files\n");
start_heartbeat_monitor(jcr);
jcr->JobStatus = JS_Running;
- set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime, jcr->mtime_only);
+ set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
stat = find_files(jcr, (FF_PKT *)jcr->ff, tally_file, (void *)jcr);
return stat;
Dmsg2(100, "Got since time: %s mtime_only=%d\n", ctime(&mtime), mtime_only);
jcr->incremental = 1; /* set incremental or decremental backup */
jcr->mtime = mtime; /* set since time */
- jcr->mtime_only = mtime_only; /* and what to compare */
/*
* We get his UTC since time, then sync the clocks and correct it
* to agree with our clock.
Dmsg2(100, "adj = %d since_time=%d\n", (int)adj, (int)since_time);
jcr->incremental = 1; /* set incremental or decremental backup */
jcr->mtime = since_time; /* set since time */
- jcr->mtime_only = mtime_only; /* and what to compare */
} else {
Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level);
free_memory(level);
Jmsg1(jcr, M_ABORT, 0, _("Cannot malloc %d network read buffer\n"),
DEFAULT_NETWORK_BUFFER_SIZE);
}
- set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime, jcr->mtime_only);
+ set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
Dmsg0(10, "Start find files\n");
/* Subroutine verify_file() is called for each file */
find_files(jcr, (FF_PKT *)jcr->ff, verify_file, (void *)jcr);
ff->sys_fname = get_pool_memory(PM_FNAME);
init_include_exclude_files(ff); /* init lists */
- ff->mtime_only = 0; /* use both st_mtime and st_ctime */
/* Get system path and filename maximum lengths */
path_max = pathconf(".", _PC_PATH_MAX);
* of save_time. For additional options, see above
*/
void
-set_find_options(FF_PKT *ff, int incremental, time_t save_time, int mtime_only)
+set_find_options(FF_PKT *ff, int incremental, time_t save_time)
{
Dmsg0(100, "Enter set_find_options()\n");
ff->incremental = incremental;
ff->save_time = save_time;
- ff->mtime_only = mtime_only;
Dmsg0(100, "Leave set_find_options()\n");
}
#define FO_READFIFO (1<<8) /* read data from fifo */
#define FO_SHA1 (1<<9) /* Do SHA1 checksum */
#define FO_PORTABLE (1<<10) /* Use portable data format -- no BackupWrite */
+#define FO_MTIMEONLY (1<<11) /* Use mtime rather than mtime & ctime */
+#define FO_KEEPATIME (1<<12) /* Reset access time */
struct s_included_file {
struct s_included_file *next;
int32_t LinkFI; /* FileIndex of main hard linked file */
struct f_link *linked; /* Set if this file is hard linked */
int type; /* FT_ type from above */
- uint32_t flags; /* control flags */
+ uint32_t flags; /* backup options */
int ff_errno; /* errno */
- int incremental; /* do incremental save */
BFILE bfd; /* Bacula file descriptor */
time_t save_time; /* start of incremental time */
- int mtime_only; /* incremental on mtime_only */
- int dereference; /* follow links */
+ bool dereference; /* follow links (not implemented) */
+ bool null_output_device; /* using null output device */
+ bool incremental; /* incremental save */
int GZIP_level; /* compression level */
- int atime_preserve; /* preserve access times */
- int null_output_device; /* using null output device */
char VerifyOpts[20];
struct s_included_file *included_files_list;
struct s_excluded_file *excluded_files_list;
#include "bacula.h"
#include "find.h"
-extern int32_t name_max; /* filename max length */
-extern int32_t path_max; /* path name max length */
+extern int32_t name_max; /* filename max length */
+extern int32_t path_max; /* path name max length */
/*
* Structure for keeping track of hard linked files, we
*/
struct f_link {
struct f_link *next;
- dev_t dev; /* device */
- ino_t ino; /* inode with device is unique */
+ dev_t dev; /* device */
+ ino_t ino; /* inode with device is unique */
short linkcount;
- uint32_t FileIndex; /* Bacula FileIndex of this file */
- char name[1]; /* The name */
+ uint32_t FileIndex; /* Bacula FileIndex of this file */
+ char name[1]; /* The name */
};
static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
}
/*
- * Find a single file.
+ * Find a single file.
* handle_file is the callback for handling the file.
* p is the filename
* parent_device is the device we are currently on
*/
int
find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
- void *pkt, char *fname, dev_t parent_device, int top_level)
+ void *pkt, char *fname, dev_t parent_device, int top_level)
{
struct utimbuf restore_times;
int rtn_stat;
Dmsg1(300, "Non-directory incremental: %s\n", ff_pkt->fname);
/* Not a directory */
if (ff_pkt->statp.st_mtime < ff_pkt->save_time
- && (ff_pkt->mtime_only ||
- ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
- /* Incremental option, file not changed */
- ff_pkt->type = FT_NOCHG;
- return handle_file(ff_pkt, pkt);
+ && ((ff_pkt->flags & FO_MTIMEONLY) ||
+ ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
+ /* Incremental option, file not changed */
+ ff_pkt->type = FT_NOCHG;
+ return handle_file(ff_pkt, pkt);
}
}
*/
if (ff_pkt->statp.st_nlink > 1
&& (S_ISREG(ff_pkt->statp.st_mode)
- || S_ISCHR(ff_pkt->statp.st_mode)
- || S_ISBLK(ff_pkt->statp.st_mode)
- || S_ISFIFO(ff_pkt->statp.st_mode)
- || S_ISSOCK(ff_pkt->statp.st_mode))) {
+ || S_ISCHR(ff_pkt->statp.st_mode)
+ || S_ISBLK(ff_pkt->statp.st_mode)
+ || S_ISFIFO(ff_pkt->statp.st_mode)
+ || S_ISSOCK(ff_pkt->statp.st_mode))) {
struct f_link *lp;
/* Search link list of hard linked files */
for (lp = ff_pkt->linklist; lp; lp = lp->next)
- if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) {
- ff_pkt->link = lp->name;
- ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */
- ff_pkt->LinkFI = lp->FileIndex;
- return handle_file(ff_pkt, pkt);
- }
+ if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) {
+ ff_pkt->link = lp->name;
+ ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */
+ ff_pkt->LinkFI = lp->FileIndex;
+ return handle_file(ff_pkt, pkt);
+ }
/* File not previously dumped. Chain it into our list. */
lp = (struct f_link *)bmalloc(sizeof(struct f_link) + strlen(fname) +1);
strcpy(lp->name, fname);
lp->next = ff_pkt->linklist;
ff_pkt->linklist = lp;
- ff_pkt->linked = lp; /* mark saved link */
+ ff_pkt->linked = lp; /* mark saved link */
} else {
ff_pkt->linked = NULL;
}
sizeleft = ff_pkt->statp.st_size;
/* Don't bother opening empty, world readable files. Also do not open
- files when archive is meant for /dev/null. */
+ files when archive is meant for /dev/null. */
if (ff_pkt->null_output_device || (sizeleft == 0
- && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
- ff_pkt->type = FT_REGE;
+ && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
+ ff_pkt->type = FT_REGE;
} else {
- ff_pkt->type = FT_REG;
+ ff_pkt->type = FT_REG;
}
rtn_stat = handle_file(ff_pkt, pkt);
if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
}
return rtn_stat;
size = readlink(fname, buffer, path_max + name_max + 101);
if (size < 0) {
- /* Could not follow link */
- ff_pkt->type = FT_NOFOLLOW;
- ff_pkt->ff_errno = errno;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- return rtn_stat;
+ /* Could not follow link */
+ ff_pkt->type = FT_NOFOLLOW;
+ ff_pkt->ff_errno = errno;
+ rtn_stat = handle_file(ff_pkt, pkt);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ return rtn_stat;
}
buffer[size] = 0;
- ff_pkt->link = buffer; /* point to link */
- ff_pkt->type = FT_LNK; /* got a real link */
+ ff_pkt->link = buffer; /* point to link */
+ ff_pkt->type = FT_LNK; /* got a real link */
rtn_stat = handle_file(ff_pkt, pkt);
if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
}
return rtn_stat;
struct dirent *entry, *result;
char *link;
int link_len;
- int len;
+ int len;
int status;
dev_t our_device = ff_pkt->statp.st_dev;
* in principle, we should be able to access everything.
*/
if (!have_win32_api() || (ff_pkt->flags & FO_PORTABLE)) {
- if (access(fname, R_OK) == -1 && geteuid() != 0) {
- /* Could not access() directory */
- ff_pkt->type = FT_NOACCESS;
- ff_pkt->ff_errno = errno;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- return rtn_stat;
- }
+ if (access(fname, R_OK) == -1 && geteuid() != 0) {
+ /* Could not access() directory */
+ ff_pkt->type = FT_NOACCESS;
+ ff_pkt->ff_errno = errno;
+ rtn_stat = handle_file(ff_pkt, pkt);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ return rtn_stat;
+ }
}
/* Build a canonical directory name with a trailing slash in link var */
bstrncpy(link, fname, link_len);
/* Strip all trailing slashes */
while (len >= 1 && link[len - 1] == '/')
- len--;
+ len--;
link[len++] = '/'; /* add back one */
link[len] = 0;
ff_pkt->link = link;
if (ff_pkt->incremental &&
- (ff_pkt->statp.st_mtime < ff_pkt->save_time &&
- ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
- /* Incremental option, directory entry not changed */
- ff_pkt->type = FT_DIRNOCHG;
+ (ff_pkt->statp.st_mtime < ff_pkt->save_time &&
+ ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
+ /* Incremental option, directory entry not changed */
+ ff_pkt->type = FT_DIRNOCHG;
} else {
- ff_pkt->type = FT_DIR;
+ ff_pkt->type = FT_DIR;
}
/*
dir_ff_pkt->excluded_files_list = NULL;
dir_ff_pkt->excluded_paths_list = NULL;
dir_ff_pkt->linklist = NULL;
-
+
ff_pkt->link = ff_pkt->fname; /* reset "link" */
/*
* user has turned it off for this directory.
*/
if (ff_pkt->flags & FO_NO_RECURSION) {
- /* No recursion into this directory */
- ff_pkt->type = FT_NORECURSE;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- free(link);
- free_dir_ff_pkt(dir_ff_pkt);
- return rtn_stat;
+ /* No recursion into this directory */
+ ff_pkt->type = FT_NORECURSE;
+ rtn_stat = handle_file(ff_pkt, pkt);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
+ return rtn_stat;
}
/*
* avoid doing so if the user only wants to dump one file system.
*/
if (!top_level && !(ff_pkt->flags & FO_MULTIFS) &&
- parent_device != ff_pkt->statp.st_dev) {
- /* returning here means we do not handle this directory */
- ff_pkt->type = FT_NOFSCHG;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- free(link);
- free_dir_ff_pkt(dir_ff_pkt);
- return rtn_stat;
+ parent_device != ff_pkt->statp.st_dev) {
+ /* returning here means we do not handle this directory */
+ ff_pkt->type = FT_NOFSCHG;
+ rtn_stat = handle_file(ff_pkt, pkt);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
+ return rtn_stat;
}
/*
* Decend into or "recurse" into the directory to read
*/
errno = 0;
if ((directory = opendir(fname)) == NULL) {
- ff_pkt->type = FT_NOOPEN;
- ff_pkt->ff_errno = errno;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- free(link);
- free_dir_ff_pkt(dir_ff_pkt);
- return rtn_stat;
+ ff_pkt->type = FT_NOOPEN;
+ ff_pkt->ff_errno = errno;
+ rtn_stat = handle_file(ff_pkt, pkt);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
+ return rtn_stat;
}
/*
rtn_stat = 1;
entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
for ( ; !job_canceled(jcr); ) {
- char *p, *q;
- int i;
+ char *p, *q;
+ int i;
- status = readdir_r(directory, entry, &result);
- if (status != 0 || result == NULL) {
+ status = readdir_r(directory, entry, &result);
+ if (status != 0 || result == NULL) {
// Dmsg2(99, "readdir returned stat=%d result=0x%x\n",
-// status, (long)result);
- break;
- }
- ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
- p = entry->d_name;
+// status, (long)result);
+ break;
+ }
+ ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
+ p = entry->d_name;
/* Skip `.', `..', and excluded file names. */
if (p[0] == '\0' || (p[0] == '.' && (p[1] == '\0' ||
(p[1] == '.' && p[2] == '\0')))) {
- continue;
- }
-
- if ((int)NAMELEN(entry) + len >= link_len) {
- link_len = len + NAMELEN(entry) + 1;
- link = (char *)brealloc(link, link_len + 1);
- }
- q = link + len;
- for (i=0; i < (int)NAMELEN(entry); i++) {
- *q++ = *p++;
- }
- *q = 0;
- if (!file_is_excluded(ff_pkt, link)) {
- rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- }
+ continue;
+ }
+
+ if ((int)NAMELEN(entry) + len >= link_len) {
+ link_len = len + NAMELEN(entry) + 1;
+ link = (char *)brealloc(link, link_len + 1);
+ }
+ q = link + len;
+ for (i=0; i < (int)NAMELEN(entry); i++) {
+ *q++ = *p++;
+ }
+ *q = 0;
+ if (!file_is_excluded(ff_pkt, link)) {
+ rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ }
}
closedir(directory);
free(link);
* the directory modes and dates. Temp directory values
* were used without this record.
*/
- handle_file(dir_ff_pkt, pkt); /* handle directory entry */
+ handle_file(dir_ff_pkt, pkt); /* handle directory entry */
if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
+ ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
}
free_dir_ff_pkt(dir_ff_pkt);
- if (ff_pkt->atime_preserve) {
- utime(fname, &restore_times);
+ if (ff_pkt->flags & FO_KEEPATIME) {
+ utime(fname, &restore_times);
}
return rtn_stat;
} /* end check for directory */
#ifdef HAVE_FREEBSD_OS
/*
* On FreeBSD, all block devices are character devices, so
- * to be able to read a raw disk, we need the check for
- * a character device.
+ * to be able to read a raw disk, we need the check for
+ * a character device.
* crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/ad0s3
* crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/rad0s3
*/
#else
if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) {
#endif
- ff_pkt->type = FT_RAW; /* raw partition */
+ ff_pkt->type = FT_RAW; /* raw partition */
} else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) &&
- ff_pkt->flags & FO_READFIFO) {
+ ff_pkt->flags & FO_READFIFO) {
ff_pkt->type = FT_FIFO;
} else {
/* The only remaining types are special (character, ...) files */
lc = lp;
lp = lp->next;
if (lc) {
- free(lc);
- count++;
+ free(lc);
+ count++;
}
}
return count;
case 's':
inc->options |= FO_SPARSE;
break;
+ case 'm':
+ inc->options |= FO_MTIMEONLY;
+ break;
+ case 'k':
+ inc->options |= FO_KEEPATIME;
+ break;
case 'V': /* verify options */
/* Copy Verify Options */
for (j=0; *p && *p != ':'; p++) {
*/
/* from attribs.c */
-void encode_stat (char *buf, FF_PKT *ff_pkt, int data_stream);
-int decode_stat (char *buf, struct stat *statp, int32_t *LinkFI);
-int32_t decode_LinkFI (char *buf, struct stat *statp);
-int encode_attribsEx (JCR *jcr, char *attribsEx, FF_PKT *ff_pkt);
-int set_attributes (JCR *jcr, ATTR *attr, BFILE *ofd);
-int select_data_stream(FF_PKT *ff_pkt);
+void encode_stat (char *buf, FF_PKT *ff_pkt, int data_stream);
+int decode_stat (char *buf, struct stat *statp, int32_t *LinkFI);
+int32_t decode_LinkFI (char *buf, struct stat *statp);
+int encode_attribsEx (JCR *jcr, char *attribsEx, FF_PKT *ff_pkt);
+int set_attributes (JCR *jcr, ATTR *attr, BFILE *ofd);
+int select_data_stream(FF_PKT *ff_pkt);
/* from create_file.c */
-int create_file (JCR *jcr, ATTR *attr, BFILE *ofd, int replace);
+int create_file (JCR *jcr, ATTR *attr, BFILE *ofd, int replace);
/* From find.c */
FF_PKT *init_find_files();
-void set_find_options(FF_PKT *ff, int incremental, time_t mtime, int mtime_only);
+void set_find_options(FF_PKT *ff, int incremental, time_t mtime);
int find_files(JCR *jcr, FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt), void *pkt);
int term_find_files(FF_PKT *ff);
int file_is_excluded(FF_PKT *ff, char *file);
int file_is_included(FF_PKT *ff, char *file);
struct s_included_file *get_next_included_file(FF_PKT *ff,
- struct s_included_file *inc);
+ struct s_included_file *inc);
/* From find_one.c */
int find_one_file(JCR *jcr, FF_PKT *ff, int handle_file(FF_PKT *ff_pkt, void *hpkt),
- void *pkt, char *p, dev_t parent_device, int top_level);
+ void *pkt, char *p, dev_t parent_device, int top_level);
int term_find_one(FF_PKT *ff);
/* from makepath.c */
int make_path(JCR *jcr, const char *argpath, int mode,
- int parent_mode, uid_t owner, gid_t group,
- int preserve_existing, char *verbose_fmt_string);
+ int parent_mode, uid_t owner, gid_t group,
+ int preserve_existing, char *verbose_fmt_string);
/* from bfile.c -- see bfile.h */
/*********FIXME********* add missing files and files to be retried */
int incremental; /* set if incremental for SINCE */
time_t mtime; /* begin time for SINCE */
- int mtime_only; /* compare only mtime and not ctime as well */
int listing; /* job listing in estimate */
long Ticket; /* Ticket */
char *big_buf; /* I/O buffer */
*/
strip_trailing_junk(str);
len = strlen(str);
- /* Strip trailing spaces */
- for (i=len; i>0; i--) {
- if (!B_ISSPACE(str[i-1])) {
- break;
- }
- str[i-1] = 0;
- }
+
/* Find beginning of the modifier */
- for ( ; i>0; i--) {
+ for (i=len; i > 0; i--) {
if (!B_ISALPHA(str[i-1])) {
break;
}
}
- /* If not found, error */
- if (i == 0 || i == len) {
+
+ /* If nothing found, error */
+ if (i == 0) {
Dmsg2(200, "error i=%d len=%d\n", i, len);
return false;
}
- /* Move modifier to mod */
+
+ /* Move modifier to its location */
bstrncpy(mod, &str[i], mod_len);
- if (strlen(mod) == 0) { /* Make sure we have a modifier */
- Dmsg0(200, "No modifier found\n");
- return false;
- }
Dmsg2(200, "in=%s mod=%s:\n", str, mod);
+
/* Backup over any spaces in front of modifier */
- for ( ; i>0; i--) {
+ for ( ; i > 0; i--) {
if (B_ISSPACE(str[i-1])) {
continue;
}
}
}
if (mod[i] == NULL) {
- Dmsg0(200, "Modifier not found\n");
- return 0; /* modifer not found */
+ i = 1; /* no modifier, assume 1 */
}
Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]);
errno = 0;
}
}
if (mod[i] == NULL) {
- Dmsg0(200, "Modifier not found\n");
- return 0; /* modifer not found */
+ i = 0; /* no modifier found, assume 1 */
}
Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]);
errno = 0;
}
/* Limit maximum File size on volume to user specified value */
- if (dev_state(dev, ST_TAPE)) {
- if ((dev->max_file_size > 0) &&
- (dev->file_addr+block->binbuf) >= dev->max_file_size) {
+ if ((dev->max_file_size > 0) &&
+ (dev->file_size+block->binbuf) >= dev->max_file_size) {
+ if (dev_state(dev, ST_TAPE) && weof_dev(dev, 1) != 0) { /* write eof */
/* Write EOF */
- if (weof_dev(dev, 1) != 0) { /* write eof */
- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
- block->write_failed = true;
- dev->VolCatInfo.VolCatErrors++;
- dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
- Dmsg0(100, "dir_update_volume_info\n");
- dev->VolCatInfo.VolCatFiles = dev->file;
- dir_update_volume_info(jcr, dev, 0);
- return 0;
- }
-
- /* Do bookkeeping to handle EOF just written */
+ Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
+ block->write_failed = true;
+ dev->VolCatInfo.VolCatErrors++;
+ dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
Dmsg0(100, "dir_update_volume_info\n");
dev->VolCatInfo.VolCatFiles = dev->file;
dir_update_volume_info(jcr, dev, 0);
- if (!dir_create_jobmedia_record(jcr)) {
- Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
- jcr->VolCatInfo.VolCatName, jcr->Job);
- return 0;
- }
- /*
- * Walk through all attached jcrs indicating the file has changed
- */
- Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
- for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
- if (mjcr->JobId == 0) {
- continue; /* ignore console */
- }
- mjcr->NewFile = true; /* set reminder to do set_new_file_params */
+ return 0;
+ }
+
+ /* Create a JobMedia record so restore can seek */
+ Dmsg0(100, "dir_update_volume_info\n");
+ dev->VolCatInfo.VolCatFiles = dev->file;
+ dir_update_volume_info(jcr, dev, 0);
+ if (!dir_create_jobmedia_record(jcr)) {
+ Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
+ jcr->VolCatInfo.VolCatName, jcr->Job);
+ return 0;
+ }
+ dev->file_size = 0; /* reset file size */
+ /*
+ * Walk through all attached jcrs indicating the file has changed
+ */
+ Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
+ for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
+ if (mjcr->JobId == 0) {
+ continue; /* ignore console */
}
- set_new_file_parameters(jcr, dev);
+ mjcr->NewFile = true; /* set reminder to do set_new_file_params */
}
+ set_new_file_parameters(jcr, dev);
}
dev->VolCatInfo.VolCatWrites++;
dev->VolCatInfo.VolCatBytes += block->binbuf;
dev->VolCatInfo.VolCatBlocks++;
- dev->file_addr += wlen;
dev->EndBlock = dev->block_num;
dev->EndFile = dev->file;
dev->block_num++;
jcr->EndBlock = dev->EndBlock;
jcr->EndFile = dev->EndFile;
} else {
+ /* Save address of start of block just written */
jcr->EndBlock = (uint32_t)dev->file_addr;
jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
}
jcr->VolLastIndex = block->LastIndex;
}
jcr->WroteVol = true;
+ dev->file_addr += wlen; /* update file address */
+ dev->file_size += wlen;
Dmsg2(190, "write_block: wrote block %d bytes=%d\n", dev->block_num,
wlen);
off_t pos = lseek(dev->fd, (off_t)0, SEEK_CUR); /* get curr pos */
pos -= block->read_len;
lseek(dev->fd, pos, SEEK_SET);
+ dev->file_addr = pos;
}
Mmsg1(&dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len);
Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
dev->VolCatInfo.VolCatBytes += block->block_len;
dev->VolCatInfo.VolCatBlocks++;
- dev->file_addr += block->block_len;
dev->EndBlock = dev->block_num;
dev->EndFile = dev->file;
dev->block_num++;
} else {
jcr->EndBlock = (uint32_t)dev->file_addr;
jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
+ dev->block_num = jcr->EndBlock;
+ dev->file = jcr->EndFile;
}
+ dev->file_addr += block->block_len;
+ dev->file_size += block->block_len;
/*
* If we read a short block on disk,
lseek(dev->fd, pos, SEEK_SET);
Dmsg2(100, "Did lseek blk_size=%d rdlen=%d\n", block->block_len,
block->read_len);
+ dev->file_addr = pos;
}
Dmsg2(200, "Exit read_block read_len=%d block_len=%d\n",
block->read_len, block->block_len);
if (!(dev_state(dev, ST_TAPE))) {
off_t pos = (((off_t)file)<<32) + block;
+ Dmsg1(100, "===== lseek to %d\n", (int)pos);
if (lseek(dev->fd, pos, SEEK_SET) == (off_t)-1) {
dev->dev_errno = errno;
Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
dev->dev_name, strerror(dev->dev_errno));
return 0;
}
+ dev->file = file;
+ dev->block_num = block;
+ dev->file_addr = pos;
return 1;
}
Dmsg4(100, "reposition_dev from %u:%u to %u:%u\n",
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 */
+ uint64_t file_size; /* Current file size */
uint32_t EndBlock; /* last block written */
uint32_t EndFile; /* last file written */
uint32_t min_block_size; /* min block size */
#undef VERSION
#define VERSION "1.33.4"
#define VSTRING "1"
-#define BDATE "24 Feb 2004"
-#define LSMDATE "24Feb04"
+#define BDATE "26 Feb 2004"
+#define LSMDATE "26Feb04"
/* Debug flags */
#undef DEBUG