From d269487ecbe16d55a1f4399c2b12a100d9c46405 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Sat, 31 Mar 2007 08:05:13 +0000 Subject: [PATCH] ebl Check size, age of each file after their backup to see if they have changed during backup. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4467 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/inc_conf.c | 7 +++++- bacula/src/filed/backup.c | 6 +++++ bacula/src/filed/job.c | 3 +++ bacula/src/findlib/find.h | 1 + bacula/src/findlib/find_one.c | 45 +++++++++++++++++++++++++++++++++++ bacula/src/findlib/protos.h | 2 +- bacula/technotes-2.1 | 8 +++++++ 7 files changed, 70 insertions(+), 2 deletions(-) diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 0960a59aeb..c9ebc37995 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -120,6 +120,7 @@ static RES_ITEM options_items[] = { {"noatime", store_opts, {0}, 0, 0, 0}, {"enhancedwild", store_opts, {0}, 0, 0, 0}, {"drivetype", store_drivetype, {0}, 0, 0, 0}, + {"checkfilechanges",store_opts, {0}, 0, 0, 0}, {NULL, NULL, {0}, 0, 0, 0} }; @@ -145,7 +146,8 @@ enum { INC_KW_IGNORECASE, INC_KW_HFSPLUS, INC_KW_NOATIME, - INC_KW_ENHANCEDWILD + INC_KW_ENHANCEDWILD, + INC_KW_CHKCHANGES }; /* @@ -174,6 +176,7 @@ static struct s_kw FS_option_kw[] = { {"hfsplussupport", INC_KW_HFSPLUS}, {"noatime", INC_KW_NOATIME}, {"enhancedwild", INC_KW_ENHANCEDWILD}, + {"checkfilechanges", INC_KW_CHKCHANGES}, {NULL, 0} }; @@ -239,6 +242,8 @@ static struct s_fs_opt FS_options[] = { {"no", INC_KW_NOATIME, "0"}, {"yes", INC_KW_ENHANCEDWILD, "K"}, {"no", INC_KW_ENHANCEDWILD, "0"}, + {"yes", INC_KW_CHKCHANGES, "c"}, + {"no", INC_KW_CHKCHANGES, "0"}, {NULL, 0, 0} }; diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index f218f52f15..83ba1d4f65 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -466,7 +466,13 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) } stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest); + + if (ff_pkt->flags & FO_CHKCHANGES) { + has_file_changed(jcr, ff_pkt); + } + bclose(&ff_pkt->bfd); + if (!stat) { goto bail_out; } diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 89aa461d58..13b094ec26 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -1021,6 +1021,9 @@ static void set_options(findFOPTS *fo, const char *opts) case 'K': fo->flags |= FO_NOATIME; break; + case 'c': + fo->flags |= FO_CHKCHANGES; + break; default: Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p); break; diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 7b6c7ab741..9c2e6b4c23 100644 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -107,6 +107,7 @@ enum { #define FO_ENCRYPT (1<<21) /* Encrypt data stream */ #define FO_NOATIME (1<<22) /* Use O_NOATIME to prevent atime change */ #define FO_ENHANCEDWILD (1<<23) /* Enhanced wild card processing */ +#define FO_CHKCHANGES (1<<24) /* Check if file have been modified during backup */ struct s_included_file { struct s_included_file *next; diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index 3615f8088c..d6c25fbdee 100644 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -181,6 +181,51 @@ static bool volume_has_attrlist(const char *fname) return false; } +/* check if a file have changed during backup and display an error */ +bool has_file_changed(JCR *jcr, FF_PKT *ff_pkt) +{ + struct stat statp; + Dmsg1(500, "has_file_changed fname=%s\n",ff_pkt->fname); + + if (ff_pkt->type != FT_REG) { /* not a regular file */ + return false; + } + + if (lstat(ff_pkt->fname, &statp) != 0) { + berrno be; + Jmsg(jcr, M_WARNING, 0, + _("Cannot stat file %s: ERR=%s\n"),ff_pkt->fname,be.strerror()); + return true; + } + + if (statp.st_mtime != ff_pkt->statp.st_mtime) { + /* TODO: add time of changes */ + Jmsg(jcr, M_ERROR, 0, _("%s mtime changed during backup.\n"), ff_pkt->fname); + return true; + } + + if (statp.st_ctime != ff_pkt->statp.st_ctime) { + /* TODO: add time of changes */ + Jmsg(jcr, M_ERROR, 0, _("%s ctime changed during backup.\n"), ff_pkt->fname); + return true; + } + + if (statp.st_size != ff_pkt->statp.st_size) { + /* TODO: add size change */ + Jmsg(jcr, M_ERROR, 0, _("%s size changed during backup.\n"),ff_pkt->fname); + return true; + } + + if ((statp.st_blksize != ff_pkt->statp.st_blksize) || + (statp.st_blocks != ff_pkt->statp.st_blocks)) { + /* TODO: add size change */ + Jmsg(jcr, M_ERROR, 0, _("%s size changed during backup.\n"),ff_pkt->fname); + return true; + } + + return false; +} + /* * Find a single file. * handle_file is the callback for handling the file. diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index 4999a1fb55..a2332e048f 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -65,7 +65,7 @@ int find_one_file(JCR *jcr, FF_PKT *ff, int handle_file(FF_PKT *ff_pkt, void *hpkt, bool top_level), void *pkt, char *p, dev_t parent_device, bool top_level); int term_find_one(FF_PKT *ff); - +bool has_file_changed(JCR *jcr, FF_PKT *ff_pkt); /* From get_priv.c */ int enable_backup_privileges(JCR *jcr, int ignore_errors); diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index aa6c8c493a..60e41dab84 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -1,6 +1,14 @@ Technical notes on version 2.1 General: +31Mar07 +ebl Check size and age of each file after their backup to see if + they have changed during backup. + It ask to fd to do an extra check (stat(2)) after + each file backup. mtime, ctime and size are compared with + "before backup" informations. If time or size mismatch, an + error will raise. + You must upgrade FD to use it. 30Mar07 kes Make database name and user configurable --with-db-name=xxx --with-db-user=xxx -- 2.39.5