⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsraid.c

📁 create raid tool at linux
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        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 + -