GRUB2 a FreeBSD - upresneni + pokusy
Jan Dušátko
jan at dusatko.org
Fri Apr 22 17:01:06 CEST 2011
> On 04/22/11 13:07, Jan Dušátko:
> > Prisel jsem konecne na zpusob, jak přinutit Grub2 nacist FreeBSD tak,
jak
> > to chci ja, nikoliv jak si to predstavuji vyvojari GRUB.
>
> > GRUB ma proste stale sve male musky.
>
> Otazka je (skutecne otazka, ja to nezkoumal natolik, abych mel jakykoliv
> predbezny odhad odpovedi) jestli by scriptovanym nativnim /boot/loader
> neslo dosahnout nejmene tehoz co pozadujes - a s mensim rizikem "broken
> after upgrade" (at uz systemu nebo GRUBu). Nativni loader je preci jen
> nativni loader ...
>
> V podstate je tam jedina klicova podotazka - zda ten scriptovaci jazyk
> ma mechanismus umoznujici neco nekam zapsat. Vyrozumel jsem, ze "vyber"
> bootovani je stavova zalezitost neb primarne chces nabootovat "totez co
> minule" (coz vyzaduje schopnost nekam poznamenat co bylo minule). Pokud
> tohle jde, pak by uz nic dalsiho nemelo branit "nativnimu" reseni tveho
> problemu.
>
> Dan
Pro ty kdo se v tom stratili. Jedna se mi o dualni boot prostredi, kde
Jedno funguje jako pracovni, druhe jako zalozni. Pokud se mi pracovni
jakymkoliv způsobem poondi, chci aby se automaticky nastartovalo zalozni.
V tom je vyhoda grubu a jeho autostartu spolecne s watchdogem.
Kdo ma zajem, nize je maximum veci, ktere se mohou hodit. Ostatnim se
omlouvam za dlouhy e-mail. Pokud chcete, ozvete se mi primo
V soucasnosti mam tato prostredi ponekud marnotratne definovana jako:
(při cene dnešních disku to vazne nema smysl resit)
PTT 1 - 32GB
a UFS / 16GB (used 5,7GB)
b swap velikost pameti
d UFS /tmp 8GB (used 0B)
e UFS /var 4GB (used 217MB)
PTT 2 - 32GB
a UFS / 16GB
b swap velikost pameti
d UFS /tmp 8GB
e UFS /var 4GB
Ke swapu - mam dva swapy, tedy dohromady davaji dvojnasobek pameti. Mam 4GB
a shodna je i velikost swapu. Ale jeste jsem ho nepouzil.
a /etc/fstab pak vypada
# Device Mountpoint FStype Options Dump
Pass#
# Primary boot environment
/dev/ar0s1b none swap sw 0 0
/dev/ar0s1a / ufs rw 1 1
/dev/ar0s1d /tmp ufs rw 2 2
/dev/ar0s1e /var ufs rw 2 2
# Alternate boot environment
/dev/ar0s2b none swap sw 0 0
/dev/ar0s2a /.alt ufs rw,noauto 0 0
/dev/ar0s2d /.alt/tmp ufs rw,noauto 0 0
/dev/ar0s2e /.alt/var ufs rw,noauto 0 0
# Other filesystems
proc /proc procfs rw 0 0
/dev/cd0 /cdrom cd9660 ro,noauto 0 0
Cele to pak zastresuje skript, ktery kopiruje boot prostredi.
Zminovany soubor /etc/fstab.alt je temer shodny s /etc/fstab, az na
prohozene
cisla partice. Cisla slice zustavaji shodna.
#!/bin/sh
# Create empty filesystem
echo Create script for cleaning filesystem ...
/bin/cat /etc/fstab | /usr/bin/grep /.alt | /usr/bin/awk '{print
"/sbin/newfs -O2 -U "$1}' >/tmp/vmf_make.sh
/bin/chmod 700 /tmp/vmf_make.sh
/tmp/vmf_make.sh
/bin/rm /tmp/vmf_make.sh
# Mount and backup alternate root
echo Mounting and restore new root
/sbin/mount /.alt
cd /.alt
/sbin/dump -0uL -f - / | /sbin/restore rf -
# Mount and backup alternate tmp, var
echo Mounting and restore new /tmp /var
/sbin/mount /.alt/tmp
/sbin/mount /.alt/var
cd /.alt/tmp
/sbin/dump -0uL -f - /tmp | /sbin/restore rf -
cd /.alt/var
/sbin/dump -0uL -f - /var | /sbin/restore rf -
# Copy mountpoints
echo Copying mountpoints
/bin/cp /etc/fstab.alt /.alt/etc/fstab
/bin/cp /etc/fstab /.alt/etc/fstab.alt
# Unmount filesystem to avoid corruption
echo Dismounting part of alternate boot environment
cd /.alt
/sbin/umount /.alt/tmp
/sbin/umount /.alt/var
cd /
echo Generating GRUB scripts
cp /boot/grub/grub.cfg /boot/grub/grub.old
cp /.alt/boot/grub/grub.cfg /.alt/boot/grub/grub.old
/usr/local/sbin/grub-mkconfig --output=/boot/grub/grub.cfg
cp /boot/grub/grub.cfg /.alt/boot/grub/grub.cfg
echo Dismounting rest of alternate boot environment
/sbin/umount /.alt
echo Creating script to activate boot environment
V /boot/loader.conf pak musi byt:
# podpora ich
ichsmb_load="YES"
# podpora ipmi
ipmi_load="YES"
# podpora watchdog
ichwd_load="YES"
A v /etc/rc.conf
# Watchdog daemon
watchdogd_enable="YES"
Ten je mozne nainstalovat pomoci portinstall watchdog
Grub mam ted upraveny, skript vypada nasledovne:
/usr/local/etc/grub.d/10_kfreebsd a 11_kfreebsd
(kde 11_kfreebsd se lisi pouze v definici proměnných GRUB_DEVICE* a DEVICE*)
# grub-mkconfig helper skript, modified
prefix=/usr/local
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
libdir=${exec_prefix}/lib
. ${libdir}/grub/grub-mkconfig_lib
export TEXTDOMAIN=grub
export TEXTDOMAINDIR=@LOCALEDIR@
CLASS="--class os"
GRUB_DEVICE_BOOT="/dev/ar0s1a"
GRUB_DEVICE="/dev/ar0s1a"
DEVICE_UUID=`/sbin/glabel status | /usr/bin/grep s1a | /usr/bin/tr "/" " " |
/usr/bin/awk '{print $2}'`
DEVICE_BOOT="'(/dev/ar0,1,a)'"
case "${GRUB_DISTRIBUTOR}" in
Debian)
OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]')
--class gnu-kfreebsd --class gnu ${CLASS}"
;;
*)
OS="FreeBSD"
CLASS="--class freebsd --class bsd ${CLASS}"
;;
esac
kfreebsd_entry ()
{
os="$1"
version="$2"
recovery="$3" # not used yet
args="$4" # not used yet
title="$(gettext "%s, Primary Boot Environment %s")"
printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}"
# save_default_entry | sed -e "s/^/ /"
# if [ -z "${prepare_boot_cache}" ]; then
# prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT}
| sed -e "s/^/ /")"
# fi
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
insmod ufs2
set root=${DEVICE_BOOT}
search --no-floppy --fs-uuid --set ${DEVICE_UUID}
echo $(printf "$(gettext "Loading kernel of
FreeBSD %s ...")" ${version})
kfreebsd /boot/loader
EOF
}
list=`for i in /boot/kfreebsd-* /boot/kernel/kernel ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
prepare_boot_cache=
while [ "x$list" != "x" ] ; do
kfreebsd=`version_find_latest $list`
echo "Found kernel of FreeBSD: $kfreebsd" >&2
basename=`basename $kfreebsd`
dirname=`dirname $kfreebsd`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
if [ -f /boot/device.hints ] ; then
devices=/boot/device.hints
devices_basename=`basename $devices`
devices_dirname=`dirname $devices`
devices_rel_dirname=`make_system_path_relative_to_its_root
$devices_dirname`
fi
case ${GRUB_FS} in
ufs1 | ufs2) kfreebsd_fs=ufs ;;
*) kfreebsd_fs=${GRUB_FS} ;;
esac
version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
acpi_ko=
for i in "/lib/modules/${version}/acpi.ko"
"/lib/modules/${alt_version}/acpi.ko" \
"/boot/kernel/acpi.ko"; do
if test -e "$i" ; then
acpi_ko="$i"
break
fi
done
if test -n "${acpi_ko}" ; then
echo "Found ACPI module: ${acpi_ko}" >&2
acpi_ko_basename=`basename ${acpi_ko}`
acpi_ko_dirname=`dirname ${acpi_ko}`
acpi_ko_rel_dirname=`make_system_path_relative_to_its_root
$acpi_ko_dirname`
fi
kfreebsd_entry "${OS}" "${version}"
list=`echo $list | tr ' ' '\n' | grep -vx $kfreebsd | tr '\n' ' '`
done
Jeste to stale ladim, takze jakekoliv pripominky uvitam.
Honza
More information about the Users-l
mailing list