摘要
用Linux的同學應該都知道yum,是用來管理系統軟件包的,非常快捷,可以自動解決包依賴問題。
但真正瞭解yum的工作原理的人估計並不多。
本文記錄一次在公司雲平臺上遇到無法使用yum的問題。
正文
問題重現:
在虛擬機上安裝包(比如tcpdump),報Timeout
28, 'Operation too slow. Less than 1 bytes/sec transfered the last 30 seconds'
乍一看,感覺是和repo服務器連接太慢,所以Timeout了,實際情況是不是這樣呢?我們用strace命令來分析下過程。
原因分析:
1. 可以把strace結果保存到文件中,打開慢慢看,也可以指定只輸出特定system call。
strace -s 2000 -f -o yum.output yum install tcpdump strace -s 2000 -f -e poll,select,connect,recvfrom,sendto yum install tcpdump
"-s 2000":規定輸出最大字節爲2000,默認是32,太小了,會導致我們忽略一些重要信息。
"-f":追蹤所有子進程
這裏我概述下結果:
strace先查找nscd有沒有cache對應的dns記錄,然後查找/etc/resolv.conf裏面的dns服務器的地址,然後判斷出repo主機的IP地址。
之後系統給repo主機發出sendto() GET請求,請求獲取repos.xml文件,但最後都一直顯示poll() Timeout 。
由此我們知道原因是根本連不上repo服務器。
2. 那是不是真的連不上repo服務器呢?
我用wget/curl 嘗試了下,發現可以下載repos.xml文件。說明repo服務器的80口是通的。
哎,這就奇怪了,爲什麼用不用的工具返回的結果卻不一樣呢?
想來想去,只有Header不一樣。
我們回過頭重新看下strace的結果,發現yum用的User-agent是“urlgrabber/3.1.0 yum/3.2.22”,而wget用的是Wget/1.12 (linux-gnu) , 所以我們需要修改對應的yum源碼文件。
vim /usr/lib/python2.6/site-packages/yum/yumRepo.py
先備份下,然後做如下修改,把第一行改爲第二行:
'user_agent': default_grabber.opts.user_agent, 'user_agent': 'Wget/1.12 (linux-gnu)',
保存好後,清除所有yum緩存
yum clean all
再安裝tcpdump包
yum install tcpdump
刷的一下,彈出來熟悉的東西,成功了!!
未完待續
到此問題算是解決了,但後面還有工作要做,就是repo服務端爲什麼對請求的Header做了限制?它是怎麼做限制的?