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

📄 lilo.c

📁 linux 的引导程序源码The Microsoft&reg Windows&reg Software Development Kit (SDK) provides the documentation
💻 C
📖 第 1 页 / 共 3 页
字号:
/* lilo.c  -  LILO command-line parameter processing *//*Copyright 1992-1998 Werner Almesberger.Copyright 1999-2002 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.*/#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 "common.h"#include "lilo.h"#include "boot.h"#include "temp.h"#include "device.h"#include "geometry.h"#include "map.h"#include "bsect.h"#include "cfg.h"#include "identify.h"#include "partition.h"#include "probe.h"#include "md-int.h"#include "edit.h"#include "flags.i"static int lowest;static md_array_info_t md_array_info;static DT_ENTRY *md_disk;static DT_ENTRY *disk;static unsigned long 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, md_bios;enum {MD_NULL=0, MD_PARALLEL, MD_MIXED, MD_SKEWED};int do_md_install;char *config_file;		/* actual name of the config file */int config_read;		/* readable by other than root */FILE *errstd;static char *raid_list[MAX_RAID];static int list_index[MAX_RAID];static int ndisk, nlist, faulty;#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);}#if 0static int is_master(int device){    int mask;        mask = has_partitions(device);    if (!mask) die("is_master:  Not a valid device  0x%04X", device);    mask = device & ~mask;    return (!mask);}#endifstatic int master(int device){    int mask;        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);}static void raid_final(void){    int pass, force;    char *cp;	if (verbose>=2)	printf("do_md_install: %s\n", do_md_install == MD_PARALLEL ? "MD_PARALLEL" :		do_md_install == MD_MIXED ? "MD_MIXED" :		do_md_install == MD_SKEWED ? "MD_SKEWED" : "unknown");		    if (extra == X_MBR_ONLY) {            pass = 0;        while (pass < ndisk) {	    if (!test) {	        force = 0;	      /* we need to re-visit the logic about backups */	        if ((cp=cfg_get_strg(cf_options,"force-backup"))) force=1;	        else cp=cfg_get_strg(cf_options,"backup");	    	        bsect_raid_update(raid_mbr[pass], raid_offset[pass],			cp, force, pass);	        if (!nowarn) fprintf(errstd, "The Master boot record of  %s  has been updated.\n", raid_mbr[pass]);	    } else {	        if (pass==0) {	    	    bsect_cancel();		    if (passw) fprintf(errstd,"The password crc file has *NOT* been updated.\n");		    fprintf(errstd, "The map file has *NOT* been altered.\n");	        }	        fprintf(errstd,"The Master boot record of  %s  has *NOT* been altered.\n", 	    		raid_mbr[pass]);	    }	    pass++;        }    }     else {	/*  extra != X_MBR_ONLY   */    	char *boot = cfg_get_strg(cf_options,"boot");    		raid_flags &= ~FLAG_RAID_DEFEAT;    /* change won't affect /dev/mdX */	if (!test) {	    force = 0;	    	    if ((cp=cfg_get_strg(cf_options,"force-backup"))) force=1;	    else cp=cfg_get_strg(cf_options,"backup");	/* write out the /dev/mdX boot records */	    	    bsect_raid_update(boot, 0L, cp, force, 0);	    if (!nowarn) fprintf(errstd, "The boot record of  %s  has been updated.\n", boot);	}	else {	    bsect_cancel();	    if (passw) fprintf(errstd,"The password crc file has *NOT* been updated.\n");	    fprintf(errstd, "The map file has *NOT* been updated.\n");	    fprintf(errstd,"The boot record of  %s  has *NOT* been updated.\n", 	    		boot);	}	if (extra == X_NONE || (extra == X_AUTO && do_md_install == MD_PARALLEL) ) return;	if (extra == X_SPEC)	for (pass = 0; pass < nlist; pass++) {	    int index;	    	    if (raid_bios[list_index[pass]] & 0xFF) {	    	index = list_index[pass];	/* within RAID set */	    }	    else {  /* not in the RAID set */	    	raid_flags |= FLAG_RAID_DEFEAT;  /* make outsider invisible */	    	index = lowest;	    }	    if (verbose>=2) printf("Specifed partition:  %s  raid offset = %08lX\n",					raid_list[pass], raid_offset[index]);	    if (!test) {	        bsect_raid_update(raid_list[pass], raid_offset[index],	    		NULL, 0, 1);	    }	    if (test || !nowarn)	        fprintf(errstd,"The boot record of  %s  has%s been updated.\n",			raid_list[pass], (test ? " *NOT*" : ""));	    raid_flags &= ~FLAG_RAID_DEFEAT; /* restore DEFEAT flag to 0 */	}	else {		/* extra = X_AUTO */	    for (pass = 0; pass < ndisk; pass++)	    if (!(raid_bios[pass] & IS_COVERED) && (raid_bios[pass] & 0xFF) != 0x80) {		if (!test)		    bsect_raid_update(raid_mbr[pass], raid_offset[pass],		    	NULL, 0, 1);		if (test || !nowarn)	            fprintf(errstd,"The Master boot record of  %s  has%s been updated.\n",			raid_mbr[pass], (test ? " *NOT*" : ""));	    }	}    }    if (raid_flags & FLAG_RAID_NOWRITE) {	if (!nowarn) {		fprintf(errstd, "Warning: FLAG_RAID_NOWRITE has been set.\n");		if (verbose >= 1)		fprintf(errstd,   "  The boot loader will be unable to update the stored command line;\n"		                  "  'lock' and 'fallback' are not operable; the 'lilo -R' boot command\n"		                  "  line will be locked.\n\n");	}    }}static long raid_setup(void){    int pass, mask;    struct stat st;    int md_fd;    md_disk_info_t md_disk_info;    GEOMETRY geo;    char *boot, *extrap;    int ro_set, all_pri_eq, pri_index;    long pri_offset;    int raid_limit;        if ((boot=cfg_get_strg(cf_options,"boot")) != NULL &&        strncmp("/dev/md",boot,7) == 0) {	if ((md_fd=open(boot,O_NOACCESS)) < 0)	    die("Unable to open %s",boot);	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);	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 == 0) && (md_array_info.minor_version < 90))	    die("Raid versions < 0.90 are not supported");	if (md_array_info.level != 1)	    die("Only RAID1 devices are supported as boot devices");	if (!linear && !lba32) {#if 0	    cfg_set(cf_options,"lba32",NULL,NULL);#endif	    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 :		    X_SPEC;		do_md_install = MD_PARALLEL;	all_pri_eq = 1;	ro_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 = (MD_MAJOR << 8) | 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 = (MD_MAJOR << 8) | 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;   	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)		die("main: GET_DISK_INFO: %s", strerror(errno));	    device = (md_disk_info.major << 8) | md_disk_info.minor;            if(verbose>=2) printf("md: RAIDset device %d = 0x%04X\n", pass, device);	    	    if (device == 0) { /* empty slot left over from recovery process */	        faulty++;		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>=2)		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_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 (ro_set) {		    all_pri_eq &= (pri_offset == raid_offset[ndisk]);		} else {		    pri_offset = raid_offset[ndisk];		    ro_set = 1;		    pri_index = ndisk;		}	    }	    if (geo.device < md_bios) {	        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 >= 2 && do_md_install) {		printf("disk->start = %d\t\traid_offset = %ld (%08lX)\n",		   disk->start, (long)raid_offset[ndisk], (long)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=...    */   	if(close(md_fd) < 0) die("Error on close of %s", boot);   	raid_bios[ndisk] = 0;		/* mark the end */   	raid_device[ndisk] = 0;	all_pri_eq &= ro_set;	if (all_pri_eq && do_md_install == MD_SKEWED) {	    do_md_install = MD_MIXED;	}	else pri_index = lowest;	/* check that all devices have an accessible block for writeback info */	for (pass=0; pass < ndisk; pass++) {	    if (extra == X_MBR_ONLY)		raid_bios[pass] |= TO_BE_COVERED;	    if (extra == X_AUTO && raid_bios[pass] != 0x80) {		if (do_md_install == MD_SKEWED)  raid_bios[pass] |= TO_BE_COVERED;		if (do_md_install == MD_MIXED) {		    if (is_primary(raid_device[pass])) raid_bios[pass] |= IS_COVERED;		    else  raid_bios[pass] |= TO_BE_COVERED;

⌨️ 快捷键说明

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