linux核心md原始碼解讀 二 md模組初始化

來源:互聯網
上載者:User

在編譯完成linux核心原始碼的時候,drivers/md目錄下會產生多個ko檔案,那麼這些核心模組哪一個先載入,哪一個後載入的呢?例如md-mod.ko, raid5.ko, raid10.ko,這些模組是一起載入的呢,還是有先後順序呢?如果熟悉linux核心編程的話,知道有一個request_module函數,這個函數用於請求載入一個模組,但這個函數並不能說明一個模組對另一個模組的依賴關係。準確的資訊還是來自於Kconfig,這裡只抽取Kconfig中相關的部分:

config BLK_DEV_MD

tristate "RAID support"

config MD_RAID10

tristate "RAID-10 (mirrored striping) mode"

depends on BLK_DEV_MD

config MD_RAID456

tristate "RAID-4/RAID-5/RAID-6 mode"

depends on BLK_DEV_MD

從這裡我們可以看出,raid5.ko, raid10.ko都是依賴於md-mod.ko的,這就決定了我們的閱讀方向是從md-mod.ko中開始的。

那麼md-mod.ko中又是從哪個檔案開始的呢?這就要找module_init函數,這個函數在md.c中定義的,那麼就從這裡入手。

8416 static int __init md_init(void)  8417 {  8418         int ret = -ENOMEM;  8419   8420         md_wq = alloc_workqueue("md", WQ_MEM_RECLAIM, 0);  8421         if (!md_wq)  8422                 goto err_wq;  8423   8424         md_misc_wq = alloc_workqueue("md_misc", 0, 0);  8425         if (!md_misc_wq)  8426                 goto err_misc_wq;  8427   8428         if ((ret = register_blkdev(MD_MAJOR, "md")) < 0)  8429                 goto err_md;  8430   8431         if ((ret = register_blkdev(0, "mdp")) < 0)  8432                 goto err_mdp;  8433         mdp_major = ret;  8434   8435         blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,  8436                             md_probe, NULL, NULL);  8437         blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,  8438                             md_probe, NULL, NULL);  8439   8440         register_reboot_notifier(&md_notifier);  8441         raid_table_header = register_sysctl_table(raid_root_table);  8442   8443         md_geninit();  8444         return 0;  8445   8446 err_mdp:  8447         unregister_blkdev(MD_MAJOR, "md");  8448 err_md:  8449         destroy_workqueue(md_misc_wq);  8450 err_misc_wq:  8451         destroy_workqueue(md_wq);  8452 err_wq:  8453         return ret;  8454 }

模組的初始化過程看起來異常地簡單,這就像有些人表面看起來十分普通,內心裡卻無比地強大,所以不要只看外表,還要聽其言觀其行。內在的美麗比外表的榮華更具吸引力和持久性。

8420和8424行,分別建立了工作隊列,md_wq是用於flush命令的,另一個md_misc_wq,misc是miscellaneous的簡寫,是雜項的意思,用於處理一些零零碎碎的事情。

8428和8431行,建立了兩個塊裝置,剛開始我只注意md的裝置,壓根沒在意mdp,搜尋變數mdp_major,在函數autorun_devices中使用了這個變數:

5474                 if (part) {  5475                         dev = MKDEV(mdp_major,  5476                                     rdev0->preferred_minor << MdpMinorShift);  5477                         unit = MINOR(dev) >> MdpMinorShift;  5478                 } else {  5479                         dev = MKDEV(MD_MAJOR, rdev0->preferred_minor);  5480                         unit = MINOR(dev);  5481                 }

5474行,變數part是函數傳入參數,表示磁碟第幾個分區,那麼就知道mdp_major中字母p是表示part的意思,而mdp_major就表示用磁碟分割建立的陣列。8435和8437行,建立了兩個region,這兩個函數的作用是在使用者態建立了一個/dev/md*裝置時,核心態就會對應調用md_probe建立一個mddev結構體,之後在使用者態對/dev/md*的操作到核心態就相應地對mddev的操作了。8440行,註冊關機回呼函數,主要作用是停止陣列線程,刷資料操作。8441行,註冊sysctl函數,用於控制陣列最小和最大的sync速度。8443行,註冊proc函數,於是有了目錄/proc/mdstat,該目錄的顯示由函數md_seq_show控制。md初始化代碼就這樣輕鬆地完成了,可是回到我們的初衷,仍然對md裝置一無所知。那麼md裝置是如何建立的呢?建立的過程又是怎麼的呢?一個陣列擁有哪些資源?下一節我們直入核心,開始閱讀陣列建立的過程。

出處:http://blog.csdn.net/liumangxiong

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.