diff --git a/runtime/vm/CRIUHelpers.cpp b/runtime/vm/CRIUHelpers.cpp index 72130b8a186..e1c5230575c 100644 --- a/runtime/vm/CRIUHelpers.cpp +++ b/runtime/vm/CRIUHelpers.cpp @@ -19,6 +19,8 @@ * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception *******************************************************************************/ +#include + #include "objhelp.h" #include "j9.h" #include "j9comp.h" @@ -48,6 +50,7 @@ static IDATA findinstanceFieldOffsetHelper(J9VMThread *currentThread, J9Class *i static void initializeCriuHooks(J9VMThread *currentThread); static BOOLEAN juRandomReseed(J9VMThread *currentThread, void *userData, const char **nlsMsgFormat); static BOOLEAN criuRestoreInitializeTrace(J9VMThread *currentThread, void *userData, const char **nlsMsgFormat); +static BOOLEAN criuRestoreInitializeXrs(J9VMThread *currentThread, void *userData, const char **nlsMsgFormat); static jvmtiIterationControl objectIteratorCallback(J9JavaVM *vm, J9MM_IterateObjectDescriptor *objectDesc, void *userData); BOOLEAN @@ -232,7 +235,7 @@ juRandomReseed(J9VMThread *currentThread, void *userData, const char **nlsMsgFor } /** - * An internal JVM checkpoint hook is to initialize trace after restore. + * An internal JVM checkpoint hook to initialize trace after restore. * * @param[in] currentThread vmThread token * @param[in] userData J9InternalHookRecord pointer @@ -263,6 +266,60 @@ criuRestoreInitializeTrace(J9VMThread *currentThread, void *userData, const char return result; } +/** + * An internal JVM checkpoint hook to initialize -Xrs after restore. This only + * supports -Xrs options with "onRestore" appended to it. + * + * @param[in] currentThread vmThread token + * @param[in] userData J9InternalHookRecord pointer + * @param[in/out] nlsMsgFormat an NLS message + * + * @return Always returns TRUE + */ +static BOOLEAN +criuRestoreInitializeXrs(J9VMThread *currentThread, void *userData, const char **nlsMsgFormat) +{ + J9JavaVM *vm = currentThread->javaVM; + J9VMInitArgs *args = vm->checkpointState.restoreArgsList; + + if (NULL != args) { + IDATA argIndex = 0; + if ((argIndex = FIND_ARG_IN_ARGS(args, OPTIONAL_LIST_MATCH, VMOPT_XRS, NULL)) >= 0) { + bool argProcessed = false; + char* optionValue = NULL; + U_32 sigOptions = 0; + + GET_OPTION_VALUE_ARGS(args, argIndex, ':', &optionValue); + if (NULL != optionValue) { + if (0 == strcmp(optionValue, "syncOnRestore")) { + vm->sigFlags |= J9_SIG_XRS_SYNC; + sigOptions |= J9PORT_SIG_OPTIONS_REDUCED_SIGNALS_SYNCHRONOUS; + argProcessed = true; + } else if (0 == strcmp(optionValue, "asyncOnRestore")) { + vm->sigFlags |= (J9_SIG_XRS_ASYNC | J9_SIG_NO_SIG_QUIT | J9_SIG_NO_SIG_USR2); + sigOptions |= J9PORT_SIG_OPTIONS_REDUCED_SIGNALS_ASYNCHRONOUS; + argProcessed = true; + } else if (0 == strcmp(optionValue, "onRestore")) { + vm->sigFlags |= (J9_SIG_XRS_SYNC | J9_SIG_XRS_ASYNC | J9_SIG_NO_SIG_QUIT | J9_SIG_NO_SIG_USR2); + sigOptions |= (J9PORT_SIG_OPTIONS_REDUCED_SIGNALS_SYNCHRONOUS | J9PORT_SIG_OPTIONS_REDUCED_SIGNALS_ASYNCHRONOUS); + argProcessed = true; + } + } + + if (argProcessed) { + PORT_ACCESS_FROM_VMC(currentThread); + CONSUME_ARG(args, argIndex); + j9sig_set_options(sigOptions); + } + } + } + + /* In cases of error (arg options are not supported) the entire args is not consumed. + * Return TRUE as checkpointJVMImpl will throw an exception if any arg is not consumed. + */ + return TRUE; +} + /** * This cleans up the instanceObjects associated with each J9JavaVM->checkpointState.hookRecords, * the hookRecords and classIterationRestoreHookRecords as well if checkpointState.isNonPortableRestoreMode is TRUE. @@ -348,6 +405,7 @@ initializeCriuHooks(J9VMThread *currentThread) addInternalJVMCheckpointHook(currentThread, TRUE, juRandomClass, FALSE, juRandomReseed); } addInternalJVMCheckpointHook(currentThread, TRUE, NULL, FALSE, criuRestoreInitializeTrace); + addInternalJVMCheckpointHook(currentThread, TRUE, NULL, FALSE, criuRestoreInitializeXrs); } done: diff --git a/test/functional/cmdLineTests/criu/criu_nonPortable.xml b/test/functional/cmdLineTests/criu/criu_nonPortable.xml index 5af6a6cbdb3..ad8dfbf7774 100644 --- a/test/functional/cmdLineTests/criu/criu_nonPortable.xml +++ b/test/functional/cmdLineTests/criu/criu_nonPortable.xml @@ -495,7 +495,7 @@ Restore arg: -Dprop2=val2 Restore arg: -Dprop3=val3 - + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest9 1 Killed failed properties test @@ -510,7 +510,7 @@ Could not dump the JVM processes, err=-70 - + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest10 1 Killed failed properties test @@ -525,7 +525,7 @@ Could not dump the JVM processes, err=-70 - + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest11 1 Killed failed properties test @@ -540,7 +540,88 @@ Could not dump the JVM processes, err=-70 - + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$ -Xtrace:print=j9criu.16" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest12 1 + Killed + failed properties test + Pre-checkpoint + Failed to load options from the options file + CRIU is not enabled + Operation not permitted + + Thread pid mismatch + do not match expected + Unable to create a thread: + + Could not dump the JVM processes, err=-70 + Restore arg: -Dprop1=val1 + Restore arg: -Dprop2=val2 + Restore arg: -Dprop3=val3 + + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest13 1 + Killed + failed properties test + Pre-checkpoint + Failed to load options from the options file + CRIU is not enabled + Operation not permitted + + Thread pid mismatch + do not match expected + Unable to create a thread: + + Could not dump the JVM processes, err=-70 + org.eclipse.openj9.criu.JVMRestoreException + + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest14 1 + Killed + failed properties test + Pre-checkpoint + Failed to load options from the options file + CRIU is not enabled + Operation not permitted + + Thread pid mismatch + do not match expected + Unable to create a thread: + + Could not dump the JVM processes, err=-70 + org.eclipse.openj9.criu.JVMRestoreException + + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest15 1 + Killed + failed properties test + Pre-checkpoint + Failed to load options from the options file + CRIU is not enabled + Operation not permitted + + Thread pid mismatch + do not match expected + Unable to create a thread: + + Could not dump the JVM processes, err=-70 + org.eclipse.openj9.criu.JVMRestoreException + + + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_ENVVAR_TEST$ EnvVarFileTest16 1 + Killed + failed properties test + Pre-checkpoint + Failed to load options from the options file + CRIU is not enabled + Operation not permitted + + Thread pid mismatch + do not match expected + Unable to create a thread: + + Could not dump the JVM processes, err=-70 + org.eclipse.openj9.criu.JVMRestoreException + bash $SCRIPPATH$ $TEST_RESROOT$ $JAVA_COMMAND$ "$JVM_OPTIONS$" $MAINCLASS_OPTIONSFILE_TEST$ TraceOptionsTest 1 Killed diff --git a/test/functional/cmdLineTests/criu/src/org/openj9/criu/EnvVarFileTest.java b/test/functional/cmdLineTests/criu/src/org/openj9/criu/EnvVarFileTest.java index 1372deb5644..2358add9fdc 100644 --- a/test/functional/cmdLineTests/criu/src/org/openj9/criu/EnvVarFileTest.java +++ b/test/functional/cmdLineTests/criu/src/org/openj9/criu/EnvVarFileTest.java @@ -68,6 +68,21 @@ public static void main(String[] args) { case "EnvVarFileTest11": envVarFileTest11(); break; + case "EnvVarFileTest12": + envVarFileTest12(); + break; + case "EnvVarFileTest13": + envVarFileTest13(); + break; + case "EnvVarFileTest14": + envVarFileTest14(); + break; + case "EnvVarFileTest15": + envVarFileTest15(); + break; + case "EnvVarFileTest16": + envVarFileTest16(); + break; default: throw new RuntimeException("incorrect parameters"); } @@ -330,4 +345,63 @@ static void envVarFileTest12() { System.out.println("ERR: failed properties test"); } } + + static void envVarFileTest13() { + String optionsContents = RESTORE_ENV_VAR + "=-Xrs\n"; + Path optionsFilePath = CRIUTestUtils.createOptionsFile("options", optionsContents); + + Path imagePath = Paths.get("cpData"); + CRIUTestUtils.createCheckpointDirectory(imagePath); + CRIUSupport criuSupport = new CRIUSupport(imagePath); + criuSupport.registerRestoreEnvFile(optionsFilePath); + + System.out.println("Pre-checkpoint"); + CRIUTestUtils.checkPointJVM(criuSupport, imagePath, true); + System.out.println("Post-checkpoint"); + System.out.println("ERR: failed properties test"); + } + + static void envVarFileTest14() { + String optionsContents = RESTORE_ENV_VAR + "=-Xrs:sync\n"; + Path optionsFilePath = CRIUTestUtils.createOptionsFile("options", optionsContents); + + Path imagePath = Paths.get("cpData"); + CRIUTestUtils.createCheckpointDirectory(imagePath); + CRIUSupport criuSupport = new CRIUSupport(imagePath); + criuSupport.registerRestoreEnvFile(optionsFilePath); + + System.out.println("Pre-checkpoint"); + CRIUTestUtils.checkPointJVM(criuSupport, imagePath, true); + System.out.println("Post-checkpoint"); + System.out.println("ERR: failed properties test"); + } + + static void envVarFileTest15() { + String optionsContents = RESTORE_ENV_VAR + "=-Xrs:onRestore\n"; + Path optionsFilePath = CRIUTestUtils.createOptionsFile("options", optionsContents); + + Path imagePath = Paths.get("cpData"); + CRIUTestUtils.createCheckpointDirectory(imagePath); + CRIUSupport criuSupport = new CRIUSupport(imagePath); + criuSupport.registerRestoreEnvFile(optionsFilePath); + + System.out.println("Pre-checkpoint"); + CRIUTestUtils.checkPointJVM(criuSupport, imagePath, true); + System.out.println("Post-checkpoint"); + } + + static void envVarFileTest16() { + String optionsContents = RESTORE_ENV_VAR + "=-Xrs:syncOnRestore\n"; + Path optionsFilePath = CRIUTestUtils.createOptionsFile("options", optionsContents); + + Path imagePath = Paths.get("cpData"); + CRIUTestUtils.createCheckpointDirectory(imagePath); + CRIUSupport criuSupport = new CRIUSupport(imagePath); + criuSupport.registerRestoreEnvFile(optionsFilePath); + + System.out.println("Pre-checkpoint"); + CRIUTestUtils.checkPointJVM(criuSupport, imagePath, true); + System.out.println("Post-checkpoint"); + } + }