日々様々なトラブルにハマっている、困ったシステム管理者の奮闘日記です。

PAEに対応していないPCにCentOS6をいれてみた後の対応

前回、非PAEなPCにCentOS6を入れるために、カーネルを再構築した顛末を書いた。

今回は、前回に予告していたように、「じゃあ、カーネルがアップデートされたらどうするのん?」という課題に答えようと思う。

 

やることは、

カーネルがアップデートされた時の対応

  1. 前回のカーネルコンパイル環境の削除
  2. カーネルソースのダウンロード&展開
  3. カーネルパラメータの編集
  4. カーネルコンパイル
  5. 対象PCへ再構築したカーネルrpmをコピー
  6. 対象PCでのカーネルアップデート(インストール)
  7. カーネルがアップデートされたことを知る仕組みを考える

といったところか。

カーネルのアップデート が出たら、この流れで操作すると何とか非PAE環境でもCentOS6での運用ができそうだ。

 

※2014年11月5日追記:
2014年10月末にリリースされたCentOS6.6 に対しても、カーネルがアップデートされたことを検知でき、カーネル再構築~インストールまで正常にできたことを確認。

以下の作業は、前回非PAE対応用カーネルを再構築したVMwwareゲストOSで行う。

消しちゃった場合は、前回の記事を参考に環境を再構築するしかない。

前回のカーネルコンパイル環境の削除

必要に応じてバックアップを取ったほうが良いかも。
#cd /root
#rm -rf rpmbuild/

 

カーネルソースのダウンロード&展開

この辺は前回と同様。
#cd /root
#wget http://vault.centos.org/6.5/updates/Source/SPackages/kernel-~
#rpm -ivh kernel-~

 

カーネルパラメータの編集

この辺も前回と同様。

.specファイルの編集

 #cd ~/rpmbuild/SPECS/
#vi kernel.spec
---------------------------------------------------------------
 :
# % define buildid .local
 ↓このように修正
%define buildid .nonPAE
 :
---------------------------------------------------------------

 

SOURCEツリー生成

#rpmbuild -bp --target=$(uname -m) kernel.spec

これで rpmbuild 以下に
BUILD, BUILDROOT, RPMS, SOURCES, SPECS, SRPMS
ディレクトリができる。

make menuconfigの実行

前回と同様にカーネルパラメータを変更する。
最低限の変更点は、

Processor type and features > High Memory Support を選択 > 64GBから4GBへ変更して書き込み

のみ。

#cd /root/rpmbuild/BUILD/kernel-2.6.~

#make oldconfig

#make menuconfig

 

カーネルコンパイル

今回ここからがハマったところ。

このままrpmbuild -bb~を実行すると、nonPAE環境のカーネルはできあがらない。
make menuconfigで設定した.configファイルが、rpmbuildの途中で~/rpmbuild/SOURCES/ ディレクトリにあるconfig-xx ファイルの内容で書き換わってしまうことが原因のようだ。

[対応]
なので、最低限の変更箇所を上書きさせないようにパッチを入れる。

#perl -i -n -e '/CONFIG_HIGHMEM/ or print' /root/rpmbuild/SOURCES/config-i686*

その他にもmake menuconfigで変更した内容があるのであれば、config-xxファイルに上書きされる可能性があるのでチェックする必要があるだろう。

 

進めると、コンパイルエラーもでる。

 :
arch/x86/kernel/cpu/mshyperv.c: In function 'ms_hyperv_platform':
arch/x86/kernel/cpu/mshyperv.c:45: error: implicit declaration of function 'xen_cpuid_base'
make[3]: *** [arch/x86/kernel/cpu/mshyperv.o] Error 1
make[2]: *** [arch/x86/kernel/cpu] Error 2
make[1]: *** [arch/x86/kernel] Error 2
make: *** [arch/x86] Error 2
エラー: /var/tmp/rpm-tmp.GIZsTJ の不正な終了ステータス (%build)

RPM ビルドエラー:
/var/tmp/rpm-tmp.GIZsTJ の不正な終了ステータス (%build)

arch/x86/kernel/cpu/mshyperv.c 内の「xen_cpuid_base()」関数が定義されていないことが原因のようだ。

 

[対応]
この関数の実行をやめるようにソースにパッチを入れる。

#perl -p -i -e 's/xen_cpuid_base\(\)/0/' /root/rpmbuild/BUILD/kernel*/vanilla*/arch/x86/kernel/cpu/mshyperv.c

と、
さらにエラー

scripts/mod/file2alias.c:797: warning: 'do_x86cpu_entry' defined but not used
cc1: warnings being treated as errors
drivers/pci/pci-sysfs.c: In function 'pci_mmap_resource':
drivers/pci/pci-sysfs.c:879: error: format '%16Lx' expects type 'long long unsigned int', but argument 9 has type 'resource_size_t'
drivers/pci/pci-sysfs.c:879: error: format '%16Lx' expects type 'long long unsigned int', but argument 10 has type 'resource_size_t'
make[2]: *** [drivers/pci/pci-sysfs.o] Error 1
make[1]: *** [drivers/pci] Error 2
make: *** [drivers] Error 2
エラー: /var/tmp/rpm-tmp.LzFtp8 の不正な終了ステータス (%build)

RPM ビルドエラー:
/var/tmp/rpm-tmp.LzFtp8 の不正な終了ステータス (%build)

 

[対応]
Makefileの「-Werror」をやめる。

#perl -p -i -e 's/echo "-Werror";/echo "";/' /root/rpmbuild/BUILD/kernel*/vanilla*/Makefile

 

これらの対応は、前回利用させてもらったDIGITGEスクリプト内にもちゃっかり入っていた。

また、これらの対応は、rpmbuild/BUILD/kernel*/linux*/ 以下のファイルに適用するのではだめで、「rpmbuild/BUILD/kernel*/vanilla*」にも必要の様子。

※この辺の仕組みは勉強不足でよく把握していない。何か理由があり、また、もっとスマートな対処方法があるのだろうが、現時点ではここまでが限界。

 

ここまでやってやっと正常にビルドできた。
念のため、結果を「/root/rpmbuild-yymmdd.log」ファイルに出力するようにし、後で結果を確認できるようにした。

#rpmbuild -bb --target=i686 --without kabichk --without perf --without debug --without debuginfo --with firmware kernel.spec 2>&1 |tee /root/rpmbuild-`date +"%Y%m%d"`.log

 

面倒なので、これらの手順をスクリプトにし「build-kernel-updates.sh」、これを実行することにする。

# cd /root
#sh build-kernel-updates.sh

ちなみに、build-kernel-updatesの中身。

#!/bin/bash
perl -i -n -e '/CONFIG_HIGHMEM/ or print' /root/rpmbuild/SOURCES/config-i686*</pre>

perl -p -i -e 's/xen_cpuid_base\(\)/0/' /root/rpmbuild/BUILD/kernel*/vanilla*/arch/x86/kernel/cpu/mshyperv.c

perl -p -i -e 's/echo "-Werror";/echo "";/' /root/rpmbuild/BUILD/kernel*/vanilla*/Makefile

cd /root/rpmbuild/SPECS

rpmbuild -bb --target=i686 --without kabichk --without perf --without debug --without debuginfo --with firmware kernel.spec 2>&1 |tee /root/rpmbuild-`date +"%Y%m%d"`.log

 

対象PCへ再構築したカーネルrpmをコピー

対象PCでsshデーモンが動作していることを前提にすると、以下で直接rpmパッケージを転送することができる。

#cd /root/rpmbuild/RPMS/i686
#sftp root@対象PC

sftp> mput *.rpm
Uploading kernel-~
 :
sftp> quit
#

 

対象PCでのカーネルアップデート(インストール)

普通にインストールすると、下記のようにエラーになる。

# rpm -ivh kernel-*
準備中... ########################################### [100%]
ファイル /usr/include/asm-generic/socket.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.el6.NOPAE.i686 からのファイルと競合しています。
ファイル /usr/include/linux/kvm.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.el6.NOPAE.i686 からのファイルと競合しています。
ファイル /usr/include/asm/msr-index.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.el6.NOPAE.i686 からのファイルと競合しています。
ファイル /usr/include/linux/filter.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.el6.NOPAE.i686 からのファイルと競合しています。
ファイル /usr/include/asm-generic/socket.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.1.2.0.1.el6.nonPAE.i686 からのファイルと競合しています。
ファイル /usr/include/linux/kvm.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.1.2.0.1.el6.nonPAE.i686 からのファイルと競合しています。
ファイル /usr/include/asm/msr-index.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.1.2.0.1.el6.nonPAE.i686 からのファイルと競合しています。
ファイル /usr/include/linux/filter.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.1.2.0.1.el6.nonPAE.i686 からのファイルと競合しています。
ファイル /usr/include/linux/filter.h (パッケージ kernel-headers-2.6.32-431.29.2.el6.nonPAE.i686 から) は、パッケージ kernel-headers-2.6.32-431.23.3.el6.nonPAE.i686 からのファイルと競合しています。

なので、「–force」オプションつきでインストールする。

#rpm -ivh --force kernel-*

 


カーネルがアップデートされたことを知る仕組みを考える

要は、アップデート対象のrpmパッケージの中にkernelを含んでいるかどうかを検知すれば良い。

その際、yum.conf にカーネルの変更は反映しないように定義(exclusive=kernel*)しているので、確認の際にこの設定を無視すれば良い。

結果、次のコマンドで確認できるんじゃないかな。

#yum --disableexcludes=all check-update |grep kernel

 

で、こんなスクリプトを作ってみた。
これをcronに定義し、定期的にチェックさせ、もしkernelのアップデートがあればメールで知らせる仕組みにしてみた。

#!/bin/bash

CHECK_FILE=/usr/local/tools/test.txt
YUM=/usr/bin/yum
MAILBODY=/usr/local/tools/mailbody.txt

NKFCMD=/usr/bin/nkf
MAILCMD=/usr/sbin/sendmail
MAILFROM=admin@aaa.com
MAILTO=kanrisya@bbb.com

$YUM --disableexcludes=all check-update |grep kernel &gt;$CHECK_FILE
if [ -s $CHECK_FILE ] ; then

echo "From: $MAILFROM" > $MAILBODY
echo "To: $MAILTO" >> $MAILBODY
echo "Subject: Kernel Patch Released" >> $MAILBODY
echo " " >> $MAILBODY
echo "#############################" >> $MAILBODY
echo " `date`" &gt;&gt; $MAILBODY
echo "#############################" >> $MAILBODY
echo " " >> $MAILBODY
cat $CHECK_FILE >> $MAILBODY

cat $MAILBODY |$NKFCMD -j |$MAILCMD -f $MAILFROM $MAILTO
# echo `cat $MAILBODY |$NKFCMD -j`
else
echo "nothing"
fi

yumとsendmail(postfix)が入っており、メール送信できる環境であることが前提。
nkfは別になくても良い。

 

以上


You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

AddThis Social Bookmark Button

Leave a Reply