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

📄 lsraid.c

📁 create raid tool at linux
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * lsraid.c - A tool for displaying md device information. * * Copyright (C) 2002 Oracle Corporation, Joel Becker * <joel.becker@oracle.com> * All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have recieved a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 021110-1307, USA. */#include "common.h"#include "parser.h"#include "raid_io.h"#include "raidlib.h"#include "version.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/time.h>#include <time.h>#include <dirent.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <linux/types.h>#include <linux/major.h>#include <linux/fs.h>#include <linux/raid/md_u.h>#include <linux/raid/md_p.h>/* Local copies of things I use - Clean up later */#include "list.h"/* * Defines */#define LSRAID_VERSION "0.7.0"/* Imagine the fun when we get to different major,minor sizes :-) */#define MAJORBITS 8#define MINORBITS 8#define MAJORS (1 << MAJORBITS)#define MINORS (1 << MINORBITS)/* Debugging for device scanning */#define SCAN_DEBUG 0/* * Typedefs */typedef struct _LSRContext LSRContext;typedef struct _LSRNamEnt  LSRNamEnt;typedef struct _LSRDir     LSRDir;typedef struct _LSRArray   LSRArray;typedef struct _LSRDisk    LSRDisk;/* * Enums */typedef enum{    LSR_ARRAY = 'A',    LSR_DISK = 'D',    LSR_RAIDTAB = 'R'} LSRAction;typedef enum{    LSR_ARRAY_GOOD   = 1 << 0,    LSR_ARRAY_SPARE  = 1 << 1,    LSR_ARRAY_FAILED = 1 << 2,    LSR_DISK_LONG    = 1 << 3,    LSR_DEV_SCAN     = 1 << 4} LSRFlags;/* * Structures */struct _LSRContext{    LSRAction action;    LSRFlags flags;    struct list_head o_arrays;  /* Array names from parse_options */    struct list_head o_disks;   /* Disk names from parse_options */    struct list_head arrays;    /* Anchor for list of arrays (a_list) */    struct list_head disks;     /* Anchor for list of disks (d_list) */    char ***devtable;           /* Table of known device names                                   (major, minor) -> name */};struct _LSRNamEnt{    struct list_head list;    char *name;    union    {        LSRArray *array;        LSRDisk *disk;    } u;};struct _LSRDir{    struct list_head list;    char name[PATH_MAX + 1];    DIR *dir;};struct _LSRArray{    struct list_head a_list;    /* Hook into list of arrays */    struct list_head disks;     /* Anchor for array disks (d_array) */    char *name;                 /* Device name */    unsigned int uuid0;         /* Array uuid */    unsigned int uuid1;    unsigned int uuid2;    unsigned int uuid3;    int minor;                  /* Array minor (in MD major) */    mdu_array_info_t info;      /* Online info */};struct _LSRDisk{    struct list_head d_list;    /* Hook into list of disks */    struct list_head d_array;   /* Hook into array disks */    LSRArray *array;            /* Pointer to owning array */    char *name;                 /* Device name */    int major;                  /* Device major */    int minor;                  /* Device minor */    mdu_disk_info_t info;       /* Online info */    mdp_super_t sb;             /* On-disk superblock */};/* * Prototypes */static void print_usage(int rc);static void print_usage_long();static void print_version();static void parse_options(LSRContext *ctxt, int argc, char *argv[]);static LSRContext *alloc_context();static LSRNamEnt *alloc_nament();static LSRArray *alloc_array();static LSRDisk *alloc_disk();static int read_md_super(LSRContext *ctxt, LSRDisk *disk);static int query_array(LSRContext *ctxt, LSRArray *array);static int fill_array(LSRContext *ctxt, LSRArray *array);static int fill_disk(LSRContext *ctxt, LSRDisk *disk);static LSRArray *find_add_array(LSRContext *ctxt, char *name,                                int minor);static LSRDisk *find_add_disk(LSRContext *ctxt, char *name,                              int major, int minor);static int find_device(LSRContext *ctxt, char **name,                       int major, int minor);static void maybe_add_device(LSRContext *ctxt,                             int major, int minor);static int load_partitions(LSRContext *ctxt);static LSRDir *alloc_dir();static LSRDir *pop_dir(struct list_head *dtree);static LSRDir *push_dir(struct list_head *dtree, char *name);static int scan_slash_dev(LSRContext *ctxt);static int scan_arrays(LSRContext *ctxt);static int scan_disks(LSRContext *ctxt);static void clean_context(LSRContext *ctxt);static void disk_state_offline(LSRDisk *disk, char *state);static void disk_state_online(LSRDisk *disk, char *state);static const char *disk_state(LSRDisk *disk);static void dump_disk_long(LSRDisk *disk);static void dump_disk_short(LSRDisk *disk);static void dump_disks(LSRContext *ctxt);static void dump_array_diskinfo(LSRContext *ctxt,                                char **diskinfo,                                int numdisks,                                int raid_disks);static void dump_array_online(LSRContext *ctxt, LSRArray *array);static void dump_array_offline(LSRContext *ctxt, LSRArray *array);static void dump_array(LSRContext *ctxt, LSRArray *array);static void dump_arrays(LSRContext *ctxt);static void dump_raidtab_array_online(LSRArray *array);static void dump_raidtab_array_offline(LSRArray *array);static void dump_raidtab_array(LSRArray *array);static void dump_raidtab(LSRContext *ctxt);#if 0 /* Currently unused */static int sb_equal(LSRDisk *disk1, LSRDisk *disk2);#endif  /* Currently unused *//* * Functions */static void print_version(){    fprintf(stdout, "lsraid version " LSRAID_VERSION "\n");    exit(0);}  /* print_version() */static void print_usage_long(){    /* FIXME */    print_usage(0);}  /* print_usage_long() */static void print_usage(int rc){    FILE *output = rc ? stderr : stdout;    fprintf(output,            "Usage: lsraid -A [-g|-f|-s] {-a <device> | -d <device>} ...\n"            "       lsraid -A [-g|-f|-s] -p\n"            "       lsraid -D [-l] {-a <device> | -d <device>} ...\n"            "       lsraid -D [-l] -p\n"            "       lsraid -R {-a <device> | -d <device>} ...\n"            "       lsraid -R -p\n"            "       lsraid -h\n"            "       lsriad -V\n");    exit(rc);}  /* print_usage() */static LSRContext *alloc_context(){    LSRContext *ctxt;    ctxt = (LSRContext *)malloc(sizeof(LSRContext));    if (ctxt)    {        memset(ctxt, 0, sizeof(LSRContext));        INIT_LIST_HEAD(&ctxt->o_disks);        INIT_LIST_HEAD(&ctxt->o_arrays);        INIT_LIST_HEAD(&ctxt->disks);        INIT_LIST_HEAD(&ctxt->arrays);        ctxt->devtable = (char ***)malloc(MAJORS * sizeof(char **));        if (!ctxt->devtable)        {            free(ctxt);            return(NULL);        }        memset(ctxt->devtable, 0, MAJORS * sizeof(char **));    }    return(ctxt);}  /* alloc_context() */static LSRNamEnt *alloc_nament(){    LSRNamEnt *ent;    ent = (LSRNamEnt *)malloc(sizeof(LSRNamEnt));    if (ent)    {        memset(ent, 0, sizeof(LSRNamEnt));        INIT_LIST_HEAD(&ent->list);    }    return(ent);}  /* alloc_nament() */static LSRArray *alloc_array(){    LSRArray *array;    array = (LSRArray *)malloc(sizeof(LSRArray));    if (array)    {        memset(array, 0, sizeof(LSRArray));        INIT_LIST_HEAD(&array->a_list);        INIT_LIST_HEAD(&array->disks);        array->minor = -1;    }    return(array);}  /* alloc_array() */static LSRDisk *alloc_disk(){    LSRDisk *disk;    disk = (LSRDisk *)malloc(sizeof(LSRDisk));    if (disk)    {        memset(disk, 0, sizeof(LSRDisk));        INIT_LIST_HEAD(&disk->d_list);        INIT_LIST_HEAD(&disk->d_array);    }    return(disk);}  /* alloc_disk() */static void parse_options(LSRContext *ctxt, int argc, char *argv[]){    int i;    LSRNamEnt *ent;    /* Pre-clear */    ctxt->action = 0;    ctxt->flags = 0;    for (i = 1; i < argc; i++)    {        if (argv[i][0] != '-')            break;        switch (argv[i][1])        {            case '-':                if (argv[i][2] == '\0')                {                    i++;                    break;                }                else if (strcmp(argv[i], "--help") == 0)                    print_usage_long();                else if (strcmp(argv[i], "--version") == 0)                    print_version();                else                {                    fprintf(stderr, "lsraid: Invalid option: %s\n",                            argv[i]);                }                break;            case 'h':            case '?':            case 'H':                print_usage(0);                break;            case 'V':                print_version();                break;            case 'A':            case 'D':            case 'R':                if (ctxt->action)                {                    fprintf(stderr,                            "lsraid: Options %c and %c cannot be combined\n",                            argv[i][1], ctxt->action);                    print_usage(EINVAL);                }                ctxt->action = argv[i][1];                break;            case 'g':                ctxt->flags |= LSR_ARRAY_GOOD;                break;            case 's':                ctxt->flags |= LSR_ARRAY_SPARE;                break;            case 'f':                ctxt->flags |= LSR_ARRAY_FAILED;                break;            case 'p':                ctxt->flags |= LSR_DEV_SCAN;                break;            case 'a':                i++;                if (i >= argc)                {                    fprintf(stderr,                            "lsraid: Option \'-a\' requires an argument\n");                    print_usage(EINVAL);                }                ent = alloc_nament();                if (!ent)                {                    fprintf(stderr,                            "lsraid: Unable to allocate memory for information on array \"%s\": %s\n",                            argv[i],                            strerror(errno));                    return;                }                ent->name = argv[i];                list_add_tail(&ent->list, &ctxt->o_arrays);                break;            case 'd':                i++;                if (i >= argc)                {                    fprintf(stderr,                            "lsraid: Option \'-d\' requires an argument\n");                    print_usage(EINVAL);                }                ent = alloc_nament();                if (!ent)                {                    fprintf(stderr,                            "lsraid: Unable to allocate memory for information on device \"%s\": %s\n",                            argv[i],                            strerror(errno));                    return;                }                ent->name = argv[i];                list_add_tail(&ent->list, &ctxt->o_disks);                break;            case 'l':                ctxt->flags |= LSR_DISK_LONG;                break;            default:                fprintf(stderr,                        "lsraid: Invalid option: %s\n",                        argv[i]);                print_usage(EINVAL);                break;        }    }    if ((ctxt->flags & LSR_DISK_LONG) && (ctxt->action != LSR_DISK))    {        fprintf(stderr,                "lsraid: '-l' option requires '-D' option\n");        print_usage(EINVAL);    }    if ((ctxt->flags &         (LSR_ARRAY_GOOD | LSR_ARRAY_FAILED | LSR_ARRAY_SPARE)) &&        (ctxt->action != LSR_ARRAY))    {        fprintf(stderr,                "lsraid: '-g', '-f', and '-s' options require '-A' option\n");        print_usage(EINVAL);    }    if (list_empty(&ctxt->o_arrays) && list_empty(&ctxt->o_disks))    {        if (!(ctxt->flags & LSR_DEV_SCAN))        {            fprintf(stderr,                    "lsraid: You must specify a device to query\n");            print_usage(EINVAL);        }    }    else if (ctxt->flags & LSR_DEV_SCAN)    {        fprintf(stderr,                "lsraid: The '-p' option cannot be combined with the '-a' option\n"                "        or the '-d' option\n");        print_usage(EINVAL);    }

⌨️ 快捷键说明

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