|
|
第 1 帖 | |
|
|
标题: [LFS实战]DIY一个实用的mini-LAPP服务器(Apache PHP PostgreSQL OpenSSH Iptables) 由于论坛排版效果不理想,而且我也只在我的个人空间对文章进行后继更新,所以建议直接到我的空间查看:
DIY一个实用的 miniLAPP 服务器 [x86版] http://lamp.linux.gov.cn/miniLAPP/LAPP-x86.html ------------------------------------------------------------------------------- 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发,但必须保留作者署名,亦不得对声明中的任何条款作任何形式的修改,也不得附加任何其它条件。您可以自由链接、下载、传播此文档,但前提是必须保证全文完整转载,包括完整的版权信息和作译者声明。 其他作品 本文作者十分愿意与他人共享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有作品的列表: 金步国作品列表 BUG报告,切磋与探讨 由于作者水平有限,因此不能保证作品内容准确无误,请在阅读中自行鉴别。如果你发现了作品中的错误,请您来信指出,哪怕是错别字也好,任何提高作品质量的建议我都将虚心接纳。如果你愿意就作品中的相关内容与我进行进一步切磋与探讨,也欢迎你与我联系。联系方式:Email: csfrank@citiz.net ; QQ: 70171448 ; MSN: csfrank122@hotmail.com ============================================== 先决条件 本文的读者应当至少手动安装过一次 LFS ,如果你没有做过 LFS ,这篇文章很可能不适合你,请先按照《Linux彻底定制指南》做一遍 LFS 。另外,如果你对编译优化也很感兴趣,那么《GCC编译优化指南》也很值得一读。 目标 youbest兄的大作《5M大小的Apache服务器》和其续篇《600K的Apache服务器》将LFS的精神发挥到了极致,令人叹为观止!然而许多实用主义者(包括我在内)也只能叹为观止而已,因为这样的服务器由于过分追求小巧而变得不太实用,基本上不能在实践中用于生产目的。 鉴于上述原因,本文打算制作一个既实用又小巧的 Linux + Apache + PHP + PostgreSQL + OpenSSH + Iptables 服务器,并且实用优先于小巧。尽管实用优先于小巧,但是与基于普通发行版搭建的LAPP服务器相比仍然相当Mini(本文制作出来的最终系统核心部分大约 15MB[其中体积较大的文件有:bzImage约1MB、postgres约3.5MB、libphp5.so约4.6MB、libc.so约 1.3MB、libcrypto.so约1.1MB],总体积大约150MB),因此我把它称为"miniLAPP"服务器。当然,除了小巧,灵活和高效也重要,这在本文中主要体现在:㈠对软件包进行最大限度的自定义配置,㈡在保证稳定的前提下进行编译优化。 为了避免纠缠于各种复杂的硬件环境(它不是重点所在),本文将在 VMware Workstation 5.5.5 上建立一个虚拟机。具体如下:Intel 440BX 主板,athlon-xp处理器(如果你的CPU与我不同,那么只要将本文中所有的"athlon-xp"都替换成你的CPU型号即可,具体可以参考Gentoo Safe Cflags),512M内存(最低384MB),100M网卡(PCnet32),4G硬盘(BusLogic SCSI 0:0),CDROM(IDE 1:0 lfslivecd-x86-6.3-r2160-min.iso 仅供安装)。 网络环境:ip:192.168.10.33/24 ,broadcast:192.168.10.255 ,gateway:192.168.10.250 ,没有DNS 。如果你的环境与此不同,请自行调整相应的ip命令。 思路 基本上,小巧和实用是有冲突的,因为越要求实用就越需要各种功能,也就越无法保证小巧。为了解决这个问题,本文采用了"核心+扩展"的思路。所谓" 核心"是指保证服务器正常运行必须使用的资源,比如:libc, init, httpd, postgres, libphp, sshd ... 以及各种设备文件、配置文件等等。所谓"扩展"是指非运行时必须的资源,比如:top, cat, gcc ... 等等,主要用于服务器维护。 解决方案是将"核心"部分安装在"/"目录下,使其在服务器一起动的时候就能够使用,而将"扩展"部分安装在"/usr"目录下,并且"/usr"位于独立的分区上,仅在需要使用的时候才手动挂载,使用完毕以后再手动卸载。 事实上,对于绝大多数软件包而言,所需要的只是其中的一小部分而已,因此,绝大部分软件包的主体都位于"/usr"目录下,仅将必须的某些部分安装到"/"下。 另一个问题是使用静态连接还是使用动态共享库?从小巧的目标来看,似乎应当使用静态连接,但是考虑到: 1. 追求小巧并非第一重要,此处"Mini"的含义并非偏重于磁盘空间,而是尽可能减少不必要的程序和组件。 2. 动态连接的程序可以在内存**享库文件,而静态连接的程序则无法实现。考虑到此服务器可能扩展为提供 DNS, FTP, Mail, Proxy 等其它服务,静态连接将导致运行时占用更多的内存。 因此本文决定采用常规的动态连接。更多关于静态连接的害处,可以参考"Static Linking Considered Harmful"一文。 制作工具链前的准备工作 使用 LiveCD 开机,直接按回车键启动,所有设置均采用默认。 如果希望使用ssh进行远程安装,请执行如下步骤: 代码:
代码:
代码:
[提示]如果在工具链的制作过程中中途关机,那么只需在重新开机后重新执行下面的命令即可恢复工作状态。不过,关机前一定要运行"sync"命令并 umount所有挂载点,否则可能出现意外。 [说明]为了binutils-pass2测试成功,这里使用了一个rm废除LiveCD的g++和cpp,否则ld测试可能会失败。不过,没有C++编译器将会导致Glibc的 bug-atexit3-lib.os tst-cancel24.o c++-types-check 测试失败,并且无法运行dejagnu的测试程序。 代码:
编译过程是一个漫长的冒险,特别是在使用了一大堆configure选项和优化参数的情况下,出现错误是再正常不过的事情了。本文的所有代码都在我的CPU上测试通过,因为我没有更多的CPU,所以无法进行更多的测试,但是一个基本原则就是,一旦遇到编译或测试错误,首先想到的应当就是降低优化级别,看看能不能通过。理论上,将本文所有的"athlon-xp"都替换成"i686",并且设置 CFLAGS="-O2 -fomit-frame-pointer -pipe -march=i686" LDFLAGS="-s" kLDFLAGS="",应当可以在目前实际使用的所有 x86 CPU 上顺利完成。如果降低优化级别仍然不能解决问题,那么可以继续调整configure选项。 下面这些优化选项可能是地雷,尽量不要使用,如果你喜欢冒险,并且不小心踩到了,别怪我没提醒过你..... CFLAGS "-D_FILE_OFFSET_BITS=64 -fvisibility=hidden; -malign-double; -mregparm=3; -msseregparm; -ftracer; --param max-gcse-memory=100M; --param max-gcse-passes=3; -Wa,-R; -Wa,-march=athlon"至少会导致Glibc配置或编译失败。"-m128bit-long-double"会导致GCC的 gcc.dg/pr19402-2.c测试失败,Glibc的math/test-misc.out测试失败,autoconf的AC_PROG_SED 测试失败,tar的31/33/35号测试失败。"-freg-struct-return"虽然能让Glibc通过测试但却会间接导致GCC的 gcc.dg/struct-ret-libc.c测试失败,这是二进制兼容性所致,一般可以忽略它。"-ftree-loop-linear"会导致 PostgreSQL无法运行测试程序(无法初始化数据库),还会导致JPEG测试失败。 LDFLAGS "--as-needed"将导致Glibc的stdlib,nptl,elf测试出现多处错误,"-znow"将导致 Glibc的elf测试出现多处错误。"--sort-common"会导致Automake的ccnoco.test测试失败(直接和间接原因都有??)。 kLDFLAGS "-s"会导致内核编译失败。 附件为本文所有需要使用的补丁和配置文件
__________________
@@ 此帖于 08-03-03 11:14 被 csfrank 编辑. |
|
|
|
|
|
|
|
第 2 帖 | |
|
|
确实很长,赞一个!
![]()
__________________
青橄榄在入口的时候是苦的,过了一会你就可以长久的品味那淡淡而又清爽的甜味。 青橄榄 http://youbest.cublog.cn 青橄榄计划的第一步总算迈出来了,等待它的是万里长征. 做技术要有做技术的原则,决不拿技术做侵权的事情,更不能用来做违法的事情。工作丢了可以再找一个,原则丢了就找不回来了。 |
|
|
|
|
|
|
|
第 3 帖 | |
|
|
楼主无私奉献,感激。支持
__________________
为了那些爱你的人和你爱的人 无论你多努力都不为过 徐牛 |
|
|
|
|
|
|
|
第 4 帖 | |
|
|
制作工具链
此处工具链的制作基本上与 LFS 第五章相同,只是增删几个包、改动了一些配置选项、简化了几个包的安装动作、将几个补丁的功能用 sed 进行了替代、以及其它一些小变化等等,因此下面只列出命令而不进行任何说明。 代码:
|
|
|
|
|
|
|
|
第 5 帖 | |
|
|
重启工具链
与 LFS 的标准做法不同,本文为了尽可能摆脱宿主系统的影响,做完工具链之后不是chroot进入虚根环境,而是做一些必要的准备工作,然后重新启动计算机,进入一个完全与宿主系统无关的工具链环境,再继续完成目标系统的构建。 创建基础目录结构、必需的符号连接与文件、存储随机数种子、用户和组([注意]pgsql属于www组,root的密码是"123"): [提示]如果现在就将 mtab 指向 /proc/mounts 的话,Coreutils 测试程序会将 /dev/root 挂载到 tests/rm/one-file-system.tmp/ 下的某个目录中,从而导致无法删除Coreutils 的编译目录。 代码:
由于本文不打算使用 Udev ,因此这里手动创建所有设备。 代码:
代码:
代码:
代码:
代码:
分支㈠[关机] 关机前的准备(如果没有启动ssh就省略相应的命令): 代码:
代码:
分支㈡[chroot] 为了方便期望在编译最终系统的过程中也能使用ssh的读者,这里也介绍一下传统的chroot方法。需要说明的是,由于此分支的方法不能完全摆脱宿主系统的影响,所以本文不推荐使用。仅供那些贪图copy/paste便利的玩家参考和测试。 代码:
|
|
|
|
|
|
|
|
第 6 帖 | |
|
|
依赖关系分析
在正式开始编译最终系统之前,我们需要静下心来认真分析一下这个最终系统究竟需要哪些东西。 所谓"依赖性"是多方面的。一般来说,可以分为"运行时依赖"、"编译安装依赖"、"测试依赖"三个层面。为了构建一个严谨的自依赖系统,显然这三种依赖性都必须满足。运行时依赖比较简单,一般就是库的依赖;而后两种依赖则比较复杂(运行时依赖实际上取决于编译安装依赖)。比如,如果你不需要安装文档,那么 Textinfo 就不是必须的;如果你不需要国际化支持,那么 GetText 也不是必需的,等等。庆幸的是 LFS-Book 的附录部分给出了宝贵的依赖关系资料,可以提供参考,这样可以省去很多麻烦。 首先,我们来看看"核心"部分需要哪些东西。很显然,下面这些是必须的:GRUB, Kernel, Glibc, Sysklogd, Dcron, Bash, IPRoute2, Apache, PHP, PostgreSQL, OpenSSH, Iptables 。再深入思考一下,就会发现如下组件也是"核心"部分必须的:E2fsprogs(被mount和xfs_repair依赖),XFS(用于开机时的磁盘检查),Ncurses(被Readline/Bash依赖),Readline(被Bash/PostgreSQL依赖),Zlib(被 Apache/PostgreSQL/OpenSSH依赖),JPEG+PNG(被PHP依赖),PCRE(被Apache/PHP依赖), OpenSSL(被Apache/OpenSSH/PostgreSQL依赖),Util-linux 与 Coreutils 中的部分程序。核心部分只需要满足运行时依赖即可。 然后,再看看"扩展"部分需要哪些东西。这部分的选择因人而异,这里就大致选择了几个系统管理相关的组件和几个实用工具:Coreutils, Procps, Psmisc, Util-linux, Bzip2, Findutils, Grep, Sed, Tar, XFS 。选择这部分组件时,暂时无需考虑依赖关系。 最后,考虑到可扩展性以及将来的组件升级与维护等,就必须构建一个自依赖的系统。也就是说,所有组件加在一起必须能构成一个完整的依赖环(3种依赖关系全部满足)。本文安装的、并且未在前面提到的软件包都属于这个用途。它们都属于"扩展"。 需要说明的是,这里的"核心"与"扩展"的划分不是绝对严格的:扩展部分的组件严格属于"扩展",而核心部分的组件通常只有某一部分属于"核心" (其他部分归入"扩展")。比如 Glibc 的基本库部分就属于"核心",而扩展库、实用程序、文档、头文件等则属于"扩展"。 包管理 其实这么简单的系统根本不需要包管理,所以本文并不使用任何一种包管理技术,只是使用了一种非常简单的 DESTDIR 方法来将每个包都复制一份到/root目录下,以方便管理员查看每个软件包究竟安装了哪些东西。当然,并不是所有软件包都遵循这个约定俗成的规则,对于这些软件包使用的命令也有所不同。 编译最终系统 配置选项 要做到最大限度的定制每一个软件包,获取完整的配置选项是必须的。当然,要想更加详细、全面的了解如何自定义安装,还需要查看 README INSTALL FAQ 之类的文档,甚至是软件包的官方手册。需要注意的是,有不少软件包的配置选项分布在多个 configure 脚本中,还有少数并不是通过 configure 脚本进行配置的,查看完整的配置信息就变成一件很吃力的事情了。因此唯一的建议就是:读文档、读文档、再读文档。当然,鸟语是免不了的... 关机与状态回复 由于编译过程漫长,下面的编译步骤被设计为"易于恢复状态的"(仅对"分支㈠"有效),意思是,你可以在编译完任意一个软件包之后关机,并且重新开机后就已经自动的恢复了工作状态。要达到这个目的,你可以使用任何你喜欢的方式关机(比如直接拔掉电源),但是你必须确保在关机前运行了"sync"命令。 对于分支㈡,恢复步骤如下: ①使用 LiveCD 开机,直接按回车键启动,所有设置均采用默认。 ②如果希望使用ssh进行远程安装,步骤同前。 ③挂载文件系统后进入虚根环境,即可完成状态恢复: 代码:
代码:
此帖于 08-03-03 10:15 被 csfrank 编辑. |
|
|
|
|
|
|
|
第 7 帖 | |
|
|
内核头文件
根据 Glibc 的 FAQ ,编译 Glibc 时使用的内核头文件版本可以比实际运行 Glibc 的内核版本高。比如用于编译 Glibc 的内核头文件版本为 2.6.24 ,但是实际运行 Glibc 的可以是 2.6.16 版本的内核(编译 Glibc 时必须使用 --enable-kernel=2.6.16 而不能使用 --enable-kernel=2.6.24 )。允许这样做的好处是即使将来把内核升级到 2.6.24 也不需要重新编译 Glibc 了。另一方面,如果实际运行的内核版本比头文件版本高,那么新内核的新特性(主要是系统调用)将无法被Glibc使用。[注意]不要直接 INSTALL_HDR_PATH=/usr ,这样可能使得Glibc变得不稳定。[小提示]如果将来把内核升级为更高版本,头文件是不是也需要跟着一起升级?答案是:NO!! 关于内核头文件变迁的历史,这里有一篇《[八卦故事]内核头文件传奇》,可以当作课外读物 ![]() 代码:
Glibc 的安装指南中说测试套件中的某些测试项目是假定以非 root 身份运行的,因此建议使用普通用户身份进行编译与安装。不过经过实践,以 root 用户进行编译和安装也没问题。这里仅安装了 zh_CN.UTF-8 的 locale 支持,如果你想支持更多的 locale 请自己添加适当的 localedef 命令。出于安全最大化的考虑还禁用了 DNS 。将时区设为UTC(相当于取消时区的概念,如果你有使用时区的需求可以设为"PRC")。更多关于安装 Glibc 的信息,请查看源码树下的 configure INSTALL FAQ 三个文件。[提示]由于没有安装C++编译器的缘故,bug-atexit3-lib.os tst-cancel24.o c++-types-check 测试将会失败,你可以安全的忽略它。touch用于阻止可能发生的Autoconf调用(当Makefile检测到一个configure文件的时间戳比它对应的configure.in文件旧的时候),这种调用有时候会导致编译失败。将"/dev/log"修改为"/dev/shm/log"是因为将来的根文件系统是只读挂载的,而syslogd会在启动的时候删除并重建此socket。Glibc GCC Binutils 三者是整个工具链的核心,因此如何对其进行定制就显得很重要。这里有一篇文章《Glibc 安装指南》,可以在漫长的编译过程中作为参考资料读一读。 代码:
代码:
[提示]使用 --with(out)-tk 将导致 expect 配置失败,使用了 --with-tcl 之后就不需要再详细指定 --with-tclconfig --with-tcllib --with-tcllibdir 了。使用 --with(out)-docbook 或 --with(out)-oskith 将导致 dejagnu 配置失败。sed 一定要先修改 configure.in 再修改 configure ,否则会导致 Autoconf 的调用。dejagnu 的安装指南说测试套件需要以非 root 身份运行,可是经过实践,无论 root 与否,都不能在第一次安装后立即通过测试,一般需要安装两次甚至三次才能测试成功(无论是否root都是这样),不知何故。再加上dejagnu的测试程序依赖于这里并不存在的C++编译器,因此这里跳过dejagnu测试。 代码:
由于"-finline-functions"会导致ld测试出现多处错误,因此这里需要专门禁用它。对Makefile.in的修改用于移除对 makeinfo的依赖,否则编译将会失败(因为工具链中并未安装Texinfo)。[提示]由于 binutils-2.17 的测试套件将路径 /bin/stty 进行了硬编码,且本文作者尚未找到简便的迂回方法,因此如果你使用的是 2.17 ,那么要先建立一个符号链接来满足测试套件的需求,安装完毕后再删除它。对于如何安装 Binutils 和 GCC 可以参考一下《Binutils与GCC配置选项简介》。 代码:
因为GCC的Makefile.in并不传递LDFLAGS,所以需要sed一下。为了得到更加高效的编译器,这里使用"make profiledbootstrap"代替"make"。对"LINK_SPEC"的修改是为了将"--hash-style=gnu"选项添加到默认的连接器选项中去,如果你希望这样的话,就去掉相应的注释。[提示]如果Glibc的CFLAGS中使用了-freg-struct-return的话, gcc.dg/struct-ret-libc.c测试将会失败,不过这是二进制兼容性所致,可以安全的忽略它。 代码:
Sed 代码:
[提示]"--disable-htree"和"--disable-debugfs"选项都会导致许多测试错误,"--disable-swapfs" 会导致lib/ext2fs测试由于找不到"tst_types"而失败,此外由于lib/ext2fs测试总是由于"Failed to allocate scratch memory!"失败,原因不明,所以这里使用sed跳过这个测试。CFLAGS和LDFLAGS必须在configure选项上设置。[依赖提示] UUID被XFS依赖,blkid,uuid 被mount/umount依赖。 代码:
运行 make check 的非特权用户要求至少位于两个不同的组中,因此这里将 pgsql 用户临时添加到 dummy 组内。"RUN_VERY_EXPENSIVE_TESTS=yes"用于运行更多的测试项目。[说明]因为test-getaddrinfo测试总是由于缺乏DNS支持而失败,需要跳过它。[说明]由于Findutils包内的 xargs 程序将 echo 程序硬编码为"/bin/echo",且不能在源代码中将其修改为"echo"(会导致测试失败,原因不明),另一方面echo也是bash的内置命令,所以就将它也安装在 /bin 目录下。 代码:
[依赖提示]至少被Bison/Autoconf/Automake/Flex依赖 代码:
[依赖提示]至少被Bash依赖 代码:
[依赖提示]至少XFS的安装依赖于它。 代码:
这个包的配置选项简直多如牛毛,这里没有(也没必要)涵盖全部选项。更多安装信息请查看源码树目录下的 INSTALL 文件(所有选项皆有描述,不需要查看 configure 的内容)。Ncurses 的测试套件与大多数包不同,不能用简单的非交互式"make check"来测试,因为 Ncurses 牵涉到视觉效果,所以必须是交互式的测试,更多有关如何测试的细节,请查看源码树下的 test/README 文件。更多官方补丁请查看:ftp://invisible-island.net/ncurses/5.6/ 。[提示]--enable/disable-database都将导致编译失败,不能使用。--disable-ext-funcs --disable-tparm-varargs 将导致 Procps 无法编译。如果你不想安装terminfo数据库可以使用"--disable-database --without-terminfo-dirs",如果你不想安装实用程序可以使用"--without-progs"。可以使用"make install.libs"仅安装共享库。 代码:
Procps 的测试套件与 Ncurses 类似,由于牵涉到视觉效果,因此也是交互式测试,具体细节请查看 README 文件。 代码:
Perl的测试很奇怪,有时候第一次运行失败,再运行一次却能成功。 代码:
由于只需要共享库,因此只编译和安装共享库(包括头文件)。"bash_cv_func_ctype_nonascii=yes"用于修正当en_US.ISO8859-1这个locale不存在时会出现的问题 代码:
由于只需要共享库,因此只编译和安装共享库(包括头文件)。[提示]configure脚本只传递了CFLAGS而未传递LDFLAGS,因此需要在配置完毕后(不能提前修改Makefile.in,configure会覆盖掉你的修改)再修改Makefile中的LDSHARED(作用于共享库)和 LDFLAGS(作用于二进制文件)。 代码:
|
|
|
|
|
|
|
|
第 8 帖 | |
|
|
Flex
由于没有安装C++编译器的原因,将会有6个与C++相关的测试项目失败,不必紧张。[依赖提示]仅在安装IPRoute2的tc工具和安装Bc时需要它。 代码:
以root身份运行automake-1.10.1的instsh2.test测试总是会失败,所以需要使用一个sed跳过它。[提示]如果你忍受不了测试的漫长可以去掉注释。[依赖提示]至少被PHP依赖。 代码:
Bash 的测试套件不像其他软件包那样遇到错误就停下来并返回非零的错误代码,而是始终返回表示成功的零,因此不能在脚本中根据 make tests 命令的返回状态判断测试的成败,你必须用眼睛亲自检查 make tests 的输出结果。另一方面由于 Bash 的测试套件如同 GCC 一样,错误总是不可避免的,因此如果错误不是特别多就无需太在意(可以在 http://www.linuxfromscratch.org/lfs/build-logs/ 找到参照)。更多有关安装的详细信息请查看源码树下的 INSTALL config-top.h 以及 configure --help 本身。 代码:
Bzip2 的两个 Makefile 文件写的相当简洁易懂,建议直接阅读以获取安装信息。 代码:
代码:
[提醒] xargs 程序将 echo 程序硬编码为"/bin/echo",且不能在源代码中将其修改为"echo"(会导致测试失败,原因不明)。 代码:
代码:
详细的安装信息位于源码树下的 README 文件中(不需要查看 INSTALL 了),需要仔细阅读。此外,pcrebuild手册页还有更详细的说明。 代码:
由于grep-2.5.3的文档依赖于Texinfo,所以为了编译成功,需要用一个sed去掉doc子目录。foad1.sh 和 fmbtest.sh 测试是意料中的失败(不过我这里却能通过)。 代码:
代码:
这个软件包不是通过 configure 脚本而是通过直接修改 Makefile 文件进行配置的,具体细节请阅读 README 文件。[提示]由于 arpd 对这个系统没有价值而且还依赖于 Berkeley DB ,所以这里用一个 sed 去掉它。如果你不需要依赖于Flex的tc可以去掉注释。 代码:
[提示]不能明确指定 --enable/disable-case-insensitive-file-system ,否则无法编译成功。 代码:
代码:
因为 Psmisc 默认的 configure 依赖于C++编译器,而实际上编译过程并不需要C++编译器,所以这里要重新生成一个不依赖于C++编译器的 configure 。 代码:
代码:
SUID_CFLAGS 和 SUID_LDFLAGS 用于定义几个带有 suid 位的程序(chfn, chsh, newgrp, write, mount, umount)的编译选项,出于安全考虑,这里使用了"-fpie"和"-pie"编译选项。这个包硬编码了"/bin/{login,umount}" 路径,由于这个硬编码还算合理,因此未作改动,如果你要改动的话,请查看源码树下的 include/pathnames.h 文件。由于本文将使用此包中的 simpleinit 而不是 Sysvinit 中的 init ,因此 /etc/inittab 的语法有所不同。simpleinit 不但比 init 的配置简洁,而且没有所谓"运行级"的概念。更多细节可以查看simpleinit的手册页。这个包的测试程序不是通过"make check"执行的,而是通过tests子目录中的run.sh脚本执行的,不过这里的测试程序仅供开发者使用,切勿用于生产系统!具体细节请看 tests/README 文件。 代码:
|
|
|
|
|
|
|
|
第 9 帖 | |
|
|
Linux-Kernel
为了尽可能简单,这个内核不支持initrd也不带任何动态加载模块,甚至禁用了模块加载功能。内核的编译优化参数是直接通过 CC 和 LD 传递的(而不是通常的 CFLAGS 和 LDFLAGS)。建议在修改默认值之前先用 make -qp | egrep '^(CC|LD|CFLAGS|LDFLAGS)' 查看一下默认值[在本文情况下的默认值是:CC='gcc -m32' LD='ld -m elf_i386']。[提示]在 LD 中使用"-s"会导致编译失败;"V=1"将显示详细的命令。此外,由于本文作者觉得默认的"-mtune"不过瘾,所以还修改了 Makefile*.cpu 文件的内容。更多有关内核编译的信息可以参考内核源码树下 Documentation/kbuild 目录中的内容;对于如何配置内核,可以参考《Linux 2.6.19.x 内核编译配置选项简介》。此外,《Linux Kernel in a Nutshell》也是一本不可多得的好书。[补充说明]patch-o-matic-ng是用于扩展内核Netfilter功能的模块,可以创建更强大的防火墙规则。最新的patch-o-matic-ng可以在这里下载,如果你需要可以打上这个补丁,详细说明请阅读源码树下的 README 文件。 代码:
如果你需要使用 klogd 的延时启动功能,可以去掉注释。由于本文不将内核消息转发到 syslogd ,而是由 klogd 直接记录到日志,因此无需延时启动。将"/dev/log"修改为"/dev/shm/log"是因为将来的根文件系统是只读挂载的,而syslogd会在启动的时候删除并重建此socket。有关Sysklogd的更多知识,可以参考《Sysklogd 系统日志记录器》。 代码:
Dillon's Cron 是一种简单、严谨、安全的 cron 实现。此软件包非常简单,可以直接修改 Makefile 和 defs.h 对其进行定制。[注意]Dcron并不使用Sysklogd记录日志,一般的方法是直接将命令的结果重定向到日志文件。有关Dcron的更多知识,可以参考《简单、严谨、安全 —— Dcron 简介》。 代码:
这个包并不是典型的"configure && make && make install"风格的软件包,但是这里用一个 sed 来达到模仿的目的,但是仍然要注意的是 configure 的目的不是为了生成 Makefile 文件,而是为了生成 include/{builddefs,platform_defs.h} 文件。要了解更多安装信息,请仔细阅读源码树下的 Makefile include/builddefs.in doc/INSTALL 文件。内核源码树下的 Documentation/filesystems/xfs.txt 文件包含了 XFS 可以使用的挂载选项。[提示]"--enable-shared=yes"会导致 libxfs.so,libxlog.so 库丢失,不知何故。 代码:
建议编译前好好读一读 Makefile 文件,然后按你的需求进行修改[这里编译的是静态版本]。当然,还有 INSTALL 也不要忘记了。此外,如果你升级了内核,那么最好把这个包重新编译一次。由于配置Iptables是一个见仁见智的工作,需要根据实际情况灵活变通,因此本文只示范其安装,而没有涉及其配置。 代码:
如果你不打算运行 OpenSSL 的测试套件就可以不安装它(不建议这么做)。BC的测试程序在遇见错误的时候也不会返回非零的结果,因此这里将测试输出记录在一个文件中。大约有10个左右的测试项目会在最末尾一位出现舍入误差,这是正常的,无需在意。 代码:
config 脚本检查系统环境并调用 Configure 完成配置,因此配置选项是通过 config 脚本向 Configure 传递的。事实上 config 脚本的作用相当于 config.guess ,所以如果你想直接调用 Configure 的话就一定要正确指定"操作系统-目标平台"(本文就是这么干的),所有可用的目标机器列表可以使用"./Configure LIST"命令获取。Configure 脚本除了根据 Makefile.org 生成 Makefile 之外,还在 crypto/opensslconf.h 中定义了许多宏(基于 crypto/opensslconf.h.in)。详细的安装信息位于源码树下的 INSTALL Configure(特别是"PROCESS_ARGS"段) Makefile.shared Makefile.org 文件中。安装后的使用与配置信息位于 doc 目录中, FAQ 文件也可以提供一些参考。 Configure第一行是全局性选项,比如:如果你的CPU是P4/K8以上,那么就可以使用"enable-sse2"。所有可用的"[no -]***"全局选项如下:zlib,zlib-dynamic,threads,shared,asm,sse2,hw,gmp,rfc3779, krb5,ssl(ssl2,ssl3),tls,dso。no-dso仅在no-shared的前提下可用。[提示]为了安装Apache的 mod_ssl成功,SSLv2/SSLv3/TLS都必须开启。[TODO]测试"asm,no-asm"的速度差异。 Configure第二行的"no-***"用于禁用crypto目录下相应的子目录,为了保证能够最小安装libcrypto,libssl, openssl,其中的大部分目录都必须保留,实际可选的目录仅有如下这些:md2,md4,mdc2,ripemd,des,rc2,rc4,rc5, idea,bf,cast,camellia,ec,dsa,ecdsa,dh,ecdh,comp,store。如果你禁用了其中的某些子目录,那么在编译前必须执行make depend步骤。[提示]为了安装OpenSSH成功,ripemd,des,rc4,bf,cast,dsa,dh目录不能被禁止。 Configure第三行相当于CPPFLAGS+CFLAGS的内容(DEVRANDOM指定随机设备,SSL_FORBID_ENULL则禁止使用NULL加密算法)。由于无法通过Configure设置LDFLAGS,并且Configure会强制清空Makefile中的LDFLAGS,所以在运行完Configure之后,使用一个sed修改所有Makefile中的LDFLAGS(用于连接openssl)和 SHARED_LDFLAGS(用于连接libcrypto,libssl库)。[提示]不能省略find命令内"Makefile*"两边的引号。 OpenSSH 只依赖于该软件包的加密库(libcrypto),而带有 HTTPS 支持的 Apache 则依赖于该软件包的加密库和 SSL/TLS 库(libssl)。因此,如果你不打算使用 HTTPS 的话,可以只安装加密库(no-ssl no-tls);更多介绍可以查看 README 文件的"OVERVIEW"部分。由于本文将安装一个支持 HTTPS 的 Apache 服务器,所以这两部分库都安装了。 如果你想了解更多信息,可以读一读《OpenSSL-0.9.8g 安装与配置指南》。 依赖于OpenSSL的包都对OpenSSL的版本很敏感,所以即使将来只把OpenSSL进行了很小的版本升级,也建议你将所有依赖于OpenSSL的包重新编译一遍。 代码:
详细的安装信息可以从 configure INSTALL README.privsep 文件中获取,测试相关的信息可以从 regress/README.regress 文件中获取。TEST_SSH_QUIET=yes表示抑制测试成功的输出信息(仅输出失败信息),将TEST_SSH_TRACE设为"yes"可以输出详细且罗嗦的测试信息。TEST_SSH_PORT将用于测试的TCP监听端口改为非22以避免可能的端口冲突。如果 $PATH 中不包含"scp",那么 multiplex scp 测试将会失败,因此这里在测试前先建立一个符号链接。[提示]测试套件要求 /bin 目录下至少有两个"l"打头的文件,否则 sftp-badcmds 等测试会失败,诡异的要求! 更多有关OpenSSH的知识可以阅读《OpenSSH 安装指南》,以及一系列的《OpenSSH 中文手册》。 代码:
configure脚本的主要任务是生成 src/Makefile.global 文件,阅读它可以得到不少信息。更多安装信息可以查看《PostgreSQL 8.2.3 中文文档》,这里就不多罗嗦了。该文档位于PostgreSQL 中文之家。此外,本文还安装了非常有用的加密模块。要了解如何添加模块,可以阅读 contrib/README 来选择你想要的模块,然后进入相应的子目录阅读 README 文件。此外,contrib/start-scripts 目录下有非常棒的启动脚本示范。由于对咱中国人来说,只需要utf8与gbk的编码转换即可,为了"减负",这里删除了许多在initdb时默认创建的转换规则,仅保留了utf8与gbk之间的转换规则。此外,加载库的搜索路径也被调整了。[TODO]测试-fprefetch-loop-arrays的效果。 代码:
详细的安装信息可以查看《Apache 2.2 中文手册》,这里就不详细解说了。[提示]--without-libtool 会导致apr编译失败;--disable-ipv6 会导致httpd和其他二进制程序编译失败。--without-ldap --without-dbm 会导致apr-util配置失败。 APR的configure脚本在--disable/enable-profile的时候都在CFLAGS中添加"-pg"(这应当是一个 bug),而如果不明确指定则添加"-g",由于"-fomit-frame-pointer"与"-pg"是冲突的,所以在CFLAGS中含有- fomit-frame-pointer的情况下使用--disable-profile会导致apr配置和编译失败。为了可以使用"-fomit- frame-pointer",这里用一个sed来确保不向CFLAGS中(实际上是不向EXTRA_CFLAGS中)添加"-pg",另外,由于看"- g"也不顺眼,顺手也去掉它。 代码:
代码:
PHP的安装比较复杂,好在官方文档提供了详尽的安装指导,请到 http://www.php.net/manual/zh/ 查看。这里安装的PHP除了核心模块(date,standard)之外,还包括下列PECL扩展:PCRE Session APC GD mbstring PostgresSQL 。PHP的测试程序不像其他软件包那样遇到错误就停下来并返回非零的错误代码,而是始终返回表示成功的零,因此不能在脚本中根据 make test 命令的返回状态判断测试的成败,你必须用眼睛亲自检查输出结果。[提示]只有使用了--enable-cli选项后才能运行测试程序。[TODO]测试" -minline-all-stringops"的效果。 代码:
此帖于 08-03-03 10:51 被 csfrank 编辑. |
|
|
|
|
|
|
|
第 10 帖 | |
|
|
结尾工作
系统清理 为了最大限度避免不必要的麻烦,这里首先简单的删除一些无用文件,存储随机数种子,然后重新启动,再使用临时工具链进行 strip 操作。 代码:
代码:
代码:
[提示]数据库的超级用户名是:pgsql,密码是:123 代码:
启动登陆(交互) shell 时会执行 /etc/profile 和 ~/.bash_profile 文件(后者的内容会覆盖前者),通常在其中定义环境变量。 启动非登录(非交互) shell 时会执行 /etc/bashrc 和 ~/.bashrc 文件(后者的内容会覆盖前者),通常在其中定义别名和函数。 习惯上一般要求 profile 额外执行 bashrc 的内容。 退出 shell 时会执行 /etc/bash_logout 和 ~/.bash_logout 文件。 代码:
出于安全考虑,需要使用md5密码(这里是"123")保护启动菜单。密码字符串可以使用宿主系统的 grub-md5-crypt 程序得到。[提示]因为simpleinit会在运行'bootprog'之前首先创建 /dev/initctl 这个FIFO,所以要先"rw"挂载根然后再在启动脚本里面remount成"ro"。 代码:
下面的脚本相当于"有网络多用户模式"的运行级别。一般来说,启动时至少要(大体上按这个顺序)做这些事情:⒈设置掩码与环境变量。⒉挂载内核文件系统。⒊加载内核模块。⒋启动Udev守护进程。⒌挂载交换分区。⒍设置各项内核参数(控制台日志等级、主机名、ctrl-alt-del、硬件时钟……)。⒎磁盘文件系统检查与挂载。⒏清理文件系统中的垃圾、创建所必要的文件和目录。⒐还原上次关机时保存的随机数。⒑设置控制台特性。⒒启动网络接口。⒓开启防火墙。⒔启动日志守护进程。⒕启动其它各项守护进程。而关闭时的动作基本上就是上述步骤的逆过程。 [提示]PostgreSQL的自动清理功能依赖于 INET socket 和 /etc/hosts ,所以必须要启动本地回环接口。 代码:
先关机: 代码:
代码:
到此为止,这个 MiniLAPP 系统全部制作完毕。现在可以关闭计算机,拿掉CDROM。 代码:
1. 使用 SSH2 客户端(PuTTY SecureCRT SecureFX ssh sftp ...)连接到 192.168.10.33:22 并使用 root 账号和密码("123")应当可以正常登陆。 2. 登陆后,首先执行"source /root/musr"将 /dev/sda5 挂载到 /usr ,然后使用 pstree 应当可以看到所有的守护进程都在运行当中。 3. 将 SSH2 客户端的字符集设为 UTF-8 ,应当可以在命令行上正常使用中文。比如创建和删除中文名称的文件和目录。 4. 在 /etc/hosts 或 C:\WINDOWS\system32\drivers\etc\hosts 中添加一条"192.168.10.33 dbadmin.oklaoshi.com"记录之后应当就可以使用 http://dbadmin.oklaoshi.com 来访问phpPgAdmin[HTTP认证的用户名和密码都是"DB_Admin"],然后应当也可以使用"pgsql"用户(密码:"123")登陆数据库。 5. 可以使用 /bin/reboot 正常重启,使用 /bin/shutdown -q -h now 正常关闭。 |
|
|
|
|
|
|
|
第 11 帖 | |
|
|
很好的帖子~~~
|
|
|
|
|
|
|
|
第 12 帖 | |
|
|
学习了,很不错的帖子
|
|
|
|
|
|
|
|
第 13 帖 | |
|
|
真是太好了。
非常感谢分享! 辛苦了。。。 |
|
|
|
|
|