diff --git a/emhttp/plugins/dynamix/scripts/ssd_trim b/emhttp/plugins/dynamix/scripts/ssd_trim index a27ebd948..acd0e1da7 100755 --- a/emhttp/plugins/dynamix/scripts/ssd_trim +++ b/emhttp/plugins/dynamix/scripts/ssd_trim @@ -45,10 +45,28 @@ function write(...$messages){ curl_close($com); } +/* Check if the disk is an HDD based on rotational flag */ function is_hdd($disk) { - $disk = explode('/',$disk); - $disk = preg_replace('/^(sd[a-z]+|nvme[0-9]+n1)p?1$/','$1',end($disk)); - return file_get_contents("/sys/block/$disk/queue/rotational")==1; + /* Ensure $disk is properly extracted */ + $disk = trim($disk); + + /* Extract the last part of the path */ + $disk = explode('/', $disk); + $disk = preg_replace('/^(sd[a-z]+|nvme[0-9]+n1)p?1$/', '$1', end($disk)); + + /* Validate the extracted disk name */ + if (strpos($disk, ' ') !== false || empty($disk)) { + return false; + } + + $file = "/sys/block/$disk/queue/rotational"; + $result = false; + + if (file_exists($file)) { + $result = trim(file_get_contents($file)) == '1'; + } + + return $result; } function zfs_info($name) { @@ -72,17 +90,48 @@ function zfs_trim($write) { } } +/* Perform fstrim on XFS and Btrfs filesystems */ function xfs_btrfs_trim($write) { - exec("findmnt -lnt btrfs,xfs -o target,source|awk '\$2!~\"\\\\[\"{print \$1,\$2}'",$mounts); + /* Use findmnt with JSON output and jq to ensure accurate parsing */ + exec("findmnt -lnt btrfs,xfs -J | jq -r '.filesystems[] | select(.source | test(\"^/dev/\")) | \"\\(.target)\\t\\(.source)\"'", $mounts); + foreach ($mounts as $mount) { - [$target,$source] = explode(' ',$mount); - if (is_hdd($source)) continue; + /* Split using tab as the delimiter */ + $parts = explode("\t", $mount, 2); + + /* Ensure we have both target and source */ + if (count($parts) < 2) continue; + + [$target, $source] = $parts; + $target_escaped = escapeshellarg($target); + + /* Ensure $source is valid */ + if (empty($source)) continue; + + /* Resolve the actual device backing the mount */ + $device = trim(exec("findmnt -no SOURCE " . escapeshellarg($target))); + + /* Skip if we cannot resolve a device */ + if (empty($device)) continue; + + /* Check if the device is an HDD */ + if (is_hdd($device)) continue; + if ($write) write("$target: ... \r"); - $trim = exec("fstrim -v $target 2>/dev/null"); + + $trim = exec("fstrim -v $target_escaped 2>/dev/null"); + + /* Handle output based on mode (write or echo) */ if ($write) { - if ($trim) write("$trim on $source\r","\n"); else write("\r"); + if ($trim) { + write("$trim on $source\r", "\n"); + } else { + write("\r"); + } } else { - if ($trim) echo("$trim on $source\n"); + if ($trim) { + echo("$trim on $source\n"); + } } } }