パーティションのサブディレクトリからLinuxシステムを起動しますか?

パーティションのサブディレクトリからLinuxシステムを起動しますか?

同じファイルシステムに複数のLinuxをインストールするようにコンピュータを設定したいと思います。たとえば、ファイルシステムには/Ubuntu_Precise/Ubuntu_Oneiricおよび3つのフォルダがあります/Ubuntu_Natty

(BTRFSとサブボリュームを使用してこれを実行できることを知っていますが、速度のためにEXT4を使用したい)。

私はBTRFSを使用してさまざまなディストリビューションの複数のインストールを設定し、それを機能させることでGrubが「非標準」パスからvmlinuzイメージとinitrdイメージを起動できることを知っています。ところで、BTRFSをするときにrootflags=subvol=@<subvolume_name>ファイルシステムからサブボリュームを/にマウントするようにカーネルに指示するコマンドがありました。パーティションのサブフォルダを/にバインドマウントしてから起動するようにカーネルに渡すことができるパラメータはありますか?

他の部分においてはほぼ似ていると思います。/etc/fstabまた、BTRFSサブボリュームに複数のLinuxがインストールされているシステムを設定したときから、仮想マシンにディストリビューションをインストールしてからrsyncを使用して移行することに慣れていたため、あまり心配しません。私は正しい設定を得るために何をすべきかについて正しい設定が何であるかを見つけようとしています。これがわかったら、サブフォルダに簡単に移行してファイルを編集できます。

私はすでに仮想化とパーティショニングについて知っていますが、それは私が望むものではありません。ターゲットコンピュータに仮想化に十分な電力がなく、パーティションが空き容量を共有しません。 Linuxディストリビューションをデュアル/トリプル/クワッド/など起動するようにシステムを設定しようとしていますが、「空き容量がありますが間違ったパーティションにあります!」という問題が発生しないように、ファイルシステムを使用してください。

誰もが私の質問やタイトルをより明確に編集する方法についての提案があれば耳を傾けます。

答え1

短い答え - 私が知っている限り、あなたの特定の要件に合うようにすぐに機能する解決策はありません。特定の要件をサポートするには、各ディストリビューションの各initramfsを調整する必要があります。

長い答え - はい、可能です。今日、ほとんどのLinuxディストリビューションはブートローダによってメモリにロードされ、カーネルによって解凍されるinitramfsを使用しています。そこで実行され、/sbin/init初期ユーザースペースの設定(udevの実行、モジュールのロード、plymouthの起動、暗号化パスワードの要求、ネットワークインストールのためのネットワーク設定など)を担当します。これは、独自のスクリプトを実行してカスタム起動パラメータを評価できるためです。

Debian はい

Debianを使用している場合(Ubuntuと同じである必要があります)、/etc/initramfs-tools/scripts/init-bottom/initが起動する前に実行されるスクリプトを配置できる必要があります。スクリプト、さまざまなディレクトリ、レイアウトの詳細については、以下を確認してください。男 initramfs - ツールrootmntターゲットディレクトリを調整して追加する必要があります。

/etc/initramfs-tools/scripts/local-bottom/00-myrootサンプル(テストされていない)スクリプトは、または次のようにインストールする必要があります/usr/share/initramfs-tools/scripts/init-top/00-myroot

#!/bin/sh -e

PREREQS=""

prereqs() { echo "$PREREQS"; }

case "$1" in
  prereqs)
  prereqs
  exit 0
;;
esac

for opt in $(cat /proc/cmdline); do
  case $opt in
    rootdir=*)
      new_mntdir="${opt#rootdir=}"
      ;;
    esac
done

if [ -n "$new_mntdir" ] ; then
  echo rootmnt="$rootmnt/$new_mntdir" >> /conf/param.conf
fi

アイデアは、実際のinitを起動/実行するためにrootmnt 使用されるinitramfsスクリプトを調整することです。initルートデバイスはすでにinit-bootomステージにインストールされているため、ターゲットディレクトリのみを調整/変更できます。

このスクリプトを使用するには、新しいブートパラメータを追加し、スクリプトをコピーし、実行可能にし、initramfsを再構築し、Linuxディストリビューションのブートパラメータ(たとえばrootdir=/Ubuntu_Precise

答え2

Ubuntu Focus&Bionic(そしておそらく他の場所でも)で動作する2つの方法は次のとおりです。コメントを提示する担当者は十分ではありませんが、bionic:/usr/share/initramfs-tools/init は mountroot を呼び出した後、*-bottom スクリプトを呼び出す前に /etc/fstab で /usr を探します。したがって、init-bottomを追加します。 (他の答えで提案されているように)スクリプトが「遅すぎます」。代わりに、以下をお勧めします。

#!/bin/bash -f
#copyleft 2018 greg mott

#set a subdirectory as root (so multiple installs don't need partitions)
#these work in ubuntu bionic, might need tweaking to work elsewhere
#1st choice:  tweak initramfs-tools/scripts/local
#   pro:  $sub becomes root directly, nothing gets any chance to see the partition root
#   con:  requires the subdirectory's initramfs/initrd to be tweaked and rebuilt
#2nd choice:  specify this scriptfile as init= on the kernel commandline
#   pro:  no need to rebuild initramfs
#   con:  bin/bash in partition root must be executable by $sub/vmlinux (partition root older than $sub likely will work)
#   con:  if the partition root etc/fstab mounts /usr, the $sub initramfs will mount the partition root /usr
#   con:  additional initramfs scripts might also look in the partition root rather than $sub

#for either choice copy /etc/grub.d/40_custom to /etc/grub.d/07_custom and add one or more menuentries that specify subroot:
#menuentry "subroot foo" {
#     echo "subroot foo"
#              sub=/foo
#             uuid=22e7c84a-a416-43e9-ae9d-ee0119fc3894         #use your partition's uuid
#     search --no-floppy --fs-uuid --set=root $uuid
#            linux $sub/vmlinuz ro root=UUID=$uuid subroot=$sub
#     echo "initrd $sub/initrd.img"
#           initrd $sub/initrd.img      #works in recent releases where the /initrd.img softlink is relative
#}

#for the 2nd choice, in addition to subroot= on the kernel commandline also specify:
#   init=/path/to/script        #pathname from partition root to this scriptfile (chmod 744)

#for the 1st choice, the tweak for bionic:/usr/share/initramfs-tools/scripts/local is replace:
#          mount ${roflag} ${FSTYPE:+-t ${FSTYPE} }${ROOTFLAGS} ${ROOT} ${rootmnt}
#          mountroot_status="$?"
#with:
#          set -x
#          karg=" $(cat<proc/cmdline) " m=${karg#* subroot=}
#          [ "$m" = "$karg" ]||subroot=${m%% *}                                  #extract subroot from kernel commandline
#          [ $subroot ]&&part=part||part=$rootmnt                                #no subroot, just mount partition as root
#          mkdir part
#          mount ${roflag} ${FSTYPE:+-t ${FSTYPE} }${ROOTFLAGS} ${ROOT} $part&&  #mount partition
#             if [ "$subroot" ]
#             then mount --bind part/$subroot $rootmnt&&                         #mount subroot
#                  umount part                       #&&sleep 15                 #unmount partition root (uncomment &&sleep for time to watch)
#             fi
#          mountroot_status="$?"
#          [ $mountroot_status = 0 ]||sleep 90                                   #if error pause to see it
#          set +x
#once you've edited /usr/share/initramfs-tools/scripts/local, update-initramfs -u will rebuild for the current kernel,
#and it will automatically build into every new initrd/initramfs installed thereafter

subroot(){ karg=" $(cat<proc/cmdline) " m=${karg#* subroot=}
           [ "$m" = "$karg" ]||subroot=${m%% *}                 #extract subroot from kernel commandline
           [ $subroot ]||return 0                               #no subroot, just proceed in partition root
           while read -r m r m
           do for m in $M x                                     #build list of what's already mounted
              do    [[ $r = $m* ]]&&break                       #exclude subtrees (eg dev/**)
              done||[[ $r = /   ]]||M=$M\ $r                    #exclude /
           done<proc/mounts
           (set -x;mount --bind $subroot mnt)||{ set -x         #mount subroot
                                                 sleep 30          #if not found pause to see error
                                                 return 0;}        #then reincarnate as partition root init
           for m in $M
           do (set -x;mount -n --move $m mnt$m)||return         #move listed mounts to subroot
           done
           set -x
           cd           mnt&&
           pivot_root . mnt&&                                   #subroot becomes root
           umount -l    mnt&&                                   #unmount partition root
          #sleep 15        &&                                   #so far so good?  uncomment for time to look
           exec chroot . init "$@"                              #reincarnate as subroot init
}
subroot "$@"&&exec init "$@"||exec bash                         #land in a shell if moves or pivot fail

答え3

他の目的のためにパーティションテーブルに触れることなく他のLinuxを起動することは興味深いでしょう。共有ファイルシステムのもう1つの解決策は循環ボリュームを使用することです。ここに/ debian循環ファイル/ボリュームがあるとしましょう。 /dev/sdb1ファイルシステム(メインOSとループOSで現在GNU / Debian sid / unstableを使用しています)。

/etc/grub.d/40_custom: # outside from loop volume
menuentry 'label' --class gnu-linux --class gnu --class os {
    ...
    loopback loop (hd2,msdos1)/debian
    linux   (loop)/boot/vmlinuz root=/dev/sdb1 loop=/debian ro
    initrd  (loop)/boot/initrd
}

Linuxコマンドラインでgrubで定義されたパラメータは、initrd / initによってenvに設定されます。したがって、次のようになります。

ROOT=/dev/sdb1
rootmnt=/root
loop=/debian 

ループを使用すると、ボリュームを「自己」にマウントできます。デフォルトのスクリプトフロー実行では、mount /dev/sdb1 /root/dev/sdb1 を rw (ro の場合) に再マウントし、常にmount -o loop /root/debian /root.

/etc/initramfs-tools/scripts/local-bottom/loop: # inside the loop volume
#!/bin/sh

[ "$1" = "prereqs" ] && echo && exit 0

if [ -n "${loop}" ]; then
        if [ "${readonly}" = "y" ]; then
                roflag=-r
                mount -o remount,rw ${ROOT} ${rootmnt}
        else
                roflag=-w
        fi
        mount ${roflag} -o loop ${rootmnt}${loop} ${rootmnt}
fi

また、一部のモジュールをinitramにプリロードする必要があります(その後、update-initramfsを実行することを忘れないでください)。

/etc/initramfs-tools/modules: # inside the loop volume
...
loop
ext4

ループの使用がパフォーマンスやリソースの無駄にどのように影響するかはわかりませんが、ext4の上にext4をインストールすると、ファイルシステムのエラーの可能性が2倍になるのではないかと思いますが、いくつかの調整がある可能性があると思います。おそらくループをハッキングしにくくするより良い方法があります。もしあればまだ見つからなかったので教えてください。

答え4

これは答えではありませんが、Ulrichの答えとコメントに関するいくつかのことを明確にしたいと思いました(上記には言えません)。

Ulrichによって提案された解決策は「動作することができます」(まだテストされていません)。ファイルシステムを再インストールできません。。回避策(IMHOの醜い)では、chrootの前にfsをrwとしてマウントできます(ここで提案されているように)しかし、壊れた初期化スクリプトに注意してください。この回避策にはより多くの副作用があるようです(たとえば、破損したfsがroを再インストールしようとして失敗するなど)。

私はext4でカーネル3.2を使用しており、chrootの内部に開発をインストールしましたが、psusiが述べたようにまだEBUSYを提供しています。

関連情報