📄 lsraid.c
字号:
{ ent = list_entry(pos, LSRNamEnt, list); free(ent); } if (ctxt->devtable) { for (i = 0; i < MAJORS; i++) if (ctxt->devtable[i]) free(ctxt->devtable[i]); free(ctxt->devtable); } free(ctxt);} /* clean_context() */static void disk_state_online(LSRDisk *disk, char *state){ if (!disk || !state) return; if (disk->info.state & (1<<MD_DISK_REMOVED)) sprintf(state, "removed"); else if (disk->info.state & (1<<MD_DISK_FAULTY)) sprintf(state, "failed"); else if (disk->info.state & (1<<MD_DISK_ACTIVE)) sprintf(state, "good"); else sprintf(state, "spare");} /* disk_state_online() */static void disk_state_offline(LSRDisk *disk, char *state){ if (!disk || !state) return; if (disk->sb.this_disk.state & (1<<MD_DISK_REMOVED)) sprintf(state, "removed"); else if (disk->sb.this_disk.state & (1<<MD_DISK_FAULTY)) sprintf(state, "failed"); else if (disk->sb.this_disk.state & (1<<MD_DISK_ACTIVE)) sprintf(state, "good"); else sprintf(state, "spare");#if 0 /* I don't think this matters */ if (!(disk->sb.this_disk.state & (1<<MD_DISK_SYNC))) strcat(state, " (unsynced)");#endif} /* disk_state_offline() *//* For convenience, this is a static buffer */static const char *disk_state(LSRDisk *disk){ static char *state = NULL; if (!state) { state = (char *)malloc(255 * sizeof(char)); if (!state) return("unknown"); } state[0] = '\0'; if (disk->info.major) disk_state_online(disk, state); else if (disk->array) disk_state_offline(disk, state); else strcat(state, "unknown"); return(state);} /* disk_state() */static void dump_disk_short(LSRDisk *disk){ const char *state; if (!disk || !disk->major || !disk->sb.md_magic) return; state = disk_state(disk); fprintf(stdout, "[dev %d, %d] %s:\n", disk->major, disk->minor, disk->name ? disk->name : "(unknown)\n"); if (disk->array) { fprintf(stdout, "\tmd device\t= [dev %d, %d] %s\n" "\tmd uuid\t\t= %08X.%08X.%08X.%08X\n", MD_MAJOR, disk->array->minor, disk->array->name, disk->array->uuid0, disk->array->uuid1, disk->array->uuid2, disk->array->uuid3); } else { fprintf(stdout, "\told md device\t= [dev %d, %d]\n" "\told md uuid\t= %08X.%08X.%08X.%08X\n", MD_MAJOR, disk->sb.md_minor, disk->sb.set_uuid0, disk->sb.set_uuid1, disk->sb.set_uuid2, disk->sb.set_uuid3); } fprintf(stdout, "\tstate\t\t= %s\n", state); if (*state == 'a') fprintf(stdout, "\tarray position\t= %d\n", disk->info.major ? disk->info.raid_disk : disk->sb.this_disk.raid_disk); fprintf(stdout, "\n");} /* dump_disk_short() */static void dump_disk_long(LSRDisk *disk){ int len; const char *state; char ctimestr[NAME_MAX + 1], utimestr[NAME_MAX + 1]; if (!disk || !disk->major || !disk->sb.md_magic) return; state = ctime((time_t *)&disk->sb.ctime); len = strlen(state); if (len > NAME_MAX) len = NAME_MAX + 1; memcpy(ctimestr, state, len); ctimestr[len - 1] = '\0'; state = ctime((time_t *)&disk->sb.utime); len = strlen(state); if (len > NAME_MAX) len = NAME_MAX + 1; memcpy(utimestr, state, len); utimestr[len - 1] = '\0'; state = disk_state(disk); fprintf(stdout, "[dev %d, %d] %s:\n" "\tmd version\t\t= %d.%d.%d\n" "\tsuperblock uuid\t\t= %08X.%08X.%08X.%08X\n" "\tmd minor number\t\t= %d\n" "\tcreated\t\t\t= %d (%s)\n" "\tlast updated\t\t= %d (%s)\n" "\traid level\t\t= %d\n" "\tchunk size\t\t= %d KB\n" "\tapparent disk size\t= %d KB\n" "\tdisks in array\t\t= %d\n" "\trequired disks\t\t= %d\n" "\tactive disks\t\t= %d\n" "\tworking disks\t\t= %d\n" "\tfailed disks\t\t= %d\n" "\tspare disks\t\t= %d\n" "\tposition in disk list\t= %d\n" "\tposition in md device\t= %d\n" "\tstate\t\t\t= %s\n" "\n", disk->major, disk->minor, disk->name ? disk->name : "(unknown)", disk->sb.major_version, disk->sb.minor_version, disk->sb.patch_version, disk->sb.set_uuid0, disk->sb.set_uuid1, disk->sb.set_uuid2, disk->sb.set_uuid3, disk->sb.md_minor, disk->sb.ctime, ctimestr, disk->sb.utime, utimestr, disk->sb.level, disk->sb.chunk_size / 1024, disk->sb.size, disk->sb.nr_disks, disk->sb.raid_disks, disk->sb.active_disks, disk->sb.working_disks, disk->sb.failed_disks, disk->sb.spare_disks, disk->sb.this_disk.number, (disk->sb.this_disk.number < disk->sb.raid_disks) ? disk->sb.this_disk.raid_disk : -1, state );} /* dump_disk_long() */static void dump_array_diskinfo(LSRContext *ctxt, char **diskinfo, int numdisks, int raid_disks){ int i; if (!ctxt || !diskinfo) return; /* * This is complicated by the '-g', '-s', and '-f' flags to array * operation. I suspect there is a simpler way to check these, but * I'm lazy right now. */ for (i = 0; i < numdisks; i++) { if ((ctxt->flags & LSR_ARRAY_GOOD) && (!diskinfo[i] || !strstr(diskinfo[i], "good\n"))) continue; else if ((ctxt->flags & LSR_ARRAY_SPARE) && (!diskinfo[i] || !strstr(diskinfo[i], "spare\n"))) continue; else if ((ctxt->flags & LSR_ARRAY_FAILED) && (!diskinfo[i] || !strstr(diskinfo[i], "failed\n"))) continue; else if (diskinfo[i]) fprintf(stdout, "%s", diskinfo[i]); else if (i < raid_disks) fprintf(stdout, "[dev ?, ?] %-16s %08X.%08X.%08X.%08X missing\n", "(unknown)", 0, 0, 0, 0); }} /* dump_array_diskinfo() */static void dump_array_online(LSRContext *ctxt, LSRArray *array){ int numdisks, i; char *tmp = NULL; char **diskinfo; LSRDisk *disk; struct list_head *pos; if (!ctxt || !array) return; if (!array->info.major_version && !array->info.minor_version) return; numdisks = array->info.raid_disks + array->info.spare_disks + array->info.failed_disks; /* The diskinfo hoops are for printing disks in .number order */ diskinfo = (char **)malloc(numdisks * sizeof(char*)); if (!diskinfo) { fprintf(stderr, "lsraid: Unable to allocate memory while querying md device\n" "[dev %3d, %3d] %s: %s\n", MD_MAJOR, array->minor, array->name ? array->name : "(unknown)", strerror(errno)); return; } memset(diskinfo, 0, numdisks * sizeof(char*)); list_for_each(pos, &array->disks) { disk = list_entry(pos, LSRDisk, d_array); /* Shouldn't happen */ if (!disk->info.major) continue; tmp = (char *)malloc(sizeof(char) * MAX_LINE_LENGTH); if (!tmp) continue; tmp[0] = '\0'; sprintf(tmp, "[dev % 3d, % 3d] %-16s %08X.%08X.%08X.%08X %.17s\n", disk->major, disk->minor, disk->name ? disk->name : "(unknown)", disk->sb.set_uuid0, disk->sb.set_uuid1, disk->sb.set_uuid2, disk->sb.set_uuid3, disk_state(disk)); i = disk->info.number; if (i < numdisks) diskinfo[i] = tmp; else free(tmp); } fprintf(stdout, "[dev % 3d, % 3d] %-16s %08X.%08X.%08X.%08X online\n", MD_MAJOR, array->minor, array->name ? array->name : "(unknown)", array->uuid0, array->uuid1, array->uuid2, array->uuid3); dump_array_diskinfo(ctxt, diskinfo, numdisks, array->info.raid_disks); fprintf(stdout, "\n");/* out_free: */ for (i = 0; i < numdisks; i++) if (diskinfo[i]) free(diskinfo[i]); free(diskinfo);} /* dump_array_online() */static void dump_array_offline(LSRContext *ctxt, LSRArray *array){ int numdisks, i, j; char *name, *tmp = NULL; const char *state; char **diskinfo; LSRDisk *disk, *a_disk = NULL; struct list_head *pos; if (!ctxt || !array) return; if (list_empty(&array->disks)) { fprintf(stderr, "lsraid: md device [dev %d, %d] %s is offline: Please specify a disk to query\n", MD_MAJOR, array->minor, array->name ? array->name : "(unknown)"); return; } a_disk = list_entry(array->disks.next, LSRDisk, d_array); numdisks = a_disk->sb.raid_disks + a_disk->sb.spare_disks + a_disk->sb.failed_disks; /* The diskinfo hoops are for printing disks in .number order */ diskinfo = (char **)malloc(numdisks * sizeof(char*)); if (!diskinfo) { fprintf(stderr, "lsraid: Unable to allocate memory while querying md device\n" "[dev %3d, %3d] %s: %s\n", MD_MAJOR, array->minor, array->name ? array->name : "(unknown)", strerror(errno)); return; } memset(diskinfo, 0, numdisks * sizeof(char*)); for (j = 0; j < numdisks; j++) { /* Empty slot */ if (!a_disk->sb.disks[j].major) continue; tmp = (char *)malloc(sizeof(char) * MAX_LINE_LENGTH); if (!tmp) continue; tmp[0] = '\0'; /* Oh, my, this is inefficient */ name = "(unknown)"; state = "unknown"; list_for_each(pos, &array->disks) { disk = list_entry(pos, LSRDisk, d_array); if ((disk->major == a_disk->sb.disks[j].major) && (disk->minor == a_disk->sb.disks[j].minor)) { if (disk->name) name = disk->name; state = disk_state(disk); break; } } /* UUID is guaranteed to be identical across &array->disks */ sprintf(tmp, "[dev % 3d, % 3d] %-16s %08X.%08X.%08X.%08X %.17s\n", a_disk->sb.disks[j].major, a_disk->sb.disks[j].minor, name, a_disk->sb.set_uuid0, a_disk->sb.set_uuid1, a_disk->sb.set_uuid2, a_disk->sb.set_uuid3, state); i = a_disk->sb.disks[j].number; if (i < numdisks) diskinfo[i] = tmp; else free(tmp); } fprintf(stdout, "[dev % 3d, % 3d] %-16s %08X.%08X.%08X.%08X offline\n", MD_MAJOR, array->minor, array->name ? array->name : "(unknown)", array->uuid0, array->uuid1, array->uuid2, array->uuid3); dump_array_diskinfo(ctxt, diskinfo, numdisks, a_disk->sb.raid_disks); fprintf(stdout, "\n");/* out_free: */ for (i = 0; i < numdisks; i++) if (diskinfo[i]) free(diskinfo[i]); free(diskinfo);} /* dump_array_offline() */static void dump_array(LSRContext *ctxt, LSRArray *array){ if (!ctxt || !array) return; if (array->info.major_version || array->info.minor_version) dump_array_online(ctxt, array); else dump_array_offline(ctxt, array);} /* dump_array() */static void dump_arrays(LSRContext *ctxt){ struct list_head *pos; LSRArray *array; LSRDisk *disk; LSRNamEnt *ent; /* * It is possible that one of the arrays came from a disk that * no longer belongs to the array. The result is that the array * does not have the disk, so the disk on the command line is not * printed from calls to dump_array(). The solution is to run * through &ctxt->o_disks. Any disk where disk->array is NULL has * not been printed by dump_array() and is a candidate. */ list_for_each(pos, &ctxt->arrays) { array = list_entry(pos, LSRArray, a_list); dump_array(ctxt, array); } list_for_each(pos, &ctxt->o_disks) { ent = list_entry(pos, LSRNamEnt, list); disk = ent->u.disk; if (!disk) continue; if (disk->array) continue; fprintf(stdout, "[dev % 3d, % 3d] %-16s %08X.%08X.%08X.%08X unbound\n", disk->major, disk->minor, disk->name ? disk->name : "(unknown)", disk->sb.set_uuid0, disk->sb.set_uuid1, disk->sb.set_uuid2, disk->sb.set_uuid3); }} /* dump_array() */static void dump_disks(LSRContext *ctxt){ int exists; struct list_head *dpos, *apos; LSRNamEnt *dent, *aent; LSRArray *array; LSRDisk *disk; list_for_each(apos, &ctxt->o_arrays) { aent = list_entry(apos, LSRNamEnt, list); array = aent->u.array; if (!array) continue; if (list_empty(&array->disks)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -