記一次yum故障的問題解決

摘要

用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做了限制?它是怎麼做限制的?

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