#!/bin/sh # Copyright (c) 2012-2019, Piotr Karbowski # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, are # permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this list # of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, this list # of conditions and the following disclaimer in the documentation and/or other # materials provided with the distribution. # * Neither the name of the Piotr Karbowski nor the names of its contributors may be # used to endorse or promote products derived from this software without specific # prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR 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 US # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This script meant to create /dev/disk/by-* and /dev/mapper/* symlinks. # and remove them after storage device is removed. # the /dev/disk/by-* handling based on the idea and proof of concept from BitJam. # debug #exec >> /run/debug-mdev 2>&1 #set -x #echo '### ENV:' #env #echo '### CODE:' # umask 077 # TODO use /tmp storage_dir="/tmp/.mdev-like-a-boss" [ -d "$storage_dir" ] || mkdir "$storage_dir" [ "$MDEV" ] || exit 2 create_uuid_label_symlink() { target_dir="/dev/disk/by-${1}" target_symlink="${target_dir}/${2}" [ -e "$target_symlink" ] && return mkdir -p "$target_dir" ln -sf "/dev/${MDEV}" "$target_symlink" printf "%s\n" "$target_symlink" > "${storage_dir}/storage_symlink_${1}_${MDEV}" } add_symlinks() { # Skip temp cryptsetup nodes. case "$MDEV" in "dm-"[0-9]*) case "$(cat "/sys/block/${MDEV}/dm/name")" in "temporary-cryptsetup-"[0-9]*) return 0 ;; esac ;; esac if command -v blkid > /dev/null 2>&1; then blkid_output=$(blkid "/dev/${MDEV}") eval "${blkid_output#*: }" [ "$UUID" ] && create_uuid_label_symlink uuid "$UUID" [ "$LABEL" ] && create_uuid_label_symlink label "$LABEL" [ "$PARTUUID" ] && create_uuid_label_symlink partuuid "$PARTUUID" fi if [ -f "/sys/block/${MDEV}/dm/name" ]; then [ -d /dev/mapper ] || mkdir /dev/mapper if ! [ -c /dev/mapper/control ]; then #awk '$2 == "device-mapper" { foo = system("mknod /dev/mapper/control c 10 " $1); exit foo }' /proc/misc || exit 1 while read -r dm; do [ "${dm#* }" = device-mapper ] && { mknod /dev/mapper/control c 10 "${dm% *}" || exit 1 } done < /proc/misc fi dmname=$(cat "/sys/block/${MDEV}/dm/name") if [ "$dmname" ]; then target_symlink="/dev/mapper/${dmname}" [ -e "$target_symlink" ] && return ln -sf "/dev/${MDEV}" "$target_symlink" printf "%s\n" "$target_symlink" > "${storage_dir}/storage_symlink_mapper_${MDEV}" fi fi } set_readahead() { read_ahead_kb_control="/sys/class/block/${MDEV}/queue/read_ahead_kb" new_read_ahead_kb="2048" if [ -f "$read_ahead_kb_control" ]; then read_ahead_kb=$(cat "$read_ahead_kb_control") if [ "$read_ahead_kb" -lt "$new_read_ahead_kb" ]; then logger -t mdev "Changing $MDEV read_ahead_kb from $read_ahead_kb to $new_read_ahead_kb" printf "%s" "$new_read_ahead_kb" > "$read_ahead_kb_control" fi fi } drop_symlinks() { for type in uuid label mapper; do [ -f "${storage_dir}/storage_symlink_${type}_${MDEV}" ] || continue target_symlink=$(cat "${storage_dir}/storage_symlink_${type}_${MDEV}" 2> /dev/null) [ "$target_symlink" ] || continue target_symlink_device=$(readlink "$target_symlink") if [ "$target_symlink_device" = "/dev/${MDEV}" ]; then rm "$target_symlink" fi rm "${storage_dir}/storage_symlink_${type}_${MDEV}" done } case "$ACTION" in add | "") add_symlinks set_readahead ;; remove) drop_symlinks ;; esac