Skip to content

Instantly share code, notes, and snippets.

@fonic
Last active June 1, 2020 08:15
Show Gist options
  • Save fonic/f37cec16d39c222da3f1d2fda1faa984 to your computer and use it in GitHub Desktop.
Save fonic/f37cec16d39c222da3f1d2fda1faa984 to your computer and use it in GitHub Desktop.
Generate udisks / udisks2 device configuration
#!/usr/bin/env bash
# -------------------------------------------------------------------------
# -
# Created by Fonic <https://github.com/fonic> -
# Date: 06/01/20 -
# -
# Based on: -
# https://petermolnar.net/article/hard-drive-spindown-clicking-noise/ -
# man 8 udisks -
# -
# -------------------------------------------------------------------------
# ------------------------------------
# -
# Configuration -
# -
# ------------------------------------
# Path to udisks config directory
UDISKS_CONFIG_DIR="/etc/udisks2"
# Spin-down timeout (integer value of range 0-255):
# 0: timeout disabled
# 1-240: timeout is multiple of 5 seconds (yielding timeouts from 5 seconds to 20 minutes)
# 241-251: timeout is multiple of 30 minutes (yielding timeouts from 30 minutes to 5.5 hours)
# 252: timeout is 21 minutes
# 253: timeout is vendor-defined between 8 and 12 hours
# 254: reserved
# 255: timeout is 21 minutes 15 seconds
STANDBY_TIMEOUT="242"
# Advanced Power Management (integer value of range 0-255; lower value = more power management / less performance, higher value = less power management / more performance):
# 1-127: power management enabled, spin-down enabled
# 128-254: power management enabled, spin-down disabled
# 255: power management disabled
APM_LEVEL="127"
# Automatic Acoustic Management (integer value of range 0-255; lower value = more acoustic management / less performance, higher value = less acoustic management / more performance):
# 128: most quiet / lowest performance
# 254: least quiet / highest performance
# NOTE:
# some drives don't support AAM at all,
# some drives only support two levels (quiet/fast),
# most drives only support three distinct modes:
# 0: acoustic management disabled
# 128: quiet / slow
# 254: loud / fast
AAM_LEVEL="254"
# Write cache (boolean value 'true'/'false'):
# true: write cache enabled
# false: write cache disabled
WRITE_CACHE="true"
# Read look-ahead (boolean value 'true'/'false'):
# true: read look-ahead enabled
# false: read look-ahead disabled
READ_LOOKAHEAD="true"
# ------------------------------------
# -
# Main Program -
# -
# ------------------------------------
# Check command line
if (( $# < 1 )); then
echo "Usage: $(basename "$0") <device>..."
exit 2
fi
# Check root privileges
if (( ${EUID} != 0 )); then
echo -e "\e[1;31mError: root privileges required\e[0m"
exit 1
fi
# Process specified device(s)
for device; do
# Determine device model and serial number
unset model serial
re_model1="^Device Model:[[:space:]]*(.*)$" # SATA
re_model2="^Model Number:[[:space:]]*(.*)$" # NVMe
re_serial="^Serial Number:[[:space:]]*(.*)$" # SATA + NVMe
while read -r line; do
if [[ "${line}" =~ $re_model1 || "${line}" =~ $re_model2 ]]; then
model="${BASH_REMATCH[1]}"
elif [[ "${line}" =~ $re_serial ]]; then
serial="${BASH_REMATCH[1]}"
fi
done < <(smartctl -i "${device}")
# Verify results
#echo "Device '${device}', model: '${model}', serial: '${serial}'"
[[ -z "${model+set}" ]] && echo -e "\e[1;31mError: device '${device}': failed to determine device model\e[0m"
[[ -z "${serial+set}" ]] && echo -e "\e[1;31mError: device '${device}': failed to determine serial number\e[0m"
[[ -z "${model+set}" || -z "${serial+set}" ]] && continue
# Generate udisks device configuration
file="${UDISKS_CONFIG_DIR}/${model// /-}-${serial// /-}.conf"
> "${file}"
echo "# -------------------------------------------------------------------------" >> "${file}"
echo "# -" >> "${file}"
printf "# %-69s -\n" "Auto-generated by '$(basename "$0")'" >> "${file}"
printf "# %-69s -\n" "Date: $(date +%m/%d/%y)" >> "${file}"
echo "# -" >> "${file}"
printf "# %-69s -\n" "Device: '${device}'" >> "${file}"
printf "# %-69s -\n" "Model: '${model}'" >> "${file}"
printf "# %-69s -\n" "Serial: '${serial}'" >> "${file}"
echo "# -" >> "${file}"
echo "# -------------------------------------------------------------------------" >> "${file}"
echo "" >> "${file}"
echo "[ATA]" >> "${file}"
[[ -n "${STANDBY_TIMEOUT+set}" ]] && echo "StandbyTimeout=${STANDBY_TIMEOUT}" >> "${file}"
[[ -n "${APM_LEVEL+set}" ]] && echo "APMLevel=${APM_LEVEL}" >> "${file}"
[[ -n "${AAM_LEVEL+set}" ]] && echo "AAMLevel=${AAM_LEVEL}" >> "${file}"
[[ -n "${WRITE_CACHE+set}" ]] && echo "WriteCacheEnabled=${WRITE_CACHE}" >> "${file}"
[[ -n "${READ_LOOKAHEAD+set}" ]] && echo "ReadLookaheadEnabled=${READ_LOOKAHEAD}" >> "${file}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment