summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2013-08-12 15:50:30 +1000
committerAmitay Isaacs <amitay@gmail.com>2013-08-14 16:55:51 +1000
commitae30b61255fd4e133ff68a697ac8a656d1fab69a (patch)
tree1e1ed2bd4ca833c612095d2d9f388653cdf2979a
parentee8d5730690ff2801f52ef62de268b6880cfac6a (diff)
downloadsamba-ae30b61255fd4e133ff68a697ac8a656d1fab69a.tar.gz
samba-ae30b61255fd4e133ff68a697ac8a656d1fab69a.tar.xz
samba-ae30b61255fd4e133ff68a697ac8a656d1fab69a.zip
vacuuming: Fix vacuuming bug where requests keep bouncing between nodes (part 2)
This is caused by corruption of a record header such that the records on two nodes point to each other as dmaster. This makes a request for that record bounce between nodes endlessly. Signed-off-by: Amitay Isaacs <amitay@gmail.com> (This used to be ctdb commit f0853013655ac3bedf1b793de128fb679c6db6c6)
-rw-r--r--ctdb/server/ctdb_recover.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c
index a89074a058..1cbcc59abe 100644
--- a/ctdb/server/ctdb_recover.c
+++ b/ctdb/server/ctdb_recover.c
@@ -785,7 +785,7 @@ bool ctdb_recovery_lock(struct ctdb_context *ctdb, bool keep)
*/
static int delete_tdb_record(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db, struct ctdb_rec_data *rec)
{
- TDB_DATA key, data;
+ TDB_DATA key, data, data2;
struct ctdb_ltdb_header *hdr, *hdr2;
/* these are really internal tdb functions - but we need them here for
@@ -816,13 +816,13 @@ static int delete_tdb_record(struct ctdb_context *ctdb, struct ctdb_db_context *
return -1;
}
- data = tdb_fetch(ctdb_db->ltdb->tdb, key);
- if (data.dptr == NULL) {
+ data2 = tdb_fetch(ctdb_db->ltdb->tdb, key);
+ if (data2.dptr == NULL) {
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
return 0;
}
- if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
+ if (data2.dsize < sizeof(struct ctdb_ltdb_header)) {
if (tdb_lock_nonblock(ctdb_db->ltdb->tdb, -1, F_WRLCK) == 0) {
if (tdb_delete(ctdb_db->ltdb->tdb, key) != 0) {
DEBUG(DEBUG_CRIT,(__location__ " Failed to delete corrupt record\n"));
@@ -831,59 +831,59 @@ static int delete_tdb_record(struct ctdb_context *ctdb, struct ctdb_db_context *
DEBUG(DEBUG_CRIT,(__location__ " Deleted corrupt record\n"));
}
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
- free(data.dptr);
+ free(data2.dptr);
return 0;
}
- hdr2 = (struct ctdb_ltdb_header *)data.dptr;
+ hdr2 = (struct ctdb_ltdb_header *)data2.dptr;
if (hdr2->rsn > hdr->rsn) {
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
DEBUG(DEBUG_INFO,(__location__ " Skipping record with rsn=%llu - called with rsn=%llu\n",
(unsigned long long)hdr2->rsn, (unsigned long long)hdr->rsn));
- free(data.dptr);
- return -1;
+ free(data2.dptr);
+ return -1;
}
/* do not allow deleting record that have readonly flags set. */
if (hdr->flags & CTDB_REC_RO_FLAGS) {
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
DEBUG(DEBUG_INFO,(__location__ " Skipping record with readonly flags set\n"));
- free(data.dptr);
- return -1;
+ free(data2.dptr);
+ return -1;
}
if (hdr2->flags & CTDB_REC_RO_FLAGS) {
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
DEBUG(DEBUG_INFO,(__location__ " Skipping record with readonly flags set\n"));
- free(data.dptr);
- return -1;
+ free(data2.dptr);
+ return -1;
}
if (hdr2->dmaster == ctdb->pnn) {
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
DEBUG(DEBUG_INFO,(__location__ " Attempted delete record where we are the dmaster\n"));
- free(data.dptr);
- return -1;
+ free(data2.dptr);
+ return -1;
}
if (tdb_lock_nonblock(ctdb_db->ltdb->tdb, -1, F_WRLCK) != 0) {
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
- free(data.dptr);
- return -1;
+ free(data2.dptr);
+ return -1;
}
if (tdb_delete(ctdb_db->ltdb->tdb, key) != 0) {
tdb_unlock(ctdb_db->ltdb->tdb, -1, F_WRLCK);
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
DEBUG(DEBUG_INFO,(__location__ " Failed to delete record\n"));
- free(data.dptr);
- return -1;
+ free(data2.dptr);
+ return -1;
}
tdb_unlock(ctdb_db->ltdb->tdb, -1, F_WRLCK);
tdb_chainunlock(ctdb_db->ltdb->tdb, key);
- free(data.dptr);
- return 0;
+ free(data2.dptr);
+ return 0;
}