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

📄 lsraid.c

📁 create raid tool at linux
💻 C
📖 第 1 页 / 共 5 页
字号:
            free(disk);            disk = NULL;        }    }    return(disk);}  /* find_add_disk() */static void maybe_add_device(LSRContext *ctxt,                             int major, int minor){    FILE *f;    char *dev_base = NULL;    static char *proc_name = NULL;    LSRNamEnt *ent;    if (!ctxt || !ctxt->devtable || !major)        return;    if (!proc_name)    {        proc_name = (char *)malloc(sizeof(char) * (PATH_MAX + 1));        if (!proc_name)        {            fprintf(stderr,                    "lsraid: Unable to allocate memory for information on device \"%s\": %s\n",                    ctxt->devtable[major][minor],                    strerror(errno));            return;        }    }    proc_name[0] = '\0';    dev_base = strrchr(ctxt->devtable[major][minor], '/');    if ((dev_base == NULL) ||        (dev_base[1] == '\0'))        return;    /* Welcome to Hardcoded /proc Land */    if (strlen(dev_base) >        (PATH_MAX - strlen("/proc/ide//media")))        return;    sprintf(proc_name, "/proc/ide/%s/media", dev_base);    f = fopen(proc_name, "r");    if (f)    {        if (fgets(proc_name, PATH_MAX + 1, f))        {            /* IDE devices we don't want to probe */            if (!strcmp(proc_name, "cdrom") ||                !strcmp(proc_name, "tape"))            {                fclose(f);                return;            }        }        fclose(f);    }    ent = alloc_nament();    if (!ent)    {        fprintf(stderr,                "lsraid: Unable to allocate memory for information on device \"%s\": %s\n",                ctxt->devtable[major][minor],                strerror(errno));        return;    }    ent->name = ctxt->devtable[major][minor];    /* Should we add MD_MAJOR devices to o_disks too? */    if (major == MD_MAJOR)        list_add_tail(&ent->list, &ctxt->o_arrays);    else        list_add_tail(&ent->list, &ctxt->o_disks);}  /* maybe_add_device() */static int load_partitions(LSRContext *ctxt){    FILE *proc;    int major, minor, rc;    char line[MAX_LINE_LENGTH], name[MAX_LINE_LENGTH];    struct stat stat_buf;    if (!ctxt || !ctxt->devtable)        return(-EINVAL);    /* Here we are in wonderful Hardcoded /proc Land */    proc = fopen("/proc/partitions", "r");    if (!proc)        return(-errno);    while (1)    {        rc = 0;        if ((fgets(line, MAX_LINE_LENGTH, proc)) == NULL)            break;        name[0] = 0;        major = minor = 0;        /* FIXME: I'm lazy.  Can this be overrun? */        if (sscanf(line, "%d %d %*d %99[^ \t\n]",                   &major, &minor, name) < 3)            continue;        if (*name && major)        {            if (!ctxt->devtable[major])            {                ctxt->devtable[major] =                    (char **)malloc(MINORS * sizeof(char *));                if (!ctxt->devtable[major])                {                    rc = -ENOMEM;                    break;                }                memset(ctxt->devtable[major], 0,                       MINORS * sizeof(char *));            }            if (ctxt->devtable[major][minor])                continue;            /*             * This is all '/dev' specific.  If it isn't found there,             * it is going to fall back to /dev scanning (think              * /dev/usb/disk1 or something in devfs).  This heuristic             * should probably check whatever devfs puts together             * for 'hda1 in /proc/partitions', but I don't know what             * devfs does, and I don't much care right now.             */            ctxt->devtable[major][minor] =                (char *)malloc((strlen(name) + strlen("/dev/") + 1) *                               sizeof(char));            if (!ctxt->devtable[major][minor])                continue;            sprintf(ctxt->devtable[major][minor], "/dev/%s", name);            rc = stat(ctxt->devtable[major][minor], &stat_buf);            if ((rc != 0) && (!S_ISBLK(stat_buf.st_mode)))            {                free(ctxt->devtable[major][minor]);                ctxt->devtable[major][minor] = NULL;            }            else if (ctxt->flags & LSR_DEV_SCAN)                maybe_add_device(ctxt, major, minor);        }    }    fclose(proc);    return(rc);}  /* load_partitions() */static LSRDir *alloc_dir(){    LSRDir *dir;    dir = (LSRDir *)malloc(sizeof(LSRDir));    if (dir)    {        memset(dir, 0, sizeof(LSRDir));        INIT_LIST_HEAD(&dir->list);    }    return(dir);}  /* alloc_dir() */static LSRDir *push_dir(struct list_head *dtree, char *name){    int len;    LSRDir *dir, *pdir;    if (!dtree)        return(NULL);    if (!list_empty(dtree))        pdir = list_entry(dtree->next, LSRDir, list);    else        pdir = NULL;    if (!name)        return(pdir);    len = strlen(name);    if (len > NAME_MAX)        return(pdir);    if (pdir)    {        len += strlen("/");        len += strlen(pdir->name);        if (len > PATH_MAX)            return(pdir);    }    dir = alloc_dir();    if (!dir)        return(pdir);    sprintf(dir->name, "%s/%s", pdir ? pdir->name : "", name);    dir->dir = opendir(dir->name);    if (!dir->dir)    {        free(dir);        return(pdir);    }    list_add(&dir->list, dtree);    return(dir);}static LSRDir *pop_dir(struct list_head *dtree){    struct list_head *top;    LSRDir *dir;    if (!dtree)        return(NULL);    if (list_empty(dtree))        return(NULL);    top = dtree->next;    dir = list_entry(top, LSRDir, list);    closedir(dir->dir);    list_del(&dir->list);    free(dir);    if (list_empty(dtree))        return(NULL);    top = dtree->next;    return(list_entry(top, LSRDir, list));}  /* pop_dir() */static int scan_slash_dev(LSRContext *ctxt){    int rc, dirnamelen, major, minor;    char name[PATH_MAX + 1];    struct list_head dtree;    struct dirent *dirent;    struct stat stat_buf;    LSRDir *dir;    if (!ctxt || !ctxt->devtable)        return(-EINVAL);    INIT_LIST_HEAD(&dtree);    dir = push_dir(&dtree, "dev");    if (!dir)        return(-ENOENT);    dirnamelen = strlen(dir->name);    rc = 0;    while (!list_empty(&dtree))    {        /* sanity */        if (!dir || !dir->dir)            break;        dirent = readdir(dir->dir);        if (dirent == NULL)        {            dir = pop_dir(&dtree);            if (dir)                dirnamelen = strlen(dir->name);            continue;        }        if (!strcmp(dirent->d_name, ".") ||            !strcmp(dirent->d_name, ".."))            continue;        if ((dirnamelen + strlen("/") +             strlen(dirent->d_name)) > PATH_MAX)            continue;        sprintf(name, "%s/%s", dir->name, dirent->d_name);        rc = lstat(name, &stat_buf);        if (rc != 0)            continue;        if (S_ISDIR(stat_buf.st_mode))        {            dir = push_dir(&dtree, dirent->d_name);            if (dir)                dirnamelen = strlen(dir->name);        }        else if (S_ISBLK(stat_buf.st_mode))        {            major = major(stat_buf.st_rdev);            minor = minor(stat_buf.st_rdev);            if (!ctxt->devtable[major])            {                ctxt->devtable[major] =                    (char **)malloc(MINORS * sizeof(char *));                if (!ctxt->devtable[major])                {                    /* FIXME: what error if any? rc = -ENOMEM; */                    continue;                }                memset(ctxt->devtable[major], 0,                       MINORS * sizeof(char *));            }            if (ctxt->devtable[major][minor])                continue;                        ctxt->devtable[major][minor] =                (char *)malloc((strlen(name) + 1) * sizeof(char));            if (ctxt->devtable[major][minor])                strcpy(ctxt->devtable[major][minor], name);        }    }    return(rc);}  /* scan_slash_dev() *//* * We may want to build a raidtab, or at least we like pretty device * names.  However, the raid superblock only stores major,minor, so we * have to look up the name.  The algorithm is mostly brute.  99% of * devices will exist on the system, and hence will be in * /proc/partitions.  If, however, a device has been removed or moved * such that the major,minor are not in /proc/partitions, we have to * scan /dev.  Ewww.  We scan it once in scan_slash_dev().  The device * table holds the devices we've already looked at, either from * /proc/partitions or /dev. * * This assumes the 8/8 major/minor. */static int find_device(LSRContext *ctxt, char **name,                       int major, int minor){    static int loaded_partitions = 0;    static int scanned_dev = 0;    int rc = 0;    /* sanity */    if (!ctxt || !ctxt->devtable)        return(-EINVAL);    if (!name)        return(-EINVAL);    if (*name)        return(-EEXIST);    if (!major)        return(-EINVAL);    if (ctxt->devtable[major] && ctxt->devtable[major][minor])        goto out;    if (!loaded_partitions)    {        load_partitions(ctxt);        loaded_partitions = 1;        if (ctxt->devtable[major] && ctxt->devtable[major][minor])            goto out;    }    if (!scanned_dev)    {        scan_slash_dev(ctxt);        scanned_dev = 1;        if (ctxt->devtable[major] && ctxt->devtable[major][minor])            goto out;    }    rc = -ENOENT;out:    if (ctxt->devtable[major])        *name = ctxt->devtable[major][minor];    return(rc);}  /* find_device() */static int scan_arrays(LSRContext *ctxt){    LSRNamEnt *ent;    struct list_head *pos;    list_for_each(pos, &ctxt->o_arrays)    {        ent = list_entry(pos, LSRNamEnt, list);        ent->u.array = find_add_array(ctxt, ent->name, -1);    }    return(0);}  /* scan_arrays *//* Ripped from md.c */#if 0 /* Currently unused */static int sb_equal(LSRDisk *disk1, LSRDisk *disk2){	int ret;	mdp_super_t *tmp1, *tmp2;	tmp1 = (mdp_super_t *)malloc(sizeof(*tmp1));	tmp2 = (mdp_super_t *)malloc(sizeof(*tmp2));	if (!tmp1 || !tmp2) {		ret = 0;		goto abort;	}	*tmp1 = disk1->sb;	*tmp2 = disk2->sb;	/*	 * nr_disks is not constant	 */	tmp1->nr_disks = 0;	tmp2->nr_disks = 0;	if (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4))		ret = 0;	else		ret = 1;abort:	if (tmp1)		free(tmp1);	if (tmp2)		free(tmp2);	return ret;}#endif  /* Currently unused */static int scan_disks(LSRContext *ctxt){    LSRNamEnt *ent;    struct list_head *pos;    list_for_each(pos, &ctxt->o_disks)    {        ent = list_entry(pos, LSRNamEnt, list);        ent->u.disk = find_add_disk(ctxt, ent->name, 0, 0);    }    return(0);}  /* scan_disks() */static void clean_context(LSRContext *ctxt){    int i;    struct list_head *pos, *n;    LSRArray *array;    LSRDisk *disk;    LSRNamEnt *ent;    list_for_each_safe(pos, n, &ctxt->disks)    {        disk = list_entry(pos, LSRDisk, d_list);        free(disk);    }    list_for_each_safe(pos, n, &ctxt->arrays)    {        array = list_entry(pos, LSRArray, a_list);        free(array);    }    list_for_each_safe(pos, n, &ctxt->o_disks)    {        ent = list_entry(pos, LSRNamEnt, list);        free(ent);    }    list_for_each_safe(pos, n, &ctxt->o_arrays)

⌨️ 快捷键说明

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