summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2012-02-21 07:12:50 +1100
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2012-02-21 07:12:50 +1100
commit574b47e23fd141e96357cc596fe215f7f5c5007b (patch)
tree040d6e270683ae2a5298986c53e8fb2cd23a2ed5
parentbaa3d7ea39c9b8225fd041e30745db1e1e683534 (diff)
parent42e477b14e0c690be28115825ac61f890e84d1c4 (diff)
downloadsamba-574b47e23fd141e96357cc596fe215f7f5c5007b.tar.gz
samba-574b47e23fd141e96357cc596fe215f7f5c5007b.tar.xz
samba-574b47e23fd141e96357cc596fe215f7f5c5007b.zip
Merge branch 'master' of 10.1.1.27:/shared/ctdb/ctdb-master
(This used to be ctdb commit 9b85aa1aa14091dc1de470a587f7c054b9e40078)
-rw-r--r--ctdb/client/ctdb_client.c4
-rw-r--r--ctdb/common/ctdb_util.c1
-rw-r--r--ctdb/include/ctdb_private.h3
-rw-r--r--ctdb/server/ctdb_ltdb_server.c5
-rw-r--r--ctdb/server/ctdb_persistent.c33
-rw-r--r--ctdb/server/ctdb_vacuum.c10
6 files changed, 29 insertions, 27 deletions
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index 0d0f2fea44..1b4143985f 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/client/ctdb_client.c
@@ -4123,7 +4123,9 @@ int switch_from_server_to_client(struct ctdb_context *ctdb, const char *fmt, ...
return -1;
}
- return 0;
+ ctdb->can_send_controls = true;
+
+ return 0;
}
/*
diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c
index bb32b6a345..dadaf18f1e 100644
--- a/ctdb/common/ctdb_util.c
+++ b/ctdb/common/ctdb_util.c
@@ -346,6 +346,7 @@ pid_t ctdb_fork(struct ctdb_context *ctdb)
if (ctdb->do_setsched) {
ctdb_restore_scheduler(ctdb);
}
+ ctdb->can_send_controls = false;
}
return pid;
}
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index f420e6c341..272b94aa86 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -483,6 +483,9 @@ struct ctdb_context {
/* Used to defer db attach requests while in recovery mode */
struct ctdb_deferred_attach_context *deferred_attach;
+
+ /* if we are a child process, do we have a domain socket to send controls on */
+ bool can_send_controls;
};
struct ctdb_db_context {
diff --git a/ctdb/server/ctdb_ltdb_server.c b/ctdb/server/ctdb_ltdb_server.c
index e699c2ad80..8e183e87a4 100644
--- a/ctdb/server/ctdb_ltdb_server.c
+++ b/ctdb/server/ctdb_ltdb_server.c
@@ -83,7 +83,7 @@ static int ctdb_ltdb_store_server(struct ctdb_db_context *ctdb_db,
*/
if (data.dsize != 0) {
keep = true;
- } else if (header->flags & (CTDB_REC_RO_HAVE_DELEGATIONS|CTDB_REC_RO_HAVE_READONLY)) {
+ } else if (header->flags & (CTDB_REC_RO_HAVE_DELEGATIONS|CTDB_REC_RO_HAVE_READONLY|CTDB_REC_RO_REVOKING_READONLY|CTDB_REC_RO_REVOKE_COMPLETE)) {
keep = true;
} else if (ctdb_db->persistent) {
keep = true;
@@ -128,7 +128,8 @@ static int ctdb_ltdb_store_server(struct ctdb_db_context *ctdb_db,
if (keep) {
if ((data.dsize == 0) &&
!ctdb_db->persistent &&
- (ctdb_db->ctdb->pnn == header->dmaster))
+ (ctdb_db->ctdb->pnn == header->dmaster) &&
+ !(header->flags & (CTDB_REC_RO_HAVE_DELEGATIONS|CTDB_REC_RO_HAVE_READONLY|CTDB_REC_RO_REVOKING_READONLY|CTDB_REC_RO_REVOKE_COMPLETE)))
{
schedule_for_deletion = true;
}
diff --git a/ctdb/server/ctdb_persistent.c b/ctdb/server/ctdb_persistent.c
index 0f4f4da52d..dd8d4793fb 100644
--- a/ctdb/server/ctdb_persistent.c
+++ b/ctdb/server/ctdb_persistent.c
@@ -456,12 +456,12 @@ static int ctdb_persistent_store(struct ctdb_persistent_write_state *state)
}
for (i=0;i<m->count;i++) {
- struct ctdb_ltdb_header *oldheader;
- struct ctdb_ltdb_header *header;
+ struct ctdb_ltdb_header oldheader;
+ struct ctdb_ltdb_header header;
TDB_DATA key, data, olddata;
TALLOC_CTX *tmp_ctx = talloc_new(state);
- rec = ctdb_marshall_loop_next(m, rec, NULL, NULL, &key, &data);
+ rec = ctdb_marshall_loop_next(m, rec, NULL, &header, &key, &data);
if (rec == NULL) {
DEBUG(DEBUG_ERR,("Failed to get next record %d for db_id 0x%08x in ctdb_persistent_store\n",
@@ -469,42 +469,29 @@ static int ctdb_persistent_store(struct ctdb_persistent_write_state *state)
talloc_free(tmp_ctx);
goto failed;
}
- header = (struct ctdb_ltdb_header *)&data.dptr[0];
/* fetch the old header and ensure the rsn is less than the new rsn */
- olddata = tdb_fetch(state->ctdb_db->ltdb->tdb, key);
- if (olddata.dptr == NULL) {
+ ret = ctdb_ltdb_fetch(state->ctdb_db, key, &oldheader, tmp_ctx, &olddata);
+ if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to fetch old record for db_id 0x%08x in ctdb_persistent_store\n",
state->ctdb_db->db_id));
talloc_free(tmp_ctx);
goto failed;
}
- if (olddata.dsize < sizeof(struct ctdb_ltdb_header)) {
- DEBUG(DEBUG_ERR,("Not enough header for record for db_id 0x%08x in ctdb_persistent_store\n",
- state->ctdb_db->db_id));
- talloc_free(tmp_ctx);
- free(olddata.dptr);
- goto failed;
- }
- oldheader = (struct ctdb_ltdb_header *)&olddata.dptr[0];
- if (oldheader->rsn >= header->rsn &&
- (olddata.dsize != data.dsize ||
- memcmp(&olddata.dptr[sizeof(struct ctdb_ltdb_header)],
- &data.dptr[sizeof(struct ctdb_ltdb_header)],
- data.dsize - sizeof(struct ctdb_ltdb_header)) != 0)) {
+ if (oldheader.rsn >= header.rsn &&
+ (olddata.dsize != data.dsize ||
+ memcmp(olddata.dptr, data.dptr, data.dsize) != 0)) {
DEBUG(DEBUG_CRIT,("existing header for db_id 0x%08x has larger RSN %llu than new RSN %llu in ctdb_persistent_store\n",
state->ctdb_db->db_id,
- (unsigned long long)oldheader->rsn, (unsigned long long)header->rsn));
+ (unsigned long long)oldheader.rsn, (unsigned long long)header.rsn));
talloc_free(tmp_ctx);
- free(olddata.dptr);
goto failed;
}
talloc_free(tmp_ctx);
- free(olddata.dptr);
- ret = tdb_store(state->ctdb_db->ltdb->tdb, key, data, TDB_REPLACE);
+ ret = ctdb_ltdb_store(state->ctdb_db, key, &header, data);
if (ret != 0) {
DEBUG(DEBUG_CRIT,("Failed to store record for db_id 0x%08x in ctdb_persistent_store\n",
state->ctdb_db->db_id));
diff --git a/ctdb/server/ctdb_vacuum.c b/ctdb/server/ctdb_vacuum.c
index ff373564f8..e0e1e3b508 100644
--- a/ctdb/server/ctdb_vacuum.c
+++ b/ctdb/server/ctdb_vacuum.c
@@ -1560,8 +1560,16 @@ int32_t ctdb_local_schedule_for_deletion(struct ctdb_db_context *ctdb_db,
return ret;
}
- /* child process: send the main daemon a control */
+ /* if we dont have a connection to the daemon we can not send
+ a control. For example sometimes from update_record control child
+ process.
+ */
+ if (!ctdb_db->ctdb->can_send_controls) {
+ return -1;
+ }
+
+ /* child process: send the main daemon a control */
indata.dsize = offsetof(struct ctdb_control_schedule_for_deletion, key) + key.dsize;
indata.dptr = talloc_zero_array(ctdb_db, uint8_t, indata.dsize);
if (indata.dptr == NULL) {