Использование CRIU для приложения Java - PullRequest
1 голос
/ 08 апреля 2019

Итак, я хочу использовать CRIU, чтобы сделать снимок процесса JVM и восстановить его позже. Для этого я написал небольшую программу, которая ничего не делает, кроме печати счетчика каждую секунду:

package some;

public class Fun {
    public static void main(String[] args) throws InterruptedException {
        for(int i = 0; i < Integer.valueOf(args[0]); i++) {
            System.out.println("Counter: "+i);
            Thread.sleep(1000);
        }       
    }   
}

Теперь, когда я запускаю программу $ java some.Fun 3000, программа начинает показывать мне секунды, пока все хорошо.

Теперь, когда я хочу сохранить процесс с помощью criu, я делаю $ ps -aux, нахожу PID моего процесса java (в нашем случае 3503) и вызываю criu $ criu dump -t 3503 -o dump.log --shell-job. После этого терминал со счетчиком прекращает считать, печатает Killed и, похоже, завершает работу.

На данный момент в папке, где я назвал criu, у меня есть несколько файлов дампа, которые я могу использовать для восстановления процесса $ criu restore -o dump.log --shell-job

Когда я это делаю, создается новый процесс с новым PID, и счетчик начинает отсчет с того момента, когда он остановился, как и должно быть. Ницца!

Однако, допустим, я убил процесс и попытался использовать те же файлы дампа, чтобы восстановить процесс. Если я это сделаю, criu сразу же завершит работу с сообщением Aborted (core dumped). То же самое происходит, если я пытаюсь перенести файлы на другую машину с той же версией Java и попробовать запустить ее там ...

Теперь мой вопрос: так и должно быть? Должны ли мы быть в состоянии восстановить состояние только один раз? Или я что-то не так делаю? Заранее спасибо!

1 Ответ

0 голосов
/ 23 июня 2019

Вам необходимо отключить функцию perfdata в JVM.

$ java -XX: -UsePerfData some.Fun 3000

Это подавляет создание каталогов /tmp/hsperfdata_userid.

Проблема возникает из-за того, что когда контрольные точки CRIU задают дерево процессов, в нем хранится информация для всех дескрипторов открытых файлов, а при восстановлении требуется, чтобы все файлы присутствовали (и имели одинаковый размер).

Когда вы впервые восстановили Java-приложение, временные файлы hsperfdata все еще были там, и все работало. Однако, когда вы убили ваше приложение, эти временные данные также были удалены.

...