svn commit: samba r23981 - in branches: SAMBA_3_2/source/lib SAMBA_3_2_0/source/lib

obnox at samba.org obnox at samba.org
Fri Jul 20 16:39:45 GMT 2007


Author: obnox
Date: 2007-07-20 16:39:42 +0000 (Fri, 20 Jul 2007)
New Revision: 23981

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=23981

Log:
Make tdb_validate_and_backup try harder to end up with a valid tdb:

If restoring a backup fails due to lack of space, remove the
corrupt tdb previously moved away to "name.corrupt", and retry.
If restoring still fails, move the backup in place instead of
copying it.

Michael


Modified:
   branches/SAMBA_3_2/source/lib/util_tdb.c
   branches/SAMBA_3_2_0/source/lib/util_tdb.c


Changeset:
Modified: branches/SAMBA_3_2/source/lib/util_tdb.c
===================================================================
--- branches/SAMBA_3_2/source/lib/util_tdb.c	2007-07-20 16:31:32 UTC (rev 23980)
+++ branches/SAMBA_3_2/source/lib/util_tdb.c	2007-07-20 16:39:42 UTC (rev 23981)
@@ -1183,6 +1183,7 @@
 	char *tmp_path = NULL;
 	struct stat st;
 	int count1, count2;
+	int saved_errno = 0;
 	int ret = -1;
 
 	if (stat(src_path, &st) != 0) {
@@ -1212,6 +1213,7 @@
 	if (dst_tdb == NULL) {
 		DEBUG(3, ("Error creating tdb '%s': %s\n", tmp_path,
 			  strerror(errno)));
+		saved_errno = errno;
 		unlink(tmp_path);
 		goto done;
 	}
@@ -1264,6 +1266,9 @@
 		unlink(tmp_path);
 		TALLOC_FREE(tmp_path);
 	}
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
@@ -1296,17 +1301,45 @@
  */
 static int tdb_backup_with_rotate(TALLOC_CTX *ctx, const char *src_path,
 		      		  const char *dst_path, int hash_size,
-				  const char *rotate_suffix)
+				  const char *rotate_suffix,
+				  BOOL retry_norotate_if_nospc,
+				  BOOL rename_as_last_resort_if_nospc)
 {
 	int ret;
 
-	ret = rename_file_with_suffix(ctx, dst_path, rotate_suffix);
+        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);
+        ret = tdb_backup(ctx, src_path, dst_path, hash_size);
 
-	return ret;
+	if (ret != 0) {
+		DEBUG(10, ("backup of %s failed: %s\n", src_path, strerror(errno)));
+	}
+        if ((ret != 0) && (errno == ENOSPC) && retry_norotate_if_nospc)
+        {
+                char *rotate_path = talloc_asprintf(ctx, "%s%s", dst_path,
+                                                    rotate_suffix);
+                DEBUG(10, ("backup of %s failed due to lack of space\n",
+			   src_path));
+                DEBUGADD(10, ("trying to free some space by removing rotated "
+			      "dst %s\n", rotate_path));
+                if (unlink(rotate_path) == -1) {
+                        DEBUG(10, ("unlink of %s failed: %s\n", rotate_path,
+				   strerror(errno)));
+                } else {
+                        ret = tdb_backup(ctx, src_path, dst_path, hash_size);
+                }
+                TALLOC_FREE(rotate_path);
+        }
+
+        if ((ret != 0) && (errno == ENOSPC) && rename_as_last_resort_if_nospc)
+        {
+                DEBUG(10, ("backup of %s failed due to lack of space\n", 
+			   src_path));
+                DEBUGADD(10, ("using 'rename' as a last resort\n"));
+                ret = rename(src_path, dst_path);
+        }
+
+        return ret;
 }
 
 /*
@@ -1347,7 +1380,7 @@
 	if (ret == 0) {
 		DEBUG(1, ("tdb '%s' is valid\n", tdb_path));
 		ret = tdb_backup_with_rotate(ctx, tdb_path, tdb_path_backup, 0,
-					     rotate_suffix);
+					     rotate_suffix, True, False);
 		if (ret != 0) {
 			DEBUG(1, ("Error creating backup of tdb '%s'\n",
 				  tdb_path));
@@ -1360,32 +1393,36 @@
 	} 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);
+		ret =stat(tdb_path_backup, &st);
 		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(5, ("Could not stat '%s': %s\n", tdb_path_backup,
 				  strerror(errno)));
 			DEBUG(1, ("No backup found.\n"));
-			ret = -1;
-			goto done;
+		} else {
+			DEBUG(1, ("backup '%s' found.\n", tdb_path_backup));
+			ret = tdb_validate(tdb_path_backup, validate_fn);
+			if (ret != 0) {
+				DEBUG(1, ("Backup '%s' is invalid.\n",
+					  tdb_path_backup));
+			}
 		}
-		DEBUG(1, ("backup '%s' found.\n", tdb_path_backup));
-		ret = tdb_validate(tdb_path_backup, validate_fn);
+
 		if (ret != 0) {
-			DEBUG(1, ("Backup '%s' is invalid.\n",tdb_path_backup));
+			int renamed = rename_file_with_suffix(ctx, tdb_path,
+							      corrupt_suffix);
+			if (renamed != 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));
+			}
 			goto done;
 		}
 
 		DEBUG(1, ("valid backup '%s' found\n", tdb_path_backup));
-		ret = tdb_backup(ctx, tdb_path_backup, tdb_path, 0);
+		ret = tdb_backup_with_rotate(ctx, tdb_path_backup, tdb_path, 0,
+					     corrupt_suffix, True, True);
 		if (ret != 0) {
 			DEBUG(1, ("Error restoring backup from '%s'\n",
 				  tdb_path_backup));

Modified: branches/SAMBA_3_2_0/source/lib/util_tdb.c
===================================================================
--- branches/SAMBA_3_2_0/source/lib/util_tdb.c	2007-07-20 16:31:32 UTC (rev 23980)
+++ branches/SAMBA_3_2_0/source/lib/util_tdb.c	2007-07-20 16:39:42 UTC (rev 23981)
@@ -1183,6 +1183,7 @@
 	char *tmp_path = NULL;
 	struct stat st;
 	int count1, count2;
+	int saved_errno = 0;
 	int ret = -1;
 
 	if (stat(src_path, &st) != 0) {
@@ -1212,6 +1213,7 @@
 	if (dst_tdb == NULL) {
 		DEBUG(3, ("Error creating tdb '%s': %s\n", tmp_path,
 			  strerror(errno)));
+		saved_errno = errno;
 		unlink(tmp_path);
 		goto done;
 	}
@@ -1264,6 +1266,9 @@
 		unlink(tmp_path);
 		TALLOC_FREE(tmp_path);
 	}
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
@@ -1296,17 +1301,45 @@
  */
 static int tdb_backup_with_rotate(TALLOC_CTX *ctx, const char *src_path,
 		      		  const char *dst_path, int hash_size,
-				  const char *rotate_suffix)
+				  const char *rotate_suffix,
+				  BOOL retry_norotate_if_nospc,
+				  BOOL rename_as_last_resort_if_nospc)
 {
 	int ret;
 
-	ret = rename_file_with_suffix(ctx, dst_path, rotate_suffix);
+        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);
+        ret = tdb_backup(ctx, src_path, dst_path, hash_size);
 
-	return ret;
+	if (ret != 0) {
+		DEBUG(10, ("backup of %s failed: %s\n", src_path, strerror(errno)));
+	}
+        if ((ret != 0) && (errno == ENOSPC) && retry_norotate_if_nospc)
+        {
+                char *rotate_path = talloc_asprintf(ctx, "%s%s", dst_path,
+                                                    rotate_suffix);
+                DEBUG(10, ("backup of %s failed due to lack of space\n",
+			   src_path));
+                DEBUGADD(10, ("trying to free some space by removing rotated "
+			      "dst %s\n", rotate_path));
+                if (unlink(rotate_path) == -1) {
+                        DEBUG(10, ("unlink of %s failed: %s\n", rotate_path,
+				   strerror(errno)));
+                } else {
+                        ret = tdb_backup(ctx, src_path, dst_path, hash_size);
+                }
+                TALLOC_FREE(rotate_path);
+        }
+
+        if ((ret != 0) && (errno == ENOSPC) && rename_as_last_resort_if_nospc)
+        {
+                DEBUG(10, ("backup of %s failed due to lack of space\n", 
+			   src_path));
+                DEBUGADD(10, ("using 'rename' as a last resort\n"));
+                ret = rename(src_path, dst_path);
+        }
+
+        return ret;
 }
 
 /*
@@ -1347,7 +1380,7 @@
 	if (ret == 0) {
 		DEBUG(1, ("tdb '%s' is valid\n", tdb_path));
 		ret = tdb_backup_with_rotate(ctx, tdb_path, tdb_path_backup, 0,
-					     rotate_suffix);
+					     rotate_suffix, True, False);
 		if (ret != 0) {
 			DEBUG(1, ("Error creating backup of tdb '%s'\n",
 				  tdb_path));
@@ -1360,32 +1393,36 @@
 	} 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);
+		ret =stat(tdb_path_backup, &st);
 		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(5, ("Could not stat '%s': %s\n", tdb_path_backup,
 				  strerror(errno)));
 			DEBUG(1, ("No backup found.\n"));
-			ret = -1;
-			goto done;
+		} else {
+			DEBUG(1, ("backup '%s' found.\n", tdb_path_backup));
+			ret = tdb_validate(tdb_path_backup, validate_fn);
+			if (ret != 0) {
+				DEBUG(1, ("Backup '%s' is invalid.\n",
+					  tdb_path_backup));
+			}
 		}
-		DEBUG(1, ("backup '%s' found.\n", tdb_path_backup));
-		ret = tdb_validate(tdb_path_backup, validate_fn);
+
 		if (ret != 0) {
-			DEBUG(1, ("Backup '%s' is invalid.\n",tdb_path_backup));
+			int renamed = rename_file_with_suffix(ctx, tdb_path,
+							      corrupt_suffix);
+			if (renamed != 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));
+			}
 			goto done;
 		}
 
 		DEBUG(1, ("valid backup '%s' found\n", tdb_path_backup));
-		ret = tdb_backup(ctx, tdb_path_backup, tdb_path, 0);
+		ret = tdb_backup_with_rotate(ctx, tdb_path_backup, tdb_path, 0,
+					     corrupt_suffix, True, True);
 		if (ret != 0) {
 			DEBUG(1, ("Error restoring backup from '%s'\n",
 				  tdb_path_backup));



More information about the samba-cvs mailing list