![파티션의 하위 디렉터리에서 Linux 시스템을 부팅하시겠습니까?](https://linux55.com/image/48539/%ED%8C%8C%ED%8B%B0%EC%85%98%EC%9D%98%20%ED%95%98%EC%9C%84%20%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%EC%97%90%EC%84%9C%20Linux%20%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%9D%84%20%EB%B6%80%ED%8C%85%ED%95%98%EC%8B%9C%EA%B2%A0%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
동일한 파일 시스템에 여러 개의 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을 사용하는 경우(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(그리고 아마도 다른 곳에서도)에서 작동하는 두 가지 방법은 다음과 같습니다. 의견을 제시할 담당자가 충분하지 않지만 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를 부팅하는 것은 흥미로울 것입니다. 공유 파일 시스템을 위한 또 다른 해결책은 순환 볼륨을 사용하는 것입니다. 여기에 /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를 설치하면 파일 시스템 오류 가능성이 두 배로 높아지는지 궁금하지만 약간의 조정이 있을 수 있다고 추측합니다. 아마도 루프를 덜 해킹적으로 사용하는 더 좋은 방법이 있을 것입니다. 만약 있다면 아직 찾지 못했기 때문에 알려주시기 바랍니다.
답변4
이것은 답변은 아니지만 Ulrich의 답변과 의견에 대한 몇 가지 사항을 명확히하고 싶었습니다 (위에 언급할 수 없습니다).
Ulrich가 제안한 솔루션은 "작동할 수 있습니다"(아직 테스트되지 않음).파일 시스템을 다시 설치할 수 없습니다.. 해결 방법(IMHO 추악함)으로 chroot 전에 fs를 rw로 마운트할 수 있습니다(여기에 제안된 대로) 하지만 깨진 초기화 스크립트에 주의하세요. 이 해결 방법에는 더 많은 부작용이 있는 것 같습니다(예: 손상된 fs가 ro를 다시 설치하려고 시도하고 실패하는 것과 같은).
저는 ext4와 함께 커널 3.2를 사용하고 있으며 chroot 내부에 개발을 설치했지만 psusi가 언급한 대로 여전히 EBUSY를 제공합니다.