궁합이 좋지 않은 CentOS 7과 Xen

서초 UCloud에서 기술지원 요청이 왔다. DomU CentOS 7 커널을 최신으로 업데이트 하니 부팅이 안된다고 한다.

Xen과 CentOS 7 커널간 무슨 문제가 발생한 걸까?

실험 서버

  • Hardware

    • Vendor: Dell

    • Model: PowerEdge R730

    • CPU model: Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz

    • CPUs: 6 cores * 2 sockets * HT = 24 cores

    • RAM:

    • RAID: MegaRAID SAS-3 3108

    • HDD: 600GB 15k rpm SAS Disk (found out using smartmontools)

      $sudo smartctl -i /dev/sda -d megaraid,0
      smartctl 6.4 2014-10-07 r4002 [x86_64-linux-3.16.0-4-amd64] (local build)
      Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org
      
      === START OF INFORMATION SECTION ===
      Vendor:               SEAGATE
      Product:              ST600MP0005
      Revision:             VT31
      Compliance:           SPC-4
      User Capacity:        600,127,266,816 bytes [600 GB]
      Logical block size:   512 bytes
      Formatted with type 2 protection
      LB provisioning type: unreported, LBPME=0, LBPRZ=0
      Rotation Rate:        15000 rpm
      Form Factor:          2.5 inches
      Logical Unit id:      0x5000c5008eb88c07
      Serial number:        S7M0JDDF
      Device type:          disk
      Transport protocol:   SAS (SPL-3)
      Local Time is:        Sat May  5 20:25:37 2018 KST
      SMART support is:     Available - device has SMART capability.
      SMART support is:     Enabled
      Temperature Warning:  Disabled or Not Supported
      
  • Xen Dom0

    • hostname: orchard (별로 좋지 않은 호스트명, 사용자명과 혼동된다.)
    • IP: 117.52.152.103
  • CentOS 7 DomU

    • hostname: localhost (내가 아주 싫어하는 호스트명)
    • IP: 117.52.152.104

증상

CentOS 7.2를 iso로 설치하여 부팅하면 문제없이 부팅이 된다. 이 때 커널 버전은 3.10.0-327.el7.x86_64.

yum install kernel 하여 최신 커널로 업그레이드한 후 리부팅하면 grub 화면에서 5초가 흐른 후 검은 화면이 나오고 부팅이 진행되지 않는다.

최신 커널 버전은 3.10.0-693.21.1.el7.x86_64.

직원 말로는 우리 회사 실험 서버(사실 PC)에서는 최신 커널에서도 부팅이 잘 된다고 한다. 그렇다면 서초 UCloud에 있는 서버 하드웨어와의 문제라고 할 수 있다.

실험 1. 문제 확인

grub에서 rhgb와 quiet 옵션을 제거하고 커널 부트 로그를 보자.

grub 화면에서 해당 커널을 선택한 후 e 를 치면 inline edit mode가 된다. kernel line에서 rhgb와 quiet을 삭제하고 Ctrl-x 를 눌러 부팅을 진행한다. 커널 부트 로그가 다음 그림처럼 나온다.

../../../_images/centos7_domu_boot_stop.png

실험 2. 작동 커널을 찾아서

최신 커널이 문제가 있으니 바로 이전 커널도 같은 문제가 있는 지 확인하자.

http://rpmfind.net/ 에서 kernel을 검색해 보니 최신 커널 3.10.0-693.21.1.el7.x86_64 바로 전 커널 패키지는

3.10.0-693.17.1.el7.x86_64 이다.

이 커널을 설치하여 부팅해 보자.

$ wget http://rpmfind.net/linux/centos/7.4.1708/updates/x86_64/Packages/kernel-3.10.0-693.17.1.el7.x86_64.rpm

$ sudo rpm -Uvh kernel-3.10.0-693.17.1.el7.x86_64.rpm

이제 3.10.0-693.17.1.el7.x86_64로 부팅해 보니 잘 부팅된다.

그렇다면 최신 3.10.0-693.21.1.el7.x86_64과 이전 패키지 간 이 서버에 대해 문제가 있다는 것이다.

실험 3. ACPI, APIC 커널 옵션

위 실험 1. 문제 확인에서 보면 마지막 커널 로그 메세지가 ACPI 관현 메세지였다. 그래서 CentOS 7 최신 커널에서 현 서버의 ACPI 시스템과 문제가 있는 건 아닌지 의심스러웠다. grub 커널 옵션에서 acpi를 꺼볼까?

CentOS 7에서의 grub 커널 옵션 변경법은 다음과 같다.

#. /etc/default/grub파일을 편집한다.

$ sudo vi /etc/default/grub
...
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
...

위 GRUB_CMDLINE_LINUX에 원하는 커널 옵션을 추가한다.

#. grub.cfg파일을 생성한다.

$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

ACPI 관련해서 3개의 커널 옵션이 있다.

  • acpi=off
  • noapic
  • nolapic

각각의 의미를 살펴보자.

acpi=off

ACPI는 Advanced Configuration and Power Interface의 약자로 번역하면 “고급 구성 및 전원 인터페이스”이다.

ACPI위키백과 에 의하면 1996월 12월 공개된 표준으로 하드웨어 감지, 메인보드 및 장치 구성, 전원 관리를 담당하는 일반적인 인터페이스를 정의한단다.

예를 들면 ACPI가 enable된 시스템에서는 리눅스에서 poweroff 또는 shutdown 명령으로 종료하면 ACPI가 시스템 전원을 종료한다. ACPI를 disable하면 리눅스가 종료되어도 시스템 전원은 꺼지지 않는다. 수동으로 전원버튼을 눌러 꺼야 한다.

커널 옵션에 acpi=off를 주면 ACPI기능을 사용하지 않겠다는 것이다.

noapic/nolapic

APIC은 Advanced Programmable Interrupt Controller의 약자로 번역하면 “고급 프로그램가능한 인터럽트 제어기” 아~~ 번역이 이상하다.

역시 APIC위키백과 에 의하면 더 많은 출력, 더 복잡한 우선 순위 계획, 고급 IRQ 관리를 한다고 한다.

APIC은 split architecture design(Local and System bus IO)으로 LAPIC(Local APIC)은 CPU에 통합되어 있고 시스템 버스에 IOAPIC은 선택사항이다.

noapic 옵션은 시스템 버스의 IOAPIC을 disable한다는 것이다.

nolapic 옵션은 CPU의 LAPIC을 disable한다는 것이다.

각 옵션을 켜고 끄면서 부팅이 되는 지 실험해 보았다.

options Boot OK
acpi=off NO
noapic NO
nolapic YES

acpi=off와 noapic 옵션은 각각 따로 설정해도 또는 함께 설정해도 부팅에 실패했다. nolapic 옵션은 다른 옵션없이 이 옵션만 설정해도 부팅에 성공했다.

안 되는 것과 되는 것 비교

dmesg를 비교해 보았다.

[    0.096000] pinctrl core: initialized pinctrl subsystem
[    0.097000] RTC time: 18:26:10, date: 05/05/18
[    0.098000] NET: Registered protocol family 16
[    0.099000] ACPI: bus type PCI registered
[    0.100000] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[    0.101000] PCI: Using configuration type 1 for base access
안되는 것은 여기서 멈춘다.
되는 것은 아래와 같이 부팅이 진행된다.
[    0.102000] ACPI: Added _OSI(Module Device)
[    0.103000] ACPI: Added _OSI(Processor Device)
[    0.104000] ACPI: Added _OSI(3.0 _SCP Extensions)
[    0.105000] ACPI: Added _OSI(Processor Aggregator Device)
[    0.107000] ACPI: SCI (ACPI GSI 9) not registered
[    0.108000] ACPI: EC: Look up EC in DSDT

nolapic 옵션의 문제

VM에 4개의 CPU를 할당했으나 nolapic 옵션을 주면 CPU가 한 개로 제한된다.

dmesg를 보면

[    0.000000] Processors: 4
[    0.000000] smpboot: Allowing 4 CPUs, 0 hotplug CPUs
...
[    0.084000] Brought up 1 CPUs
[    0.215000] ACPI: NR_CPUS/possible_cpus limit of 4 reached.  Processor 4/0x2 ignored.
[    0.217000] ACPI: Unable to map lapic to logical cpu number
[    0.218000] ACPI: NR_CPUS/possible_cpus limit of 4 reached.  Processor 5/0x4 ignored.
[    0.219000] ACPI: Unable to map lapic to logical cpu number
[    0.220000] ACPI: NR_CPUS/possible_cpus limit of 4 reached.  Processor 6/0x6 ignored.
[    0.222000] ACPI: Unable to map lapic to logical cpu number

따라서 nolapic 옵션은 부팅에는 성공하나 CPU가 한 개로 제한되므로 해결책은 아니다.

실험 4. ELRepo의 최신 커널

ELRepo는 Enterprise Linux Repository의 약자로 최신 패키지들로 구성되어 있다. CentOS 7의 ELRepo를 enable하여 최신 커널을 설치, 시험해 보자.

Enable ELRepo:

$ sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
$ sudo rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

Check ELRepo:

$ yum repolist enabled
repo id           repo name                                               status
...
elrepo            ELRepo.org Community Enterprise Linux Repository - el7    235

Show all available packages in elrepo channel:

$ yum --disablerepo="*" --enablerepo="elrepo" list available

Show all available packages in elrepo-kernel channel:

$ yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
...
Available Packages
kernel-lt.x86_64                        4.4.131-1.el7.elrepo       elrepo-kernel
...
kernel-ml.x86_64                        4.16.7-1.el7.elrepo        elrepo-kernel

kernel-it? kernel-ml? 무슨 차이일까?

두 패키지 모두 Linux Kernel Archives에서 소스를 가져도 빌드한 패키지이다. kernel-lt는 Long Term support branch 커널이고 kernel-ml은 Mainline Stable branch 커널이다.

kernel-lt 패키지를 설치하자.

$ sudo yum --disablerepo="*" --enablerepo="elrepo-kernel" install kernel-lt

$ sudo grub2-set-default 0
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
$ sudo reboot

리부팅해 보니 잘 부팅된다.

$ uname -a
Linux localhost.localdomain 4.4.131-1.el7.elrepo.x86_64 #1 SMP Wed May 2 13:09:02 EDT 2018 x86_64 x86_64 x86_64 GNU/Linux

Pick your pill

Matrix영화에서 Morpheus가 Neo에게 한 말:

This is your last chance. After this, there is no turning back. You take the blue pill—the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill—you stay in Wonderland, and I show you how deep the rabbit hole goes. Remember: all I’m offering is the truth. Nothing more.

지금까지의 실험을 요약하자.

  • CentOS 기본 패키지 저장소의 최신 커널은 Dell커뮤니티 에서 논의되는 것처럼 Dell R730 장비와 호환성이 의심된다. 물리머신에서도 CentOS 7 최신 커널을 설치하면 유사한 증상이 재연된다.
  • CentOS 7 최신 커널에 nolapic 커널 옵션을 주면 정상 부팅되나 CPU가 한 개로 제한된다.
  • CentOS 7 최신 커널 패키지(3.10.0-693.21.1.el7.x86_64) 바로 이전 커널 패키지(3.10.0-693.17.1.el7.x86_64)로 부팅하면 문제없이 정상 부팅된다. 난 이것을 Blue Pill 이라 하겠다.
  • ELrepo의 최신 Long Term Support 커널 (kernel-lt)를 설치하여 부팅하면 문제없이 정상 부팅된다. 난 이것을 Red Pill 이라 하겠다.

그래서 결론은? 우리는 파란 약을 선택할 지, 빨간 약을 선택할 지 결정해야 한다.

Blue Pill or Red Pill?

Pick your pill.