- 投稿日:2019-07-09T21:41:30+09:00
Makefileを作ってビルドしよう(超初級編)
Cの入門書を進めてる途中(進捗だめです)
もう何回目の入門だよって感じですけどこれやってます
make……?makefile?
巷によくある入門書みたいにただ単にコンパイルするだけじゃなくてmakefileを作成してコンパイルを通すやり方で進んでいくので、実践に近い形になってます。(なってるそうです)
無知だった自分
実際にmakeでコンパイルを業務でしたことがあるにもかかわらず、読み進めて「これ実行ファイルの名前を変えてるだけなのにわざわざMakefile作る必要なくね?」と思ってしまったのですが、それをツイッターで呟いたらソースファイルが数百数千個あるでっかいプロジェクトでは便利というありがたいツッコミがございました
全く恥ずかしいことにこれまで現場で散々(といっても半年くらいですが)makeのお世話になってたはずなのに、どう書くかもどんなメリットがあるかも知らずにいました
Makefileをどうやって書くのか
Makefile.hogePROGRAM = hoge OBJS = hoge.o SRCS = $(OBJS:%.o=%.c) CC = gcc CFLAGS = -g -Wall LDFLAGS = $(PROGRAM):$(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $(OBJS) $(LDLIBS)※PROGRAM行のCCの後ろはタブです。
どんな意味があるかを上から解説します。
PROGRAM:プログラム名で、実行ファイルの名前になります
OBJS:リンクするオブジェクトファイル名をスペース区切りで列挙。hoge.o fuga.oみたいに続けて書くことで複数ファイルを指定できる……って認識であってますかね?
SRCS:ソースコードのファイル名指定。ここではOBJSの拡張子を.cにすることでコンパイル対象をhoge.cにしています。
CC:Cコンパイラのコマンド名。ここではgcc
CFLAGS:コンパイルのオプション指定。ここではデバッガ用の-gと警告を厳しくする-Wallを指定してます。
LDFLAGS:リンカのオプション指定(よくわかってないので割愛。特殊なライブラリのリンク等をする際に使用するそうです)
$(PROGRAM):プログラムの生成方法の記述Makefileの書き方は他にもあるようなので、まだまだ勉強が必要ですね……
Makefileを使ってビルド
$ make -f Makefile.hogeビルドの過程はこんな感じです
gcc -g -Wall -c -o hoge.o hoge.c gcc -g -Wall -o hoge hoge.oこれで実行ファイルhogeが出来るので以下で実行できます。
$ ./hogeまとめ
・Makefileは大規模開発で便利
・書き方多種多様……でも、makeいろんな書き方あるってことだけどググっても書籍がオライリー本しか出てこないのはどういうことなの。調べ方が悪い?
- 投稿日:2019-07-09T20:04:29+09:00
Slackware 14.2 の LVM への OS インストール例
当方執筆の技術情報に関するライセンス、免責事項、禁止事項
執筆動機
lvm に関連する一連のコマンドラインツール群、及び eliloconfig を活用することで、そこそこシンプルに LVM 領域への Slackware のインストールが可能でした。
※ なお、ESP( EFI システムパーティション)は LVM の中には置けないようです。おのれディケイドぉぉぉぉぉ!!
参考文献:
参考文献:
https://www.slackwiki.com/LVM/Luks_Encryption
https://wa3.i-3-i.info/word25557.html
https://wa3.i-3-i.info/word12796.html
https://www.debian.org/releases/stable/i386/apcs04.ja.html
https://wiki.archlinux.jp/index.php/LVM
https://wiki.gentoo.org/wiki/LVM/ja
https://ansaikuropedia.org/wiki/Uncyclopedia:%E9%A6%AC%E9%B9%BF%E3%81%AB%E3%81%AA%E3%82%89%E3%81%9A%E3%81%AB%E3%83%90%E3%82%AB%E3%83%90%E3%82%AB%E3%81%97%E3%81%8F%E3%82%84%E3%82%8B%E6%96%B9%E6%B3%95
https://www.linuxquestions.org/questions/slackware-14/slackware-current-elilo-lvm-4175534140/
http://www.slackware.com/~alien/archive/13.1/README_LVM.TXT
https://docs.slackware.com/howtos:slackware_admin:set_up_syslinux_as_boot_loader_on_uefi_based_hardware
http://docs.slackware.com/howtos:slackware_admin:set_up_grub_as_boot_loader_on_uefi_based_hardware
https://docs.slackware.com/howtos:slackware_admin:installing_on_uefi_hardware
https://www.reddit.com/r/slackware/comments/4ydl83/slackware_and_uefi_help/
https://blog.paranoidpenguin.net/2016/07/configuring-elilo-with-a-generic-kernel-on-slackware-14-2/
https://www.linuxquestions.org/questions/slackware-14/slackpkg-lilo-elilo-initrd-4175628620/
https://www.ibm.com/developerworks/jp/linux/library/l-initrd/index.html
https://tech.nikkeibp.co.jp/it/article/COLUMN/20061025/251702/
https://linux.die.net/man/8/mkinitrd
https://duckduckgo.com/?q=lvm+can't+deactivate
https://duckduckgo.com/?q=LVM+アンマウント
https://rin-ka.net/centos7-lvm/
https://www.youtube.com/watch?v=njxzwMGTWWs
https://wiki.gentoo.org/wiki/Chroot/ja
https://wiki.archlinux.jp/index.php/Chroot
http://toaruhenjin.com/digimono-review/hotswap
https://www.linuxquestions.org/linux/answers/Hardware/Mini_HOW_TO_Hibernate_and_resume_0
https://wiki.gentoo.org/wiki/Suspend_and_hibernate
https://takuya-1st.hatenablog.jp/entry/2016/12/16/183718
https://duckduckgo.com/?q=スーパー牛さんパワー
https://qiita.com/kon_yu/items/b8864ff566b8b67a9810
https://qiita.com/mkamotsu/items/0135d2e756db4a18d965
https://qiita.com/g_maeda/items/3602dc2f7af3f711f9c4
https://qiita.com/takaki@github/items/5d96d80dc78b09ea600bデスクトップ用途での LVM の利点として思いつくこと
色々インストールしたりダウンロードしたりコンパイルしたり好き放題していたらいつの間にか容量が足りない!という場合に少ない手間で容量を継ぎ足せます。
基本工程
・OS インストール環境の立ち上げ
・GPT でフォーマット
・LVM パーティションの作成
・LVM 論理ボリュームの作成
・通常の OS インストール手順
・ブートローダーの LVM 対応
・再起動インストール時に HDD/SSD/swap を暗号化したい場合
LVM/Luks Encryption - SlackWiki
https://www.slackwiki.com/LVM/Luks_Encryption
↑こちらをご覧下さい。※ EFI システムパーティションをこの方法で暗号化するのは無理っぽいです。改竄防止などは BIOS/UEFI 側の機能で行えるのかな?
※ Fat32 の EFI システムパーティションってセキュリティ的にはどうなんだろ?意外と強いのか?各工程の詳細
OS インストール環境の立ち上げ
インストールメディアの用意
!!!CAUTION!!!イメージを書き込むドライブを間違えないこと!
dd で空の USB メモリに インストール DVD の iso を流し込むのが楽です。インストールイメージ入手先
http://www.slackware.com/getslack/インストールメディアからブート
UEFI ブート。その際、インストール対象 HDD/SSD は IDE 互換モードではなく AHCI モードにしておく1。
GPT でフォーマット
!!!CAUTION!!!フォーマットするドライブを間違えないこと!
# fdisk -l # sgdisk -o /dev/moo※ /dev/moo は環境に応じて適宜読み替えて下さい。
参考文献:
Man page of FDISK
https://linuxjm.osdn.jp/html/util-linux/man8/fdisk.8.htmlMan page of SGDISK
http://www.rodsbooks.com/gdisk/sgdisk.htmlLinux におけるデバイス名
https://www.debian.org/releases/stable/i386/apcs04.ja.htmlLVM パーティションの作成
# sgdisk -p /dev/moo # sgdisk -n 1:2048:1050623 -c 1:"ESP" -t 1:ef00 /dev/moo # sgdisk -n 2:1050624:3147775 -c 2:"swap" -t 2:8200 /dev/moo # sgdisk -n 3:3147776:$(sgdisk -E /dev/sda) -c 3:"LVM00" -t 3:8e00 /dev/moo # sgdisk -p /dev/moo※ /dev/moo は環境に応じて適宜読み替えて下さい。
※ EFIシステムパーティション(ESP)は LVM の外に。
※ Swap パーティションは LVM の中でも外でも(中に置くと swsusp させる場合 mkinitrd で一工夫必要swsusp させる場合は mkinitrd で -h オプションを使うのが無難)。
※ 各パーティションに割り当てる容量はシステム環境や管理方針によります。
※ 2048 セクタ:1 MiB(1 セクタ 512 バイトの場合)
※ 1024 MiB = 1 GiB
※ 1024 GiB = 1 TiB
※ メモ書きからのコピペやシェルスクリプトに記述する用途では sgdisk 。通常使うなら対話的な gdisk や cgdisk が使いやすいかと。
参考文献:
Man page of SGDISK
http://www.rodsbooks.com/gdisk/sgdisk.htmlAn sgdisk Walkthrough
http://www.rodsbooks.com/gdisk/sgdisk-walkthrough.htmlsgdisk(gdisk コマンドライン版) でまとめて変更する使い方 - それマグで!
https://takuya-1st.hatenablog.jp/entry/2016/12/16/183718bash Tips - コマンド置換と算術式展開、パラメータ展開 - Qiita
https://qiita.com/mashumashu/items/bbc3a79bc779fe8c4f99Man page of BASH
https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.htmlLVM 論理ボリュームの作成
# pvcreate /dev/moo3 # vgcreate SlackVG /dev/moo3 # lvcreate -l 100%FREE SlackVG -n root※ /dev/moo3 SlackVG root は環境や用途、sgdisk の実行状況等に応じて適宜読み替えて下さい。
※ pv=PhysicalVolume vg=VolumeGroup lv=LogicalVolume 略語のもとになった言葉。
参考文献:
pvcreate(8) - Linux man page
https://linux.die.net/man/8/pvcreatevgcreate(8) - Linux man page
https://linux.die.net/man/8/vgcreatelvcreate(8) - Linux man page
https://linux.die.net/man/8/lvcreateLVM/Luks Encryption - SlackWiki
https://www.slackwiki.com/LVM/Luks_EncryptionLVM - ArchWiki
https://wiki.archlinux.jp/index.php/LVM通常の OS インストール手順
# setup※ 完了時にうっかり再起動をかけないこと。
参考文献:
http://www.slackware.com/install/setup.phpOS インストール環境におけるブートローダーの LVM 対応
# chroot /mnt # $(/usr/share/mkinitrd/mkinitrd_command_generator.sh -r) # exit # eliloconfig /mnt /dev/SlackVG/root※ mkinitrd_command_generator.sh は mkinitrd に対する適切な引数を自動生成するコマンドです。詳細は
/usr/share/mkinitrd/mkinitrd_command_generator.sh --longhelpで確認。
※ eliloconfig は引数1で OS ルートを、引数2でルートに対応するデバイスを指定出来るようです。
※ /dev/SlackVG/root は作成した論理ボリュームに応じて適宜読み替えて下さい。
※ 再起動後、インストール済みの Slackware からは eliloconfig に引数を与えなくとも正しく /boot/efi/EFI/Slackware/elilo.conf を生成出来ました。
※ カーネルのアップグレードを行った場合は忘れずに$(/usr/share/mkinitrd/mkinitrd_command_generator.sh -r)及びeliloconfigを実行すること。インストール済みの Slackware で行う場合 chroot の必要はありません。
参考文献:
bash Tips - コマンド置換と算術式展開、パラメータ展開 - Qiita
https://qiita.com/mashumashu/items/bbc3a79bc779fe8c4f99Man page of BASH
https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.htmlGNU Coreutils: 23.1 chroot: ルートディレクトリを変更して、コマンドを実行する
https://linuxjm.osdn.jp/info/GNU_coreutils/coreutils-ja_169.html#chroot-invocationChroot - Gentoo Wiki
https://wiki.gentoo.org/wiki/Chroot/jachroot - ArchWiki
https://wiki.archlinux.jp/index.php/ChrootLVM/Luks Encryption - SlackWiki
https://www.slackwiki.com/LVM/Luks_Encryption[SOLVED] Slackware-current elilo lvm
https://www.linuxquestions.org/questions/slackware-14/slackware-current-elilo-lvm-4175534140/
eliloconfig 本体
/usr/sbin/eliloconfig#!/bin/sh # Copyright 2013, 2016, 2017 Patrick Volkerding, Sebeka, Minnesota, USA # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 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. # # This script installs the elilo boot loader, the kernel, and optionally # an initrd into the EFI System Partition. A boot menu entry can also be # installed using efibootmgr. The kernel used will be whatever the symlink # /boot/vmlinuz points to, and if /boot/initrd.gz exists, that will be # installed as the initrd. # # The EFI System Partition is expected to be mounted on /boot/efi before # running this script. TMP=/var/log/setup/tmp # Set the OS root directory (called T_PX for some unknown reason). # If an argument is given to this script and it is a directory, it # is taken to be the root directory. First though, we check for a # directory named $T_PX, and that gets the first priority. if [ ! -d "$T_PX" ]; then if [ ! "$1" = "" ]; then if [ -d "$1" ]; then T_PX="$1" fi else # Are we on the installer image? if [ -r /usr/lib/setup/SeTpartitions ]; then T_PX=/mnt # Or, are we on a running system? elif [ -r /etc/slackware-version ]; then T_PX=/ # One more installer-likely thing: elif [ -r /usr/lib/setup/setup ]; then T_PX=/mnt else # We will have to assume we're on an installed and running system. T_PX=/ fi fi fi # Determine the root partition (such as /dev/sda1) ROOT_DEVICE=$2 if [ "$ROOT_DEVICE" = "" ]; then if [ -r $TMP/SeTrootdev ]; then ROOT_DEVICE="$(cat $TMP/SeTrootdev)" else ROOT_DEVICE="$(mount | cut -f 1 -d ' ' | head -n 1)" fi fi # If the system is not running under EFI, skip running this script: if [ ! -d /sys/firmware/efi ]; then if [ "$T_PX" = "/" ]; then echo "ERROR: System is not running under UEFI." fi exit fi # If there's no vfat mounted on /boot/efi or $T_PX/boot/efi, forget it: if ! mount | grep vfat | grep -wq /boot/efi ; then if ! mount | grep vfat | grep -wq $T_PX/boot/efi ; then if [ "$T_PX" = "/" ]; then echo "ERROR: No EFI System Partition mounted on /boot/efi." fi exit fi fi # Figure out the device and partition number of the ESP: DEVLEN=8 PARTLEN=9 if mount | grep vfat | grep -wq /boot/efi ; then mount | grep vfat | grep -w /boot/efi | grep -q -e nvme -e mmcblk && DEVLEN=12 && PARTLEN=14 EFI_DEVICE=$(mount | grep vfat | grep -w /boot/efi | cut -b 1-${DEVLEN}) EFI_PARTITION=$(mount | grep vfat | grep -w /boot/efi | cut -f 1 -d ' ' | cut -b ${PARTLEN}- | tr -d [a-z]) else mount | grep vfat | grep -w $T_PX/boot/efi | grep -q -e nvme -e mmcblk && DEVLEN=12 && PARTLEN=14 EFI_DEVICE=$(mount | grep vfat | grep -w $T_PX/boot/efi | cut -b 1-${DEVLEN}) EFI_PARTITION=$(mount | grep vfat | grep -w $T_PX/boot/efi | cut -f 1 -d ' ' | cut -b ${PARTLEN}- | tr -d [a-z]) fi # There better be a kernel: if [ ! -r $T_PX/boot/vmlinuz ]; then if [ "$T_PX" = "/" ]; then echo "ERROR: No kernel found at /boot/vmlinuz." fi exit fi dialog --title "INSTALL ELILO" \ --backtitle "ELILO (EFI Linux Loader) installation" \ --menu "ELILO is a Linux boot loader for \ EFI based systems. Installing ELILO will allow you to boot your Linux \ system from the hard drive after selecting it from the UEFI boot menu. \ Since an EFI System Partition was detected on this machine, it is \ recommended that you install ELILO now. Please select an option:" \ 13 70 2 \ "install" "Install ELILO on the EFI System Partition" \ "skip" "Do not install ELILO" 2> $TMP/reply if [ $? = 1 -o $? = 255 ]; then exit fi REPLY="`cat $TMP/reply`" rm -f $TMP/reply if [ "$REPLY" = "skip" ]; then exit fi mkdir -p $T_PX/boot/efi/EFI/Slackware 1> /dev/null 2> /dev/null cat << EOF > $T_PX/boot/efi/EFI/Slackware/elilo.conf chooser=simple delay=1 timeout=1 # EOF cp -a $T_PX/boot/elilo-x86_64.efi $T_PX/boot/efi/EFI/Slackware/elilo.efi 1> /dev/null 2> /dev/null cp $T_PX/boot/vmlinuz $T_PX/boot/efi/EFI/Slackware 1> /dev/null 2> /dev/null cat << EOF >> $T_PX/boot/efi/EFI/Slackware/elilo.conf image=vmlinuz label=vmlinuz EOF touch -r $T_PX/boot/vmlinuz $T_PX/boot/efi/EFI/Slackware/vmlinuz if [ -r $T_PX/boot/initrd.gz ]; then cp $T_PX/boot/initrd.gz $T_PX/boot/efi/EFI/Slackware 1> /dev/null 2> /dev/null touch -r $T_PX/boot/initrd.gz $T_PX/boot/efi/EFI/Slackware/initrd.gz cat << EOF >> $T_PX/boot/efi/EFI/Slackware/elilo.conf initrd=initrd.gz EOF fi cat << EOF >> $T_PX/boot/efi/EFI/Slackware/elilo.conf read-only append="root=$ROOT_DEVICE vga=normal ro" EOF dialog --title "INSTALL BOOT MENU ENTRY?" \ --backtitle "ELILO (EFI Linux Loader) installation" \ --menu "Would you like to install \ a boot menu entry so that you can easily select Slackware when you boot your \ machine? WARNING: DO NOT install a boot menu entry on Apple hardware. \ Apple computers use a different type of EFI firmware, and efibootmgr has \ been known to damage them. On all other computers, it is recommended to add \ a boot menu entry. Please select an option:" \ 14 70 2 \ "install" "Install a boot menu entry" \ "skip" "Do not install a boot menu entry" 2> $TMP/reply if [ $? = 1 -o $? = 255 ]; then exit fi REPLY="`cat $TMP/reply`" rm -f $TMP/reply if [ "$REPLY" = "skip" ]; then exit fi if [ ! -d /sys/firmware/efi/vars ]; then modprobe efivars 1> /dev/null 2> /dev/null sleep 1 # Probably not needed, but playing it safe fi # If it's still gone, we fail silently: if [ ! -d /sys/firmware/efi/vars ]; then exit fi efibootmgr -v | rev | cut -f 2- | rev | grep Boot0 | grep Slackware | while read line ; do # Reject entries that don't exactly match as not our business if [ ! "$(echo $line | cut -f 2- -d ' ')" = "Slackware" ]; then continue fi ENTRY="$(efibootmgr -v | grep "^$(echo $line | cut -b1-8)")" dialog --title "REMOVE OLD \"Slackware\" EFI BOOT ENTRY?" \ --backtitle "ELILO (EFI Linux Loader) installation" \ --yesno "An old Slackware boot entry has been found in your EFI boot menu. \ Would you like to remove this before installing the new Slackware boot \ entry? This is recommended.\n\nOld EFI boot menu entry:\n$ENTRY" 13 70 if [ ! $? = 0 ]; then continue fi # Remove the boot entry: efibootmgr -q -B -b $(echo $line | cut -b5-8) done efibootmgr -q -c -d $EFI_DEVICE -p $EFI_PARTITION -l "\\EFI\\Slackware\\elilo.efi" -L "Slackware" efibootmgr -v | rev | cut -f 2- | rev | grep Boot0 | grep Slackware | while read line ; do # Reject entries that don't exactly match as not our business if [ ! "$(echo $line | cut -f 2- -d ' ')" = "Slackware" ]; then continue fi ENTRY="$(efibootmgr -v | grep "^$(echo $line | cut -b1-8)")" if echo $ENTRY | grep -q -F "\EFI\Slackware\elilo.efi" ; then dialog --title "EFI BOOT ENTRY INSTALLED" \ --backtitle "ELILO (EFI Linux Loader) installation" \ --msgbox "A Slackware boot entry has been installed to your EFI boot menu.\n\nEFI boot menu entry:\n$ENTRY" 11 70 fi done # Done.
mkinitrd_command_generator.sh 本体
/usr/share/mkinitrd/mkinitrd_command_generator.sh#!/bin/sh # $Id: mkinitrd_command_generator.sh,v 1.45 2011/02/17 09:27:05 eha Exp eha $ # Copyright 2013 Patrick J. Volkerding, Sebeka, Minnesota, USA # Copyright 2008, 2009, 2010, 2011 Eric Hameleers, Eindhoven, Netherlands # # Copyright 2008, 2009 PiterPUNK, Sao Paulo, SP, Brazil # # All rights reserved. # # Permission to use, copy, modify, and distribute this software for # any purpose with or without fee is hereby granted, provided that # the above copyright notice and this permission notice appear in all # copies. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR # CONTRIBUTORS 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. # ----------------------------------------------------------------------------- # # Create an initrd which fits the system. # Take into account the use of LVM/LUKS/RAID. # Find out about any hardware drivers the system may need in an initrd when # booting from a generic lightweight kernel. # # ----------------------------------------------------------------------------- # The script's revision number will be displayed in the help text: REV=$( echo "$Revision: 1.45 $" | cut -d' ' -f2 ) # Define some essential parameter values: USING_LVM="" USING_LUKS="" USING_RAID="" MLIST="" REALDEV="" # The device that contains the LUKS volume BASEDEV="" # Lowest level device (raw block device or RAID volume) FSTAB=${FSTAB:-"/etc/fstab"} # so we can test with alternate fstab files # These are needed by -c and -i options: SOURCE_TREE=${SOURCE_TREE:-"/boot/initrd-tree"} CLEAR_TREE=${CLEAR_TREE:-1} KEYMAP=${KEYMAP:-"us"} UDEV=${UDEV:-1} # ARM devices need more time: case "$( uname -m )" in arm*) WAIT_DEFAULT=4;; *) WAIT_DEFAULT=1;; esac WAIT=${WAIT:-$WAIT_DEFAULT} # A basic explanation of the commandline parameters: basic_usage() { cat <<-EOT *** $(basename $0) revision $REV *** Usage: $(basename $0) [ options ] [ kernel_filename ] Options: -a <"additional params"> Additional parameters to pass to mkinitrd. -c | --conf Show a suitable mkinitrd configuration file. -h | --help Show this help. -i | --interactive Navigate through menus instead of using commandline arguments. --longhelp Show more detailed information/examples. -k <kernelversion> Use specific kernel version. -m <"additional mods"> Additional modules to pass to mkinitrd, separated by colons (:). -l | --lilo Only show lilo.conf section (requires a kernel_filename). -r | --run Only show 'mkinitrd' command. EOT } # More of a tutorial here: extended_usage() { cat <<-EOT This script is useful in situations where you require an initrd image to boot your computer. For instance, when booting a kernel that does not have support for your storage or root filesystem built in (such as the Slackware 'generic' kernels'). * When you run the script without parameters, it will examine your running system, your current kernel version and will output an example of a 'mkinitrd' commandline that you can use to generate an initrd image containing enough driver support to boot the computer. * You can make it more specific: when you add the filename of a kernel as parameter to the script, it will determine the kernel version from that kernel, and also give an example of the lines that you should add to your '/etc/lilo.conf' file. * If you want your initrd image to have a custom name instead of the default '/boot/initrd.gz' you can add it as another parameter to the script, as follows: $(basename $0) -a "-o /boot/custom.gz" The arguments to the '-a' parameter will be used as additional arguments to the 'mkinitrd' command. * If you need additional modules in the initrd image, apart from what the script determines, you can pass then to the script using the '-m' parameter as follows: $(basename $0) -m "uhci-hcd:usbhid:hid_generic" The above example adds support for USB keyboards to the initrd - you may need that if you have encrypted your root partition and need to enter a passphrase using a USB keyboard. * Instead of copying and pasting the script's output, you can create an initrd by directly executing the output, like in this example: EOT echo " \$($(basename $0) --run /boot/vmlinuz-generic-smp-2.6.35.11-smp)" cat <<-EOT That used the '-r' or '--run' switch to make the script only write the 'mkinitrd' commandline to the terminal. * When you want to add a section for a specific kernel to '/etc/lilo.conf' directly, use the '-l' or '--lilo' switch and use a command like in this example: EOT echo " $(basename $0) --lilo /boot/vmlinuz-generic-smp-2.6.35.11-smp >>/etc/lilo.conf" cat <<-EOT That command will result in the following lines being added to your '/etc/lilo.conf' file (example for my hardware): # Linux bootable partition config begins # initrd created with 'mkinitrd -c -k 2.6.35.11-smp -m ata_generic:pata_amd:mbcache:jbd:ext3 -f ext3 -r /dev/hda7' image = /boot/vmlinuz-generic-smp-2.6.35.11-smp initrd = /boot/initrd.gz root = /dev/hda7 label = 2.6.35.11-smp read-only # Linux bootable partition config ends The last two examples show how easy it is to configure your computer for the use of an initrd if you need one. The only thing left to do afterwards is running 'lilo'. EOT } # Find the device that holds the root partition: get_root_device() { if [ -e $FSTAB ]; then RD=$(cat $FSTAB |tr '\t' ' ' |grep -v '^ *#' |tr -s ' ' |grep ' / ' |cut -f1 -d' ') if [ "$(echo $RD | cut -f1 -d=)" = "LABEL" -o "$(echo $RD | cut -f1 -d=)" = "UUID" ]; then DKEY=$(echo $RD | cut -f1 -d=) # The value can be LABEL=foo or LABEL='foo' or LABEL="foo" DVAL=$(echo $RD | cut -f2 -d= | tr -d "'\042") RD=$(/sbin/blkid | grep -w $DKEY | grep -w $DVAL | cut -f1 -d:) fi else RD=$(grep -m1 "^/dev/.*[[:blank:]]/[[:blank:]]" /proc/mounts | cut -f1 -d' ') fi echo $RD } # Get the root fs information: get_rootfs_type() { if $(type blkid 1>/dev/null 2>&1) ; then blkid -s TYPE -o value $ROOTDEV elif $(type vol_id 1>/dev/null 2>&1) ; then vol_id $ROOTDEV | grep ID_FS_TYPE | cut -f2 -d= else # As a fallback, use: cat $FSTAB |tr '\t' ' ' |grep -v '^ *#' |tr -s ' ' |grep ' / ' |cut -f3 -d' ' fi } # Add the module(s) needed for the root filesystem: add_rootfs_module() { local FSMOD FSMOD=$(/sbin/modprobe --set-version $KVER --show-depends ${ROOTFS} 2>/dev/null | while read LINE; do echo $(basename $(echo $LINE | cut -d' ' -f2) .ko ) done) if [ -n "$FSMOD" ]; then [ -n "$MLIST" ] && echo "$MLIST:$(echo $FSMOD | tr ' ' ':')" \ || echo $FSMOD | tr ' ' ':' fi } # Determine the list of kernel modules needed to support the root device: determine_blockdev_drivers() { # Walk the /sys tree to find kernel modules that are # required for our storage devices. # Thanks to PiterPUNK for help with this code. local MLIST MLIST=$(for i in $(find /sys/block/*/ -name "device" -print0 | xargs -0 -i'{}' readlink -f '{}' | sort -u); do /sbin/udevadm info --query=all --path=$i --attribute-walk | \ sed -ne 's/^[[:blank:]]\+DRIVER[S]*=="\([^"]\+\)"$/\1/p' | \ xargs -I@ /sbin/modprobe --set-version $KVER --show-depends @ \ 2>/dev/null | grep -v "builtin " | \ while read LINE ; do echo $(basename $(echo $LINE | cut -d' ' -f2) .ko ) done done) MLIST=$( echo $MLIST | tr ' ' ':' ) echo $MLIST } # Search for USB keyboards: function add_usb_keyboard() { local USBMOD if cat /proc/bus/input/devices | sed -e 's/^$/\$/g' | \ tr "\n$" " \n" | grep -q " Phys=.*usb.* .*Handlers=.*kbd.*B:"; then USBMOD="xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:hid:usbhid:i2c-hid:hid_generic:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch" [ -n "$MLIST" ] && MLIST="$MLIST:$USBMOD" \ || MLIST="$USBMOD" fi echo $MLIST } # Determine what USB Host Controller is in use function add_usb_hcd() { local USBMOD for i in $(ls -Ld /sys/module/*_hcd/drivers/* 2> /dev/null); do if ls -L $i | grep -q "[0-9a-f]*:" ; then USBMOD=$( echo $i | cut -f4 -d/ | tr "_" "-") [ -n "$MLIST" ] && MLIST="$MLIST:$USBMOD" \ || MLIST="$USBMOD" fi done echo $MLIST } # Is the root partition on a (combination of) LVM/LUKS volume? check_luks_lvm_raid() { if $( lvdisplay -c $ROOTDEV 1>/dev/null 2>/dev/null ); then # Our root partition is on a LV: USING_LVM=1 # Search the Physical Volume of our Logical Volume: MYVG=$( echo $(lvdisplay -c $ROOTDEV 2>/dev/null) | cut -d: -f2 ) for LINE in $(pvdisplay -c) ; do VG=$(echo $LINE | cut -d: -f2) [ "$VG" = "$MYVG" ] && break done PV=$(echo $LINE | cut -d: -f1) # Check if there is a LUKS device underneath: if $( cryptsetup status $PV 1>/dev/null 2>/dev/null ) ; then # Our root partition's LV is on a LUKS volume: USING_LUKS=1 REALDEV=$( cryptsetup status $PV | grep 'device: ' | tr -d ' ' | cut -d: -f2 ) BASEDEV=$REALDEV else BASEDEV=$PV fi elif $( cryptsetup status $ROOTDEV 1>/dev/null 2>/dev/null ) ; then # Our root device is on a LUKS volume: USING_LUKS=1 REALDEV=$( cryptsetup status $ROOTDEV | grep 'device: ' | tr -d ' ' | cut -d: -f2 ) ROOTDEV=$(basename $ROOTDEV) # Check for LVM: for LV in $(lvdisplay -c 2>/dev/null | tr -d ' ' | cut -f1 -d:) ; do # Note: cryptsetup shows the real device, whereas # lvdisplay requires the /dev/<myvg>/... symlink to the real device. if [ "$(readlink $LV)" = "$REALDEV" ]; then REALDEV=$LV break fi done if $( lvdisplay -c $REALDEV 1>/dev/null 2>/dev/null ); then # Our root partition's LUKS device is on a LV: USING_LVM=1 # Search the Physical Volume of our Logical Volume: MYVG=$( echo $(lvdisplay -c $REALDEV 2>/dev/null) | cut -d: -f2 ) for LINE in $(pvdisplay -c) ; do VG=$(echo $LINE | cut -d: -f2) [ "$VG" = "$MYVG" ] && break done PV=$(echo $LINE | cut -d: -f1) BASEDEV=$PV else BASEDEV=$REALDEV fi else BASEDEV=$ROOTDEV fi # Finally, we should check if base device is # a real block device or a RAID volume: for MD in $(cat /proc/mdstat | grep -w active | cut -d' ' -f1) ; do if [ "$BASEDEV" = "/dev/$MD" ]; then USING_RAID=1 break fi done } # Before we start [ -x /bin/id ] && CMD_ID="/bin/id" || CMD_ID="/usr/bin/id" if [ "$($CMD_ID -u)" != "0" ]; then echo "You need to be root to run $(basename $0)." exit 1 fi # Parse the commandline parameters: while [ ! -z "$1" ]; do case $1 in --longhelp) basic_usage extended_usage exit 0 ;; -a) MKINIT_PARAMS="$2" shift 2 ;; -c|--conf) [ -n "$EMIT" ] && { echo "Do not mix incompatible parameters!"; exit 1; } EMIT="conf" shift ;; -h|--help) basic_usage exit 0 ;; -i|--interactive) INTERACTIVE=1 shift ;; -k) KVER=$2 shift 2 ;; -m) MKINIT_MODS=$2 shift 2 ;; -l|--lilo) [ -n "$EMIT" ] && { echo "Do not mix incompatible parameters!"; exit 1; } EMIT="lilo" shift ;; -L|--fromlilo) FROMLILO=1 shift ;; -r|--run) [ -n "$EMIT" ] && { echo "Do not mix incompatible parameters!"; exit 1; } EMIT="run" shift ;; -R|--rootdev) ROOTDEV=$2 shift 2 ;; -*) echo "Unsupported parameter '$1'!" exit 1 ;; *) # Everything else but switches (which start with '-') follows: if [ -f $1 ]; then KFILE=$1 # Construction of KFILE's full filename: KFILEPATH=$(cd $(dirname $KFILE) && pwd) if [ -L $KFILE ]; then KFILE=$(readlink $KFILE) else KFILE=$(basename $KFILE) fi KFILE=${KFILEPATH}/$KFILE if [ -z "$(file $KFILE | grep -E 'Linux kernel x86 boot|x86 boot sector')" ]; then echo "File '$KFILE' does not look like it is a kernel file!" exit 1 fi else echo "File $1 not found!" exit 1 fi shift ;; esac done # Determine what to show as output (other options may have set EMIT already) EMIT=${EMIT:-"all"} # An EMIT value of 'lilo' requires a kernel filename as script parameter: if [ "$EMIT" = "lilo" ]; then if [ -z "$KFILE" ]; then echo "A kernel_filename is required with the '-l|--lilo' option!" exit 1 fi fi # Determine kernel version to use, # and check if modules for this kernel are actually present: if [ -z "$KVER" ]; then if [ -n "$KFILE" ]; then KVER="$(strings $KFILE | grep '([^ ]*@[^ ]*) #' | cut -f1 -d' ')" else KVER="$(uname -r)" fi fi if [ ! -d /lib/modules/$KVER ]; then echo "Modules for kernel $KVER aren't installed." exit 1 fi # Determine whether the user passed an alternate filename for the initrd: if [ -n "$MKINIT_PARAMS" ]; then SRCHLIST="$MKINIT_PARAMS" for ELEM in $MKINIT_PARAMS ; do SRCHLIST=$(echo $SRCHLIST | cut -d' ' -f2-) # cut ELEM from the list if [ "$ELEM" = "-o" ]; then IMGFILE=$(echo $SRCHLIST | cut -d' ' -f1) break fi done fi IMGFILE=${IMGFILE:-"/boot/initrd.gz"} # Get information about the root device / root filesystem: ROOTDEV=${ROOTDEV:-$(get_root_device)} ROOTFS=$(get_rootfs_type) # Determine the list of kernel modules needed to support the root device: MLIST=$(determine_blockdev_drivers) # Check if we are running in a kvm guest with virtio block device driver # (add all virtio modules, we sort out the doubles later): if echo $MLIST | grep -q "virtio"; then MLIST="$MLIST:virtio:virtio_balloon:virtio_blk:virtio_ring:virtio_pci:virtio_net" fi # Determine if a USB keyboard is in use and include usbhid and hid_generic # to module list MLIST=$(add_usb_keyboard) # If we use any USB module, try to determine the Host Controller if echo $MLIST | grep -q "usb"; then MLIST=$(add_usb_hcd) fi # Check what combination of LUKS/LVM/RAID we have to support: # This sets values for USING_LUKS, USING_LVM, USING_RAID, REALDEV and BASEDEV. check_luks_lvm_raid # This is the interactive part: if [ "$INTERACTIVE" = "1" ]; then if [ "$FROMLILO" != "1" ]; then dialog --stdout --title "WELCOME TO MKINITRD COMMAND GENERATOR" --msgbox "\ The main goal of this utility is to create a good initrd to \ fit your needs. It can detect what kernel you are running, \ what is your root device, root filesystem, if you use encryption, \ LVM, RAID, etc. \ \n\n\ Usually the probed values are OK and they will be the \ defaults in all subsequent dialogs, but maybe you want \ to change something. \n\ If in doubt, leave the defaults." 0 0 KVER=$( ls -d1 --indicator-style=none /lib/modules/* | \ awk -F/ -vVER=$KVER '{ if ( VER == $NF ) { ONOFF="on" } else { ONOFF="off" } ; printf("%s \"\" %s\n",$NF,ONOFF) }' | \ xargs dialog --stdout --title "CHOOSE KERNEL VERSION" \ --default-item $KVER --radiolist "\ Please, select the kernel version you want to create this initrd for." 0 0 4 ) [ -z "$KVER" ] && exit 1 OLDROOTDEV=$ROOTDEV ROOTDEV=$( dialog --stdout --title "SELECT ROOT DEVICE" --inputbox "\ Enter your root device. Root device is the one where your '/' filesystem \ is mounted." 0 0 "$ROOTDEV" ) [ -z "$ROOTDEV" ] && exit 1 # We need to re-check our defaults in case the user changed the default # value for ROOTDEV: [ "$OLDROOTDEV" != "$ROOTDEV" ] && check_luks_lvm_raid ROOTFS=$(get_rootfs_type) ROOTFS=$( dialog --stdout --title "SELECT ROOT FILESYSTEM" --inputbox "\ Enter the type of your root filesystem." 0 0 "$ROOTFS" ) [ -z "$ROOTFS" ] && exit 1 fi MLIST=$(add_rootfs_module) LLR=$( dialog --stdout --title "LVM/LUKS/RAID" --checklist "\ Do you use some of those in your root filesystem? \ If this is the case, please select one or more options." 12 45 3 \ "LVM" "Logical Volume Manager" $([ "$USING_LVM" = "1" ] && echo on || echo off) \ "LUKS" "Linux Unified Key Setup" $([ "$USING_LUKS" = "1" ] && echo on || echo off) \ "RAID" "Linux Software RAID" $([ "$USING_RAID" = "1" ] && echo on || echo off)) if [ "$?" != "0" ]; then exit 1 fi echo $LLR | grep -q LUKS && USING_LUKS="1" echo $LLR | grep -q LVM && USING_LVM="1" echo $LLR | grep -q RAID && USING_RAID="1" if [ "$USING_LUKS" = "1" ]; then REALDEV=$( dialog --stdout --title "LUKS ROOT DEVICE" --inputbox "\ Please, enter your LUKS root device:" 0 0 "$REALDEV" ) [ -z "$REALDEV" ] && exit 1 fi fi # Step out of the interactive loop for a moment. The next block needs to be # executed in all cases. # We need to 'undouble' the MLIST array. Some people report that walking the # /sys tree produces duplicate modules in the list. # The awk command elimitates doubles without changing the order: MLIST=$( echo $MLIST | tr ':' '\n' | awk '!x[$0]++' | tr '\n' ' ' ) MLIST=$( echo $MLIST | tr ' ' ':' ) MLIST=$(echo ${MLIST%:}) # To weed out a trailing ':' which was reported once. # Back to the interactive part: if [ "$INTERACTIVE" = "1" ]; then MLIST=$( dialog --stdout --title "INITRD'S MODULE LIST" --inputbox "\ The list here shows all modules needed to support your root filesystem \ and boot from it. But you can change the list to use some alternative \ or additional modules. If you don't know what to do, the default is safe." \ 0 0 "$MLIST" ) if [ "$?" != "0" ]; then exit 1 fi EXTRA=$( dialog --stdout --title "EXTRA CONFIGURATION" --checklist "\ Now is your chance for some additional configuration. All of these \ configurations are optional and you can stick to the defaults." 11 72 3 \ "KEYMAP" "Select keyboard layout (default: US)" \ $([ $USING_LUKS = 1 ] && echo on || echo off) \ "RESUMEDEV" "Select device for 'suspend-to-disk' feature" off \ "UDEV" "Use UDEV in the initrd for device configuration" $(test $UDEV -eq 1 && echo on || echo off) \ "WAIT" "Add delay to allow detection of slow disks at boot" $(test $WAIT -gt $WAIT_DEFAULT && echo on || echo off) ) if [ "$?" != "0" ]; then exit 1 fi if echo $EXTRA | grep -q KEYMAP ; then KEYMAP=$( dialog --stdout --title "KEYBOARD LAYOUT SELECTION" \ --cancel-label "Skip" \ --menu "You may select one of the following keyboard layouts. \ If you do not select a keyboard map, 'us.map' \ (the US keyboard layout) is the default. Use the UP/DOWN \ arrow keys and PageUp/PageDown to scroll \ through the whole list of choices." \ 22 55 11 \ "qwerty/us.map" "" \ "azerty/azerty.map" "" \ "azerty/be-latin1.map" "" \ "azerty/fr-latin0.map" "" \ "azerty/fr-latin1.map" "" \ "azerty/fr-latin9.map" "" \ "azerty/fr-old.map" "" \ "azerty/fr-pc.map" "" \ "azerty/fr.map" "" \ "azerty/wangbe.map" "" \ "azerty/wangbe2.map" "" \ "dvorak/ANSI-dvorak.map" "" \ "dvorak/dvorak-l.map" "" \ "dvorak/dvorak-r.map" "" \ "dvorak/dvorak.map" "" \ "dvorak/no-dvorak.map" "" \ "fgGIod/tr_f-latin5.map" "" \ "fgGIod/trf-fgGIod.map" "" \ "olpc/es-olpc.map" "" \ "olpc/pt-olpc.map" "" \ "qwerty/bg-cp1251.map" "" \ "qwerty/bg-cp855.map" "" \ "qwerty/bg_bds-cp1251.map" "" \ "qwerty/bg_bds-utf8.map" "" \ "qwerty/bg_pho-cp1251.map" "" \ "qwerty/bg_pho-utf8.map" "" \ "qwerty/br-abnt.map" "" \ "qwerty/br-abnt2.map" "" \ "qwerty/br-latin1-abnt2.map" "" \ "qwerty/br-latin1-us.map" "" \ "qwerty/by-cp1251.map" "" \ "qwerty/by.map" "" \ "qwerty/bywin-cp1251.map" "" \ "qwerty/cf.map" "" \ "qwerty/cz-cp1250.map" "" \ "qwerty/cz-lat2-prog.map" "" \ "qwerty/cz-lat2.map" "" \ "qwerty/cz-qwerty.map" "" \ "qwerty/defkeymap.map" "" \ "qwerty/defkeymap_V1.0.map" "" \ "qwerty/dk-latin1.map" "" \ "qwerty/dk.map" "" \ "qwerty/emacs.map" "" \ "qwerty/emacs2.map" "" \ "qwerty/es-cp850.map" "" \ "qwerty/es.map" "" \ "qwerty/et-nodeadkeys.map" "" \ "qwerty/et.map" "" \ "qwerty/fi-latin1.map" "" \ "qwerty/fi-latin9.map" "" \ "qwerty/fi-old.map" "" \ "qwerty/fi.map" "" \ "qwerty/gr-pc.map" "" \ "qwerty/gr.map" "" \ "qwerty/hu101.map" "" \ "qwerty/il-heb.map" "" \ "qwerty/il-phonetic.map" "" \ "qwerty/il.map" "" \ "qwerty/is-latin1-us.map" "" \ "qwerty/is-latin1.map" "" \ "qwerty/it-ibm.map" "" \ "qwerty/it.map" "" \ "qwerty/it2.map" "" \ "qwerty/jp106.map" "" \ "qwerty/kazakh.map" "" \ "qwerty/kyrgyz.map" "" \ "qwerty/la-latin1.map" "" \ "qwerty/lt.baltic.map" "" \ "qwerty/lt.l4.map" "" \ "qwerty/lt.map" "" \ "qwerty/mk-cp1251.map" "" \ "qwerty/mk-utf.map" "" \ "qwerty/mk.map" "" \ "qwerty/mk0.map" "" \ "qwerty/nl.map" "" \ "qwerty/nl2.map" "" \ "qwerty/no-latin1.map" "" \ "qwerty/no.map" "" \ "qwerty/pc110.map" "" \ "qwerty/pl.map" "" \ "qwerty/pl1.map" "" \ "qwerty/pl2.map" "" \ "qwerty/pl3.map" "" \ "qwerty/pl4.map" "" \ "qwerty/pt-latin1.map" "" \ "qwerty/pt-latin9.map" "" \ "qwerty/pt.map" "" \ "qwerty/ro.map" "" \ "qwerty/ro_std.map" "" \ "qwerty/ru-cp1251.map" "" \ "qwerty/ru-ms.map" "" \ "qwerty/ru-yawerty.map" "" \ "qwerty/ru.map" "" \ "qwerty/ru1.map" "" \ "qwerty/ru2.map" "" \ "qwerty/ru3.map" "" \ "qwerty/ru4.map" "" \ "qwerty/ru_win.map" "" \ "qwerty/ruwin_alt-CP1251.map" "" \ "qwerty/ruwin_alt-KOI8-R.map" "" \ "qwerty/ruwin_alt-UTF-8.map" "" \ "qwerty/ruwin_cplk-CP1251.map" "" \ "qwerty/ruwin_cplk-KOI8-R.map" "" \ "qwerty/ruwin_cplk-UTF-8.map" "" \ "qwerty/ruwin_ct_sh-CP1251.map" "" \ "qwerty/ruwin_ct_sh-KOI8-R.map" "" \ "qwerty/ruwin_ct_sh-UTF-8.map" "" \ "qwerty/ruwin_ctrl-CP1251.map" "" \ "qwerty/ruwin_ctrl-KOI8-R.map" "" \ "qwerty/ruwin_ctrl-UTF-8.map" "" \ "qwerty/se-fi-ir209.map" "" \ "qwerty/se-fi-lat6.map" "" \ "qwerty/se-ir209.map" "" \ "qwerty/se-lat6.map" "" \ "qwerty/se-latin1.map" "" \ "qwerty/sk-prog-qwerty.map" "" \ "qwerty/sk-qwerty.map" "" \ "qwerty/speakup-jfw.map" "" \ "qwerty/speakupmap.map" "" \ "qwerty/sr-cy.map" "" \ "qwerty/sv-latin1.map" "" \ "qwerty/tr_q-latin5.map" "" \ "qwerty/tralt.map" "" \ "qwerty/trf.map" "" \ "qwerty/trq.map" "" \ "qwerty/ttwin_alt-UTF-8.map.gz" "" \ "qwerty/ttwin_cplk-UTF-8.map.gz" "" \ "qwerty/ttwin_ct_sh-UTF-8.map.gz" "" \ "qwerty/ttwin_ctrl-UTF-8.map.gz" "" \ "qwerty/ua-cp1251.map.gz" "" \ "qwerty/ua-utf-ws.map" "" \ "qwerty/ua-utf.map" "" \ "qwerty/ua-ws.map" "" \ "qwerty/ua.map" "" \ "qwerty/uk.map" "" \ "qwerty/us-acentos.map" "" \ "qwerty/us.map" "" \ "qwertz/croat.map" "" \ "qwertz/cz-us-qwertz.map" "" \ "qwertz/cz.map" "" \ "qwertz/de-latin1-nodeadkeys.map" "" \ "qwertz/de-latin1.map" "" \ "qwertz/de.map" "" \ "qwertz/de_CH-latin1.map" "" \ "qwertz/fr_CH-latin1.map" "" \ "qwertz/fr_CH.map" "" \ "qwertz/hu.map" "" \ "qwertz/sg-latin1-lk450.map" "" \ "qwertz/sg-latin1.map" "" \ "qwertz/sg.map" "" \ "qwertz/sk-prog-qwertz.map" "" \ "qwertz/sk-qwertz.map" "" \ "qwertz/slovene.map" "" ) [ -n "$KEYMAP" ] && KEYMAP=$(basename $KEYMAP .map) fi if echo $EXTRA | grep -q UDEV ; then UDEV=1 fi if echo $EXTRA | grep -q RESUMEDEV ; then # Print information about swap partitions: FREERAM=$(free -k | grep "^Mem:" | tr -s ' ' | cut -d' ' -f2) SWPINFO="" for SWPDEV in $(grep -w swap $FSTAB | cut -d' ' -f1) ; do SWPINFO="$SWPINFO $SWPDEV Linux swap partition $(fdisk -s $SWPDEV) KB \\n" [ $(fdisk -s $SWPDEV) -gt $FREERAM ] && RESUMEDEV=$SWPDEV done FREERAM=$(free -m | grep "^Mem:" | tr -s ' ' | cut -d' ' -f2) RESUMEDEV=$( dialog --stdout --no-collapse --title "HIBERNATE RESUME DEVICE" --inputbox "\ When using suspend-to-disk feature (hibernate), your computer's RAM is copied \ to a swap device when it shuts down. The kernel will resume from that RAM \ image at boot. This means that the swap partition must not be smaller than \ the amount of RAM you have ($FREERAM MB). \n\ $SWPINFO \n\ Please specify a swap partition to be used for hibernation:" \ 0 0 "$RESUMEDEV") [ -z "$RESUMEDEV" ] && exit 1 fi if echo $EXTRA | grep -q WAIT ; then WAIT=$( dialog --stdout --title "WAIT FOR ROOT DEVICE" --inputbox "\ Some block devices are too slow to be detected properly at boot. USB storage \ devices and some disk arrays have this 'feature'. To make your machine \ boot properly, you can add some delay here, to wait until all your disks are \ probed and detected. The time is in seconds:" 0 0 "$WAIT") [ -z "$WAIT" ] && exit 1 fi IMGFILE=$( dialog --stdout --title "INITRD IMAGE NAME" --inputbox "\ Enter your initrd image filename." 0 0 "$IMGFILE" ) [ -z "$IMGFILE" ] && exit 1 else MLIST=$(add_rootfs_module) fi # Add any modules passed along on the commandline: if [ -n "$MKINIT_MODS" ]; then [ -n "$MLIST" ] && MLIST="$MLIST:$(echo $MKINIT_MODS | tr ' ' ':')" \ || MLIST="$(echo $MKINIT_MODS | tr ' ' ':')" fi # Constructing the mkinitrd command: MKINIT="mkinitrd -c -k $KVER -f $ROOTFS -r $ROOTDEV" # If we have a module list, add them: if ! [ -z "$MLIST" -o "$MLIST" = ":" ]; then MKINIT="$MKINIT -m $MLIST" fi # Deal with LUKS/LVM/RAID: if [ "$USING_LUKS" = "1" ]; then MKINIT="$MKINIT -C $REALDEV" fi if [ "$USING_LVM" = "1" ]; then MKINIT="$MKINIT -L" fi if [ "$USING_RAID" = "1" ]; then MKINIT="$MKINIT -R" fi if [ -n "$RESUMEDEV" ]; then # Add hibernation partition: MKINIT="$MKINIT -h $RESUMEDEV" fi if [ -n "$KEYMAP" -a "$KEYMAP" != "us" ]; then # Add non-us keyboard mapping: MKINIT="$MKINIT -l $KEYMAP" fi if [ $UDEV -eq 1 ]; then # Add UDEV support: MKINIT="$MKINIT -u" fi if [ -n "$WAIT" -a $WAIT -ne $WAIT_DEFAULT ]; then # Add non-default wait time: MKINIT="$MKINIT -w $WAIT" fi if ! echo "$MKINIT_PARAMS" | grep -q -- '-o ' ; then # Add default output filename: MKINIT="$MKINIT -o $IMGFILE" fi if [ -n "$MKINIT_PARAMS" ]; then # Add user-supplied additional parameters: MKINIT="$MKINIT $MKINIT_PARAMS" fi # Notify the user: if [ "$EMIT" = "all" ]; then cat <<-EOT # # $(basename $0) revision $REV # # This script will now make a recommendation about the command to use # in case you require an initrd image to boot a kernel that does not # have support for your storage or root filesystem built in # (such as the Slackware 'generic' kernels'). # A suitable 'mkinitrd' command will be: $MKINIT EOT elif [ "$EMIT" = "run" ]; then echo "$MKINIT" elif [ "$EMIT" = "conf" ]; then cat <<-EOT SOURCE_TREE="$SOURCE_TREE" CLEAR_TREE="$CLEAR_TREE" OUTPUT_IMAGE="$IMGFILE" KERNEL_VERSION="$KVER" KEYMAP="$KEYMAP" MODULE_LIST="$(echo $MLIST | cut -f2 -d\ )" LUKSDEV="$REALDEV" ROOTDEV="$ROOTDEV" ROOTFS="$ROOTFS" RESUMEDEV="$RESUMEDEV" RAID="$USING_RAID" LVM="$USING_LVM" UDEV="$UDEV" WAIT="$WAIT" EOT fi if [ -n "$KFILE" ]; then if [ "$EMIT" = "all" ]; then cat <<-EOT # An entry in 'etc/lilo.conf' for kernel '$KFILE' would look like this: EOT fi if [ "$EMIT" = "all" -o "$EMIT" = "lilo" ]; then # Compensate for the syntax used for the LUKS-on-LVM case: [ "$(basename $ROOTDEV)" = "$ROOTDEV" ] && BASE="/dev/mapper/" || BASE="" cat <<-EOT # Linux bootable partition config begins # initrd created with '$MKINIT' image = $KFILE initrd = $IMGFILE root = $BASE$ROOTDEV label = $KVER read-only # Linux bootable partition config ends EOT fi fi再起動
# reboot※ インストールメディアを取り出し忘れないこと。
参考文献:
https://linuxjm.osdn.jp/html/0MultiFileIdx/man8/reboot.8.html/ に容量を継ぎ足す場合
コマンド実行例:
# fdisk -l # pvcreate /dev/moomoo # lvs # vgextend SlackVG /dev/moomoo # lvextend -l +100%FREE SlackVG/root # resize2fs /dev/SlackVG/root # lvs※ 100%FREE って何だか体に良さそう。
※ /dev/moomoo SlackVG root はハードウェア構成や LVM の設定に応じて適宜読み替えてください。
※ ファイルシステムのオンラインリサイズについて、
・ext2/3/4 の場合はresize2fs。
・btrfs の場合はbtrfs filesystem resize。
・reiserfs の場合はresize_reiserfs。
・xfs の場合はxfs_growfs。
参考文献:
Man page of FDISK
https://linuxjm.osdn.jp/html/util-linux/man8/fdisk.8.htmlpvcreate(8) - Linux man page
https://linux.die.net/man/8/pvcreatelvs(8) - Linux man page
https://linux.die.net/man/8/lvsvgextend(8) - Linux man page
https://linux.die.net/man/8/vgextendlvextend(8) - Linux man page
https://linux.die.net/man/8/lvextendresize2fs(8) - Linux man page
https://linux.die.net/man/8/resize2fsbtrfs(8) - Linux man page
https://linux.die.net/man/8/btrfsMan page of RESIZE_REISERFS
https://linuxjm.osdn.jp/html/reiserfsprogs/man8/resize_reiserfs.8.htmlxfs_growfs(8) - Linux man page
https://linux.die.net/man/8/xfs_growfsLVM - ArchWiki
https://wiki.archlinux.jp/index.php/LVMPantora Networks » 3章 LVM操作 応用編
http://pantora.net/pages/linux/lvm/3/LVMで新たにディスクを追加して既存のLVを拡張する - Qiita
https://qiita.com/g_maeda/items/3602dc2f7af3f711f9c4LVM上のbtrfsのRAID1のサイズを拡張する - Qiita
https://qiita.com/takaki@github/items/5d96d80dc78b09ea600b備考
シャットダウン・リブート時の “lvm can't deactivate …” エラー
LVM に置いたルートでは毎回このエラーが出ますが、リードオンリーで再マウントした後の話なので最悪でもデータが飛ぶ恐れはないそうです。
# This never hurts again (especially since root-on-LVM always fails # to deactivate the / logical volume... but at least it was # remounted as read-only first) /bin/sync出典:
/etc/rc.d/rc.6 本体
/etc/rc.d/rc.6#! /bin/sh # # rc.6 This file is executed by init when it goes into runlevel # 0 (halt) or runlevel 6 (reboot). It kills all processes, # unmounts file systems and then either halts or reboots. # # Version: @(#)/etc/rc.d/rc.6 2.47 Sat Jan 13 13:37:26 PST 2001 # # Author: Miquel van Smoorenburg # Modified by: Patrick J. Volkerding # # Set the path. PATH=/sbin:/etc:/bin:/usr/bin # If there are SystemV init scripts for this runlevel, run them. if [ -x /etc/rc.d/rc.sysvinit ]; then . /etc/rc.d/rc.sysvinit fi # Set linefeed mode to avoid staircase effect. /bin/stty onlcr echo "Running shutdown script $0:" # Find out how we were called. case "$0" in *0) shutdown_command="halt" ;; *6) shutdown_command=reboot ;; *) echo "$0: call me as \"rc.0\" or \"rc.6\" please!" exit 1 ;; esac # Save the system time to the hardware clock using hwclock --systohc. # This will also create or update the timestamps in /etc/adjtime. if [ -x /sbin/hwclock ]; then # Check for a broken motherboard RTC clock (where ioports for rtc are # unknown) to prevent hwclock causing a hang: if ! grep -q " : rtc" /proc/ioports ; then CLOCK_OPT="--directisa" fi if [ /etc/adjtime -nt /etc/hardwareclock ]; then if grep -q "^LOCAL" /etc/adjtime ; then echo "Saving system time to the hardware clock (localtime)." else echo "Saving system time to the hardware clock (UTC)." fi /sbin/hwclock $CLOCK_OPT --systohc elif grep -q "^UTC" /etc/hardwareclock 2> /dev/null ; then echo "Saving system time to the hardware clock (UTC)." if [ ! -r /etc/adjtime ]; then echo "Creating system time correction file /etc/adjtime." fi /sbin/hwclock $CLOCK_OPT --utc --systohc else echo "Saving system time to the hardware clock (localtime)." if [ ! -r /etc/adjtime ]; then echo "Creating system time correction file /etc/adjtime." fi /sbin/hwclock $CLOCK_OPT --localtime --systohc fi fi # Run any local shutdown scripts: if [ -x /etc/rc.d/rc.local_shutdown ]; then /etc/rc.d/rc.local_shutdown stop fi # Stop the Apache web server: if [ -x /etc/rc.d/rc.httpd ]; then /etc/rc.d/rc.httpd stop fi # Stop the MySQL database: if [ -r /var/run/mysql/mysql.pid ]; then . /etc/rc.d/rc.mysqld stop fi # Stop the Samba server: if [ -x /etc/rc.d/rc.samba ]; then . /etc/rc.d/rc.samba stop fi # Shut down the NFS server: if [ -x /etc/rc.d/rc.nfsd ]; then /etc/rc.d/rc.nfsd stop fi # Shut down the SSH server: if [ -x /etc/rc.d/rc.sshd ]; then /etc/rc.d/rc.sshd stop fi # Shut down the SASL authentication daemon: if [ -x /etc/rc.d/rc.saslauthd ]; then /etc/rc.d/rc.saslauthd stop fi # Shut down OpenLDAP: if [ -x /etc/rc.d/rc.openldap ]; then /etc/rc.d/rc.openldap stop fi # Stop D-Bus: if [ -x /etc/rc.d/rc.messagebus ]; then sh /etc/rc.d/rc.messagebus stop fi # Kill any processes (typically gam) that would otherwise prevent # unmounting NFS volumes: unset FUSER_DELAY for dir in $(/bin/mount | grep 'type nfs ' | cut -d ' ' -f 3 ) ; do echo "Killing processes holding NFS mount $dir open..." # Background this to prevent fuser from also blocking shutdown: /usr/bin/fuser -k -m $dir & FUSER_DELAY=5 done # If fuser was run, let it have some delay: if [ ! -z "$FUSER_DELAY" ]; then sleep $FUSER_DELAY fi # Unmount any NFS, SMB, or CIFS filesystems: echo "Unmounting remote filesystems:" /bin/umount -v -a -l -f -r -t nfs,smbfs,cifs | tr -d ' ' | grep successfully | sed "s/:successfullyunmounted/ has been successfully unmounted./g" # Try to shut down pppd: PS="$(ps ax)" if echo "$PS" | /bin/grep -q -w pppd ; then if [ -x /usr/sbin/ppp-off ]; then /usr/sbin/ppp-off fi fi # Shut down YP services: if [ -x /etc/rc.d/rc.yp ]; then if grep -wq stop /etc/rc.d/rc.yp ; then /etc/rc.d/rc.yp stop fi fi # Bring down the networking system, but first make sure that this # isn't a diskless client with the / partition mounted via NFS: if ! /bin/mount | /bin/grep -q 'on / type nfs' ; then if [ -x /etc/rc.d/rc.inet1 ]; then . /etc/rc.d/rc.inet1 stop fi fi # In case dhcpcd might have been manually started on the command line, # look for the .pid file, and shut dhcpcd down if it's found: if /bin/ls /etc/dhcpc/*.pid 1> /dev/null 2> /dev/null ; then /sbin/dhcpcd -k 1> /dev/null 2> /dev/null # A little time for /etc/resolv.conf and/or other files to # restore themselves. sleep 2 fi # Shut down PCMCIA devices: if [ -x /etc/rc.d/rc.pcmcia ]; then . /etc/rc.d/rc.pcmcia stop # The cards might need a little extra time here to deactivate: /bin/sleep 5 fi # Turn off process accounting: if [ -x /sbin/accton -a -r /var/log/pacct ]; then /sbin/accton off fi # Terminate acpid before syslog: if [ -x /etc/rc.d/rc.acpid -a -r /var/run/acpid.pid ]; then # quit . /etc/rc.d/rc.acpid stop fi # Stop udev: if [ -x /etc/rc.d/rc.udev ]; then sh /etc/rc.d/rc.udev force-stop fi # Kill all remaining processes. OMITPIDS="$(for p in $(pgrep mdmon); do echo -o $p; done)" # Don't kill mdmon if [ ! "$1" = "fast" ]; then echo "Sending all processes the SIGTERM signal." /sbin/killall5 -15 $OMITPIDS /bin/sleep 5 echo "Sending all processes the SIGKILL signal." /sbin/killall5 -9 $OMITPIDS fi # Try to turn off quota. if /bin/grep -q quota /etc/fstab ; then if [ -x /sbin/quotaoff ]; then echo "Turning off filesystem quotas." /sbin/quotaoff -a fi fi # Carry a random seed between reboots. echo "Saving random seed from /dev/urandom in /etc/random-seed." # Use the pool size from /proc, or 4096 bits: if [ -r /proc/sys/kernel/random/poolsize ]; then /bin/dd if=/dev/urandom of=/etc/random-seed count=1 bs=$(expr $(cat /proc/sys/kernel/random/poolsize) / 8) 2> /dev/null else /bin/dd if=/dev/urandom of=/etc/random-seed count=1 bs=512 2> /dev/null fi /bin/chmod 600 /etc/random-seed # Before unmounting file systems write a reboot or halt record to wtmp. $shutdown_command -w # Turn off swap: echo "Turning off swap." /sbin/swapoff -a /bin/sync # Stop cgmanager and cgproxy: if [ -x /etc/rc.d/rc.cgmanager ]; then sh /etc/rc.d/rc.cgmanager stop fi echo "Unmounting local file systems:" /bin/umount -v -a -t no,proc,sysfs | tr -d ' ' | grep successfully | sed "s/:successfullyunmounted/ has been successfully unmounted./g" 2> /dev/null echo "Remounting root filesystem read-only:" /bin/mount -v -n -o remount,ro / # This never hurts: /bin/sync # Close any volumes opened by cryptsetup: if [ -f /etc/crypttab -a -x /sbin/cryptsetup ]; then cat /etc/crypttab | grep -v "^#" | grep -v "^$" | while read line; do # NOTE: we only support LUKS formatted volumes (except for swap)! LUKS=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f1 -d' ') DEV=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f2 -d' ') OPTS=$(echo $line | tr '\t' ' ' | tr -s ' ' | cut -f4 -d' ') if /sbin/cryptsetup isLuks $DEV 2>/dev/null ; then echo "Locking LUKS crypt volume '${LUKS}':" /sbin/cryptsetup luksClose ${LUKS} elif echo $OPTS | grep -wq swap ; then # If any of the volumes was used as encrypted swap, # then run mkswap on the underlying device - # in case other Linux installations on this computer should use it: echo "Erasing encrypted swap '${LUKS}' and restoring normal swap on ${DEV}:" /sbin/cryptsetup remove ${LUKS} mkswap $DEV fi done fi # Deactivate LVM volume groups: if [ -r /etc/lvmtab -o -d /etc/lvm/backup ]; then echo "Deactivating LVM volume groups:" /sbin/vgchange -an --ignorelockingfailure fi # This never hurts again (especially since root-on-LVM always fails # to deactivate the / logical volume... but at least it was # remounted as read-only first) /bin/sync # sleep 3 fixes problems with some hard drives that don't # otherwise finish syncing before reboot or poweroff /bin/sleep 3 # This is to ensure all processes have completed on SMP machines: wait if [ -x /sbin/genpowerd ]; then # See if this is a powerfail situation: if /bin/egrep -q "FAIL|SCRAM" /etc/upsstatus 2> /dev/null ; then # Signal UPS to shut off the inverter: /sbin/genpowerd -k if [ ! $? = 0 ]; then echo echo "There was an error signaling the UPS." echo "Perhaps you need to edit /etc/genpowerd.conf to configure" echo "the serial line and UPS type." # Wasting 15 seconds of precious power: /bin/sleep 15 fi fi fi # Now halt (poweroff with APM or ACPI enabled kernels) or reboot. if [ "$shutdown_command" = "reboot" ]; then echo "Rebooting." /sbin/reboot else /sbin/poweroff fiELILO におけるハイバネート機能(SWSUSP)の有効化、任意のカーネルパラメータの適用
/usr/sbin/eliloconfig を編集することで swsusp に対応させることが出来る他、起動時にお好みのカーネルパラメータを渡すことが可能です。
該当個所を、例えば以下のように編集します。
/usr/sbin/eliloconfigcat << EOF >> $T_PX/boot/efi/EFI/Slackware/elilo.conf read-only append="root=$ROOT_DEVICE vga=normal ro" EOF/usr/local/sbin/eliloconfig-modifiedcat << EOF >> $T_PX/boot/efi/EFI/Slackware/elilo.conf read-only append="root=$ROOT_DEVICE resume=/dev/moo2 vga=normal ro" EOFresume=/dev/moo2 はインストールした Slackware で使用している swap 領域を指定。
直接編集せず、/usr/local/sbin/eliloconfig-modified 等の名前でコピーを作成してそちらを編集すると安全かも。
※
swap 領域が LVM の中にある場合initramfsを使い、かつ swsusp を行う場合はmkinitrdに-h /dev/moo等を渡してやる必要があるようですのが無難です。2 3
参考文献:
howtos:slackware_admin:hibernation - SlackDocs
https://docs.slackware.com/howtos:slackware_admin:hibernationUsing swap files with software suspend (swsusp)
https://www.kernel.org/doc/Documentation/power/swsusp-and-swap-files.txtkernel.org の Documentation/admin-guide/kernel-parameters.txt
https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txtMan page of BOOTPARAM
https://linuxjm.osdn.jp/html/LDP_man-pages/man7/bootparam.7.htmlinitramfs と swsusp と LVM についての掘り下げ
/boot/initrd.gz 内の init スクリプト
init#!/bin/ash # # /init: init script to load kernel modules from an initramfs # This requires that your kernel supports initramfs!!! # # Copyright 2004 Slackware Linux, Inc., Concord, CA, USA # Copyright 2007, 2008, 2009, 2010, 2012 Patrick J. Volkerding, Sebeka, MN, USA # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 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. # ################################################################################## # With a generic kernel, you need to load the modules needed to mount the # root partition. This might mean a SCSI, RAID, or other drive controller # module, as well as the module to support the root filesystem. Once the # root partition is mounted all the other modules will be available so you # don't need to load them here. # # Config files used by this script: # # /rootdev Contains the name of the root device, such as: /dev/hda1 # # /rootfs Contains the root filesystem type, such as: xfs # # /initrd-name Contains the name of the initrd file. # # /resumedev Contains the name of the device to resume from hibernation. # # /luksdev Contains colon separated list of luks encrypted devices to # be unlocked. # # /lukstrim Contains colon separated list of luks encrypted devices to # pass '--allow-discards' when unlocking # # /lukskey Contains the path to a LUKS key-file for automatic unlock # Format: LABEL=<partition_label>:/path/to/file # UUID=<partition_uuid>:/path/to/file # # /wait-for-root Contains a number - the init script will wait this amount # of seconds before creating device nodes. # # /keymap Contains the name for a custom keyboard map # # Optional: # # /load_kernel_modules # A script that uses modprobe to load the desired modules. # # There's an example in here. To actually use it, you'll # need to make it executable: # # chmod 755 load_kernel_modules ################################################################################## # Changelog # 10-Dec-2012 mozes # * Added support for the official Kernel parameters to select root filesystem # type ('rootfstype') and pause before attempting to mount the root filesystem # ('rootdelay'). The original parameters may continue to be used. ################################################################################## INITRD=$(cat /initrd-name) ROOTDEV=$(cat /rootdev) ROOTFS=$(cat /rootfs) LUKSDEV=$(cat /luksdev) LUKSTRIM=$(cat /lukstrim 2>/dev/null) LUKSKEY=$(cat /lukskey) RESUMEDEV=$(cat /resumedev) WAIT=$(cat /wait-for-root) KEYMAP=$(cat /keymap) INIT=/sbin/init PATH="/sbin:/bin:/usr/sbin:/usr/bin" # Mount /proc and /sys: mount -n proc /proc -t proc mount -n sysfs /sys -t sysfs mount -n tmpfs /run -t tmpfs -o mode=0755,size=32M,nodev,nosuid,noexec if grep devtmpfs /proc/filesystems 1>/dev/null 2>/dev/null ; then DEVTMPFS=1 mount -n devtmpfs /dev -t devtmpfs -o size=8M fi # Parse command line for ARG in $(cat /proc/cmdline); do case $ARG in 0|1|2|3|4|5|6|S|s|single) RUNLEVEL=$ARG ;; init=*) INIT=$(echo $ARG | cut -f2 -d=) ;; luksdev=/dev/*) LUKSDEV=$(echo $ARG | cut -f2 -d=) ;; lukskey=*) LUKSKEY=$(echo $ARG | cut -f2- -d=) ;; rescue) RESCUE=1 ;; resume=*) RESUMEDEV=$(echo $ARG | cut -f2- -d=) ;; root=/dev/*) ROOTDEV=$(echo $ARG | cut -f2 -d=) ;; root=LABEL=*) ROOTDEV=$(echo $ARG | cut -f2- -d=) ;; root=UUID=*) ROOTDEV=$(echo $ARG | cut -f2- -d=) ;; rootfs=*|rootfstype=*) ROOTFS=$(echo $ARG | cut -f2 -d=) ;; waitforroot=*|rootdelay=*) WAIT=$(echo $ARG | cut -f2 -d=) ;; esac done # If udevd is available, use it to generate block devices # else use mdev to read sysfs and generate the needed devices if [ -x /sbin/udevd -a -x /sbin/udevadm ]; then /sbin/udevd --daemon --resolve-names=never /sbin/udevadm trigger --subsystem-match=block --action=add /sbin/udevadm settle --timeout=10 else [ "$DEVTMPFS" != "1" ] && mdev -s fi # Load kernel modules (ideally this was already done by udev): if [ ! -d /lib/modules/$(uname -r) ]; then echo "No kernel modules found for Linux $(uname -r)." elif [ -x ./load_kernel_modules ]; then # use load_kernel_modules script: echo "${INITRD}: Loading kernel modules from initrd image:" . ./load_kernel_modules else # load modules (if any) in order: if ls /lib/modules/$(uname -r)/*.*o 1> /dev/null 2> /dev/null ; then echo "${INITRD}: Loading kernel modules from initrd image:" for module in /lib/modules/$(uname -r)/*.*o ; do /sbin/modprobe $module done unset module fi fi # Sometimes the devices need extra time to be available. # A root filesystem on USB is a good example of that. sleep $WAIT # Load a custom keyboard mapping: if [ -n "$KEYMAP" ]; then echo "${INITRD}: Loading '$KEYMAP' keyboard mapping:" tar xzOf /etc/keymaps.tar.gz ${KEYMAP}.bmap | loadkmap fi if [ "$RESCUE" = "" ]; then # Initialize RAID: if [ -x /sbin/mdadm ]; then # If /etc/mdadm.conf is present, udev should DTRT on its own; # If not, we'll make one and go from there: if [ ! -r /etc/mdadm.conf ]; then /sbin/mdadm -E -s >/etc/mdadm.conf /sbin/mdadm -S -s /sbin/mdadm -A -s # This seems to make the kernel see partitions more reliably: fdisk -l /dev/md* 1> /dev/null 2> /dev/null fi fi # Unlock any encrypted partitions necessary to access the # root filesystem, such as encrypted LVM Physical volumes, disk # partitions or mdadm arrays. # Unavailable devices such as LVM Logical Volumes will need to be # deferred until they become available after the vgscan. if [ -x /sbin/cryptsetup ]; then # Determine if we have to use a LUKS keyfile: if [ ! -z "$LUKSKEY" ]; then mkdir /mountkey KEYPART=$(echo $LUKSKEY |cut -f1 -d:) KEYNAME=$(echo $KEYPART |cut -f2 -d=) LUKSPATH="/mountkey$(echo $LUKSKEY |cut -f2 -d:)" # Catch possible mount failure: if blkid |grep "TYPE=\"vfat\"" |grep $KEYNAME 1>/dev/null 2>&1 ; then MOUNTOPTS="-t vfat -o shortname=mixed" else MOUNTOPTS="-t auto" fi mount $MOUNTOPTS $(findfs $KEYPART) /mountkey 2>/dev/null # Check if we can actually use this file: if [ ! -f $LUKSPATH ]; then LUKSKEY="" else echo ">>> Using LUKS key file: '$LUKSKEY'" LUKSKEY="-d $LUKSPATH" fi fi LUKSLIST_DEFERRED="" LUKSLIST=$(echo $LUKSDEV | tr -s ':' ' ') for LUKSDEV in $LUKSLIST ; do if /sbin/cryptsetup isLuks ${LUKSDEV} 1>/dev/null 2>/dev/null ; then if echo $ROOTDEV | grep -q "LABEL=" || echo $ROOTDEV | grep -q "UUID=" ; then CRYPTDEV="luks$(basename $LUKSDEV)" elif [ "x$ROOTDEV" = "x$(basename $ROOTDEV)" ]; then CRYPTDEV="$ROOTDEV" else CRYPTDEV="luks$(basename $LUKSDEV)" fi if echo $LUKSTRIM | grep -wq $LUKSDEV 2>/dev/null ; then LUKSOPTS="--allow-discards" else LUKSOPTS="" fi if [ -z "${LUKSOPTS}" ]; then echo "Unlocking LUKS encrypted device '${LUKSDEV}' as luks mapped device '$CRYPTDEV':" else echo "Unlocking LUKS encrypted device '${LUKSDEV}' as luks mapped device '$CRYPTDEV' with '$LUKSOPTS':" fi /sbin/cryptsetup ${LUKSOPTS} ${LUKSKEY} luksOpen ${LUKSDEV} ${CRYPTDEV} </dev/tty0 >/dev/tty0 2>&1 if [ "$ROOTDEV" = "$LUKSDEV" -o "$ROOTDEV" = "$CRYPTDEV" ] ; then ROOTDEV="/dev/mapper/$CRYPTDEV" fi else LUKSLIST_DEFERRED="${LUKSLIST_DEFERRED} ${LUKSDEV}" fi done fi # Initialize LVM: if [ -x /sbin/vgchange ]; then mkdir -p /var/lock/lvm # this avoids useless warnings /sbin/vgchange -ay --ignorelockingfailure 2>/dev/null /sbin/udevadm settle --timeout=10 fi # Unlock any LUKS encrypted devices that were deferred above but have now # become available due to the vgscan (i.e. filesystems on LVM Logical Volumes) if [ -x /sbin/cryptsetup -a -n "${LUKSLIST_DEFERRED}" ]; then for LUKSDEV in ${LUKSLIST_DEFERRED} ; do if /sbin/cryptsetup isLuks ${LUKSDEV} 1>/dev/null 2>/dev/null ; then if echo $ROOTDEV | grep -q "LABEL=" || echo $ROOTDEV | grep -q "UUID=" ; then CRYPTDEV="luks$(basename $LUKSDEV)" elif [ "x$ROOTDEV" = "x$(basename $ROOTDEV)" ]; then CRYPTDEV="$ROOTDEV" else CRYPTDEV="luks$(basename $LUKSDEV)" fi echo "Unlocking LUKS encrypted device '${LUKSDEV}' as luks mapped device '$CRYPTDEV':" /sbin/cryptsetup ${LUKSKEY} luksOpen ${LUKSDEV} ${CRYPTDEV} </dev/tty0 >/dev/tty0 2>&1 if [ "$ROOTDEV" = "$LUKSDEV" -o "$ROOTDEV" = "$CRYPTDEV" ] ; then ROOTDEV="/dev/mapper/$CRYPTDEV" fi else echo "LUKS device '${LUKSDEV}' unavailable for unlocking!" fi done /sbin/udevadm settle --timeout=10 fi # Scan for btrfs multi-device filesystems: if [ -x /sbin/btrfs ]; then /sbin/btrfs device scan fi # Find root device if a label or UUID was given: if echo $ROOTDEV | grep -q "LABEL=" || \ echo $ROOTDEV | grep -q "UUID=" ; then ROOTDEV=$(findfs $ROOTDEV) fi # Clean up after LUKS unlock using a keyfile: if grep -q mountkey /proc/mounts 2>/dev/null ; then umount -l /mountkey rmdir /mountkey 2>/dev/null fi # Resume state from swap if [ "$RESUMEDEV" != "" ]; then # Find resume device if a label or UUID was given: if echo $RESUMEDEV | grep -q "LABEL=" || \ echo $RESUMEDEV | grep -q "UUID=" ; then RESUMEDEV=$(findfs $RESUMEDEV) elif ls -l $RESUMEDEV | grep -q "^l" ; then RESUMEDEV=$(readlink -f $RESUMEDEV) fi echo "Trying to resume from $RESUMEDEV" RESMAJMIN=$(ls -l $RESUMEDEV | tr , : | awk '{ print $5$6 }') echo $RESMAJMIN > /sys/power/resume fi # Switch to real root partition: /sbin/udevadm settle --timeout=10 echo 0x0100 > /proc/sys/kernel/real-root-dev mount -o ro -t $ROOTFS $ROOTDEV /mnt if [ ! -r /mnt/sbin/init ]; then echo "ERROR: No /sbin/init found on rootdev (or not mounted). Trouble ahead." echo " You can try to fix it. Type 'exit' when things are done." echo /bin/sh fi else echo echo "RESCUE mode" echo echo " You can try to fix or rescue your system now. If you want" echo " to boot into your fixed system, mount your root filesystem" echo " read-only under /mnt:" echo echo " # mount -o ro -t filesystem root_device /mnt" echo echo " Type 'exit' when things are done." echo /bin/sh fi # Need to make sure OPTIONS+="db_persist" exists for all dm devices # That should be handled in /sbin/mkinitrd now /sbin/udevadm info --cleanup-db /sbin/udevadm control --exit unset ERR mount -o move /proc /mnt/proc mount -o move /sys /mnt/sys mount -o move /run /mnt/run [ "$DEVTMPFS" = "1" ] && mount -o move /dev /mnt/dev echo "${INITRD}: exiting" exec switch_root /mnt $INIT $RUNLEVEL考察:
LVM に "/" をいれた場合、ramdisk(initrd.gz)無しだと "/" をマウント出来ずカーネルパニックに。ramdisk を生成させると上記で引用した init スクリプトが LVM や LUKS 及び RAID を上手く扱ってくれる。また、Slackware の mkinitrd に -h オプションで swap デバイスのパス渡すと initrd.gz 内の resumedev 内に swsusp 対象デバイスのパスが書き込まれる。
ramdisk の init は最後に "/" をリードオンリーでマウントし、"/" 内部の sbin/init を呼び出すが、mkinitrd に -h オプションを渡しておくことで、ramdisk の段階でレジュームしてくれる。
結論:
Slackware でブート時に ramdisk(initrd.gz)を使う場合は -h オプションでサスペンド/ レジュームのための swap 領域を指定しておくと、実ドライブ側の init に移ってからレジュームプロセスを始めるより早い段階でレジューム出来、時間短縮になると予想する。また、レジュームが実ドライブマウント前に行われるので問題も生じにくいと思われる。懸念:
EFI システムパーティション上の initrd.gz を第三者に改竄されるとヤバい(ESP がいじれる段階まで侵入されている時点で既にアウトではあるけれども)。
参考文献:
howtos:slackware_admin:hibernation - SlackDocs
https://docs.slackware.com/howtos:slackware_admin:hibernation18:initrdファイルの作成 | 日経 xTECH(クロステック)
https://tech.nikkeibp.co.jp/it/article/COLUMN/20061025/251702/Linux 初期 RAM ディスク (initrd) の概要
https://www.ibm.com/developerworks/jp/linux/library/l-initrd/index.html編集後記:
主要な設定・管理ツールがすべてシェルスクリプト4というのは見通しが良いし、改造するにも楽しいので助かります。怪しげなツールを自作する際の教材としても Good!
何だこのエラー?と思ってスクリプトを開くとコメント行で解説がついているのはとても助かりました。
Slackware、使って楽しいディストリです。
なんとなくドライブの潜在能力がもったいない気がするので。 ↩
https://docs.slackware.com/howtos:slackware_admin:hibernation ↩
例えば pkgtool 関係は軒並みシェルスクリプト(+ dialog コマンド)。 ↩
- 投稿日:2019-07-09T10:39:28+09:00
xfc4-terminalでアンダーバーが表示されない時の対応方法
- 環境
- CentOS Linux release 7.6.1810 (Core)
- xfc4-terminal 0.8.7.4
デフォルトのフォントで半角アンダーバー(_)が表示されなかった・・・。
- xfc4-terminalを起動する
- [Edit] > [Preferences...] > [Appearance]タブ
- 「[Use System font]にチェックを入れる」 or 「アンダーバーが表示されるフォントを選択する」




