(轉)xen make file

經過這幾天來的磕磕碰碰,總算成功安裝上了 Xen 3.2.0
 
對於像 globus , linux 內核, xen 這樣的大型系統的安裝和部署,準備工作一定要做足。安裝前一定要詳細閱讀附帶的安裝文檔,而不是從網上找一大堆別人的安裝文檔然後挑一篇出來作爲自己的指導文檔,一定要詳細看安裝包中附帶的文檔,一篇也不放過。在安裝時, make 會 持續很長時間(一般都是一個小時以上,安裝內核花費的時間最少,十來分鐘左右),所以,一定要記得把錯誤輸出重定向到日誌文件中。在安裝過程中出了錯誤再 把錯誤信息貼到網上去找解決方法。附帶文檔中要求的預先必須有的安裝包一定要按照要求去做。出了錯誤不要輕易地把一切刪除了重來,在出現錯誤時一定要保持 冷靜,想盡辦法去解決它,刪除文件前一定要三思。不要輕易地說“我們重來吧”,最好是能在最少改動當前局面的情況下把問題給解決了。要勇敢地解決問題,不 要遇到問題就放棄或者重來。
 
 
現在是把所有東西都又重新來過。之前安裝了 N 次,每次都遇到很多問題。現在把所有的 dependencies 都安裝好了,然後按照 xen3.2.0 的文檔上說的,直接 make world
( 注意,其中 xorg-x11-devel cent os 上已經被另一個似乎是 mesa 的取代了,但 xen 只認 xorg-x11-devel ,通過查看 Makefile ,找到檢查 xorg-x11-devel 是否安裝的 shell 腳本,這個腳本是: xen-3.2.0/tools/check/check_x11_devel ,它在 /usr/include/X11 /usr/X11R6/include/X11 這兩個目錄下檢查是否任何一個目錄下存在 keysymdef.h 這個文件,如果兩個目錄下都沒有這個文件,就表示 xorg-x11-devel 沒有安裝,報錯,這個無所謂,在網上能找到這個文件的內容,大約有 2000 多行,把網上找到的這個文件放到任任意一個目錄下面就可以解決這個問題 )
現在 make world ,出現了下列問題:
cp : cannot stat `build-linux-2.6.18-xen_x86_32/arch/i386/boot/vmlinuz': No such file or directory
make[ 3]: *** [build] Error 1
make[ 2]: *** [linux-2.6-xen-install] Error 2
make[ 1]: *** [install-kernels] Error 1
make : *** [world] Error 2
是說 cp 在指定的目錄下找不到 vmlinuz 這個文件,顯然是在編譯內核時遇到的錯誤。查看,發現在 build-linux-2.6.18-xen_x86_32/arch/i386 下面沒有 boot 這個目錄。以前安裝時也遇到過這個問題,當時自己的解決方法是進入 build-linux-2.6.18-xen_x86_32 ,用 make menuconfig , make 先編譯好這個內核,但是發現編譯好的內核是 vmlinux 而不是 vmlinuz ,於是把它改名後複製到 build-linux-2.6.18-xen_x86_32/arch/i386/boot 目錄下,後來 xen make 完全成功但是重啓進入系統失敗,不知道和那種解決方法有沒有關係。
現在又遇到這個問題,感覺在整體沒有把握的情況下去猜如何解決,實在是很沒有方向。於是打算先了解這個錯誤發生前 make world 做過的事情。這裏的錯誤信息看起來就是一個遞歸過程: make world 調用 make install-kernels ,後者又調用 make linux-2.6-xen-install ,然後在 make linux-2.6-xen-install 裏面又是 make build ,然後 build 出錯,於是形成了這樣一個錯誤信息輸出。那麼,現在看看這幾個 make 都做了些什麼。在網上初步查了一下 makefile 的語法,找到 Makefile 中的 make world 部分:
# build xen , the tools, and a domain 0 plus unprivileged linux-xen images,
# and place them in the install directory. 'make install' should then
# copy them to the normal system directories
.PHONY: world
world :
        $(MAKE) clean
        $(MAKE) kdelete
        $(MAKE) dist
make world 實際上先做清除工作然後 make dist ,再找 make dist 部分:
# build and install everything into local dist directory
.PHONY: dist
dist : DESTDIR=$(DISTDIR)/install
dist : dist-xen dist-kernels dist-tools dist-docs
        $(INSTALL_DIR) $(DISTDIR)/check
        $(INSTALL_DATA) . /COPYING $(DISTDIR)
        $(INSTALL_DATA) . /README $(DISTDIR)
        $(INSTALL_PROG) ./install.sh $(DISTDIR)
        $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DISTDIR)/check
dist- %: DESTDIR=$(DISTDIR)/install
dist- %: install-%
        @: # do nothing
這部分中有個 % ,這是 make 文件的一種規則,自己不是太懂,猜測意思就是前後一樣,比如 dist-xen 的意思就是 install-xen dist-kernels 的意思也就是 install-kernels ,即 make dist 時會檢查 dist-xen , dist-kernel 等,而 dist-xen 等同於 install-xen ,可能就是這個意思。
那麼,現在看看 install-xen , install-kernels 等部分:
.PHONY: install-xen
install-xen :
        $(MAKE) -C xen install
 
.PHONY: install-tools
install-tools :
        $(MAKE) -C tools install
 
.PHONY: install-kernels
install-kernels :
        for i in $(XKERNELS) ; do $(MAKE) $$i -install || exit 1; done
 
.PHONY: install-docs
install-docs :
        sh ./docs/check_pkgs && $(MAKE) -C docs install || true
 
make –C 參數指定了一個目錄,表示在執行操作前先進入 -C 後面的目錄。所以, make –C xen install 意思就是先進入 xen 目錄,然後執行 make install 了。
我們已經知道了 make dist 是分這幾個步驟來的,那麼我們分開執行,看看到底錯誤在哪裏。
先執行 make install-xen
[root@jcwkyl xen-3.2.0]# make install-xen
結果正確無誤。現在執行 make install-tools:
[root@jcwkyl xen-3.2.0]# make install-tools 2>make_install_tools_err.log
發現了一些 warning ,還有兩個看起來比較重要的如下:
Makefile:352 : *** pciutils-devl package not found - missing /usr/include/pci
Makefile:353 : *** PCI passthrough capability has been disabled
但是 make install-tools 仍然成功執行。現在執行 make intall -kernels
[root@jcwkyl xen-3.2.0]# make install-kernels 2>make_install_kernels_err.log
並且趁機記錄下來 make install-kernels 時執行的 makefile 中的語句在變量擴展後的形式:
for i in  linux-2.6-xen   linux-2.6-xen0   linux-2.6-xenU  ; do make $i -install || exit 1; done
再看看 Makefile 文件中對 install-kernels 的定義操作:
.PHONY: install-kernels
install-kernels :
        for i in $(XKERNELS) ; do $(MAKE) $$i -install || exit 1; done
做這些僅是爲了好玩,同時也能加深理解。因爲這一步執行的很慢,再多看些東西:
make[ 1]: Entering directory `/usr/local/Xen-3.2.0/xen-3.2.0'
make -f buildconfigs/mk.linux-2.6-xen build
make[ 2]: Entering directory `/usr/local/Xen-3.2.0/xen-3.2.0'
if grep "^CONFIG_MODULES=" build-linux-2.6.18-xen_x86_32/.config ; then /
            make -C build-linux-2.6.18-xen_x86_32 ARCH=i386 modules || exit 1 ; /
            make -C build-linux-2.6.18-xen_x86_32 ARCH=i386 INSTALL_MOD_PATH=/ modules_install ; /
        fi
CONFIG_MODULES=y
make[ 3]: Entering directory `/usr/local/Xen-3.2.0/xen-3.2.0/build-linux-2.6.18-xen_x86_32'
make -C /usr/local/Xen-3.2.0/linux-2.6.18-xen.hg O=/usr/local/Xen-3.2.0/xen-3.2.0/build-linux-2.6.18-xen_x86_32 modules
  Using /usr/local/Xen-3.2.0/linux-2.6.18-xen.hg as source for kernel
好了,現在 make install-kernels 退出了,看看錯誤輸出日誌文件的內容:
[root@jcwkyl xen-3.2.0]# tail make_install_kernels_err.log
WARNING: drivers/atm/he.o - Section mismatch: reference to .init.text : from .text between 'he_start ' (at offset 0x20c5) and 'he_service_tbrq '
cp : cannot stat `build-linux-2.6.18-xen_x86_32/arch/i386/boot/vmlinuz': No such file or directory
make[ 2]: *** [build] Error 1
make[ 1]: *** [linux-2.6-xen-install] Error 2
make : *** [install-kernels] Error 1
現在能得出的結論就是在 make kernels 上出了重大問題。接下來呢?繼續分析 Makefile 定位錯誤嗎?從剛纔的 make install-kernels 說起,這條命令導致以下三條命令被執行:
make linux-2.6-xen-install
make linux-2.6-xen0-install
make linux-2.6-xenU-install
同樣,現在把這三條命令拆開執行:
[root@jcwkyl xen-3.2.0]# make linux-2.6-xen-install 2>err.log
make -f buildconfigs/mk.linux-2.6-xen build

執行結束了,查看 err.log ,果然出錯了,錯誤就是上面反覆提到的 cp 的那個錯誤。感覺,總共是編譯三個內核,這是第一個內核,後面兩個和這個應該也差不了多少,只要這個解決了,後面應該就不會出問題了。同時也看到了,執行 make 時用的是 buildconfig/mk.linux-2.6-xen 這個 makefile ,一路追蹤下去,會發現這個 makefile 中僅有兩三行變量定義,接着 include buildconfig 目錄下的 mk.linux-2.6-common 這個 makefile ,即,等於最終執行的是:
make –f buildconfigs/mk.linux-2.6-comman build
把這個文件中的 build 部分弄出來看看:
# The real action starts here!
.PHONY: build
build : $(LINUX_DIR)/include/linux/autoconf.h
ifneq ($(XEN_LINUX_ALLOW_INTERFACE_MISMATCH),y)
         @if ! diff -urN -X buildconfigs/interface.exclude /
              $(LINUX_SRCDIR)/include/xen /interface xen /include/public ; then /
                echo "" 1>&2 ; /
                echo " *** $(LINUX_SRCDIR)/include/xen /interface is out of date " 1>&2 ; /
                echo " *** relative to $(XEN_ROOT)/xen /include/public." 1>&2 ; /
                echo "" 1>&2 ; /
                exit 1 ; /
        fi
endif
        if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then /
            $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules || exit 1 ; /
            $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_MOD_PATH=$(DESTDIR) modules_instal /
l ; /
        fi
        $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) $(IMAGE_TARGET)
         mkdir -p $(INSTALL_BOOT_PATH)
        cp $(LINUX_DIR)/$(IMAGE_PATH) $(INSTALL_BOOT_PATH)/vmlinuz -$(KERNELRELEASE)
        cp $(LINUX_DIR)/.config $(INSTALL_BOOT_PATH)/config -$(KERNELRELEASE)
        cp $(LINUX_DIR)/System.map $(INSTALL_BOOT_PATH)/System.map -$(KERNELRELEASE)
……
爲了把整個的 make 流程看個清楚,仔細看看 make –help ,發現 -n 參數能幫這個忙。於是:
[root@jcwkyl xen-3.2.0]# make -n linux-2.6-xen-install > make_process.log
-n 命令指示 make 不要去做實際的 build ,而僅僅是把要執行的命令輸出出來。現在得到了這份 make 執行的流程文件,定位到 cp */vmlinuz 的那一部分是很簡單的了,但是知道了又怎麼樣呢?看到 vmlinuz 就應該知道錯誤是在哪裏了。
Makefile ,風險太大,那就換一種方式,先編譯好內核,等有了 vmlinuz 文件後再執行 xen 的安裝。
[root@jcwkyl xen-3.2.0]# make prep-kernels
這條命令成功執行。在 xen-3.2.0 目錄下多出了三個內核的目錄。根據安裝文檔上說的,可以複製一份現成的內核配置文件,然後執行 make oldconfig 來編譯內核。所以:
[root@jcwkyl xen-3.2.0]# cp /boot/config-2.6.18-128.el5 build-linux-2.6.18-xen_x86_32/.config
把以前的 .config 文件覆蓋掉。
[root@jcwkyl xen-3.2.0]# emacs build-linux-2.6.18-xen_x86_32/.config
找到其中和 ext2 以及 ext3 有關的部分,確認它們全部是 y ,這是因爲前兩天在 vmware 上編譯 linux 內核時的經驗。
但是有一個問題,如果僅僅是這樣編譯內核, make 的參數無法確定,即這個單獨編譯的內核並不知道有個 xen 在這裏,因爲它並不是從 xen 的安裝過程中引發出來的編譯過程,所以這個單獨的內核編譯過程必然對 xen 的安裝是沒有什麼幫助的。現在嘗試最有希望的解決方法,那就是稍微修改一下 Makefile
通過對照:在 make –n 執行後的 make_process.log 中尋找 mkdir –p( 因爲錯誤信息是緊接着 mkdir –p 然後 cp 錯誤的 ) ,幸運的是只找到了一處。比對一下,看它是哪個 Makefile 裏面的,如前面的分析,它其實就肯定是 buildconfigs/mk.linux-2.6-common 文件裏的了,和這個文件進行對比, buildconfigs/mk.linux-2.6-common 文件中的語句是:
        if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then /
            $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules || exit 1 ; /
            $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_MOD_PATH=$(DESTDIR) modules_instal /
l ; /
        fi
        $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) $(IMAGE_TARGET)
        mkdir -p $(INSTALL_BOOT_PATH)
        cp $(LINUX_DIR)/$(IMAGE_PATH) $(INSTALL_BOOT_PATH)/vmlinuz -$(KERNELRELEASE)
        cp $(LINUX_DIR)/.config $(INSTALL_BOOT_PATH)/config -$(KERNELRELEASE)
        cp $(LINUX_DIR)/System.map $(INSTALL_BOOT_PATH)/System.map -$(KERNELRELEASE)
make –n 執行的文件中對應地方的語句是:
make -C /usr/local/Xen-3.2.0/xen-3.2.0/build-linux-2.6.18-xen_x86_32 /
        KBUILD_SRC=/usr/local/Xen-3.2.0/linux-2.6.18-xen.hg /
        KBUILD_EXTMOD="" -f /usr/local/Xen-3.2.0/linux-2.6.18-xen.hg/Makefile vmlinuz
make[ 4]: Nothing to be done for `vmlinuz '.
make[ 2]: Leaving directory `/usr/local/Xen-3.2.0/xen-3.2.0/build-linux-2.6.18-xen_x86_32'
mkdir -p //boot
cp build-linux-2.6.18-xen_x86_32/arch/i386/boot/vmlinuz //boot/vmlinuz - make -C /usr/local/Xen-3.2/
.0/linux-2.6.18-xen.hg O=/usr/local/Xen-3.2.0/xen-3.2.0/build-linux-2.6.18-xen_x86_32 kernelrelease make -C /usr/local/Xen-3.2.0/xen-3.2.0/build-linux-2.6.18-xen_x86_32 /     KBUILD_SRC=/usr /loc/
al/Xen-3.2.0/linux-2.6.18-xen.hg /   KBUILD_EXTMOD="" -f /usr/local/Xen-3.2.0/linux-2.6.18-xen.hg/
/Makefile kernelrelease echo 2.6.18.8-xen
看到其實問題不止一個。
在網上查這個問題,只有一個人問,而且也是 xen3.2.0 版本,很有可能是 xen3.2.0 版本的一個 bug ,回頭安裝一次 xen3.3.0 或者其它版本試試看。
對這種安裝過程感到厭倦,一個 make 過程動輒半個小時以上的時間,儘管以前被執行過,再執行一次檢查也得花很長時間,而安裝系統時,出現這樣那樣的錯誤,不斷地想出更正的方法,然後運行 make , 等上半個小時以上的時間來看看自己想出來的更正方法是否有效,這個過程讓人崩潰!有沒有更有效的方法來做這樣的事情?我想最好的方法就是做足準備工作,安 裝過程中的每一步都必須走得異常小心,走每一步之前做好充分的準備和預見,而不是遇到問題再兵來將擋。儘量不要返工。最明顯的路不是最快的路。一定要小 心。儘可能並行地工作。
再說那個 cp 的問題,最後自己的方法是在 mk.linux-2.6-common 文件中把 make 的那個 ${IMAGE_TARGET} 去掉,然後執行 make kernels ,到這裏就能由 xen make 過程引發出 linux-2.6-xen make ,這個 make 生成的是 bzImage ,然後把 bzImage 改名爲 vmlinuz ,然後重新運行 make ,然後就一路順利了。奇怪的是,另外兩個內核都 make 良好,觀察了另外兩個內核的 make 時候的輸出,它們都確實是生成的 arch/i386/boot/vmlinuz ,只有第一個內核不是的。
現在配置 grub ,看看是不是確實成功了。首先要用 mkinitrd 命令生成對應的文件,中間可能會說什麼 uhci , mptspi 什麼的找不到,把所有的參數用上還有萬能的 builtin =XXX ,總之隨機應變,硬湊出來一個也可以的。我用的命令是:
#mkinitrd --omit-scsi -modules --omit-raid-modules --omit-lvm -modules --without-usb --without-dmraid --builtin =mptspi initrd-2.6.18.8-xen0.img 2.6.18.8-xen0
#mkinitrd --omit-scsi -modules --omit-raid-modules --omit-lvm -modules --without-usb --without-dmraid --builtin =mptspi initrd-2.6.18.8-xenU.img 2.6.18.8-xenU
我的 grub 文件最後的形式是:
default= 0
timeout= 5
splashimage =(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-128.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-128.el5 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
        initrd /initrd-2.6.18-128.el5.img
title Xen 3.2.0 / XenLinux 2.6.18.8
        kernel /xen-3.2.0.gz
        module /vmlinuz-2.6.18.8-xen0 ro console=tty0
        module /initrd-2.6.18.8-xen0.img
重啓後,進入 xen0 內核成功。那個 xenU 內核暫時就不管它了,現在對 xen 也不熟。至於內核 xen ,爲什麼要有三個內核,這個真不知道,也是照着文檔依葫蘆畫瓢的。
 
 

(另外,用make -n還是不可能確定很多Makefile中變量的運行時內容的,上面用make -n生成的那個make_process.log中的內容與make時實際輸出不符。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章