Skip to content

Instantly share code, notes, and snippets.

@jandk
Created January 30, 2012 12:21
Show Gist options
  • Save jandk/1704129 to your computer and use it in GitHub Desktop.
Save jandk/1704129 to your computer and use it in GitHub Desktop.
Manual repair of RAID5 (Version which actually ran)
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#define STRIPESIZE (64 * 1024)
#define BUFSIZE (2 * STRIPESIZE)
#define MIB16 (16 * 1024 * 1024)
#define GIB (1024 * 1024 * 1024)
void xor(uint8_t* src1, uint8_t* src2, uint32_t len) {
uint32_t i, count = len / 4;
uint32_t *s1, *s2;
s1 = (uint32_t *)src1;
s2 = (uint32_t *)src2;
for(i = 0; i < count; i += 4) {
s1[i+0] ^= s2[i+0];
s1[i+1] ^= s2[i+1];
s1[i+2] ^= s2[i+2];
s1[i+3] ^= s2[i+3];
}
}
int main(int argc, char** argv) {
if(argc <= 4) {
printf("I'm not even going to explain what this does.\n");
printf("\n");
printf(" 1: Source disk 1\n");
printf(" 2: Source disk 2\n");
printf(" 3: Destination disk\n");
printf(" 4: Source disk offset\n");
return 1;
}
int fd0, fd1, fdd;
uint64_t maxoffset, offset, dstoffset, numrows, cur;
uint8_t *buf0, *buf1, *tmp;
/* Try opening all files */
fd0 = open(argv[1], O_RDONLY);
if(fd0 == -1) { fprintf(stderr, "%s\n", strerror(errno)); }
fd1 = open(argv[2], O_RDONLY);
if(fd1 == -1) { fprintf(stderr, "%s\n", strerror(errno)); }
fdd = open(argv[3], O_WRONLY);
if(fdd == -1) { fprintf(stderr, "%s\n", strerror(errno)); }
/* Read maxoffset */
maxoffset = strtoull(argv[4], NULL, 16);
numrows = maxoffset / STRIPESIZE;
printf("Number of stripe rows: %#llx\n\n", numrows);
/* Alloc buffers */
buf0 = (uint8_t*) malloc(STRIPESIZE);
buf1 = (uint8_t*) malloc(STRIPESIZE);
if(!buf0 || !buf1) {
fprintf(stderr, "Could not allocate memory");
return 2;
}
offset = 0; dstoffset = 0;
for(cur = 0; cur < numrows; cur++) {
// Always in reversed order
// printf("fd0 => buf0 | offset 0x%12llx\n", offset);
read(fd0, buf0, STRIPESIZE);
// printf("fd1 => buf1 | offset 0x%12llx\n", offset);
read(fd1, buf1, STRIPESIZE);
offset += STRIPESIZE;
switch(cur % 3) {
case 0:
// printf("buf0 ^= buf1\n");
xor(buf0, buf1, STRIPESIZE);
break;
case 1:
// printf("buf1 ^= buf0\n");
xor(buf1, buf0, STRIPESIZE);
// printf("buf0 <> buf1\n");
tmp = buf0; buf0 = buf1; buf1 = tmp;
break;
case 2:
// printf("buf0 <> buf1\n");
tmp = buf0; buf0 = buf1; buf1 = tmp;
break;
default:
fprintf(stderr, "Switch not possible\n");
return 3;
}
// printf("buf0 => fdd | offset 0x%12llx\n", dstoffset);
write(fdd, buf0, STRIPESIZE);
dstoffset += STRIPESIZE;
// printf("buf1 => fdd | offset 0x%12llx\n", dstoffset);
write(fdd, buf1, STRIPESIZE);
dstoffset += STRIPESIZE;
if(!((dstoffset + BUFSIZE) & (MIB16 - 1)))
{
printf(".");
if(!((dstoffset + BUFSIZE) & (GIB - 1)))
printf(" %3lld GiB\n", dstoffset / GIB);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment