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

📄 raid.c

📁 LINUX lilo-22.7.1 源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* raid.c  -  The RAID-1 hooks for LILO *//*Copyright 2001-2005 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.*/#define _GNU_SOURCE#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <fcntl.h>#include <errno.h>#include <sys/stat.h>/*#include <asm/page.h>*/#include "config.h"#include "lilo.h"#include "common.h"#include "raid.h"#include "boot.h"#include "device.h"#include "geometry.h"#include "bsect.h"#include "cfg.h"#include "partition.h"#include "md-int.h"static int lowest;static DT_ENTRY *md_disk;static DT_ENTRY *disk;static unsigned int raid_base, raid_offset[MAX_RAID];static char *raid_mbr[MAX_RAID];static int raid_device[MAX_RAID+1];static int raid_bios[MAX_RAID+1];static int device;enum {MD_NULL=0, MD_PARALLEL, MD_MIXED, MD_SKEWED};int do_md_install, ndisk, md_bios;static char *raid_list[MAX_RAID];static int list_index[MAX_RAID];static int nlist, faulty;static int autocount;static char *boot;#define IS_COVERED    0x1000#define TO_BE_COVERED 0x2000#define COVERED   (IS_COVERED|TO_BE_COVERED)static int is_primary(int device){    int mask;        mask = has_partitions(device);    if (!mask) die("is_primary:  Not a valid device  0x%04X", device);    mask = device & ~mask;    return (mask && mask<=PART_MAX);}static int master(int device){    int mask;        if (MAJOR(device) == MAJOR_FD) return device;        mask = has_partitions(device);    if (!mask) die("master:  Not a valid device  0x%04X", device);    return device & mask;}static int is_accessible(int device){    int mask;        mask = has_partitions(device);    if (!mask) die("is_accessible:  Not a valid device  0x%04X", device);    mask = device & ~mask;    return (mask<=PART_MAX);}int raid_setup(void){    int pass, mask;    struct stat st;    int md_fd;    struct md_version md_version_info;    md_disk_info_t md_disk_info;    md_array_info_t md_array_info;    GEOMETRY geo;    DEVICE dev;    char *extrap;    int raid_offset_set, all_pri_eq, pri_index;    int pri_offset;    int raid_limit;        if (!(boot=cfg_get_strg(cf_options,"boot"))) {	boot = "/";	if (!nowarn)	   fprintf(errstd,"Warning: RAID1 install implied by omitted 'boot='\n");    }    if (stat(boot,&st)<0) die("raid_setup: stat(\"%s\")", boot);    if (verbose>=5)	printf("raid_setup: dev=%04X  rdev=%04X\n",				(int)st.st_dev, (int)st.st_rdev);#if BETA_TEST	fflush(stdout);#endif    if ( MAJOR(st.st_rdev) != MAJOR_MD ) {	/* not raid */	if (cfg_get_strg(cf_options, RAID_EXTRA_BOOT))	    die("Not a RAID install, '" RAID_EXTRA_BOOT "=' not allowed");	return 0L;    }    else {	/* It is a RAID installation *//* scan the devices in /proc/partitions */	pf_hard_disk_scan();	if ((md_fd=dev_open(&dev, st.st_rdev, O_NOACCESS) ) < 0)	    die("Unable to open %s",boot);	boot = stralloc(dev.name);	if (fstat(md_fd,&st) < 0)	    die("Unable to stat %s",boot);	if (!S_ISBLK(st.st_mode))	    die("%s is not a block device",boot);	boot_dev_nr = st.st_rdev;	/* set this very early */	if (ioctl(md_fd,RAID_VERSION,&md_version_info) < 0)	    die("Unable to get RAID version on %s", boot);	if (md_version_info.major > 0)	    die("Raid major versions > 0 are not supported");	if (md_version_info.minor < 90)	    die("Raid versions < 0.90 are not supported");		if (ioctl(md_fd,GET_ARRAY_INFO,&md_array_info) < 0)	    die("Unable to get RAID info on %s",boot);	if ((md_array_info.major_version != md_version_info.major) &&		(md_array_info.minor_version != md_version_info.minor))	    die("Inconsistent Raid version information on %s", boot);	if (md_array_info.level != 1)	    die("Only RAID1 devices are supported as boot devices");	if (!linear && !lba32) {	    lba32 = 1;	    if (!nowarn)		fprintf(errstd,"Warning: RAID install requires LBA32 or LINEAR;"			" LBA32 assumed.\n");	}	extrap = cfg_get_strg(cf_options, RAID_EXTRA_BOOT);	extra = !extrap ? X_AUTO :		!strcasecmp(extrap,"none") ? X_NONE :		!strcasecmp(extrap,"auto") ? X_AUTO :		!strcasecmp(extrap,"mbr-only") ? X_MBR_ONLY :		!strcasecmp(extrap,"mbr") ? X_MBR :		    X_SPEC;		do_md_install = MD_PARALLEL;	all_pri_eq = 1;	raid_offset_set = pri_index = pri_offset = 0;	raid_flags = FLAG_RAID;	md_bios = 0xFF;			/* we want to find the minimum */	ndisk = 0;			/* count the number of disks on-line */	nlist = 0;	faulty = 0;		device = MKDEV(MD_MAJOR, md_array_info.md_minor);	    /* search the disk table for a definition */	md_disk = disktab;	while (md_disk && md_disk->device != device)	    md_disk = md_disk->next;	    	if (!md_disk) {	    md_disk = alloc_t(DT_ENTRY);	    md_disk->device = MKDEV(MD_MAJOR, md_array_info.md_minor);	    md_disk->bios = -1;	/* use the default */	    md_disk->next = disktab;	    disktab = md_disk;	}	if (verbose >= 2) {	   printf("RAID info:  nr=%d, raid=%d, active=%d, working=%d, failed=%d, spare=%d\n",		md_array_info.nr_disks,		md_array_info.raid_disks,		md_array_info.active_disks,		md_array_info.working_disks,		md_array_info.failed_disks,		md_array_info.spare_disks );	}    /* scan through all the RAID devices */	raid_limit = md_array_info.raid_disks + md_array_info.spare_disks;	raid_index = 0;   	for (pass=0; pass < raid_limit; pass++) {	    DEVICE dev;	    int disk_fd;	    char new_name[MAX_TOKEN+1];	    char *np;	    	    md_disk_info.number = pass;	    if (ioctl(md_fd,GET_DISK_INFO,&md_disk_info) < 0)#if 1		die("raid: GET_DISK_INFO: %s, pass=%d", strerror(errno), pass);#else		{		printf("raid: GET_DISK_INFO: %s, pass=%d\n", strerror(errno), pass);		continue;		}#endif	    device = MKDEV(md_disk_info.major, md_disk_info.minor);            if(verbose>=3) printf("md: RAIDset device %d = 0x%04X\n", pass, device);	    	    if (device == 0) { /* empty slot left over from recovery process */		faulty++;	        if (!nowarn)		    fprintf(errstd,"Warning: Faulty disk in RAID-1 array; boot with caution!!\n");		continue;	    }	    disk_fd = dev_open(&dev,device,O_NOACCESS);	    if (md_disk_info.state & (1 << MD_DISK_FAULTY)) {		printf("disk %s marked as faulty, skipping\n",dev.name);		faulty++;		continue;	    }	    geo_get(&geo, device, -1, 1);	    disk = alloc_t(DT_ENTRY);	    if (verbose>=3)		printf("RAID scan: geo_get: returns geo->device = 0x%02X"		      " for device %04X\n", geo.device, device);	      	    disk->bios = geo.device;	/* will be overwritten */	    disk->device = device;	      /* used to mask above with 0xFFF0; forces MBR; sloppy, mask may be: 0xFFF8 */	    disk->sectors = geo.sectors;	    disk->heads = geo.heads;	    disk->cylinders = geo.cylinders;	    disk->start = geo.start;	    if (ndisk==0) {		raid_base = geo.start;		raid_index = pass;	    }	    raid_offset[ndisk] = geo.start - raid_base;	    raid_device[ndisk] = device;	    if (raid_offset[ndisk]) {	        do_md_install = MD_SKEWED;	 /* flag non-zero raid_offset */	    }	    if (all_pri_eq && is_primary(device)) {		if (raid_offset_set) {		    all_pri_eq &= (pri_offset == raid_offset[ndisk]);		} else {		    pri_offset = raid_offset[ndisk];		    raid_offset_set = 1;		    pri_index = ndisk;		}	    }#if 1	    if (geo.device < md_bios) {	/* OLD: use smallest device code */#else	    if (ndisk==0) {	/* NEW: use the device code of the first device */#endif	        md_bios = geo.device;	/* find smallest device code, period */	        lowest = ndisk;		/* record where */	    }	    raid_bios[ndisk] = geo.device;  /* record device code */	    disk->next = disktab;	    disktab = disk;	    if (verbose >= 3 && do_md_install) {		printf("disk->start = %d\t\traid_offset = %d (%08X)\n",		   disk->start, (int)raid_offset[ndisk], (int)raid_offset[ndisk]);	    }   		/* derive the MBR name, which may be needed later */	    strncpy(new_name,dev.name,MAX_TOKEN);	    new_name[MAX_TOKEN] = '\0';	    np = boot_mbr(dev.name, 0);	    if (!np) np = stralloc(new_name);	    raid_mbr[ndisk] = np;	    if (ndisk==0) {	/* use the first disk geometry */		md_disk->sectors = geo.sectors;		md_disk->heads = geo.heads;		md_disk->cylinders = geo.cylinders;		md_disk->start = geo.start;	    }	    	    ndisk++;  /* count the disk */   	}  /* for (pass=...    */	dev_close(&dev);   	raid_bios[ndisk] = 0;		/* mark the end */   	raid_device[ndisk] = 0;	all_pri_eq &= raid_offset_set;	if (all_pri_eq && do_md_install == MD_SKEWED) {	    do_md_install = MD_MIXED;	}	else pri_index = lowest;

⌨️ 快捷键说明

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