diff options
author | Michael Adam <obnox@samba.org> | 2007-07-18 11:43:50 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:28:49 -0500 |
commit | 21a847473da54b6e4b41a94f781a2935f482ebaa (patch) | |
tree | 136766f4fac58057bb718ca9122c43f0e1003bc8 /source3 | |
parent | e6875b1b45577917ff9b465623502f49755aa612 (diff) | |
download | samba-21a847473da54b6e4b41a94f781a2935f482ebaa.tar.gz samba-21a847473da54b6e4b41a94f781a2935f482ebaa.tar.bz2 samba-21a847473da54b6e4b41a94f781a2935f482ebaa.zip |
r23952: Streamline and improve the logic of tdb_validate_and backup:
- call tdb_validate on the given tdb.
- if validation is successful, create a backup
return 0 (success) even if the backup fails.
- if validation fails:
- move tdb to name.corrupt (don't exit if this fails)
- look for a valid backup
- if a valid backup is found, restore it, else return -1 (failure)
if restoring succeeds, return 0 (success), else -1 (failure)
Summing up:
If 0 is returned, there is a valid tdb at the given location:
either the original one ore one restrored from a backup.
If -1 is returned, there is no valid tdb at the given location:
Either there is no file at all, or the original file is still
in place (if moving it away failed).
Michael
(This used to be commit 1c36ccd86d85b02f27ec66d37bdf7f04ad760901)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/util_tdb.c | 92 |
1 files changed, 63 insertions, 29 deletions
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index cd8eb4c8c1..26239d1c78 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -1265,6 +1265,30 @@ done: return ret; } +static int rename_file_with_suffix(TALLOC_CTX *ctx, const char *path, + const char *suffix) +{ + int ret = -1; + char *dst_path; + + dst_path = talloc_asprintf(ctx, "%s%s", path, suffix); + + ret = (rename(path, dst_path) != 0); + + if (ret == 0) { + DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path)); + } else if (errno == ENOENT) { + DEBUG(3, ("file '%s' does not exist - so not moved\n", path)); + ret = 0; + } else { + DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path, + strerror(errno))); + } + + TALLOC_FREE(dst_path); + return ret; +} + /* * do a backup of a tdb, moving the destination out of the way first */ @@ -1272,20 +1296,14 @@ static int tdb_backup_with_rotate(TALLOC_CTX *ctx, const char *src_path, const char *dst_path, int hash_size, const char *rotate_suffix) { - char *rotate_path; - int ret = -1; + int ret; - rotate_path = talloc_asprintf(ctx, "%s%s", dst_path, rotate_suffix); - if ((rename(dst_path, rotate_path) != 0) && (errno != ENOENT)) { - DEBUG(0, ("tdb_backup_with_rotate: error renaming " - "%s to %s: %s\n", dst_path, rotate_path, - strerror(errno))); - goto done; - } + ret = rename_file_with_suffix(ctx, dst_path, rotate_suffix); + + /* ignore return value of rename here: + * the more important thing is to do the backup */ ret = tdb_backup(ctx, src_path, dst_path, hash_size); -done: - TALLOC_FREE(rotate_path); return ret; } @@ -1294,11 +1312,14 @@ done: * * - calls tdb_validate * - if the tdb is ok, create a backup "name.bak", possibly moving - * existing backup to name.bak.old - * - if the tdb is corrupt, check if there is a valid backup. - * if so, move corrupt tdb to "name.corrupt", - * and restore the backup - * (give up if there is no backup or if it is invalid) + * existing backup to name.bak.old, + * return 0 (success) even if the backup fails + * - if the tdb is corrupt: + * - move the tdb to "name.corrupt" + * - check if there is valid backup. + * if so, restore the backup. + * if restore is successful, return 0 (success), + * - otherwise return -1 (failure) */ int tdb_validate_and_backup(const char *tdb_path, tdb_validate_data_func validate_fn) @@ -1328,35 +1349,48 @@ int tdb_validate_and_backup(const char *tdb_path, if (ret != 0) { DEBUG(1, ("Error creating backup of tdb '%s'\n", tdb_path)); - goto done; + /* the actual validation was successful: */ + ret = 0; + } else { + DEBUG(1, ("Created backup '%s' of tdb '%s'\n", + tdb_path_backup, tdb_path)); } - DEBUG(1, ("Created backup '%s' of tdb '%s'\n", tdb_path_backup, - tdb_path)); } else { DEBUG(1, ("tdb '%s' is invalid\n", tdb_path)); + + /* move corrupt tdb away first, but don't return on error*/ + ret = rename_file_with_suffix(ctx, tdb_path, corrupt_suffix); + if (ret != 0) { + DEBUG(1, ("Error moving tdb to '%s%s'\n", tdb_path, + corrupt_suffix)); + } else { + DEBUG(1, ("Corrupt tdb stored as '%s%s'\n", tdb_path, + corrupt_suffix)); + } + if (stat(tdb_path_backup, &st) != 0) { - DEBUG(3, ("Could not stat '%s': %s\n", tdb_path_backup, + DEBUG(5, ("Could not stat '%s': %s\n", tdb_path_backup, strerror(errno))); - DEBUG(1, ("No backup found. Giving up.\n")); + DEBUG(1, ("No backup found.\n")); + ret = -1; goto done; } + DEBUG(1, ("backup '%s' found.\n", tdb_path_backup)); ret = tdb_validate(tdb_path_backup, validate_fn); if (ret != 0) { - DEBUG(1, ("Backup '%s' found but it is invalid.\n", - tdb_path_backup)); + DEBUG(1, ("Backup '%s' is invalid.\n",tdb_path_backup)); goto done; } + DEBUG(1, ("valid backup '%s' found\n", tdb_path_backup)); - ret = tdb_backup_with_rotate(ctx, tdb_path_backup, tdb_path, 0, - corrupt_suffix); + ret = tdb_backup(ctx, tdb_path_backup, tdb_path, 0); if (ret != 0) { DEBUG(1, ("Error restoring backup from '%s'\n", tdb_path_backup)); - goto done; + } else { + DEBUG(1, ("Restored tdb backup from '%s'\n", + tdb_path_backup)); } - DEBUG(1, ("Restored tdb backup from '%s'\n", tdb_path_backup)); - DEBUGADD(1, ("Corrupt tdb stored as '%s%s'\n", tdb_path, - corrupt_suffix)); } done: |