Tags

arm arpaname bin_sh blocage blosxom bsd bsdfrance cblog certification chroot cluster dg834 dhcp diffusion dns dnsmasq domU dovecot fail-over fail2ban firefox fossil freebsd ftp git guruplug install ipv6 jail kernel kimsufi lex libre linutop liste makefile mikrotik ml150 mohawk nanojail netbook netbsd nginx ntp ntp.org openbsd openntpd openrd opensmtpd openwrt orke pkgng poudriere privee proxy pxe python rescue reverse rmll route rrdcgi sendmail serial sieve sjail sl2009 ssd sshd symon unbound update usb var_empty vimperator world xen yacc zfs

Powered by

blOg
maRkdown
awK
shEll

01/11/2014

[ freebsd pxe serial ]

201411011200 freebsd pxe serial

FreeBSD, pxeboot et port série

Il est toujours utile d'avoir un pxeboot supportant le port série, pour au hasard installer freebsd en tant que domU hvm sans utiliser de console graphique.

J'ai à ma disposition:

Je commence par chercher les options supportées par le Makefile de pxeboot:

# find /usr/src/ -type d -name '*pxe*'
/usr/src/sys/boot/i386/pxeldr
# ls /usr/src/sys/boot/i386/pxeldr
Makefile        pxeboot.8       pxeldr.S
# grep '^.if ' /usr/src/sys/boot/i386/pxeldr/Makefile
.if defined(BOOT_PXELDR_PROBE_KEYBOARD)
.if defined(BOOT_PXELDR_ALWAYS_SERIAL)

Je prépare un petit script:

# cat $HOME/bin/serial_pxeboot.sh
#!/bin/sh

SRCCONF=$HOME/etc/pxe/src.conf
if [ ! -f "${SRCCONF}" ]; then
    "'${SRCCONF}': file not found. Exit"
    exit 1
fi

export SRCCONF

cd sys/boot/i386/pxeldr && make clean && make

J'active l'option kivabien:

# cat $HOME/etc/pxe/src.conf
BOOT_PXELDR_ALWAYS_SERIAL=yes

Permier essai:

# $HOME/bin/serial_pxeboot.sh
rm -f pxeboot pxeboot.tmp loader pxeldr pxeldr.o pxeboot.8.gz pxeboot.8.cat.gz
Warning: Object directory not changed from original /usr/src/sys/boot/i386/pxeldr
cc -O2 -pipe  -march=i386 -ffreestanding -mpreferred-stack-boundary=2  -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float -m32 -DALWAYS_SERIAL -I/usr/src/sys/boot/i386/pxeldr/../common -std=gnu99 -Qunused-arguments   -no-integrated-as  -m32 -c pxeldr.S
cc -O2 -pipe  -march=i386 -ffreestanding -mpreferred-stack-boundary=2  -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float -m32 -DALWAYS_SERIAL -I/usr/src/sys/boot/i386/pxeldr/../common -std=gnu99 -Qunused-arguments     -nostdlib -m elf_i386_fbsd -e start -Ttext 0x7c00 -Wl,-N,-S,--oformat,binary -o pxeldr pxeldr.o
gzip -cn pxeboot.8 > pxeboot.8.gz
make: don't know how to make /usr/src/sys/boot/i386/pxeldr/../loader/loader.bin. Stop

make: stopped in /usr/src/sys/boot/i386/pxeldr

Les options supportées pour la construction de loader.bin:

# grep '^.if ' /usr/src/sys/boot/i386/loader/Makefile
.if defined(LOADER_FIREWIRE_SUPPORT)
.if defined(LOADER_ZFS_SUPPORT)
.if defined(LOADER_TFTP_SUPPORT)
.if ${MK_FORTH} != "no"
.if defined(LOADER_BZIP2_SUPPORT)
.if !defined(LOADER_NO_GZIP_SUPPORT)
.if defined(LOADER_NANDFS_SUPPORT)
.if !defined(LOADER_ONLY)
.if !exists(${DESTDIR}/boot/loader.rc)
.if !exists(${DESTDIR}/boot/menu.rc)
.if ${MACHINE_CPUARCH} == "amd64"

A la lecture du Makefile je m'aperçois qu'il est question de /etc/make.conf. Pour faire simple, je vais utiliser un unique fichier avec mes options.

# cat $HOME/etc/pxe/src.conf
BOOT_PXELDR_ALWAYS_SERIAL=yes
LOADER_TFTP_SUPPORT=yes
WITHOUT_FORTH=yes
LOADER_BZIP2_SUPPORT=yes
LOADER_NO_GZIP_SUPPORT=yes

Le script:

#!/bin/sh

SRCCONF=$HOME/etc/pxe/src.conf
DIR=sys/boot/i386

if [ ! -f "${SRCCONF}" ]; then
    "'${SRCCONF}': file not found. Exit"
    exit 1
fi
__MAKE_CONF=${SRCCONF}
export SRCCONF __MAKE_CONF

if [ ! -d "${DIR}" ]; then
    echo "'${DIR}' not exists. Exit."
    exit 1
fi
cd ${DIR}

DIRS="loader pxeldr"

for dir in ${DIRS}; do
    cd ${dir} && make clean && cd ..
done
for dir in ${DIRS}; do
    cd ${dir} && make
    if [ $? -ne 0 ]; then
        echo "Can't make '${dir}'. Exit"
        exit 1
    fi
    cd ..
done

Deuxième essai:

# $HOME/bin/serial_pxe.sh
[ snip des trucs ]
cc: error: no such file or directory: '/usr/src/sys/boot/i386/loader/../btx/lib/crt0.o'
cc: error: no such file or directory: '/usr/src/sys/boot/i386/loader/../libi386/libi386.a'
*** Error code 1

Stop.
make: stopped in /usr/src/sys/boot/i386/loader
Can't make 'loader'. Exit

On devine qu'il nous manque libi386 et btx. Leur Makefile respectif ne semble pas définir d'option particulière.

Je rajoute les répertoires dans mon script:

# grep ^DIRS $HOME/bin/serial_pxeboot.sh
DIRS="libi386 btx loader pxeldr"

Au résultat:

# $HOME/bin/serial_pxeboot.sh
[ snip des trucs ]
cat pxeldr loader > pxeboot.tmp
dd if=pxeboot.tmp of=pxeboot obs=2k conv=osync
369+1 records in
93+0 records out
190464 bytes transferred in 0.001461 secs (130362911 bytes/sec)
rm pxeboot.tmp
# ls -l sys/boot/i386/pxeldr/pxeboot
-rw-r--r--  1 root  wheel  190464 Nov  1 07:46 sys/boot/i386/pxeldr/pxeboot
# sha256 sys/boot/i386/pxeldr/pxeboot
SHA256 (sys/boot/i386/pxeldr/pxeboot) = 8ac08d2af6df8ebc3b0701efd0867daa413c08775dac5073735c9f1cd5e4b476

Pour les plus attentifs, il est inutile de désactiver les drapeaux en relation avec les disques durs et les partitions (-DLOADER_DISK_SUPPORT -DLOADER_GPT_SUPPORT -DLOADER_MBR_SUPPORT) sous prétexte que notre pxe charge le noyau par le réseau. Le code du loader était là bien avant l'arrivée du pxe et, pour avoir essayé, désactiver ces drapeaux rend le code invalide.

Il ne reste plus qu'à configurer le tftp de mon dom0 NetBSD:

$ ifconfig tap4 | grep 'inet '
    inet 10.40.20.1 netmask 0xffffff00 broadcast 10.40.20.255
$ dig dom0-gw +short
10.40.20.1
$ grep tftp /etc/inetd.conf
dom0-gw:tftp            dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -l -s /xen/tftpboot
$ cd /xen/tftpboot
$ ftp -o freepxeboot http://download.bsdsx.fr/freebsd/pxeboot

ainsi que le dhcpd:

$ cat /etc/dhcpd.conf
[ snip ]
host freebsd-001 { hardware ethernet 00:16:3e:00:11:04; fixed-address 10.40.20.11;
     filename "freepxeboot";
     next-server 10.40.20.1;
}
[ snip ]

et préparer un domU:

$ cd /xen/disks
$ ftp ftp://ftp.fr.freebsd.org/pub/FreeBSD/snapshots/VM-IMAGES/11.0-CURRENT/amd64/Latest/FreeBSD-11.0-CURRENT-amd64.raw.xz
$ unxz FreeBSD-11.0-CURRENT-amd64.raw.xz
$ cat /xen/etc/freebsd-hvm-current.cfg
builder = 'hvm'
memory = 256
name = 'freebsd-001.bsdsx.fr'
nicks = 2
vif = [ 'mac=00:16:3e:00:11:04, bridge=bridge4', 'mac=00:16:3e:00:11:06, bridge=bridge6' ]
disk = [
	'file:/xen/disks/FreeBSD-11.0-CURRENT-amd64.raw,hda,rw'
]
boot = 'c'
serial = 'pty'
vnc = 0
on_reboot="destroy"

Permier démarrage:

$ sudo xl create /xen/etc/freebsd-hvm-current.cfg -c "boot = 'n'"
Parsing config from /xen/etc/freebsd-hvm-current.cfg
xc: info: VIRTUAL MEMORY ARRANGEMENT:
  Loader:        0000000000100000->0000000000171de4
  TOTAL:         0000000000000000->000000000f800000
  ENTRY ADDRESS: 0000000000100000
xc: info: PHYSICAL MEMORY ALLOCATION:
  4KB PAGES: 0x0000000000000200
  2MB PAGES: 0x000000000000007b
  1GB PAGES: 0x0000000000000000
Daemon running with PID 1563
net0: 00:16:3e:00:11:04 on PCI00:04.0 (open)
  [Link:up, TX:0 TXE:0 RX:0 RXE:0]
DHCP (net0 00:16:3e:00:11:04).... ok
net0: 10.40.20.11/255.255.255.0 gw 10.40.20.1
Booting from filename "freepxeboot"
tftp://10.40.20.1/freepxeboot. ok
Consoles: serial port  
BIOS drive C: is disk0

PXE version 2.1, real mode entry point @9ab9:0344
BIOS 618kB/251496kB available memory

FreeBSD/x86 bootstrap loader, Revision 1.1
(root@blade.bsdsx.xxx, Sat Nov  1 07:46:48 CET 2014)
pxe_open: server addr: 10.40.20.1
pxe_open: server path: /
pxe_open: gateway ip:  10.40.20.1
\
can't load 'kernel'

Type '?' for a list of commands, 'help' for more detailed help.
OK 

Un petit tour dans les logs:

$ tail /var/log/messages
Nov  1 08:13:35 dom0 tftpd[3539]: 10.40.20.11: read request for /boot/loader.rc.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[10540]: 10.40.20.11: read request for /boot/loader.rc: File not found
Nov  1 08:13:35 dom0 tftpd[6888]: 10.40.20.11: read request for /boot/boot.conf.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[3215]: 10.40.20.11: read request for /boot/boot.conf: File not found
Nov  1 08:13:35 dom0 tftpd[25944]: 10.40.20.11: read request for /boot/kernel/kernel.ko.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[29596]: 10.40.20.11: read request for /boot/kernel/kernel.ko: File not found
Nov  1 08:13:35 dom0 tftpd[3591]: 10.40.20.11: read request for /boot/kernel/kernel.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[9980]: 10.40.20.11: read request for /boot/kernel/kernel: File not found
Nov  1 08:13:35 dom0 tftpd[20777]: 10.40.20.11: read request for /boot/kernel/kernel.debug.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[14883]: 10.40.20.11: read request for /boot/kernel/kernel.debug: File not found
Nov  1 08:13:35 dom0 tftpd[10770]: 10.40.20.11: read request for /boot/modules/kernel.ko.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[28441]: 10.40.20.11: read request for /boot/modules/kernel.ko: File not found
Nov  1 08:13:35 dom0 tftpd[9190]: 10.40.20.11: read request for /boot/modules/kernel.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[25233]: 10.40.20.11: read request for /boot/modules/kernel: File not found
Nov  1 08:13:35 dom0 tftpd[28245]: 10.40.20.11: read request for /boot/modules/kernel.debug.bz2: File not found
Nov  1 08:13:35 dom0 tftpd[16295]: 10.40.20.11: read request for /boot/modules/kernel.debug: File not found

Je place un kernel au bon endroit:

$ cd /xen/tftpboot
$ ftp ftp://ftp.fr.freebsd.org/pub/FreeBSD/snapshots/amd64/11.0-CURRENT/kernel.txz
$ tar -x --xz -f kernel.txz ./boot/kernel/kernel

Le deuxième essai se termine par:

loader variables:

manual root filesystem specification:
  <fstype>:<device> [options]
      mount <device> using filesystem <fstype>
      and with the specified (optional) option list.

    eg. ufs:/dev/da0s1a
        zfs:tank
        cd9660:/dev/acd0 ro
          (which is equivalent to: mount -t cd9660 -o ro /dev/acd0 /)

  ?               list valid disk boot devices
  .               yield 1 second (for background tasks)
  <empty line>    abort manual input

mountroot> 

Un oeil aux logs:

nov  1 11:23:40 dom0 tftpd[631]: 10.40.20.11: read request for /etc/fstab.bz2: file not found
nov  1 11:23:40 dom0 tftpd[762]: 10.40.20.11: read request for /etc/fstab: file not found

Il y aurait donc moyen de passer le fstab par tftp. Reste à définir son contenu:

mountroot> ?

list of geom managed disk devices:
  ufsid/544bb9f742228653 gptid/5a8b65b7-5c57-11e4-a093-002564f96db2 gpt/rootfs gptid/5a8b65a9-5c57-11e4-a093-002564f96db2 gpt/swapfs gptid/5a8b6586-5c57-11e4-a093-002564f96db2 gpt/bootfs ada0p3 ada0p2 ada0p1 ada0

Ce qui donne:

$ mkdir /xen/tftpboot/etc
$ cat >> /xen/tftpboot/etc/fstab
# Device          Mountpoint      FStype  Options Dump    Pass#
/dev/gpt/rootfs   /               ufs     rw      1       1
/dev/gpt/swapfs   none            swap    sw      0       0
^D

On peut se passer de cette étape en saisissant depuis l'invite:

mountroot> ufs:/dev/gpt/rootfs

Dernier essai:

[ snip des trucs ]
root@:~ # uname -a
FreeBSD  11.0-CURRENT FreeBSD 11.0-CURRENT #0 r273635: Sat Oct 25 14:23:40 UTC 2014     root@grind.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

Reste à configurer l'utilisation du port série:

root@:~ # echo 'console="comconsole"' > /boot/loader.conf

On peut désormer lancer le domU normalement:

$ sudo xl create /xen/etc/freebsd-hvm-current.cfg -c
[ snip des trucs ]
root@:~ # uname -a
FreeBSD  11.0-CURRENT FreeBSD 11.0-CURRENT #0 r273635: Sat Oct 25 14:23:40 UTC 2014     root@grind.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

Pour éviter les mauvaises surprises, ne pas oublier de faire un peu de nettoyage dans /xen/tftpboot.


Lien vers ce billet