mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
Merge branch 'master' of 10.1.1.27:/shared/ctdb/ctdb-master
(This used to be ctdb commit 9b85aa1aa14091dc1de470a587f7c054b9e40078)
This commit is contained in:
commit
574b47e23f
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user