Building a Slackware magical script. Feedback and suggestions welcome.
SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Building a Slackware magical script. Feedback and suggestions welcome.
Hi Slackers ! ;^)
The purpose of this script is to transform a Slackware into a PXE server.
Not an installation server, i mean : A real networked Slack ^^.
I tested it on Slackware-13.37 and Slackware64-13.37.
Should work after my latest modifications (no more time to test yet).
Note that the client kernel is recompiled, and for now, a few network cards are added.
Takes ~2h30 on a P4-class machine.
I intend to add more stuff later, maybe in a separate script.
And i may deposit it in LQ's tutorials/SBo/n(yes, i dream ^^).
Feel free to suggest.
Enjoy.
Code:
#!/bin/sh
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
echo "If you currently are not, please run after 'su -' or log in as root(bleh!)."
echo "Go in 10 seconds. Then it may take up to 3+ hours."
sleep 10
CWD=$(pwd)
#Build time will be displayed at the end
date1=$(date +%s)
#Cleaning from a previous execution
rm -rf /srv/exports/nfs/slackware/filesystem/*
#ISO mounting
mkdir -p $CWD/slackware-iso-loop
#Make your choice
mount -t iso9660 /dev/sr0 $CWD/slackware-iso-loop
#mount -t iso9660 -o loop image.iso $CWD/slackware-iso-loop
#mount -t nfs x.x.x.x:/srv/exports/whatever $CWD/slackware-iso-loop
#Creating some exported filesystem directories
mkdir -p /srv/exports/nfs/slackware/filesystem
mkdir -p /srv/exports/nfs/slackware/filesystem/boot/initrd-tree
mkdir -p /srv/exports/nfs/slackware/filesystem/home/nfs/
mkdir -p /srv/exports/nfs/slackware/filesystem/tmp/def/
#Creating exported /home/nfs directory
#Note that /home is not directly used, to ease future settings
mkdir -p /srv/exports/nfs/slackware/homedirs
#Creating tftpboot tree
#Note that /tftpboot is moved into /srv/exports/
#Sounds more coherent to me
mkdir -p /srv/exports/tftpboot/pxelinux.cfg
mkdir -p /srv/exports/tftpboot/slackware
#The /usr/lib is kept for retrocompatibility so expect at least one cp error :^)
cp /usr/lib/syslinux/pxelinux.0 /srv/exports/tftpboot/
cp /usr/share/syslinux/pxelinux.0 /srv/exports/tftpboot/
#Setting up network boot options
echo "
default huge.s-pxe
prompt 1
timeout 12
label huge.s-pxe
kernel /slackware/vmlinuz
append initrd=/slackware/initrd.gz load_ramdisk=1
" > /srv/exports/tftpboot/pxelinux.cfg/default
#Let's activate the portmapper
chmod +x /etc/rc.d/rc.rpc
/etc/rc.d/rc.rpc start
#Configuring NFS
echo "/srv/exports/nfs/slackware/filesystem/ 10.0.0.0/24(ro,no_subtree_check,no_root_squash)
/srv/exports/nfs/slackware/homedirs/ 10.0.0.0/24(rw,no_subtree_check,no_root_squash)
" > /etc/exports
#And start it cleanly
chmod +x /etc/rc.d/rc.nfsd
/etc/rc.d/rc.nfsd stop
/etc/rc.d/rc.nfsd start
# /tftpboot's exodus and activation through inetd's config
sed -i -e "s/# tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/tftpboot -r blksize/tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/srv\/exports\/tftpboot -r blksize/g" /etc/inetd.conf
#sed -i '/# tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/tftpboot -r blksize/a \tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/srv\/exports\/tftpboot -r blksize' /etc/inetd.conf
#And start it cleanly
chmod +x /etc/rc.d/rc.inetd
/etc/rc.d/rc.inetd stop
/etc/rc.d/rc.inetd start
#Lay down the DHCP server settings
echo 'allow bootp;
allow booting;
filename = "/pxelinux.0";
authoritative;
ddns-update-style none;
next-server 10.0.0.1;
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.2 10.0.0.253;
default-lease-time 3600;
max-lease-time 4800;
option domain-name-servers 10.0.0.1;
option subnet-mask 255.255.255.0;
option domain-name "local";
host n1 {
hardware ethernet 00:37:72:13:37:C1;
fixed-address 10.0.0.2;
option host-name "n1";
filename "/pxelinux.0";
}
}
' > /etc/dhcpd.conf
#I don't know why these are not included in stock Slackware
mkdir -p /var/state/dhcp
touch /var/state/dhcp/dhcpd.leases
#DHCP server activation
dhcpd eth0
#Make this activation permanent
echo "dhcpd eth0" >> /etc/rc.d/rc.local
#Slackware installation
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/a/tagfile $CWD/slackware-iso-loop/slackware/a/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/ap/tagfile $CWD/slackware-iso-loop/slackware/ap/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/d/tagfile $CWD/slackware-iso-loop/slackware/d/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/e/tagfile $CWD/slackware-iso-loop/slackware/e/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/f/tagfile $CWD/slackware-iso-loop/slackware/f/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/k/tagfile $CWD/slackware-iso-loop/slackware/k/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/kde/tagfile $CWD/slackware-iso-loop/slackware/kde/*.t?z
#installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/kdei/tagfile $CWD/slackware-iso-loop/slackware/kdei/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/l/tagfile $CWD/slackware-iso-loop/slackware/l/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/n/tagfile $CWD/slackware-iso-loop/slackware/n/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/t/tagfile $CWD/slackware-iso-loop/slackware/t/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/tcl/tagfile $CWD/slackware-iso-loop/slackware/tcl/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/x/tagfile $CWD/slackware-iso-loop/slackware/x/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/xap/tagfile $CWD/slackware-iso-loop/slackware/xap/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/y/tagfile $CWD/slackware-iso-loop/slackware/y/*.t?z
#Make a temporary copy of the custom initrd mandatory packages inside the exported system
#They will be used later, in a chroot
cp $CWD/slackware-iso-loop/slackware/l/glibc-2*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
cp $CWD/slackware-iso-loop/slackware/n/dhcpcd-*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
cp $CWD/slackware-iso-loop/slackware/n/nfs-uti*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
cp $CWD/slackware-iso-loop/slackware/n/portmap*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
#Ugly modifications
#Don't touch the initial initrd mount
sed -i -e "s/READWRITE=yes/READWRITE=no/g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
sed -i -e "s/\/sbin\/fsck \$FORCEFSCK -C -a \//#\/sbin\/fsck \$FORCEFSCK -C -a \//g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
sed -i -e "s/\/sbin\/mount -w -v -n -o remount \//#\/sbin\/mount -w -v -n -o remount \//g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
#sed -i -e "s/\/sbin\/mount -w -o remount \//#\/sbin\/mount -w -o remount \//g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
#Not used yet, at least in this form ;)
#echo "ftp://ftp.funet.fi/pub/mirrors/ftp.slackware.com/pub/slackware-13.37/" >> /srv/exports/nfs/slackware/filesystem/etc/slackpkg/mirrors
#Populate client's /etc/fstab
echo "10.0.0.1:/srv/exports/nfs/slackware/filesystem / nfs nfsvers=3,rsize=8192,wsize=8192,tcp 0 0
10.0.0.1:/srv/exports/nfs/slackware/homedirs/ /home/nfs/ nfs nfsvers=3,rsize=8192,wsize=8192,tcp 0 0
proc /proc proc defaults
ramfs /media ramfs 0 0
ramfs /tmp ramfs defaults 0 0
ramfs /var/lock ramfs 0 0
ramfs /var/log ramfs 0 0
ramfs /var/run ramfs 0 0
ramfs /var/state ramfs 0 0
ramfs /var/tmp ramfs 0 0
" > /srv/exports/nfs/slackware/filesystem/etc/fstab
#The client will use the same DNS as the server
cp /etc/resolv.conf /srv/exports/nfs/slackware/filesystem/etc/
#Stock kernel's .config "patching"
#In order to compile, the result must be identical to a classic 'make menuconfig'
#So be careful if you add options. Diff with a normally produced one
#ip-level autoconf
sed -i -e "s/# CONFIG_IP_PNP is not set/CONFIG_IP_PNP=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_IP_PNP=y/a \# CONFIG_IP_PNP_RARP is not set' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_IP_PNP=y/a \CONFIG_IP_PNP_BOOTP=y' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_IP_PNP=y/a \CONFIG_IP_PNP_DHCP=y' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#Network cards
sed -i -e "s/CONFIG_MII=m/CONFIG_MII=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_PHYLIB=m/CONFIG_PHYLIB=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_MICREL_PHY=m/a \# CONFIG_FIXED_PHY is not set' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s///g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s///g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s///g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_VORTEX is not set/CONFIG_VORTEX=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
##net hard
#sed -i -e "s/CONFIG_VORTEX=m/CONFIG_VORTEX=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_VORTEX is not set/CONFIG_VORTEX=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_TYPHOON=m/CONFIG_TYPHOON=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_TYPHOON is not set/CONFIG_TYPHOON=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_B44=m/CONFIG_B44=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_B44 is not set/CONFIG_B44=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_FORCEDETH=m/CONFIG_FORCEDETH=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_FORCEDETH is not set/CONFIG_FORCEDETH=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_E100=m/CONFIG_E100=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/# CONFIG_E100 is not set/CONFIG_E100=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_8139CP=m/CONFIG_8139CP=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_8139CP is not set/CONFIG_8139CP=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_8139TOO=m/CONFIG_8139TOO=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_8139TOO is not set/CONFIG_8139TOO=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL2=m/CONFIG_ATL2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL2 is not set/CONFIG_ATL2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_NETDEV_1000=m/CONFIG_NETDEV_1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/# CONFIG_NETDEV_1000 is not set/CONFIG_NETDEV_1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_E1000=m/CONFIG_E1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/# CONFIG_E1000 is not set/CONFIG_E1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_IGB=m/CONFIG_IGB=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_IGB is not set/CONFIG_IGB=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_R8169=m/CONFIG_R8169=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_R8169 is not set/CONFIG_R8169=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_SKGE=m/CONFIG_SKGE=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_SKGE is not set/CONFIG_SKGE=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_TIGON3=m/CONFIG_TIGON3=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_TIGON3 is not set/CONFIG_TIGON3=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_BNX2=m/CONFIG_BNX2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_BNX2 is not set/CONFIG_BNX2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL1=m/CONFIG_ATL1=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL1 is not set/CONFIG_ATL1=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL1E=m/CONFIG_ATL1E=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL1E is not set/CONFIG_ATL1E=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL1C=m/CONFIG_ATL1C=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL1C is not set/CONFIG_ATL1C=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#Really mandatory one !
sed -i '/# CONFIG_NFS_V4_1 is not set/a \CONFIG_ROOT_NFS=y' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#Client's kernel compilation and initrd generation, from inside
chroot /srv/exports/nfs/slackware/filesystem /bin/bash <<FinChroot1
##Not a good idea. If a kernel upgrade occurs, things may break
#slackpkg update
#slackpkg install-new
#slackpkg upgrade-all
##Kernel
cd /usr/src/linux
cp .config config-shipped
#make menuconfig
make clean
##Don't hesitate to tweak the cpu*2 number
make -j4 bzImage
make -j4 modules
make modules_install
rm /boot/vmlinuz
rm /boot/System.map
##32 and 64 bit compatibility, so now expect at least two cp errors :D
cp arch/i386/boot/bzImage /boot/vmlinuz
cp arch/x86_64/boot/bzImage /boot/vmlinuz
cp System.map /boot/
##Initrd
cd /boot
mkinitrd -c -f nfs -r 10.0.0.1:/srv/exports/nfs/slackware/filesystem/ -D eth0 -k 2.6.37.6
##Packages needed
##Note that i do not delete them after, for ease of debugging
installpkg -root /boot/initrd-tree/ /tmp/def/*.t?z
chmod +x /boot/initrd-tree/etc/rc.d/rc.rpc
sed -i '/mdev -s/a \/etc/rc.d/rc.rpc start' /boot/initrd-tree/init
sed -i '/mdev -s/a \/sbin/dhcpcd eth0' /boot/initrd-tree/init
##Dirty modification
sed -i -e "s/mount -o ro -t \$ROOTFS \$ROOTDEV \/mnt/mount -o rw,nolock -t \$ROOTFS \$ROOTDEV \/mnt/g" /boot/initrd-tree/init
mkinitrd
FinChroot1
#Back to host
#Copying custom official kernel and initrd to /srv/exports/tftpboot/slackware/
cp /srv/exports/nfs/slackware/filesystem/boot/vmlinuz /srv/exports/tftpboot/slackware/
cp /srv/exports/nfs/slackware/filesystem/boot/initrd.gz /srv/exports/tftpboot/slackware/
#A new chroot to manually finish the client's installation
chroot /srv/exports/nfs/slackware/filesystem /bin/bash <<FinChroot2
#Test
mount proc /proc -t proc
##Again, not a good idea. If a kernel upgrade occurs, things may break.
#slackpkg update
#slackpkg install-new
#slackpkg upgrade-all
##Setup
/var/log/setup/setup.04.mkfontdir
/var/log/setup/setup.05.fontconfig
/var/log/setup/setup.07.update-desktop-database
/var/log/setup/setup.07.update-mime-database
/var/log/setup/setup.08.gtk-update-icon-cache
#/var/log/setup/setup.htmlview
/var/log/setup/setup.mouse
#/var/log/setup/setup.netconfig
/var/log/setup/setup.services
#/var/log/setup/setup.setconsolefont
/var/log/setup/setup.timeconfig
/var/log/setup/setup.xwmconfig
##Guess what it adds:
#adduser
FinChroot2
umount slackware-iso-loop
date2=$(date +%s)
time=$(((date2-date1)/60))
echo "Build time: "$time" minutes."
echo "That's all folks !"
Last edited by Linux.tar.gz; 09-14-2011 at 06:39 PM.
Good work. This is something I am interested in. What is exported to the clients - a whole desktop like XFCE? And how do the clients perform?
Could the PXE server export just a small desktop like FVWM or Fluxbox to the clients, with little more than a VNC viewer, so that they can then VNC back into the server to do their work?
Little feedback... First of all, thnx for this funky script. However, for some reason I encountered few problems with it. As you did, I also had a similar problem you described in your post. After some random tweaking I managed to boot normally. I'll try to reproduce the errors again on a fresh vms because atm I have no idea what was wrong/fixed. As far as I noticed, the problem had something to do with rpc.statd & rpc.lockd on the server machine. I was able to see the output of
Code:
rpcinfo -p ip
but
Code:
showmounts -e ip
didn't work from the pxe client. Anyhow, after manual chroot and mkinitrd stuff (finchroot1 in your script) with added
This is a GREAT idea.
But unfortunately running the PXE client in VirtualBox on a vanilla slackware install caused a lot of kernel problems within the first two seconds (and wouldn't continue booting after that).
I'll have to try doing it between actual machines.
I've been looking all over for something like this and the best I could find was LTSP-4.2 (I think I followed an answer to one of your previous threads to get it to work).
I suppose that if I want to get a Folding@Home diskless farm served by Slackware I might just have to create my own tiny distro.
LTSP-4.2 works for this but I can only run version 5 of the folding@home client, because v6 complains that the kernel is too old (2.6.9).
Instead of just dipping my toe into linux anymore I'll just have to dive in and hope the community can keep my head above water enough to learn to swim.
Ahh, Slackware, thou art a heartless yet simplistic bitch.
#!/bin/sh
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
echo "If you currently are not, please run after 'su -' or log in as root(bleh!)."
echo "Go in 10 seconds. Then it may take up to 3+ hours."
sleep 10
CWD=$(pwd)
#Build time will be displayed at the end
date1=$(date +%s)
#Cleaning from a previous execution
rm -rf /srv/exports/nfs/slackware/filesystem/*
#ISO mounting
mkdir -p $CWD/slackware-iso-loop
#Make your choice
mount /dev/sr0 $CWD/slackware-iso-loop
mount -t iso9660 -o loop image.iso $CWD/slackware-iso-loop
#mount -t nfs x.x.x.x:/srv/exports/whatever $CWD/slackware-iso-loop
#Creating some exported filesystem directories
mkdir -p /srv/exports/nfs/slackware/filesystem
mkdir -p /srv/exports/nfs/slackware/filesystem/boot/initrd-tree
mkdir -p /srv/exports/nfs/slackware/filesystem/home/nfs/
mkdir -p /srv/exports/nfs/slackware/filesystem/tmp/def/
#Creating exported /home/nfs directory
#Note that /home is not directly used, to ease future settings
mkdir -p /srv/exports/nfs/slackware/homedirs
#Creating tftpboot tree
#Note that /tftpboot is moved into /srv/exports/
#Sounds more coherent to me
mkdir -p /srv/exports/tftpboot/pxelinux.cfg
mkdir -p /srv/exports/tftpboot/slackware
#The /usr/lib is kept for retrocompatibility so expect at least one cp error :^)
cp /usr/lib/syslinux/pxelinux.0 /srv/exports/tftpboot/
cp /usr/share/syslinux/pxelinux.0 /srv/exports/tftpboot/
#Setting up network boot options
echo "
default huge.s-pxe
prompt 1
timeout 12
label huge.s-pxe
kernel /slackware/vmlinuz
append initrd=/slackware/initrd.gz load_ramdisk=1
" > /srv/exports/tftpboot/pxelinux.cfg/default
#Let's activate the portmapper
chmod +x /etc/rc.d/rc.rpc
/etc/rc.d/rc.rpc start
#Configuring NFS
echo "/srv/exports/nfs/slackware/filesystem/ 10.0.0.0/24(rw,no_subtree_check,no_root_squash)
/srv/exports/nfs/slackware/homedirs/ 10.0.0.0/24(rw,no_subtree_check,no_root_squash)
" > /etc/exports
#And start it cleanly
chmod +x /etc/rc.d/rc.nfsd
/etc/rc.d/rc.nfsd stop
/etc/rc.d/rc.nfsd start
# /tftpboot's exodus and activation through inetd's config
sed -i -e "s/# tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/tftpboot -r blksize/tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/srv\/exports\/tftpboot -r blksize/g" /etc/inetd.conf
#sed -i '/# tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/tftpboot -r blksize/a \tftp dgram udp wait root \/usr\/sbin\/in.tftpd in.tftpd -s \/srv\/exports\/tftpboot -r blksize' /etc/inetd.conf
#And start it cleanly
chmod +x /etc/rc.d/rc.inetd
/etc/rc.d/rc.inetd stop
/etc/rc.d/rc.inetd start
#Lay down the DHCP server settings
echo 'allow bootp;
allow booting;
filename = "/pxelinux.0";
authoritative;
ddns-update-style none;
next-server 10.0.0.1;
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.2 10.0.0.253;
default-lease-time 3600;
max-lease-time 4800;
option domain-name-servers 10.0.0.1;
option subnet-mask 255.255.255.0;
option domain-name "local";
host n1 {
hardware ethernet 00:13:72:A5:9D:C1;
fixed-address 10.0.0.2;
option host-name "n1";
filename "/pxelinux.0";
}
}
' > /etc/dhcpd.conf
#I don't know why these are not included in stock Slackware
mkdir -p /var/state/dhcp
touch /var/state/dhcp/dhcpd.leases
#DHCP server activation
ifconfig eth0 10.0.0.1/24
dhcpd eth0
#Make this activation permanent
echo "ifconfig eth0 10.0.0.1/24" >> /etc/rc.d/rc.local
echo "dhcpd eth0" >> /etc/rc.d/rc.local
#Slackware installation
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/a/tagfile $CWD/slackware-iso-loop/slackware/a/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/ap/tagfile $CWD/slackware-iso-loop/slackware/ap/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/d/tagfile $CWD/slackware-iso-loop/slackware/d/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/e/tagfile $CWD/slackware-iso-loop/slackware/e/*.t?z
#installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/f/tagfile $CWD/slackware-iso-loop/slackware/f/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/k/tagfile $CWD/slackware-iso-loop/slackware/k/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/kde/tagfile $CWD/slackware-iso-loop/slackware/kde/*.t?z
#installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/kdei/tagfile $CWD/slackware-iso-loop/slackware/kdei/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/l/tagfile $CWD/slackware-iso-loop/slackware/l/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/n/tagfile $CWD/slackware-iso-loop/slackware/n/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/t/tagfile $CWD/slackware-iso-loop/slackware/t/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/tcl/tagfile $CWD/slackware-iso-loop/slackware/tcl/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/x/tagfile $CWD/slackware-iso-loop/slackware/x/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/x/tagfile $CWD/slackware-iso-loop/slackware/xfce/*.t?z
installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/xap/tagfile $CWD/slackware-iso-loop/slackware/xap/*.t?z
#installpkg -root /srv/exports/nfs/slackware/filesystem/ -tagfile $CWD/slackware-iso-loop/slackware/y/tagfile $CWD/slackware-iso-loop/slackware/y/*.t?z
#Make a temporary copy of the custom initrd mandatory packages inside the exported system
#They will be used later, in a chroot
cp $CWD/slackware-iso-loop/slackware/l/glibc-2*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
cp $CWD/slackware-iso-loop/slackware/n/dhcpcd-*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
cp $CWD/slackware-iso-loop/slackware/n/nfs-uti*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
cp $CWD/slackware-iso-loop/slackware/n/portmap*.t?z /srv/exports/nfs/slackware/filesystem/tmp/def/
#Ugly modifications
#Don't touch the initial initrd mount
sed -i -e "s/READWRITE=yes/READWRITE=no/g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
sed -i -e "s/\/sbin\/fsck \$FORCEFSCK -C -a \//#\/sbin\/fsck \$FORCEFSCK -C -a \//g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
sed -i -e "s/\/sbin\/mount -w -v -n -o remount \//#\/sbin\/mount -w -v -n -o remount \//g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
#sed -i -e "s/\/sbin\/mount -w -o remount \//#\/sbin\/mount -w -o remount \//g" /srv/exports/nfs/slackware/filesystem/etc/rc.d/rc.S
#Not used yet, at least in this form ;)
#echo "ftp://ftp.funet.fi/pub/mirrors/ftp.slackware.com/pub/slackware-13.37/" >> /srv/exports/nfs/slackware/filesystem/etc/slackpkg/mirrors
#Populate client's /etc/fstab
echo "10.0.0.1:/srv/exports/nfs/slackware/filesystem / nfs nfsvers=3,rsize=8192,wsize=8192,tcp 0 0
10.0.0.1:/srv/exports/nfs/slackware/homedirs/ /home/nfs/ nfs nfsvers=3,rsize=8192,wsize=8192,tcp,nolock 0 0
proc /proc proc defaults
ramfs /media ramfs 0 0
ramfs /tmp ramfs defaults 0 0
ramfs /var/lock ramfs 0 0
ramfs /var/log ramfs 0 0
ramfs /var/run ramfs 0 0
ramfs /var/state ramfs 0 0
ramfs /var/tmp ramfs 0 0
" > /srv/exports/nfs/slackware/filesystem/etc/fstab
#The client will use the same DNS as the server
cp /etc/resolv.conf /srv/exports/nfs/slackware/filesystem/etc/
##Cooking a Kernel for clients
cd /srv/exports/nfs/slackware/filesystem/usr/src/linux
cp .config config-shipped
#Stock kernel's .config "patching"
#In order to compile, the result must be identical to a classic 'make menuconfig'
#So be careful if you add options. Diff with a normally produced one
#ip-level autoconf
sed -i -e "s/# CONFIG_IP_PNP is not set/CONFIG_IP_PNP=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_IP_PNP=y/a \# CONFIG_IP_PNP_RARP is not set' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_IP_PNP=y/a \CONFIG_IP_PNP_BOOTP=y' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_IP_PNP=y/a \CONFIG_IP_PNP_DHCP=y' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#Network cards
sed -i -e "s/CONFIG_MII=m/CONFIG_MII=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_PHYLIB=m/CONFIG_PHYLIB=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i '/CONFIG_MICREL_PHY=m/a \# CONFIG_FIXED_PHY is not set' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s///g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s///g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s///g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_VORTEX is not set/CONFIG_VORTEX=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
##net hard
#sed -i -e "s/CONFIG_VORTEX=m/CONFIG_VORTEX=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_VORTEX is not set/CONFIG_VORTEX=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_TYPHOON=m/CONFIG_TYPHOON=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_TYPHOON is not set/CONFIG_TYPHOON=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_B44=m/CONFIG_B44=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_B44 is not set/CONFIG_B44=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_FORCEDETH=m/CONFIG_FORCEDETH=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_FORCEDETH is not set/CONFIG_FORCEDETH=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_E100=m/CONFIG_E100=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/# CONFIG_E100 is not set/CONFIG_E100=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_8139CP=m/CONFIG_8139CP=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_8139CP is not set/CONFIG_8139CP=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_8139TOO=m/CONFIG_8139TOO=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_8139TOO is not set/CONFIG_8139TOO=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL2=m/CONFIG_ATL2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL2 is not set/CONFIG_ATL2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_NETDEV_1000=m/CONFIG_NETDEV_1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/# CONFIG_NETDEV_1000 is not set/CONFIG_NETDEV_1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/CONFIG_E1000=m/CONFIG_E1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
sed -i -e "s/# CONFIG_E1000 is not set/CONFIG_E1000=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_IGB=m/CONFIG_IGB=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_IGB is not set/CONFIG_IGB=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_R8169=m/CONFIG_R8169=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_R8169 is not set/CONFIG_R8169=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_SKGE=m/CONFIG_SKGE=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_SKGE is not set/CONFIG_SKGE=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_TIGON3=m/CONFIG_TIGON3=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_TIGON3 is not set/CONFIG_TIGON3=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_BNX2=m/CONFIG_BNX2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_BNX2 is not set/CONFIG_BNX2=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL1=m/CONFIG_ATL1=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL1 is not set/CONFIG_ATL1=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL1E=m/CONFIG_ATL1E=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL1E is not set/CONFIG_ATL1E=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/CONFIG_ATL1C=m/CONFIG_ATL1C=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#sed -i -e "s/# CONFIG_ATL1C is not set/CONFIG_ATL1C=y/g" /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#Really mandatory one !
sed -i '/# CONFIG_NFS_V4_1 is not set/a \CONFIG_ROOT_NFS=y' /srv/exports/nfs/slackware/filesystem/usr/src/linux/.config
#make menuconfig
make clean
##Don't hesitate to tweak the cpu*2 number
make -j4 bzImage
make -j4 modules
#Client's kernel compilation and initrd generation, from inside
chroot /srv/exports/nfs/slackware/filesystem /bin/bash <<FinChroot1
##Not a good idea. If a kernel upgrade occurs, things may break
#slackpkg update
#slackpkg install-new
#slackpkg upgrade-all
cd /usr/src/linux
make modules_install
FinChroot1
cd /srv/exports/nfs/slackware/filesystem/usr/src/linux
rm /srv/exports/nfs/slackware/filesystem/boot/vmlinuz
rm /srv/exports/nfs/slackware/filesystem/boot/System.map
##32 and 64 bit compatibility, so now expect at least two cp errors :D
cp arch/i386/boot/bzImage /srv/exports/nfs/slackware/filesystem/boot/vmlinuz
cp arch/x86_64/boot/bzImage /srv/exports/nfs/slackware/filesystem/boot/vmlinuz
cp System.map /srv/exports/nfs/slackware/filesystem/boot/
chroot /srv/exports/nfs/slackware/filesystem /bin/bash <<FinChroot1bis
##Initrd
cd /boot
mkinitrd -c -f nfs -r 10.0.0.1:/srv/exports/nfs/slackware/filesystem/ -D eth0 -k 3.2.27-smp -m ehci_hcd:ohci_hcd:uhci_hcd:xhci_hcd:3c59x:b44:bnx2:tg3:skge:8139cp:8139too:r8169:atl1c:atl1e:atl1:atl2:e1000e:igb:forcedeth:broadcom:libphy:lxt:marvell:realtek
##Packages needed
##Note that i do not delete them after, for ease of debugging
installpkg -root /boot/initrd-tree/ /tmp/def/*.t?z
chmod +x /boot/initrd-tree/etc/rc.d/rc.rpc
sed -i '/Switch to real root partition:/a \/etc/rc.d/rc.rpc start' /boot/initrd-tree/init
sed -i '/Switch to real root partition:/a \/sbin/dhcpcd eth0' /boot/initrd-tree/init
##Dirty modification
sed -i -e "s/mount -o ro -t /mount -o rw,nolock -t /g" /boot/initrd-tree/init
mkinitrd
FinChroot1bis
#Back to host
#Copying custom official kernel and initrd to /srv/exports/tftpboot/slackware/
cp /srv/exports/nfs/slackware/filesystem/boot/vmlinuz /srv/exports/tftpboot/slackware/
cp /srv/exports/nfs/slackware/filesystem/boot/initrd.gz /srv/exports/tftpboot/slackware/
#A new chroot to manually finish the client's installation
chroot /srv/exports/nfs/slackware/filesystem /bin/bash <<FinChroot2
#Test
mount proc /proc -t proc
##Again, not a good idea. If a kernel upgrade occurs, things may break.
#slackpkg update
#slackpkg install-new
#slackpkg upgrade-all
##Setup
/var/log/setup/setup.04.mkfontdir
/var/log/setup/setup.05.fontconfig
/var/log/setup/setup.07.update-desktop-database
/var/log/setup/setup.07.update-mime-database
/var/log/setup/setup.08.gtk-update-icon-cache
#/var/log/setup/setup.htmlview
/var/log/setup/setup.mouse
#/var/log/setup/setup.netconfig
/var/log/setup/setup.services
#/var/log/setup/setup.setconsolefont
/var/log/setup/setup.timeconfig
/var/log/setup/setup.xwmconfig
##Guess what it adds:
#adduser
FinChroot2
umount slackware-iso-loop
date2=$(date +%s)
time=$(((date2-date1)/60))
echo "Build time: "$time" minutes."
echo "That's all folks !"
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.