# Installing multiple kernel versions on SLES 15
## Preface
SUSE Linux Enterprise Server 支援同時安裝多個 Kernel 版本。安裝第二個 Kernel 時,會自動建立啟動項目和 initrd,因此無需進一步手動設定。重新啟動電腦時,新加入的核心可作為附加啟動參數。
在 SLES 12 以後的版本,預設都有啟用安裝多版本的 Kernel 軟體套件。
## 1. Enabling and configuring multiversion support
### 1.1. 檢查設定
```bash!
$ sudo cat /etc/zypp/zypp.conf | grep "^multi"
```
執行結果如下 :
```
multiversion = provides:multiversion(kernel)
multiversion.kernels = latest,latest-1,running
```
> - `multiversion = provides:multiversion(kernel)`
> - 這行的開頭沒有註解,代表作業系統在升級 Kernel 時會保留多版本的 Kernel。
> - 如果把這行註解掉,再升級 Kernel 的時候,就會把舊的 Kernel 刪除。
> - `multiversion.kernels = latest,latest-1,running`
> - 保留最後兩個 Kernel 版本和目前正在運行的 Kernel。(在大部分的情況下就是只保留前一版的 Kernel)
> - `latest` : keep the kernel with the highest version number
> - `running` : keep the running kernel
> - `latest` 和 `running` 的版本基本上會是一樣的。
> - `latest-N` : keep the kernel with the Nth highest version number
> - 如果把這行註解掉,但上面那行有設定,代表所有的 Kernel 版本都會被保留。
## 2. 設定保留要保留前三版的 Kernel
```bash!
$ sudo nano /etc/zypp/zypp.conf
```
要更改的設定如下 :
```bash!
## 新增 latest-2, latest-3
multiversion.kernels = latest,latest-1,latest-2,latest-3,running
```
## 3. 實測升級 Kernel 版本並保留 3 份舊版本的 Kernel
### 3.1. 檢查有哪些可升級的 Kernel
```bash!
# 1. 檢查當前 Kernel 版本
$ uname -r
5.3.18-57-default
# 2. 查看可升級的 Kernel 版本
$ sudo zypper se -s 'kernel-default' 2> /dev/null | cut -d "|" -f 2,4
...
Loading repository data...
Reading installed packages...
Name | Version
---+----------------------+------------+
kernel-default | 5.3.18-150300.59.161.1
kernel-default | 5.3.18-150300.59.158.1
kernel-default | 5.3.18-150300.59.153.2
kernel-default | 5.3.18-150300.59.150.1
kernel-default | 5.3.18-150300.59.147.2
kernel-default | 5.3.18-150300.59.144.1
kernel-default | 5.3.18-150300.59.141.2
kernel-default | 5.3.18-150300.59.138.1
kernel-default | 5.3.18-150300.59.133.1
...
$ ls /boot | grep 57
config-5.3.18-57-default
initrd-5.3.18-57-default
initrd-5.3.18-57-default-kdump
symvers-5.3.18-57-default.gz
sysctl.conf-5.3.18-57-default
System.map-5.3.18-57-default
vmlinux-5.3.18-57-default.gz
vmlinuz-5.3.18-57-default
```
### 3.2. 升級 Kernel 到指定版本
```bash!
# 1. 安裝 5.3.18-150300.59.49.1 版本的 Kernel
$ sudo zypper in kernel-default-5.3.18-150300.59.49.1
# 2. 重新開機
$ sudo init 6
# 3. 檢查 Kernel 版本
$ uname -r
5.3.18-150300.59.49-default
# 4. 檢查是否有保留上一版的 Kernel
$ ls /boot/ | grep 57
config-5.3.18-57-default
initrd-5.3.18-57-default
initrd-5.3.18-57-default-kdump
symvers-5.3.18-57-default.gz
sysctl.conf-5.3.18-57-default
System.map-5.3.18-57-default
vmlinux-5.3.18-57-default.gz
vmlinuz-5.3.18-57-default
$ sudo cat /boot/grub2/grub.cfg | grep 57
menuentry 'SLES 15-SP3, with Linux 5.3.18-57-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-57-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-57-default ...'
linux /boot/vmlinuz-5.3.18-57-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-57-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-57-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-57-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-57-default ...'
linux /boot/vmlinuz-5.3.18-57-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-57-default
```
### 3.3. 第二次升級 Kernel 到指定版本
```bash!
# 1. 安裝 5.3.18-150300.59.63.1 版本的 Kernel
$ sudo zypper in kernel-default-5.3.18-150300.59.63.1
# 2. 重新開機
$ sudo init 6
# 3. 檢查 Kernel 版本
$ uname -r
5.3.18-150300.59.63-default
# 4. 檢查是否有保留上上一版的 Kernel
$ ls /boot/ | grep 57
config-5.3.18-57-default
initrd-5.3.18-57-default
initrd-5.3.18-57-default-kdump
symvers-5.3.18-57-default.gz
sysctl.conf-5.3.18-57-default
System.map-5.3.18-57-default
vmlinux-5.3.18-57-default.gz
vmlinuz-5.3.18-57-default
$ sudo cat /boot/grub2/grub.cfg | grep 57
menuentry 'SLES 15-SP3, with Linux 5.3.18-57-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-57-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-57-default ...'
linux /boot/vmlinuz-5.3.18-57-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-57-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-57-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-57-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-57-default ...'
linux /boot/vmlinuz-5.3.18-57-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-57-default
# 5. 檢查是否有保留上一版的 Kernel
$ ls /boot/ | grep 49
config-5.3.18-150300.59.49-default
initrd-5.3.18-150300.59.49-default
initrd-5.3.18-150300.59.49-default-kdump
symvers-5.3.18-150300.59.49-default.gz
sysctl.conf-5.3.18-150300.59.49-default
System.map-5.3.18-150300.59.49-default
vmlinux-5.3.18-150300.59.49-default.gz
vmlinuz-5.3.18-150300.59.49-default
$ sudo cat /boot/grub2/grub.cfg | grep 49
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.49-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.49-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.49-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.49-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-150300.59.49-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.49-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.49-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.49-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.49-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-150300.59.49-default
```
### 3.3. 第三次升級 Kernel 到指定版本
```bash!
# 1. 安裝 5.3.18-150300.59.109.1 版本的 Kernel
$ sudo zypper in kernel-default-5.3.18-150300.59.109.1
# 2. 重新開機
$ sudo init 6
# 3. 檢查 Kernel 版本
$ uname -r
5.3.18-150300.59.109-default
# 4. 檢查是否有保留最原始的 Kernel
$ ls /boot/ | grep 57
config-5.3.18-57-default
initrd-5.3.18-57-default
initrd-5.3.18-57-default-kdump
symvers-5.3.18-57-default.gz
sysctl.conf-5.3.18-57-default
System.map-5.3.18-57-default
vmlinux-5.3.18-57-default.gz
vmlinuz-5.3.18-57-default
$ sudo cat /boot/grub2/grub.cfg | grep 57
menuentry 'SLES 15-SP3, with Linux 5.3.18-57-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-57-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-57-default ...'
linux /boot/vmlinuz-5.3.18-57-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-57-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-57-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-57-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-57-default ...'
linux /boot/vmlinuz-5.3.18-57-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-57-default
# 5. 檢查是否有保留第一次升級後的 Kernel
$ ls /boot/ | grep 49
config-5.3.18-150300.59.49-default
initrd-5.3.18-150300.59.49-default
initrd-5.3.18-150300.59.49-default-kdump
symvers-5.3.18-150300.59.49-default.gz
sysctl.conf-5.3.18-150300.59.49-default
System.map-5.3.18-150300.59.49-default
vmlinux-5.3.18-150300.59.49-default.gz
vmlinuz-5.3.18-150300.59.49-default
$ sudo cat /boot/grub2/grub.cfg | grep 49
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.49-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.49-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.49-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.49-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-150300.59.49-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.49-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.49-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.49-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.49-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-150300.59.49-default
# 6. 檢查是否保留第二次升級後的 Kernel
$ ls /boot/ | grep 63
config-5.3.18-150300.59.63-default
initrd-5.3.18-150300.59.63-default
initrd-5.3.18-150300.59.63-default-kdump
symvers-5.3.18-150300.59.63-default.gz
sysctl.conf-5.3.18-150300.59.63-default
System.map-5.3.18-150300.59.63-default
vmlinux-5.3.18-150300.59.63-default.gz
vmlinuz-5.3.18-150300.59.63-default
$ sudo cat /boot/grub2/grub.cfg | grep '59.63'
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.63-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.63-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.63-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.63-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-150300.59.63-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.63-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.63-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.63-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.63-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-150300.59.63-default
```
### 3.4. 第四次升級 Kernel 到指定版本
```bash!
# 1. 安裝 5.3.18-150300.59.147.2 版本的 Kernel
$ sudo zypper in kernel-default-5.3.18-150300.59.147.2
# 2. 重新開機
$ sudo init 6
# 3. 檢查 Kernel 版本
$ uname -r
5.3.18-150300.59.147-default
# 4. 檢查原始的 Kernel 版本是否被刪除
$ ls /boot/ | grep 57
$ sudo cat /boot/grub2/grub.cfg | grep '57'
# 5. 檢查第一次升級的 Kernel 版本是否保留
$ ls /boot/ | grep 49
config-5.3.18-150300.59.49-default
initrd-5.3.18-150300.59.49-default
initrd-5.3.18-150300.59.49-default-kdump
symvers-5.3.18-150300.59.49-default.gz
sysctl.conf-5.3.18-150300.59.49-default
System.map-5.3.18-150300.59.49-default
vmlinux-5.3.18-150300.59.49-default.gz
vmlinuz-5.3.18-150300.59.49-default
$ sudo cat /boot/grub2/grub.cfg | grep 49
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.49-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.49-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.49-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.49-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-150300.59.49-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.49-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.49-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.49-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.49-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-150300.59.49-default
# 6. 檢查第二次升級的 Kernel 版本是否保留
$ ls /boot/ | grep 63
config-5.3.18-150300.59.63-default
initrd-5.3.18-150300.59.63-default
initrd-5.3.18-150300.59.63-default-kdump
symvers-5.3.18-150300.59.63-default.gz
sysctl.conf-5.3.18-150300.59.63-default
System.map-5.3.18-150300.59.63-default
vmlinux-5.3.18-150300.59.63-default.gz
vmlinuz-5.3.18-150300.59.63-default
$ sudo cat /boot/grub2/grub.cfg | grep '59.63'
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.63-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.63-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.63-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.63-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-150300.59.63-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.63-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.63-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.63-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.63-default root=/dev/mapper/system-root ${extra_cmdline}
initrd /boot/initrd-5.3.18-150300.59.63-default
# 7. 檢查第三次升級的 Kernel 版本是否保留
$ ls /boot | grep 109
config-5.3.18-150300.59.109-default
initrd-5.3.18-150300.59.109-default
initrd-5.3.18-150300.59.109-default-kdump
symvers-5.3.18-150300.59.109-default.gz
sysctl.conf-5.3.18-150300.59.109-default
System.map-5.3.18-150300.59.109-default
vmlinux-5.3.18-150300.59.109-default.gz
vmlinuz-5.3.18-150300.59.109-default
$ sudo cat /boot/grub2/grub.cfg | grep 109
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.109-default' --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.109-default-advanced-6500a139-6f62-4060-b6fe-c6314ddc9ab5' { echo 'Loading Linux 5.3.18-150300.59.109-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.109-default root=/dev/mapper/system-root ${extra_cmdline} splash=silent mitigations=auto quiet crashkernel=195M,high crashkernel=72M,low
initrd /boot/initrd-5.3.18-150300.59.109-default
menuentry 'SLES 15-SP3, with Linux 5.3.18-150300.59.109-default (recovery mode)' --hotkey=1 --class sles --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.3.18-150300.59.109-default-recovery-6500a139-6f62-4060-b6fe-c6314ddc9ab5' {
echo 'Loading Linux 5.3.18-150300.59.109-default ...'
linux /boot/vmlinuz-5.3.18-150300.59.109-default root=/dev/mapper/system-root ${extra_cmdline} initrd /boot/initrd-5.3.18-150300.59.109-default
```
## 4. TroubleShooting
### 4.1. 問題描述
不小心在升級前,把 `/etc/zypp/zypp.conf` 檔案裡面的 `multiversion = provides:multiversion(kernel)` 和 `multiversion.kernels = latest,latest-1,running` 都註解掉,導致之前所保留的 Kernel 都被刪除了,該如何救回來 ???
### 4.2. 問題解答 : 裝回舊版的 Kernel
```bash!
# 將保留多個 kernel 版本的設定啟用,並保留所有的 kernel 版本
$ sudo nano /etc/zypp/zypp.conf
...
multiversion = provides:multiversion(kernel)
#multiversion.kernels = latest,latest-1,latest-2,latest-3,running
$ sudo zypper in --oldpackage --download-only kernel-default-5.3.18-150300.59.109.1
$ sudo init 6
## 開機選單選 Advanced options for SLES 15-SP3 -> 選舊版本的 Kernel
$ uname -r
5.3.18-150300.59.109-default
$ sudo zypper in --oldpackage kernel-default-5.3.18-150300.59.63.1
$ sudo init 6
## 開機選單選 Advanced options for SLES 15-SP3 -> 選舊版本的 Kernel
$ uname -r
5.3.18-150300.59.63-default
```