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 <[email protected]> --- 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 *)×tamp)); 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
