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

📄 lsraid.c

📁 create raid tool at linux
💻 C
📖 第 1 页 / 共 5 页
字号:
            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)");            continue;        }        list_for_each(dpos, &array->disks)        {            disk = list_entry(dpos, LSRDisk, d_array);            if (!disk->major || !disk->sb.md_magic)                continue;            if (ctxt->flags & LSR_DISK_LONG)                dump_disk_long(disk);            else                dump_disk_short(disk);        }    }    list_for_each(dpos, &ctxt->o_disks)    {        dent = list_entry(dpos, LSRNamEnt, list);        disk = dent->u.disk;        if (!disk)            continue;        if (!disk->major || !disk->sb.md_magic)            continue;        /* Was it seen in the loop over &ctxt->o_arrays */        if (disk->array)        {            /* Can you smell the O(n^2)?  Please make it better */            exists = 0;            list_for_each(apos, &ctxt->o_arrays)            {                aent = list_entry(apos, LSRNamEnt, list);                array = aent->u.array;                if (!array)                    continue;                if (disk->array == array)                {                    exists = 1;                    break;                }            }            if (exists)                continue;        }        if (ctxt->flags & LSR_DISK_LONG)            dump_disk_long(disk);        else            dump_disk_short(disk);    }}  /* dump_disks() */static void dump_raidtab_array_online(LSRArray *array){    int i, n, s, numdisks, failedstart;    LSRDisk *disk;    struct list_head *pos;    char **diskinfo;    char *tmp, *type;    if (!array)        return;    if (!array->name)    {        /* FIXME: probably should bleat here */        return;    }    /*     * raid_disks slots for good disks     * spare_disks slots for good disks     * raid_disks slots for failed/missing disks,     *     * This attempts to follow the order of raidtab rules, rather     * than any current order.  (eg, spare-disks should come after     * raid-disks in the raidtab, even if the first disk in the     * online array is a spare-disk).     *     * A good disk is placed in its raid_disk location in the first     * raid_disks slots.  A spare disk is placed sequentially in the     * spare_disks slots.  A failed or missing disk is placed in its     * raid_disk location in the last raid_disks slots.  If more than     * one failed disk exists for a given raid_disk slot, the first is     * given only.     *     * Eg, a raid5 array, where there are three disks in the array plus     * one spare.  The second disk has failed:     *     * diskinfo[0] = good disk 0 = disk0     * diskinfo[1] = good disk 1 = NULL     * diskinfo[2] = good disk 2 = disk2     * diskinfo[3] = spare disk 0 = disk3     * diskinfo[4] = failed disk 0 = NULL     * diskinfo[5] = failed disk 1 = disk1     * diskinfo[6] = failed disk 2 = NULL     */    numdisks = array->info.raid_disks + array->info.spare_disks +        array->info.raid_disks;    failedstart = array->info.raid_disks + array->info.spare_disks;    diskinfo = (char **)malloc(sizeof(char *) * numdisks);    if (!diskinfo)    {        fprintf(stderr,                "lsraid: Unable to allocate memory while creating raidtab entry for md device\n"                "[dev %d, %d] %s: %s\n",                MD_MAJOR, array->minor,                array->name ? array->name : "(unknown)",                strerror(errno));        return;    }    memset(diskinfo, 0, sizeof(char *) * numdisks);    /* diskinfo [i]ndex, type [n]umber, [s]pare number */    i = n = s = 0;    list_for_each(pos, &array->disks)    {        disk = list_entry(pos, LSRDisk, d_array);        tmp = (char *)malloc(sizeof(char) * MAX_LINE_LENGTH);        if (!tmp)            continue;        tmp[0] = '\0';        if (disk->info.state & (1<<MD_DISK_ACTIVE))        {            type = "raid-disk";            i = n = disk->info.raid_disk;        }        else if (disk->info.state & (1<<MD_DISK_FAULTY))        {            type = "failed-disk";            n = disk->info.raid_disk;            i = failedstart + disk->info.raid_disk;        }        else if (disk->info.state == 0)        {            type = "spare-disk";            n = s++;            i = n + array->info.raid_disks;        }        else        {            type = "error";            n = 0;            i = numdisks; /* out of bounds */        }        sprintf(tmp,                "\tdevice\t\t%s\n"                "\t%s\t\t%d\n",                disk->name ? disk->name : "(unknown)",                type, n);        if ((i < numdisks) && !diskinfo[i])            diskinfo[i] = tmp;        else            free(tmp);    }    /* Scan for missing disks */    for (i = 0; i < array->info.raid_disks; i++)    {        if (!diskinfo[i] && !diskinfo[failedstart + i])        {            tmp = (char *)malloc(sizeof(char) * MAX_LINE_LENGTH);            if (!tmp)                continue;            tmp[0] = '\0';            sprintf(tmp,                "\tdevice\t\t/dev/null\n"                "\tfailed-disk\t\t%d\n",                i);            if ((failedstart + i) < numdisks)                diskinfo[failedstart + i] = tmp;            else                free(tmp);        }    }    fprintf(stdout,            "# md device [dev %d, %d] %s queried online\n"            "raiddev %s\n"            "\traid-level\t\t%d\n"            "\tnr-raid-disks\t\t%d\n"            "\tnr-spare-disks\t\t%d\n"            "\tpersistent-superblock\t%d\n"            "\tchunk-size\t\t%d\n",            MD_MAJOR, array->minor,            array->name,            array->name,            array->info.level,            array->info.raid_disks,            array->info.spare_disks,            array->info.not_persistent ? 0 : 1,            /* raid docs are wrong.  raidtab chunk size is in K */            array->info.chunk_size / 1024);    fprintf(stdout, "\n");    for (i = 0; i < numdisks; i++)        if (diskinfo[i])            fprintf(stdout, "%s", diskinfo[i]);    fprintf(stdout, "\n");/* out_free: */    for (i = 0; i < numdisks; i++)        if (diskinfo[i])            free(diskinfo[i]);    free(diskinfo);}  /* dump_raidtab_array_online() */static void dump_raidtab_array_offline(LSRArray *array){    int j, i, n, s, numdisks, failedstart;    LSRDisk *disk, *a_disk;    struct list_head *pos;    char **diskinfo;    char *tmp, *type, *name;    if (!array)        return;    if (!array->name)    {        /* FIXME: probably should bleat here */        return;    }    if (list_empty(&array->disks))    {        /*         * We really shouldn't be able to get here, as an offline array         * is discovered from its disks         */        fprintf(stderr,                "lsraid: device [dev %d, %d] %s has no disks\n",                MD_MAJOR, array->minor,                array->name ? array->name : "(Unknown)");        return;    }    a_disk = list_entry(array->disks.next, LSRDisk, d_array);    /*     * raid_disks slots for good disks     * spare_disks slots for good disks     * raid_disks slots for failed/missing disks,     *     * This attempts to follow the order of raidtab rules, rather     * than any current order.  (eg, spare-disks should come after     * raid-disks in the raidtab, even if the first disk in the     * online array is a spare-disk.     *     * A good disk is placed in its raid_disk location in the first     * raid_disks slots.  A spare disk is placed sequentially in the     * spare_disks slots.  A failed or missing disk is placed in its     * raid_disk location in the last raid_disks slots.  If more than     * one failed disk exists for a given raid_disk, only the first is     * given.     *     * Eg, a raid5 array, where there are three disks in the array plus     * one spare.  The second disk has failed:     *     * diskinfo[0] = good disk 0 = disk0     * diskinfo[1] = good disk 1 = NULL     * diskinfo[2] = good disk 2 = disk2     * diskinfo[3] = spare disk 0 = disk3     * diskinfo[4] = failed disk 0 = NULL     * diskinfo[5] = failed disk 1 = disk1     * diskinfo[6] = failed disk 2 = NULL     */    numdisks = a_disk->sb.raid_disks + a_disk->sb.spare_disks +        a_disk->sb.raid_disks;    failedstart = a_disk->sb.raid_disks + a_disk->sb.spare_disks;    diskinfo = (char **)malloc(sizeof(char *) * numdisks);    if (!diskinfo)    {        fprintf(stderr,                "lsraid: Unable to allocate memory while creating raidtab entry for md device\n"                "[dev %d, %d] %s: %s\n",                MD_MAJOR, array->minor,                array->name ? array->name : "(unknown)",                strerror(errno));        return;    }    memset(diskinfo, 0, sizeof(char *) * numdisks);    /* diskinfo [i]ndex, location [n]umber, [s]pare number */    i = n = s = 0;    for (j = 0; (j < numdisks) && (j < MD_SB_DISKS); j++)    {        if (!a_disk->sb.disks[j].major)            continue;        tmp = (char *)malloc(sizeof(char) * MAX_LINE_LENGTH);        if (!tmp)            continue;        tmp[0] = '\0';        if (a_disk->sb.disks[j].state & (1<<MD_DISK_ACTIVE))        {            type = "raid-disk";            i = n = a_disk->sb.disks[j].raid_disk;        }        else if (a_disk->sb.disks[j].state & (1<<MD_DISK_FAULTY))        {            type = "failed-disk";            n = a_disk->sb.disks[j].raid_disk;            i = failedstart + a_disk->sb.disks[j].raid_disk;;        }        else if (a_disk->sb.disks[j].state == 0)        {            type = "spare-disk";            n = s++;            i = n + a_disk->sb.raid_disks;        }        else        {            type = "error";            n = 0;            i = numdisks; /* out of bounds */        }        /* Oh, my, this is inefficient */        name = "(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;                break;            }        }        sprintf(tmp,                "\tdevice\t\t%s\n"                "\t%s\t\t%d\n",                name, type, n);        if ((i < numdisks) && !diskinfo[i])            diskinfo[i] = tmp;        else            free(tmp);    }    /* Scan for missing disks */    for (i = 0; i < a_disk->sb.raid_disks; i++)    {        if (!diskinfo[i] && !diskinfo[failedstart + i])        {            tmp = (char *)malloc(sizeof(char) * MAX_LINE_LENGTH);            if (!tmp)                continue;            tmp[0] = '\0';            sprintf(tmp,                "\tdevice\t\t/dev/null\n"                "\tfailed-disk\t\t%d\n",                i);            if ((failedstart + i) < numdisks)                diskinfo[failedstart + i] = tmp;            else                free(tmp);        }    }    fprintf(stdout,            "# md device [dev %d, %d] %s queried offline\n"            "# Authoritative device is [dev %d, %d] %s\n"            "raiddev %s\n"            "\traid-level\t\t%d\n"            "\tnr-raid-disks\t\t%d\n"            "\tnr-spare-disks\t\t%d\n"            "\tpersistent-superblock\t%d\n"            "\tchunk-size\t\t%d\n",            MD_MAJOR, array->minor,            array->name,            a_disk->major, a_disk->minor,            a_disk->name ? a_disk->name : "(unknown)",            array->name,            a_disk->sb.level,            a_disk->sb.raid_disks,            a_disk->sb.spare_disks,            a_disk->sb.not_persistent ? 0 : 1,            /* raid docs are wrong.  raidtab chunk size is in K */            a_disk->sb.chunk_size / 1024);    fprintf(stdout, "\n");    for (i = 0; i < numdisks; i++)        if (diskinfo[i])            fprintf(stdout, "%s", diskinfo[i]);    fprintf(stdout, "\n");/* out_free: */    for (i = 0; i < numdisks; i++)        if (diskinfo[i])            free(diskinfo[i]);    free(diskinfo);}  /* dump_raidtab_array_offline() */static void dump_raidtab_array(LSRArray *array){    if (array->info.major_version || array->info.minor_version)        dump_raidtab_array_online(array);    else        dump_raidtab_array_offline(array);}  /* dump_raidtab_array() */static void dump_raidtab(LSRContext *ctxt){    LSRArray *array;    LSRNamEnt *ent;    struct list_head *pos;    fprintf(stdout,            "# This raidtab was generated by lsraid version %s.\n"            "# It was created from a query on the following devices:\n",            LSRAID_VERSION);    list_for_each(pos, &ctxt->o_arrays)    {        ent = list_entry(pos, LSRNamEnt, list);        fprintf(stdout, "#\t%s\n", ent->name);    }    list_for_each(pos, &ctxt->o_disks)    {        ent = list_entry(pos, LSRNamEnt, list);        fprintf(stdout, "#\t%s\n", ent->name);    }    fprintf(stdout, "\n");    /*     * Grr, ignores the issue of raid 1+0.  The admin should be     * bright enough...     */    list_for_each(pos, &ctxt->arrays)    {        array = list_entry(pos, LSRArray, a_list);        dump_raidtab_array(array);    }}  /* dump_raidtab() *//* * The link_arrays(), link_array(), link_array_online(), and * link_array_offline() functions handle matching disks with their * arrays. * * The easy case: The md device is online. * o The array must have array->info. * o The disks must have disk->info. * o Scan ctxt->disks.  Every disk that is free, has disk->info, and  *   matches disk->sb.md_minor with array->minor gets selected.  Set *   array->uuid* from the first disk and verify they all match. * * The harder case: The md device is offline. * o First pass, scan all disks that are free and have disk->sb.md_minor *   matching array->minor.  The disk with the most recent *   disk->sb.utime is authoritative for the array.  Add it to th

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -