[Cluster-devel] [PATCH] qdisk: Make mixed-endian work

Lon Hohberger lhh at redhat.com
Thu Mar 19 19:54:20 UTC 2009


This patch makes mixed-endian clusters to use
qdiskd.  Unfortunately, the headers + CRCs in
the headers of each data block are stored in
little-endian format while the data itself is
stored in big-endian format.  Ew.  This patch
does not fix that, but ensures the data vs.
header blocks are stored in the right byte order
to preserve upgrade compatibility.

Signed-off-by: Lon Hohberger <lhh at redhat.com>
---
 cman/qdisk/disk.c    |   45 ++++++++++++++++++++++-----------------------
 cman/qdisk/main.c    |   14 ++++++++++----
 cman/qdisk/mkqdisk.c |    7 +++++--
 cman/qdisk/proc.c    |    7 ++++---
 4 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/cman/qdisk/disk.c b/cman/qdisk/disk.c
index 9a8d8ee..12202d5 100644
--- a/cman/qdisk/disk.c
+++ b/cman/qdisk/disk.c
@@ -53,15 +53,15 @@ static void
 header_encode(shared_header_t *hdr)
 {
 	/* sanity check - LE machine -> already encoded. */
-	if (hdr->h_magic == be_swap32(SHARED_HEADER_MAGIC))
+	if (hdr->h_magic == le_swap32(SHARED_HEADER_MAGIC))
 		return;
 
-	swab32(hdr->h_magic);
-	swab32(hdr->h_hcrc);
-	swab32(hdr->h_dcrc);
-	swab32(hdr->h_length);
-	swab64(hdr->h_view);
-	swab64(hdr->h_timestamp);
+	hdr->h_magic = le_swap32(hdr->h_magic);
+	hdr->h_hcrc = le_swap32(hdr->h_hcrc);
+	hdr->h_dcrc = le_swap32(hdr->h_dcrc);
+	hdr->h_length = le_swap32(hdr->h_length);
+	hdr->h_view = le_swap64(hdr->h_view);
+	hdr->h_timestamp = le_swap64(hdr->h_timestamp);
 }
 
 
@@ -78,12 +78,12 @@ header_decode(shared_header_t *hdr)
 	if (hdr->h_magic == SHARED_HEADER_MAGIC)
 		return;
 
-	swab32(hdr->h_magic);
-	swab32(hdr->h_hcrc);
-	swab32(hdr->h_dcrc);
-	swab32(hdr->h_length);
-	swab64(hdr->h_view);
-	swab64(hdr->h_timestamp);
+	hdr->h_magic = le_swap32(hdr->h_magic);
+	hdr->h_hcrc = le_swap32(hdr->h_hcrc);
+	hdr->h_dcrc = le_swap32(hdr->h_dcrc);
+	hdr->h_length = le_swap32(hdr->h_length);
+	hdr->h_view = le_swap64(hdr->h_view);
+	hdr->h_timestamp = le_swap64(hdr->h_timestamp);
 }
 
 
@@ -119,15 +119,15 @@ header_generate(shared_header_t *hdr, const char *data, size_t count)
 	}
 
 	hdr->h_timestamp = (uint64_t)time(NULL);
+	header_encode(hdr);
+	hdr->h_hcrc = 0;
+	hdr->h_hcrc = le_swap32(clu_crc32((char *)hdr, sizeof(*hdr)));
 
-	hdr->h_hcrc = clu_crc32((char *)hdr, sizeof(*hdr));
 	if (hdr->h_hcrc == 0) {
 		logt_print(LOG_ERR, "Invalid CRC32 generated on header!\n");
 		return -1;
 	}
 
-	header_encode(hdr);
-
 	return 0;
 }
 
@@ -148,24 +148,27 @@ header_verify(shared_header_t *hdr, const char *data, size_t count)
 	uint32_t crc;
 	uint32_t bkupcrc;
 
-	header_decode(hdr);
 	/*
 	 * verify the header's CRC32.  Ok, we know it's overkill taking
 	 * the CRC32 of a friggin' 16-byte (12 bytes, really) structure,
 	 * but why not?
 	 */
 	bkupcrc = hdr->h_hcrc;
+
+	/* BUG: Headers are stored in little-endian form */
+	bkupcrc = le_swap32(hdr->h_hcrc); 
+
 	hdr->h_hcrc = 0;
 	crc = clu_crc32((char *)hdr, sizeof(*hdr));
 	hdr->h_hcrc = bkupcrc;
 	if (bkupcrc != crc) {
-#ifdef DEBUG
 		logt_print(LOG_DEBUG, "Header CRC32 mismatch; Exp: 0x%08x "
 			"Got: 0x%08x\n", bkupcrc, crc);
-#endif
 		return -1;
 	}
 
+	header_decode(hdr);
+
 	/*
 	 * Verify the magic number.
 	 */
@@ -328,7 +331,6 @@ diskRawReadShadow(target_info_t *disk, off_t readOffset, char *buf, int len)
 	int ret;
 	shared_header_t *hdrp;
 	char *data;
-	int datalen;
 
 	ret = lseek(disk->d_fd, readOffset, SEEK_SET);
 	if (ret != readOffset) {
@@ -350,8 +352,6 @@ diskRawReadShadow(target_info_t *disk, off_t readOffset, char *buf, int len)
 	/* Decode the header portion so we can run a checksum on it. */
 	hdrp = (shared_header_t *)buf;
 	data = (char *)buf + sizeof(*hdrp);
-	swab_shared_header_t(hdrp);
-	datalen = hdrp->h_length;
 
 	if (header_verify(hdrp, data, len)) {
 #ifdef DEBUG
@@ -650,7 +650,6 @@ qdisk_write(target_info_t *disk, __off64_t offset, const void *buf, int count)
 		free((char *)hdrp);
 		return -1;
 	}
-	swab_shared_header_t(hdrp);
 
 	/* 
 	 * Locking must be performed elsewhere.  We make no assumptions
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
index 86187ee..4b69ed8 100644
--- a/cman/qdisk/main.c
+++ b/cman/qdisk/main.c
@@ -650,13 +650,19 @@ check_votes(qd_ctx *ctx, node_info_t *ni, int max, disk_msg_t *msg)
 static void
 print_node_info(FILE *fp, node_info_t *ni)
 {
+	uint64_t incarnation;
+
 	fprintf(fp, "node_info_t [node %d] {\n", ni->ni_status.ps_nodeid);
+
+	incarnation = be_swap64(ni->ni_incarnation);
 	fprintf(fp, "    ni_incarnation = 0x%08x%08x\n",
-		((int)(ni->ni_incarnation>>32))&0xffffffff,
-		((int)(ni->ni_incarnation)&0xffffffff));
+		((int)(incarnation>>32))&0xffffffff,
+		((int)(incarnation)&0xffffffff));
+
+	incarnation = be_swap64(ni->ni_evil_incarnation);
 	fprintf(fp, "    ni_evil_incarnation = 0x%08x%08x\n",
-		((int)(ni->ni_evil_incarnation>>32))&0xffffffff,
-		((int)(ni->ni_evil_incarnation)&0xffffffff));
+		((int)(incarnation>>32))&0xffffffff,
+		((int)(incarnation)&0xffffffff));
 	fprintf(fp, "    ni_last_seen = %s", ctime(&ni->ni_last_seen));
 	fprintf(fp, "    ni_misses = %d\n", ni->ni_misses);
 	fprintf(fp, "    ni_seen = %d\n", ni->ni_seen);
diff --git a/cman/qdisk/mkqdisk.c b/cman/qdisk/mkqdisk.c
index 6efa630..338bd5c 100644
--- a/cman/qdisk/mkqdisk.c
+++ b/cman/qdisk/mkqdisk.c
@@ -21,8 +21,6 @@ main(int argc, char **argv)
 	char *newdev = NULL, *newlabel = NULL;
 	int rv, verbose_level = 1;
 
-	logt_init(PROGRAM_NAME, LOG_MODE_OUTPUT_STDERR, 0, 0, 0, NULL);
-
 	printf(PROGRAM_NAME " v" RELEASE_VERSION "\n\n");
 
 	/* XXX this is horrible but we need to prioritize options as long as
@@ -32,10 +30,15 @@ main(int argc, char **argv)
 		switch (rv) {
 		case 'd':
 			++verbose_level;
+			if (verbose_level > LOG_DEBUG)
+				verbose_level = LOG_DEBUG;
 			break;
 		}
 	}
 
+	logt_init(PROGRAM_NAME, LOG_MODE_OUTPUT_STDERR,
+		  verbose_level, verbose_level, verbose_level, NULL);
+
 	/* reset the option index to reparse */
 	optind = 0;
 
diff --git a/cman/qdisk/proc.c b/cman/qdisk/proc.c
index 28bdd8b..a59613b 100644
--- a/cman/qdisk/proc.c
+++ b/cman/qdisk/proc.c
@@ -127,6 +127,7 @@ static void
 print_status_block(status_block_t *sb)
 {
 	time_t timestamp = (time_t)sb->ps_timestamp;
+	uint64_t incarnation = be_swap64(sb->ps_incarnation);
 
 	if (sb->ps_state == S_NONE)
 		return;
@@ -134,15 +135,15 @@ print_status_block(status_block_t *sb)
 	logt_print(LOG_INFO, "\tLast updated by node %d\n", sb->ps_updatenode);
 	logt_print(LOG_INFO, "\tLast updated on %s", ctime((time_t *)&timestamp));
 	logt_print(LOG_INFO, "\tState: %s\n", state_str(sb->ps_state));
-	logt_print(LOG_INFO, "\tFlags: %04x\n", sb->ps_flags);
+	logt_print(LOG_INFO, "\tFlags: %04x\n", (be_swap16(sb->ps_flags)));
 	logt_print(LOG_INFO, "\tScore: %d/%d\n", sb->ps_score, sb->ps_scoremax);
 	logt_print(LOG_INFO, "\tAverage Cycle speed: %d.%06d seconds\n", 
 		sb->ps_ca_sec, sb->ps_ca_usec);
 	logt_print(LOG_INFO, "\tLast Cycle speed: %d.%06d seconds\n", 
 		sb->ps_lc_sec, sb->ps_lc_usec);
 	logt_print(LOG_INFO, "\tIncarnation: %08x%08x\n",
-		(int)(sb->ps_incarnation>>32&0xffffffff),
-		(int)(sb->ps_incarnation&0xffffffff));
+		(int)(incarnation>>32&0xffffffff),
+		(int)(incarnation&0xffffffff));
 
 }
 
-- 
1.5.6.6




More information about the Cluster-devel mailing list