Завантажте систему Linux з підкаталогу на розділі?


11

Я хотів би спробувати налаштувати комп'ютер так, щоб він мав декілька встановлень Linux, все в одній файловій системі. Наприклад, filesytem матиме 3 папки: /Ubuntu_Precise, /Ubuntu_Oneiricі /Ubuntu_Natty.

(Я знаю, що ви можете зробити це за допомогою BTRFS і підтомників, але я хотів би використовувати EXT4 для швидкості).

Одного разу я встановив декілька встановлень різних дистрибутивів за допомогою BTRFS, і, працюючи з цим, я знаю, що Grub справляється із завантаженням vmlinuz та initrd-зображення з "нестандартних" шляхів. Але коли я робив річ BTRFS, там було те, rootflags=subvol=@<subvolume_name>що казало ядру монтувати цей підтомник як / у файловій системі. Чи є якийсь аргумент, щоб ви могли передавати ядро, яке змусило б його зв'язати монтувати підпапку в розділ як /, а потім завантажитися?

Я думаю, що для інших частин я досить близький. Я знаю, як конкретно встановити прив'язку /etc/fstab. Крім того, коли я налаштовував свою систему з кількома встановленнями Linux в підтомниках BTRFS, я звик встановлювати дистрибутив у віртуальний комп'ютер, а потім мігрувати його за допомогою rsync, тому я не надто переживаю, що мені потрібно робити отримати правильну конфігурацію, я просто намагаюся з’ясувати, якою буде правильна конфігурація. Як тільки я знаю це, я повинен мати можливість зробити міграцію в підпапки та редагування файлів досить легко.

Я вже знаю про віртуалізацію та розділи, але це не те, що я шукаю. Цільовий комп'ютер не має достатньої потужності для віртуалізації, а розділи не ділять вільного місця. Я хочу налаштувати систему, яка dual / triple / quad / etc завантажує Linux-дистрибутив, але це робить це з однією файловою системою, так що немає випадків "у мене вільний простір, але він знаходиться в неправильному розділі!"

Якщо у когось є пропозиції, як відредагувати моє запитання чи його назву, щоб бути зрозумілішим, я все чую.


1
У системі AFAIK нічого не вбудовано. Напевно, вам доведеться зробити ще один завантажувальний параметр і змінити свої інітрами, щоб вони входили в підкаталог перед виконанням init
Ульріх Дангел

@UlrichDangel - це те, що я збирався запропонувати. Зробіть це відповіддю!
Нілс

@Nils ok, я просто дав відповідь, тбг. Я не хотів спочатку писати його, оскільки не хотів надавати патч / сценарій
Ульріх Дангель,

Відповіді:


10

Коротка відповідь - наскільки я не знаю, не існує справжнього робочого рішення для ваших конкретних вимог. Вам потрібно буде налаштувати всі initramfs кожного дистрибутива, щоб підтримувати ваші конкретні потреби.

Довга відповідь - так це можливо. В даний час більшість дистрибутивів Linux використовує initramfs, який завантажується в пам'ять завантажувачем, а потім розпаковується ядром. Там він запуститься, /sbin/initякий відповідає за налаштування раннього простору користувачів (запуск udev, завантаження модулів, запуск plymouth, прохання крипто-парольної фрази, налаштування мережі для мережевих кріплень,… ви її називаєте). Оскільки ви можете запускати власні сценарії та оцінювати власні завантажувачі.

Приклад для Debian

Якщо ви використовуєте Debian (має бути однаково з Ubuntu), ви маєте змогу розмістити сценарій, в /etc/initramfs-tools/scripts/init-bottom/якому буде виконано виконання до запуску init. Для отримання додаткової інформації про сценарій, різні каталоги та макет ознайомтеся з інструментами man 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

Ідея полягає в тому, щоб відрегулювати те, rootmnt що використовується в initсценарії initramfs для запуску / виконання справжнього init. Оскільки кореневий пристрій вже встановлений на init-bootomетапі, ви можете просто налаштувати / змінити цільовий каталог.

Щоб використовувати цей скрипт, просто додайте новий параметр завантаження, скопіюйте його, зробіть його виконуваним, відновіть свої initramfs та додайте параметр завантаження для вашого дистрибутиву Linux, наприклад rootdir=/Ubuntu_Precise.


Ви також, ймовірно, хочете прив’язати монтування справжнього кореня до підкаталогу кореня OS, щоб ви могли бачити інші файли ОС із завантаженого.
psusi

@psusi Ви можете це зробити через fstab або просто безпосередньо mount /dev/rootdevice /mountpointпісля запуску системи
Ульріх Дангел,

Цікаво, коли це змінилося? Ви раніше не мали змоги знову встановити той самий блок пристроїв; ви отримаєте EBUSY.
psusi

1
@psusi не впевнений, але, ймовірно, із введенням бандажів для зв'язування
Ульріх Дангел

@UlrichDangel Дякую за (дуже) детальну відповідь!
Azendale

3

Ось два способи роботи в ubuntu bionic (а можливо і в інших місцях). у мене недостатньо респ. для коментарів, але, bionic: / usr / share / initramfs-tools / init виглядає в / etc / fstab for / usr відразу після виклику mountroot та перед викликом сценаріїв * -ttom, тому додаючи init- нижній сценарій (як запропоновано в іншій відповіді тут) "занадто пізно". замість цього я рекомендую такі:

#!/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:  requires bin/bash in the partition root executable by $sub/vmlinux (ie $sub same or newer than partition root)
#   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

Це спрацювало для мене
частування

1

Завантаження різних Linux без пов'язування з таблицею розділів цікаво для різних цілей, альтернативним рішенням спільної файлової системи є використання томів циклу, тут потрібні декілька змін, припускаючи, що у файловій системі / dev / sdb1 є файл / цикл debian (Я використовую поточний GNU / Debian sid / нестабільний як для основного, так і для циклу ОС).

/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
}

Аргументи, визначені в grub як командний рядок linux, встановлюються env initrd / init, таким чином:

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

циклі дозволяють монтувати гучність над "самою", потік сценарію за замовчуванням робимо a, mount /dev/sdb1 /rootми просто необов'язково перекомпонуємо / dev / sdb1 як rw, якщо це було ro, то завжди додаємо a 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 вдвічі збільшує ймовірність відмови файлової системи, але здогадуйтесь, що певна настройка може бути виконана. Можливо, є кращий спосіб використовувати цикл, менше хакі, якщо є, будь ласка, повідомте мене, тому що я не знайшов.


0

Це не відповідь, але я хочу уточнити деякий момент щодо відповіді та коментарів Ульріха (я не можу коментувати вище).

Рішення, яке пропонує Ульріх, "може" працювати (ще не перевірено), але тоді ви отримаєте файлову систему, що не відзначається . Як вирішення (IMHO некрасиво), ви можете встановити fs як rw перед хроніруванням ( як тут пропонується ), але будьте обережні щодо зламаних сценаріїв init. Я думаю, що в цьому вирішенні є більше побічних ефектів (наприклад, непрацездатні файли, які намагаються переробити ро-си і не вдається).

Я використовую ядро ​​3.2 з ext4 і монтування вже встановленого диска всередині chroot все ще дає EBUSY, як прокоментував psusi.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.