#include "mdadm.h"
#include <stdint.h>
+#include <signal.h>
+#include <sys/mman.h>
int geo_map(int block, unsigned long long stripe, int raid_disks,
int level, int layout);
return curr_broken_disk;
}
-int check_stripes(int *source, unsigned long long *offsets,
+int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets,
int raid_disks, int chunk_size, int level, int layout,
unsigned long long start, unsigned long long length, char *name[])
{
int diskP, diskQ;
int data_disks = raid_disks - 2;
int err = 0;
+ sighandler_t sig[3];
+ int rv;
extern int tables_ready;
printf("pos --> %llu\n", start);
+ if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
+ err = 2;
+ goto exitCheck;
+ }
+ sig[0] = signal(SIGTERM, SIG_IGN);
+ sig[1] = signal(SIGINT, SIG_IGN);
+ sig[2] = signal(SIGQUIT, SIG_IGN);
+ rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks);
+ rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks);
for (i = 0 ; i < raid_disks ; i++) {
lseek64(source[i], offsets[i] + start * chunk_size, 0);
read(source[i], stripes[i], chunk_size);
}
+ rv |= sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
+ rv |= sysfs_set_num(info, NULL, "suspend_hi", 0);
+ rv |= sysfs_set_num(info, NULL, "suspend_lo", 0);
+ signal(SIGQUIT, sig[2]);
+ signal(SIGINT, sig[1]);
+ signal(SIGTERM, sig[0]);
+ if(munlockall() != 0) {
+ err = 3;
+ goto exitCheck;
+ }
+
+ if(rv != 0) {
+ err = rv * 256;
+ goto exitCheck;
+ }
+
for (i = 0 ; i < data_disks ; i++) {
int disk = geo_map(i, start, raid_disks, level, layout);
blocks[i] = stripes[disk];
char **disk_name = NULL;
unsigned long long *offsets = NULL;
int raid_disks = 0;
+ int active_disks;
int chunk_size = 0;
int layout = -1;
int level = 6;
unsigned long long start, length;
int i;
int mdfd;
- struct mdinfo *info, *comp;
+ struct mdinfo *info = NULL, *comp = NULL;
char *err = NULL;
int exit_err = 0;
int close_flag = 0;
GET_LEVEL|
GET_LAYOUT|
GET_DISKS|
+ GET_DEGRADED |
GET_COMPONENT|
GET_CHUNK|
GET_DEVS|
GET_OFFSET|
GET_SIZE);
+ if(info == NULL) {
+ fprintf(stderr, "%s: Error reading sysfs information of %s\n", prg, argv[1]);
+ exit_err = 9;
+ goto exitHere;
+ }
+
if(info->array.level != level) {
fprintf(stderr, "%s: %s not a RAID-6\n", prg, argv[1]);
exit_err = 3;
goto exitHere;
}
+ if(info->array.failed_disks > 0) {
+ fprintf(stderr, "%s: %s degraded array\n", prg, argv[1]);
+ exit_err = 8;
+ goto exitHere;
+ }
+
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("\n");
comp = info->devs;
- for(i = 0; i < info->array.raid_disks; i++) {
+ for(i = 0, active_disks = 0; active_disks < info->array.raid_disks; i++) {
printf("disk: %d - offset: %llu - size: %llu - name: %s - slot: %d\n",
i, comp->data_offset * 512, comp->component_size * 512,
map_dev(comp->disk.major, comp->disk.minor, 0),
comp->disk.raid_disk);
-
+ if(comp->disk.raid_disk >= 0)
+ active_disks++;
comp = comp->next;
}
printf("\n");
close_flag = 1;
comp = info->devs;
- for (i=0; i<raid_disks; i++) {
+ for (i=0, active_disks=0; active_disks<raid_disks; i++) {
int disk_slot = comp->disk.raid_disk;
- disk_name[disk_slot] = map_dev(comp->disk.major, comp->disk.minor, 0);
- offsets[disk_slot] = comp->data_offset * 512;
- fds[disk_slot] = open(disk_name[disk_slot], O_RDWR);
- if (fds[disk_slot] < 0) {
- perror(disk_name[disk_slot]);
- fprintf(stderr,"%s: cannot open %s\n", prg, disk_name[disk_slot]);
- exit_err = 6;
- goto exitHere;
+ if(disk_slot >= 0) {
+ disk_name[disk_slot] = map_dev(comp->disk.major, comp->disk.minor, 0);
+ offsets[disk_slot] = comp->data_offset * 512;
+ fds[disk_slot] = open(disk_name[disk_slot], O_RDWR);
+ if (fds[disk_slot] < 0) {
+ perror(disk_name[disk_slot]);
+ fprintf(stderr,"%s: cannot open %s\n", prg, disk_name[disk_slot]);
+ exit_err = 6;
+ goto exitHere;
+ }
+ active_disks++;
}
-
comp = comp->next;
}
- int rv = check_stripes(fds, offsets,
+ int rv = check_stripes(info, fds, offsets,
raid_disks, chunk_size, level, layout,
start, length, disk_name);
if (rv != 0) {