Linux sistemi bir bölümdeki bir alt dizinden önyükleme?


11

Aynı dosya sisteminde birden çok Linux yüklemesi olacak şekilde bir bilgisayar kurmayı denemek istiyorum. Örneğin, dosyasistemiyle 3 klasörleri olurdu: /Ubuntu_Precise, /Ubuntu_Oneiric, ve /Ubuntu_Natty.

(Bunu BTRFS ve alt hacimlerle yapabileceğinizi biliyorum, ancak hız için EXT4 kullanmak istiyorum).

Bir keresinde BTRFS kullanarak farklı dağıtımların birden fazla kurulumunu kurdum ve bu çalışmayı elde etmenin, Grub'un 'standart olmayan' yollardan vmlinuz ve initrd görüntüsünü önyüklemede iyi olduğunu biliyorum. Ama BTRFS olayını yaparken, rootflags=subvol=@<subvolume_name>çekirdeğe bu alt birimi dosya sisteminde / olarak monte etmesini söyleyen şeyler vardı. Bir alt bölümde / / ve sonra önyükleme olarak bağlama alt bağlayıcı bağlamak yapacak çekirdek geçebileceği herhangi bir argüman var mı?

Bence diğer kısımlar için oldukça yakınım. Bir bağlama parçasını nasıl belirleyeceğimi biliyorum /etc/fstab. Ayrıca, sistemimi BTRFS alt hacimlerinde birden çok linux yüklemesi ile kurduğumdan, bir VM'ye dağıtım dağıtmaya ve daha sonra rsync kullanarak geçirmeye alışkınım, bu yüzden ne yapmam gerektiğinden endişelenmiyorum doğru yapılandırmayı al, sadece doğru yapılandırmanın ne olacağını bulmaya çalışıyorum. Bunu öğrendikten sonra, alt klasörlere geçişi ve dosya düzenlemeyi yeterince kolay bir şekilde yapabilmeliyim.

Sanallaştırma ve bölümleri zaten biliyorum, ama aradığım şey bu değil. Hedef bilgisayarın sanallaştırma için yeterli gücü yok ve bölümler boş alanı paylaşmıyor. Ben çift / üçlü / dört / vb linux dağıtımları önyükleme bir sistem kurmak için arıyorum, ama bunu bir dosya sistemi ile yapar, böylece "boş alan var, ama yanlış bölümde!"

Daha net olması için, sorumun veya başlığının nasıl düzenleneceğine dair önerileriniz varsa, tamamen kulaklarım.


1
Sistemde hiçbir şey AFAIK yoktur. Muhtemelen yapmanız gereken şey, başka bir bootparametre eklemek ve initramflarınızı
init'i

@UlrichDangel önereceğim şey buydu. Bir cevap verin!
Nils

@Nils tamam bir cevap verdim, tbh. Yama / senaryo sağlamak istemediğim gibi ilk başta bir tane yazmak istemedim
Ulrich Dangel 28:12

Yanıtlar:


10

Kısa cevap - Bildiğim kadarıyla özel gereksinimleriniz için kutudan çalışma çözümü yok. Her bir dağıtımın her bir initramfını özel gereksinimlerinizi destekleyecek şekilde ayarlamanız gerekecektir.

Uzun cevap - evet mümkün. Günümüzde çoğu Linux dağıtımı, önyükleyici tarafından belleğe yüklenecek ve daha sonra çekirdek tarafından açılacak bir initramfs kullanmaktadır. Orada /sbin/init, erken kullanıcı alanını ayarlamaktan sorumlu olacak (udev'i çalıştırmak, modülleri yüklemek, plymouth'u başlatmak, kripto parolası istemek, ağ bağları için ağı kurmak,… adını siz verin). Kendi komut dosyalarınızı çalıştırabilir ve özel önyükleme parmaterlerini değerlendirebilirsiniz.

Debian örneği

Debian kullanıyorsanız (Ubuntu ile aynı olmalıdır) /etc/initramfs-tools/scripts/init-bottom/, başlatma başlamadan önce çalıştırılacak bir komut dosyası yerleştirebilmeniz gerekir . Senaryo hakkında daha fazla bilgi için, farklı dizinler ve düzen adam initramfs-tools bir göz atın . rootmntHedef dizini ayarlamanız ve eklemeniz gerekir.

/etc/initramfs-tools/scripts/local-bottom/00-myrootVeya olarak yüklenmesi gereken örnek (denenmemiş) komut dosyası /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

Fikir, rootmnt initramfs initbetiğinde gerçek init'i başlatmak / yürütmek için kullanılanı ayarlamaktır . Kök aygıt zaten init-bootomsahneye monte edildiğinden , hedef dizini ayarlayabilir / değiştirebilirsiniz.

Bu komut dosyasını kullanmak için yeni bir önyükleme parametresi ekleyin, komut dosyasını kopyalayın, yürütülebilir yapın, initramflerinizi yeniden oluşturun ve Linux dağıtımınız için bir önyükleme parametresi ekleyin, örn rootdir=/Ubuntu_Precise.


Ayrıca, gerçek root'u os kökünün bir alt dizinine bağlamak istersiniz, böylece önyüklemenizdeki diğer OS dosyalarını görebilirsiniz.
psusi

@psusi Bunu fstab üzerinden yapabilir veya mount /dev/rootdevice /mountpointsistem çalıştıktan hemen sonra doğrudan yapabilirsiniz
Ulrich Dangel 28:12

Acaba bu ne zaman değişti? Aynı blok cihazı bir daha monte edemezdiniz; bir EBUSY alırsın.
psusi

1
@psusi emin değilim ama muhtemelen bağlama bağlarının tanıtımı ile
Ulrich Dangel 28:12

@UlrichDangel (Çok) ayrıntılı cevap için teşekkürler!
Azendale

3

Ubuntu biyonik (ve muhtemelen başka yerlerde) çalışan iki yol. yorum yapmak için yeterli temsilcisi yok, ama biyonik: / usr / share / initramfs-tools / init / etc / fstab / mount /ot için doğrudan mountroot çağırdıktan sonra ve * -bottom komut dosyalarını çağırmadan önce görünüyor, bu yüzden bir init- alt komut dosyası (burada başka bir cevapta önerildiği gibi) "çok geç". bunun yerine bu tavsiye:

#!/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

Bu benim için bir tedavi çalıştı
paultop6

1

Bölüm tablosu ile uğraşmadan farklı linux önyükleme farklı amaçlar için ilginçtir, paylaşılan bir dosya sistemine alternatif bir çözüm döngü birimlerini kullanmaktır, burada / dev / sdb1 dosya sistemine / debian döngü dosyası / biriminiz olduğunu varsayarak gereken birkaç değişiklik (Hem ana hem de döngü işletim sistemi için geçerli GNU / Debian sid / kararsız kullanıyorum).

/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 komut satırı olarak tanımlanan argümanlar initrd / init tarafından env olarak ayarlanır, bu nedenle:

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

döngü "kendisi" üzerine birim monte izin, varsayılan komut dosyası akış mount /dev/sdb1 /rootsadece biz isteğe bağlı olarak / dev / sdb1 rw olarak rw olarak yeniden her zaman a ekleyin 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

Ayrıca bazı modülü initram içine önceden yüklemeniz gerekir (daha sonra update-initramfs çalıştırmayı unutmayın)

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

Döngüyü kullanarak performansları veya atık kaynaklarını ne kadar etkilediğini bilmiyorum, ext4'ün ext4 üzerine monte edilmesinin bir dosya sistemi hatası olasılığını iki katına çıkarıp katmadığını merak ediyorum, ancak bazı ayarlamalar yapılabilir. Belki döngü kullanmanın daha iyi bir yolu var, daha az hackish, lütfen bulamadığım için bana bildirin.


0

Bu bir cevap değil, ancak Ulrich'in cevabı ve yorumları hakkında bir noktayı açıklığa kavuşturmak istiyorum (yukarıda yorum yapamam).

Ulrich'in önerdiği çözüm (henüz denenmemiş) işe yarayabilir ancak daha sonra kaldırılamaz bir dosya sistemi elde edersiniz . Geçici bir çözüm olarak (IMHO çirkin), fs'yi krokmeden önce rw olarak bağlayabilirsiniz ( burada önerildiği gibi ), ancak kırık başlangıç ​​komut dosyalarına dikkat edin. Sanırım bu geçici çözüm daha fazla yan etkiye sahiptir (kırık fs ro yeniden denemeye çalışırken ve başarısız gibi).

Ben ext4 ile çekirdek 3.2 kullanıyorum ve zaten chot içinde monte edilmiş bir dev montaj hala psusi yorum olarak EBUSY vermek.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.