Как обеспечить завершение всех процессов перед размонтированием файловой системы?

sudo systemctl set -default graphical.target Затем sudo reboot, чтобы перезагрузить компьютер. В моей системе работает нормально, сразу после перезагрузки я перенаправляюсь в свой графический интерфейс.

3
08.03.2020, 13:56
1 ответ

Вот два метода. Если вы не доверяете своим приложениям, вы можете сразу перейти ко второму методу.

1.umount --lazy

Если эти мешающие процессы неchdir())в точку монтирования (используют абсолютные пути, например ), и вы знаете, что они в конечном итоге сдадутся, тогда в Linux вы можете использоватьumount --lazy:ядро ​​отключит сопоставление файловая система из каталогов, делающая ее недоступной для новых обращений, и автоматически размонтирует ее, когда исчезнет последняя ссылка. Ссылкой может быть открытый fd, cwd, точка монтирования внутри (последнее было бы плохо )...

Но это не повлияет на процессы/потоки, сохраняющие ссылку «внутри», например все еще открытые файловые дескрипторы или имеющие cwd внутри. Тогда это будет еще сложнее, поскольку теперь файловая система больше недоступна, и становится еще труднее отслеживать нарушающие процессы/потоки (, например,:fuser -mбольше не найдет их ). Итак, каким-то образом вам нужно, чтобы процессы вели себя правильно для этого метода.

2. морозильная группа

Альтернативное решение, которое должно работать для плохого поведения процессов :сгруппировать все эти процессы (и потоки )в одной и той же контрольной группе заморозки. Заморозьте их все, чтобы они не добавляли использование ресурсов в точку монтирования (путем разветвления/клонирования/открытия новых файловых файлов ). Даже если вы пропустите несколько в первом цикле, вы в конечном итоге уловите все новое в последующих итерациях. Поскольку они теперь заморожены, никаких новых действий не произойдет :, теперь вы можете убить их всех. Для cgroups v1, уже инициализированных ОС (, например :с помощью systemd или cgmanager , в противном случае вам придется выяснить, как смонтировать cgroup заморозки. подсистема ), что-то вроде этого должно работать. Обратите внимание, что, по-видимому, запись в cgroup.procsдолжна включать все потоки, которые должны появиться в tasks, но были сообщения о ненадежном поведении,поэтому на всякий случай я также перебираю потоки, даже если это, вероятно, не нужно (, т.е. :tasks, вероятно, уже правильно заполнен потоками, поэтому цикл for tявляется избыточным ).

mkdir -p /sys/fs/cgroup/freezer/prepareumount

echo FROZEN > /sys/fs/cgroup/freezer/prepareumount/freezer.state

for i in $(seq 1 10); do
    for p in $(fuser -m /mount/v1 2>/dev/null); do
        echo $p > /sys/fs/cgroup/freezer/prepareumount/cgroup.procs
        for t in $(ps -L -o tid= -p $p); do
            echo $t > /sys/fs/cgroup/freezer/prepareumount/tasks
        done
    done
done

#give time to an overloaded kernel to freeze everything (FREEZING->FROZEN)
while ! cat /sys/fs/cgroup/freezer/prepareumount/freezer.state | grep -q FROZEN; do
    sleep 0.1
done

# kills, delayed
for i in $(cat /sys/fs/cgroup/freezer/prepareumount/cgroup.procs); do
    kill -KILL $i
done

# actual kills happen now, at once
echo THAWED > /sys/fs/cgroup/freezer/prepareumount/freezer.state

sleep 1
umount /mount/v1

При использовании cgroups v2 это необходимо изменить.

0
28.04.2021, 23:21

Теги

Похожие вопросы