Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-72833] Do not attempt to self-exec on systems without libc #9025

Merged
merged 1 commit into from Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/src/main/java/hudson/lifecycle/Lifecycle.java
Expand Up @@ -120,13 +120,13 @@
// if run on Unix, we can do restart
try {
instance = new UnixLifecycle();
} catch (final IOException e) {
LOGGER.log(Level.WARNING, "Failed to install embedded lifecycle implementation", e);
} catch (final Throwable t) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code, since this constructor could never in fact throw IOException, but I thought it best to keep this fallback since any unanticipated errors here should not be fatal.

LOGGER.log(Level.WARNING, "Failed to install embedded lifecycle implementation", t);

Check warning on line 124 in core/src/main/java/hudson/lifecycle/Lifecycle.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 123-124 are not covered by tests
instance = new Lifecycle() {
@Override
public void verifyRestartable() throws RestartNotSupportedException {
throw new RestartNotSupportedException(
"Failed to install embedded lifecycle implementation, so cannot restart: " + e, e);
"Failed to install embedded lifecycle implementation, so cannot restart: " + t, t);
}
};
}
Expand Down
20 changes: 10 additions & 10 deletions core/src/main/java/hudson/lifecycle/UnixLifecycle.java
Expand Up @@ -31,6 +31,8 @@

import com.sun.jna.Native;
import com.sun.jna.StringArray;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Functions;
import hudson.Platform;
import java.io.IOException;
import java.util.List;
Expand All @@ -50,16 +52,12 @@
* @since 1.304
*/
public class UnixLifecycle extends Lifecycle {

@NonNull
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can never be null, so annotate it as such.

private List<String> args;
private Throwable failedToObtainArgs;

public UnixLifecycle() throws IOException {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can never throw IOException, so stop declaring it.

try {
args = JavaVMArguments.current();
} catch (UnsupportedOperationException | LinkageError e) {
// can't restart / see JENKINS-3875
failedToObtainArgs = e;
}
Comment on lines -57 to -62
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was based on the old implementation, which used Akuma. That was ripped out a long time ago, and these exceptions shouldn't be thrown in the current implementation. But just to be on the safe side, we're now catching Throwable in the caller, so this shouldn't result in a regression in any case.

public UnixLifecycle() {
args = JavaVMArguments.current();
}

@Override
Expand Down Expand Up @@ -89,6 +87,10 @@

@Override
public void verifyRestartable() throws RestartNotSupportedException {
if (!Functions.isGlibcSupported()) {

Check warning on line 90 in core/src/main/java/hudson/lifecycle/UnixLifecycle.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 90 is only partially covered, one branch is missing
throw new RestartNotSupportedException("Restart is not supported on platforms without libc");

Check warning on line 91 in core/src/main/java/hudson/lifecycle/UnixLifecycle.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 91 is not covered by tests
}
Comment on lines +90 to +92
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix for JENKINS-72833: do not attempt to use UnixLifecycle if JNA can't make calls to libc.


// see http://lists.apple.com/archives/cocoa-dev/2005/Oct/msg00836.html and
// http://factor-language.blogspot.com/2007/07/execve-returning-enotsup-on-mac-os-x.html
// on Mac, execv fails with ENOTSUP if the caller is multi-threaded, resulting in an error like
Expand All @@ -97,8 +99,6 @@
// according to http://www.mail-archive.com/wine-devel@winehq.org/msg66797.html this now works on Snow Leopard
if (Platform.isDarwin() && !Platform.isSnowLeopardOrLater())
throw new RestartNotSupportedException("Restart is not supported on Mac OS X");
if (args == null)
throw new RestartNotSupportedException("Failed to obtain the command line arguments of the process", failedToObtainArgs);
Comment on lines -100 to -101
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code, since args can never be null.

}

private static final Logger LOGGER = Logger.getLogger(UnixLifecycle.class.getName());
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/jenkins/util/JavaVMArguments.java
@@ -1,6 +1,6 @@
package jenkins.util;

import com.google.common.primitives.Ints;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Functions;
import hudson.util.ProcessTree;
import java.lang.management.ManagementFactory;
Expand All @@ -20,6 +20,7 @@ public class JavaVMArguments {
/**
* Gets the process argument list of the current process.
*/
@NonNull
public static List<String> current() {
ProcessHandle.Info info = ProcessHandle.current().info();
if (info.command().isPresent() && info.arguments().isPresent()) {
Expand All @@ -30,7 +31,7 @@ public static List<String> current() {
return args;
} else if (Functions.isGlibcSupported()) {
// Native approach
int pid = Ints.checkedCast(ProcessHandle.current().pid());
int pid = Math.toIntExact(ProcessHandle.current().pid());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary use of Guava.

ProcessTree.OSProcess process = ProcessTree.get().get(pid);
if (process != null) {
List<String> args = process.getArguments();
Expand Down