#!/bin/sh set -e # Source debconf library: . /usr/share/debconf/confmodule # Source bilibop library: . /usr/lib/bilibop/common.sh PATH="${PATH}:/usr/share/bilibop" ETC_RULES_DIR="/etc/udev/rules.d" belong_to_disk_group() { for g in $(stat -c %G ${1}*); do [ "${g}" = "disk" ] || return 1 done } case "${1}" in configure|reconfigure) # Debconf specific configuration # ============================== # At first, backup some values if this is not already done. HELPER="physical_volumes_filter" LVMCONF="/etc/lvm/lvm.conf" lvm_variables="obtain_device_list_from_udev filter global_filter" if [ -f "${LVMCONF}" ]; then for lvmvar in ${lvm_variables}; do db_fget bilibop-rules/${HELPER}/${lvmvar} seen [ "${RET}" = "true" ] && continue lvmval="$(grep "^[[:blank:]]*${lvmvar}[[:blank:]]*=" ${LVMCONF} | sed 's,^[^=]\+=\s*,,')" db_set bilibop-rules/${HELPER}/${lvmvar} ${lvmval} db_fset bilibop-rules/${HELPER}/${lvmvar} seen true # Now the initial values of 'obtain_device_list_from_udev', # 'filter' and 'global_filter' are stored in the debconf # db. They will be restored if the package is purged. done fi # Now we have to take care of the order of the processes: # 1. Ask the user if she wants to use a custom rules file # 2. Trigger uevents to apply bilibop (custom or generic) # udev rules # 3. Then ask the user if she wants to modify lvm.conf # (needs BILIBOP udev-tagged devices) # 4. Update initramfs by including the (modified or not) # lvm.conf if [ -h /proc/mounts -a -d /sys/block -a -c /dev/null ] && invoke-rc.d udev status >/dev/null 2>&1 && BILIBOP_DISK="$(physical_hard_disk /)" && query_sysfs_attrs ${BILIBOP_DISK} | grep -Eq '^[[:blank:]]*SUBSYSTEMS=="(usb|firewire|memstick|mmc)"'; then db_get bilibop-rules/on-live-system if [ "${RET}" = "false" ]; then # bilibop_rules_generator # ----------------------- # Maybe build custom rules CUSTOM_RULES="false" HELPER="bilibop_rules_generator" if [ -f ${ETC_RULES_DIR}/66-bilibop.rules ]; then db_get bilibop-rules/${HELPER}/overwrite if [ "${RET}" = "rebuild" ]; then CUSTOM_RULES="true" elif [ "${RET}" = "remove" ]; then rm ${ETC_RULES_DIR}/66-bilibop.rules # Now that the custom rules file has been removed, # say to debconf the user does not want to build it. db_reset bilibop-rules/${HELPER}/customize db_fset bilibop-rules/${HELPER}/customize seen true # But also say to keep it if it is rebuilt manually. # We don't set the seen flag to true: if the custom # rules file has been built manually, the question # should be asked on next package upgrade. db_reset bilibop-rules/${HELPER}/overwrite fi else db_get bilibop-rules/${HELPER}/customize if [ "${RET}" = "true" ]; then CUSTOM_RULES="true" fi fi # Build the custom rules: if [ "${CUSTOM_RULES}" = "true" ]; then db_get bilibop-rules/${HELPER}/options if ${HELPER} ${RET} -t ${BILIBOP_DISK} 2>/dev/null; then # Custom rules file has been successfully created; # so say debconf to keep it the next time the package # is configured: db_reset bilibop-rules/${HELPER}/overwrite db_fset bilibop-rules/${HELPER}/overwrite seen true else CUSTOM_RULES="false" fi fi fi # Udev specific configuration # =========================== # Trigger uevents for block devices owned by 'disk' group # or being on the same disk than the root filesystem. BILIBOP_LIST="$(lsbilibop -l)" opt="--sysname-match=${BILIBOP_DISK##*/}*" for dev in ${BILIBOP_LIST}; do case "${dev}" in ${BILIBOP_DISK}*) ;; *) opt="${opt} --sysname-match=${dev##*/}" ;; esac done udevadm trigger ${opt} udevadm settle # But it can happen that this doesn't work and new rules must be # explicitly loaded before triggering uevents: if ! belong_to_disk_group ${BILIBOP_DISK}; then udevadm control --reload-rules udevadm trigger ${opt} udevadm settle # Now do something if the drive and its partitions still belong # to another group than disk (floppy, plugdev, ...). if ! belong_to_disk_group ${BILIBOP_DISK}; then for dev in $(find ${BILIBOP_DISK}* ! -group disk); do flop="${flop:+${flop} }${dev}" done if [ -f "${ETC_RULES_DIR}/66-bilibop.rules" -a "${CUSTOM_RULES}" != "true" ]; then # Custom rules file exists, but it has not been created # just before: db_subst bilibop-rules/not_belong_to_disk_group/custom_rules_error DEVICE "${flop}" db_input critical bilibop-rules/not_belong_to_disk_group/custom_rules_error || true db_go || true else # Custom rules file does not exist, or it has just been # created: db_subst bilibop-rules/not_belong_to_disk_group/internal_error DEVICE "${flop}" db_input critical bilibop-rules/not_belong_to_disk_group/internal_error || true db_go || true fi fi fi # Debconf stuff... again (because we need updated udev tags to do it) # ====================== db_get bilibop-rules/on-live-system if [ "${RET}" = "false" ]; then # physical_volumes_filter # ----------------------- HELPER="physical_volumes_filter" # The file copied into the initrd is always /etc/lvm/lvm.conf # (the hook does not care about LVM_SYSTEM_DIR); so we reset # LVM_SYSTEM_DIR to be sure the helper script will apply to # this file. export LVM_SYSTEM_DIR="/etc/lvm" LVMCONF_RECONFIGURE="0" if lsblk ${BILIBOP_DISK} --noheadings -o type,fstype | grep -Eq '\<(lvm|LVM2_member)\>'; then OLDPVFILTER="$(${HELPER})" || true db_get bilibop-rules/${HELPER}/system-only if [ "${RET}" = "true" ]; then unlinked= untagged= PV_LIST="$(lsblk --noheadings -o fstype,kname ${BILIBOP_DISK} | awk '/^LVM2_member/ {print $2}')" for dev in ${PV_LIST}; do linked="false" for symlink in $(udevadm info --query symlink --name ${dev}); do case "${symlink}" in disk/by-id/lvm-pv-uuid-*) ;; disk/by-id/*|mapper/*) linked="true" break ;; esac done [ "${linked}" = "true" ] || unlinked="${unlinked:+${unlinked} }/dev/${dev}" [ "$(lsbilibop /dev/${dev})" = "/dev/${dev}" ] || untagged="${untagged:+${untagged} }/dev/${dev}" done fi if [ "${RET}" = "true" -a -z "${untagged}" -a -z "${unlinked}" ]; then if ! ${HELPER} --udev --accept bilibop --reject all >/dev/null 2>&1; then ${HELPER} --init fi ${HELPER} --overwrite --udev --accept bilibop --reject all else if [ "${RET}" = "true" ]; then db_reset bilibop-rules/${HELPER}/system-only db_get bilibop-rules/${HELPER}/global_filter db_subst bilibop-rules/${HELPER}/warning GLOBAL_FILTER "${RET}" db_subst bilibop-rules/${HELPER}/warning UNTAGGED "${untagged}" db_subst bilibop-rules/${HELPER}/warning UNLINKED "${unlinked}" db_get bilibop-rules/${HELPER}/obtain_device_list_from_udev db_subst bilibop-rules/${HELPER}/warning FROMUDEV "${RET}" db_get bilibop-rules/${HELPER}/filter db_subst bilibop-rules/${HELPER}/warning FILTER "${RET}" db_input critical bilibop-rules/${HELPER}/warning || true db_go || true fi for lvmvar in ${lvm_variables}; do db_fget bilibop-rules/${HELPER}/${lvmvar} seen [ "${RET}" = "true" ] || continue db_get bilibop-rules/${HELPER}/${lvmvar} if [ -z "${RET}" ]; then sed -i "/^\s*${lvmvar}\s*=/d" ${LVMCONF} elif grep -q "^[[:blank:]]*${lvmvar}[[:blank:]]*=" ${LVMCONF}; then sed -ri "s@^(\s*${lvmvar}\s*=).*@\1 ${RET}@" ${LVMCONF} else sed -ri "s@^\s*devices\s*\{.*@&\n ${lvmvar} = ${RET}@" ${LVMCONF} fi done fi NEWPVFILTER="$(${HELPER})" || true if [ "${NEWPVFILTER}" != "${OLDPVFILTER}" ]; then LVMCONF_RECONFIGURE="1" # Regenerate cache file: vgscan --ignorelockingfailure fi fi fi fi db_stop # Add a new script in the initramfs. And modify it also if LVM has # been reconfigured (see above): if which update-initramfs >/dev/null; then if [ "${DEBCONF_RECONFIGURE}" = "1" ]; then if [ "${LVMCONF_RECONFIGURE}" = "1" ]; then update-initramfs -u fi else update-initramfs -u fi fi ;; esac : # vim: et ts=4 sts=4 sw=4