Здрасьте. А можно ли как-то в линуксе «клонировать» запущенный процесс, и имеет ли это смысл? Поиск по документации и интернету прогнозируемо отсылает к функциям fork() и clone(), но это не совсем то. Я хочу не написать программу, которая будет уметь себя клонировать, а скопировать уже запущенный и выполняющийся процесс, который, вероятно, такого сам по себе не умеет. Принципиальный вопрос: даже если это удастся сделать, будет ли «клон» в принципе жизнеспособен? Допустим, никаких файлов или сетевых соединений у него в момент клонирования не открыто, но как поведут себя хотя-бы стандартные stdin/stdout/stderr? Ну и в принципе - возможно ли это, и как?
Пару слов зачем это. Давно у меня витает одна идея о том, как правильно делать бэкапы с запущенных виртуальных машин qemu-kvm. Все нынешние методы основываются на том, чтобы в нужный момент времени снять и сбэкапить снапшоты с дисков этой машины. Таким образом можно получить crash-consistent backup, т.е. как будто из физической машины дёрнули питание, и потом (в другой машине) сделали бэкап дисков, в надежде на то, что журналируемые файловые системы и транзакционные базы данных сами обеспечат целостность данных при таком форс-мажоре. Другой подход - сделать «снимок» работающей виртуальной машины, вместе с памятью и состоянием процессора, и потом это всё забэкапить. Здесь основной минус - процедура прерывает выполнение машины на довольно существенное время, к тому же добавляет к бэкапу содержимое памяти (а её может быть много). Хочется попробовать реализовать идею shutdown-consistent backup. То есть как если бы мы в произвольный момент времени нажали кнопку питания ACPI, дождались завершения работы машины, а потом сбэкапили её диски. Примерный алгоритм следующий: 1) поставить виртуальную машину на паузу (да, без этого никак, вопрос только в длительности); 2) сделать снимки всех дисков этой машины; 3) сделать клон процесса этой машины; 4) запустить виртуальную машину (исходный процесс) обратно. Как видим, даунтайм минимальный. Снимки дисков, если всё сделано правильно, делаются быстро (LVM, ZFS). Вопрос в третьем пункте. Если это тоже сделать правильно, как, например, делает fork(), то, даже при большом объеме выделенной для машины памяти клонирование процесса не займет много времени, т.к. копирования содержимого страниц при этом не происходит, они только помечаются как shared, и потом «делятся» между процессами с помощью механизма copy-on-write. Далее «правильный» бэкап снимаем уже с клона примерно так: 5) подменяем клону диски на их созданные только что снимки (не очень тривиально, но делается); 6) изолируем клон от сети и других устройств; 7) запускаем клон и через ACPI посылаем ему сигнал shutdown; 8) когда выключится, бэкапим диски. Вот такой вот ужас. Как вы думаете, реально?