manjaro (arch)安裝完成後重啓報錯:Root device mounted successfully, but sbininit does not exist

manjaro (arch) 安裝完成後重啓報錯:Root device mounted successfully, but /sbin/init does not exist.

前言

這個問題是我的大佬同學賴拐發現的,估計也有很多和他一樣被鳥叔帶入門linux的童鞋吧?哈哈,只能說實在可惜第三版出的時間太過久遠(八年前),據說第四版已經出啦(今年十一),大家有能力去支持一下吧~

問題

言歸正傳,錯誤應該是在我們開開心心裝好manjaro之後重啓,本以爲可愛的plasma-kde出現,結果出來了黑不溜秋的報錯提示:

ERROR: Root device mounted successfully, but /sbin/init does not exist.

sh:can't access tty; job control turned off

[rootfs /]#

**實際上真正的原因是我們把/usr掛載在了單獨的分區上。**具體的原因可以參考stackexchange的一篇問答,很有價值。這裏稍作引用

As @Leiaz very correctly pointed out in the comments, /sbin in Arch (and by extension, Manjaro) is now a symlink to /usr/bin. This means that unless /usr is mounted, /usr/sbin/init will not exist. You therefore need to make sure that /usr is mounted by the initial ramdisk. That’s what the Arch wiki quote in your OP means:

If you keep /usr as a separate partition, you must adhere to the following requirements:

  • Enable mkinitcpio-generate-shutdown-ramfs.service or add the shutdown hook.
  • Add the fsck hook, mark /usr with a passno of 0 in /etc/fstab. While recommended for everyone, it is mandatory if you want your /usr partition to be fsck’ed at boot-up. Without this hook, /usr will never be fsck’d.
  • Add the usr hook. This will mount the /usr partition after root is mounted. Prior to 0.9.0, mounting of /usr would be automatic if it was found in the real root’s /etc/fstab.

白話文就是:開機的時候需要訪問/sbin/init下的文件,但是這個文件不存在。因爲arch及其衍生版對於從前老式的/sbin, /bin, /lib的處理是直接用一個鏈接指向/usr/sbin, /usr/bin, /usr/lib,但是剛開機的時候,你的/usr(因爲是單獨的分區)還沒有掛載上去呢~

如果想多理解一些的話,建議參考一下我的另一篇博客,在Manjaro安裝配置小記裏有詳細解釋爲什麼ubuntu、debian這類系統可以單獨把/usr分出來(主要是一些歷史遺留問題)。


怎麼辦?

不把/usr分出來,保持其和根目錄在一起

解決方案很直接,直接的辦法就是不要把/usr單獨分出來,保持它和根目錄在一起就好。

不過能看到這個帖子的人至少應該是嘗試過把/usr單獨分出來的,那這裏稍微討論一下把/usr單獨分出來的必要性:

先說說爲什麼要分出來:

裝系統的時候分區是個技術活,而一般來說我們都會把這些掛載點單獨分區分出來,依據是FHS的標準建議:根目錄所在分區應該越小越好,且應用程序所安裝的軟件最好不要與根目錄放在同一個分區內。保持根目錄越小越好。如此不但性能較好,根目錄所在的文件系統也較不容易發生問題

翻譯一下就是你係統出問題的時候,可以保護其他部分的數據。

根據鳥叔的linux私房菜第三版和個人經驗:

 -   /
 -   /tmp
 -   /boot
 -   /usr
 -   /home
 -   /var
 -   SWAP
 -   /opt
 -   ….

鳥哥的私房菜和一些教程,以及一些歷史原因的確成爲了大多數把/usr分出來的人的理由,像對用戶比較友好的ubuntu、debian發行版也的確保留了/bin,/sbin這些目錄,但是對於激進的arch及它的衍生髮行版就不這麼想了,畢竟這些實屬歷史遺留的目錄,arch設計的宗旨是完全可定製化輕量級的操作系統,所以就二話不說移走了。

不分出來的理由是這樣的:

先引用一段v2ex上的評論:

algas 2015-05-10 19:21:02 +08:00

/usr單獨分出來沒有什麼必要,我甚至覺得這樣做有副作用。重裝系統的時候,如果安裝的系統版本高於之前的,/usr/lib之類的東西都應該覆蓋,而不是直接掛在/usr(大概是這樣的)。倒是/usr/local/比較推薦單獨分區。雖然opt是設計給第三方軟件的,但是opt並沒有默認的bin目錄,而且很多軟件默認就選擇了/usr/local位置,所以,是吧。

我對這個解釋是比較認可的,就好像現在windows上的office、騰訊qq這些即使你按在了D盤,C盤重裝之後還不是得重新安裝這些軟件,因爲像註冊表啊依賴啊這些東西C盤裏的都沒了嘛,去補這個那個還不如重新安裝來的簡單快捷。/usr下的東西也是同理可得,即使分出來了,許多依賴還沒有的話,也是一樣需要reinstall,那乾脆和/一起重裝得了。

另一個石錘是鳥叔在2018-10-01出的linux私房菜第四版裏也不再把/usr單獨劃分出來,推薦劃分的只有下面5個。

在這裏插入圖片描述

我的分區方案是:

  • /boot
  • /boot/efi
  • SWAP
  • /
  • /opt
  • /var
  • /home
  • /tmp

如果有多系統的話,還需要把/boot/efi掛載到之前系統的引導分區裏(僅限UEFI),一個詳細的分區方案及介紹可以參考我的一篇博客Manjaro安裝配置小記

依然想把/usr分出來

這個方案我個人沒有去實施,畢竟有點難度,需要考慮引導、hook之類的東西,其實原理上主要是一下兩種:

  • 提前把/usr下的一些東西提前掛上去
  • 或者是考慮直接把/usr/sbin這類軟鏈接刪除掉,然後把/usr下的拷出去

這裏提供stackexchange大佬參考manjaro提供的解決方案

So, you need to generate a new init file with the right hooks1. These are added by changing the HOOKS="" line in /etc/mkinitcpio.conf. So

  1. Boot into Mint and mount the Manjaro / directory:

    mkdir manjaro_root && sudo mount /dev/sda11 manjaro_root
    

    Now, Manjaro’s root will be mounted at ~/manjaro_root.

  2. Edit the mkinitcpio.conf file using your favorite editor (I’m using nano as an example, no more):

    sudo nano ~/manjaro_root/etc/mkinitcpio.conf
    

    Find the HOOKS line and make sure it contains the relevant hooks

    HOOKS="shutdown usr fsck"
    

    Important" : do not remove any of the hooks already present. Just add the above to those there. For example, the final result might look like

    HOOKS="base udev autodetect sata filesystems shutdown usr fsck"
    
  3. Mark /usr with a passno of 0 in /etc/fstab. To do this, open manjaro_root/etc/fstaband find the /usr line. For this example, I will assume it is /dev/sda12 but use whichever one it is on your system. The “pass” number is the last field of an /etc/fstab entry. So, you need to make sure the line looks like

    /dev/sda12  /usr  ext4  rw,errors=remount-ro     0      0
                                                            ^
                             This is the important one -----|
    
  4. Create the new init image. To do this, you will have to mount Manjaro’s /usr directory as well.

    sudo mount /dev/sda12 ~/manjaro_root/usr
    

    I don’t have much experience with Arch so this might not bee needed (you might be able to run mkinitcpio without a chroot) but to be on the safe side, set up a chroot environment:

    sudo mount --bind /dev ~/manjaro_root/dev && 
    sudo mount --bind /dev/pts ~/manjaro_root/dev/pts && 
    sudo mount --bind /proc ~/manjaro_root/proc && 
    sudo mount --bind /sys ~/manjaro_root/sys &&
    sudo chroot ~/manjaro_root
    

    You will now be in a chroot environment that thinks that ~/manjaro_root/ is actually /. You can now go ahead and generate your new init image

    mkinitcpio -p linux
    
  5. Exit the chroot

    exit
    
  6. Update your grub.cfg (again, this might not actually be needed):

    sudo update-grub
    

不過我都沒實際操作,要是有感興趣的小夥伴實施了可以給我反饋一下嘻嘻嘻。

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