System:
  Kernel: 6.12.77-1-MANJARO arch: x86_64 bits: 64 compiler: gcc v: 15.2.1
    clocksource: tsc avail: hpet,acpi_pm
    parameters: BOOT_IMAGE=/boot/vmlinuz-6.12-x86_64
    root=UUID=945612fb-3bcb-4f73-909f-90543efe40bb rw quiet apparmor=1
    security=apparmor udev.log_priority=3
  Console: pty pts/2 DM: LightDM v: 1.32.0 Distro: Manjaro base: Arch Linux
Machine:
  Type: Laptop System: XIAOMI product: REDMI Book 14 2025(AMD) v: N/A
    serial: <filter> Chassis: type: 10 serial: <filter>
  Mobo: XIAOMI model: TM2422 v: V24C1 serial: <filter> part-nu: TM2422-66205
    uuid: 07242025-50bb-b587-18c4-50bbb58718c5 Firmware: UEFI vendor: XIAOMI
    v: RMARB4B1P0606 date: 08/07/2025
Battery:
  ID-1: BAT0 charge: 53.3 Wh (93.1%) condition: 57.2/56 Wh (102.2%)
    power: 16.3 W volts: 17.72 min: 15.44 model: SUNWODA R14B06W type: Li-ion
    serial: <filter> charging: status: charging cycles: -1
CPU:
  Info: model: AMD Ryzen 5 7535H w/ Radeon 660M Graphics socket: FP7 bits: 64
    type: MT MCP arch: Zen 3+ gen: 3 level: v3 note: check built: 2022
    process: TSMC n6 (7nm) family: 0x19 (25) model-id: 0x44 (68) stepping: 1
    microcode: 0xA404108
  Topology: cpus: 1x dies: 1 clusters: 1 cores: 6 threads: 12 tpc: 2
    smt: enabled cache: L1: 384 KiB desc: d-6x32 KiB; i-6x32 KiB L2: 3 MiB
    desc: 6x512 KiB L3: 16 MiB desc: 1x16 MiB
  Speed (MHz): avg: 400 min/max: 400/4603 boost: enabled
    base/boost: 3300/4600 scaling: driver: amd-pstate-epp governor: powersave
    volts: 1.2 V ext-clock: 100 MHz cores: 1: 400 2: 400 3: 400 4: 400 5: 400
    6: 400 7: 400 8: 400 9: 400 10: 400 11: 400 12: 400 bogomips: 79080
  Flags-basic: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3
    svm
  Vulnerabilities:
  Type: gather_data_sampling status: Not affected
  Type: indirect_target_selection status: Not affected
  Type: itlb_multihit status: Not affected
  Type: l1tf status: Not affected
  Type: mds status: Not affected
  Type: meltdown status: Not affected
  Type: mmio_stale_data status: Not affected
  Type: reg_file_data_sampling status: Not affected
  Type: retbleed status: Not affected
  Type: spec_rstack_overflow mitigation: Safe RET
  Type: spec_store_bypass mitigation: Speculative Store Bypass disabled via
    prctl
  Type: spectre_v1 mitigation: usercopy/swapgs barriers and __user pointer
    sanitization
  Type: spectre_v2 mitigation: Retpolines; IBPB: conditional; IBRS_FW;
    STIBP: always-on; RSB filling; PBRSB-eIBRS: Not affected; BHI: Not
    affected
  Type: srbds status: Not affected
  Type: tsa mitigation: Clear CPU buffers
  Type: tsx_async_abort status: Not affected
  Type: vmscape mitigation: IBPB before exit to userspace
Graphics:
  Device-1: Advanced Micro Devices [AMD/ATI] Rembrandt [Radeon 680M]
    vendor: Xiaomi driver: amdgpu v: kernel arch: RDNA-2 code: Navi-2x
    process: TSMC n7 (7nm) built: 2020-22 pcie: gen: 4 speed: 16 GT/s lanes: 16
    ports: active: eDP-1 empty: DP-1, DP-2, DP-3, DP-4, DP-5, DP-6, HDMI-A-1,
    Writeback-1 bus-ID: 03:00.0 chip-ID: 1002:1681 class-ID: 0300 temp: 46.0 C
  Device-2: ShineTech XiaoMi WebCam driver: uvcvideo type: USB rev: 2.0
    speed: 480 Mb/s lanes: 1 mode: 2.0 bus-ID: 5-1:2 chip-ID: 3277:00bf
    class-ID: fe01 serial: <filter>
  Display: x11 server: X.org v: 1.21.1.21 with: Xwayland v: 24.1.9 driver: X:
    loaded: amdgpu unloaded: modesetting alternate: fbdev,vesa dri: radeonsi
    gpu: amdgpu tty: 211x55
  Monitor-1: eDP-1 model: TM140VDXP02 built: 2024 res: 1920x1200 dpi: 162
    gamma: 1.2 size: 301x188mm (11.85x7.4") diag: 355mm (14") ratio: 16:10 modes:
    max: 1920x1200 min: 640x480
  API: EGL v: 1.5 hw: drv: amd radeonsi platforms: device: 0 drv: radeonsi
    device: 1 drv: swrast gbm: drv: radeonsi surfaceless: drv: radeonsi
    inactive: wayland,x11
  API: OpenGL v: 4.6 compat-v: 4.5 vendor: mesa v: 26.0.2-arch1.1
    note: console (EGL sourced) renderer: AMD Radeon 660M (radeonsi rembrandt
    ACO DRM 3.61 6.12.77-1-MANJARO), llvmpipe (LLVM 22.1.1 256 bits)
  Info: Tools: api: eglinfo,glxinfo de: kscreen-doctor x11: xprop,xrandr
Audio:
  Device-1: Advanced Micro Devices [AMD/ATI] Radeon High Definition Audio
    vendor: Xiaomi driver: snd_hda_intel v: kernel pcie: gen: 4 speed: 16 GT/s
    lanes: 16 bus-ID: 03:00.1 chip-ID: 1002:1640 class-ID: 0403
  Device-2: Advanced Micro Devices [AMD] Audio Coprocessor vendor: Xiaomi
    driver: snd_pci_acp6x v: kernel alternate: snd_pci_acp3x, snd_rn_pci_acp3x,
    snd_pci_acp5x, snd_acp_pci, snd_rpl_pci_acp6x, snd_pci_ps,
    snd_sof_amd_renoir, snd_sof_amd_rembrandt, snd_sof_amd_vangogh,
    snd_sof_amd_acp63, snd_sof_amd_acp70 pcie: gen: 4 speed: 16 GT/s lanes: 16
    bus-ID: 03:00.5 chip-ID: 1022:15e2 class-ID: 0480
  Device-3: Advanced Micro Devices [AMD] Ryzen HD Audio vendor: Xiaomi
    driver: snd_hda_intel v: kernel pcie: gen: 4 speed: 16 GT/s lanes: 16
    bus-ID: 03:00.6 chip-ID: 1022:15e3 class-ID: 0403
  API: ALSA v: k6.12.77-1-MANJARO status: kernel-api with: aoss
    type: oss-emulator tools: alsactl,alsamixer,amixer
  Server-1: sndiod v: N/A status: off tools: aucat,midicat,sndioctl
  Server-2: JACK v: 1.9.22 status: off tools: N/A
  Server-3: PipeWire v: 1.6.2 status: n/a (root, process) with:
    1: pipewire-pulse status: active 2: wireplumber status: active
    3: pipewire-alsa type: plugin tools: pactl,pw-cat,pw-cli,wpctl
Network:
  Device-1: MEDIATEK vendor: AzureWave driver: mt7921e v: kernel pcie: gen: 1
    speed: 2.5 GT/s lanes: 1 port: N/A bus-ID: 01:00.0 chip-ID: 14c3:7920
    class-ID: 0280
  IF: wlp1s0 state: up mac: <filter>
  IF-ID-1: tun0 state: unknown speed: 10000 Mbps duplex: full mac: N/A
  Info: services: NetworkManager, sshd, systemd-timesyncd, wpa_supplicant
Bluetooth:
  Device-1: IMC Networks Wireless_Device driver: btusb v: 0.8 type: USB
    rev: 2.1 speed: 480 Mb/s lanes: 1 mode: 2.0 bus-ID: 3-3:3 chip-ID: 13d3:3621
    class-ID: e001 serial: <filter>
  Report: rfkill ID: hci0 rfk-id: 0 state: up address: see --recommends
Drives:
  Local Storage: total: 476.94 GiB used: 60.7 GiB (12.7%)
  SMART Message: Required tool smartctl not installed. Check --recommends
  ID-1: /dev/nvme0n1 maj-min: 259:0 vendor: Foresee model: XP2000F512G
    size: 476.94 GiB block-size: physical: 512 B logical: 512 B speed: 63.2 Gb/s
    lanes: 4 tech: SSD serial: <filter> fw-rev: V1223M1T temp: 27.9 C
    scheme: GPT
Partition:
  ID-1: / raw-size: 363.74 GiB size: 363.56 GiB (99.95%)
    used: 60.67 GiB (16.7%) fs: xfs block-size: 512 B dev: /dev/nvme0n1p5
    maj-min: 259:5
  ID-2: /boot/efi raw-size: 100 MiB size: 96 MiB (96.00%)
    used: 31.6 MiB (32.9%) fs: vfat block-size: 512 B dev: /dev/nvme0n1p1
    maj-min: 259:1
Swap:
  Alert: No swap data was found.
Sensors:
  System Temperatures: cpu: 50.2 C mobo: N/A gpu: amdgpu temp: 47.0 C
  Fan Speeds (rpm): N/A
Info:
  Memory: total: 16 GiB note: est. available: 14.82 GiB used: 4.03 GiB (27.2%)
  Processes: 394 Power: uptime: 19m states: freeze,mem,disk suspend: s2idle
    wakeups: 0 hibernate: platform avail: shutdown, reboot, suspend, test_resume
    image: 5.87 GiB services: csd-power,upowerd Init: systemd v: 259
    default: graphical tool: systemctl
  Packages: 1485 pm: pacman pkgs: 1470 libs: 390 tools: pamac pm: flatpak
    pkgs: 15 Compilers: clang: 22.1.1 gcc: 15.2.1 Shell: Bash (su) v: 5.3.9
    running-in: pty pts/2 inxi: 3.3.40
  Static hostname: lala-book
        Icon name: computer-laptop
          Chassis: laptop 💻
Chassis Asset Tag: Chassis Asset Tag
       Machine ID: 28e61ccf8bed436986de92b3b00e196a
          Boot ID: c4e6fbd9a01b497f91aeae34b229ed6e
     Product UUID: 07242025-50bb-b587-18c4-50bbb58718c5
 Operating System: Manjaro Linux                       
           Kernel: Linux 6.12.77-1-MANJARO
     Architecture: x86-64
  Hardware Vendor: XIAOMI
   Hardware Model: REDMI Book 14 2025_AMD_
  Hardware Serial: 66205/25UR01373
     Hardware SKU: TM2422-66205
 Hardware Version: V24C1
 Firmware Version: RMARB4B1P0606
    Firmware Date: Thu 2025-08-07
     Firmware Age: 7month 3w 1d

redmi-book AES-256-CBC    6253546.15k  8439674.67k  9205890.99k  9370426.03k  9414625.96k  9401625.26k

[file-name 000357_2026-03-30_11-16-21.txt]

##добавить своп для гибернации

#!/usr/bin/env bash
# setup-hibernate.sh — настройка гибернации на Arch + GRUB + ext4/xfs
# Использование: sudo ./setup-hibernate.sh [SWAP_SIZE_MB]
set -Eeuo pipefail

# ---------- конфигурация ----------
SWAP_SIZE_MB="${1:-16384}"
SWAP_PATH="/swapfile"
TS=$(date +%Y%m%d-%H%M%S)
BACKUPS=("/etc/fstab" "/etc/default/grub" "/etc/mkinitcpio.conf")

# ---------- логирование и откат ----------
log()  { printf '[\033[1;34m*\033[0m] %s\n' "$*"; }
err()  { printf '[\033[1;31m!\033[0m] %s\n' "$*" >&2; }
die()  { err "$*"; exit 1; }

on_err() {
    err "Сбой на строке $1. Бэкапы с суффиксом .bak.$TS в /etc."
    err "Откат: for f in /etc/fstab /etc/default/grub /etc/mkinitcpio.conf; do"
    err "           cp -a \"\$f.bak.$TS\" \"\$f\"; done && mkinitcpio -P && grub-mkconfig -o /boot/grub/grub.cfg"
}
trap 'on_err $LINENO' ERR

# ---------- проверки окружения ----------
[ "$EUID" -eq 0 ] || die "Нужен root"
for cmd in mkinitcpio grub-mkconfig filefrag findmnt dd mkswap swapon; do
    command -v "$cmd" >/dev/null || die "Не найдена команда: $cmd"
done

# Поддержка гибернации ядром
grep -qw disk /sys/power/state || die "Ядро не поддерживает hibernation (нет 'disk' в /sys/power/state)"

# Загрузчик — GRUB
[ -x /usr/bin/grub-mkconfig ] || die "Скрипт рассчитан на GRUB. Для systemd-boot/rEFInd правьте конфиг вручную."

# ФС, где будет swapfile
DIR=$(dirname "$SWAP_PATH")
FSTYPE=$(findmnt -no FSTYPE -T "$DIR")
case "$FSTYPE" in
    ext4|xfs) log "ФС для swapfile: $FSTYPE" ;;
    btrfs)    die "Btrfs swapfile требует особого обращения (swapfile в subvolume, chattr +C). Скрипт не поддерживает." ;;
    *)        die "ФС $FSTYPE не поддерживается этим скриптом" ;;
esac

# LUKS — предупреждаем, но не блокируем
if lsblk -o type,fstype -n 2>/dev/null | grep -qw crypto_LUKS; then
    err "ВНИМАНИЕ: обнаружен LUKS. Для гибернации нужен encrypt/sd-encrypt hook ДО resume,"
    err "и resume= должен указывать на decrypted device. Скрипт этого не делает."
    err "Если не уверены — прервите (Ctrl-C) и настройте вручную."
    sleep 5
fi

# RAM vs swap
RAM_MB=$(free -m | awk '/^Mem:/ {print $2}')
if [ "$SWAP_SIZE_MB" -lt "$RAM_MB" ]; then
    err "ВНИМАНИЕ: swap (${SWAP_SIZE_MB}MB) < RAM (${RAM_MB}MB)."
    err "Гибернация может не работать или терять данные. Продолжить? (y/N)"
    read -r ans
    [ "$ans" = "y" ] || die "Прервано пользователем"
fi

# ---------- бэкапы ----------
for f in "${BACKUPS[@]}"; do
    [ -f "$f" ] || die "Нет файла $f"
    cp -a "$f" "$f.bak.$TS" || die "Не удалось создать бэкап $f"
done
log "Бэкапы созданы: *.bak.$TS"

# ---------- [1/7] swapfile ----------
log "[1/7] Создание swapfile ${SWAP_SIZE_MB}MB..."
if [ -f "$SWAP_PATH" ]; then
    CUR_SIZE_MB=$(( $(stat -c %s "$SWAP_PATH") / 1024 / 1024 ))
    if [ "$CUR_SIZE_MB" -ne "$SWAP_SIZE_MB" ]; then
        err "Существующий $SWAP_PATH имеет размер ${CUR_SIZE_MB}MB, ожидалось ${SWAP_SIZE_MB}MB."
        err "Используем как есть. Чтобы пересоздать — удалите его вручную и запустите снова."
    fi
else
    avail=$(df -BM --output=avail "$DIR" | tail -1 | tr -dc 0-9)
    [ "$avail" -gt $((SWAP_SIZE_MB + 1024)) ] \
        || die "Мало места на $DIR: доступно ${avail}MB, нужно $((SWAP_SIZE_MB + 1024))MB"

    tmp="${SWAP_PATH}.tmp"
    rm -f "$tmp"

    # fallocate быстрее на ext4, но НЕ безопасен для swapfile на XFS (дырки).
    # Используем dd везде — надёжно.
    log "    dd if=/dev/zero of=$tmp bs=1M count=$SWAP_SIZE_MB"
    dd if=/dev/zero of="$tmp" bs=1M count="$SWAP_SIZE_MB" status=progress
    chmod 0600 "$tmp"
    mkswap "$tmp"

    # Проверка фрагментации: swapfile должен быть contiguous
    EXTENTS=$(LC_ALL=C filefrag -v "$tmp" 2>/dev/null \
              | awk -F'[ .:]+' '$1 ~ /^[0-9]+$/ {n++} END{print n+0}')
    if [ "$EXTENTS" -gt 1 ]; then
        rm -f "$tmp"
        die "swapfile получился фрагментированным ($EXTENTS экстентов). \
Попробуйте освободить место или используйте отдельный swap-раздел."
    fi

    mv "$tmp" "$SWAP_PATH"
    log "    swapfile создан (1 экстент)"
fi

# Активация
if ! swapon --show=NAME --noheadings 2>/dev/null | grep -qx "$SWAP_PATH"; then
    swapon "$SWAP_PATH" || die "swapon не удался"
fi

# /etc/fstab — обеспечить финальный \n, затем дописать, если нет записи
[ -z "$(tail -c1 /etc/fstab 2>/dev/null)" ] || printf '\n' >> /etc/fstab
if ! grep -qE "^[[:space:]]*${SWAP_PATH}[[:space:]]" /etc/fstab; then
    printf '%s none swap defaults 0 0\n' "$SWAP_PATH" >> /etc/fstab
    log "    Добавлено в /etc/fstab"
fi

# ---------- [2/7] UUID и offset ----------
log "[2/7] UUID и physical offset..."
SWAP_FS_UUID=$(findmnt -no UUID -T "$SWAP_PATH") \
    || die "Не удалось получить UUID ФС для $SWAP_PATH"
[[ "$SWAP_FS_UUID" =~ ^[0-9A-Fa-f-]+$ ]] || die "Некорректный UUID: '$SWAP_FS_UUID'"

# Надёжный парсинг filefrag: берём начало первого экстента.
# Формат: "   0:        0..   N:  OFFSET..  ...:  length:  ..."
SWAP_OFFSET=$(LC_ALL=C filefrag -v "$SWAP_PATH" 2>/dev/null \
    | awk -F'[ .:]+' '/^[[:space:]]*0:/ {print $5; exit}')
[[ "$SWAP_OFFSET" =~ ^[0-9]+$ ]] || die "Не удалось определить physical offset"
log "    FS_UUID=$SWAP_FS_UUID  offset=$SWAP_OFFSET"

# ---------- [3/7] /etc/default/grub ----------
log "[3/7] /etc/default/grub..."
grep -q '^GRUB_CMDLINE_LINUX_DEFAULT="' /etc/default/grub \
    || die "Нет строки GRUB_CMDLINE_LINUX_DEFAULT=\"...\" в /etc/default/grub"

# Удаляем старые resume=/resume_offset= (в любом порядке, с любыми значениями)
sed -i -E \
    -e 's/[[:space:]]+resume=UUID=[^ "]+//g' \
    -e 's/[[:space:]]+resume=[^ "]+//g' \
    -e 's/[[:space:]]+resume_offset=[^ "]+//g' \
    /etc/default/grub

# Дописываем новые параметры перед закрывающей кавычкой
sed -i -E \
    "s|^(GRUB_CMDLINE_LINUX_DEFAULT=\")([^\"]*)\"|\1\2 resume=UUID=${SWAP_FS_UUID} resume_offset=${SWAP_OFFSET}\"|" \
    /etc/default/grub

# Проверка: ровно одна resume= и одна resume_offset=
N_RESUME=$(grep -cE 'resume=' /etc/default/grub)
N_OFFSET=$(grep -cE 'resume_offset=' /etc/default/grub)
[ "$N_RESUME" -eq 1 ] || die "Ожидалась 1 строка с resume=, найдено $N_RESUME"
[ "$N_OFFSET" -eq 1 ] || die "Ожидалась 1 строка с resume_offset=, найдено $N_OFFSET"
log "    GRUB_CMDLINE обновлён"

# ---------- [4/7] mkinitcpio hooks ----------
log "[4/7] mkinitcpio hooks..."
HOOKS_LINE=$(grep -E '^HOOKS=' /etc/mkinitcpio.conf || true)
[ -n "$HOOKS_LINE" ] \
    || die "В /etc/mkinitcpio.conf нет активной строки HOOKS= (закомментирована?). Настройте вручную."

if [[ "$HOOKS_LINE" == *systemd* ]]; then
    log "    Обнаружен systemd hook — resume hook не нужен (используется sd-resume)"
elif [[ "$HOOKS_LINE" == *resume* ]]; then
    log "    resume hook уже присутствует"
else
    # Вставляем 'resume' ПЕРЕД 'filesystems'
    if [[ "$HOOKS_LINE" == *filesystems* ]]; then
        sed -i -E '/^HOOKS=/ s/(\(|[[:space:]])filesystems[[:space:]]/\1resume filesystems /' \
            /etc/mkinitcpio.conf
        # Гарантия: проверим результат
        grep -E '^HOOKS=' /etc/mkinitcpio.conf | grep -qw resume \
            || die "Не удалось вставить resume hook. Проверьте /etc/mkinitcpio.conf вручную."
        log "    resume hook добавлен перед filesystems"
    else
        die "В HOOKS нет 'filesystems'. Добавьте 'resume' вручную перед вашим последним hook."
    fi
fi

# ---------- [5/7] mkinitcpio ----------
log "[5/7] Пересборка initramfs..."
mkinitcpio -P || die "mkinitcpio завершился с ошибкой"

# ---------- [6/7] GRUB ----------
log "[6/7] grub-mkconfig..."
grub-mkconfig -o /boot/grub/grub.cfg || die "grub-mkconfig завершился с ошибкой"

# ---------- [7/7] финальная проверка ----------
log "[7/7] Проверка конфигурации..."
{
    echo "----- /etc/default/grub (resume) -----"
    grep -E 'GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub
    echo "----- /etc/mkinitcpio.conf (HOOKS) -----"
    grep -E '^HOOKS=' /etc/mkinitcpio.conf
    echo "----- swap -----"
    swapon --show
    echo "----- /etc/fstab (swap) -----"
    grep swap /etc/fstab
} | sed 's/^/    /'

trap - ERR
cat <<EOF

Готово. ПОРЯДОК ДЕЙСТВИЙ:

1. ПЕРЕЗАГРУЗИТЕСЬ.
2. После загрузки проверьте, что ядро увидело resume-параметры:
       cat /sys/power/resume /sys/power/resume_offset
   Должно быть: <SWAP_FS_UUID>:0 и offset из вывода выше.
3. Сохраните всю работу, затем:
       systemctl hibernate

Если что-то пошло не так — откат:
   for f in /etc/fstab /etc/default/grub /etc/mkinitcpio.conf; do
       cp -a "\$f.bak.$TS" "\$f"
   done
   mkinitcpio -P && grub-mkconfig -o /boot/grub/grub.cfg

Бэкапы ($TS) можно удалить после успешной проверки гибернации:
   rm /etc/{fstab,default/grub,mkinitcpio.conf}.bak.$TS
EOF