Linux 的服务管理,就是玩一玩 systemctl 这个指令!还有开机流程的管理,也就是 grub2 啰!
之前的课程介绍过 process 与 program 的差别,也谈过 PID 信息的观察,以及包括 job control 等与进程相关的数据。 本节课会继续介绍 process 管理所需要具备的 signal 信息。另外,管理员是需要管理服务的,每个服务都是需要被启动的 process。 最终会介绍开机流程到底是如何运作。
服务就是一个被启动的进程,这个进程可以常驻于内存当中提供网络连接、例行工作调度等任务,就可称为服务。
一个程序被运行触发之后会变成在内存当中的一个活动的单位,那就是进程 (process)。之前的课程介绍过 PID 与进程的观察, 本小节会继续介绍 PID 的管理方面的任务。
管理员可以通过给某进程一个信号 (signal) 去告知该进程你想要让它作什么。主要的进程信号可以使用 kill -l 或 man 7 signal 查找, 底下截取较常见的信号代号与对应内容:
至于传输 signal 则是通过 kill 这个指令。举例来说,若管理员想要直接让前一堂课介绍的 rsyslogd 这个进程重读其设置档, 而不通过服务管理的正常机制时,可以尝试如下处理方式:
[root@localhost ~]# pstree -p | grep rsyslog |-rsyslogd(6701)-+-{rsyslogd}(6708) | |-{rsyslogd}(6709) | `-{rsyslogd}(6710) [root@localhost ~]# kill -1 6701 [root@localhost ~]# tail /var/log/messages ....... May 24 14:57:37 www rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="6701" x-info="http://www.rsyslog.com"] rsyslogd was HUPed
读者可以发现在注册表出现了 rsyslogd 被要求重新读取设置档的记录 (HUPed)!而除了 PID 之外,管理员也能够使用指令名称来给予 signal, 直接通过 killall 即可。如下管理方式:
[root@localhost ~]# killall -1 rsyslogd
从 CentOS 7.x 以后,Red Hat 系列的 distribution 放弃沿用多年的 System V 开机启动服务的流程, 改用 systemd 这个启动服务管理机制~采用 systemd 的原因如下:
但是 systemd 也有许多存在的问题:
基本上, systemd 将过去所谓的 daemon 运行脚本通通称为一个服务单位 (unit),而每种服务单位依据功能来区分时,就分类为不同的类型 (type)。 基本的类型有包括系统服务、数据监听与交换的插槽档服务 (socket)、保存系统状态的快照类型、提供不同类似运行等级分类的操作环境 (target) 等等。 至于设置档都放置在底下的目录中:
也就是说,到底系统开机会不会运行某些服务其实是看 /etc/systemd/system/ 底下的设置,所以该目录底下就是一大堆链接档。而实际运行的 systemd 启动脚本设置档, 其实都是放置在 /usr/lib/systemd/system/ 底下的!
/usr/lib/systemd/system/ 内的数据主要使用扩展名来进行分类,底下尝试找出 cron 与 multi-user 这些服务的数据:
[root@localhost ~]# ll /usr/lib/systemd/system/ | grep -E '(multi|cron)' -rw-r--r--. 1 root root 284 7月 27 2015 crond.service -rw-r--r--. 1 root root 597 11月 20 2015 multipathd.service -rw-r--r--. 1 root root 492 11月 20 2015 multi-user.target drwxr-xr-x. 2 root root 4096 2月 18 02:56 multi-user.target.wants lrwxrwxrwx. 1 root root 17 2月 18 02:55 runlevel2.target -> multi-user.target lrwxrwxrwx. 1 root root 17 2月 18 02:55 runlevel3.target -> multi-user.target lrwxrwxrwx. 1 root root 17 2月 18 02:55 runlevel4.target -> multi-user.target
所以我们可以知道 crond 其实算是系统服务 (service),而 multi-user 要算是运行环境相关的类型 (target type)。根据这些扩展名的类型, 我们大概可以找到几种比较常见的 systemd 的服务类型如下:
扩展名 | 主要服务功能 |
.service | 一般服务类型 (service unit):主要是系统服务,包括服务器本身所需要的本机服务以及网络服务都是!比较经常被使用到的服务大多是这种类型! |
.socket | 内部进程数据交换的插槽服务 (socket unit): 这种类型的服务通常在监控消息传递的插槽档,当有通过此插槽档传递消息来说要链接服务时,就依据当时的状态将该用户的要求发送到对应的 daemon, 若 daemon 尚未启动,则启动该 daemon 后再发送用户的要求。 使用 socket 类型的服务一般是比较不会被用到的服务,因此在开机时通常会稍微延迟启动的时间。一般用于本机服务比较多, 例如我们的图形界面很多的软件都是通过 socket 来进行本机进程数据交换的行为。 |
.target | 运行环境类型 (target unit):其实是一群 unit 的集合,例如上面表格中谈到的 multi-user.target 其实就是一堆服务的集合~也就是说, 选择运行 multi-user.target 就是运行一堆其他 .service 或/及 .socket 之类的服务就是了! |
其中又以 .service 的系统服务类型最常见。
一般来说,服务的启动有两个阶段,一个是『开机的时候设置要不要启动这个服务』, 以及『现在要不要启动这个服务』两个阶段。 这两个阶段都可以使用 systemctl 指令来管理。systemctl 的基本语法为:
[root@localhost ~]# systemctl [command] [unit]
上表所谓的 command 主要有:
缺省的情况下, systemctl 可以列出目前系统已经启动的服务群,如下列表:
[root@localhost ~]# systemctl
UNIT LOAD ACTIVE SUB DESCRIPTION
.......
chronyd.service loaded active running NTP client/server
crond.service loaded active running Command Scheduler
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
timers.target loaded active active Timers
systemd-tmpfiles-clean.timer loaded active waiting Daily Cleanup of Temporary Directories
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
153 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
列表当中,LOAD/ACTIVE/DESCRIPTION 等意义为:
如上表显示 chronyd 为 service 的类别,下次开机会启动 (load),而现在的状态是运作中 (active running)。最底下两行显示共有 153 的 unit 显示在上面, 如果想要列出系统上还没有被列出的服务群,可以加上 --all 来继续观察。此外,我们也能够仅针对 service 的类别来观察,如下所示:
[root@localhost ~]# systemctl list-units --type=service --all
如果想要观察更详细的每个启动的数据,可以通过底下的方式来处理:
[root@localhost ~]# systemctl list-unit-files
UNIT FILE STATE
proc-sys-fs-binfmt_misc.automount static
dev-hugepages.mount static
.......
mdadm-last-resort@.timer static
systemd-readahead-done.timer static
systemd-tmpfiles-clean.timer static
unbound-anchor.timer disabled
368 unit files listed.
Linux 缺省的操作画面可以是纯文本也能够是文本加上图形界面。早期的 systemV 系统称文本界面为 runlevel 3 而图形界面为 runlevel 5。 systemd 提供多种的操作界面,主要是通过『 target 』这种 unit 来作为规范。读者可以使用如下的指令来观察所有的 target:
[root@localhost ~]# systemctl list-units --type=target --all
在 CentOS 7 底下常见的操作界面 (target unit) 有底下几种:
而上述的操作模式中,缺省的是 multi-user 与 graphical 这两种。其实这些模式彼此之间还是有相依性的,读者可以使用如下的方式查出来 graphical 运行前, 有哪些 target 需要被运行:
[root@localhost ~]# systemctl list-dependencies graphical.target
graphical.target
● ├─.......
● └─multi-user.target
● ├─.......
● ├─basic.target
● │ ├─.......
● │ ├─sockets.target
● │ │ └─.......
● │ ├─sysinit.target
● │ │ ├─.......
● │ │ ├─local-fs.target
● │ │ │ └─.......
● │ │ └─swap.target
● │ │ └─.......
● │ └─timers.target
● │ └─.......
● ├─getty.target
● │ └─.......
● ├─nfs-client.target
● │ └─.......
● └─remote-fs.target
● └─nfs-client.target
● └─.......
上述的表格已经精简化过,仅保留了 unit=target 的项目,从里面读者也能够发现到要运行 graphical 之前,还得需要其他的 target 才行。 若须取得目前的操作界面,可以使用如下的方式来处理:
[root@localhost ~]# systemctl get-default
graphical.target
若需要设置缺省的操作界面,例如将原本的图形界面改为文本界面的操作方式时,可以使用如下的方式来处理:
[root@localhost ~]# systemctl set-default multi-user.target Removed symlink /etc/systemd/system/default.target. Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target. [root@localhost ~]# systemctl get-default multi-user.target
如此即可将文本界面设置为缺省的操作环境。上述的作法是开机时才进行的缺省操作环境界面,若需要即时将图形界面改为文本界面, 或者反过来处理时,可以使用如下的方式来处置:
[root@localhost ~]# systemctl isolate multi-user.target
如果是网络服务,一般都会启动监听界面在 TCP 或 UDP 的封包端口口上。取得目前监听的端口口可以使用如下的方式:
[root@localhost ~]# netstat -tlunp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 1452/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 29941/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 29938/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 30092/master
tcp6 0 0 :::22 :::* LISTEN 29941/sshd
tcp6 0 0 ::1:631 :::* LISTEN 29938/cupsd
tcp6 0 0 ::1:25 :::* LISTEN 30092/master
udp 0 0 0.0.0.0:53273 0.0.0.0:* 29287/avahi-daemon:
udp 0 0 192.168.122.1:53 0.0.0.0:* 1452/dnsmasq
udp 0 0 0.0.0.0:67 0.0.0.0:* 1452/dnsmasq
udp 0 0 0.0.0.0:5353 0.0.0.0:* 29287/avahi-daemon:
udp 0 0 0.0.0.0:514 0.0.0.0:* 29256/rsyslogd
udp6 0 0 :::514 :::* 29256/rsyslogd
重点在 Local Address 那一行,会显示该服务是启动在本机的哪一个 IP 界面的哪一个端口口上,如此管理员即可了解启动该端口口的服务是哪一个。 若无须该网络服务,则可以将该进程关闭。以上述表格来说,如果需要关闭 avahi-daemon 以及 cupsd 时,可以使用如下的方式取得服务名称:
[root@localhost ~]# systemctl list-unit-files | grep -E '(avahi|cups)'
cups.path enabled
avahi-daemon.service enabled
cups-browsed.service disabled
cups.service enabled
avahi-daemon.socket enabled
cups.socket enabled
若需要将其关闭,则应该使用如下的方式,将『目前』与『缺省』的服务启动都关闭才行:
[root@localhost ~]# systemctl stop avahi-daemon.service avahi-daemon.socket [root@localhost ~]# systemctl stop cups.path cups.service cups.socket [root@localhost ~]# systemctl disable avahi-daemon.service avahi-daemon.socket [root@localhost ~]# systemctl disable cups.path cups.service cups.socket [root@localhost ~]# netstat -tlunp
读者将可发现到 avahi-daemon 以及 cupsd 的服务已经被关闭。而若需要启动某个网络服务,则需要了解到该服务是由哪一个软件所启动的, 该软件需要先安装后才可以启动该服务。
系统如果出错,可能需要进入救援模式才能够处理相关的任务。但如何进入救援模式?这就需要从开机流程分析来下手。
一般正常的情况下, Linux 的开机流程会是如下所示:
如上,读者们可以发现内核文件驱动系统完成后,接下来就是 systemd 的任务,也就是前一小节所探讨的内容。但内核文件在哪里? 以及如何设置不同的内核文件开机,那就是开机管理程序的任务了。
系统的内核大多放置于 /boot/vmlinuz* 开头的文件中,而 initramfs 则放置于 /boot/initramfs* 。 至于内核的模块则放置于 /lib/modules/$(uname -r)/ 目录内。
目前系统上面已经加载的模块,可以使用底下的方式来观察:
[root@localhost ~]# lsmod [root@localhost ~]# lsmod | grep xfs
找到名为 xfs 的模块后,若想了解该模块的功能,可以使用如下的方式查找:
[root@localhost ~]# modinfo xfs
filename: /lib/modules/3.10.0-327.el7.x86_64/kernel/fs/xfs/xfs.ko
license: GPL
description: SGI XFS with ACLs, security attributes, no debug enabled
author: Silicon Graphics, Inc.
alias: fs-xfs
rhelversion: 7.2
srcversion: 978077FBDF054363971A9EE
depends: libcrc32c
intree: Y
vermagic: 3.10.0-327.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: 79:AD:88:6A:11:3C:A0:22:35:26:33:6C:0F:82:5B:8A:94:29:6A:B3
sig_hashalgo: sha256
若想要加载某个模块,就使用 modprobe 来加载,卸载则使用 modprobe -r 来卸载即可。
某些情况下,你会需要更动内核参数。而缺省的内核参数字于 /proc/sys/ 底下。一般不建议用户直接使用手动修改方式处理 /proc 内的文件 (因为下次开机就不会持续提供),应使用修改 /etc/sysctl.conf 来处理。举例而言,若你的 server 不想要回应 ping 的封包, 则可以如此测试:
[root@localhost ~]# ping -c 2 localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.050 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.049 ms --- localhost ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.049/0.049/0.050/0.007 ms [root@localhost ~]# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all [root@localhost ~]# ping -c 2 localhost PING localhost (127.0.0.1) 56(84) bytes of data. --- localhost ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 999ms [root@localhost ~]# echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all
读者可以发现 icmp 确实不会回应 ping 的要求了。而这个设置值如果一定要每次开机都生效, 可以写入 sysctl.conf 内,写法为:
[root@localhost ~]# vim /etc/sysctl.conf net.ipv4.icmp_echo_ignore_all = 1 [root@localhost ~]# sysctl -p [root@localhost ~]# cat /proc/sys/net/ipv4/icmp_echo_ignore_all 1
如此则可以每次都生效了。不过,这个功能对于内部环境的测试还是很重要的,因此还是请修订回来比较妥当。
内核的加载与设置是由开机管理程序来处理的,而 CentOS 7 缺省的开机管理程序为 grub2 这一个软件。该软件的优点包括有:
开机时,数据得从磁盘读出,因此磁盘、分区的代号信息得先要了解厘清才行。 grub2 对磁盘的代号定义如下:
(hd0,1) # 一般的缺省语法,由 grub2 自动判断分割格式 (hd0,msdos1) # 此磁盘的分割为传统的 MBR 模式 (hd0,gpt1) # 此磁盘的分割为 GPT 模式
所以说,整个硬盘代号为:
硬盘搜索顺序 | 在 Grub2 当中的代号 |
第一颗(MBR) | (hd0) (hd0,msdos1) (hd0,msdos2) (hd0,msdos3).... |
第二颗(GPT) | (hd1) (hd1,gpt1) (hd1,gpt2) (hd1,gpt3).... |
第三颗 | (hd2) (hd2,1) (hd2,2) (hd2,3).... |
基本上,开机时 grub2 会去读取的设置档就是 grub.cfg 这个文件,但是这个文件是由系统程序分析创建的,不建议读者们手动修改。 因此底下读者先观察该文件内容即可,先不要修订。
[root@localhost ~]# cat /boot/grub2/grub.cfg ### BEGIN /etc/grub.d/00_header ### set pager=1 if [ -s $prefix/grubenv ]; then load_env fi ....... if [ x$feature_timeout_style = xy ] ; then set timeout_style=menu set timeout=5 # Fallback normal timeout code in case the timeout_style feature is # unavailable. else set timeout=5 fi ### END /etc/grub.d/00_header ### ### BEGIN /etc/grub.d/00_tuned ### set tuned_params="" ### END /etc/grub.d/00_tuned ### ### BEGIN /etc/grub.d/01_users ### if [ -f ${prefix}/user.cfg ]; then source ${prefix}/user.cfg if [ -n ${GRUB2_PASSWORD} ]; then set superusers="root" export superusers password_pbkdf2 root ${GRUB2_PASSWORD} fi fi ### END /etc/grub.d/01_users ### ### BEGIN /etc/grub.d/10_linux ### menuentry 'CentOS Linux (3.10.0-327.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-327.el7.x86_64-advanced-fb871e94-6242-48c9-82ee-3c2df02a070e' { load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod xfs set root='hd0,gpt2' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint='hd0,gpt2' ..... else search --no-floppy --fs-uuid --set=root a026bf1c-3028-4962-88e3-cd92c6a2a877 fi linux16 /vmlinuz-3.10.0-327.el7.x86_64 root=/dev/mapper/centos-root ro rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8 initrd16 /initramfs-3.10.0-327.el7.x86_64.img } ....... ### END /etc/grub.d/10_linux ### ....... ### BEGIN /etc/grub.d/40_custom ### # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. ### END /etc/grub.d/40_custom ###
上表中 menuentry 后面接的就是菜单的的标题与实际的内容了。而该内容比较重要的项目有:
基本上,修改 grub2 设置档你可以在如下的位置进行:
主要环境设置内容为:
[root@www ~]# cat /etc/default/grub GRUB_TIMEOUT=5 # 指定缺省倒数读秒的秒数 GRUB_DEFAULT=saved # 指定缺省由哪一个菜单来开机,缺省开机菜单之意 GRUB_DISABLE_SUBMENU=true # 是否要隐藏次菜单,通常是藏起来的好! GRUB_TERMINAL_OUTPUT="console" # 指定数据输出的终端机格式,缺省是通过文本终端机 GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet" # 就是在 menuentry 括号内的 linux16 项目后续的内核参数 GRUB_DISABLE_RECOVERY="true" # 取消救援菜单的制作
若有修改上述文件,则需要使用 grub2-mkconfig -o /boot/grub2/grub.cfg 来进行修订。现在假设:
那应该要如何处理 grub.cfg 呢?基本上,你应该要修订 /etc/default/grub 的内容如下:
[root@localhost ~]# vim /etc/default/grub GRUB_TIMEOUT=40 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=0 GRUB_TIMEOUT_STYLE=menu GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet elevator=deadline" GRUB_DISABLE_RECOVERY="true"
修改完毕之后再来则是进行输出修订的任务:
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-327.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-327.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-741c73b552ed495d92a024bc7a9768cc
Found initrd image: /boot/initramfs-0-rescue-741c73b552ed495d92a024bc7a9768cc.img
done
若想要知道是否完整的变更了,请 vim /boot/grub2/grub.cfg 查阅相关设置值是否变更即可。
grub2-mkconfig 运行之后会去分析 /etc/grub.d/* 里面的文件,然后运行该文件来建置 grub.cfg。至于 /etc/grub.d/ 目录底下会有这些文件存在:
所以,一般来说,我们会更动到的就是仅有 40_custom 这个文件即可。那这个文件内容也大多在放置管理员自己想要加进来的菜单项目就是了。 好了,那问题来了,我们知道 menuentry 就是一个菜单,那后续的项目有哪些东西呢?简单的说,就是这个 menuentry 有几种常见的设置? 亦即是 menuentry 的功能啦!常见的有这几样:
基本上如果是 Linux 的内核要直接被用来开机,那么你应该要通过 grub2-mkconfig 去抓 10_linux 这个脚本直接制作即可,因此这个部份你不太需要记忆! 因为在 grub.cfg 当中就已经是系统能够捉到的正确的内核开机菜单了!不过如果你有比较特别的参数需要进行呢?这时候你可以这样作: (1)先到 grub.cfg 当中取得你要制作的那个内核的菜单项目,然后将它拷贝到 40_custom 当中 (2)再到 40_custom 当中依据你的需求修改即可。
这么说或许你很纳闷,我们来做个实际练习好了:
[root@study ~]# vim /etc/grub.d/40_custom menuentry 'My graphical CentOS, with Linux 3.10.0-229.el7.x86_64' --class rhel fedora --class gnu-linux --class gnu --class os --unrestricted --id 'mygraphical' { load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod xfs set root='hd0,gpt2' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint='hd0,gpt2' 94ac5f77-cb8a-495e-a65b-... else search --no-floppy --fs-uuid --set=root 94ac5f77-cb8a-495e-a65b-2ef7442b837c fi linux16 /vmlinuz-3.10.0-229.el7.x86_64 root=/dev/mapper/centos-root ro rd.lvm.lv= centos/root rd.lvm.lv=centos/swap crashkernel=auto rhgb quiet elevator=deadline systemd.unit=graphical.target initrd16 /initramfs-3.10.0-229.el7.x86_64.img } # 请注意,上面的数据都是从 grub.cfg 里面拷贝过来的,增加的项目仅有特殊字体的部份而已! # 同时考量画面宽度,该项目稍微被变动过,请依据您的环境来设置喔! [root@study ~]# grub2-mkconfig -o /boot/grub2/grub.cfg当你再次 reboot 时,系统就会多出一个菜单给你选择了!而且选择该菜单之后,你的系统就可以直接进入图形界面 (如果有安装相关的 X window 软件时), 而不必考量 default.target 是啥东西了!了解乎?
所谓的 chain loader (开机管理程序的链结) 仅是在将控制权交给下一个 boot loader 而已, 所以 grub2 并不需要认识与找出 kernel 的文件名 ,『 他只是将 boot 的控制权交给下一个 boot sector 或 MBR 内的 boot loader 而已 』 所以通常他也不需要去查验下一个 boot loader 的文件系统!
一般来说, chain loader 的设置只要两个就够了,一个是预计要前往的 boot sector 所在的分区代号, 另一个则是设置 chainloader 在那个分区的 boot sector (第一个磁区) 上!假设我的 Windows 分区在 /dev/sda1 ,且我又只有一颗硬盘,那么要 grub 将控制权交给 windows 的 loader 只要这样就够了:
menuentry "Windows" { insmod chain # 你得要先加载 chainloader 的模块对吧? insmod ntfs # 建议加入 windows 所在的文件系统模块较佳! set root=(hd0,1) # 是在哪一个分区~最重要的项目! chainloader +1 # 请去 boot sector 将 loader 软件读出来的意思! }
通过这个项目我们就可以让 grub2 交出控制权了!
[root@study ~]# fdisk -l /dev/vda
Device Boot Start End Blocks Id System
/dev/vda1 2048 10487807 5242880 83 Linux
/dev/vda2 * 10487808 178259967 83886080 7 HPFS/NTFS/exFAT
/dev/vda3 178259968 241174527 31457280 83 Linux
其中 /dev/vda2 使用是 windows 7 的操作系统。现在我需要增加两个开机选项,一个是取得 windows 7 的开机菜单,一个是回到 MBR 的缺省环境,应该如何处理呢?
[root@study ~]# vim /etc/grub.d/40_custom menuentry 'Go to Windows 7' --id 'win7' { insmod chain insmod ntfs set root=(hd0,msdos2) chainloader +1 } menuentry 'Go to MBR' --id 'mbr' { insmod chain set root=(hd0) chainloader +1 } [root@study ~]# grub2-mkconfig -o /boot/grub2/grub.cfg另外,如果每次都想要让 windows 变成缺省的开机选项,那么在 /etc/default/grub 当中设置好『 GRUB_DEFAULT=win7 』 然后再次 grub2-mkconfig 这样即可啦!不要去算 menuentry 的顺序喔!通过 --id 内容来处理即可!
一般来说,如果是文件系统错误,或者是某些开机过程中的问题,我们可以通过开机时进入 grub2 的交互界面中, 在 linux16 的字段,加入 rd.break 或者是 init=/bin/bash 等方式来处理即可。但是,如果是 grub2 本身就有问题, 或者是根本就是内核错误,或者是 initramfs 出错时,那就无法通过上述的方式来处理了。
在 CentOS 7 的操作经验中,在升级内核时,偶而会有 initramfs 制作错误的情况导致新内核无法开机的问题。 此时,若你已经没有保留旧的内核,此时就无法顺利开机了。
要处理这个问题,最常见的就是通过『原版光盘开机,然后使用救援模式 (rescue) 来自动侦测硬盘系统, 再通过 chroot 的动作,同时使用 dracut 来重建 initramfs 』即可。
sh4.2# grep init /boot/grub2/grub.cfg initrd16 /initramfs-3.10.0-514.el7.x86_64.img initrd16 /initramfs-0-rescue-741c73b552ed495d92a024bc7a9768cc.img上面那个 initramfs-3.10.0-514.el7.x86_64.img 就是等等我们需要创建的文件名了!
sh4.2# dracut -v /boot/initramfs-3.10.0-514.el7.x86_64.img 3.10.0-514.el7.x86_64 sh4.2# touch /.autorelabel sh4.2# exit sh4.2# reboot当然,你也可以选择其他的内核,来开机,不过我们这里就使用缺省内核即可。这样应该就可以救援你的系统了! 这个光盘救援的步骤最好能够多操作几次,偶而它会是你的救命符!
前置动作:请使用 unit13 的硬盘进入作业环境,并请先以 root 身分运行 vbird_book_setup_ip 指令设置好你的学号与 IP 之后,再开始底下的作业练习。
请使用 root 的身份进行如下实做的任务。直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。
作业结果传输:请以 root 的身分运行 vbird_book_check_unit 指令上传作业结果。 正常运行完毕的结果应会出现【XXXXXX;aa:bb:cc:dd:ee:ff;unitNN】字样。若需要查阅自己上传数据的时间, 请在操作系统上面使用: http://192.168.251.250 检查相对应的课程文件。