Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/hotspot/share/include/crlib/crlib_description.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@ struct crlib_description {
// Returns a valid C-string with a formatted list of configuration keys supported by the engine
// with their descriptions, or null on error.
//
// Some keys can be excluded if they are not supposed to be set by a user but rather by the
// application the engine is linked to.
//
// Example:
// "
// * do_stuff=<true/false> (default: true) — whether to do stuff.\n
// * args=<string> (default: \"\") — other arguments.
// * args=<string> (default: \"\") — other arguments.\n
// "
const char *(*configuration_doc)(crlib_conf_t *);

Expand Down
13 changes: 13 additions & 0 deletions src/hotspot/share/runtime/crac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "logging/logConfiguration.hpp"
#include "memory/allocation.hpp"
#include "memory/oopFactory.hpp"
#include "nmt/memTag.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/crac_engine.hpp"
Expand All @@ -50,6 +51,7 @@
#include "os.inline.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/ostream.hpp"

static jlong _restore_start_time;
Expand Down Expand Up @@ -323,6 +325,17 @@ void crac::print_engine_info_and_exit() {
tty->print_raw_cr("Configuration options:");
tty->print_raw(conf_doc); // Doc string ends with CR by convention

const char * const *controlled_opts = CracEngine::vm_controlled_options();
tty->cr();
tty->print_raw("Configuration options controlled by the JVM: ");
for (const auto *opt = controlled_opts; *opt != nullptr; opt++) {
tty->print_raw(*opt);
if (*(opt + 1) != nullptr) {
tty->print_raw(", ");
}
}
tty->cr();

vm_exit(0);
ShouldNotReachHere();
}
Expand Down
65 changes: 54 additions & 11 deletions src/hotspot/share/runtime/crac_engine.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
/*
* Copyright (c) 2025, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#include "precompiled.hpp"

#include "crlib/crlib.h"
#include "crlib/crlib_restore_data.h"
#include "logging/log.hpp"
#include "memory/allStatic.hpp"
#include "nmt/memTag.hpp"
#include "runtime/crac_engine.hpp"
#include "runtime/globals.hpp"
#include "runtime/os.hpp"
Expand All @@ -15,8 +39,19 @@
#include <cstring>

// CRaC engine configuration options JVM sets directly instead of relaying from the user
#define ENGINE_OPT_IMAGE_LOCATION "image_location"
#define ENGINE_OPT_EXEC_LOCATION "exec_location"
#define VM_CONTROLLED_ENGINE_OPTS(OPT) \
OPT(image_location) \
OPT(exec_location) \

#define ARRAY_ELEM(opt) #opt,
static constexpr const char * const vm_controlled_engine_opts[] = {
VM_CONTROLLED_ENGINE_OPTS(ARRAY_ELEM) nullptr
};
#undef ARRAY_ELEM

#define DEFINE_OPT_VAR(opt) static constexpr const char engine_opt_##opt[] = #opt;
VM_CONTROLLED_ENGINE_OPTS(DEFINE_OPT_VAR)
#undef DEFINE_OPT_VAR

#ifdef _WINDOWS
static char *strsep(char **strp, const char *delim) {
Expand All @@ -35,6 +70,10 @@ static char *strsep(char **strp, const char *delim) {
}
#endif // _WINDOWS

const char * const *CracEngine::vm_controlled_options() {
return vm_controlled_engine_opts;
}

static bool find_engine(const char *dll_dir, char *path, size_t path_size, bool *is_library) {
// Try to interpret as a file path
if (os::is_path_absolute(CRaCEngine)) {
Expand Down Expand Up @@ -111,8 +150,8 @@ static bool find_engine(const char *dll_dir, char *path, size_t path_size, bool

static bool configure_image_location(const crlib_api_t &api, crlib_conf_t *conf, const char *image_location) {
precond(image_location != nullptr && image_location[0] != '\0');
if (!api.configure(conf, ENGINE_OPT_IMAGE_LOCATION, image_location)) {
log_error(crac)("CRaC engine failed to configure: '" ENGINE_OPT_IMAGE_LOCATION "' = '%s'", image_location);
if (!api.configure(conf, engine_opt_image_location, image_location)) {
log_error(crac)("CRaC engine failed to configure: '%s' = '%s'", engine_opt_image_location, image_location);
return false;
}
return true;
Expand Down Expand Up @@ -156,10 +195,10 @@ static crlib_conf_t *create_conf(const crlib_api_t &api, const char *image_locat
}

if (exec_location != nullptr) { // Only passed when using crexec
guarantee(api.can_configure(conf, ENGINE_OPT_EXEC_LOCATION),
"crexec does not support an internal option: " ENGINE_OPT_EXEC_LOCATION);
if (!api.configure(conf, ENGINE_OPT_EXEC_LOCATION, exec_location)) {
log_error(crac)("crexec failed to configure: '" ENGINE_OPT_EXEC_LOCATION "' = '%s'", exec_location);
guarantee(api.can_configure(conf, engine_opt_exec_location),
"crexec does not support expected option: %s", engine_opt_exec_location);
if (!api.configure(conf, engine_opt_exec_location, exec_location)) {
log_error(crac)("crexec failed to configure: '%s' = '%s'", engine_opt_exec_location, exec_location);
api.destroy_conf(conf);
return nullptr;
}
Expand All @@ -169,6 +208,11 @@ static crlib_conf_t *create_conf(const crlib_api_t &api, const char *image_locat
return conf;
}

CStringSet vm_controlled_keys;
#define PUT_CONTROLLED_KEY(opt) vm_controlled_keys.put_when_absent(engine_opt_##opt, false);
VM_CONTROLLED_ENGINE_OPTS(PUT_CONTROLLED_KEY)
#undef PUT_CONTROLLED_KEY

char *engine_options = os::strdup_check_oom(CRaCEngineOptions, mtInternal);
char *const engine_options_start = engine_options;
CStringSet keys;
Expand All @@ -177,9 +221,8 @@ static crlib_conf_t *create_conf(const crlib_api_t &api, const char *image_locat
const char *key = strsep(&key_value, "=");
const char *value = key_value != nullptr ? key_value : "";
assert(key != nullptr, "Should have terminated before");
if (strcmp(key, ENGINE_OPT_IMAGE_LOCATION) == 0 ||
(exec_location != nullptr && strcmp(key, ENGINE_OPT_EXEC_LOCATION) == 0)) {
log_warning(crac)("Internal CRaC engine option provided, skipping: %s", key);
if (vm_controlled_keys.contains(key)) {
log_warning(crac)("VM-controlled CRaC engine option provided, skipping: %s", key);
continue;
}
{
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/runtime/crac_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
// CRaC engine library wrapper.
class CracEngine : public CHeapObj<mtInternal> {
public:
static const char * const *vm_controlled_options();

explicit CracEngine(const char *image_location = nullptr);
~CracEngine();

Expand Down
8 changes: 3 additions & 5 deletions src/java.base/share/native/libcrexec/crexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,18 +362,16 @@ static const char *description(crlib_conf_t *conf) {
}

static const char *configuration_doc(crlib_conf_t *conf) {
// Internal options which are expected to be set by the program crexec is linked to are omitted
// since users are not supposed to pass them directly:
// * image_location=<path> (no default) - path to a directory with checkpoint/restore files.
// * exec_location=<path> (no default) - path to the engine executable.
return
"* image_location=<path> (no default) - path to a directory with checkpoint/restore files.\n"
"* exec_location=<path> (no default) - path to the engine executable.\n"
"* keep_running=<true/false> (default: false) - keep the process running after the checkpoint "
"or kill it.\n"
"* direct_map=<true/false> (default: true) - on restore, map process data directly from saved "
"files. This may speedup the restore but the resulting process will not be the same as before "
"the checkpoint.\n"
"* args=<string> (default: \"\") - free space-separated arguments passed directly to the "
"engine executable, e.g. \"--arg1 --arg2 --arg3\".";
"engine executable, e.g. \"--arg1 --arg2 --arg3\".\n";
}

static const char * const *configurable_keys(crlib_conf_t *conf) {
Expand Down
2 changes: 1 addition & 1 deletion test/jdk/jdk/crac/engineOptions/ParsingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void test_engines() throws Exception {
public void test_options() throws Exception {
test("simengine", "");
test("simengine", "image_location=cr", 0,
"Internal CRaC engine option provided, skipping: image_location");
"VM-controlled CRaC engine option provided, skipping: image_location");
if (Platform.isLinux()) {
test("criuengine", Arrays.asList("keep_running=true,args=-v -v -v -v"), 0,
Arrays.asList(
Expand Down