dracut-functions: added functions: mksubdirs, inst_decompress, inst_opt_decompress and print_vars dracut.conf.d: added configuration files for Gentoo and RedHat/Fedora --- dracut-functions | 63 ++++++++++ dracut.conf.d/gentoo-openrc.conf.example | 10 ++ dracut.conf.d/gentoo.conf.example | 10 ++ dracut.conf.d/redhat.conf.example | 10 ++ modules.d/10i18n/10-console.rules | 2 + modules.d/10i18n/check | 7 + modules.d/10i18n/console_init | 107 ++++++++++++++++ modules.d/10i18n/install | 195 ++++++++++++++++++++++++++++++ modules.d/10i18n/parse-i18n.sh | 24 ++++ modules.d/10redhat-i18n/10-console.rules | 2 + 10 files changed, 430 insertions(+), 0 deletions(-) create mode 100644 dracut.conf.d/gentoo-openrc.conf.example create mode 100644 dracut.conf.d/gentoo.conf.example create mode 100644 dracut.conf.d/redhat.conf.example create mode 100644 modules.d/10i18n/10-console.rules create mode 100755 modules.d/10i18n/check create mode 100755 modules.d/10i18n/console_init create mode 100755 modules.d/10i18n/install create mode 100755 modules.d/10i18n/parse-i18n.sh create mode 100644 modules.d/10redhat-i18n/10-console.rules diff --git a/dracut-functions b/dracut-functions index 2cd573a..4212c5f 100755 --- a/dracut-functions +++ b/dracut-functions @@ -24,6 +24,10 @@ IF_dynamic="" # Generic substring function. If $2 is in $1, return 0. strstr() { [[ $1 =~ $2 ]]; } +# Create all subdirectories for given path without creating the last element. +# $1 = path +mksubdirs() { mkdir -p ${1%/*}; } + # Version comparision function. Assumes Linux style version scheme. # $1 = version a # $2 = comparision op (gt, ge, eq, le, lt, ne) @@ -77,6 +81,18 @@ derror() { [[ -w $dracutlogfile ]] && echo "E: $@" >>"$dracutlogfile" } +# Function prints global variables in format name=value line by line. +# $@ = list of global variables' name +print_vars() { + local var value + + for var in $@ + do + value=$(eval echo \$$var) + [[ ${value} ]] && echo "${var}=\"${value}\"" + done +} + get_fs_env() { eval $(udevadm info --query=env --name=$1|egrep 'ID_FS_(TYPE|UUID)=') [[ $ID_FS_TYPE ]] && return @@ -381,6 +397,53 @@ dracut_install() { done } +# install function decompressing the target and handling symlinks +# $@ = list of compressed (gz or bz2) files or symlinks pointing to such files +# +# Function install targets in the same paths inside overlay but decompressed +# and without extensions (.gz, .bz2). +inst_decompress() { + local src dst realsrc realdst cmd + + for src in $@ + do + case ${src} in + *.gi) cmd='gzip rd' ;; + *.bz2) cmd='bzip2 -d' ;; + *) return 1 ;; + esac + + if [[ -L ${src} ]] + then + realsrc="$(readlink -f ${src})" # symlink target with extension + dst="${src%.*}" # symlink without extension + realdst="${realsrc%.*}" # symlink target without extension + mksubdirs "${initdir}/${src}" + # Create symlink without extension to target without extension. + ln -s "${realdst}" "${initdir}/${dst}" + fi + + # If the source is symlink we operate on its target. + [[ ${realsrc} ]] && src=${realsrc} + inst ${src} + # Decompress with chosen tool. We assume that tool changes name e.g. + # from 'name.gz' to 'name'. + ${cmd} "${initdir}${src}" + done +} + +# It's similar to above, but if file is not compressed, performs standard +# install. +# $@ = list of files +inst_opt_decompress() { + local src + + for src in $@ + do + inst_decompress "${src}" || inst "${src}" + done +} + check_module_deps() { local moddir dep ret # if we are already set to be loaded, we do not have to be checked again. diff --git a/dracut.conf.d/gentoo-openrc.conf.example b/dracut.conf.d/gentoo-openrc.conf.example new file mode 100644 index 0000000..cd5da46 --- /dev/null +++ b/dracut.conf.d/gentoo-openrc.conf.example @@ -0,0 +1,10 @@ +# /etc/dracut.conf.d/gentoo-openrc.conf +# Dracut config file customized for Gentoo Base System release 2 + +# +# Modules +# + +# i18n +keyboard_vars="/etc/conf.d/keymaps:keymap-KEYMAP,extended_keymaps-EXT_KEYMAPS" +i18n_vars="/etc/conf.d/consolefont:consolefont-SYSFONT,consoletranslation-CONTRANS /etc/rc.conf:unicode-UNICODE" diff --git a/dracut.conf.d/gentoo.conf.example b/dracut.conf.d/gentoo.conf.example new file mode 100644 index 0000000..43e66e8 --- /dev/null +++ b/dracut.conf.d/gentoo.conf.example @@ -0,0 +1,10 @@ +# /etc/dracut.conf.d/gentoo.conf +# Dracut config file customized for Gentoo Base System release 1 + +# +# Modules +# + +# i18n +keyboard_vars="/etc/conf.d/keymaps:KEYMAP,EXTENDED_KEYMAPS-EXT_KEYMAPS" +i18n_vars="/etc/conf.d/consolefont:CONSOLEFONT-SYSFONT,CONSOLETRANSLATION-CONTRANS /etc/rc.conf:UNICODE" diff --git a/dracut.conf.d/redhat.conf.example b/dracut.conf.d/redhat.conf.example new file mode 100644 index 0000000..ae8f6e7 --- /dev/null +++ b/dracut.conf.d/redhat.conf.example @@ -0,0 +1,10 @@ +# /etc/dracut.conf.d/redhat.conf +# Dracut config file customized for RedHat/Fedora. + +# +# Modules +# + +# i18n +keyboard_vars="/etc/sysconfig/keyboard:KEYTABLE-KEYMAP" +i18n_vars="/etc/sysconfig/i18n:SYSFONT,SYSFONTACM-CONTRANS,UNIMAP" diff --git a/modules.d/10i18n/10-console.rules b/modules.d/10i18n/10-console.rules new file mode 100644 index 0000000..c234c8a --- /dev/null +++ b/modules.d/10i18n/10-console.rules @@ -0,0 +1,2 @@ +# Console initialization - keyboard, font, etc. +KERNEL=="tty0", RUN+="/lib/udev/console_init %k" diff --git a/modules.d/10i18n/check b/modules.d/10i18n/check new file mode 100755 index 0000000..ec85ce9 --- /dev/null +++ b/modules.d/10i18n/check @@ -0,0 +1,7 @@ +#!/bin/bash + +# TODO: We should check if ${keyboard_vars} && ${i18n_vars} are set for +# hostonly setup. +[[ $1 = -h ]] && exit 0 + +exit 255 diff --git a/modules.d/10i18n/console_init b/modules.d/10i18n/console_init new file mode 100755 index 0000000..9a8d621 --- /dev/null +++ b/modules.d/10i18n/console_init @@ -0,0 +1,107 @@ +#!/bin/sh + +. /etc/sysconfig/i18n +. /etc/sysconfig/keyboard + +DEFAULT_SYSFONT=LatArCyrHeb-16 +DEFAULT_KEYMAP=/etc/sysconfig/console/default.kmap + + +print_vars() { + local var value + + for var in $@ + do + value=$(eval echo \$$var) + [ -n "${value}" ] && echo "${var}=\"${value}\"" + done +} + +run_debug() { + echo -n $@ + echo -n ' ' + if $@; then + echo 'OK' + else + echo 'Failed!' + fi +} + +set_keyboard() { + local param + + [ "${UNICODE}" = 1 ] && param=-u || param=-a + kbd_mode ${param} +} + +set_terminal() { + local dev=$1 + + if [ "${UNICODE}" = 1 ]; then + printf '\033%%G' >&7 + stty -F ${dev} iutf8 + else + printf '\033%%@' >&7 + fi +} + +set_keymap() { + local utf_switch + + if [ -z "${KEYMAP}" ]; then + [ -f "${DEFAULT_KEYMAP}" ] && KEYMAP=${DEFAULT_KEYMAP} + fi + + [ -n "${KEYMAP}" ] || return 1 + + [ "${UNICODE}" = 1 ] && utf_switch=-u + + loadkeys ${utf_switch} ${KEYMAP}.map +} + +set_font() { + local dev=$1; local trans=''; local uni='' + + [ -z "${SYSFONT}" ] && SYSFONT=${DEFAULT_SYSFONT} + [ -n "${CONTRANS}" ] && trans="-m ${CONTRANS}" + [ -n "${UNIMAP}" ] && uni="-u ${UNIMAP}" + + setfont ${SYSFONT} -C ${dev} ${trans} ${uni} +} + +dev_close() { + exec 6>&- + exec 7>&- +} + +dev_open() { + local dev=$1 + + exec 6<${dev} && \ + exec 7>>${dev} +} + + +dev=/dev/${1#/dev/} + +[ -c "${dev}" ] || { + echo "Usage: $0 device" >&2 + exit 1 +} + +dev_open ${dev} + +for fd in 6 7; do + if ! [ -t ${fd} ]; then + echo "ERROR: File descriptor not opened: ${fd}" >&2 + dev_close + exit 1 + fi +done + +set_keyboard +set_terminal ${dev} +set_font ${dev} +set_keymap + +dev_close diff --git a/modules.d/10i18n/install b/modules.d/10i18n/install new file mode 100755 index 0000000..a335260 --- /dev/null +++ b/modules.d/10i18n/install @@ -0,0 +1,195 @@ +#!/bin/bash + +KBDSUBDIRS=consolefonts,consoletrans,keymaps,unimaps +DEFAULT_SYSFONT=LatArCyrHeb-16 +I18N_CONF="${initdir}/etc/sysconfig/i18n" +KEYBOARD_CONF="${initdir}/etc/sysconfig/keyboard" + + +# This is from 10redhat-i18n. +findkeymap () { + local MAP=$1 + [[ ! -f $MAP ]] && \ + MAP=$(find ${kbddir}/keymaps -type f -name $MAP -o -name $MAP.\* | head -n1) + [[ " $KEYMAPS " = *" $MAP "* ]] && return + KEYMAPS="$KEYMAPS $MAP" + case $MAP in + *.gz) cmd=zgrep;; + *.bz2) cmd=bzgrep;; + *) cmd=grep ;; + esac + + for INCL in $($cmd "^include " $MAP | cut -d' ' -f2 | tr -d '"'); do + for FN in $(find ${kbddir}/keymaps -type f -name $INCL\*); do + findkeymap $FN + done + done +} + +# Function gathers variables from distributed files among the tree, maps to +# specified names and prints the result in format "new-name=value". +# +# $@ = list in format specified below (BNF notation) +# +# <list> ::= <element> | <element> " " <list> +# <element> ::= <conf-file-name> ":" <map-list> +# <map-list> ::= <mapping> | <mapping> "," <map-list> +# <mapping> ::= <src-var> "-" <dst-var> | <src-var> +# +# We assume no whitespace are allowed between symbols. +# <conf-file-name> is a file holding <src-var> in your system. +# <src-var> is a variable holding value of meaning the same as <dst-var>. +# <dst-var> is a variable which will be set up inside initramfs. +# If <dst-var> has the same name as <src-var> we can omit <dst-var>. +# +# Example: +# /etc/conf.d/keymaps:KEYMAP,extended_keymaps-EXT_KEYMAPS +# <list> = /etc/conf.d/keymaps:KEYMAP,extended_keymaps-EXT_KEYMAPS +# <element> = /etc/conf.d/keymaps:KEYMAP,extended_keymaps-EXT_KEYMAPS +# <conf-file-name> = /etc/conf.d/keymaps +# <map-list> = KEYMAP,extended_keymaps-EXT_KEYMAPS +# <mapping> = KEYMAP +# <src-var> = KEYMAP +# <mapping> = extended_keymaps-EXT_KEYMAPS +# <src-var> = extended_keymaps +# <dst-var> = EXT_KEYMAPS +gather_vars() { + local item map value + + for item in $@ + do + item=(${item/:/ }) + for map in ${item[1]/,/ } + do + map=(${map/-/ }) + value=$(grep "^${map[0]}=" "${item[0]}") + value=${value#*=} + echo "${map[1]:-${map[0]}}=${value}" + done + done +} + +install_base() { + dracut_install setfont loadkeys kbd_mode stty + inst ${moddir}/console_init /lib/udev/console_init + inst_rules ${moddir}/10-console.rules + inst_hook cmdline 20 "${moddir}/parse-i18n.sh" +} + +install_all_kbd() { + local rel f + + for f in $(eval find ${kbddir}/{${KBDSUBDIRS}} -type f -print) + do + inst $f + done + + # remove unnecessary files + rm -f "${initdir}${kbddir}/consoletrans/utflist" + find "${initdir}${kbddir}/" -name README\* -delete + + dracut_install gzip bzip2 +} + +install_local_keyboard() { + local map + + eval $(gather_vars ${keyboard_vars}) + + # Gentoo user may have KEYMAP set to something like "-u pl2", + KEYMAP=${KEYMAP#-* } + EXT_KEYMAPS=${EXT_KEYMAPS:-backspace} + # I'm not sure of the purpose of UNIKEYMAP and GRP_TOGGLE. They were in + # original redhat-i18n module. Anyway it won't hurt. + EXT_KEYMAPS+=\ ${UNIKEYMAP}\ ${GRP_TOGGLE} + + [[ ${KEYMAP} ]] || derror 'No KEYMAP.' || return 1 + findkeymap ${KEYMAP} + + for map in ${EXT_KEYMAPS} + do + dinfo "Adding extra map: ${map}" + findkeymap ${map} + done + + inst_opt_decompress ${KEYMAPS} + + mksubdirs ${KEYBOARD_CONF} + print_vars KEYMAP EXT_KEYMAPS >> ${KEYBOARD_CONF} +} + +install_local_i18n() { + eval $(gather_vars ${i18n_vars}) + + [[ ${SYSFONT} ]] || SYSFONT=${DEFAULT_SYSFONT} + SYSFONT=${SYSFONT%.psf*} + inst ${kbddir}/consolefonts/${SYSFONT}.* + + if [[ ${CONTRANS} ]] + then + CONTRANS=${CONTRANS%.trans} + inst ${kbddir}/consoletrans/${CONTRANS}.trans + fi + + if [[ ${UNIMAP} ]] + then + UNIMAP=${UNIMAP%.uni} + inst ${kbddir}/unimaps/${UNIMAP}.uni + fi + + if [[ ${UNICODE} ]] + then + if [[ ${UNICODE^^} = YES || ${UNICODE} = 1 ]] + then + UNICODE=1 + elif [[ ${UNICODE^^} = NO || ${UNICODE} = 0 ]] + then + UNICODE=0 + else + UNICODE='' + fi + fi + if [[ ! ${UNICODE} && ${LANG^^} =~ .*\.UTF-?8 ]] + then + UNICODE=1 + fi + + mksubdirs ${I18N_CONF} + print_vars LC_ALL LANG UNICODE SYSFONT CONTRANS UNIMAP >> ${I18N_CONF} +} + +checks() { + for kbddir in ${kbddir} /usr/lib/kbd /lib/kbd /usr/share + do + [[ -d "${kbddir}" ]] && \ + for dir in ${KBDSUBDIRS//,/ } + do + [[ -d "${kbddir}/${dir}" ]] && continue + false + done || kbddir='' + done + + [[ ${kbddir} ]] || { + derror "Directories ${KBDSUBDIRS//,/, } not found. Please inform us about the issue including your OS name and version." + return 1 + } + + [[ ! ${hostonly} || ${keyboard_vars} && ${i18n_vars} ]] || { + derror 'Please set up keyboard_vars and i18n_vars in configuration file.' + return 1 + } +} + + +if checks +then + install_base + + if [[ ${hostonly} ]] + then + install_local_keyboard + install_local_i18n + else + install_all_kbd + fi +fi diff --git a/modules.d/10i18n/parse-i18n.sh b/modules.d/10i18n/parse-i18n.sh new file mode 100755 index 0000000..785b51b --- /dev/null +++ b/modules.d/10i18n/parse-i18n.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +inst_key_val() { + local value + value=$(getarg $1) + [ -n "${value}" ] && printf '%s="%s"\n' $1 ${value} >> $2 +} + + +mkdir -p /etc/sysconfig +inst_key_val KEYMAP /etc/sysconfig/keyboard +inst_key_val EXT_KEYMAPS /etc/sysconfig/keyboard +inst_key_val UNICODE /etc/sysconfig/i18n +inst_key_val SYSFONT /etc/sysconfig/i18n +inst_key_val CONTRANS /etc/sysconfig/i18n +inst_key_val UNIMAP /etc/sysconfig/i18n +inst_key_val LANG /etc/sysconfig/i18n +inst_key_val LC_ALL /etc/sysconfig/i18n + +if [ -f /etc/sysconfig/i18n ]; then + . /etc/sysconfig/i18n + export LANG + export LC_ALL +fi diff --git a/modules.d/10redhat-i18n/10-console.rules b/modules.d/10redhat-i18n/10-console.rules new file mode 100644 index 0000000..c234c8a --- /dev/null +++ b/modules.d/10redhat-i18n/10-console.rules @@ -0,0 +1,2 @@ +# Console initialization - keyboard, font, etc. +KERNEL=="tty0", RUN+="/lib/udev/console_init %k" -- 1.7.1
Attachment:
signature.asc
Description: PGP signature