From 8500c3f8d0b232c61e0042d8d458a3bc9d9607fb Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 11 Jun 2003 20:34:13 +0000 Subject: [PATCH] Fix restore of altered special file; tweak purge/prune VolStatus git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@578 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 43 +++++++++++++------------- bacula/src/dird/autoprune.c | 6 ++-- bacula/src/dird/query.sql | 2 +- bacula/src/dird/recycle.c | 6 ++-- bacula/src/dird/ua_purge.c | 12 ++++++++ bacula/src/dird/ua_status.c | 10 +++--- bacula/src/findlib/create_file.c | 52 ++++++++++++++++++++------------ 7 files changed, 79 insertions(+), 52 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 313859278b..b0b41f8af4 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -40,24 +40,6 @@ For 1.31 release: - lstat() is not going to work on Win32 for testing date. - Implement a Recycle command - Something is not right in last block of fill command. -- Check this below from Phil. - This was SD reported data rather than FD data! - > When the job was done, Bacula reported 11084 files restored: - > - > JobId: 527 - > Job: Zocalo_Restore.2003-06-05_16.42.01 - > Client: Zocalo - > Start time: 05-Jun-2003 16:42 - > End time: 06-Jun-2003 01:21 - > Files Restored: 11,084 - > Bytes Restored: 65,474,772 - > Rate: 2.1 KB/s - > FD termination status: OK - > Termination: Restore OK - > - > when it should probably have reported 11084 files scanned, 250 restored. - > The bytes restored count looks about right. - > - If during a restore, a hard linked file already exists (on option), delete the file and re-link it. This is to avoid the possibility that the user had re-linked the file between the backup and the restore. @@ -71,13 +53,11 @@ For 1.31 release: - Check if Incremental is working correctly when it looks for the previous Job (Phil's problem). - Add next Volume to be used to status output. -- Add a recycle command. - Make bootstrap filename unique. - Sort JobIds entered into recover tree. - The bsr for Dan's job has file indexes covering the whole range rather than only the range contained on the volume. Constrain FileIndex to be within range for Volume. -- Should Bacula make an Append tape as Purged when purging? - Test a second language e.g. french. - Start working on Base jobs. - Make "make binary-release" work from any directory. @@ -85,7 +65,6 @@ For 1.31 release: - Unsaved Flag in Job record. - Base Flag in Job record. - Implement UnsavedFiles DB record. -- Use switch() in backup.c and restore.c in FD instead of giant if statement. - Implement argc/argv for daemon command line scanning using table driven stuff below. - Implement table driven single argc/argv scanner to pickup all arguments. @@ -113,6 +92,7 @@ For 1.31 release: - Implement new serialize subroutines send(socket, "string", &Vol, "uint32", &i, NULL) - Audit all UA commands to ensure that we always prompt where possible. +- Scratch Pool where the volumes can be re-assigned to any Pool. After 1.31: @@ -975,3 +955,24 @@ Done: (see kernsdone for more) - Fix restore on Win95/98 - Remove the Jmsg() in sql_find.c:102 or only print on hard error. - Implement FileSet VolIndex -- done, but must update old records. +- Check this below from Phil. + This was SD reported data rather than FD data! + > When the job was done, Bacula reported 11084 files restored: + > + > JobId: 527 + > Job: Zocalo_Restore.2003-06-05_16.42.01 + > Client: Zocalo + > Start time: 05-Jun-2003 16:42 + > End time: 06-Jun-2003 01:21 + > Files Restored: 11,084 + > Bytes Restored: 65,474,772 + > Rate: 2.1 KB/s + > FD termination status: OK + > Termination: Restore OK + > + > when it should probably have reported 11084 files scanned, 250 restored. + > The bytes restored count looks about right. + > +- Should Bacula make an Append tape as Purged when purging? +- Use switch() in backup.c and restore.c in FD instead of giant if statement. + diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index f225dc41e5..e3b8b56867 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -150,8 +150,10 @@ int prune_volumes(JCR *jcr) if (pr.PoolId != mr.PoolId) { continue; } - /* Prune only Volumes with status "Full" or "Used" */ - if (strcmp(mr.VolStatus, "Full") == 0 || strcmp(mr.VolStatus, "Used") == 0) { + /* Prune only Volumes with status "Full", "Used", or "Append" */ + if (strcmp(mr.VolStatus, "Full") == 0 || + strcmp(mr.VolStatus, "Append") == 0 || + strcmp(mr.VolStatus, "Used") == 0) { Dmsg1(200, "Prune Volume %s\n", mr.VolumeName); stat += prune_volume(&ua, &pr, &mr); Dmsg1(200, "Num pruned = %d\n", stat); diff --git a/bacula/src/dird/query.sql b/bacula/src/dird/query.sql index 9cbd51f0fa..61ecdc4c3c 100644 --- a/bacula/src/dird/query.sql +++ b/bacula/src/dird/query.sql @@ -2,7 +2,7 @@ SELECT count(*) AS Jobs, sum(JobFiles) AS Files, sum(JobBytes) AS Bytes, Name AS Job FROM Job GROUP BY Name; SELECT max(JobId) AS Jobs,sum(JobFiles) AS Files, - sum(JobBytes) As Bytes FROM Job + sum(JobBytes) As Bytes FROM Job; # :List where a file is saved: *Enter path with trailing slash: diff --git a/bacula/src/dird/recycle.c b/bacula/src/dird/recycle.c index 06e2ef8f94..72b37025e0 100644 --- a/bacula/src/dird/recycle.c +++ b/bacula/src/dird/recycle.c @@ -76,9 +76,9 @@ int recycle_oldest_purged_volume(JCR *jcr, MEDIA_DBR *mr) struct s_oldest_ctx oldest; POOLMEM *query = get_pool_memory(PM_EMSG); char *select = -"SELECT MediaId, LastWritten FROM Media " -"WHERE PoolId=%d AND Recycle=1 AND VolStatus=\"Purged\" " -"AND MediaType=\"%s\""; + "SELECT MediaId, LastWritten FROM Media " + "WHERE PoolId=%d AND Recycle=1 AND VolStatus=\"Purged\" " + "AND MediaType=\"%s\""; Dmsg0(100, "Enter recycle_oldest_purged_volume\n"); oldest.MediaId = 0; diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index f943fbcd0f..237511dcaa 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -453,6 +453,18 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) int i, stat = 0; JOB_DBR jr; + stat = strcmp(mr->VolStatus, "Append") == 0 || + strcmp(mr->VolStatus, "Full") == 0 || + strcmp(mr->VolStatus, "Used") == 0 || + strcmp(mr->VolStatus, "Error") == 0; + if (!stat) { + bsendmsg(ua, "\n"); + bsendmsg(ua, _("Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" + "The VolStatus must be: Append, Full, Used, or Error to be purged.\n"), + mr->VolumeName, mr->VolStatus); + goto bail_out; + } + memset(&jr, 0, sizeof(jr)); memset(&del, 0, sizeof(del)); cnt.count = 0; diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 4340034ba4..56a7e0301e 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -454,7 +454,7 @@ static void print_jobs_scheduled(UAContext *ua) Dmsg2(200, "tod=%d tom=%d\n", tod, tom); found = FALSE; - if (tod) { + if (tod) { /* Jobs scheduled today (next 24 hours) */ /* find time (time_t) job is to be run */ localtime_r(&now, &tm); hour = 0; @@ -477,8 +477,8 @@ static void print_jobs_scheduled(UAContext *ua) } } -// Dmsg2(200, "runtime=%d now=%d\n", runtime, now); - if (!found && tom) { +// Dmsg2(200, "runtime=%d now=%d\n", runtime, now); + if (!found && tom) { /* look at jobs scheduled tomorrow */ localtime_r(&tomorrow, &tm); hour = 0; for (i=0; i < 24; i++) { @@ -500,8 +500,8 @@ static void print_jobs_scheduled(UAContext *ua) prt_runtime(ua, job, level, runtime); } } - } - } + } /* end for loop over runs */ + } /* end for loop over resources */ UnlockRes(); Dmsg0(200, "Leave find_runs()\n"); } diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index 279f209ad9..378e8553fb 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -67,6 +67,8 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *ofd, int replace) uid_t uid; gid_t gid; int pnl; + bool exists = false; + struct stat mstatp; binit(ofd); new_mode = attr->statp.st_mode; @@ -76,27 +78,29 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *ofd, int replace) uid = attr->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(attr->ofname, &mstatp) == 0) { - switch (replace) { - case REPLACE_IFNEWER: - if (attr->statp.st_mtime <= mstatp.st_mtime) { - Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname); - return CF_SKIP; - } - break; - case REPLACE_IFOLDER: - if (attr->statp.st_mtime >= mstatp.st_mtime) { - Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname); - return CF_SKIP; - } - break; - case REPLACE_NEVER: - Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname); + if (lstat(attr->ofname, &mstatp) == 0) { + exists = true; + switch (replace) { + case REPLACE_IFNEWER: + if (attr->statp.st_mtime <= mstatp.st_mtime) { + Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname); + return CF_SKIP; + } + break; + + case REPLACE_IFOLDER: + if (attr->statp.st_mtime >= mstatp.st_mtime) { + Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname); return CF_SKIP; } + break; + + case REPLACE_NEVER: + Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname); + return CF_SKIP; + + case REPLACE_ALWAYS: + break; } } switch (attr->type) { @@ -107,6 +111,14 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *ofd, int replace) case FT_SPEC: case FT_REGE: /* empty file */ case FT_REG: /* regular file */ + if (exists) { + /* Get rid of old copy */ + if (unlink(attr->ofname) == -1) { + Jmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"), + attr->ofname, strerror(errno)); + /* Continue despite error */ + } + } /* * Here we do some preliminary work for all the above * types to create the path to the file if it does @@ -220,7 +232,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *ofd, int replace) } /* End inner switch */ case FT_DIR: - Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); + Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) { return CF_ERROR; } -- 2.39.5