分享
 
 
 

构造Linux的图形化安装程序(3)

王朝system·作者佚名  2006-11-23
窄屏简体版  字體: |||超大  

分区功能和RAID、LVM支持

本文是构造Linux的图形化安装程序系列文章的第三部分,作者将从基本的分区表结构开始,介绍分区功能的实现和如何支持RAID、LVM这些高级功能。

分区功能对于Linux图形化安装程序来说,是一个非常重要的功能。它的基本功能是自动识别硬盘,并在硬盘上创建ext2类型的分区和交换分区。用户将此分区作为根分区,在其上进行Linux系统的安装。

对于一个功能较全的安装程序,它还应该具备创建其他类型的分区的能力,包括reiserfs、fat等等,创建软件RAID分区,创建逻辑卷管理分区的能力。以及具有过滤合法安装点,根据选择的分区类型决定最合适挂接点的能力。分区能够动态的删除和修改,分区操作能够恢复到分区操作之前具体内容的状态。

这个部分介绍的主要内容包括代码都是基于HappyLinux的安装程序,所有功能全部在HappyLinux3.0的安装程序中实现。您可以在安装盘的/HappyLinux/happyinst/usr/bin/perl-install目录下获得安装程序[url=http://www.pccode.net].net" class="wordstyle"源码。

1 安装程序分区模块介绍

在图形化安装程序中,硬盘分区的一般流程是:

装程序中与分区功能密切相关的模块包括:

diskdrake.pm

图形化的分区处理模块,它是分区功能的主控模块,处理与用户的交互,进行分区操作的合法性检查。

diskdrake.rc

分区操作窗口的资源文件,主要描述不同分区类型的表述。

fs.pm

完成挂接和格式化分区的操作,同时也生成/etc/fstab文件。

fsedit.pm

获得硬盘分区结构,完成添加、删除、修改分区的操作。

lvm.pm

提供创建、修改和获取逻辑卷管理分区的模块。

partition_table.pm

对分区表操作的逻辑副本进行操作的模块,包括分区操作的合法性判断、设置分区对齐、读取主分区和扩展分区、类型判断的函数。

partition_table_dos.pm

对dos类型的分区表进行操作的模块。

partition_table_raw.pm

直接存取硬盘分区表读取/写入分区信息。

raid.pm

软件raid设备进行处理的模块。

2 基本分区功能

硬盘主分区由240字节的硬盘主引导记录(0000H-00EFH),64字节的硬盘分区表(01BEH-01FDH)以及最后两个字节的自举记录有效标志等三部分组成。主引导记录块的布局:

硬盘0柱面0磁头1扇区

主引导记录代码区

第一个分区表

第二个分区表

第三个分区表

第四个分区表

主引导记录有效标志55H,AAH

表 1-1

硬盘分区各个字段的意义是:

字节位移 长度(字节) 字段含义

0 1 活动分区指示符。该值为80H,表示可自举分区(仅有一个);改值为00H,表示不可自举分区。该字节也称为自举标志。

1 1 起始磁头号

2 1 起始扇区号(低6位)和起始柱面号的高2位

3 1 起始柱面号的低8位

4 1 分区上的系统标志。

该值为01H,表示采用12位FAT格式的DOS分区。

该值为04H,表示采用16位FAT格式的DOS分区。

该值为07H,表示采用NTFS分区。

该值为0BH,表示采用WIN98的FAT32格式的分区。

该值为0CH,表示采用WIN98的FAT32格式的分区,支持LBA方式。

该值为0FH,表示采用WIN95的扩展分区,支持LBA方式。

该值为82H,表示采用LINUX SWAP格式的分区。

该值为83H,表示采用LINUX EXT2格式的分区。

该值为8EH,表示采用LVM格式的分区。

该值为FDH,表示采用软件RAID格式的分区。

5 1 结束磁头号

6 1 结束扇区号(低6位)和结束柱面号的高2位

7 1 结束柱面号的低8位

8 4 相对扇区号

12 4 该分区所用的扇区号

表 1-2

硬盘分区是以链接表的形式存在的,在每个硬盘上都存在一个主分区描述块,它可以描述四个分区,每个硬盘最多只存在四个主分区,其他的分区则为扩展分区。每个扩展分区是通过链接字段联结在一起。

主分区使用的设备别名是从/dev/hda1到/dev/hda4,其后从/dev/hda5开始的分区,都代表扩展分区。

读入分区表 #- 以下代码读入整个硬盘分区表形成分区的描述结构。

sub read($;$) {

my ($hd, $clearall) = @_;

if ($clearall) {

partition_table_raw::zero_MBR_and_dirty($hd);

return 1;

}

#- 读入主分区表,检测这分区表上扩展分区数,如大于1,则出错。

my $pt = read_one($hd, 0) or return 0;

#- 主分区描述数组存入primary变量中。

$hd->{primary} = $pt;

undef $hd->{extended};

#- 校验主分区,校验包括:分区是否重叠,是否存在未知空洞。

verifyPrimary($pt);

#- 如果存在扩展分区,则读入扩展分区,这时要检测扩展分区是否重叠,是否存在循环联结。

eval {

$pt->{extended} and read_extended($hd, $pt->{extended}) || return 0;

};

#- 对读出的分区指定其设备号,主分区/dev/hda1(/dev/sda1)到/dev/hda4(/dev/sda4)。

assign_device_numbers($hd);

#- 除去扩展分区中的空连接。

remove_empty_extended($hd);

1;

}

将分区操作写入分区表 #- 此操作只是根据用户的操作写分区表,包括写入分区大小分区类型等信息。

sub write($) {

my ($hd) = @_;

$hd->{isDirty} or return;

#- 设置引导标志

for ($hd->{primary}{raw}) {

(grep { $_->{local_start} = $_->{start}; $_->{active} ||= 0 } @$_) or $_->[0]{active} = 0x80;

}

#- 校验分区,校验包括:分区是否重叠,是否存在未知空洞。

verifyParts($hd);

#- 写入分区表

$hd->write(0, $hd->{primary}{raw}, $hd->{primary}{info}) or die "writing of partition table failed";

$hd->{isDirty} = 0;

$hd->{hasBeenDirty} = 1;

if ($hd->{needKernelReread}) {

sync();

$hd->kernel_read;

$hd->{needKernelReread} = 0;

}

}

3 创建文件系统

在分区操作结束之后,为了在其上进行安装,还需要在分区上创建文件系统。安装程序是使用系统命令,比如mkdosfs,mke2fs,mkreiserfs来创建文件系统。

sub format_ext2($@) {

my ($dev, @options) = @_;

$dev =~ m,(rd|ida|cciss)/, and push @options, qw(-b 4096 -R stride=16);

push @options, qw(-b 1024 -O none) if arch() =~ /alpha/;

#- 调用mke2fs创建ext2文件系统

run_program::run("mke2fs", @options, devices::make($dev)) or die _("%s formatting of %s failed", "ext2", $dev);

}

sub format_dos($@) {

my ($dev, @options) = @_;

#- 调用mkdosfs创建fat文件系统

run_program::run("mkdosfs", @options, devices::make($dev)) or die _("%s formatting of %s failed", "dos", $dev);

}

创建Reiserfs文件系统

sub format_reiserfs($@) {

my ($dev, @options) = @_;

#- 调用mkreiserfs创建Reiserfs文件系统

run_program::run("mkreiserfs", "-f", @options, devices::make($dev)) or die _("%s formatting of %s failed", "reiserfs", $dev);

}

在使用Reiserfs文件系统作为系统的根分区时,系统在启动的过程中需要加载模块reiserfs.o。RedHat 7.0以下的版本则不支持Reiserfs文件系统,所以很多基于RedHat的发行版本也不支持Reiserfs文件系统。如果您要在这样的系统上加入reiserfs支持,除了装载Reiserfs对应的rpm包之外,还要在生成初始启动镜像(initrd)时,在linuxrc中加载Reiserfs模块。

这需要在/sbin/mkinitrd文件中加入下列语句:

# 对于/etc/fstab中挂接的文件系统,如果它的类型不是ext2,那么必须加载设备模块。

fs=$(awk '$2 == "/" {print $3 }' /etc/fstab)

[ -n "$fs" -a "$fs" != "ext2" ] && findmodule $fs

4 支持LVM类型的分区

一般而言,磁盘分区的大小是固定的,它要求用户在安装系统时对分区空间的使用有大概的了解。在用户用尽了分区上所有的空间时,则要求重新分区或者移走一部分文件。

LVM(Logical Volume Management)是逻辑卷管理的缩写。它的出现将物理磁盘分割成一些逻辑单位,来自于不同磁盘的分区能组成一个逻辑卷。此外,在需要时分区能被动态的加入和删除。举例来说,如果你有一个8GB的磁盘,其上有一个2GB的分区/usr,它的空间已经耗尽了。如果您要扩大/usr分区的话,必须首先创建一个更大的分区,然后将/usr的所有内容都拷贝到此分区中,改变/etc/fstab文件,重新启动。但是如果在系统中使用了LVM的话,你只需使用LVM中的命令,就可以简单的增大/usr。

LVM的分区方式对于需要大数据量存储的分区进行管理,可以极大的减轻管理员的负担。而且,在LVM和RAID设备结合使用之后,可以构造出一种灵活而且高效的存储方案。

4.1 LVM的基本概念

后面在建立LVM类型的分区时,会用到一些术语,下面先对这些术语进行介绍。

物理卷(PV)

物理卷仅仅是进行了LVM初始化的物理分区,以使得LVM管理程序能识别这个分区。

物理范围(PE)

物理范围是一些大数据块,通常有几兆字节。

卷组(VG)

一个VG可由多个PE组成。一个VG可由几个分区组成,它包含的PE由这些分区提供。在某种意义上说,我们可以认为VG就是一个硬盘设备。

逻辑卷(LV)

逻辑卷是最终用户访问的部分,它用于存储数据。在某种意义上说,我们可以认为LV就是一个逻辑分区。其上可以创建任何类型的分区,包括EXT2,ReiserFS,NTFS等等。在访问时,它和正常的磁盘分区一样。

逻辑范围(LE)

每个逻辑卷被分割成为数据块。

为了使LVM在系统中能够正常工作,那么在定制内核的时候,要将LVM支持作为模块形式定制。然后,为了创建和管理LVM逻辑分区,您还需要安装LVM包。

步骤如下:

使用fdisk命令设置分区/dev/hda3和/dev/hdc3类型为0x8e。

创建物理卷。

pvcreate /dev/hda3

pvcreate /dev/hdc3

创建新卷组newvg,它包含/dev/hda3和/dev/hdc3分区,卷组的大小是两个分区容量的总和。在成功创建此卷组之后会在/dev目录下形成目录/dev/newvg,在其后生成的逻辑卷设备文件都保存在此目录下。

vgcreate newvg /dev/hda3

vgcreate newvg /dev/hdc3

创建新的逻辑卷

lvcreate -L1500 -nnewlv newvg

创建一个1500MB线性逻辑卷,同时这条命令也创建逻辑卷对应的块设备文件/dev/newvg/newlv。

lvcreate -i2 -I4 -l1500 -notherlv newvg

以交错块(stripe)为2,块大小为4 KB创建另一个逻辑卷,对应的设备别名是/dev/newvg/otherlv。

创建文件系统

mke2fs /dev/newvg/newlv

在设备/dev/newvg/newlv上创建ext2文件系统,除了ext2文件系统之外,您还可以创建Reiserfs等多种文件系统。

激活lvm逻辑卷

vgchange -a y

在使用卷组之前,控制卷组对内核的可见性。这条命令激活系统中所有已知的卷组。在删除一个卷组之前,最好先使用vgchange -a n禁用卷组。

读入LVM分区信息 sub get_lvs {

my ($lvm) = @_;

my @fstabs;

my $start = 0;

@fstabs = ();

$lvm->{primary}{normal} = ();

undef $lvm->{primary}{normal};

#- 使用vgdisplay -v -D lvmname获得所有卷组。

foreach (map { /^LV Name\s+(\S+)/ ? $1 : () } `vgdisplay -v -D $lvm->{LVMname}`) {

#- 使用lvdisplay -D -c lv获得逻辑卷的信息。

my @lvinfo = split(':', `lvdisplay -D -c $_`);

my $size = $lvinfo[6];

my $type = -e $_ && fsedit::typeOfPart($_);

my %fstab;

$fstab{device} = $_;

$fstab{type} = $type || 0x83;

$fstab{size} = $size;

$fstab{isFormatted} = $type;

$fstab{number} = $lvinfo[4];

$fstab{start} = $start;

$fstab{lvm} = $_;

$start += $size;

push @fstabs, \%fstab;

}

$lvm->{primary}{normal} = \@fstabs;

}

将LVM分区操作写入磁盘 #- 对已经删除的lvm分区,则除去其上的逻辑卷,然后将其除去。

#- 若只有部分逻辑卷被除去,则删除这部分逻辑卷

foreach my $lv (@{$o->{lvms}}) {

if ($lv->{isRemove}) {

#- 除去所有的逻辑卷

foreach (fsedit::get_fstab($lv)) {

lvm::lv_delete($_);

}

#- 清空主分区描述结构

splice @{$lv->{primary}{normal}}, 0;

#- 清除卷组

lvm::vg_destroy($lv);

} else &#

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有