Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Automate script enabling write cache on HDDs

Featured Replies

Hello all, i'm new to unraid and currently loving it. (Bought the pro license)

 

I'm now running 1 array of 17: 3TB seagate disks (7 on the way to make a total of 24), 1: 2TB nvme cache and 6: ~1TB enterpise SSD on the way for a ZFS pool for proxmox

 

The only "dificulty" i have is that i want to enable all the write caches on the 24 seagate's. I found the following script and currently running this at the first startup of the array:

 

#!/bin/bash

# use ls /dev/disk/by-id/ to get disk id's

# Drives
declare -a StringArray=("scsi-35000c500ed8a1a6f" "scsi-35000c500ed8a04c3" "scsi-35000c500ed54eb6c" "scsi-35000c500ed54c967" "scsi-35000c50091b768fa" "scsi-35000c50082a1c7ef" "scsi-35000c5007ce2c2c7" "scsi-35000c50079e4545e" "scsi-35000c50078328fa7" "scsi-35000c5006752a28c" "scsi-35000c500675289ae" "scsi-35000c50065e89da1" "scsi-35000c50065e89aeb" "scsi-35000c5005367b818" "scsi-35000c5004f34906b" "scsi-35000c5003d78538c" "scsi-35000c5003d3ef109")

# Show status
echo "Current drive status: "
for drive in ${StringArray[@]}; do
    sdparm -g WCE /dev/disk/by-id/$drive
done

# Enable write caching
for drive in ${StringArray[@]}; do
    sdparm --set=WCE /dev/disk/by-id/$drive
done

# Show status again
echo "Finished running, check if the write cache was enabled!"
for drive in ${StringArray[@]}; do
    sdparm -g WCE /dev/disk/by-id/$drive
done

 

This works and does the job, is there someone with more linux experience then me that can automate the retrieval of the "scsi-" device ID's?

Please do note that when running "ls /dev/disk/by-id/" i also get results with: "wwn-", "usb-" and "nvme-". The "scsi-" results also show duplicates with "-part1" at the end

 

The best solution i think would be to filter the results bij array or pool

 

I want to automate this process because eventualy i will need to replace some of the currently 6 years+ spinning drives, and to search te removed ID and replace them with the newly added would be time consuming i think.

 

Maybe there are better solutions for my "problem"?

 

Cheers,

Lex

  • 4 months later...
  • Author

I'm currently using the following for anyone intrested:

 

#!/bin/bash
echo "Starting script...";

declare -a HDDArray=()

for i in /dev/disk/by-id/*; do HDDArray+=("$i");done

# Show status
echo "Current drive status: "
for drive in ${HDDArray[@]}; do
    sdparm -g WCE $drive;
    hdparm -W $drive
done

# Enable write caching
for drive in ${HDDArray[@]}; do
    sdparm $drive --set=WCE;
    hdparm -W1 $drive
done

# Show status again
echo "Finished running, check if the write cache was enabled!"
for drive in ${HDDArray[@]}; do
    sdparm -g WCE $drive;
    hdparm -W $drive
done

echo "Done!";

 

Probably not the best method because it tries to set the setting on all the attached storage devices but it works for now

Edited by Lexvdpoel

  • 11 months later...

why not use the --save flag for sdparm? That will persist it to the drive. There's an equivalent for hdparm.

 

Enabling volatile write cache can silently make the UnRaid parity inconsistent. 

 

  • 1 year later...

I created a smart version for UserScript plugin.
You might need to translate the messages.
Feel free to use it.

#!/usr/bin/env bash
#description=Maximale Stabilität mit sauberem Status-Abschluss für Unraid v7.
#name=Smart Disk Cache Pro Final

SUCCESS_COUNT=0
ERROR_COUNT=0
TOTAL_COUNT=0
ERROR_LIST=""

# Funktion zum Auffüllen mit Punkten (für die Spaltenmitten)
fill() {
    local str="$1"
    local len="$2"
    local dot=".................................................."
    local res="${str}${dot}"
    echo "${res:0:len}"
}

echo "Prüfung: $(date '+%Y-%m-%d %H:%M:%S')"
echo "----------------------------------------------------------------------------------------------------"

# KOPFZEILE: Status ohne Punkte am Ende
H_DEV=$(fill "Device" 10)
H_DRV=$(fill "Driver" 8)
H_TYP=$(fill "Typ" 5)
H_MOD=$(fill "Modell" 25)
H_SER=$(fill "Serial" 20)
H_STA="Status" # Hier keine Punkte

echo "${H_DEV}  ${H_DRV}  ${H_TYP}  ${H_MOD}  ${H_SER}  ${H_STA}"
echo "----------------------------------------------------------------------------------------------------"

for DRIVE_PATH in /sys/block/sd*; do
    DEV=$(basename "$DRIVE_PATH")
    NODE="/dev/$DEV"
    [ -e "$NODE" ] || continue
    # USB-Geräte ignorieren
    if [[ $(readlink -f "$DRIVE_PATH") == *"usb"* ]]; then continue; fi

    ((TOTAL_COUNT++))

    # 1. Hardware Info sammeln
    INFO=$(smartctl -i "$NODE")
    IFACE="SATA"
    echo "$INFO" | grep -qi "SAS" && IFACE="SAS"
    
    MODEL=$(echo "$INFO" | grep -Ei "Device Model:|Vendor:" | head -1 | awk -F: '{print $2}' | xargs)
    SERIAL=$(echo "$INFO" | grep -i "Serial Number:" | awk -F: '{print $2}' | xargs)
    DRIVER=$(basename $(readlink "$DRIVE_PATH/device/driver" 2>/dev/null) 2>/dev/null || echo "???")

    # 2. Cache-Aktivierung (hdparm & smartctl persistent)
    hdparm -W 1 "$NODE" &>/dev/null
    hdparm -A 1 "$NODE" &>/dev/null
    smartctl -s wcache-sct,on,p "$NODE" &>/dev/null
    smartctl -s lookahead,on "$NODE" &>/dev/null

    # 3. Validierung je nach Interface
    RAW_STATUS="FEHLER"
    if [[ "$IFACE" == "SATA" ]]; then
        hdparm -W "$NODE" 2>/dev/null | grep -q "1" && RAW_STATUS="AKTIV"
    else
        smartctl -g wcache "$NODE" 2>/dev/null | grep -qi "Enabled" && RAW_STATUS="AKTIV"
    fi

    # 4. Status-Formatierung & Statistik
    if [ "$RAW_STATUS" == "AKTIV" ]; then
        ((SUCCESS_COUNT++))
        FMT_STATUS="[AKTIV]"
    else
        ((ERROR_COUNT++))
        FMT_STATUS="[FEHLER]"
        ERROR_LIST+="$DEV, "
    fi

    # 5. Datenzeilen: Spalten mit Punkten, Status am Ende frei
    P_DEV=$(fill "/dev/$DEV" 10)
    P_DRV=$(fill "$DRIVER" 8)
    P_TYP=$(fill "$IFACE" 5)
    P_MOD=$(fill "${MODEL:0:24}" 25)
    P_SER=$(fill "${SERIAL:0:19}" 20)

    echo "${P_DEV}  ${P_DRV}  ${P_TYP}  ${P_MOD}  ${P_SER}  ${FMT_STATUS}"
done

echo "----------------------------------------------------------------------------------------------------"

# --- Unraid v7 Notification Engine ---
NOTIFY_BIN="/usr/bin/notify"
if [ $ERROR_COUNT -eq 0 ]; then
    [ -x "$NOTIFY_BIN" ] && $NOTIFY_BIN -e "Disk Cache Optimizer" -d "Alle $SUCCESS_COUNT Laufwerke optimiert." -i "normal"
    echo "Zusammenfassung: Alle $SUCCESS_COUNT Laufwerke sind aktiv."
else
    CLEAN_ERROR_LIST=$(echo "$ERROR_LIST" | sed 's/, $//')
    [ -x "$NOTIFY_BIN" ] && $NOTIFY_BIN -e "Disk Cache ERROR" -d "$ERROR_COUNT Fehler!" -m "Betroffen: $CLEAN_ERROR_LIST" -i "alert"
    echo "Zusammenfassung: $ERROR_COUNT FEHLER gemeldet! ($CLEAN_ERROR_LIST)"
fi

echo "Script abgeschlossen."

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.