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 檢查相對應的課程檔案。