Wednesday, September 28, 2011

四月的暖風吹過,遠方傳來了爺爺過世的消息。今年硅谷的春天似乎來得特別早,立春才過這裡的櫻花樹就已經含苞待放了。❀
  群山黛如墨色,從太平洋來的風吹過如風鈴,不斷重複放送著遠方已經落幕的故事。
  
  
(一 )
  爷爷走得很突然。正如他一直所希望的那樣,無病無災,乍然離世。
  民國十三年出生,在那個軍閥割據的年代。出生在大別山區的一隻餘脈,現在是六零年代所築成的一個水庫之底。少時家裏頗有幾分田產,除了自家人耕種之外,需另僱短工才能完成全部的收成。但這些也注定了解放以後成為被批鬥階層的厄運。那個大山裏的稻田其實都是薄田,就我年少時曾經回鄉拜祭祖爺爺靈位時所見,那山裡的稻田跟平原上現代農業耕種的田野全然不同,它沒有平原上那樣大塊的一望無垠,而是山溝裡十分小塊的梯田,日出勞作都十分辛苦,需要翻越很多道山嶺才能到達;山溝裡只有半日陽光,莊稼普遍都長不太好,還需要擔心野獸的出沒,一旦有野豬的光顧,那毫無辦法,整條山溝的莊稼都會毀個大半。這樣的田地其實不適合耕種,近些年隨著農業政策的改變,那裡已經逐步退耕還林了,重建的是大別山國家森林。
  爺爺一家兄弟四人,排行第四,外有一位小妹。許多年後我曾唯一一次碰到他們相遇,那時前三位兄長已逝,我聽到她親切的叫了一聲『四哥…』 不知道他們在一起談了有多久,那個下午有知了一直在歌唱,少年在爺爺的腳下睡著了。爺爺曾說起小時候最大的樂趣就是看過兵了,兄弟幾人一起趴在某一處山頭,遠遠的看那些路過的部隊,有時候看得呆了,那些兵士就沒日沒夜的過,彷彿就沒得完的,從清晨到黃昏,日落後又點上火把繼續行軍從夜幕到天明。我猜想那應該是蔣介石的北伐,又或者是中原大戰的前夕。在那樣奼紫嫣紅的時局,誰人又會去關心躲在遠山上幾位好奇觀察的少年呢。那裡有一座山在當地遠近聞名,名曰查兒山,年少的我曾隨爺爺和爸爸爬過一次,山勢陡峭,但那時已年過六十的爺爺仍然走在前面健步如飛,一邊給我講起那座山的得名,大約是古代一位將軍打仗經過此山丟失幼子又返回搜尋而不得的故事,四月的清明時節,留給我的記憶只有滿山的落英繽紛。
  到了四十年代開始在農閒季節跟隨長輩出門行走,到安徽霍山挑鹽,或是到漢口漢正街淘點貨迴響賣,都是走去走回,一二百里地;但那個年代其實沒多少貨,無非火柴、鐵釘(那時的爺爺輩稱其為洋火、洋釘);也可以買點膠鞋襪子回去,但那時山里人消費不起。膠質雨鞋是大部分山裏人所夢寐以求的,他們長年穿的是草鞋,也沒有穿襪子的必要。爺爺常和我描述起解放前漢正街的繁華。與我日後曾在武漢專程前往漢正街所見也許不同:時過境遷,漢正街曾經的風雨,和歷史地位,在全國的聲望,也許再也不會回來了。
  二十岁婚配,娶妻段氏。段氏在婚后似乎一直在多病的状态,年出三十竟然病故,無所出。這是我在家譜上能找到的關於段氏的唯一記載。但既然無所出,當然就不會是我的奶奶,我的親生奶奶在我此生也從未記得,因為她在我出生的第一年就已經離我們而去了。關於段氏我曾問過爺爺,但爺爺留給我的只有嘆息。
  
  
(二)
  五十年代土改,打成地主阶层,被周围贫苦的农民分走了土地,长年处于被批斗的状态,自此日子就很艰难了;六十年代因建设水库的需要,四面凡山坳都被築成水壩,中間一塊僅剩的平地本是村子自古以來的住屋地基,也變成了水庫之池底,数百被淹住户被搬迁至周围邻镇邻乡邻县插队安家。爷爷便是其中之一,带着奶奶和儿女转移至鄰縣一个完全陌生的村子继续生活。搬家有当年的移民办联络新的生产队给协助砌好两间砖房,除此之外只有自家随迁的几样家具,一切是从赤贫重新开始。所幸新的村子新的环境下周围居民并不知底细,不似贫农批斗地主那般关系紧张,反而眼见同样贫寒的家境,乐得和睦相处。
  我想那次水庫移民也許正好是上天給安排我的爺爺和奶奶相遇的機會。
  我的祖母劉氏,出生是大家閨秀,所嫁也是大戶人家,在解放後短短幾年的社會運動中便經歷人生命運的逆轉:從原本平淡安逸的生活中突然跌至谷底:眼見自己的丈夫離世,人生有幾人能承受起這樣的打擊?而暴力就來源於周圍這裡世世代代和睦相處的鄉親們,這是為什麼?奶奶這一生都沒能想通這個問題,即使到八十年代後人們被允許迴響探親時她這一生也再也沒有回去過。從日後大姑的口述裡,我知道了奶奶自己當時也沒少受委曲,拳打腳踢是常事,而且還被吊起來兩三天不給飯吃,就靠大姑省下來的飯糰度日。許多年後當我向大姑問起這一段歷史時,大姑仍然是不由自主地泣不成聲。我猜想當時的奶奶也許想過隨夫而去吧,但轉眼看一旁大姑帶隊的幾個娃娃,又如何忍心呢。改嫁的念頭在她心裡從未想過,直到族裡有人提議讓她和我爺爺重新結合時,她還堅決反對而作罷。轉機就出現在幾年後的水庫移民。也許是嘗試了獨立帶大幾個孩子確實不易,也許是即將遷移至陌生的環境能讓她稍稍減輕良心的不安,這次她答應了與我的爺爺一起搬去嶄新的環境。
  
  爺爺曾描述解放前的社會關係其實沒有這麼複雜,人心遠沒有這般兇險,人們和睦相處,大部分村民都是多多少少有份自己的田產,完全以做工維生的佃農是相當少的,為富不仁的事情在他所知的那個範圍根本沒有發生,那些只在如楊白勞黃世仁一般的戲文裡出現;在災荒年都有人們自發的互相救助,而且有宗族祠堂和神明約束,也沒有什麼偷盜和殺人越貨的故事發生。這麼說來,彼時的民國似乎是一個溫情脈脈的時代?又或許是大山的阻隔,讓那個時代的兵連禍結無所殃及?當我從歷史課本裡找到四十年代的抗戰、接著是內戰,然後幾年的國民政府濫發紙幣通貨膨脹,爺爺所親身經歷的歷史裡似乎都未曾有過?『打仗?是聽說過』但那時不知道在哪裡,至少不在我們那裡,日本人甚麼摸樣也未曾見過,那我問道那時沒有什麼事情需要報告官府的嗎,縣城裡也許有呢。『還真沒什麼事要驚動官府。』一個縣裏面就是縣衙一個公家單位,裡面也沒幾個人,鄉鎮級只有鄉約,只在過年時由村里幾個大戶人家補貼些米糧,算是一些微不足道的實物工資吧。至於紙幣,住在山裡連需要用到錢的機會都很少。
  
  
(三)
  五六十年代開始疯狂的"大集体"农庄:從大炼钢铁同时开大锅饭,每户的锅碗瓢盆凡铁器都被收归集体用於煉鋼鐵,誓要超英趕美,粮食也全收归集体,集体大食堂做饭、集体劳动回来集体吃饭、秋收后的那个季节开始集体大吃大喝、对集体的仓库开始吃用无度、憧憬着美好共产主义的提前实现。实际上次年春即揭不开锅了、生产队预留一年的粮食被人们提前吃完了。也可能是前一年上缴过多,预留的部分预计错误,总之就是集体的仓库被吃空了。开始有人饿死。不知道后来这几个月他们是怎么过来的。再后来就是年复一年的集体劳动,所有人被要求集体劳动,挣工分。再以一定工分换取人民币。我所记得的来自爷爷的亲口表述是曾有一个月他挣到了一角二分钱。当然是领不到现钱,而是记在帐上,至于何时兑换成现钱,大概是年底吧。
  
  在六零年代的水庫移民以及後來的大生產中我的爺爺也逐漸自己琢磨一些機會,在建設中缺少足夠有訓練的尼瓦匠,或稱砌匠,我的爺爺在觀察了幾天別人砌房子後便謊稱自己以前就是砌匠,從此開始了自學的砌匠生涯,幾年之後還能帶出徒弟,鄉村裡至今還有他們師徒當年的作品。
  
  
(四)
  似乎一直到了七零年代末。
  
  革新之聲傳遍神州大地,爺爺是最早響應的一個。恢復高考和承包責任田,讓社會又重新找回對這個國家的希望。爺爺一家也比從前更忙碌了。人們開始被允許迴響祭祖,也包擴遠在海峽之外的舅公,那是我的祖母劉氏的親兄弟。解放前曾在武漢上學,誤打誤撞就被加入了國民黨,一個只能隨國軍遠赴台灣,一個留下來的就是莫名其妙的三十年把牢底坐穿。人生能有幾個三十年,奶奶似乎就是在那次前往農場監獄探監回來後一病不起。說是風寒,自此就在床上躺了大半年再也沒有起來。
  
  
(五)
  革新之後的社會才真正有如天地初開,爺爺此時畢竟已經慢慢爬不動牆了,砌匠活就完全交給徒弟們了,又開始做石匠雕刻,都是無師自通,還和釋放歸來的舅公一起合資經營小賣部。都是從社會發展中,細心的人去觀察需求中發現的機會。另一面又在迴響祭祖的過程中找回了當年私藏的古書,一套《象吉通書》五卷本全。能經歷文革破四舊的瘋狂年代而依然大部分完好,不得不說是一個奇蹟。據我的研究此書出於清朝康熙年間,薄薄的竹紋紙質,讓人擔心似乎一戳就會破,雕版印刷,內容方面只能算是編纂之集大成者,上至天文下至地理、人情世故、婚喪嫁娶,居家風水,內容無所不包,在清朝時期發行量很大,應該算得上是一部家喻戶曉的藏書,但能保存至今也極為不易,因為在破四舊的年代中,紅小兵們衝進每家每戶,凡舊時代繁體字著作皆搜羅殆盡付之一炬。
  爺爺找回了這套書認真研究,又從開放後的社會逐漸回歸的祭祖、嫁娶、安門儀式上發現了新的需求,此時的他開始留起了長長的白鬚,加上清瘦的外型,常戴著做石匠時習慣的黑框平視眼鏡,回想起來,還真是飄飄然有道骨仙風之感。不出幾年竟又成為了名震一方的風水先生。業務範圍包擴新屋安門定向、墓碑立向,還有為新人們選擇與生辰八字相匹配的黃道吉日等等。有時也非正式的跟大家算一算命理。爺爺並未正式包含這一項業務是因為在農村的約定俗成:算命是留給那些因先天或後天原因致盲的人的一項正式職業,雖然不是每個盲人都可以走上這項職業,這還要看個人天賦。我曾向爺爺介紹了一些來自西方的流行命理,就是關於星座,或稱西洋占星术。
  『你說西洋人算命,只根據月份就算出來了?』
  『這不科學呀。在中國要看出生年月日、還要有時辰,合為生辰八字,天道甲子六十年為一循環…』
  『其實現在西洋人自己都不信這個了,在中國反而會談點星座的越來越多了…』
  有時我也會嚷嚷說這是迷信,以後的人有文化有知識學科學,就不會有人再來看風水了。爺爺會假裝生氣的說,不可能吧,現在還是有很多人信啊,你看,省裡的大官有知識吧,也都派車來接我去看屋。我說這些大官迷信,爺爺說越是大官越相信這個,不是你說不信別人就不信的。是啊,這個社會的發展不是個人喜好所能預測的,有人回歸祖製想從風水中去尋一份心靈的安寧便自然有人去研究風水理論,這個行業師從戰國時代鬼谷子先生為祖師,歷朝歷代不斷有人添磚加瓦,早已成為中國傳統文化的一部分,又豈是個人能去杞人憂天的。像這舶來的星座理論,在西方早已式微,也不妨礙可以繼續在中國發揚光大。
  
  
  
  爺爺常說『人生七十古來稀,你們看我都活到八十多了還健健康康,在我們這個家族還從來沒有過的,已經知足了吧……』
  
  
(六)
  太平洋的風在持續的吹過,氤氳的霧氣中傳過來的是大洋彼岸的氣息吧。人們常說人去如燈滅,我在想的是人生命運無常。余光中在給初生才三天就亡故的幼子作了一篇《鬼雨》,描寫太平洋上無時無盡、無晝無夜的雨,傾灑在小島上,只有無盡的哀思。我記起了魔戒中鄧不利多墜堐的場景,一位清瘦白鬚的長者形象,在時代變遷面前不斷輾轉求存,從不向命運低頭,直至最終殞落。
  東臨米慎峰(MissionPeak),我見到初升的旭日冉冉升起,在人們的歡呼聲中冉冉升起,給林海間的蒼翠在剎那間披上了金色的光芒,我知道在這太陽的背後如果有一個天國,我的爺爺在那條路上一定不會悲傷,繼續做一個執著而樂觀的人。

Wednesday, September 14, 2011

run MegaCli under Linux kernel 3.0 with LD_PRELOAD a fake uname


the MegaCli tool seems doesn't recognize the kernel 3.0; even the latest 8.02.16_MegaCLI
http://www.lsi.com/products/storagecomponents/Pages/MegaRAIDSAS9240-8i.aspx#misc

Since lsi only provides its binary, we cannot know what is lsi internally doing, what we can do is only to strace it,

Gentoo-11 tmp # env -i strace -v -e execve,open,ioctl,uname ./opt/MegaRAID/MegaCli/MegaCli64 -adpCount
execve("./opt/MegaRAID/MegaCli/MegaCli64", ["./opt/MegaRAID/MegaCli/MegaCli64", "-adpCount"], []) = 0
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib64/libpthread.so.0", O_RDONLY) = 3
open("/lib64/libncurses.so.5", O_RDONLY) = 3
open("/lib64/libdl.so.2", O_RDONLY)     = 3
open("/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/libstdc++.so.6", O_RDONLY) = 3
open("/lib64/libm.so.6", O_RDONLY)      = 3
open("/lib64/libgcc_s.so.1", O_RDONLY)  = 3
open("/lib64/libc.so.6", O_RDONLY)      = 3
                                     
open("/proc/devices", O_RDONLY)         = 3
open("/dev/megaraid_sas_ioctl_node", O_RDONLY) = 3
open("/proc/devices", O_RDONLY)         = 4
uname({sysname="Linux", nodename="Gentoo-11", release="3.0.0-gentoo-r1", version="#1 SMP Mon Aug 1 02:33:28 UTC 2011", machine="x86_64"}) = 0
open("/proc/scsi/megaraid_sas/hba_map/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/proc/scsi/megasr/hba_map/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
ioctl(3, MCE_GET_RECORD_LEN or MEMGETINFO or MFB_SET_CHROMA_KEY or MTRRIOC32_SET_ENTRY or MTRRIOC_SET_ENTRY, 0x790880) = -1 ENODEV (No such device)

Controller Count: 0.
open("MegaSAS.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4

Exit Code: 0x00
open("MegaSAS.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4

we found it tried a uname to get system info, then try to read the driver's proc file "/proc/scsi/megaraid_sas/hba_map/", but the current system has megaraid_sas driver but doesn't provide that proc file; through searching online I found that proc file was provided by a megaraid legacy driver in Linux-2.4 kernel, so the problem is probably here, the MegaCli doesn't recognize the kernel release "3.0.0-gentoo-r1" from uname system call, and judged it as Linux-2.4; dam it;

What I clearly remember is several months ago in last Gentoo-11.1 livedvd (surely with linux kernel 2.6) the MegaCli was still working, so the following is how can we fool MegaCli's uname system call as Linux kernel 2.6?

The answer is to fake a uname syscall via LD_PRELOAD;

Gentoo-11 tmp # cat fake-uname.c
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/utsname.h>

#include <stdio.h>
#include <string.h>

int uname(struct utsname *buf)
{
 int ret;

 ret = syscall(SYS_uname, buf);

 printf("uname release: \"%s\"\n", buf->release);
 strcpy(buf->release, "2.6.40");
 printf("uname release set to: \"%s\"\n", buf->release);
 printf("uname version: \"%s\"\n", buf->version);

 return ret;
}

Save it as fake-uname.c, and compile it with

Gentoo-11 tmp # gcc -Wall -fPIC -c fake-uname.c
Gentoo-11 tmp # gcc -Wall -shared -o libfake-uname.so fake-uname.o

Now we get libfake-uname.so, use LD_PRELOAD=./libfake-uname.so to preload it, over uname from glibc:

Gentoo-11 tmp # LD_PRELOAD=./libfake-uname.so LD_LIBRARY_PATH=./opt/lsi/3rdpartylibs/x86_64 ./opt/MegaRAID/MegaCli/MegaCli64 -adpCount
                                     
uname release: "3.0.0-gentoo-r1"
uname release set to: "2.6.40"
uname version: "#1 SMP Mon Aug 1 02:33:28 UTC 2011"

Controller Count: 1.

Exit Code: 0x01

Found the controller! And the strace log:
...
open("/lib64/libc.so.6", O_RDONLY)      = 3
                                     
open("/proc/devices", O_RDONLY)         = 3
open("/dev/megaraid_sas_ioctl_node", O_RDONLY) = 3
open("/proc/devices", O_RDONLY)         = 4
uname({sysname="Linux", nodename="Gentoo-11", release="3.0.0-gentoo-r1", version="#1 SMP Mon Aug 1 02:33:28 UTC 2011", machine="x86_64"}) = 0
uname release: "3.0.0-gentoo-r1"
uname release set to: "2.6.40"
uname version: "#1 SMP Mon Aug 1 02:33:28 UTC 2011"
open("./opt/lsi/3rdpartylibs/x86_64/tls/x86_64/libsysfs.so.2.0.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("./opt/lsi/3rdpartylibs/x86_64/tls/libsysfs.so.2.0.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("./opt/lsi/3rdpartylibs/x86_64/x86_64/libsysfs.so.2.0.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("./opt/lsi/3rdpartylibs/x86_64/libsysfs.so.2.0.2", O_RDONLY) = 4
open("/sys/class/scsi_host", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/sys/class/scsi_host", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/sys/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0/proc_name", O_RDONLY) = 4
open("/sys/devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1/proc_name", O_RDONLY) = 4
open("/sys/devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2/proc_name", O_RDONLY) = 4
open("/sys/devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3/proc_name", O_RDONLY) = 4
open("/sys/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4/proc_name", O_RDONLY) = 4
open("/sys/devices/pci0000:00/0000:00:1f.1/host5/scsi_host/host5/proc_name", O_RDONLY) = 4
open("/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/host7/scsi_host/host7/proc_name", O_RDONLY) = 4
ioctl(3, MCE_GET_RECORD_LEN or MEMGETINFO or MFB_SET_CHROMA_KEY or MTRRIOC32_SET_ENTRY or MTRRIOC_SET_ENTRY, 0x790420) = 0

Controller Count: 1.
open("MegaSAS.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4

Exit Code: 0x01
open("MegaSAS.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4