From 19adab986b837142623603178a68db1d8211d5f8 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 29 Dec 2002 18:44:37 +0000 Subject: [PATCH] Fix Restore options git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@253 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ChangeLog | 1 + bacula/ReleaseNotes | 1 + bacula/kernstodo | 2 +- bacula/src/baconfig.h | 2 - bacula/src/dird/restore.c | 4 +- bacula/src/filed/restore.c | 25 ++++++---- bacula/src/findlib/create_file.c | 81 +++++++++++++++++--------------- bacula/src/findlib/find.h | 8 ++++ bacula/src/stored/bextract.c | 25 ++++++---- 9 files changed, 90 insertions(+), 59 deletions(-) diff --git a/bacula/ChangeLog b/bacula/ChangeLog index da7d8fed02..03e80ce04a 100644 --- a/bacula/ChangeLog +++ b/bacula/ChangeLog @@ -15,6 +15,7 @@ Changes submitted this submission: 29Dec02 - Added --enable-client-only to ./configure - Modified --enable-static-sd to work better and documented it. +- Fixed Restore options (never,ifnewer, ...). They now work. 28Dec02 - Added more rescue documentation. - Did a spell check of the Bacula doc. diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index 61ee63a56c..f8f68993b9 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -10,6 +10,7 @@ Major Changes this Release: 1st Sun ... Minor Changes this Release: +- Fixed Restore options (never,ifnewer, ...). They now work. - New bidirectional timed pipe mechanism for running child processes permits better error messages. - Faster Storage daemon initialization (using pthreads) diff --git a/bacula/kernstodo b/bacula/kernstodo index 9492c316e4..01f1536673 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -8,7 +8,6 @@ Documentation to do: (a little bit at a time) - Document static linking Testing to do: (painful) -- that restore options work in FD (mostly done). - that console command line options work - blocksize recognition code. @@ -697,4 +696,5 @@ Done: (see kernsdone for more) from tape. Client record needs improving. - Implement ./configure --with-client-only - Finish up static linking +- that restore options work in FD diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index 8a9f2f51f0..956a0ea350 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -355,6 +355,4 @@ extern int thr_setconcurrency(int); #define REPLACE_NEVER 'n' #define REPLACE_IFOLDER 'o' - - #endif /* _BACONFIG_H */ diff --git a/bacula/src/dird/restore.c b/bacula/src/dird/restore.c index e11d110808..9fae901c52 100644 --- a/bacula/src/dird/restore.c +++ b/bacula/src/dird/restore.c @@ -230,7 +230,9 @@ int do_restore(JCR *jcr) /* Send restore command */ char replace, *where; - if (jcr->job->replace != 0) { + if (jcr->replace != 0) { + replace = jcr->replace; + } else if (jcr->job->replace != 0) { replace = jcr->job->replace; } else { replace = REPLACE_ALWAYS; /* always replace */ diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 2b5c24b6e9..a0acc19d51 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -56,7 +56,7 @@ void do_restore(JCR *jcr) struct stat statp; int extract = FALSE; int ofd = -1; - int type; + int type, stat; uint32_t total = 0; /* Job total but only 32 bits for debug */ char *wbuf; /* write buffer */ uint32_t wsize; /* write size */ @@ -245,17 +245,26 @@ void do_restore(JCR *jcr) } Dmsg1(30, "Outfile=%s\n", ofile); - print_ls_output(jcr, ofile, lname, type, &statp); - extract = create_file(jcr, fname, ofile, lname, type, - stream, &statp, attribsEx, &ofd, jcr->replace); - Dmsg1(40, "Extract=%d\n", extract); - if (extract) { + extract = FALSE; + stat = create_file(jcr, fname, ofile, lname, type, + stream, &statp, attribsEx, &ofd, jcr->replace); + switch (stat) { + case CF_ERROR: + case CF_SKIP: + break; + case CF_EXTRACT: + extract = TRUE; + pm_strcpy(&jcr->last_fname, ofile); + /* Fall-through wanted */ + case CF_CREATED: jcr->JobFiles++; fileAddr = 0; - } + print_ls_output(jcr, ofile, lname, type, &statp); + break; + } + jcr->num_files_examined++; - pm_strcpy(&jcr->last_fname, ofile); /* Data stream */ } else if (stream == STREAM_FILE_DATA || stream == STREAM_SPARSE_DATA) { diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index 97fb350250..42b6203336 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -45,8 +45,10 @@ * fname is the original filename * ofile is the output filename (may be in a different directory) * - * Returns: 1 on success - * 0 on failure + * Returns: CF_SKIP if file should be skipped + * CF_ERROR on error + * CF_EXTRACT file created and data to restore + * CF_CREATED file created no data to restore * * Note, we create the file here, except for special files, * we do not set the attributes because we want to first @@ -74,39 +76,41 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, gid = statp->st_gid; uid = statp->st_uid; + Dmsg2(400, "Replace=%c %d\n", (char)replace, replace); + /* If not always replacing, do a stat and decide */ + if (replace != REPLACE_ALWAYS) { + struct stat mstatp; + if (lstat(ofile, &mstatp) == 0) { + switch (replace) { + case REPLACE_IFNEWER: + if (statp->st_mtime <= mstatp.st_mtime) { + Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), ofile); + return CF_SKIP; + } + break; + case REPLACE_IFOLDER: + if (statp->st_mtime >= mstatp.st_mtime) { + Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), ofile); + return CF_SKIP; + } + break; + case REPLACE_NEVER: + Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), ofile); + return CF_SKIP; + } + } + } switch (type) { case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "Hard link %s => %s\n", ofile, lname); if (link(lname, ofile) != 0) { Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s ==> %s: ERR=%s\n"), ofile, lname, strerror(errno)); + return CF_ERROR; } break; case FT_REGE: /* empty file */ case FT_REG: /* regular file */ - /* If not always replacing, do a stat and decide */ - if (replace != REPLACE_ALWAYS) { - struct stat mstatp; - if (lstat(ofile, &mstatp) == 0) { - switch (replace) { - case REPLACE_IFNEWER: - if (statp->st_mtime < mstatp.st_mtime) { - Jmsg1(jcr, M_INFO, 0, _("File %s skipped. Not newer.\n"), ofile); - return 0; - } - break; - case REPLACE_IFOLDER: - if (statp->st_mtime > mstatp.st_mtime) { - Jmsg1(jcr, M_INFO, 0, _("File %s skipped. Not older.\n"), ofile); - return 0; - } - break; - case REPLACE_NEVER: - Jmsg1(jcr, M_INFO, 0, _("File %s skipped. Already exists.\n"), ofile); - return 0; - } - } - } /* Separate pathname and filename */ for (p=f=ofile; *p; p++) { if (*p == '/') { @@ -120,13 +124,13 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, fnl = p - f; if (fnl == 0) { Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname); - return 0; + return CF_ERROR; } pnl = f - ofile - 1; if (pnl <= 0) { Jmsg1(jcr, M_ERROR, 0, _("Zero length path: %s\n"), fname); - return 0; + return CF_ERROR; } savechr = ofile[pnl]; ofile[pnl] = 0; /* terminate path */ @@ -140,7 +144,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, stat = !make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL); if (stat == 0) { Dmsg1(0, "Could not make path. %s\n", ofile); - return 0; + return CF_ERROR; } ofile[pnl] = savechr; /* restore full name */ @@ -152,38 +156,40 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, Dmsg1(50, "Create file: %s\n", ofile); if ((*ofd = open(ofile, mode, S_IRUSR | S_IWUSR)) < 0) { Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), ofile, strerror(errno)); - return 0; + return CF_ERROR; } - return 1; + return CF_EXTRACT; case FT_LNK: Dmsg2(130, "FT_LNK should restore: %s -> %s\n", ofile, lname); if (symlink(lname, ofile) != 0 && errno != EEXIST) { Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), ofile, lname, strerror(errno)); + return CF_ERROR; } - return 0; + return CF_CREATED; case FT_DIR: Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, ofile); if (make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL) != 0) { Jmsg1(jcr, M_ERROR, 0, _("Could not make directory: %s\n"), ofile); + return CF_ERROR; } - return 0; + return CF_CREATED; case FT_SPEC: if (S_ISFIFO(statp->st_mode)) { Dmsg1(200, "Restore fifo: %s\n", ofile); if (mkfifo(ofile, statp->st_mode) != 0) { Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, strerror(errno)); - return 0; + return CF_ERROR; } } else { Dmsg1(200, "Restore node: %s\n", ofile); if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0) { Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, strerror(errno)); - return 0; + return CF_ERROR; } } Dmsg1(200, "FT_SPEC %s\n", ofile); - return 0; + return CF_CREATED; /* The following should not occur */ case FT_NOACCESS: @@ -196,11 +202,8 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, case FT_NOFSCHG: case FT_NOOPEN: Jmsg2(jcr, M_ERROR, 0, _("Original file %s not saved. Stat=%d\n"), fname, type); - return 0; default: Jmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), type, fname); - return 0; } - - return 0; + return CF_ERROR; } diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index ed362bbe05..4c7ebd9658 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -45,6 +45,14 @@ #include "save-cwd.h" +/* + * Status codes returned by create_file() + */ +#define CF_SKIP 1 /* skip file (not newer or something) */ +#define CF_ERROR 2 /* error creating file */ +#define CF_EXTRACT 3 /* file created, data to extract */ +#define CF_CREATED 4 /* file created, no data to extract */ + /* * NOTE!!! These go on the tape, so don't change them. If * need be, add to them. diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 4df73cd102..3ecadbdc56 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -234,6 +234,7 @@ static void do_extract(char *devname) */ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) { + int stat; if (rec->FileIndex < 0) { return; /* we don't want labels */ @@ -361,14 +362,22 @@ static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec) /* Pmsg1(000, "Restoring: %s\n", ofile); */ - extract = create_file(jcr, fname, ofile, lname, type, stream, - &statp, attribsEx, &ofd, REPLACE_ALWAYS); - num_files++; - - if (extract) { - print_ls_output(ofile, lname, type, &statp); - fileAddr = 0; - } + extract = FALSE; + stat = create_file(jcr, fname, ofile, lname, type, stream, + &statp, attribsEx, &ofd, REPLACE_ALWAYS); + switch (stat) { + case CF_ERROR: + case CF_SKIP: + break; + case CF_EXTRACT: + extract = TRUE; + /* Fall-through wanted */ + case CF_CREATED: + print_ls_output(ofile, lname, type, &statp); + num_files++; + fileAddr = 0; + break; + } } /* Data stream and extracting */ -- 2.39.5