Skip to content

Instantly share code, notes, and snippets.

@headius
Last active April 26, 2023 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/1db8e66aab4c4d229f71c9d7360f9429 to your computer and use it in GitHub Desktop.
Save headius/1db8e66aab4c4d229f71c9d7360f9429 to your computer and use it in GitHub Desktop.
JRuby CRIU proof-of-concept patch
commit dac864582a44da0017fdc5b85d431c05f40eb675
Author: Charles Oliver Nutter <headius@headius.com>
Date: Sat Apr 22 12:40:27 2023 -0500
criu testing
diff --git a/bin/jruby.sh b/bin/jruby.sh
index 00903f0ba8..fd62212a07 100755
--- a/bin/jruby.sh
+++ b/bin/jruby.sh
@@ -535,6 +535,8 @@ do
--environment) print_environment_log=true ;;
# warn but ignore
--1.8|--1.9|--2.0) echo "warning: $1 ignored" 1>&2 ;;
+ --checkpoint) append java_args -Djruby.checkpoint.path=./jruby_criu -XX:+EnableCRIUSupport ;;
+ --restore) exec criu restore -D ./jruby_criu --shell-job -v4 --log-file=restore.log ;;
# Abort processing on the double dash
--) break ;;
# Other opts go to ruby
diff --git a/core/src/main/java/org/jruby/Main.java b/core/src/main/java/org/jruby/Main.java
index a7b9e2935f..3f9c66594d 100644
--- a/core/src/main/java/org/jruby/Main.java
+++ b/core/src/main/java/org/jruby/Main.java
@@ -56,6 +56,7 @@ import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -63,6 +64,8 @@ import java.util.Set;
import java.util.HashSet;
import java.util.Properties;
+import org.eclipse.openj9.criu.CRIUSupport;
+
/**
* Class used to launch the interpreter.
* This is the main class as defined in the jruby.mf manifest.
@@ -195,6 +198,31 @@ public class Main {
main = new Main(true);
}
+ if (System.getProperty("jruby.checkpoint.path") != null) {
+ // delete property since it is unknown to the rest of JRuby
+ String path = System.getProperty("jruby.checkpoint.path");
+ System.clearProperty("jruby.checkpoint.path");
+
+ // run a bunch of JRuby stuff and then checkpoint
+ if (CRIUSupport.isCRIUSupportEnabled()) {
+ System.out.print("Warming up JRuby...");
+ for (int i = 0; i < 100; i++) {
+ Ruby.newInstance();
+ }
+ System.out.println(" done! Saving checkpoint.");
+
+ new CRIUSupport(Paths.get(path))
+ .setLeaveRunning(false)
+ .setShellJob(true)
+ .setFileLocks(true)
+ .setLogLevel(4)
+ .setLogFile("logs")
+ .checkpointJVM();
+ } else {
+ System.err.println("CRIU is not enabled: " + CRIUSupport.getErrorMessage());
+ }
+ }
+
try {
Status status = main.run(args);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment