From da2d22df98a5ede9cb98f354c3d02965d36f6654 Mon Sep 17 00:00:00 2001 From: Dennis Roppelt Date: Tue, 10 May 2022 22:05:38 +0200 Subject: [PATCH] replace shell call with a file based detection + user opt in/out (facebook#9956) --- .../java/org/rocksdb/util/Environment.java | 31 +++++++++++++------ .../org/rocksdb/util/EnvironmentTest.java | 25 ++++++++++++++- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/java/src/main/java/org/rocksdb/util/Environment.java b/java/src/main/java/org/rocksdb/util/Environment.java index 5da471f18..18b75d2de 100644 --- a/java/src/main/java/org/rocksdb/util/Environment.java +++ b/java/src/main/java/org/rocksdb/util/Environment.java @@ -1,21 +1,14 @@ // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. package org.rocksdb.util; +import java.io.File; import java.io.IOException; public class Environment { private static String OS = System.getProperty("os.name").toLowerCase(); private static String ARCH = System.getProperty("os.arch").toLowerCase(); - private static boolean MUSL_LIBC; - - static { - try { - final Process p = new ProcessBuilder("/usr/bin/env", "sh", "-c", "ldd /usr/bin/env | grep -q musl").start(); - MUSL_LIBC = p.waitFor() == 0; - } catch (final IOException | InterruptedException e) { - MUSL_LIBC = false; - } - } + private static String MUSL_ENVIRONMENT = System.getenv("ROCKSDB_ENVIRONMENT_MUSL"); + private static Boolean MUSL_LIBC; public static boolean isAarch64() { return ARCH.contains("aarch64"); @@ -50,10 +43,28 @@ public class Environment { OS.contains("nux"); } + /** + * lazy evaluation to prevent OS calls when "is this musl?" is not necessary + * no need to have a windows box report suspicious behaviour that the jvm attempts IO on unix paths + */ public static boolean isMuslLibc() { + if(MUSL_LIBC == null) MUSL_LIBC = resolveIsMuslLibc(); return MUSL_LIBC; } + static boolean resolveIsMuslLibc() { + // explicit user input in case any below calls cause issues in their environment + if("true".equalsIgnoreCase(MUSL_ENVIRONMENT)) return true; + if("false".equalsIgnoreCase(MUSL_ENVIRONMENT)) return false; + if(!isUnix()) return false; // not unix therefore not musl + File[] allFilesInLib = new File("/lib/").listFiles(); + if(allFilesInLib == null) return false; + for(File f : allFilesInLib) { + if(f.getPath().startsWith("/lib/libc.musl")) return true; + } + return false; + } + public static boolean isSolaris() { return OS.contains("sunos"); } diff --git a/java/src/test/java/org/rocksdb/util/EnvironmentTest.java b/java/src/test/java/org/rocksdb/util/EnvironmentTest.java index 301dec22f..755b75a36 100644 --- a/java/src/test/java/org/rocksdb/util/EnvironmentTest.java +++ b/java/src/test/java/org/rocksdb/util/EnvironmentTest.java @@ -5,27 +5,34 @@ package org.rocksdb.util; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.lang.reflect.Field; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.is; public class EnvironmentTest { private final static String ARCH_FIELD_NAME = "ARCH"; private final static String OS_FIELD_NAME = "OS"; + + private final static String MUSL_ENVIRONMENT_FIELD_NAME = "MUSL_ENVIRONMENT"; private final static String MUSL_LIBC_FIELD_NAME = "MUSL_LIBC"; + private static String INITIAL_OS; private static String INITIAL_ARCH; - private static boolean INITIAL_MUSL_LIBC; + private static String INITIAL_MUSL_ENVIRONMENT; + private static Boolean INITIAL_MUSL_LIBC; @BeforeClass public static void saveState() { INITIAL_ARCH = getEnvironmentClassField(ARCH_FIELD_NAME); INITIAL_OS = getEnvironmentClassField(OS_FIELD_NAME); INITIAL_MUSL_LIBC = getEnvironmentClassField(MUSL_LIBC_FIELD_NAME); + INITIAL_MUSL_ENVIRONMENT = getEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME); } @Test @@ -236,6 +243,21 @@ public class EnvironmentTest { setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false); } + @Test + public void resolveIsMuslLibc() { + setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, null); + setEnvironmentClassFields("win", "anyarch"); + assertThat(Environment.isUnix()).isFalse(); + + // with user input, will resolve to true if set as true. Even on OSs that appear absurd for musl. Users choice + assertThat(Environment.resolveIsMuslLibc()).isFalse(); + setEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME, "true"); + assertThat(Environment.resolveIsMuslLibc()).isTrue(); + setEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME, "false"); + assertThat(Environment.resolveIsMuslLibc()).isFalse(); + + } + private void setEnvironmentClassFields(String osName, String osArch) { setEnvironmentClassField(OS_FIELD_NAME, osName); @@ -246,6 +268,7 @@ public class EnvironmentTest { public static void restoreState() { setEnvironmentClassField(OS_FIELD_NAME, INITIAL_OS); setEnvironmentClassField(ARCH_FIELD_NAME, INITIAL_ARCH); + setEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME, INITIAL_MUSL_ENVIRONMENT); setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, INITIAL_MUSL_LIBC); }