Linux系统管理

2024-07-26

Linux系统管理(通用12篇)

Linux系统管理 篇1

现代嵌入式处理器上越来越多的使用Linux操作系统。这不仅由于Linux是免费开源的, 并有众多的软件开发者共同开发, 它也具有实时性等特点, 来满足嵌入式系统开发所需的特性。虽然Linux本身就提供很好的内存使用机制, 但是由于通信软件对内存使用有其特殊的方式, 长期的直接运行于Linux之上会造成很多的内存碎片, 造成无法申请到内存。

本文基于Linux操作系统设计了一种虚拟软件平台, 并着重介绍这个虚拟平台提供的内存管理机制。

1 Linux操作系统以及虚拟软件平台

1.1 Linux操作系统

Linux是一套免费使用和自由传播的类Unix操作系统, 是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想, 是一个性能稳定的多用户网络操作系统。

由于Linux具有的众多特性, 通信设备中越来越多地采用Linux, 代替费用昂贵的VxW orks操作系统。尽管会降低一定程度的实时性, 但由于实时业务的逐年下降, 取而代之的是非实时的数据业务, 系统对于实时性的依赖程度逐渐降低, 这也为使用linux提供了可行性。

1.2虚拟软件平台

通信软件架构一般采用如下图的软件架构模式。

虚拟软件平台位于操作系统与上层软件之间, 屏蔽了操作系统的特性, 由于其特殊的作用, 所以它必须提供诸如TCP/IP通信, 进程间通信, 进程调度, 内存管理, 定时器管理, 状态机等诸多功能, 而最为重要的就是内存管理。

2内存管理

2.1内存的分类

系统内存分为堆内存以及栈内存, 对于小于2 048字节的内存, 一般使用的是栈内存, 这种大小的数据区一般用来传输信令数据, 对于传输更大的数据块, 需要申请的是堆内存。

2.2内存池初始化

根据分析通信系统软件架构, 大概需要几种消息类型, 它们使用的数据长度大约为128字节, 256字节, 512字节, 1024字节, 2 048字节, 4 096字节, 8 192字节, 16 384字节等。 (如图2所示)

在内存池的构建上, 我们也根据需求, 分别向操作系统申请堆内存以及栈内存。其中小于以及等于2 048字节的, 申请栈内存, 即静态数据区内存;对于大于2 048字节的, 申请堆内存, 即动态内存区内存。但是动态内存在内存池初始化后对于操作系统来说, 它也变成了静态的内存, 因为所有的内存申请操作以及回收操作, 都是这一片在初始化即申请到的系统内存上面进行。

2.3内存分配使用算法

根据业务模块调用传进的数据长度参数, 判断数据长度是属于哪一个数据区间, 如果小于64字节, 即使用64字节内存池, 如果数据长度在64与128之间, 则使用128字节内存池, 以此类推。

申请到内存池的内存块后, 内存管理模块, 自动把它从就绪队列移到运行队列尾, 并根据系统时间戳, 申请串号 (内存池行号以及列号) , 申请内存进程ID, 对内存块标注 (形成一个唯一的标识) , 直到内存申请进程释放这片内存, 内存管理模块根据申请串号在运行队列找到这片内存, 并把它内容清空, 放回到就绪队列尾。

2.4并发申请

如果使用内存管理模块的应用进程为多线程处理, 就必须在申请内存的操作以及释放内存的操作加入互斥机制, 比如线程锁, 或者信号的PV操作, 等等, 用来保护内存管理机制, 使其能够串行地对内存池进行操作。

抑或为了增加系统的并发性处理机制, 可以在初始化的时候明确应用进程使用几个线程, 为每个线程独立配备一个内存池, 这样不会出现竞争机制, 加快了系统的运行速度。

笔者推荐后一种方法, 因为通信软件的系统特性, 这种处理方法更有利于系统稳定的运行。

3结语

内存作为一个系统软件运行依赖最为重要的资源, 需要统一地进行分配管理, 不能由上层的业务模块自行调用系统API, 去直接操作系统内存, 这样会造成内存碎片的产生, 降低系统的可靠性。

摘要:介绍了Linux操作系统的概念应用的场景, 基于Linux操作系统以及通信软件架构, 设计了一种虚拟平台, 并着重描述了这种虚拟操作系统提供的内存管理机制。

关键词:Linux操作系统,虚拟软件平台,内存管理

参考文献

[1] (美) 博韦.深入理解LINUX内核[M].陈莉群, 冯锐, 牛欣源, 译.中国电力出版社, 2008.

[2][美]洛夫.Linux系统编程[M].东南大学出版社, 2009.

[3]Dharma Prakash Agrawal Qing-An Zeng.无线与移动通信系统[M].徐春秀, 武穆清, 译.人民邮电出版社, 2005.

[4] (美) W.Richard Stevens Stephen A.Rago.UNIX环境高级编程[M].尤晋元, 张亚英, 戚正伟, 译.人民邮电出版社, 2008.

[5]严蔚敏, 吴伟民.数据结构 (C语言) [M].清华大学出版社, 2007.

Linux系统管理 篇2

Linux 指令篇:系统管理screen

语 法:screen[-AmRvx-ls-wipe][-d<作业名称>][-h<行数>][-r<作业名称>][-s][-S<作业名称>]

补充说明:screen为多重视窗管理程序。此处所谓的视窗,是指一个全屏幕的文字模式画面。通常只有在使用telnet登入主机或是使用老式的终端机时,才有可能用到screen程序。

参 数:

-A将所有的视窗都调整为目前终端机的大小,

-d<作业名称>将指定的screen作业离线。

-h<行数>指定视窗的缓冲区行数。

-m即使目前已在作业中的screen作业,仍强制建立新的screen作业。

-r<作业名称>恢复离线的screen作业。

-R先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。

-s指定建立新视窗时,所要执行的shell。

-S<作业名称>指定screen作业的名称。

-v显示版本信息。

-x恢复之前离线的screen作业。

-ls或--list显示目前所有的screen作业。

Linux:自由的操作系统 篇3

近十年来,Linux作为操作系统世界里冉冉升起的新星,继承了Unix操作系统的良好基础,以开放源代码的特性吸引了全世界电脑爱好者,受到了包括IBM、HP、Intel和Oracle在内的一些计算机业巨头的技术支持,从而在技术方面得到了迅速的发展,已成为能够与Unix、Windows和Mac OS抗衡的操作系统。

了解Linux

说到Linux,不能不提Unix操作系统。Unix操作系统诞生于1969年,是一个分时、多用户、多任务、具有网络功能、通信功能和可移植性的操作系统,广泛应用于各种机型,是影响范围最大、最为稳定的操作系统之一。但是,Unix系统比较庞大,大部分安装在小型机上,价格也很昂贵。在Linux出现之前,使用Unix系统对于个人用户是一个可望而不可及的梦想,但正是Linux使这种梦想变成了现实。

Linux是Unix操作系统的克隆。Linux系统的创始人—芬兰的赫尔辛基大学学生Linus Torvalds对Unix操作系统相当感兴趣,考虑将它移植到个人计算机 (Intel X86 架构)上。他潜心研究 Unix 的核心,并且去除较为繁复的核心程序,1991年在386的计算机上开发出了Linux 第一个0.01版的内核,首次在Internet上公布。之后,在Linus的带领下,通过互联网,一个世界范围内的开发组对Linux进行坚持不懈的开发,到了 1994 年正式发布了内核为1.0的Linux操作系统,同时作为Linux的吉祥图案的一只可爱的胖企鹅Tux诞生了。在短短的十年里Linux的 内核已发布了数十种版本(http://www.kernel.org),目前内核已升至2.6.8.1。

Linux发展的初期与Windows明显不同的是, 它的安装比较麻烦、图形界面的友好度比较低,这也导致Linux在桌面领域普及缓慢。值得庆幸的是,随着时间的推移,开发者们越来越意识到图形界面的重要性,在开发过程中融入了其他图形化操作系统的优点,包括微软的Windows系统和Unix的CDE等。目前在Linux上已实现多个图形管理程序,可变换不同的桌面图案或功能菜单,这点是Windows操作系统的单一图形接口也望尘莫及的。Linux应用最普遍的图形用户界面KDE和GNOME(见图1),不但能够给用户提供一个完整的图形界面,同时还给软件开发提供了一条捷径。事实上已涌现出越来越多的针对KDE和GNOME的应用程序。

Linux的发行版本

Linux这个词本身只表示Linux内核,对于需要更完整功能的操作系统来说,毕竟还不够完备。可能还需要一些软件开发工具、数据库、Web服务器(例如Apache 服务器)、桌面环境(比如KDE和GNOME)和办公套件(如Openoffice)等等。由于Linux免费的内核及良好的稳定性,并可以在便宜的x86 架构下的计算机平台运作,所以吸引了很多的套件商与自由软件的开发团队,在这个 Linux 的核心上开发相关的软件。他们将 Linux 内核、内核工具与相关的软件,包括一些GNU软件(如gcc、cc、C++、Tcl/Tk、Perl、Fortran77等)集合起来,并加入自己公司或团队的系统管理模块与工具,制作出一套可以完整安装的操作系统。这个完整的Linux 操作系统,我们就称为“Linux Distribution”,或者是中文所谓的安装套件。

目前世界上已有百种以上不同的Linux安装套件组合,但不论这些套件的名称或开发厂商是谁,它们都是同属于 Linux 的大家庭。由于各个 Distribution 都是架构在 Linux内核下发展属于自己公司的风格,因此大家都遵守 Linux Standard Base ( LSB ) 的规范,也就是说,各个 Distribution 其实都是差不多的,只是里面所使用的各套件可能并不完全相同而已。各家公司所发行的光盘套件是可以在网络上面自由下载的。不过,如果想要有较佳的服务,那么购买该公司发行的光盘也是不错的选择。

几个主要的 Linux 发行公司的网址:

Red Hat: http://www.redhat.com

Turbolinux: http://www.turbolinux.com

FreeBSD: http://www.freebsd.org

Debian: http://www.debian.org

Mandrake: http://www.linux-mandrake.com/en/

Slackware: http://www.slackware.com/

SuSE: http://www.suse.com/index_us.html

Fedora: http://fedora.redhat.com

……

了解更多信息,您可以查阅Linux Distributions 的网站: http://www.linuxiso.org 或http://www.fokus.gmd.de/linux/linux-distrib.html。

近年来,Linux 在我国取得了可喜的发展,涌现出不少颇具实力的中文Linux 发行商。

Redflag Linux: http://www.redflag-linux.com

Xteam linux: http://www.xteamlinux.com.cn

Linux的优势

Linux已成为最近几年来最受瞩目的操作系统之一,主要原因是它的免费,以及系统的开放性,可以随时取得程序的原代码,这对于程序开发人员是很重要的。除了这些它还具有以下的优势:

1.跨平台的硬件支持

由于Linux的内核大部分是用C 语言编写的,并采用了可移植的Unix标准应用程序接口,所以它支持如i386、Alpha、AMD和Sparc等系统平台,以及从个人电脑到大型主机,甚至包括嵌入式系统在内的各种硬件设备。

2.丰富的软件支持

与其他的操作系统不同的是,安装了Linux系统后,用户常用的一些办公软件、图形处理工具、多媒体播放软件和网络工具等都已无需安装。而对于程序开发人员来说,Linux更是一个很好的操作平台,在Linux的软件包中,包含了多种程序语言与开发工具,如gcc、cc、C++、Tcl/Tk、Perl、Fortran77等。

3.多用户多任务

和Unix系统一样,Linux是一个真正的多用户多任务的操作系统。多个用户可以各自拥有和使用系统资源,即每个用户对自己的资源(例如:文件、设备)有特定的权限,互不影响,同时多个用户可以在同一时间以网络联机的方式使用计算机系统。多任务是现代计算机的最主要的一个特点,由于Linux系统调度每一个进程是平等地访问处理器的,所以它能同时执行多个程序,而且各个程序的运行是互相独立的。

4.可靠的安全性

Linux是一个具有先天病毒免疫能力的操作系统,很少受到病毒攻击。

对于一个开放式系统而言,在方便用户的同时,很可能存在安全隐患。不过,利用Linux自带防火墙、入侵检测和安全认证等工具,及时修补系统的漏洞,就能大大提高Linux系统的安全性,让黑客们无机可乘。

5.良好的稳定性

Linux内核的源代码是以标准规范的32位(在64位CPU上是64位)的计算机来做的最佳化设计,可确保其系统的稳定性。正因为Linux的稳定,才使得一些安装 Linux 的主机像Unix机一样常年不关而不曾宕机。

6.完善的网络功能

Linux 内置了很丰富的免费网络服务器软件、数据库和网页的开发工具,如Apache、Sendmail、VSFtp、SSH、MySQL、PHP和JSP等。近年来,越来越多的企业看到了Linux的这些强大的功能,利用Linux担任全方位的网络服务器。

Linux系统管理 篇4

随着人们对能源需求量的迅速增长和非可再生资源的枯竭,可再生能源的开发利用开始受到世界各国的高度重视,光伏发电得到迅速发展,尤其是应用于偏远、交通不便、架设供电线路投资较大地区的独立光伏发电系统成为国家重点投资的对象。而约占初期投资的1/4~1/2的蓄电池在独立光伏系统中的作用至关重要,其又是系统中比较薄弱的环节,因此蓄电池的优化管理越加显得重要。它不但有利于充分利用光能资源,延长光伏发电系统的使用寿命,更使整个系统能够安全、稳定运行。这就要求其有较高的可靠性和随发展需要的可扩展能力。

当前,嵌入式系统以其优越的稳定性、可靠性和控制能力占领微控制市场。它的迅猛发展使其开发成本大幅降低,开发周期缩短,普遍应用于工业控制成为可能。本文以ARM9控制器为硬件平台,采用嵌入式Linux为操作系统实现蓄电池的全面管理,并监测控制整个光伏发电系统及其负载,使之处于完全、稳定、可靠的运行状态之中,并且便于系统的升级和扩展。

1 管理系统的功能

该管理系统的主要功能是对蓄电池的管理,包括:

(1)数据采集。其中有对光伏电池、蓄电池和负载的数据采集。

(2)蓄电池的状态预测。有蓄电池的荷电状态(So C)和健康状态(So H)。

(3)蓄电池的充放电控制。在独立光伏系统中,蓄电池的充放电不同于其它系统蓄电池的特点,其充电电源来自于太阳能电池阵列,能源不用则失,而且系统设计的太阳能电池阵列容量有限,所以放电深度必须适中。如果太浅,则蓄电池容量需求大,投入就大;如果太深,则蓄电池寿命缩短,影响发电成本,且每天需进行放电和充电,受天气影响,容易形成当弱光照时蓄电池欠充和当强光照时蓄电池过充的状态,所以必须合理控制充电速度。

(4)光伏电池、负载、蓄电池的状态显示与保护报警。将蓄电池当前所处的荷电状态、充电时的电压电流、负载的功率、光伏电池的发电功率等显示给用户,并且适时的提醒用户节约用电或鼓励用户用电,以充分利用光能资源和太阳能电池。

2 管理系统的硬件设计

本系统采用三星公司的S3C2410芯片作为嵌入式系统的主控制器,与数据采集、驱动控制等硬件一起构成整个蓄电池的管理系统,如图1所示。

S3C2410芯片是基于A R M920T内核的16/32位RISC嵌入式微处理器,功耗低,集成了大量的功能扩展单元,便于管理系统的功能扩展与升级,性价比高。强大的芯片功能不但简化了系统设计,而且提高了系统的可靠性,缩小了系统体积。

光伏电池与负载的电压、电流信息通过变送器,滤波放大,A/D转换后,传送给处理器,以便处理器输出太阳能电池最大功率点跟踪(MPPT)控制信号,使光伏电池工作在最大功率点,充分利用太阳能资源。并且根据负载状态,确定充放电控制,并将相关信息显示给用户。

综合考虑独立光伏系统所使用的蓄电池和铅酸蓄电池的特征确定本系统采用阀控式铅酸蓄电池(VRLA)[1]。对于阀控式铅酸蓄电池,由于其全封闭特性所能监测的信息只有蓄电池的端电压、电流和温度,并且通过它们来预测蓄电池的荷电状态(So C)和健康状态(So H)、控制蓄电池的充放电,这就要求所获得的数据必须要精确,所以经多路转换开关后再经高精度A/D转换器(ADC7888)接入处理器。由于使用蓄电池数量较多,采用分组管理的策略,每组中的单体电池可共用一个通道,建议每组中的最佳数量为1~10个电池,为了方便系统扩建,蓄电池的数据采集采用分散式结构,并且定期对蓄电池分组进行过充补偿,防止其因长期处于欠充状态而缩短使用寿命,校正其荷电状态偏移和检查单体电池健康状况。

由于蓄电池的状态受温度的影响是不能忽略的,需要进行补偿,蓄电池的温度对管理同样重要,它是对蓄电池的状态预测进行温度补偿不可缺少的量。在对蓄电池的充放电控制时同样需考虑温度,合理选择充放电方式,使其温度处于可行范围之内,防止损坏蓄电池,延长其使用寿命。

当检测到系统存在故障或蓄电池放电深度达到预先设定参数时,采取相应的保护措施,并报警提醒用户及时处理,使系统运行于安全、稳定之中。

3 管理系统的软件设计

嵌入式Linux是将日益流行的Linux操作系统进行裁剪修改使之能在嵌入式计算机系统上运行的一种操作系统,在裁剪时必须根据具体的硬件进行修改、补充。本系统针对采用的ARM9硬件平台特点对内核进行了裁剪、移植。软件的开发过程如下。

1)建立交叉开发环境

嵌入式系统的软件开发不同于普通的软件开发,由于嵌入式系统硬件的局限性,需要借助其它功能齐全的系统,即采用交叉编译、调试。本系统采用装有Linux操作系统的PC机作为宿主机,使用优化的开发光盘提供的cross-2.95.3作为交叉编译器。

将交叉编译工具装到/usr/local/arn/2.95.3/bin目录下,为了以后开发方便,不必每次都添加环境变量,修改/etc/bashrc,在其末端加入,:export PATH=/usr/local/arn/2.95.3/bin:$PATH。

配置Minicom和tftp服务,实现宿主机与目标机的通信和控制[2]。

2)移植Linux内核

移植Linux内核是整个嵌入式系统设计的关键所在。Linux内核移植需要完成内核与启动代码的衔接部分的移植以及硬件相关部分的移植[3],本系统选择2.4.20Linux内核版本。

首先配置内核,修改Makefile里“ARCH”,ARCH,:arm,运行:make menuconfig,进行相关配置;其次建立内核关系,运行:make dep即可;最后建立内核,使用命令:make bzlmage建立压缩的内核映像。然后使用前面的连接将内核压缩文件下载到目标机上,进行运行调试。为了使目标机跳过登陆,直接将bash运行起来,修改/etc/inittab文件,加入:1:2345:respawn:/bin/bash。

3)应用软件设计

应用软件主要包括:数据采集与处理模块、蓄电池状态分析模块、充放电控制模块、MPPT控制模块、保护报警模块、显示模块。主程序流程图见图2。

其中,在数据采集与处理时加入滤波器,并实行替代机制,增强系统的容错能力。

蓄电池的荷电状态(So C)由蓄电池原状态和充放电电流与时间决定:Qb=Qb0+∫0tIdt。其中,Qb为蓄蓄电池当前荷电状态;Qb0为蓄电池初始荷电状态;I为充电电流。

然而,这种方法长时间运行常常出现漂移,不能准确反映蓄电池的荷电状态,需要进行校正,根据用户的作息特征,采用蓄电池的开路电压分批进行校正。蓄电池的健康状态(So H)首先通过计算充电时的输入电量粗略估计,如发现问题,则通过全充电全放电对该电池进行核实。此外,蓄电池的端电压与荷电状态受温度影响,需进行温度补偿,通常蓄电池的容量与温度成正相关的方向变化,温度每上升1℃,容量就上升原来的0.8%,端电压下降3 m V。程序流程图如图3所示。

蓄电池的充电电源为太阳能光伏电池,光能资源不用则失,且受天气制约,充电时间受到限制,所以充电方式采用脉冲充电、脉冲放电去极化的快速充电方法[4]。放电控制主要限制放电电流,适时的切除负荷,防止蓄电池放电深度过深。快速充电流程图如图4所示。

4 结语

可再生能源的利用已经引起世界各国的重视,光伏发电必将得到长足发展,以缓解人类所面临的能源危机。作为可以解决偏远地区供电问题的独立光伏发电系统同样将受到社会关注,迅速发展,对蓄电池管理系统的功能要求也将越来越高。

本文将蓄电池的管理技术与当前极有发展潜力的嵌入式Linux系统相结合,构建了一个可靠性高、稳定性好、功能强大且扩展能力强的蓄电池管理系统,具有实际应用意义,有助于推动独立光伏发电系统的发展。

摘要:介绍了蓄电池组作为独立光伏发电系统中比较薄弱的环节,在整个系统中至关重要的作用,并分析了蓄电池管理系统的功能要求。采用性能优越的ARM9控制器和嵌入式Linux操作系统构建了一个功能齐全、稳定可靠、方便系统扩展的蓄电池管理系统,实现了蓄电池组的优化管理。

关键词:嵌入式Linux,光伏系统,蓄电池,管理

参考文献

[1]Rand D A J.阀控式铅酸蓄电池[M].郭永榔,译.北京:机械工业出版社,2007:177-203,406-422.

[2]孙琼.嵌入式Linux应用程序开发详解[M].北京:人民邮电出版社,2006:135-143.

[3]孙天泽,袁文菊,张海峰.嵌入式设计及Linux驱动开发指南[M].北京:电子工业出版社,2007:182-184.

Linux系统管理 篇5

dstat下载地址:pkgs.repoforge.org/dstat/ 如果centos中没有安装则可以直接使用yum安装,如果不想使用yum安装可以去上面的站点下载。

这是dstat的打开界面,它会一直刷新系统状态并且将这些内容返回到屏幕当中,如果直接输入dstat,程序则会提示“你没有做出任何筛选状态,将使用-cdngy来作为默认选项”接下来介绍一下这些选项。

常用选项:

-c:显示cpu使用情况

-d:显示磁盘使用情况

-n:显示网络IO

-g:显示分页文件

-y:系统相关数据

-m:内存相关数据

-p:显示进程

-s:交换空间相关信息

--fs:文件系统相关数据

-r:总计io

--lock:文件锁

--socket:套接字文件

--top-cpu:显示最占用cpu的进程

--top-bio:显示最占用块设备io的进程

--top-mem:显示最消耗内存的进程

--top-io:显示最占用io的进程

............

当然还有更多选项供用户选择,可直接使用-h或者--help或者man手册页获取帮助信息

如果我们需要让程序输出一定内容后自动停止下来则可以输入“dstat 1 3”最后程序将于第四次显示后自动退出(这些数字可以用户自定义的,

当我们给过多参数时dstat则判断这个终端是否可以显示完整,如果显示不完整则按照标准输出来显示。

我这里给了-cdngymp(显示了cpu、磁盘、网络、分页文件、系统信息、内存、以及进程等)七个选项执行后程序返回第一行的内容提示终端宽度太小。这时需要结束程序将终端放大后使用。

来看下它自动退出吧。前面有说使用dstat 1 3意思是在第一行显示完成后随后三行刷新一遍后退出

如果把数字1改为2那么就代表了从第二行开始的每一行起刷新两次后再返回给用户,这个请各位自己尝试下吧没办法演示(我也想做gif图。。。可是我用的ubuntu),剩下就是多次练习就好了,就写到这里吧。

★ 地震信号处理中相位匹配滤波器的设计

★ aqadcup.exe 进程信息

★ 进程的近义词

★ Hilbert-Huang变换在水声瞬态信号处理中的应用

★ wininetd wininetd.exe 进程信息

★ winadctl winadctl.exe 进程信息

★ 影响建筑工程管理的因素及处理方法

★ 企业规范化管理之生产管理

★ 简单干净的微信号

Linux系统管理 篇6

关键词:Linux qmail Web邮件系统 嵌入式数据库

0 引言

由于电子邮件不受时间、空间的限制,其成为最基本、最普及、最方便的网络通讯功能。目前,由于电子邮件收发系统本身存在着若干漏洞,其中最引人注目的是接收大量的垃圾邮件与黑客利用电子邮件进行的病毒(如木马)入侵,这些都需要靠人工处理。把E-mail和Web技术结合起来,通过Web编程和适当的系统设置,使用户只需要访问Web就可以得到和使用完整的邮件服务,我们把这种系统称为webmail[1]。本文就基本邮件服务器的构建技术进行相关分析,提供基于Web的数据库管理功能,为管理员提供了方便,同时也为邮件用户提供了基于Web的邮件服务功能。

1 电子邮件系统的构建

1.1 电子邮件收发机制 电子邮件传输过程为,当终端用户发送一封电子邮件时,首先试图去寻找一个信件传输代理,把邮件提交给它,信件传输代理得到了邮件后将它保存在自身的缓冲队列中,然后根据邮件的目标地址,通过对DNS进行查询,搜索到对应这个目标地址的邮件传输代理服务器的IP地址,并通过网络将邮件传送给邮件传输代理服务器。对方的邮件传输代理服务器接收到邮件之后,将其缓冲存储在本地,并通过投递代理将邮件分发至最终用户的邮箱,电子邮件的接收者通过用户代理查看自己的电子信箱。不管是发送过程还是接收过程,电子邮件的传输都要遵循SMTP、POP3、IMAP协议,这些协议确保了电子邮件在各种不同系统之间的传输。

1.2 电子邮件系统开发平台相关分析 Linux由于自身的特性[2],能够为我们提供最佳应用和开发环境,也给硬件平台的选择提供了很大的自由空间。基于Limix的这些优越性,我们选用Linux操作系统作为软件平台来开发Webmail系统。Linux中的电子邮件系统包括两个组件:MUA(Mail User Agent 邮件用户代理)和MTA(Mail Transport Agent 邮件传送代理)。MUA是邮件系统为用户提供的可以读写邮件的界面;而MTA运行在底层,能够处理邮件的收发工作。即用户可以通过MUA写信、读信,而通过MTA收信、发信。在Linux环境下有许多不同类型的MTA程序,当前比较流行MTA系统有Sendmail、qmail、Smail。这里采用qmail作为基本服务器软件,使用maildir作为邮件存储格式。由于vPopmail提供了大量的命令,方便建立和管理独立于系统用户的邮件用户以及对软、硬磁盘空间限额的管理。因此在qmail的基础上,我们选用vpoomail来增强系统的虚拟域功能。数据库的开发我们选用Mini SQL,它是种小型的关系数据库,性能不是太好,对SQL语言的支持也不够完全,但由于它的短小精悍,非常适合嵌入式数据库和网络数据库的应用开发。

2 qmail邮件软件机制

2.1 qmail软件结构 qmail系统是由一系列子程序组成的,这些子程序可分为两类:可执行程序和使用工具程序。qmail系统在运行时,有五个可执行程序在后台运行。这五个程序分别为:qmail-send、qmail-ISpawn、qmail rSPawn、qmail clean、splogger。qmail-send程序尝试投送qmail队列里的邮件消息;qmail-lspawn程序一般被qmail-Send程序调用向qmaill-local程序转发消息;qmail-rspawn程序被qmail-send程序调用向qmail-remote转发消息;qmail-clean程序将永远无法投递的消息从qmail队列中移出;splogger程序将消息插入系统登录程序中。这五个程序相互协调工作,共同控制qmail系统的邮件收发工作。

2.2 qmail收发邮件机制 从电子邮件的来源来看可分为两类:来自远端用户的邮件和本地用户的邮件。在qmail系统中,qmail-smtpd程序负责接收来自远端用户的邮件消息,并将它们传递给qmail-queue程序处理。远端用户的邮件消息是采用SMTP协议进行传输的,qmail-smtpd必须时刻准备接收来自网上的消息。qmail系统采用了一个网络辅助程序Inetd来监控IP连接,当一个SMTP连接尝试被检测时,Inetd自动地启动qmail-smtpd程序并将该IP连接的控制权交给该程序去处理。qmail-inject程序用来接收本地产生的邮件消息。邮件消息被接收后传递给qmail-queue程序,qmail-queue程序将邮件放入邮件队列中。一旦消息被成功的放入到邮件队列中,就调用qmail-send程序来处理它。qmail-send检查邮件队列中每个消息的状态,通过对前一次邮件请求失败的消息的识别,判断它们是处于临时的投送失败状态还是永久的投送失败状态。临时投送失败状态下的邮件消息将会被再次投送,永久投送失败状态下的邮件消息将被传递给qmail-dean程序,qmail-clean程序将这些邮件清除。

相对于邮件服务器来说,qmail-send将接收方被指定为本地的邮件都传递给qmail-lspawn程序,被指定为远程邮件服务器的邮件消息都传递给qmail-rsPawn程序。qmail-rspawn程序为每个邮件消息决定下一个目的邮件服务器,然后激活qmail-remote程序将邮件进行一次转发。qmail-rspawn把本地邮件接收后调用qmail-local程序检测邮件消息的头字段,根据头字段中的delivered-to的信息,qmail-loeal将邮件分发到相应的邮箱中。

2.3 qmail邮件管理机制 qmail有三种方法能够用来管理那些发给本地邮件服务器上用户的邮件消息:现有本地邮件方法、Mailbox方法和Maildir方法。本地邮件存储方法使用一个公共的目录,该目录中有许多独众的用户文件,每一个都用来存储发送给该本地用户的邮件消息。Mailbox方法将所有的邮件消息都存放到一个普通的邮件目录中,这个常见的邮件目录通常位于以下两个位置之一:/var/spool/mail或者/var/mail。第三种邮件管理方法是Maildir方法,这种方法不仅每个用户的邮箱被放置到他的目录中,连标准的UNIX邮箱格式也被改变了,用户消息被作为独立的文件以特定的格式存储在用户邮箱目录中。这样确保了即使一个消息损坏了,该邮箱目录内剩余的其他邮件消息仍然安全可靠。

3 结论

随着电子邮件的普及,人们逐渐将电子邮件应用到一些正式场合,其安全问题也得到了越来越多的使用者和安全开发人员的重视。本文在说明邮件系统收发及传输原理基础上,对于基本邮件软件qmail的收发机制进行详细的阐述,为实现基于Web的邮件服务系统奠定基础。

参考文献:

[1]张良胜,蒋建中,陈金阳等.Web邮件客户端程序的设计与实现[J].计算机应用与软件.2006年10期.

Linux系统管理 篇7

大学四年的学习时间相对于需要学习的知识和应该培养的能力是很短暂的, 在这个竞争非常激烈的社会里, 大学生更应该自觉地自我教育、科学规划、自我管理, 合理地安排和利用好这一段宝贵的求学时间, 并对此加以记载, 作为人生的宝贵财富而记录下来。客观来讲, 当今社会科学高速发展的“信息爆炸”时代, 要全面记录大学生活的信息, 只有依赖某类管理软件系统才能实现。

为此, 本团队运用PDFLIB、QWebKit、QT国际化等技术, 在LINUX平台下开发设计了“大学生成长系统”, 旨在通过人性化的管理功能, 督促在校大学生全面真实地记录和管理好自己的各种信息, 做好人生规划, 不断充实自己, 完善自己, 使大学生活变得更加绚丽多彩。

1 系统设计

1.1 系统开发环境及特点

系统采用的服务器操作系统是Qt4的LINUX平台系统, 开发平台为Qt4、QtCreator、QtDesigner和QDevelop, PDFLIB作为第三方静态链接库。设计时充分考虑到系统运行稳定性, 赋予该系统强大的报错处理功能。系统从纵向搭建整体架构, 然后再从横向添加其他的基本功能。通过第一次迭代开发系统最基本的功能模块, 用三层架构形式, 即界面层、中间业务层、底层数据库;运用PDFLIB、QWebKit、QT和QT国际化等技术, 利用第一次迭代开发的基本功能模块, 通过第二次迭代开发系统更为高级的功能模块。

1.2 系统总体结构设计

该软件采用现代流行的三层开发模式, 各层分工明确, 加快了开发周期。根据软件开发原则和方法, 增强各层次间的独立性, 在业务层加入网络方面应用及智能功能, 提高软件质量, 赋予其很强的拓展性。图1为“大学生成长系统”体系结构。

其中, 主窗口与子窗口封装成界面开发包, 底层数据库封装成对数据库进行操作的数据库包。

1.3 系统功能模块设计

1.3.1 基本功能模块设计

基本功能模块按照一条主线“界面设计--应用层设计--数据库层设计”, 即纵向延伸, 与“快速原型法”相似。各种功能以统一模式和模板开发, 然后进行分析设计。图2为基本功能模块设计图。

基本信息管理模块主要实现个人基本信息管理的功能。学习成绩管理模块主要用于成绩的记录计算, 并以图表的形式对成绩进行分析统计。人际关系管理模块包括两方面, 一方面是与老师的关系网, 可以详细记录每个老师的联系方式及老师对自己的评价。另一方面同学的关系网, 其内容也是联系方式和同学的评价。荣誉管理、实习管理和任职关系管理等模块是二次迭代开发高级功能所需基础数据的记录与统计。

软件界面层设计运用QT图形开发, 界面美观。数据库层涵盖具有对数据表的操作功能, 如基本信息管理、荣誉管理、实习管理、职位管理、活动管理和人际关系管理等模块可以进行添加、删除、查询、修改能操作, 学习成绩管理模块除此以外还可以进行计算、运用QT以图形化显示等操作。如图3所示学习成绩模块及统计的界面及运行示例。

1.3.2 高级功能模块设计

高级功能模块主要包括“信息库生成模块”、“简历库生成模块”、“日记管理生成模块”和“浏览器功能模块”。其中前2个功能都加载静态链接库, 运用静态链接库完成开发设计。

(1) 信息库和简历库生成模块设计

信息库和简历库生成模块将在校期间和各类信息类似于小说的文本, 让使用者在查阅自己的信息有读小说的感觉, 并可以根据自己的兴趣爱好, 选择某一类简历模板, 自动生成个人的简历。在当今竞争激烈的社里, 可以省去自己制作简历的麻烦。

图4为信息库和简历库生成模块设计示意图。同样, 数据库层涵盖了对数据表的操作, 包括删除、更新、添加和查询等。图5为简历生成模块的实例。

(2) 日记管理生成模块设计

日记管理界面拥有复制、粘贴、剪切、删除等功能, 并提供快捷操作。用户进入日记本界面可以添加新日记、打开已有日记、或保存正在编辑的日记。如果用户忘记保存, 则退出时closeEvent接受消息, 提示用户是否保存。其界面方便眩目, 如图6所示。

(3) 简易浏览器功能模块设计

浏览器功能的实现, 主要是便于使用者在当前操作情况下, 在需要时直接进行上网浏览操作功能, 这充分扩展了本系统的功能。其实现的结构流程如图7所示。本系统的浏览器应用如图8所示。

2 功能拓展

系统的功能可以进行扩展, 体现了软件具有较强的适应性。根据本系统的规划, 还可以做以下几个方面的扩展。

2.1 基本功能拓展

在项目设计阶段, 为系统主要功能搭建了一个易于拓展的构架, 具有低耦合、高聚合的特点, 很容易实现功能拓展。例如, 要实现“目标管理”的新功能, 并且使目标以直方图形式显示, 只需要进行后台数据库及中间业务层操作, 同时调用HittogramView这个类即可实现。另外, 还可实现流媒体播放器、相片管理等桌面应用功能。另外可对数据库文件———project.ab进行加密。

2.2 基于网络方面的拓展

本设计采用QWebKit包开发简易浏览器, 可实现基于网络方面的拓展功能。如通过网络获取用户获奖和发表论文信息;远程数据备份功能;网络浏览器功能以及网络不良信息的过滤功能。从而使该系统广泛用于个大专院校和公司管理学生和员工信息。

2.3 基于手机方面的拓展

通过选择Linux手机操作系统, 使本软件拓展为基于手机的开源应用程序, 实现在手机终端管理自己的信息管理平台, 进行各类操作。同时, Qt是基于C++开发平台, 该程序也可拓展为Symbian手机平台下的应用程序。

3 系统实现

3.1 底层数据库

数据库采用SQLite。SQLite虽然是轻型数据库, 但支持跨平台运行且操作简单, 使得本系统的数据库操作简单易行。数据库层中, 设计了数据库表, 实现了一些诸如SQLActivity.h的类。这些类封装了针对不同的数据库表的操作函数, 例如在SQLActivity.h中, 由于需要对活动信息进行添加、删除、更新以及查找, 我们实现了与其对应的函数:

3.2 中间业务层

中间业务层中, 对数据库层进行进一步的封装。例如Activity.h中有以下几个函数:

前台通过调用中间业务层的函数来实现对后台数据库的操作。此外, User.h类通过对static的灵活使用, 实现了保存对当前登录用户的用户名信息。这意味着当前登录用户信息已经成为全局变量, 在其他类中, 只需调用User.h类的相应函数。

3.3 前台页面

3.3.1 前台主页面

前台主页面方面, 主要通过对QStackedWidget和QListWidget的使用来实现, 在页面切换的同时加入了渐变的效果。

首先对指针进行初始化:pagesWidget=new QStackedWidge (this) ;然后将页面加入到pagesWidget中, 例如pagesWidget->addWidget (new Welcome (this) ) ;再次设置connect函数, 当pagesWidget切换页面的时候, fadeInWiget () 将会接收到一个信号, 代码如下:connect (pagesWidget, SIGNAL (current Changed (int) ) , this, SLOT (fadeInWidget (int) ) ) ;最后设置QListWidget, 将QListWidgetItem按照与pagesWidget对应的顺序加入到QListWidget。

下面描述一下有关fadeInWidget (int) 这个槽函数。在此函数中包含如下代码:faderWidget=new FaderWidget (pagesWidget->widget (index) ) ;fader Widget->start () 。由此可见渐变效果的实现是在FaderWidget这个类中。FaderWidget设置了一个定时器以及初始背景颜色, currentAlpha=255;timer->start (100) 。每次定时器开始时, 都会对widget进行重绘, 即paintEvent函数会被调用。根据背景的颜色变化来实现渐变的效果。

3.3.2 前台界面

前台界面应用了Qt的重要特征-QT国际化。国际化处理使用户界面相关的字符串在不同语言环境下使用不同的语言。应用程序使用英文作为缺省界面语言, 在编码时对需要进行国际化处理的字符串做标记, 即使用tr () 函数, 然后通过Q linguist将这些字符串提取出来, 做出中文语言资料包, 程序编译运行后根据不同的语言环境寻找不同语言的资料包, 在运行时刻通过国际化运行库将原来的字符串替换为资料包中的字符串, 从而实现一个二进制运行文件在不同语言环境下使用不同语言字符串的国际化方法。

3.3.3 浏览器

通过调用QWebkit下面的API, 实现浏览器功能。首先, WebKit是一个开源的浏览器引擎, 与之相应的引擎有Gecko (Mozilla Firefox等使用的排版引擎) 和Trident (也称为MSHTM L, IE使用的排版引擎) 。同时WebKit也是苹果Mac OS X系统引擎框架版本的名称, 主要用于Safari, Dashboard, Mail和其他一些Mac OS X程序。WebKit所包含的WebCore排版引擎和JSCore引擎来自于KDE的KHTML和KJS, 当年苹果比较了Gecko和KHTML后, 仍然选择了后者, 就因为它拥有清晰的源码结构、极快的渲染速度。

3.3.4 简历生成和信息库

简历生成和信息库通过使用PDFLIB技术实现。PDFLib是用于创建PDF文档的开发库, 提供了简单易用的API, 隐藏了创建PDF的复杂细节且不需要第三方软件的支持。

本系统中, 简历和信息库生成模块通过获取用户已输入的基本信息, 如成绩、荣誉信息等等, 自动以pdf的形式生成简历或者信息库。在生成pdf文件时需要调用PDFLib库的函数。

参考文献

[1]张坤.当代大学生的现状分析[J].科教文汇 (中旬刊) , 2009 (4) .

[2]陈周国, 王胜银, 付国晴, 等.基于Linux QT技术的远程监控GUI设计[J].通信技术, 2009 (12) .

[3]红旗教育学院.Linux系统应用与编程设计[G].北京中科红旗软件技术有限公司, 2005-2009.

Linux系统管理 篇8

通过本课程的学习, 学生能够完成Linux系统的安装、维护, 熟练使用文件、目录管理命令, 熟练掌握组和用户的管理维护, 能够安装、升级、卸载应用软件, 熟悉在Linux下的文本编辑技巧, 能对系统的资源进行定制和配置, 掌握Linux的网络参数配置, 实现办公网络内的文件资源共享。并了解Linux平台的桌面操作。

二、教学内容

本课程在教学中将教学内容分为五个模块, 每个模块又分别设计了相应的任务。教学模块划分及任务设计见图1所示:

三、课程考核

课程考核由“学习态度 (5%) + 综合素养 (5%) + 机房作业考核 (40%) + 期末考试 (50%) ”四项组成。学习态度、知识点和专业技能、综合素质表现 (社会能力、方法能力、职业素养) 等。合格标准:旷课不超过6节;平时成绩不低于12分;总分大于或等于60分;没有不诚信行为。

四、教学情境设计

在教学中, 将教学内容设计为8个学习情景。下面分别对8个学习情境进行详细介绍。1. 学习情境1:熟悉图形界面。学习目标:了解图形界面, 简单介绍图形界面的常用组件和操作。该情境学习内容分两个阶段, 阶段一是安装Linux操作系统, 背景描述为:于Linux系统优秀的稳定性, 以及在病毒入侵方面的出色表现, 公司希望在新购买的计算机中安装Linux操作系统。阶段二是登录并熟悉Linux, 背景描述为:公司的计算机安装了Linux系统, 你在安装了Linux系统的平台上熟悉Linux系统的界面, 了解系统登录和退出的过程。2. 学习情境2:使用图形界面管理用户和组。学习目标:通过图形方式管理用户和组, 进行用户和组的设置。该情境学习内容分为两个阶段, 第一阶段为文件、目录操作, 背景描述为:一个刚接触Linux的用户, 刚刚掌握了Linux的安装, 对Linux的了解不多, 这时他希望能够掌握在Linux的字符模式下要查看系统的文件和目录的属性, 以及通过命令来管理这些资源。作为网络管理员你帮他规划了一组实验命令来系统了解、掌握文件和目录的操作。阶段二是用户和组的管理, 背景描述为公司的一台Linux计算机有多个员工共同使用, 其中zhangdong为普通用户, 只要有自己主目录全部权限和support的读操作权限即可。Lizg是新来的部门主管, 需要有support和manager的读写权限。当lizg调离时删除该用户。3. 学习情境3:在图形界面下编辑文本。学习目标:通过在图形下的鼠标点击来打开或编辑文本, 体验Linux图形界面下应用。该情境学习内容为熟悉VI命令编辑器, 掌握三种模式, 背景描述为从windows下的字处理程序的使用习惯到Linux下的全屏幕编辑器是一个变化较大的过程, 熟悉VI三种模式, 在不同的模式下完成不同的操作、提高编辑技巧是本阶段的主要目标。4. 学习情境4:基本脚本编程。学习目标:通过案例来介绍脚本的编程。该情境学习内容为Shell的基本使用, 背景描述为通过使用管道和重定向提高命令的执行效率。用管道的方式查找用户中保的全部用户的详细信息。5. 学习情境5:使用图形界面下系统工具完成RPM包安装。学习目标:可以对照windows下的添加删除程序, 运用图形方式添加和删除程序。该情境的学习内容为安装与管理Linux应用程序, 背景描述为在管理和维护Linux系统的过程中, 经常要涉及到应用程序的安装和删除等问题。6. 学习情境6:管理Linux系统。学习目标:管理Linux系统。学习内容为系统定制管理。背景描述为在Linux系统上定制系统的运行级别, 然后根据需求来确定应用程序的运行时间, 在Linux的系统管理和定制上有很重要的作用。7. 学习情境7:使用图形界面设置网络参数。学习目标:使用系统工具的网络设备控制完成对网络参数的配置。学习内容:配置并激活网卡。背景描述:有一台新安装Linux系统的计算机需要接入到局域网中, 网络的参数如下, IP:192.168.2.10, NETMASK:255.255.255.0, GETWAY:192.168.2.1 DNS:192.168.2.5 。8. 学习情境8:Linux下NFS文件共享访问。学习目标:实现Linux下NFS文件共享访问。学习内容:使用NFS实现文件共享。背景描述:在一台安装了Linux操作系统的计算机上, 管理员准备放置Linux的系统安装文件, 以支持Linux系统的NFS网络安装。为此现在需要新建一个目录 /pubnfs。目录的用户和组都是user1。通过使用NFS服务把 /pubnfs文件夹共享出去。

结束语

Linux操作系统是一门实践性很强的操作系统课程, 具有操作命令多, 命令参数复杂的特点, 在以往教学中, 教师大多数以纯理论的教学方式教学, 学生很难理解和记忆命令的语义和用法, 因此教学难度大。通过对课程的教学方法、教学内容的设计, 使用理实一体化的教学方式, 引入情境教学, 使学生在操作中记忆命令, 大大提高了学生学习积极性。

参考文献

[1]赵立权, 翟勇.高校Linux教学势在必行[J].云南师范大学学报, 2001 (9) :21-23.

[2]祝世海:《Linux操作系统》课程的教学探索与实践[J].林区教学, 2007 (5) .

Linux系统管理 篇9

目前数据安全对企业以及个人用户越来越重要, 因此容灾和远程备份技术正成为目前研究的热点。当前linux下较成熟的文件同步软件rsync等提供了文件同步功能, 但他们的问题也很明显:首先, 不能实时监控文件系统来判断文件的更新变化, 而只能通过守护进程或者手动的方式进行指定文件的同步;其次, 未能考虑到企业中的一些特别的需求, 对主机两端实时数据文件的同步没有实现;再次, 传统的软件都是利用定点备份的方法, 设置一个时间段, 每隔一个时间段备份一次, 数据实时性较低。

本文提出了一种基于文件操作时间的差异备份方法, 利用linux下的inotify机制对文件进行实时监控, 当用户对所监控文件进行修改后, 捕获文件的变化信息, 转化为程序可识别时间, 对文件操作进行记录, 然后利用rsync经典算法计算出差异数据, 通过网路进行传输。

2. inotify机制介绍

inotify的API都使用文件描述符, 这样可以将监控粒度控制到单个文件, 而dnotify机制的控制粒度则为单个目录。使用文件描述符更大的优势在于对inotify的操作也可以使用read () 、close () 、select () 等这些传统的文件操作函数。

2.1 int inotify_init (void)

创建并初始化一个inotify实例, 该函数返回一个文件描述符。可以认为这个函数是打开一个inotify类型的文件并返回该类型文件的描述符。

2.2 int inotify_add_watch (int__fd, const char*__name, uint32_t__mask)

增加监视文件 (监视器) , fd用于指明该文件被添加于哪个inotify实例, name用于指名该文件的路径, mask则指明了该文件所有的监控事件。该函数调用成功后返回一个监视器的描述符。

2.3 int inotify_rm_watch (int__fd, int__wd)

从fd中删除一个监视器, wd指名具体的监视器。

3. Rsync算法介绍

rsync是unix/linux下同步文件的一个高效算法, 它能同步更新两处计算机的文件与目录, 并适当利用查找文件中的不同块以减少数据传输。rsync中一项与其他大部分类似程序或协定中所未见的重要特性是镜像只对有变更的部分进行传送。rsync可拷贝/显示目录属性, 以及拷贝文件, 并可选择性地压缩以及递归拷贝。rsync利用由Andrew Tridgell发明的算法。rsync的算法如下: (假设我们同步源文件名为file Src, 同步目的文件叫file Dst)

(1) 分块Checksum算法。首先, 我们会把file Dst的文件平均切分成若干个小块, 比如每块512个字节 (最后一块会小于这个数) , 然后对每块计算两个checksum, 一个叫rolling checksum, 是弱checksum, 32位的checksum, 其使用的是Mark Adler发明的adler-32算法, 另一个是强checksum, 128位的, 用md5 hash算法, checksum算法定义如下:

a (k, l) = (∑Xi) mod M

b (k, l) = ( (l-i+1) Xi) mod M

s (k, l) =a (k, l) +216b (k, l)

上面公式中, s (k, l) 表示数据块Xk, ..., Xl的滚动校验值, 为了简化计算, M取值为216。这种校验计算公式具有一个非常关键的特性, 就是后续校验值可以通过递推关系高效地计算获得。

a (k+1, l+1) = (a (k, l) -Xk+Xl+1) ) mod M

b (k+1, l+1) = (b (k, l) - (l-k+1) Xk+a (k+1, l+1) ) mod M

s (k+1, l+1) =a (k+1, l+1) +216b (k+1, l+1)

因此, 给定X1, ..., Xn的校验值, X1以及Xn+1, 我们就可以快速地计算出X2, ..., Xn+1校验值。这样, 利用这种性质我们就可以高效地计算数据块连续校验值, 大幅减少checksum计算量。

(2) 传输算法。同步目标端会把file Dst的一个checksum列表传给同步源, 这个列表里包括了三个东西, rolling checksum (32bits) , md5 checksume (128bits) , 文件块编号。

(3) checksum查找算法。同步源端拿到file Dst的checksum数组后, 会把这个数据存到一个hash table中, 用rolling checksum做hash, 以便获得O (1) 时间复杂度的查找性能。这个hash table是16bits的, 所以, hash table的尺寸是2的16次方, 对rolling checksum的hash会被散列到0到2^16–1中的某个整数值。

(4) 比对算法。这是最关键的算法, 细节如下:

a.取file Src的第一个文件块 (我们假设的是512个长度) , 也就是从file Src的第1个字节到第512个字节, 取出来后进行rolling checksum计算。计算好的值再到hash表中进行查找。

b.如果查到了, 说明发现在file Dst中有潜在相同的文件块, 于是就再比较md5的checksum, 因为rolling checksume太弱了, 可能发生碰撞。于是还要算md5的128bits的checksum, 这样一来, 我们就有2^- (32+128) =2^-160的概率发生碰撞, 这个值太小了可以忽略。如果rolling checksum和md5 checksum都相同, 这说明在file Dst中有相同的块, 我们需要记下这一块在file Dst下的文件编号。

c.如果file Src的rolling checksum没有在hash table中找到, 那就不用算md5 checksum了。表示这一块中有不同的信息。总之, 只要rolling checksum或md5 checksum其中有一个在file Dst的checksum hash表中找不到匹配项, 那么就会触发算法对file Src的rolling动作。于是, 算法会住后step 1个字节, 取file Src中字节2-513的文件块要做checksum, go to (a) .

4. 系统框架图

本系统的服务端运行在linux系统下, 随系统启动。主要功能模块包括inotify监控模块, 控制模块, 文件数据处理模块, 网络通信模块, 日志记录模块和异常处理模块。

控制模块:监控管理备份系统的各个模块, 协调各个模块的运行。并统一管理备份系统中的日志信息和异常信息。

静态文件数据备份模块:静态文件数据备份模块主要完成对文件的完全备份。

实时文件数据备份模块:实现文件的差异备份, 采用经典的Rsync算法计算出更新文件的差量数据, 并通过网络传输模块完成对数据的传输。

网络传输模块:主要任务是完成服务器端与客户端的链接, 并且完成对数据的传输。

日志记录模块:以特定的格式记录每个模块中的状态信息, 在备份任务创建和完成以及由于某种原因中断时, 记录下状态信息。

异常处理模块:负责对备份系统异常信息的处理方法。

5. 静态文件备份模块流程图

静态文件备份流程详细描述:

(1) 程序开始接受客户端数据;

(2) 分析接受到的客户端数据对进行备份初始化;

(3) 分析接受到的客户端数据, 取得客户端发送来的需要备份的路径列表记录;

(4) 在路径记录列表中读取到一条记录以后获取路径信息, 并且将路径信息返回给客户端;

(5) 若路径为文件路径, 则按行读取文件的内容, 将其送往发送缓冲区, 之后数据通过网络发往客户端, 遇到EOF后返回;

(6) 判断源列表记录是否还有记录, 若有则返回步骤4, 若无则将结束标志发往客户端, 结束数据传输;

(7) 若路径为目录, 则递归的读取此目录下的所有文件, 将文件数据发往数据缓冲区, 通过网络将数据发往客户端, 若目录中没有未处理文件或者目录, 则返回6。

静态文件的备份主要是在客户端设置备份的周期, 若备份周期为一周, 则在第一次备份完一周以后再执行一次静态文件的备份。

6. 实时文件备份模块

6.1 实时监控模块流程图 (如图3)

6.2 实时文件备份模块中文件数据处理流程图 (如图4)

实时文件备份模块中文件数据处理详细流程:

(1) 等待文件更新变化的发生, 从事件队列中读取事件, 判断事件的类型;

(2) 有新建的文件或者有复制过来的文件, 则对文件内容划分数据块, 放入缓冲区, 并进行数据传输;

(3) 读取更新文件, 按照RSYNC算法计算两种校验码, 并与校验码附加文件中的校验码进行对比后计算出差量数据, 构建好完整的数据包后放入缓冲区, 通过网络传输到客户端。基于RSYNC算法的文件内容更新步骤如下:

a.在服务器端, 当为指定的文件进行监控初始化时, 建立一个校验码附加文件, 将原始文件filesrc平均分成大小为b字节的若干个小块Bi, 针对每个数据块bi, 计算出两个校验码ri和mi, 即滚动校验码和MD5哈希函数, 在实际的对比过程中, 滚动校验码用来区别不同, 而MD5哈希函数是用来确认相同。将这两个校验码和文件相关信息存储为附加校验码文件checksum.txt。

b.在有更新事件发生后, 读取旧文件的checksum.txt文件中的校验列表, 并为该校验列表建立哈希表, 针对校验码序列, 遍历新文件, 按照同样的方式对新文件进行分块, 从第一块开始, 先计算出滚动校验码, 在哈希表中查找, 若有匹配, 且之后计算出的MD5校验码也匹配, 则将索引号组织为更新包放到缓冲区, 然后后移一块, 对比下一块;如果在哈希表中找不到相应的滚动校验码或者找到滚动校验码之后对应的MD5码不匹配, 则表示这一块中有不同的信息, 后移一个字节后分块, 再计算滚动校验码, 重复这样的过程直到比较完整个文件。

c.通过网络传输数据更新包。

d.在客户端, 通过服务器传输过来的更新同步数据包和旧文件来构建新文件。

7. 系统实现

本系统服务器端采用Cent OS6.2系统, 功能实现主要采用c语言和shell脚本来完成, 分别实现了静态文件备份和实时文件备份。为了简化用户操作步骤, 缩短用户熟练使用软件的周期, 客户端采用MS windows server2003系统, 用c语言集合面向对象语言c++完成了人机交互界面和相应代码程序。客户端和服务器采用soket方式连接。

8. 结语

本文介绍了一种新的linux下远程文件同步模型——基于Rsunc算法的远程文件同步系统。该远程文件同步系统提高了系统运行效率和提供较高的可扩展性, 弥补了当前linux下远程同步软件所存在的特殊要求不可达、带宽占用多等问题。

参考文献

[1]彭勇, 刘晓洁, 邓洪敏.《基于差异的远程文件备份与恢复方法》[J].四川大学学报, 2009.

[2]李波, 朱坤.《基于局域网的数据库文件备份》[J].农业网络信息, 2007, (10) .

[3]李夷苒, 李涛, 胡晓勤, 马晓旭.《基于事件的文件备份方法研究与实现》[J].计算机工程与设计, 2010, (21) .

浅谈linux系统的机制 篇10

首先让我们了解一下, 什么是存储程序计算机, 并对存储程序计算机的整个运行过程及所需的硬件组件进行简单介绍。

图1是程序存储计算机的物理框架, 主要包含CPU (包含各类寄存器, 如程序寄存器, 指令寄存器等) , 主存, I/O设备, 一个最简单的的程序存储计算机只需要以下部件来完成计算机工作:主存, 也就是我们普通PC上内存, 用于存储指令和数据处理器, 用于执行算术和逻辑操作控制单元, 解析需要操作的指令集。程序存储在计算机主存当中, 并以数据的形式被CPU访问和读写, 程序中各条指令都被获取并放到一个EIP寄存器, EIP寄存器中数据控制整个处理单元的运行, 取“下一条”指令, 继续运行。

在Linux系统中, 一般同时会有几个程序一起运行, 运行过程中这些程序的都存储在主存中, 而CPU只会在同一时间内运行其中优先级较高的某一个, 并根据优先级顺序不断的切换多个进程运行, 使得计算机操作者会有多个程序同时运行的错觉。在存储程序计算机中, 最重要的部分就是多个进程的切换, 是什么控制着进程间的切换, 如何保证进程切换过程中能够使得多个进程运行时不发生混乱, 这一切都是由Linux内核控制的, 下面我们深入解Linux内核的在进程切换时的工作机制。先看调度的方式。由于调度时机发生时进程在进入了内核态这样, 内核必须等待该进程即将结束内核态时才进行切换操作, 而进程如果正在用户态时则切换工作会立即执行, 所以, 一般进程调度发生在当前进程从内核态 (包括从系统调用而进入内核态) 返回用户态的前夕。至于调度的政策, 均按照前面所提到的以优先级为基础的调度。针对不同的进程有不同的调度政策, 主要有SCHED_FIFO, SCHED_RR, SCHED_OTHER (源码集中在kernelsched目录下) , 其中FIFO适用于时间性要求比较高的进程, 而RR针对时间片耗尽的进程, 由于没有研究过源码这里不做详细描述。当切换进程已经选好后, 就开始用户虚拟空间的处理, 然后就是进程的切换switch_to () 。所谓进程的切换主要就是堆栈的切换, 这是由宏操作switch_to () 完成的。

2 分析linux机制的核心

在核心这里的输出部分有三个参数, 表示这段程序执行后有三项数据会有改变。其中[prev_sp]、[prev_ip]都在内存中分别为prev->thread.sp、prev->thread.ip, 而最后一个参数则与寄存器EAX结合, 对应于参数中的last。而输入部则有4个参数, 其中[next_sp]、[next_ip]在内存中, 分别为next->thread.sp与next->thread.ip, 剩余的两个参数则与寄存器EAX, EDX结合, 分别对应prev, next。

先看开头有两条push指令和结尾处有两条pop指令, 再看14行将当前的esp, 也就是当前进程的prev的内核态的堆栈指针存入prev->thread.sp, 第15行又将新收到调度要进入运行的进程next的内核态的堆栈之争next->thread.sp置入esp。这样一来, CPU在第15行与第16行这两条指令之间就已经切换了堆栈。假定我们有A, B两个进程, 在本次切换中prev指向A, 而next指向B。也就是说, 在本次切换中A为要“调离”的进程, 而B为要“切入”的进程。那么, 在这里的第12到15行是在使用A的堆栈, 而从第16行开始就是在用B的堆栈了。换言之, 从第16行开始, “当前进程”, 已经是B而不是A了。在内核代码中当需要访问当前进程的task_struct结构时使用的指针current时实际上是宏定义, 它根据当前的堆栈指针的ESP计算出所需的地址。如果第16行处引用current的话, 那就是已经指向B的task_struct结构了。所以进程切换其实在第15行指令执行完就已经完成了。但是, 构成一个进程的另一个要素是程序的执行, 所以还要进行其他步骤。由于12, 13行事push进A的堆栈, 而在21行至22行从B的堆栈中POP出来, 本质就是恢复新切入的进程在上一次被调离时的push进堆栈的内容。理论上讲, 进程的切换过程中, 多个进程都已经在执行了只是暂时的撤离cpu, 所以切换过程就是在堆栈之间进程切换。

那么如何完成程序执行的切换, 看一下之后的16行至20行。第16行的[prev_ip]所在位置, 实际上就是将第21行的pop指令所在的地址保持在prev->thread.ip中, 作为进程A下一次被调度运行而切入时的“返回”地址。然后, 又将next->thread.ip压入堆栈。所以, 这里的next->thread.ip正是进程B上一次被调离时在第16行中保存的。它也指向这里的[prev_ip], 即21行的pop指令。接着, 在19行通过jmp命令, 而不是call命令, 转入了一个函数__switch_to () 。暂时不讨论__switch_to () , 当CPU执行到哪里的iret指令时, 由于是通过jmp指令转过去的, 最后进入对战的next->thread.ip就变成了返回地址, 而这就是[prev_ip]所在的地址, 也就是21行的pop指令所在的地址。由于每个进程在被调离时都要执行这里的第16行, 这就决定了每个进程在收到调度恢复运行时都是从这里的第21行开始。上面都是已有进程的切换。但新创建的进程会是怎么样切换的。新创建的进程并没有在“上一次调离时”执行过这里的第12至16行, 所以要将其task_struct结构中的thread.ip事先设置好, 并且设置“返回地址”时不一定是[prev_ip]所在的地址, 这里取决于内核态堆栈的设置。

那么, 这个地址在copy_thread () 中确定, 由于未能完整的阅读整个process_32.c中的源码, 以下内容只是推测如有错误请博友指正, 在新进程被创建时, 在父进程执行完fork之后只会返回会从调用系统调用时状态, 而子进程的“返回地址”也被设置成这个地址, 所以__switch_to () 一执行ret指令就直接回到了那里。

最后, 在__switch_to () 中到底干了些什么呢?看一下Linux3.9.7中/arch/x86/kernel/process_32.c。这里主要处理的是TSS, 核心在16行, 把next_p->thread.esp0装入对应于本地cpu的tss的esp0字段;任何由sysenter汇编指令产生的从用户态到内核态的特权级转换将把这个地址拷贝到esp寄存器中。其次段寄存器gs中的内容也做了相应的切换。然后把next进程使用的县城局部存储 (TLS) 段装入本地CPU的全局描述符表;三个段选择符保存在进程描述符内的tls_array数组中。所以, 除了刚创建新进程外, 所有进程在受到调度时的切入点都在宏定义switch_to () 中的标号[prev_ip], 一直运行到在下一次进入switch_to () 以后在__switch_to () 中执行ret为止。或者也可以认为, 切入点中全面的分析了函数在堆栈调用过程中堆栈中变量及寄存器的数值的变化。

理解函数调用栈最重要的两点是:栈的结构, ebp, esp, eip寄存器的作用。从这个基础上发现堆栈在操作系统的工作中的作用:通过堆栈来保存任务切换过程中的上下文, 进而在顺序执行的基础上支持了多任务操作。

函数调用堆栈过程可分解为:参数入栈时的push操作, 一般会有多个。另一方面在调用过程中肯定会使用call指令, call指令内部其实还暗含了一个将返回地址 (即call指令下一条指令的地址) 压栈的动作。Linux中gcc都会在每个函数体之前插入类似如下指令:即, 在程序执行到一个函数的真正函数体时, 已经有以下数据顺序入栈:参数, 返回地址, EBP。由此得到类似如下的栈结构 (参数入栈顺序跟调用方式有关) 如图2。

“pushl%ebp”“movl%esp, %ebp”先将EBP入栈, 然后将栈顶指针ESP赋值给EBP。此时EBP寄存器中存储着栈中的一个地址 (原EBP入栈后的栈顶) , 从该地址为基准, 向上 (栈底方向) 能获取返回地址、参数值, 向下 (栈顶方向) 能获取函数局部变量值, 而该地址处又存储着上一层函数调用时的EBP值。

一般而言, ss:[ebp+4]处为返回地址, ss:[ebp+8]处为第一个参数值 (最后一个入栈的参数值, 此处假设其占用4字节内存) , ss:[ebp-4]处为第一个局部变量, ss:[ebp]处为上一层EBP值。

由于ebp中的地址处总是“上一层函数调用时的ebp值”, 而在每一层函数调用中, 都能通过当时的EBP值“向上 (栈底方向) 能获取返回地址、参数值, 向下 (栈顶方向) 能获取函数局部变量值”。如此形成递归, 直至到达栈底。这就是函数调用栈。

中断机制:中断是CPU提供的一种功能, 不属于linux内核, 而对应的中断处理程序则属于内核控制, 在执行新指令前, 控制单元会检查在执行前一条指令的过程中是否有中断发生, 如果有控制大院就会抛下指令, 进入下面流程: (1) 确定与中断关联的向量i (0<=i<=255) ; (2) 寻找向量对于的处理程序; (3) 保存当前的“工作现场”, 执行中断处理程序; (4) 处理程序执行完毕后, 把控制权交还给控制单元; (5) 控制单元恢复现场, 返回继续执行原程序。

所以整个中断的处理过程中, 对于CPU, 处理过程是一样的, 中断现行程序, 转到中断服务程序处执行, 回到被中断的程序继续执行。CPU总共可以处理256种中断。

那什么是中断处理程序, 在介绍中断处理程序之前, 让我们先了解一下什么是软中断、tasklet和工作队列:

软中断:软中断是利用硬件中断的概念, 用软件方式进行模拟, 实现宏观上的异步执行效果。很多情况下, 软中断和“信号”有些类似, 同时, 软中断又是和硬中断相对应的, “硬中断是外部设备对CPU的中断”, “软中断通常是硬中断服务程序对内核的中断”, “信号则是由内核 (或其他进程) 对某个进程的中断” (《Linux内核源代码情景分析》第三章) 。

sklet:tasklet是由软中断引出的, 内核定义了两个软中断掩码HI_SOFTIRQ和TASKLET_SOFTIRQ (两者优先级不同) , 这两个掩码对应的软中断处理函数作为入口, 进入tasklet处理过程。

队列:定义一个work结构 (包含了处理函数) , 然后在中断处理过程中调用schedule_work函数, work便被添加到workqueue中, 等待处理。工作队列有着自己的处理线程, 这些work被推迟到这些线程中去处理。内核默认启动了一个工作队列, 对应一组工作线程events/n (n代表处理器编号, 这样的线程有n个) 。驱动程序可以直接向这个工作队列添加任务。某些驱动程序还可能会创建并使用属于自己的工作队列。

那么, 让我们看看目前最主要引起中断的原因:IO中断, 时钟中断, 系统调用。所谓的中断处理程序就是在响应一个特定中断的时候, 内核会执行一个函数, 该函数就是中断处理程序。图3为中断处理程序的处理流程。

从图3可以看出, 每个中断处理都要经历保存、处理与恢复过程, 我们可以总结出以下步骤: (1) 保存现场。 (2) 执行具体的中断处理程序。 (3) 从中断处理返回。 (4) 恢复现场。

那么为什么会有软中断, tasklet, 和工作队列呢?由于中断处理程序一般都是在中断请求关闭的条件下执行的, 以避免嵌套而使中断控制复杂化。但是, 中断是一个随机事件, 它随时会到来, 如果关中断的时间太长, CPU就不能及时响应其他的中断请求, 从而造成中断的丢失。因此, Linux内核的目标就是尽可能快的处理完中断请求, 尽其所能把更多的处理向后推迟。因此, 内核把中断处理分为两部分:上半部 (tophalf) 和下半部 (bottomhalf) , 上半部 (就是中断处理程序) 内核立即执行, 而下半部 (就是一些内核函数) 留着稍后处理。对应于上下半部的处理, 才有了以上这些概念。

那么, 什么情况下使用工作队列, 什么情况下使用tasklet。如果推后执行的任务需要睡眠, 那么就选择工作队列。如果推后执行的任务不需要睡眠, 那么就选择tasklet。另外, 如果需要用一个可以重新调度的实体来执行你的下半部处理, 也应该使用工作队列。它是唯一能在进程上下文运行的下半部实现的机制, 也只有它才可以睡眠。这意味着在需要获得大量的内存时、在需要获取信号量时, 在需要执行阻塞式的I/O操作时, 它都会非常有用。如果不需要用一个内核线程来推后执行工作, 那么就考虑使用tasklet。

3 小结

Linux以它的高效性和灵活性著称, Linux模块化的设计结构, 使得它既能在价格昂贵的工作站上运行, 也能够在廉价的pc机上实现全部的Unix特性, 具有多任务、多用户的能力。Linux是在GNU公共许可权限下免费获得的, 是一个符合POSIX标准的操作系统。Linux操作系统软件包不仅包括完整的Linux操作系统, 而且还包括了文本编辑器、高级语言编译器等应用软件。它还包括带有多个窗口管理器的X-Windows图形用户界面, 如同我们使用Windows NT一样, 允许我们使用窗口、图标和菜单对系统进行操作。

摘要:随着时下的发展, 操作系统也是一种人机交互的实质。根据Linux系统工作基础的分析, 对存储程序计算机、堆栈 (函数调用堆栈) 机制和中断机制进行概述。文中将为您提供操作系统 (内核) 如何工作的细节, 进一步从宏观概述结合关键点进行微观分析。Linux是一种自由和开放源码的类Unix os, 存在着许多不同的Linux版本, 但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中, 比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。Linux是一个领先的操作系统, 世界上运算最快的10台超级计算机运行的都是Linux操作系统。严格来讲, Linux这个词本身只表示Linux内核, 但实际上人们已经习惯了用Linux来形容整个基于Linux内核, 并且使用GNU工程各种工具和数据库的操作系统。

关键词:linux,unix,系统

参考文献

[1]董荣胜《.九校联盟 (C9) 计算机基础教学发展战略联合声明》呼唤教育的转型[J].中国大学教学, 2010 (10) .

[2]九校联盟 (C9) 计算机基础教学发展战略联合声明[J].中国大学教学, 2010 (09) .

Linux系统管理 篇11

一、中小学校园网的基本结构

中小学的校园网主要由以下几部分构成:一是与互联网相接的设备,包括以ADSL方式入网、以光纤方式入网等;二是校园网的安全保护设备,如防火墙、UTM等设备;三是交换机等设备;四是校园网接入终端,包括服务器、台式机以及移动笔记本等设备。

二、为什么选择Linux系统

随着网络的日益普及,采用Linux网络操作系统作为服务器的用户也越来越多。这一方面是因为Linux是开放源代码的免费正版软件;另一方面也是因为较之微软的WindowsNT网络操作系统而言,Linux系统具有更好的稳定性、效率性和安全性。

三张Linux光盘一共12元,而使用Windows2K正版系统一千多,Office一千多;在专业领域,三剑客、Photoshop、3DMark等都要上千上万,而Linux所带的软件全部免费。

Linux具有以下几个特点。一是对硬件配置要求较低,中小学校利用一台性能较高的计算机就能承载所有功能;二是占用内存少、性能稳定;Linux可运行在文本模式下,其内核可订制;三是其补丁和漏洞的升级频率低,感染病毒的可能性小,维护方便。

三、搭建Linux环境下校园网网络安全系统

校园网网络安全系统技术方案的关键在于防火墙。可利用价格低廉、性能良好的计算机,构建一台“防火墙”,保障学校的网络信息安全。

1.我校使用是内核为2.6.18版本的Linux

在安装过程中应注意以下几点:

(1)选择中文和图形方式进行安装,选择英文和文本方式用于设备的日常运行。

(2)正确配置内外两块网卡的IP地址及网关等信息。

(3)出现“防火墙配置”页面时,安全级别选择“无防火墙”。

2.配置NAT(网络地址转换)

在Linux操作系统中,利用Iptables命令可灵活方便地设置NAT,其步骤如下:

(1)设置允许IP包转发,将/etc/sysctl.conf中net.ipv4.ip_

forward=0的0改成1。

(2)完成地址转换,iptables-tnat-APOSTROUTING-oeth0-j MASQUERADE,“eth0”指的是连接外部网络的网卡名称;同时可参考Iptables命令的使用方法,对进出的IP流量进行各种有效过滤和限制。

(3)保存Iptables的配置信息,执行:iptables-save>/etc/sysconfig/iptables通过该命令可将上述配置信息保存到相应文件,保证开机后自动启动该项功能。

3.实现IP地址和网卡MAC地址的绑定

校园网时常会发生IP地址冲突、感染ARP病毒等情况,导致用户无法正常上网。采用IP地址和网卡MAC地址绑定,可一定程度上杜绝这些现象的发生。在Linux操作系统中实现方法如下:

(1)在/etc/ip-mac文件添加IP地址和对应网卡MAC地址。建立IP地址和MAC地址的对应表文件:/etc/ip-mac,将要绑定的IP和MAC写入此文件,如echo’192.168.1.100:02:B3:38:08:62’>/etc/ip-mac。

(2)设置成开机自动加载ip-mac文件。echo’arp-f/etc/ ip-mac’>>/etc/rc.d/rc.local。

4.完全开放FTP服务的搭建

FTP服务器软件使用的是开源免费的Vsftpd。Vsftpd被认为是Linux下最安全、最快速的FTP服务器软件。在Linux环境下,在控制台执行一行命令就可完成安装,即:#apt-get install vsftpd。此时,用netstat命令能看到21端口在监听。

安装完Vsftpd后,需要完成一些配置来满足具体需求。编辑Linux系统下的/etc/vsftpd.conf文件,主要配置如下参数:

listen=YES#使vsftpd运行在standalone模式

listen-address=172.16.1.7#为了安全,将其绑定内网IP地址172.16.1.7

anonymous-enable=YES#允许匿名用户访问

write-enable=YES#允许运行各种FTP写命令

anon-upload-enable=YES#允许匿名用户上传文件

anon-mkdir-write-enable=YES#允许匿名用户创建文件夹

anon-other-write-enable=YES#允许匿名用户进行其他写操作

重新启动Vsftpd服务后,用FTP客户端工具就能访问该FTP服务器了。同时也可以进行读写操作,如上传、创建文件夹、删除等。由于对匿名用户开放了较高的权限,所以把监听地址绑定在内网IP地址上,保证它只能被内网用户访问。

浅析Linux的系统调用方法 篇12

系统调用是操作系统为用户态的进程与硬件设备 (如CPU、磁盘、打印机等) 之间的交互提供的一组接口。其主要目的是使得用户可以使用操作系统提供的有关设备管理、文件系统、进程控制、进程通讯以及存储管理等方面的功能, 而不必了解系统程序的内部结构和有关硬件细节, 从而起到减轻用户负担和保护系统以及提高资源利用率的作用。以下以Linux系统体系结构为例 (图1) , 分析系统调用的意义。

Linux系统分为三个层次:用户、核心以及硬件。其中系统调用是用户程序与核心间的边界, 通过系统调用进程可由用户模式转入核心模式, 在核心模式下完成一定的服务请求后再返回用户模式。系统调用可以看作是一个所有Linux进程共享的子程序库, 是由内核提供的、功能十分强大的一系列函数。它们在内核中实现, 可以存取核心数据结构和它所支持的用户级数据, 然后通过一定的方式呈现给用户。

2 Linux内核对系统调用的管理

2.1 与系统调用有关的数据结构

为了实现系统调用功能, Linux在内部定义了相关的数据结构。

2.1.1 系统调用响应函数名的约定

函数名以“sys_”开头, 后跟该系统调用的名字, 由此构成238个形如sys_name () 的函数名。例如fork () 的响应函数是sys_fork () 。

2.1.2 系统调用号

通过系统调用号可以找到系统调用表 (sys_call_table) 中对应表项的内容, 它正好就是该系统调用响应函数的入口地址。文件/usr/src/linux-2.4.18-3/include/asm-i386/unistd.h为每个系统调用分配一个唯一的号码。文件中每一行的格式如下:#define __NR_name NNN。其中, name用系统调用名称代替, 而NNN则是该系统调用对应的号码。文件内容如下所示:

#define __NR_exit 1

……

#define __NR_tkill 238

2.1.3 最大系统调用数

在/usr/src/linux-2.4.18-3/include/linux/sys.h中定义的NR_syscalls表示该表能容纳的最大系统调用数, #define NR_syscalls = 256。

2.1.4 系统调用表

系统调用表记录了各个系统调用处理函数的入口地址。通过这张表就可以根据特定系统调用在表中的偏移量, 找到对应的系统调用响应函数的入口地址。系统调用表在文件/usr/src/linux-2.4.18-3/arch/i386/kernel/entry.S中定义, 其中“.”代表当前地址, sys_call_table代表数组首地址, NR_syscalls为系统调用总数。其结构如下所示:

该清单用来对sys_call_table[]数组进行初始化。该数组包含指向内核中每个系统调用的指针。

2.2 系统调用中参数的传递

为使系统调用的执行成为一项简单的任务, Linux提供了一组预处理宏指令, 它们可以用在程序中。这些宏指令取一定的参数, 然后扩展为调用指定的系统调用的函数。在/usr/src/linux-2.4.18-3/include/asm-i386/unistd.h这个头文件中不仅定义了所有的系统调用号, 同时还定义了7个与系统调用有关的宏, 即_syscallN () , N取0~6之间任意数。这些宏用于系统调用的格式转换和参数的传递。

这些宏指令具有类似下面的名称格式:

_syscallN (parameters)

其中N是系统调用所需的参数数目, 而parameters则用一组参数代替。这些参数使宏指令完成适合于特定的系统调用的扩展。例如, 为了建立调用setuid () 系统调用的函数, 应该使用:_syscall (int, setuid, uid_t, uid) 。

_syscallN () 宏指令的第一个参数int说明产生的函数的返回值的类型是整型, 第2个参数setuid说明产生的函数的名称, 后面是系统调用所需要的每个参数, 这一宏指令后面还有两个参数uid_t和uid分别用来指定参数的类型和名称。

另外, 用作系统调用的参数的数据类型有一个限制, 它们的容量不能超过四个字节。这是因为执行int $0x80指令进行系统调用时, 所有的参数值都存在32位的CPU寄存器中。使用CPU寄存器传递参数带来的另一个限制是可以传送给系统调用的数目。这个限制是最多可以传递6个参数。所以Linux一共定义了7个不同的_syscallN () 宏指令, 从_syscall0 () 、_syscall1 () 直到_syscall6 () 。

一旦_syscallN () 宏指令用特定系统调用的相应参数进行了扩展, 得到的结果是一个与系统调用同名的函数, 它可以在用户程序中执行这一系统调用。

2.3 系统调用过程

系统调用的过程如图2所示。其中粗线表示控制流, 细线表示相关数据关系。

(1) 虚框内, 系统处于用户态。用户程序请求系统服务时, 要以C语言函数的形式写一条系统调用命令。假如该命令已在某个.h文件中由相应的_syscallN () 展开, 则用户程序必须include该.h文件。

(2) _syscallN () :当程序执行到此调用时, 实质上是在执行由宏_syscallN () 展开的函数, 它将系统服务请求转换为中断。系统调用的参数由各通用寄存器传递。

(3) 系统执行int $0x80后, 以核心态进入入口地址system_call (代码在entry.S中) 。从system_call入口的汇编程序, 主要执行如下功能:保存寄存器当前值 (SAVE_ALL) ;检验调用是否合法;根据系统调用表sys_call_table[]和寄存器EAX中的系统调用号找到相应的系统调用响应函数并转入执行。当响应函数执行完毕后, 让EAX寄存器保存函数的返回值。这时, 控制转到ret_from_sys_call。

(4) ret_from_sys_call负责恢复现场信息, 将机器从内核态切入到用户态, 继续执行中断的程序。

3 在Linux中添加新的系统调用

添加新的系统调用可以通过两种方式实现, 一是通过修改内核源代码, 二是利用Linux内核模块。通过修改内核源代码的方式, 将新的系统调用直接静态编译成内核的一部分, 这样会增加内核的大小, 还要改动内核的源文件, 而且不能动态地卸载, 不利于调试;利用Linux内核模块的方式, 则是将新的系统调用编译成可以动态加载的模块, 所以推荐使用模块方式。

3.1 通过修改内核源代码添加系统调用

用户在Linux中添加新的系统调用, 可以遵循几个步骤才能添加成功, 下面几个步骤详细说明了添加系统调用的相关内容。

3.1.1 添加源代码

第一个任务是编写加到内核中的源程序, 即将要加到一个内核文件中的函数, 该函数的名称应该是新的系统调用名称前面加上sys_标志。假设新加的系统调用为mycall () , 在/usr/src/linux-2.4.18-3/kernel/sys.c) 文件中添加源代码 (作为一个最简单的例子, 新加的系统调用仅仅返回一个整型值) , 如下所示:

3.1.2 连接新的系统调用

添加新的系统调用后, 下一个任务是使Linux内核的其余部分知道该程序的存在。为了从已有的内核程序中增加到新的函数的连接, 需要编辑两个文件。

第一个要修改的文件是/usr/src/linux-2.4.18-3/include/asm-i386/unistd.h。根据unistd.h文件查看Linux内核自身的系统调用号码已经用到238, 而sys.h文件中显示最大系统调用号为256, 因此新的系统调用号可在239~256之间, 可设定为:#define __NR_mycall 239。

第二个要修改的文件是:/usr/src/linux/arch/i386/kernel/entry.S。在相应位置添加.long SYMBOL_NAME (sys_mycall) , 这样就在sys_call_table[]数组中增加了新的内核函数的指针。

3.1.3 编译内核, 重启动系统

通过编译内核, 重建新的Linux内核, 让新添加的系统调用成为操作系统的一部分。然后用新内核启动系统, 这样用户就可以在应用程序中使用该系统调用了。

3.1.4 使用新的系统调用

与新的内核模块运行于内核态不同, 调用新的系统调用是在用户进程中进行并运行于用户态的。相应的, 调用新的系统调用所在的程序段只需在用户态下编译即可生成可执行文件。在应用程序中使用新添加的系统调用mycall。同样为实验的目的, 写了一个简单的例子exam.c。

3.2 利用Linux内核模块添加系统调用

3.2.1 编写内核模块

编写新的内核模块有比较固定的格式, 对应的具体程序段由以下三部分组成。第一部分是新的内核函数, 这个函数体中的代码明确了添加到内核中的模块所能完成的功能。第二部分是模块初始化函数 (init_module () ) , 主要用于初始化参数、系统注册、修改系统调用表等。第三部分是卸载模块时所调用的函数 (cleanup_module () ) , 这个函数将恢复初始化函数中修改的内容, 如卸除系统注册、恢复系统调用表等。

以下给出一个内核模块的编写实例 (mker.c) , 这个实例的组成如上所述。mker.c源程序内容如下。

3.2.2 编译新的内核模块

编写新的内核模块之后, 要对这个源文件进行编译。内核模块的编译需要用到一些选项, 以指明用哪种方式编译、最终的代码运行于哪种模式下等。具体操作为, 在命令行下键入gcc –Wall –DCONFIG_KERNELD –DMODULE –D_KERNEL_-DLinux –c mker.c。其中, –Wall选项是要求gcc将所有的警告信息显示出来;后面几个以D开头的选项则指明了编译出的代码运行在内核模式下。注意, 以这种方式编译出的不是可执行文件, 而是二进制模块文件mker.o。

3.2.3 加载和卸载新的内核模块

得到mker.o文件之后, 就可以将模块加载到内核中, 以供用户通过系统调用的形式调用该模块所加载的函数。可使用insmod命令手工把它加载到核心 (即在命令行键入insmod mker.o) 。insmod命令在/lib/modules/kernel-version目录的modules.dep文件里找到它要加载的被请求的核心模块, 然后进行加载。在模块被加载之后, 可以用命令lsmod列出所有加载的核心模块和它们之间的依赖关系, 以检查是否所需模块已加载在内核中。

当内核中的模块不再使用时就需要对其卸载, 以免它占用内存空间。模块可以用rmmod命令卸载 (即在命令行输入rmmod mker, 注意这里不带.o后缀) 。

3.2.4 使用系统调用

在编写好新的内核模块、将它加载到内核, 并且做好了新的系统调用之后, 我们就可以对这个新的系统调用在用户进程中进行具体的调用。以下为使用新添加的系统调用的程序段 (callsys.c) , 这个程序调用mycall () 函数来计算值, 并在终端输出。

3.2.5 系统调用工作流程

结合以上例子, 可将系统调用的工作流程总结如下:

当程序调用mycall () 这个函数时, 便会调用第三行, 通过查看头文件unistd.h中宏syscall2的定义, mycall () 会被展开成以下代码:

从中可以看出, 程序通过调用宏__NR_mycall得到调用号, 放到寄存器eax中, 同时将参数num1、num2放入通用寄存器ebx、ecx中, 接着执行中断指令“int $0x80”。这样就陷入到内核中, 根据系统调用号索引sys_call_table, 并找到最终的内核函数sys_mycall () , 这个内核系统调用函数仅返回计算得到的值, 将返回值送入CPU的eax寄存器中, 最后进程返回到用户态, 用户程序最终执行完成, 整个系统调用过程也就完成。

3.3 两种方式对比

通过修改内核源代码的方式, 将新的系统调用直接静态编译成内核的一部分, 这样会增加内核的大小, 还要改动内核的源文件, 而且不能动态地卸载, 不利于调试。

而利用Linux内核模块的方式, 则是将新的系统调用编译成可以动态加载的模块, 使用非常灵活, 所以推荐使用模块方式。

4 总结

综上所述, 由于Linux操作系统的自由开放性及容纳用户自定义系统调用的特性, 我们完全可以在原有系统调用的基础上, 添加一些有益的、实用的新的系统调用功能, 让Linux操作系统为我们提供更多更好的服务。

摘要:系统调用是连接应用程序和系统内核的关系纽带, 本文以RedHat Linux2.4.18为例, 通过对Linux操作系统中系统调用数据结构、参数传递、调用过程的分析, 提出了两种实现系统调用的方式, 并提供了详细代码。

关键词:Linux操作系统,系统调用,内核模块

参考文献

[1]陈莉君, 康华.Linux操作系统原理与应用.北京:清华大学出版社, 2006:133-148.

[2]陈刚, 卢显良.基于Linux-2.6内核模块程序设计.福建电脑, 2004, (6) :15-16.

上一篇:天人合一与文化发展下一篇:软件项目管理活动