SysVinit

From: LFS-BOOK Chapter 7

Linux uses a special booting facility named SysVinit that is based on a concept of run-levels. It can be quite different from one system to another, so it cannot be assumed that because things worked in one particular Linux distribution, they should work the same in LFS too. LFS has its own way of doing things, but it respects generally accepted standards.

SysVinit (which will be referred to as “init” from now on) works using a run-levels scheme. There are seven (numbered 0 to 6) run-levels (actually, there are more run-levels, but they are for special cases and are generally not used. See init(8) for more details), and each one of those corresponds to the actions the computer is supposed to perform when it starts up. The default run-level is 3. Here are the descriptions of the different run-levels as they are implemented:

0: halt the computer
1: single-user mode
2: multi-user mode without networking
3: multi-user mode with networking
4: reserved for customization, otherwise does the same as 3
5: same as 4, it is usually used for GUI login (like X's xdm or KDE's kdm)
6: reboot the computer

The command used to change run-levels is init <runlevel>, where <runlevel> is the target run-level. For example, to reboot the computer, a user could issue the init 6 command, which is an alias for the reboot command. Likewise, init 0 is an alias for the halt command.

There are a number of directories under /etc/rc.d that look like rc?.d (where ? is the number of the run-level) and rcsysinit.d, all containing a number of symbolic links. Some begin with a K, the others begin with an S, and all of them have two numbers following the initial letter. The K means to stop (kill) a service and the S means to start a service. The numbers determine the order in which the scripts are run, from 00 to 99—the lower the number the earlier it gets executed. When init switches to another run-level, the appropriate services are either started or stopped, depending on the runlevel chosen.

The real scripts are in /etc/rc.d/init.d. They do the actual work, and the symlinks all point to them. Killing links and starting links point to the same script in /etc/rc.d/init.d. This is because the scripts can be called with different parameters like start, stop, restart, reload, and status. When a K link is encountered, the appropriate script is run with the stop argument. When an S link is encountered, the appropriate script is run with the start argument.

There is one exception to this explanation. Links that start with an S in the rc0.d and rc6.d directories will not cause anything to be started. They will be called with the parameter stop to stop something. The logic behind this is that when a user is going to reboot or halt the system, nothing needs to be started. The system only needs to be stopped.

These are descriptions of what the arguments make the scripts do:

start

The service is started.

stop

The service is stopped.

restart

The service is stopped and then started again.

reload

The configuration of the service is updated. This is used after the configuration file of a service was modified, when the service does not need to be restarted.

status

Tells if the service is running and with which PIDs.

Feel free to modify the way the boot process works (after all, it is your own LFS system). The files given here are an example of how it can be done.

用 UUID 在 fstab 中挂载分区

文章来源: www.linuxgem.org

fstab 文件大家都很熟悉,Linux 在启动的时候通过 fstab 中的信息挂载各个分区,一个典型的分区条目就像这样: 

/dev/sdb5              /mnt/usb            vfat      utf8,umask=0              0 0

/dev/sda4 为需要挂载的分区,sda4 是 Linux 检测硬盘时按顺序给分区的命名,一般来讲,这个名称并不会变化,但是如果你有多块硬盘,硬盘在电脑中的顺序变化的时候,相同的名称可能代表着不同的硬盘分 区,如果你是从 USB 设备启动,与其他 USB 设备的插入顺序也会导致分区识别的困难。

这个时候 UUID 就派上用场了,UUID 全称是 Universally Unique Identifier,也就是说,每个分区有一个唯一的 UUID 值,这样就不会发生分区识别混乱的问题了。

在 fstab 中用 UUID 挂载分区,看起来向这样: 

UUID=1234-5678              /mnt/usb            vfat      utf8,umask=0              0 0

在 UUID= 后面填入分区相应的 UUID 值,就可以正确挂载分区了。

那么,我们如何知道一个分区的 UUID 呢?

有 3 种方法:

1. 通过浏览 /dev/disk/by-uuid/ 下的设备文件信息。

# ls -l /dev/disk/by-uuid/
------
lrwxrwxrwx 1 root root 10 10-13 09:14 0909-090B -> ../../sdb5
lrwxrwxrwx 1 root root 10 10-13 09:13 7c627a81-7a6b-4806-987b-b5a8a0a93645 -> ../../sda4
.....

2. 通过 vol_id 命令。

# vol_id /dev/sdb5
ID_FS_USAGE=filesystem
ID_FS_TYPE=vfat
ID_FS_VERSION=FAT32
ID_FS_UUID=0909-090B
ID_FS_UUID_ENC=0909-090B
ID_FS_LABEL=SWAP
ID_FS_LABEL_ENC=SWAP
ID_FS_LABEL_SAFE=SWAP

3. 通过 blkid 命令

# blkid /dev/sdb5
/dev/sdb5: LABEL="SWAP" UUID="0909-090B" TYPE="vfat"

通过这三种方法都可以获得分区的 UUID (黄色高亮部分),UUID 依据分区不同,长度和格式都不相同。


翻译 & 修改自: http://linux.byexamples.com/archives/321/fstab-with-uuid/

探索 /proc 目录

文章来源: www.linuxgem.org

/proc 在 Linux 中是一个比较奇妙的目录,保存了当前系统所有的详细信息,包括进程、文件系统、硬件…… 而且还可以通过 /proc 来即时修改系统中的某些参数。

你可能会认为,“文件”指的就是硬盘上保存的数据,要么是文本,要么就是二进制文件。而在 Linux 的世界中,所有的东西都可以通过文件来表示和管理,哪怕是硬件设备,也可以通过 /dev 下的设备文件来操作硬件设备。

/proc 就是这样一种文件,它并不存在于硬盘上,每当系统启动的时候,操作系统自动创建 /proc 下的内容,你可以查看这些文件的列表,但是你会发现大部分文件的大小都是 0 ,这并不奇怪,因为这些文件属于“virtual files“,也就是说,当你读取这些文件的时候,系统内核为你即时生成文件中的内容。

/proc 下的信息包括了有关硬件、进程、系统的详细信息,先看看 /proc 下大致都有啥吧:

localhost ~ # ls /proc
1      143    19218  28326  28357  28406  5630  5784  5807  79   924        diskstats    interrupts  locks    pagetypeinfo  timer_list
1013   144    19223  28327  28377  28407  5713  5785  5808  814  asound     dma          iomem       meminfo  partitions    tty
11079  18990  2      28329  28382  28796  5714  5786  5809  816  buddyinfo  driver       ioports     misc     self          uptime
11086  19060  25659  28332  28385  3      5718  5787  5861  85   bus        execdomains  irq         modules  slabinfo      version
11108  19068  28300  28334  28397  3454   5750  5798  71    88   cmdline    fb           kallsyms    mounts   stat          vmstat
139    19070  28316  28338  28400  4      5781  5800  737   882  config.gz  filesystems  kcore       mtd      swaps         zoneinfo
141    19174  28317  28342  28403  5      5782  5805  74    883  cpuinfo    fs           kmsg        mtrr     sys
142    19178  28322  28347  28404  5059   5783  5806  78    893  devices    ide          loadavg     net      sysvipc

可以看到,除了一些文件之外,更多的是一堆以数字为名称的目录,每个目录代表了系统中的一个进程,目录下是有关这个进程的详细信息,这个等下我们再说。 /proc 下还有一个 self 文件,实际上是一个连接,指向了当前运行中的进程目录。

首先我们看看 /proc 目录下一些非常有用的文件,查看这些文件的内容很简单,用 cat 命令就可以了~

/proc/cpuinfo

localhost ~ # cat /proc/cpuinfo
processor    : 0
vendor_id    : GenuineIntel
cpu family    : 15
model        : 2
model name    : Intel(R) Pentium(R) 4 CPU 2.40GHz
stepping    : 7
cpu MHz        : 2394.017
cache size    : 512 KB
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 2
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pebs bts sync_rdtsc cid xtpr
bogomips    : 4792.93
clflush size    : 64

/proc/cpuinfo 即是当前系统 cpu 的详细信息,从型号到支持的特性,如果你是多核 cpu 的话,会看到多个这样的输出。检测 cpu 的程序,也是通过 /proc/cpuinfo 来得到当前 cpu 的详细信息的。

/proc/meminfo

localhost ~ # cat /proc/meminfo
MemTotal:       514624 kB
MemFree:         10144 kB
Buffers:         20248 kB
Cached:         156248 kB
SwapCached:         60 kB
Active:         387864 kB
Inactive:        79612 kB
SwapTotal:     1052216 kB
SwapFree:      1051740 kB
Dirty:               8 kB
Writeback:           0 kB
AnonPages:      290940 kB
Mapped:          66216 kB
Slab:            25404 kB
SReclaimable:    16872 kB
SUnreclaim:       8532 kB
PageTables:       2152 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   1309528 kB
Committed_AS:   801488 kB
VmallocTotal:   515808 kB
VmallocUsed:     48176 kB
VmallocChunk:   463580 kB

/proc/meminfo 是当前系统内存的详细信息,当然,随着系统的运行,这些信息也会随时变化。像 top、free 这些可以查看当前系统内存信息的程序,就是通过读取 /proc/meminfo 来实现的。

/proc/version

localhost ~ # cat /proc/version
Linux version 2.6.24-gentoo-r2 (root@localhost) (gcc version 4.2.2 (Gentoo 4.2.2 p1.0)) #1 Wed Feb 13 22:18:22 UTC 2008

/proc/version 是当前系统的版本信息,uname 这个命令,就是通过它来得到内核版本和系统版本的。

/proc/filesystems

localhost ~ # cat /proc/filesystems
nodev    sysfs
nodev    rootfs
nodev    bdev
nodev    proc
nodev    sockfs
nodev    usbfs
nodev    pipefs
nodev    anon_inodefs
nodev    futexfs
nodev    tmpfs
nodev    inotifyfs
nodev    devpts
    reiserfs
    ext3
    ext2
nodev    ramfs
    msdos
    vfat
    iso9660
nodev    cifs
    ntfs
    udf

/proc/filesystems 为当前系统支持的文件系统列表,你可以在程序中读取这个文件,以获得当前系统对文件系统的支持信息。

上面这几个只是比较常用的,实际上 /proc 下的信息相当丰富,很多文件都可以 cat 一下看看,比如:

    * /proc/apm: APM 高级电源管理信息。
    * /proc/acpi: 目录下为 ACPI 的详细信息。 比方说, 你想知道你的笔记本电脑是否连接了电源, 你可以 cat /proc/acpi/ac_adapter/AC/state 看看结果是 "on line" 还是 "off line" 。
    * /proc/cmdline: 显示内核的启动参数,一般就是你 grub 中传入内核的那些参数,比如我的就是: root=/dev/sda9 video=uvesafb:1680x1050-32,mtrr:3,ywrap
    * /proc/loadav: 显示系统的负载,w、top 这类程序也是从此得到系统负载信息。
    * /proc/uptime: 系统自启动来所经历的秒数,uptime 程序就是从此计算出系统启动后经历的时间的。
    * /proc/devices: 系统中所有可用的字符和块设备。
    * /proc/ioports: IO 端口信息。
    * /proc/dma: 当前可用的 DMA 通道。
    * /proc/mounts: 系统当前的挂载信息。

除此之外,还有一些文件和硬件相关,比如 /proc/interrupts 为终端信息,/proc/irq 为 IRQ 信息,还有 /proc/pci、/proc/bus 等等。

现在我们来看看开始提到的那些数字目录,也就是和进程相关的目录。

如前面所说,每个数字目录都代表了一个正在运行的进程,目录的数字名就是进程的 ID,每当一个新进程启动,一个新的目录就会被创建,同理进程结束的时候,相应的目录也会消失。

让我们看看进程目录下面都有啥:

localhost / # ls /proc/11108
auxv        cmdline          cwd      exe  fdinfo  maps  mounts      oom_adj    root   stat   status  wchan
clear_refs  coredump_filter  environ  fd   limits  mem   mountstats  oom_score  smaps  statm  task

随便挑选了一个名称为 11108 的目录,在我的机子上对应的进程是 firefox-bin,让我们看看目录下这些文件都是啥:

    * cmdline: 启动进程的命令和参数。
    * cwd: 指向进程当前目录的一个连接。
    * environ: 进程所有的环境变量。
    * fd: 进程所有打开的文件描述符,目录下是一个个以数字为名称的连接,指向了进程当前正在使用的文件。
    * maps, statm, mem: 进程的内存信息。
    * stat, status: 进程的状态信息,比如查看 /proc/status 中是否含有 “Zombie”字样,来查看僵尸进程。

/proc/sys

/proc/sys 目录下不仅提供了系统某些设置信息,你还可以修改这些文件来在运行中改变系统的参数,比如,你想让别人 ping 不到你,只要:

# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

这样就可以让系统忽略所有的 ICMP 回应,别人就 ping 不到你了。

/proc/sys 下的可配置的选项很多,主要有 6 类: debug、dev、fs、kernel、net、vm,只要文件属性是可读写的,一般都对应了系统某个可以修改的参数。

不过系统重启之后参数就恢复默认值了,其实有专门的工具来修改这些参数,那就是 sysctl 和 /etc/sysctl.conf 这个配置文件,不过这不是本文的内容,感兴趣的就去搜一下吧~

如上所述,/proc 是一个强大的特殊目录,其中的文件提供了非常详细的系统信息,很多常用的程序就是从此得到系统各个方面的信息的,在你写的程序和脚本中,也可以通过 /proc 方便的获得一些系统参数,甚至修改系统的某些参数,本文只是 /proc 的一个简要的介绍,更详细的内容留给各位自己去探索吧~

制作LFS过程中各个阶段恢复工作状态的方法

文章来源: http://www.linuxsir.org/bbs/showthread.php?t=242880

前提:
  对于做过一两次LFS的朋友,想必对LFS的漫长制作时间印象深刻,特别是对机器不太好的朋友,有时候LFS的制作时间真是“可怕”,有时候不得以必须关机然后重新启动并恢复到工作状态,但对一些不太清楚LFS的工作原理的朋友,可能一时无法正确的恢复到工作状态,因此为了能成功的完成LFS,有的会开个一两天的机器不关,本人特别针对这个问题写了一些自己的经验,以下的过程全部经过测试,应该是正确的,希望能给还在LFS制作中的朋友减轻一些“痛苦”。
为了说明方便,例子采用VMWare5.0的环境下开始的,但也同样适合使用真实机器的情况,只是用真实的机器需要在相应的磁盘设备名上修改成实际的设备名。(用VMWare只是为了说明方便,VMware本身就具有暂停的功能,所以不必计较这个问题)
文章使用VMWare5.0虚拟的SCSI设备,并使用sda设备名,sda1用于swap,而sda2用于目标系统的根目录。

以下是按照LFS6.1.1-3里面的章节数写的,如果你使用的LFS-Book与下面的章节数有出入,以章节数后面的标题为准。

开始~4.4. Setting Up the Environment
从头开始好了,没什么好可惜的。

4.5. About SBUs~5.33. Stripping
从现在开始一直到第五章结束,也就是完成Stripping中间的步骤中如果重新启动的恢复步骤:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.建立工具链的链接
ln -sv $LFS/tools /
5.创建lfs用户
groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
passwd lfs
chown -v lfs $LFS/tools
chown -v lfs $LFS/sources
su - lfs
6.建立lfs用户的环境
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL PATH
EOF

source ~/.bash_profile
7.检查一下
export命令查看输出,应该是
declare -x HOME="/home/lfs"
declare -x LC_ALL="POSIX"
declare -x LFS="/mnt/lfs"
declare -x OLDPWD
declare -x PATH="/tools/bin:/bin:/usr/bin"
declare -x PS1="\\u:\\w\\\$ "
declare -x PWD="/home/lfs"
declare -x SHLVL="1"
declare -x TERM="linux"
基本上就恢复工作状态了。

6.1. Introduction
这个时候也许你想睡觉关机了,那么重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
相关知识点:
这时候已经制作好了工具链,因此可以不需要建立根目录下的tools链接了。

6.2. Mounting Virtual Kernel File Systems~6.8. Populating /dev
这个时候如果你关机或重新启动,那么重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.加载必要的文件系统
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
5.Chroot到目标系统下
chroot "$LFS" /tools/bin/env -i \
HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
/tools/bin/bash --login +h

6.9. Linux-Libc-Headers-2.6.11.2~6.37. Bash-3.0
从现在开始一直到第六章的File-4.13之前,也就是Bash-3.0结束后,这个阶段如果你关机或重新启动,那么重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.加载必要的文件系统
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
5.Chroot到目标系统下
chroot "$LFS" /tools/bin/env -i \
HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
/tools/bin/bash --login +h
6.创建/dev下的设备文件
mount -nvt tmpfs none /dev
mknod -m 622 /dev/console c 5 1
mknod -m 666 /dev/null c 1 3
mknod -m 666 /dev/zero c 1 5
mknod -m 666 /dev/ptmx c 5 2
mknod -m 666 /dev/tty c 5 0
mknod -m 444 /dev/random c 1 8
mknod -m 444 /dev/urandom c 1 9
chown -v root:tty /dev/{console,ptmx,tty}
ln -sv /proc/self/fd /dev/fd
ln -sv /proc/self/fd/0 /dev/stdin
ln -sv /proc/self/fd/1 /dev/stdout
ln -sv /proc/self/fd/2 /dev/stderr
ln -sv /proc/kcore /dev/core
mkdir -v /dev/pts
mkdir -v /dev/shm
mount -vt devpts -o gid=4,mode=620 none /dev/pts
mount -vt tmpfs none /dev/shm
6.进入编译目录
cd /sources

6.38. File-4.13~6.58. Udev-056
从现在开始一直到第六章的Udev-056完成之前,这个阶段如果你关机或重新启动,那么重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.加载必要的文件系统
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
5.Chroot到目标系统下
chroot "$LFS" /tools/bin/env -i \
HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
/bin/bash --login +h
6.创建/dev下的设备文件
mount -nvt tmpfs none /dev
mknod -m 622 /dev/console c 5 1
mknod -m 666 /dev/null c 1 3
mknod -m 666 /dev/zero c 1 5
mknod -m 666 /dev/ptmx c 5 2
mknod -m 666 /dev/tty c 5 0
mknod -m 444 /dev/random c 1 8
mknod -m 444 /dev/urandom c 1 9
chown -v root:tty /dev/{console,ptmx,tty}
ln -sv /proc/self/fd /dev/fd
ln -sv /proc/self/fd/0 /dev/stdin
ln -sv /proc/self/fd/1 /dev/stdout
ln -sv /proc/self/fd/2 /dev/stderr
ln -sv /proc/kcore /dev/core
mkdir -v /dev/pts
mkdir -v /dev/shm
mount -vt devpts -o gid=4,mode=620 none /dev/pts
mount -vt tmpfs none /dev/shm
6.进入编译目录
cd /sources

6.59. Util-linux-2.12q~6.60. About Debugging Symbols
从现在开始一直到第六章的Stripping Again之前,这个阶段如果你关机或重新启动,那么重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.加载必要的文件系统
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
5.Chroot到目标系统下
chroot "$LFS" /tools/bin/env -i \
HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
/bin/bash --login +h
6.创建/dev下的设备文件
mount -nvt tmpfs none /dev
/sbin/udevstart
mkdir -v /dev/pts
mkdir -v /dev/shm
mount -vt devpts -o gid=4,mode=620 none /dev/pts
mount -vt tmpfs none /dev/shm
6.进入编译目录
cd /sources

6.61. Stripping Again
如果现在重新启动,那么重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.加载必要的文件系统
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
5.Chroot到目标系统下
chroot $LFS /tools/bin/env -i \
HOME=/root TERM=$TERM PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/tools/bin/bash --login
6.创建/dev下的设备文件
mount -nvt tmpfs none /dev
/sbin/udevstart
mkdir -v /dev/pts
mkdir -v /dev/shm
mount -vt devpts -o gid=4,mode=620 none /dev/pts
mount -vt tmpfs none /dev/shm
6.进入编译目录
cd /sources

6.62. Cleaning Up~结束
从现在开始一直到制作结束,重新开机后回到工作状态的步骤是:
1.重新启动计算机,并从LiveCD启动
2.加载分区
export LFS=/mnt/lfs
mkdir -pv $LFS
mount /dev/sda2 $LFS
3.加载交换分区(如果不想用交换分区或者没有交换分区可跳过此步骤)
swapon /dev/sda1
4.加载必要的文件系统
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
5.Chroot到目标系统下
chroot "$LFS" /usr/bin/env -i \
HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/bin/bash --login
6.创建/dev下的设备文件
mount -nvt tmpfs none /dev
/sbin/udevstart
mkdir -v /dev/pts
mkdir -v /dev/shm
mount -vt devpts -o gid=4,mode=620 none /dev/pts
mount -vt tmpfs none /dev/shm
6.进入编译目录
cd /sources
 

VMware Workstation + LFS LiveCD + SSH

终于可以通过SSH来控制虚拟机中的LFS LiveCD Operating System了, 嘻嘻。

简述过程如下:

我的Host OS是ubuntu 8.10

1. WMware Workstation的安装应该不是问题,而且至少有一个月的试用期。

2. 下载LFS LiveCD镜像,我是从官网上下载的,下了好久。

3. 从WMware Workstation中通过镜像文件安装OS, 虚拟机的配置等可以参考:
    http://www.linuxsir.org/bbs/showthread.php?t=244052
   

    不过我在安装过程中出现键盘无法使用的问题,好在已有前人将该问题解决:
    在~/.vmware文件夹中添加config文件,内容添加:
    xkeymap.nokeycodeMap=true
    另外,不熟悉虚拟机的人可能需要注意键盘无法使用的另一个原因可能是当前active的不是客户端的操作系统,只需在客户端操作系统的窗口点击鼠标即能解决,按    Ctrl+Alt组合键则又回到主操作系统。

4. 看网上文章说,VMware Workstation下的LFS LiveCD无法安装VMware Tools, 这将导致在虚拟机中的操作非常不便,解决的方法就是通过SSH来从主操作系统连接客户端操作系统,具体方法如下:

a. 设置客户端操作系统中root的密码
b. 修改/etc/ssh/sshd_config文件, 去掉Port 22前的注释 #
c. /etc/rc.d/init.d/sshd restart  重新启动ssh服务
d. 从主操作系统中使用ssh命令连接

另外,可以使用net-setup命令来设置客户端操作系统的网络,一般LFS会自动配置好网络(我在开启虚拟机时使用的是NAT), 这样就可以通过ifconfig来查看地址.

ubuntu 安装VMware Workstation 6.5.1

在初学Linux From Scratch的过程中,无意中接触到了虚拟机,所以就去官网下载了最新的VMware Workstation.

安装过程非常简单,只需下载.bundle格式的文件,然后:
chmod a+x vmware*****.bundle
./vmware*****.bundle

因为VMware只提供30天的试用期,感觉不爽,所以就google 疯狂搜索注册码,结果终于找到一个可以用的嘻嘻:

QAXU0-TDFA3-Q2HFA-4M8N2

理解Linux的守护进程

Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户。提供这些服务的程序是由 运行在后台的守护进程(daemons)来执行的。守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事 件。他们常常在系统引导装入时启动,在系统关闭时终止。linux系统有很多守护进程,大多数服务器都是用守护进程实现的。同时,守护进程完成许多系统任 务,比如,作业规划进程crond、打印进程lqd等。有些书籍和资料也把守护进程称作:“服务”。选择运行哪些守护进程,要根据具体需求决定。

一、Linux守护进程简介


1.alsasound :Alsa声卡驱动守护程序。Alsa声卡驱动程序本来是为了 一种声卡Gravis UltraSound(GUS)而写的,该程序被证 明很优秀,于是作者就开始为一般的声卡写 驱动程序。 Alsa和OSS/Free 及OSS/Linux兼容,但是有自己的接 口,甚至比OSS优秀。
2.acpid:acpid(Advanced Configuration and Power Interface)是为替代传统的APM电源管理标准而推出的新型电源管理标准。通常笔记本电脑需要启动电源进行管理。
3.atalk:AppleTalk网络守护进程。注意不要在后台运行该程序,该程序的数据结构必须在运行其他进程前先花一定时间初始化。
4.amd: 自动安装NFS守护进程。
5.anacron:一个自动化运行任务守护进程。Red Hat Linux 随带四个自动化任务的工具:cron、 anacron、at、和 batc。当你的Linux服务器并不是全天运行,这个anacron就可以帮你执行在"crontab"设定的时间内没有执行的工作。
6.apmd:apmd(Advanced Power Management)是高级电源管理。传统的电源管理标准,对于笔记本电脑比较有用,可以了解系统的电池电量信息。并将相关信息通过syslogd 写入日志。也可以用来在电源不足时关机。
7.arptables_jf :为arptables网络的用户控制过滤的守护进程。
8.arpwatch: 记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对数据库 。
atd:at和batch命令守护进程,用户用at命令调度的任务。Batch用于在系统负荷比较低时  运行批处理任务。
9.autofs:自动安装管理进程automount,与NFS相关,依赖于NIS服务器。
10.bootparamd:引导参数服务器,为LAN上的无盘工作站提供引导所需的相关信息。
11.bluetooch:蓝牙服务器守护进程。
12.crond :cron是Unix下的一个传统程序,该程序周期地运行用户 调度的任务。比起传统的Unix版本,Linux版本添加了不少属性,而且更安全,配置更简单。类似计划任务。
13.chargen:使用tcp协议的chargen server,chargen(Character Generator  Protocol)是一种网络服务,主要功能是提供类似远程打字的功能。
14.chargen-udp:使用UDP协议的chargen server。
15.cpuspeed:监测系统空闲百分比,降低或加快CPU时钟速度和电压从而在系统空闲时将能源消耗降为最小,而在系统繁忙时最大化加快系统执行速度。
16.dhcpd:动态主机控制协议(Dynamic Host Control Protocol)的服务守护进程。
17.cups: cups(Common UNIX Printing System)是通用UNIX打印守护进程,为Linux提供第三代打印功能。
18.cups-config-daemons:cups打印系统切换守护进程。
19.cups-lpd:cups行打印守护进程。
20.daytime:使用TCP 协议的Daytime守护进程,该协议为客户机实现从远程服务器获取日期 和时间的功能。预设端口:13。
21.daytime-udp:使用UDP 协议的Daytime守护进程。
22.dc_server:使用SSL安全套接字的代理服务器守护进程。
23.dc_client:使用SSL安全套接字的客户端守护进程。
24.diskdump:服务器磁盘备份守护进程。
25.echo:服务器回显客户数据服务守护进程。
26.echo-udp:使用UDP协议的服务器回显客户数据服务守护进程。
27.eklogin:接受rlogin会话鉴证和用kerberos5加密的一种服务的守护进程。
28.gated :网关路由守护进程。它支持各种路由协议,包括RIP版本1和2、DCN HELLO协议、 OSPF版本2以及EGP版本2到4。
29.gpm:gpm(General Purpose Mouse Daemon )守护进程为文本模式下的Linux程序如mc(Midnight Commander)提供了鼠标的支持。它也支持控制台下鼠标 的拷贝,粘贴操作以及弹出式菜单。
30.gssftp: 使用kerberos 5认证的ftp守护进程
31.httpd:Web服务器Apache守护进程,可用来提供HTML文件以 及CGI动态内容服务。
32.inetd :因特网操作守护程序。监控网络对各种它管理的服务的需求,并在必要的时候启动相应的服务程序。在Redhat 和Mandrake linux中被xinetd代替。Debian, Slackware, SuSE仍然使用。
33.innd:Usenet新闻服务器守护进程。
34.iiim:中文输入法服务器守护进程。
35.iptables:iptables防火墙守护进程。
36.irda:红外端口守护进程。
37.isdn:isdn启动和中止服务守护进程。
38.krb5-telnet:使用kerberos 5认证的telnet守护进程。
39.klogin:远程登陆守护进程。
40.keytable: 该进程的功能是转载在/etc/sysconfig/keyboards里定义的键盘映射表,该表可以通过kbdconfig工具进行选择。您应该使该程序处于激活状态。
41.irqbalance:对多个系统处理器环境下的系统中断请求进行负载平衡的守护程序。如果你只安装了一个CPU,就不需要加载这个守护程序。
42.kshell :kshell守护进程。
43.kudzu: 硬件自动检测程序,会自动检测硬件是否发生变动,并相应进行硬件的添加、删除工作。当系统启动时,kudzu会对当前的硬件进行检测,并且和存储在       /etc/sysconfig/hwconf中的硬件信息进行对照,如果某个硬件从系统中被添加或者删除时,那么kudzu就会察觉到,并且通知用户是否 进行相关配置,然后修改etc/sysconfig/hwconf,使硬件资料与系统保持同步。如果/etc/sysconfig/hwconf这个文件 不存在,那么kudzu将会从/etc/modprobe.conf,/etc/sysconfig/network-scripts/和 etc/X11/XF86Config中探测已经存在的硬件。如果你不打算增加新硬件,那么就可以关闭这个启动服务,以加快系统启动时间。
44.ldap:ldap(Lightweight Directory Access Protocol)目录访问协议服务器守护进程。
45.lm_seroems:检测主板工作情况守护进程。
46.lpd :lpd是老式打印守护程序,负责将lpr等程序提交给打印 作业。
47.mdmonitor:RAID相关设备的守护程序。
48.messagebus:D-BUS是一个库,为两个或两个以上的应用程序提供一对一的通讯。 dbus-daemon-1是一个应用程序,它使用这个库来实现messagebus守护程序。多个应用程序通过连接messagebus守护程序可以实现与其他程序交换信息。
49.microcode_ctl:可编码以及发送新的微代码到内核以更新Intel IA32系列处理器守护进程。
50.mysqld: 一个快速高效可靠的轻型SQL数据库引擎守护进程。
51.named:DNS(BIND)服务器守护进程。
52.netplugd:netplugd(network cable hotplug management daemon)守护程序,用于监控一个或多个网络接口的状态,当某些事件触发时运行一个外部脚本程序。
53.netdump:远程网络备份服务器守护进程。
54.netfs:Network Filesystem Mounter,该进程安装和卸载NFS、SAMBA和NCP网络文件系统。
55.nfs:网络文件系统守护进程。
56.nfslock:NFS是一个流行的通过TCP/IP网络共享文件的协议,此守护进程提供了NFS文件锁定功能。
57.ntpd:Network time Protocol daemon(网络时间校正协议)。ntpd是用来使系统和一个精确的时间源保持时间同步的协议守护进程。
58.network:激活/关闭启动时的各个网络接口守护进程。
59.psacct:该守护进程包括几个工具用来监控进程活动的工具,包括ac,lastcomm, accton 和sa。
60.pcmcia:主要用于支持笔记本电脑接口守护进程。
61.portmap:该守护进程用来支持RPC连接,RPC被用于NFS以及NIS 等服务。
62.postgresql: PostgreSQL 关系数据库引擎。
63.proftpd: proftpd 是Unix下的一个配置灵活的ftp服务器的守护程序。
64.pppoe:ADSL连接守护进程。
65.random :保存和恢复系统的高质量随机数生成器,这些随机数是系 统一些随机行为提供的。
66.rawdevices:在使用集群文件系统时用于加载raw设备的守护进程。
67.readahead、readahead_early:readahead和readahead_early是在Fedora core 2中最新推出的两个后台运行的守护程序。其作用是在启动系统期间,将启动系统所要用到的文件首先读取到内存中,然后在内存中进行执行,以加快系统的启动速度。
68.rhnsd:Red Hat 网络服务守护进程。通知官方的安全信息以及为系统打补丁。
69.routed :该守护程序支持RIP协议的自动IP路由表维护。RIP主要 使用在小型网络上,大一点的网络就需要复杂一点的协议。
70.rsync:remote sync远程数据备份守护进程。 
71.rsh :远程主机上启动一个shell,并执行用户命令。
72.rwhod: 允许远程用户获得运行rwho守护程序的机器上所有已登录用户的列表。
73.rstatd:一个为LAN上的其它机器收集和提供系统信息的守候进程。
74.ruserd:远程用户定位服务,这是一个基于RPC的服务,它提供关于当前记录到LAN上一个机器日志中的用户信息
75.rwalld:激活rpc.rwall服务进程,这是一项基于RPC的服务,允许用户给每个注册到LAN机器上的其他终端写消息 。
76.rwhod:激活rwhod服务进程,它支持LAN的rwho和ruptime服务。
77.saslauthd: 使用SASL的认证守护进程。
78.sendmail:邮件服务器sendmail守护进程。
79.smb:Samba文件共享/打印服务守护进程。
80.snmpd:本地简单网络管理守护进程。
81.squid:代理服务器squid守护进程。
82.sshd:OpenSSH服务器守护进程。Secure Shell Protocol可以实现安全地远程管理主机。
83.smartd:Self Monitor Analysis and Reporting Technology System,监控你的硬盘是否出现故障。
84.syslog:一个让系统引导时起动syslog和klogd系统日志守候进程的脚本。
85.time :该守护进程从远程主机获取时间和日期,采用TCP协议。
86.time-udp: 该守护进程从远程主机获取时间和日期,采用UDP协议。
87.tux:在Linux内核中运行apache服务器的守护进程。
88.vsftpd:vsftpd服务器的守护进程。
89.vncserver: VNC (Virtual Network Computing,虚拟网络计算),它提供了一种在本地系统上显示远程计算机整个"桌面"的轻量型协议。
90.xfs:X Window字型服务器守护进程,为本地和远程X服务器提供字型集。
91.xinetd:支持多种网络服务的核心守护进程。
92.ypbind:为NIS(网络信息系统)客户机激活ypbind服务进程 。
93.yppasswdd:NIS口令服务器守护进程。
94.ypserv:NIS主服务器守护进程。
95.yum:RPM操作系统自动升级和软件包管理守护进程。

二、守护进程工作原理和方式


 在Client/Server模式下。服务器监听 (Listen)在一个特定的端口上等待客户连接。连接成功后服务器和客户端通过端口进行数据通信。守护进程的工作就是打开一个端口,并且等待 (Listen)进入连接。如果客户端产生一个连接请求,守护进程就创建(Fork)一个子服务器响应这个连接,而主服务器继续监听其他的服务请求。

守护进程工作方式:
(1)运行独立的守护进程
  独立运行的守护进程由init脚本负责管理,所有独立运行的守护进程的脚本在/etc/rc.d/init.d/目录下。系统服务都是独立运行的守护进程 包括:syslogd和cron等。运行独立的守护进程工作方式称作:stand-alone。它Unix传统的C/S模式的访问模式。服务器监听 (Listen)在一个特点的端口上等待客户端的联机。如果客户端产生一个连接请求,守护进程就创建(Fork)一个子服务器响应这个连接,而主服务器继 续监听。以保持多个子服务器池等待下一个客户端请求。stand-alone模式工作原理见图1。


 
                图1 stand-alone工作模式
工 作在stand-alone模式下的网络服务有route、gated。另外是大家最熟悉是Web服务器:Apache和邮件服务器Sendmail、域 名服务器Bind。因为这些负载很大服务器上,预先创子服务器,可以通过客户的服务速度。在Linux系统中通过stand-alone工作模式启动的服 务由/etc/rc.d/下面对应的运行级别当中的符号链接启动。

(2)xinetd模式
从守护进程的概念可以看出,对于系统所要通过的每一种 服务,都必须运行一个监听某个端口连接所发生的守护进程,这通常意味着资源浪费。为了解决这个问题,Linux引进了“网络守护进程服务程序”的概念。 Redhat Linux 9.0使用的网络守护进程是xinted(eXtended InterNET daemon)。和stand-alone模式相比xinted模式也称 Internet Super-Server(超级服务器)。xinetd能够同时监听多个指定的端口,在接受用户请求时,他能够根据用户请求的端口不同,启动不同的网络服 务进程来处理这些用户请求。可以把xinetd看做一个管理启动服务的管理服务器,它决定把一个客户请求交给那个程序处理,然后启动相应的守护进程。 xinetd模式工作原理见图3。


                 图3  xinetd工作模式

    和stand-alone工作模式相比,系统不想要每一个网络服务进程都监听其服务端口。运行单个xinetd就可以同时监听所有服务端口,这样就降低了 系统开销,保护系统资源。但是对于访问量大、经常出现并发访问时,xinetd想要频繁启动对应的网络服务进程,反而会导致系统性能下降。察看系统为 Linux服务提供那种模式方法在Linux命令行可以使用pstree命令可以看到两种不同方式启动的网络服务。一般来说系统一些负载高的服务: sendmail、Apache服务是单独启动的。而其他服务类型都可以使用xinetd超级服务器管理。查看目前运行的守护进程可以使用命令: “pstree”

三、守护进程管理工具


Linux提供了三种不同的守护进程管理工具:redhat-config-services、ntsysv、chkconfig,可以根据具体需要灵活运用。
(1) redhat-config-services
  redhat-config-services是一个一个图形化应用程序,它显示了每项服务的描述,以及每项服务是否在引导时启动(运行级别3、4、 5),并允许你启动、停止、或重新启动/etc/rc.d/init.d 中的哪些 SysV 服务,哪些 xinetd 服务。要从桌面启动服务配置工具,点击面板上的「主菜单」 => 「系统设置」 => 「服务器设置」 => 「服务」,或在 shell 提示下,键入命令:“redhat-config-services” (见图4)。 


  
    图4 redhat-config-services配置工具
  redhat-config-services列出了 /etc/rc.d/init.d 中的服务和由 xinetd 控制的服务。点击左侧列表中的服务名来显示该服务的简短描述以及它的服务状态。如果这个服务不是 xinetd 服务,状态窗口会显示该服务目前是否在运行。如果该服务被 xinetd 所控制,状态窗口会显示「xinetd 服务」这个短语。要立即启动、停止、或重新启动某项服务,从列表中选择该项服务,然后点击工具栏上的相应按钮(或从「行动」拉下菜单中选择行动)。如果该 服务是一个 xinetd 服务,行动按钮会被禁用,因为它们不能被单个地启动或停止。 如果你通过选择或取消选择服务名旁的复选箱来启用或禁用了 xinetd 服务,你必须从拉下菜单中选择「文件」 => 「保存改变」来重新启动 xinetd,并立即启用或禁用你所改变的 xinetd 服务。xinetd 还被配置成自动记忆设置。你可以同时启用或禁用多个 xinetd 服务,在结束后再保存改变。
(2)ntsysv
 ntsysv 工具为激活或停运服务提供了简单的界面。你可以使用 ntsysv 来启动或关闭由 xinetd 管理的服务。你还可以使用 ntsysv 来配置运行级别。按照默认设置,只有当前运行级别会被配置。要配置不同的运行级别,使用 --level 选项来指定一个或多个运行级别。譬如,命令 ntsysv --level 345 配置运行级别3、4、和5。 ntsysv 的工作界面见图1。使用上下箭头来上下查看列表。使用空格键来选择或取消选择服务,或用来“按”「确定」和「取消」按钮。要在服务列表和「确定」、「取 消」按钮中切换,使用 [Tab]键。* 标明某服务被设为启动。[F1] 键会弹出每项服务的简短描述。
(3)chkconfig
 chkconfig 命令也可以用来激活和解除服务。chkconfig --list 命令显示系统服务列表,以及这些服务在运行级别0到6中已被启动(on)还是停止(off)。chkconfig 还能用来设置某一服务在某一指定的运行级别内被启动还是被停运。譬如,要在运行级别3、4、5中停运 nfs 服务,使用下面的命令:
chkconfig --level 345 nfs off
 

四、合理选择守护进程规避安全隐患


 运行不必要或有漏洞的守护进程会给操作系统带来安全和性能上的影响。对于系统安全来说,如果操作系统中的任何一个漏洞,都可能 使整个系统受到攻击。所以,增加系统安全的最佳办法就是尽量监视系统的功能。文章开始介绍了重要的守护进程,其中“crond、syslog、 keytable、xinetd、kudzu、iptables”等是需要运行的,echo、echo-udp、daytime、daytime- udp、chargen、chargen-udp主要是做调试用,普通用户基本用不到,可以关闭。
 r字开头的守护进程:rsh、 rstatd、rsync、rusersd、rwalld这些命令都是Berkley远程命令,因为都以字母r开头,故称r*命令。主要使用来使一台计算 机上的某个用户以相同的帐户远程执行另一台计算机的一个程序。但是,r命令已经被证实存在安全风险。对于确实需要的守护进程,应该尽量选用最新的版本程 序,并增加其安全防范。 
 另外我们还要合理选择守护进程例如innd是运行新闻组服务的进程,如果用户不做Usenet服务器,应该关掉。
 
总结:
 基于开放源代码的Linux给用户提供了这样一个平台:可以根据自己的软、硬件环境,定制自己的Linux守护进程。因此,根据每个用户不同的应用范围定制应用环境,可以将Linux系统的安全和性能提升到新的高度。

 

 原文地址 http://www.pcvz.com/server/ServerYJ/server_94202.html

sysklogd 系统日志记录

概述

日志对于系统的重要性不言而喻,比如对于故障诊断和入侵检测,没有日志几乎寸步难行。Linux系统当中最流行的日志记录器是sysklogd

Sysklogd 日志记录器由两个守护进程(klogd syslogd)和一个配置文件(syslog.conf)组成。klogd 不使用配置文件,它负责截获内核消息,它既可以独立使用也可以作为 syslogd 的客户端运行。syslogd 默认使用 /etc/syslog.conf 作为配置文件,它负责截获应用程序消息,还可以截获 klogd 向其转发的内核消息。支持 internet/unix domain sockets 的特性使得这两个工具可以用于记录本地和远程的日志。

重要信息

  • syslogd 守护进程默认情况下并不从 syslog/udp 端口接受任何消息,除非在命令行上使用了"-r"选项。此外,你还应当仔细看看"-l"和"-s"命令行选项。
  • syslogd 守护进程默认情况下并不转发任何来自远程主机的消息,这是为了避免可能导致的日志无限循环。"-h"选项可以开启转发功能。
  • syslogd 会剥除来自同一个域范围内的主机中的每条消息中的本地域(local domain)信息。如果你使用了日志分析程序,请将这一特性牢记在心。
  • syslogd 不会更改任何文件的属性,所以由它创建的文件将是全局可读的。如果你不想这样(比如"auth.*"被进行了记录),你必须手动事先创建这些文件并设置相应的权限。
  • 如果某些程序发送了大量的日志消息并且导致硬盘非常忙碌,你可以考虑在每一行后面关闭fsync()特性。不过这样可能会导致系统崩溃以后丢失一些日志消息。
  • 如果你使用 init 来直接启动 klogd 或 syslogd ,那么需要在命令行上使用"-n"选项。
  • 如果 System.map 文件存在并且在 klogd 命令行上使用了"-k"的话,那么它可以解码 EIP 地址。这个特性对于诊断系统崩溃非常有用,但是你必须确保 System.map 文件正确无误。
  • 这两个守护进程都会尝试在收到退出信号时删除他们的 .pid 文件,不过如果系统崩溃或者进程被"kill -9"结束,那么可能就会来不及清理。这样,下次启动时就有可能会获得与以前残留的 .pid 文件中的进程号相同的PID,从而导致无法启动(进程号冲突)。解决这个问题的最佳方案是系统的启动脚本(rc.*)自身能够在系统启动的最初就对这些 .pid 文件进行清理(通常是清空 /var/run 目录)。
  • 大文件支持(可以写入大于 2 GB 的日志)并不是 syslogd 的功能,而是 glibc 的功能(使用不同的内核API进行调用)。要启用大文件支持,你必须将 Makefile 中的相应注释取消(两个含有"-D_FILE_OFFSET_BITS"的行中的一个)。

内核的控制台日志等级

内核的控制台日志等级控制哪些内核消息会在控制台上显示。有两种途径可以修改这个等级,不过建议的途径是通过 sysctl 来控制,通常这个设置位于 /etc/sysctl.conf 中。比如:

  kernel/printk = 4 4 1 7

安装注意事项

  1. 仔细阅读 README 和 man page 会减少你不少痛苦。目前所有文档都已经放在man page中了。
  2. 按照你的需求修改 Makefile 然后再进行编译。如果你没有认真对待第一步,那么可能会编译出不合格的二进制程序。
  3. FSSTND(Linux文件系统标准)要求二进制文件和其配置文件必须位于不同的目录。这个包默认情况下遵守FSSTND的约定。你可以通过修改 Makefile 文件和源代码来修改配置文件的位置。
  4. 建议让这两个守护进程都以root身份运行,如果你想了解更多安全方面的问题,请阅读 man page 。

下面是 Makefile 文件开头的一部分节选,这部分是在安装是可能需要改动的:

CC= gcc
SKFLAGS= $(RPM_OPT_FLAGS) -O3 -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce
# 启用大文件支持,根据你的系统是32位还是64位进行选择
# -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
# -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
# $(shell getconf LFS_SKFLAGS)
LDFLAGS= -s

# 指定 install 程序的位置
INSTALL = /usr/bin/install

# 安装目录
BINDIR = $(prefix)/usr/sbin
MANDIR = $(prefix)/usr/share/man

# 有bug报告说在一个纯 ELF 系统上需要明确指定连接到 libresolv.a 库。
# 如果你在连接 syslogd 时失败,可以试一试取消下面的注释。
# LIBS = /usr/lib/libresolv.a

# 如果你在 ALPHA 平台上连接失败,可以试一试取消下面的注释。
# LIBS = ${LIBS} -linux

# 取消下面的注释可以让 klogd 实现启动延迟,这在 klogd 和 syslogd 并行启动或启动顺序靠的非常近的时候很有用。
# KLOGD_START_DELAY = -DKLOGD_DELAY=5

# 下面的定义表示文件位置遵守FSSTND标准。
FSSTND = -DFSSTND

# 下面的定义指定了 man page 的宿主和权限。
MAN_USER = root
MAN_GROUP = root
MAN_PERMS = 644

# 下面的定义指定了 syslogd 守护进程的 .pid 文件名,
# 源代码(paths.h)中默认的文件名是"syslog.pid",但很多人认为应当叫"syslogd.pid"。
# 你可以在这里指定你喜欢的名字。
SYSLOGD_PIDNAME = -DSYSLOGD_PIDNAME=\"syslogd.pid\"

syslog.conf

syslog.conf 是 syslogd 进程的配置文件,将在程序启动时读取,默认位置是 /etc/syslog.conf 。它指定了一系列日志记录规则。规则的格式如下:

facility.level    action

这个配置文件中的空白行和以"#"开头的行将被忽略。"facility.level"部分也被称为选择符(seletor)。 seletor 和 action 之间使用一个或多个空白分隔。

选择符(seletor)

选择符由 facility 和 level 两部分组成,之间用一个句点(.)连接。这两部分将在后面 syslogd 小节中详细描述。下面提到的名字和 /usr/include/syslog.h 中的 LOG_-values 相一致。

facility 指定了产生日志的子系统,可以是下面的关键字之一:

auth		由 pam_pwdb 报告的认证活动。
authpriv	包括私有信息(如用户名)在内的认证活动
cron		与 cron 和 at 有关的信息。
daemon		与 inetd 守护进程有关的信息。
ftp		与 FTP 有关的信息
kern		内核信息,首先通过 klogd 传递。
lpr		与打印服务有关的信息。
mail		与电子邮件有关的信息
mark		syslog 内部功能用于生成时间戳
news		来自新闻服务器的信息
syslog		由 syslog 生成的信息
user		由用户程序生成的信息
uucp		由 uucp 生成的信息
local0 ~ local7	由自定义程序使用,例如使用 local5 做为 ssh 功能
*		通配符代表除了 mark 以外的所有功能

在大多数情况下,任何程序都可以通过任何 facility 发送日志消息,但是一般都遵守约定俗成的规则。比如,只有内核才能使用"kern" facility 。

level 指定了消息的优先级,可以是下面的关键字之一(降序排列,严重性越来越低):

emerg	系统不可用
alert	需要立即被修改的条件
crit	阻止某些工具或子系统功能实现的错误条件
err	阻止工具或某些子系统部分功能实现的错误条件
warning	预警信息
notice	具有重要性的普通条件
info	提供信息的消息
debug	不包含函数条件或问题的其他信息
none	没有优先级,通常用于排错
*	除了none之外的所有级别

facility 部分可以是用逗号(,)分隔的多个子系统,而多个 seletor 之间也可以通过分号(;)组合在一起。需要注意的是,多个组合在一起的选择符,后面的会覆盖前面的,这样就允许从模式中排除一些优先级。

默认将对指定级别以及更严重级别的消息进行操作,但是可以通过下面2个操作符进行修改。

等于操作符(=)表示仅对这个级别的消息进行操作,不等操作符(!)表示忽略这个级别以及更严重级别的消息。这两个操作符可以同时使用,不过"!"必须出现在"="的前面。

动作(action)

这个字段定义了对符合条件的消息进行何种操作,可以选择下列操作之一:

普通文件
将消息记录到这个文件中,必须使用绝对路径。如果在文件名之前加上减号(-),则表示不将日志信息同步刷新到磁盘上(使用写入缓存),这样可以提高日志写入性能,但是增加了系统崩溃后丢失日志的风险。
命名管道
在绝对路径表示的FIFO文件(使用mkfifo命令创建)前加上管道符号(|)即可。通常用于调试。比如:|/usr/adm/debug
终端或者控制台
比如:/dev/tty1 或 /dev/console
远程主机
syslogd 能够将消息发送到远程主机或从远程主机接收消息,不过默认并不转发接收到的消息。要将消息发送到远程主机,可以在主机名前加一个"@"即可。
逗号分隔的用户名列表
critical 级别的消息除了记录到日志之外,通常还转发到root用户。
所有当前登录的用户
如果写上一个星号(*)则表示向当前所有登录的用户显示这条消息。

实例

下面的例子来自于实践,希望能够对上面的内容做一个很好的示范以帮助理解。

              # 将所有 crit 级别的消息(排除所有内核消息)记录在 critical 文件中
              #
              *.=crit;kern.none            /var/adm/critical

              # 首先记录所有内核消息到 kernel 文件,
              # crit 级别以上的消息转发到远程同时在本地控制台也显示
              # 最后将info(包含)~err(不含)范围的内核消息记录到kernel-info文件(err和更高的级别被忽略)
              #
              kern.*                       /var/adm/kernel
              kern.crit                    @finlandia
              kern.crit                    /dev/console
              kern.info;kern.!err          /var/adm/kernel-info

              # 将恰好等于mail.info的消息显示在第12个终端(tcpd默认使用mail.info)
              #
              mail.=info                   /dev/tty12

              # 将除mail.info之外的所有mail子系统消息记录到mail文件
              #
              mail.*;mail.!=info           /var/adm/mail

              # 将所有mail.info和news.info消息记录到info文件
              #
              mail,news.=info              /var/adm/info

              # 记录所有info和notice级别的消息,来自mail子系统的除外
              #
              *.=info;*.=notice;mail.none  /var/log/messages

              # 记录所有info级别的消息,来自mail和news子系统的除外
              #
              *.=info;mail,news.none       /var/log/messages

              # 向所有登录用户通知emerg级别的消息
              #
              *.=emerg                     *

              # 将所有alert以及更高级别的消息转发到root,joey用户的终端上(如果他们已经登录)
              #
              *.alert                      root,joey

              # 将所有子系统的所有消息都发送到远程名为"finlandia"的主机
              *.*                          @finlandia

syslogd

syslogd 默认通过 /dev/log 这个 unix domain socket 来接收应用程序发送过来的消息,这个位置是由系统的基本C库决定的。

这个程序的命令行参数如下:

syslogd  [ -a socket ] [ -f config-file ] [ -h ] [ -l hostlist ] [ -m interval ]
           [ -n ] [ -p socket ] [ -r ] [ -s domainlist ] [ -v ]

参数说明:

-a socket
指定额外需要监听的 socket ,最多指定19个,可以通过修改 syslogd.c 文件中的 MAXFUNIX 宏修改这个默认值。如果你将某些进程在chroot环境下运行,那么这个选项就很有用了。
-f config-file
指定配置文件的位置,默认是 /etc/syslog.conf 。
-h
默认情况下 syslogd 并不转发它接收到的远程主机消息。指定这个选项后,进程将会把它接收到的远程主机消息转发到另一个指定的远程主机。
-l hostlist
指定一个分号(:)分隔的主机名列表,只记录这些主机的 hostname 而不是全限定域名。
-m interval
syslogd 默认每隔20分钟产生一个时间戳标记(-- MARK --)。这个选项用于修改这个默认值。设为零将关闭这个特性。
-n
避免自动作为后台进程运行。如果由 init 来直接启动和控制的话这个选项就必须使用。
-p socket
你可以指定一个 unix domain socket 来代替默认的 /dev/log [这个位置是由libc决定的]
-r
从 internet domain socket 上接收远程消息,也就是监听从514端口上进来的UDP包。 默认不接受任何远程消息。
-s domainlist
指定一个分号(:)分隔的域名列表,这些域名在记录前都会被剥除。只能指定完整的域名。比如"-s north.de"并不会剥除"satu.infodrom.north.de"的尾巴,你必须这样写才行:
-s north.de:infodrom.north.de
-v
打印版本信息后退出。

信号

在运行时,syslogd 会将自己的进程号保存在 /var/run/syslogd.pid 文件中。所以可以使用下面的命令向运行中的进程发送信号:

 kill -信号 `cat /var/run/syslogd.pid`
HUP
使得 syslogd 进程重新初始化。所有打开的文件都会被关闭,然后重新读取配置文件,重新开始记录。
TERM
安全退出
CHLD
如果当前正在向所有登录的用户发送消息,那么等待这些子进程结束。

安全问题

流氓程序可以通过向 syslogd 进程发送大量日志信息来淹没日志文件或者耗尽磁盘空间。下面是一些建议:

  1. 通过防火墙来限制仅允许某些特定的主机访问 514/UDP socket
  2. 将日志文件放在独立的分区上,这样即使磁盘满了也不会有很大的影响。
  3. ext2文件系统可以保留一定的空间仅给root用户使用。这要求将 syslogd 以非root身份运行。
  4. 禁止监听 inet domain sockets 将会减少不少风险。

相关文件

/etc/syslog.conf
syslogd的配置文件
/dev/log
默认将从这个 Unix domain socket 读取本地 syslog 消息
/var/run/syslogd.pid
包含 syslogd 进程号的文件

klogd

klogd 是一个专门截获并记录 Linux 内核消息的守护进程。其命令行语法如下:

klogd  [ -f file ] [ -iI ] [ -n ] [ -o ] [ -p ] [ -s ] [ -k file ] [ -v ] [ -x ] [ -2 ]

命令行参数说明:

-f file
将日志直接记录到指定的file中,而不是转发到 syslogd 进程。
-i
-I
要求当前正在运行的 klogd 守护进程重新装载内核符号表。
-i 用于让守护进程重新装载内核模块符号。
-I 用于让守护进程重新装载静态内核符号和内核模块符号。
-n
禁止自动后台运行,在 klogd 由 init 启动并直接被 init 控制的情况下必须使用此开关。
-o
klogd 在读取并记录所有内核消息缓冲区中的消息之后立即退出(不作为守护进程)。
-p
只要 klogd 检测到内核消息流中包含了一个 Oops 字符串,那么就重新加载内核符号表。
-s
可以通过两个途径获取内核消息: /proc 文件系统和 sys_syslog 系统调用接口。虽然两者本质上完全等价,但 klogd 会优先使用 /proc/kmsg 文件。这个开关则强制 klogd 使用系统调用获取内核消息。
-k file
将指定的 file 作为内核符号表文件,也就是System.map文件的位置。
-v
打印版本信息后退出。
-x
忽略 EIP 转换信息,这样就不需要读取 System.map 文件。
-2
当展开符号时打印两行,一行将地址转换为符号,一行是原始文本。这样就允许一些外部程序(比如ksymoops)在原始数据上做一些处理。

消息转发

如果 klogd 将内核消息转发给 syslogd 进程,那么它可以分拣出某些特定的消息。原始内核消息的格式如下:

    <[0-7]>Something said by the kernel.

尖括号中的数字表示内核消息的优先级,这些数字的定义位于 kernel.h 文件中。当 klogd 收到内核消息之后,将会读取这个数字,并在将此消息转发给 syslogd 时按照这个数字分配适当的优先级。

如果使用 -f 将内核消息直接记录到特定的文件中,那么这条消息将保持原样。

内核地址解析

klogd 会尝试将内核地址解析为对应的符号,如果你想得到原始的地址信息,那么可以使用"-2"开关。如果没有使用"-k"选项,那么将会依次尝试下面的路径:

       /boot/System.map
       /System.map
       /usr/src/linux/System.map

因为内核模块动态加载所以地址并不固定,这时就要使用"-i"/"-I"通知 klogd 内核模块的变化。这两个开关都将导致当前正在运行的 klogd 守护进程重新加载内核符号表。应当在每一次加载或者卸载内核模块后立即运行下列命令:

       klogd -i

-p 开关也可以用于更新内核符号表。它会让 klogd 在检测到保护性错误的时候重新加载内核符号表。使用这个开关需要小心,因为操作系统在出现保护性错误(protection fault)的时候已经变得不稳定了,而 klogd 必须执行系统调用才能重新装载内核符号表,所以这样做可能会导致更糟糕的结果。

控制台日志等级

内核默认的控制台日志等级是"7"(debug),也就是等级数字小于等于6的消息(优先级更高)都会显示在控制台上。这些不同等级所代表的意思位 于 kernel.h 文件内,这个包内的 syslog.h 中也有一份拷贝。可以使用 sysctl 来指定控制台日志等级,这通常是在 /etc/sysctl.conf 文件中设置的,比如下面这一行:

              kernel.printk = 4 4 1 7

就是把内核的控制台日志等级设为了"4"。

信号处理

klogd 可以响应8种信号: SIGHUP, SIGINT, SIGKILL, SIGTERM, SIGTSTP, SIGUSR1, SIGUSR2, SIGCONT 。SIGINT, SIGKILL, SIGTERM, SIGHUP 信号会让进程优雅的正常退出。SIGTSTP 信号会让进程停止记录日志并进入休眠状态;SIGCONT 信号会让处于休眠状态的进程重新开始记录日志。组合使用 SIGSTOP 和 SIGCONT 可以在不退出进程的情况下切换日志消息的来源。比如需要卸载 /proc 文件系统的时候,可以使用下面的命令:

            # kill -TSTP pid
            # umount /proc
            # kill -CONT pid

SIGUSR1 和 SIGUSR2 用于加载/重新加载内核符号表。SIGUSR1 表示重新加载内核模块的符号信息;SIGUSR2 表示同时重新加载模块和静态内核的符号信息。如果 System.map 文件位置正确,那么 SIGUSR1 信号将非常有用。特别是在内核模块改变的时候。

相关文件

/proc/kmsg
klogd 默认首选的获取内核消息的来源
/var/run/klogd.pid
保存 klogd 的 PID 的文件
/boot/System.map, /System.map, /usr/src/linux/System.map
默认搜索的内核符号表位置

来源: http://lamp.linux.gov.cn/Linux/sysklogd.html
作者: 金步国

Linux 启动流程

Linux 系统主要启动步骤:

    0. 加载BIOS(Basic Input Output System, 基本输入输出系统), 并获取第一个启动设备的代号

    1. 读取第一个启动设备的MBR 信息,启动 Boot Manager
        Linux 通常使用功能强大,配置灵活的 Grub或Lilo 作为 Boot Manager。

    2. 加载系统内核, 并尝试驱动所有硬件设备

    3. 核心启动init 进程
        init 进程是 Linux 的根进程,所有的系统进程都是它的子进程。

    4. init 进程读取 /etc/inittab 文件中的信息,并进入预设的运行级别,
        按顺序运行该运行级别对应文件夹下的脚本。脚本通常以start 参数启动,并指向一个系统中的程序。
        通常情况下, /etc/rcS.d/ 目录下的启动脚本首先被执行,然后是/etc/rcN.d/ 目录。例如您设定的运行级别为3,那么它对应的启动0目录为 /etc/rc3.d/ 。

    5. 根据 /etc/rcS.d/ 文件夹中对应的脚本启动 Xwindow 服务器 xorg
            Xwindow 为 Linux 下的图形用户界面系统。

    6. 启动登录管理器,等待用户登录
            Ubuntu 系统默认使用 GDM 作为登录管理器,您在登录管理器界面中
            输入用户名和密码后,便可以登录系统。

ps:      ubuntu系统目前已经没有/etc/inittab配置文件,而是采用upstart来启动或者停止服务,引入了事件的概念。
            init程序读取的文件是/etc/event.d

            在每一个/etc/rcX.d[X from 0 to 6]中,S开头的服务表示开机时执行,K开头的服务表示关机时停止
            所有服务启动或停止的脚本都放在/etc/init.d
           "the scripts in /etc/rcX.d are executed each time the system enters the runlevel X, and the scripts are all symbolic links where targets are locates in /etc/init.d/

            可以在/etc/rc.local中新增你想开机就启动的动作。

ubuntu bash环境设置

第一步  系统级设置

读取/etc/profile文件,再根据/etc/profile文件的内容去读取其他附件的设置文件,例如/etc/profile.d/*.sh等


第二步  个人设置

根据不同的用户,到家目录去读取~/.bash_profile或~/.bash_login或~/.profile设置文件
其中:
这三个文件通常只要一个即可,不过存在顺序上的差异:bash启动时,会先去读取~/.bash_profile,找不到时就去读取~/.bash_login,再找不到时则读取~/.profile

根据不同的用户,到家目录去读取~/.bashrc文件


所以登陆bash后,最终读取的设置文件是~/.bashrc,通常可以将个人的一些常用的alias或者PATH等环境变量或者自定义变量都写到这个文件。


ps: 可能需要注意区分login shell 与 non-login shell

A login shell is one whose first character of argument zero is a -, or one started with the --login option.

An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to the terminal , or one started with the -i option.

Login Shell: 登录的时候,你输入帐号和密码进入了,出现了shell提示符,这个过程就是登录外壳;
Interactive Shell:接下来你得到了一个像root@host />这样的提示符,你输入什么,它就解释出什么,这就是交互式外壳;
Non Interactive Shell:你可能需要学习写一个bash script,用外部shell执行:bash  script.sh,它(bash)从第一条命令执行到最后一条然后退出,不与你进行任何交互,它就是非交互式外壳

详见:

man 1 bash 之 INVOCATION

" a non-login shell, which does not read /etc/profile or ~/.bash_profile files, but rather reads the ~/.bashrc instead."

 

例子:

新建用户 lfs
useradd -s /bin/bash - lfs -m -k /dev/null lfs

在用户lfs的根目录中新建.bashrc文件,输入:
LFS=/mnt/lfs

以root身份使用命令su lfs(非登录shell)
echo $LFS
/mnt/lfs

以root身份使用命令su - lfs (登录shell)
echo $LFS