RAID-6 check standalone md device
Allow RAID-6 check to be passed only the MD device, start and length. The three parameters are mandatory. All necessary information is collected using the "sysfs_read()" call. Furthermore, if "length" is "0", then the check is performed until the end of the array. Some checks are done, for example if the md device is really a RAID-6. Nevertheless I guess it is not bullet proof... Next patch will include the "suspend" action. My idea is to do it "per stripe", please let me know if you've some better options. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
78c0a3b17f
commit
a9c2c6c697
6
Makefile
6
Makefile
|
@ -107,7 +107,7 @@ OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o util.o maps.o lib.o \
|
||||||
restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o \
|
restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o \
|
||||||
platform-intel.o probe_roms.o
|
platform-intel.o probe_roms.o
|
||||||
|
|
||||||
OBJSX = restripe.o
|
CHECK_OBJS = restripe.o sysfs.o maps.o lib.o
|
||||||
|
|
||||||
SRCS = $(patsubst %.o,%.c,$(OBJS))
|
SRCS = $(patsubst %.o,%.c,$(OBJS))
|
||||||
|
|
||||||
|
@ -177,8 +177,8 @@ msg.o: msg.c msg.h
|
||||||
test_stripe : restripe.c mdadm.h
|
test_stripe : restripe.c mdadm.h
|
||||||
$(CC) $(CXFLAGS) $(LDFLAGS) -o test_stripe -DMAIN restripe.c
|
$(CC) $(CXFLAGS) $(LDFLAGS) -o test_stripe -DMAIN restripe.c
|
||||||
|
|
||||||
raid6check : raid6check.o mdadm.h $(OBJSX)
|
raid6check : raid6check.o mdadm.h $(CHECK_OBJS)
|
||||||
$(CC) $(CXFLAGS) $(LDFLAGS) -o raid6check raid6check.o $(OBJSX)
|
$(CC) $(CXFLAGS) $(LDFLAGS) -o raid6check raid6check.o $(CHECK_OBJS)
|
||||||
|
|
||||||
mdassemble : $(ASSEMBLE_SRCS) $(INCL)
|
mdassemble : $(ASSEMBLE_SRCS) $(INCL)
|
||||||
rm -f $(OBJS)
|
rm -f $(OBJS)
|
||||||
|
|
110
raid6check.c
110
raid6check.c
|
@ -159,7 +159,7 @@ int check_stripes(int *source, unsigned long long *offsets,
|
||||||
level, layout);
|
level, layout);
|
||||||
}
|
}
|
||||||
if(disk >= 0) {
|
if(disk >= 0) {
|
||||||
printf("Possible failed disk: %d --> %s\n", disk, name[disk]);
|
printf("Possible failed disk slot: %d --> %s\n", disk, name[disk]);
|
||||||
}
|
}
|
||||||
if(disk == -65535) {
|
if(disk == -65535) {
|
||||||
printf("Failure detected, but disk unknown\n");
|
printf("Failure detected, but disk unknown\n");
|
||||||
|
@ -192,71 +192,121 @@ unsigned long long getnum(char *str, char **err)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* raid_disks chunk_size layout start length devices...
|
/* md_device start length */
|
||||||
*/
|
|
||||||
int *fds;
|
int *fds;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
char **disk_name;
|
||||||
unsigned long long *offsets;
|
unsigned long long *offsets;
|
||||||
int raid_disks, chunk_size, layout;
|
int raid_disks, chunk_size, layout;
|
||||||
int level = 6;
|
int level = 6;
|
||||||
unsigned long long start, length;
|
unsigned long long start, length;
|
||||||
int i;
|
int i;
|
||||||
|
int mdfd;
|
||||||
|
struct mdinfo *info, *comp;
|
||||||
char *err = NULL;
|
char *err = NULL;
|
||||||
if (argc < 8) {
|
const char prg[] = "raid6check";
|
||||||
fprintf(stderr, "Usage: raid6check raid_disks"
|
|
||||||
" chunk_size layout start length devices...\n");
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "Usage: %s md_device start length\n", prg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
raid_disks = getnum(argv[1], &err);
|
mdfd = open(argv[1], O_RDONLY);
|
||||||
chunk_size = getnum(argv[2], &err);
|
if(mdfd < 0) {
|
||||||
layout = getnum(argv[3], &err);
|
perror(argv[1]);
|
||||||
start = getnum(argv[4], &err);
|
fprintf(stderr,"%s: cannot open %s\n", prg, argv[1]);
|
||||||
length = getnum(argv[5], &err);
|
exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
info = sysfs_read(mdfd, -1,
|
||||||
|
GET_LEVEL|
|
||||||
|
GET_LAYOUT|
|
||||||
|
GET_DISKS|
|
||||||
|
GET_COMPONENT|
|
||||||
|
GET_CHUNK|
|
||||||
|
GET_DEVS|
|
||||||
|
GET_OFFSET|
|
||||||
|
GET_SIZE);
|
||||||
|
|
||||||
|
if(info->array.level != level) {
|
||||||
|
fprintf(stderr, "%s: %s not a RAID-6\n", prg, argv[1]);
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("layout: %d\n", info->array.layout);
|
||||||
|
printf("disks: %d\n", info->array.raid_disks);
|
||||||
|
printf("component size: %llu\n", info->component_size*512);
|
||||||
|
printf("chunk size: %d\n", info->array.chunk_size);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
comp = info->devs;
|
||||||
|
for(i = 0; i < info->array.raid_disks; i++) {
|
||||||
|
printf("disk: %d - offset: %llu - size: %llu - name: %s - slot: %d\n",
|
||||||
|
i, comp->data_offset, comp->component_size*512,
|
||||||
|
map_dev(comp->disk.major, comp->disk.minor, 0),
|
||||||
|
comp->disk.raid_disk);
|
||||||
|
|
||||||
|
comp = comp->next;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
close(mdfd);
|
||||||
|
|
||||||
|
raid_disks = info->array.raid_disks;
|
||||||
|
chunk_size = info->array.chunk_size;
|
||||||
|
layout = info->array.layout;
|
||||||
|
start = getnum(argv[2], &err);
|
||||||
|
length = getnum(argv[3], &err);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "test_stripe: Bad number: %s\n", err);
|
fprintf(stderr, "%s: Bad number: %s\n", prg, err);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (argc != raid_disks + 6) {
|
|
||||||
fprintf(stderr, "test_stripe: wrong number of devices: want %d found %d\n",
|
start = (start / chunk_size) * chunk_size;
|
||||||
raid_disks, argc-6);
|
|
||||||
exit(2);
|
if(length == 0) {
|
||||||
|
length = info->component_size * 512 - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disk_name = malloc(raid_disks * sizeof(*disk_name));
|
||||||
fds = malloc(raid_disks * sizeof(*fds));
|
fds = malloc(raid_disks * sizeof(*fds));
|
||||||
offsets = malloc(raid_disks * sizeof(*offsets));
|
offsets = malloc(raid_disks * sizeof(*offsets));
|
||||||
memset(offsets, 0, raid_disks * sizeof(*offsets));
|
memset(offsets, 0, raid_disks * sizeof(*offsets));
|
||||||
|
|
||||||
|
comp = info->devs;
|
||||||
for (i=0; i<raid_disks; i++) {
|
for (i=0; i<raid_disks; i++) {
|
||||||
char *p;
|
int disk_slot = comp->disk.raid_disk;
|
||||||
p = strchr(argv[6+i], ':');
|
disk_name[disk_slot] = map_dev(comp->disk.major, comp->disk.minor, 0);
|
||||||
|
offsets[disk_slot] = comp->data_offset * 512;
|
||||||
if(p != NULL) {
|
fds[disk_slot] = open(disk_name[disk_slot], O_RDWR);
|
||||||
*p++ = '\0';
|
if (fds[disk_slot] < 0) {
|
||||||
offsets[i] = atoll(p) * 512;
|
perror(disk_name[disk_slot]);
|
||||||
}
|
fprintf(stderr,"%s: cannot open %s\n", prg, disk_name[disk_slot]);
|
||||||
fds[i] = open(argv[6+i], O_RDWR);
|
|
||||||
if (fds[i] < 0) {
|
|
||||||
perror(argv[6+i]);
|
|
||||||
fprintf(stderr,"test_stripe: cannot open %s.\n", argv[6+i]);
|
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comp = comp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = malloc(raid_disks * chunk_size);
|
buf = malloc(raid_disks * chunk_size);
|
||||||
|
|
||||||
int rv = check_stripes(fds, offsets,
|
int rv = check_stripes(fds, offsets,
|
||||||
raid_disks, chunk_size, level, layout,
|
raid_disks, chunk_size, level, layout,
|
||||||
start, length, &argv[6]);
|
start, length, disk_name);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"test_stripe: test_stripes returned %d\n", rv);
|
"%s: check_stripes returned %d\n", prg, rv);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(disk_name);
|
||||||
free(fds);
|
free(fds);
|
||||||
free(offsets);
|
free(offsets);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
|
for(i=0; i<raid_disks; i++)
|
||||||
|
close(fds[i]);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue