system

CentOS 5.4 Kernel rpm build 및 kernel Patch

KillerXman 2011. 3. 8. 15:02

CentOS 5.4 Kernel 2.6.18-164.el5 에서 2.6.18-194.32.1 Kernel을 Patch하고 업그레이드 하기 위해서 작업 함.

http://wiki.centos.org/HowTos/Custom_Kernel 사이트 참조

위 사이트에서는 user계정으로 작업을 하도록 했지만,

여러번 했음에도 실패를 했다.  

root 계정으로 모든 작업을 함

Kernel 패치 하거나 rpm 리빌드 하기 위해서는 개발툴을 미리 설치 한다.

# yum groupinstall -y "Development Tools"

자신의 Kernel 이 어떤것인지도 미리 알아 둔다.

1. Kernel Source 확인 및 설치
http://mirror.centos.org/centos/5/updates/SRPMS/  에서

최신 Kernel Source를 확인 후 설치한다.

# rpm -i http://mirror.centos.org/centos/5/updates/SRPMS/kernel-2.6.18-194.32.1.el5.src.rpm 2>&1 | grep -v mockb

# cd /usr/src/redhat/SPECS
# rpmbuild -bp --target=`uname -m` kernel-2.6.spec 2> prep-err.log | tee prep-out.log

이렇게 자신의 OS 환경에 맞는 소스가 생성 된다.
# cd /usr/src/redhat/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`

현재 config 설정을 가져오자
# cp /boot/config-`uname -r` .config

2. Kernel patch 파일 만들기

# cd /usr/src/redhat/SOURCE

소스 압축 풀기
# tar xvjf linux-2.6.18.tar.bz2

소스 폴더 복사
# cp -rp linux-2.6.18 linux-2.6.18.patch

패치파일 생성
File Open Limit 수정
# vi linux-2.6.18/include/linux/fs.h
============================================
define INR_OPEN 1024           /* Initial setting for nfile rlimits */
===========================================
에서
1024 를 4096 로 수정

# diff -uNr linux-2.6.18.patch/include/linux/fs.h linux-2.6.18/include/linux/fs.h > linux-2.6.18-tuning-fs-update.patch

Limit 수정
# vi linux-2.6.18/include/linux/limits.h
===========================================
#define NR_OPEN         1024
===========================================
에서
1024 8192 로 수정

# diff -uNr linux-2.6.18.patch/include/linux/limits.h linux-2.6.18/inlcude/linux/limits.h > linux-2.6.18-tuning-limits-update.patch

TCP WAIT Time 수정
# vi linux-2.6.18/include/net/tcp.h
===========================================
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
===========================================

에서 60 5 로 수정

# diff -uNr linux-2.6.18.patch/include/net/tcp.h linux-2.6.18/include/net/tcp.h > linux-2.6.18-tuning-tcp-update.patch


3. Kernel SPEC 수정

이전 SPEC는 복사 해 둔다.

# cd /usr/src/redhat/SPEC
# cp kernel-2.6.spec kernel-2.6.spec.back

# vi kernel-2.6.spec
===========================
%define buildid .your_identifier
============================
73번째 라인에 # $define buildid 에서 #공백을 제거 한 후 자신이 원하는 ID를 적늑다.

============================
Patch40000: linux-2.6.18-tuning-fs-update.patch
Patch40001: linux-2.6.18-tuning-limits-update.patch
Patch40002: linux-2.6.18-tuning-tcp-update.patch
============================
5234 라인 뒤에 만들 둔 pacht 파일을 적어 둔다.

=================================
%patch40000 -p1
%patch40000 -p1
%patch40000 -p1
================================
10258 라인 뒤에 패치가 적용 가능 하도록 해당 라인들 추가 한다.

4. SRPM 빌드 하기

# rpmbuild -bs --target=`uname -m' kernel-2.6.spec

명령 수행후
SRPMS/kernel-2.6.18-194.32.1.el5.XXX.src.rpm  이 새로 생성 되었을 것이다.

이 파일로 다시 설치 하고 rpm 을 빌드 해야 한다.

SOURCE 폴더의 내용 과 SPEC BUILD 아래  내용들을 지우자.

# rm -rf /usr/src/redhat/SOURCE/*
# rm -rf /usr/src/redhat/BUILD/*
# rm -f /usr/src/redhat/SPECS/kernel-2.6.spec

RPM 커널 소스를 다시 설치
# rpm -i SRPMS/kernel-2.6.18-194.32.1.el5.XXX.src.rpm  2>&1 | grep -v mockb
# cd /usr/src/redhat/SPEC
# rpmbuild -bp --target=`uname -m` kernel-2.6.spec 2> prep-err.log | tee prep-out.log


5. rmp 빌드 하기
# cd /usr/src/redhat/SPEC
# rpmbuild -bb --target=`uname -m` --with baseonly kernel-2.6.spec 2> build-err.log | tee build-out.log

이렇게 하면 /usr/src/redhat/RPMS/`uname -r` 경로에 rpm 파일이 빌드 되었을 것이다.

해당 파일을 설치 하면 패치 및 Kernel 업그레이드가 가능 하다.

# rpm -ivh kernel-XXXX.rpm

6. 기타 #1

rpm 컴파일시 아래처럼 뜨는경우

gpg: Generating a package signing key
  .++++++++++++++++++++...+++++..++++++++++++++++++++++++++++++++++++++++++++++++
  +++++++.+++++++++++++++++++++++++++++++++++++++++++++++++++++++..>+++++...+++++

  Not enough random bytes available.  Please do some other work to give
  the OS a chance to collect more entropy! (Need 123 more bytes)

  gpg: Interrupt caught ... exiting


이런경우에는 random bytes을 충분히 사용할수 없어 생기는 증상이다.
이런때는 다음 명령어를 실행해주면 다시 잘된다.

# rngd -r /dev/urandom

만약에 rngd가 없는경우에는 yum으로 인스톨을 시켜준다.

yum install rng-utils

7. 기타 #2
만약 원격에서 kernel 을 컴파일해 업그레이드 후 리부팅시 Kernel panic 이 걱정이 된다면

# vi /boot/grub/grub.conf
==========================================================
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,0)
#          kernel /boot/vmlinuz-version ro root=/dev/sda1
#          initrd /boot/initrd-version.img
#boot=/dev/sda
default=1
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-194.32.1.el5.XXXX)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.37-default ro root=LABEL=/1 panic=5
        initrd /boot/initrd-2.6.37-default.img
title CentOS (2.6.18-164.el5)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.18-164.el5 ro root=LABEL=/1
        initrd /boot/initrd-2.6.18-164.el5.img
=============================================================
Kernel 업그레이드 하면,  새로운 항목이 생성 되는데.

title CentOS (2.6.18-194.32.1.el5.XXXX)....
...
는 새로운 kernel 이미지 이다.

수정없이  리부팅을 하게 되면, 새로운 Kernel 이미지로 부팅이 된다.
 
붉은 색 panic=5 부분을 추가 하고, default=0 에서 1로 수정한다.

그런 후

#
echo "savedefault --default=1 --once" | grub --batch

또는 grub command 쉘에서 savedefault 명령을 내린다.

#
grub
grub> savedefault --default=1 --once
grub> quit

한 후 리부팅을 하게 되면,

만약 kernel panic 이 생기면 5초 후에 원래 kernel 이미지로 부팅을 하게 된다.

부팅이 되면

# uname -a

으로 확인 하고

기존 /boot/grub/grub.conf 에서 derault=0 으로 수정하자.