Log message:
- stop delaying disk log writes
- stop placing requests into the startup queue before initial config
- added recovering_region to checkpoint data to prevent duplicate region
syncing assignment.
-static int handle_cluster_request(struct clog_tfr *tfr, int server)
+static int handle_cluster_request(struct clog_tfr *tfr, int server, int printz)
{
int r = 0;
@@ -152,27 +143,22 @@
*/
if ((tfr->request_type != DM_CLOG_RESUME) ||
(tfr->originator == my_cluster_id))
- r = do_request(tfr);
+ r = do_request(tfr, server);
if (server) {
- if (r)
- LOG_ERROR("do_request failed, unable to commit log");
- else
- r = commit_log(tfr);
-
tfr->request_type |= DM_CLOG_RESPONSE;
/*
* Errors from previous functions are in the tfr struct.
*/
-
- LOG_DBG("Sending response to %u on cluster: [%s/%llu]",
- tfr->originator,
- RQ_TYPE(tfr->request_type & ~DM_CLOG_RESPONSE),
- (unsigned long long)tfr->seq);
+ if (printz)
+ LOG_DBG("[%s] Sending response to %u on cluster: [%s/%llu]",
+ SHORT_UUID(tfr->uuid), tfr->originator,
+ RQ_TYPE(tfr->request_type & ~DM_CLOG_RESPONSE),
+ (unsigned long long)tfr->seq);
r = cluster_send(tfr);
if (r)
- LOG_ERROR("cluster_send failed");
+ LOG_ERROR("cluster_send failed: %s", strerror(-r));
}
+ lowest = match->lowest_id;
+
/* Am I leaving? */
for (i = 0; i < left_list_entries; i++)
if (my_cluster_id == left_list[i].nodeid) {
@@ -863,6 +935,7 @@
goto out;
}
@@ -871,8 +944,6 @@
if (!left_list_entries &&
(member_list_entries == 1) && (joined_list_entries == 1) &&
(member_list[0].nodeid == joined_list[0].nodeid)) {
- LOG_DBG("[%s] I am the log server (and first to join)",
- SHORT_UUID(match->name.value));
match->lowest_id = my_cluster_id = joined_list[0].nodeid;
match->valid = 1;
goto out;
@@ -894,17 +965,15 @@
}
}
- lowest = match->lowest_id;
+ if (member_list_entries)
+ match->lowest_id = member_list[0].nodeid;
+ else
+ match->lowest_id = 0xDEAD;
/* Find the lowest_id, i.e. the server */
- for (i = 0, match->lowest_id = member_list[0].nodeid;
- i < member_list_entries; i++)
+ for (i = 0; i < member_list_entries; i++)
if (match->lowest_id > member_list[i].nodeid)
match->lowest_id = member_list[i].nodeid;
- if (lowest != match->lowest_id)
- LOG_DBG("[%s] Server is now %u", SHORT_UUID(match->name.value),
- match->lowest_id);
-
/*
* If I am part of the joining list, I do not send checkpoints
* FIXME: What are the cases where multiple nodes can join?
@@ -920,6 +989,21 @@
match->checkpoints_needed += i;
-/*
- * Used by the 'touched' variable, these macros mean:
- * LOG_CHANGED - bits in the in-memory log have changed
- * LOG_FLUSH - log must be committed to disk
- */
-#define LOG_CHANGED 1
-#define LOG_FLUSH 2
-
struct log_c {
struct list_head list;
@@ -715,6 +710,7 @@
LOG_DBG("[%s] Master resume: reading disk log",
SHORT_UUID(lc->uuid));
lc->resume_override = 1000;
+ commit_log = 1;
break;
case 1:
LOG_ERROR("Error:: partial bit loading (just sync_bits)");
@@ -782,11 +778,14 @@
SHORT_UUID(lc->uuid), (unsigned long long)lc->sync_count);
lc->sync_search = 0;
- /*
- * We mark 'touched' as LOG_FLUSH so that only the master commits
- * the log via 'commit_log'
- */
- lc->touched = LOG_FLUSH;
+ if (commit_log && (lc->disk_fd >= 0)) {
+ tfr->error = write_log(lc);
+ if (tfr->error)
+ LOG_ERROR("Failed initial disk log write");
+ else
+ LOG_DBG("Disk log initialized");
+ lc->touched = 0;
+ }
out:
lc->state = LOG_RESUMED;
lc->recovery_halted = 0;
@@ -917,20 +916,34 @@
* @tfr
*
*/
-static int clog_flush(struct clog_tfr *tfr)
+static int clog_flush(struct clog_tfr *tfr, int server)
{
+ int r = 0;
struct log_c *lc = get_log(tfr->uuid);
-
+
if (!lc)
return -EINVAL;
- /*
- * Actual disk flush happens in 'commit_log()'
- * Clear LOG_CHANGED and set LOG_FLUSH
+ if (!lc->touched)
+ return 0;
+
+ /*
+ * Do the actual flushing of the log only
+ * if we are the server.
*/
- lc->touched = LOG_FLUSH;
+ if (server && (lc->disk_fd >= 0)) {
+ r = tfr->error = write_log(lc);
+ if (r) {
+ LOG_ERROR("Error writing to disk log");
+ return r;
+ }
+ LOG_DBG("[%s] Disk log written", SHORT_UUID(lc->uuid));
+ }
+
+ lc->touched = 0;
return 0;
+
}
/*
@@ -1179,14 +1192,18 @@
if (pkg->in_sync) {
if (log_test_bit(lc->sync_bits, pkg->region)) {
- LOG_PRINT(" Region already in-sync: %llu",
- (unsigned long long)pkg->region);
+ LOG_ERROR("[%s] Region already in-sync: region=%llu, seq=%llu, who=%u",
+ SHORT_UUID(lc->uuid),
+ (unsigned long long)pkg->region,
+ (unsigned long long)tfr->seq,
+ tfr->originator);
} else {
log_set_bit(lc, lc->sync_bits, pkg->region);
lc->sync_count++;
- LOG_DBG("[%s] sync_count = %llu, Region %llu marked in-sync by %u",
+ LOG_DBG("[%s] sync_count=%llu, Region %llu marked in-sync by %u, seq=%llu",
SHORT_UUID(lc->uuid), (unsigned long long)lc->sync_count,
- (unsigned long long)pkg->region, tfr->originator);
+ (unsigned long long)pkg->region, tfr->originator,
+ (unsigned long long)tfr->seq);
}
} else if (log_test_bit(lc->sync_bits, pkg->region)) {
lc->sync_count--;
@@ -1249,7 +1266,7 @@
return 0;
}
@@ -1396,6 +1413,7 @@
/*
* do_request
* @tfr: the request
+ * @server: is this request performed by the server
*
* An inability to perform this function will return an error
* from this function. However, an inability to successfully
@@ -1403,7 +1421,7 @@
*
* Returns: 0 on success, -EXXX on error
*/
-int do_request(struct clog_tfr *tfr)
+int do_request(struct clog_tfr *tfr, int server)
{
int r;
@@ -1442,7 +1460,7 @@
r = clog_in_sync(tfr);
break;
case DM_CLOG_FLUSH:
- r = clog_flush(tfr);
+ r = clog_flush(tfr, server);
break;
case DM_CLOG_MARK_REGION:
r = clog_mark_region(tfr);
@@ -1489,52 +1507,6 @@
return 0;
}
-/*
- * commit_log
- * @tfr: commit log associated with this request
- *
- * This function will also set 'tfr->error' on failure
- *
- * Returns: 0 on success, -EXXX on error
- */
-int commit_log(struct clog_tfr *tfr)
-{
- int r = 0;
- struct log_c *lc;
-
- ENTER();
-
- lc = get_log(tfr->uuid);
-
- if (!lc) {
- LOG_DBG("No log found");
- tfr->error = -EINVAL;
- r = -EINVAL;
- goto out;
- }
-
- if (!(lc->touched & LOG_FLUSH))
- goto out;
-
- if (lc->disk_fd >= 0) {
- r = tfr->error = write_log(lc);
- if (r) {
- LOG_ERROR("Error writing to disk log");
- return -EIO;
- }
- LOG_DBG("[%s] Disk log written", SHORT_UUID(lc->uuid));
- }
-
- if (lc->touched & LOG_CHANGED)
- LOG_ERROR("WARNING: Log has changed during a flush operation");
-
- lc->touched &= ~LOG_FLUSH;
-
-out:
- EXIT();
- return 0;
-}
-
static void print_bits(char *buf, int size)
{
#ifdef DEBUG
@@ -1556,7 +1528,8 @@
#endif
}
lc = get_log(uuid);
if (!lc) {
- LOG_ERROR("load_bits: No log found for %s", uuid);
+ LOG_ERROR("pull_state: No log found for %s", uuid);
return -EINVAL;
}
+ if (!strncmp(which, "recovering_region", 17)) {
+ sscanf(buf, "%llu", (unsigned long long *)&lc->recovering_region);
+ LOG_DBG("[%s] recovering_region set to %llu",
+ SHORT_UUID(uuid),
+ (unsigned long long)lc->recovering_region);
+ return 0;
+ }
+
bitset_size = lc->bitset_uint32_count * sizeof(*lc->clean_bits);
if (bitset_size != size) {
- LOG_ERROR("load_bits: bad bitset_size");
+ LOG_ERROR("pull_state(%s): bad bitset_size (%d vs %d)",
+ which, size, bitset_size);
return -EINVAL;
}
int local_resume(struct clog_tfr *tfr);
int cluster_postsuspend(char *);
-int do_request(struct clog_tfr *tfr);
-int commit_log(struct clog_tfr *tfr);
+
+int do_request(struct clog_tfr *tfr, int server);
+
+/*
int store_bits(const char *uuid, const char *which, char **buf);
int load_bits(const char *uuid, const char *which, char *buf, int size);
+*/
+int push_state(const char *uuid, const char *which, char **buf);
+int pull_state(const char *uuid, const char *which, char *buf, int size);
+
int log_get_state(struct clog_tfr *tfr);
int log_status(int);
#endif /* __CLOG_FUNCTIONS_DOT_H__ */
--- cluster/cmirror/src/Attic/local.c 2008/02/06 23:03:05 1.1.2.13
+++ cluster/cmirror/src/Attic/local.c 2008/02/08 14:30:10 1.1.2.14
@@ -166,7 +166,8 @@
case DM_CLOG_STATUS_INFO:
case DM_CLOG_STATUS_TABLE:
case DM_CLOG_PRESUSPEND:
- r = do_request(tfr);
+ /* We do not specify ourselves as server here */
+ r = do_request(tfr, 0);
if (r)
LOG_DBG("Returning failed request to kernel [%s]",
RQ_TYPE(tfr->request_type));
@@ -177,7 +178,8 @@
break;
case DM_CLOG_POSTSUSPEND:
- r = do_request(tfr);
+ /* We do not specify ourselves as server here */
+ r = do_request(tfr, 0);
if (r) {
LOG_DBG("Returning failed request to kernel [%s]",
RQ_TYPE(tfr->request_type));
@@ -212,6 +214,7 @@
LOG_ERROR("[%s] Unable to send %s to cluster: %s",
SHORT_UUID(tfr->uuid),
RQ_TYPE(tfr->request_type), strerror(-r));
+ tfr->data_size = 0;
tfr->error = r;
kernel_send(tfr);
} else {