@@ -52,6 +52,7 @@ APPLY_IOMMU=0
5252APPLY_SMT=" "
5353PERSIST_SMT=0
5454AUTO_YES=0
55+ DRY_RUN=0
5556
5657usage () {
5758 cat << 'EOF '
@@ -69,6 +70,7 @@ Options:
6970 --apply-smt STATE Apply runtime SMT change (on|off). Requires --mode apply
7071 --persist-smt (apply only) Also persist SMT choice via GRUB changes (adds/removes 'nosmt')
7172 --yes Skip interactive confirmations (use with caution)
73+ --dry-run Preview the exact GRUB/sysfs changes without applying them (safe)
7274 --verbose More detail in audit output
7375 -h, --help Show this help
7476EOF
@@ -285,7 +287,9 @@ cache_kernel_versions() {
285287
286288apply_sysctl () {
287289 local outfile=" /etc/sysctl.d/90-fasterdata.conf"
288- require_root
290+ if [[ $DRY_RUN -ne 1 ]]; then
291+ require_root
292+ fi
289293 log_info " Writing $outfile "
290294 # backup existing file
291295 if [[ -f " $outfile " ]]; then
@@ -458,7 +462,9 @@ create_ethtool_persist_service() {
458462 # Generates systemd service to persist ethtool settings across reboots
459463 local svcfile=" /etc/systemd/system/ethtool-persist.service"
460464 local dry_run=${1:- 0}
461- require_root
465+ if [[ $DRY_RUN -ne 1 ]]; then
466+ require_root
467+ fi
462468
463469 log_info " Generating $svcfile to persist ethtool settings"
464470
@@ -639,6 +645,15 @@ apply_iommu() {
639645 return
640646 fi
641647 log_warn " IOMMU not in kernel cmdline (CPU: $cpu_vendor ). Will add: $iommu_cmd "
648+ local backup=" /etc/default/grub.bak.$( date +%Y%m%d%H%M%S) "
649+ if [[ $DRY_RUN -eq 1 ]]; then
650+ echo
651+ echo " === IOMMU change PREVIEW ==="
652+ echo " Current kernel cmdline: $cmdline "
653+ echo " Would ensure GRUB_CMDLINE_LINUX contains: $iommu_cmd "
654+ echo " The script would backup /etc/default/grub to $backup and run grub2-mkconfig -o /boot/grub2/grub.cfg (or update-grub)"
655+ return
656+ fi
642657 if [[ $AUTO_YES -ne 1 ]]; then
643658 read -r -p " Update /etc/default/grub and regenerate GRUB to add '$iommu_cmd '? [y/N] " resp
644659 if [[ ! " $resp " =~ ^[Yy]$ ]]; then
@@ -648,24 +663,45 @@ apply_iommu() {
648663 fi
649664 # Backup grub config
650665 local backup=" /etc/default/grub.bak.$( date +%Y%m%d%H%M%S) "
651- cp -a /etc/default/grub " $backup "
652- log_info " Backed up /etc/default/grub to $backup "
666+ if [[ $DRY_RUN -eq 1 ]]; then
667+ echo " Dry-run: would copy /etc/default/grub -> $backup "
668+ else
669+ cp -a /etc/default/grub " $backup "
670+ log_info " Backed up /etc/default/grub to $backup "
671+ fi
653672 # Read existing value and ensure we append without duplicates
654673 local existing
655674 existing=$( awk -F= ' /^GRUB_CMDLINE_LINUX=/ { match($0,/=(\"|\")(.*)\1/,m); print m[2]; exit }' /etc/default/grub || true)
656- if [[ -z " $existing " ]]; then
657- echo " GRUB_CMDLINE_LINUX=\" $iommu_cmd \" " >> /etc/default/grub
675+ if [[ $DRY_RUN -eq 1 ]]; then
676+ if [[ -z " $existing " ]]; then
677+ echo " Dry-run: would set GRUB_CMDLINE_LINUX=\" $iommu_cmd \" "
678+ else
679+ if echo " $existing " | grep -qF " $iommu_cmd " ; then
680+ echo " Dry-run: GRUB already contains required IOMMU flags"
681+ else
682+ local newval=" $existing $iommu_cmd "
683+ echo " Dry-run: would update GRUB_CMDLINE_LINUX to: $newval "
684+ fi
685+ fi
658686 else
659- if echo " $existing " | grep -qF " $iommu_cmd " ; then
660- log_info " GRUB already contains required IOMMU flags "
687+ if [[ -z " $existing " ]] ; then
688+ echo " GRUB_CMDLINE_LINUX= \" $iommu_cmd \" " >> /etc/default/grub
661689 else
662- # Append flags
663- local newval=" $existing $iommu_cmd "
664- # Replace the line
665- sed -i " s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\" $newval \" |" /etc/default/grub
690+ if echo " $existing " | grep -qF " $iommu_cmd " ; then
691+ log_info " GRUB already contains required IOMMU flags"
692+ else
693+ # Append flags
694+ local newval=" $existing $iommu_cmd "
695+ # Replace the line
696+ sed -i " s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\" $newval \" |" /etc/default/grub
697+ fi
666698 fi
667699 fi
668700 # Regenerate grub
701+ if [[ $DRY_RUN -eq 1 ]]; then
702+ echo " Dry-run: would run grub2-mkconfig -o /boot/grub2/grub.cfg or update-grub"
703+ return
704+ fi
669705 if command -v grub2-mkconfig > /dev/null 2>&1 ; then
670706 grub2-mkconfig -o /boot/grub2/grub.cfg
671707 elif command -v update-grub > /dev/null 2>&1 ; then
@@ -697,6 +733,14 @@ apply_smt() {
697733 log_info " SMT already set to $cur "
698734 else
699735 log_warn " Changing SMT from $cur to $APPLY_SMT "
736+ if [[ $DRY_RUN -eq 1 ]]; then
737+ echo
738+ echo " === SMT change PREVIEW ==="
739+ echo " Current SMT: $cur "
740+ echo " Would run: echo $APPLY_SMT | sudo tee /sys/devices/system/cpu/smt/control"
741+ echo " Dry-run: SMT will not be changed. Use --mode apply without --dry-run to apply."
742+ return
743+ fi
700744 if [[ $AUTO_YES -ne 1 ]]; then
701745 read -r -p " Apply SMT change now (writes to /sys/devices/system/cpu/smt/control)? [y/N] " resp
702746 if [[ ! " $resp " =~ ^[Yy]$ ]]; then
@@ -717,28 +761,59 @@ apply_smt() {
717761 fi
718762 # Edit GRUB similar to apply_iommu (backup/append/remove nosmt)
719763 local backup=" /etc/default/grub.bak.$( date +%Y%m%d%H%M%S) "
720- cp -a /etc/default/grub " $backup "
721- log_info " Backed up /etc/default/grub to $backup "
764+ if [[ $DRY_RUN -eq 1 ]]; then
765+ echo " Dry-run: would copy /etc/default/grub -> $backup "
766+ else
767+ cp -a /etc/default/grub " $backup "
768+ log_info " Backed up /etc/default/grub to $backup "
769+ fi
722770 local existing
723771 existing=$( awk -F= ' /^GRUB_CMDLINE_LINUX=/ { match($0,/=(\"|\")(.*)\1/,m); print m[2]; exit }' /etc/default/grub || true)
724- if [[ -z " $existing " ]]; then
725- if [[ -n " $grubnosmt " ]]; then
726- echo " GRUB_CMDLINE_LINUX=\" $grubnosmt \" " >> /etc/default/grub
772+ if [[ $DRY_RUN -eq 1 ]]; then
773+ if [[ -z " $existing " ]]; then
774+ if [[ -n " $grubnosmt " ]]; then
775+ echo " Dry-run: would set GRUB_CMDLINE_LINUX=\" $grubnosmt \" "
776+ else
777+ echo " Dry-run: would not change GRUB_CMDLINE_LINUX (no nosmt present)"
778+ fi
779+ else
780+ if [[ -n " $grubnosmt " ]]; then
781+ if echo " $existing " | grep -qF " $grubnosmt " ; then
782+ echo " Dry-run: GRUB already contains $grubnosmt "
783+ else
784+ local newval=" $existing $grubnosmt "
785+ echo " Dry-run: would update GRUB_CMDLINE_LINUX to: $newval "
786+ fi
787+ else
788+ # Remove nosmt bit if present (preview)
789+ local newval=$( echo " $existing " | sed ' s/\bnosmt\b//g' | sed ' s/ */ /g' | sed ' s/^ *//;s/ *$//' )
790+ echo " Dry-run: would update GRUB_CMDLINE_LINUX to: $newval "
791+ fi
727792 fi
728793 else
729- if [[ -n " $grubnosmt " ]]; then
730- if echo " $existing " | grep -qF " $grubnosmt " ; then
731- log_info " GRUB already contains $grubnosmt "
794+ if [[ -z " $existing " ]]; then
795+ if [[ -n " $grubnosmt " ]]; then
796+ echo " GRUB_CMDLINE_LINUX=\" $grubnosmt \" " >> /etc/default/grub
797+ fi
798+ else
799+ if [[ -n " $grubnosmt " ]]; then
800+ if echo " $existing " | grep -qF " $grubnosmt " ; then
801+ log_info " GRUB already contains $grubnosmt "
802+ else
803+ local newval=" $existing $grubnosmt "
804+ sed -i " s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\" $newval \" |" /etc/default/grub
805+ fi
732806 else
733- local newval=" $existing $grubnosmt "
807+ # Remove nosmt bit if present
808+ local newval=$( echo " $existing " | sed ' s/\bnosmt\b//g' | sed ' s/ */ /g' | sed ' s/^ *//;s/ *$//' )
734809 sed -i " s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\" $newval \" |" /etc/default/grub
735810 fi
736- else
737- # Remove nosmt bit if present
738- local newval=$( echo " $existing " | sed ' s/\bnosmt\b//g' | sed ' s/ */ /g' | sed ' s/^ *//;s/ *$//' )
739- sed -i " s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\" $newval \" |" /etc/default/grub
740811 fi
741812 fi
813+ if [[ $DRY_RUN -eq 1 ]]; then
814+ echo " Dry-run: would run grub2-mkconfig -o /boot/grub2/grub.cfg or update-grub"
815+ return
816+ fi
742817 if command -v grub2-mkconfig > /dev/null 2>&1 ; then
743818 grub2-mkconfig -o /boot/grub2/grub.cfg
744819 elif command -v update-grub > /dev/null 2>&1 ; then
@@ -964,6 +1039,7 @@ main() {
9641039 --apply-smt) APPLY_SMT=" $2 " ; shift 2;;
9651040 --persist-smt) PERSIST_SMT=1; shift ;;
9661041 --yes) AUTO_YES=1; shift ;;
1042+ --dry-run) DRY_RUN=1; shift ;;
9671043 -h|--help) usage; exit 0;;
9681044 * ) echo " Unknown arg: $1 " >&2 ; usage; exit 1;;
9691045 esac
0 commit comments