Files
sheepit-shadow-nabber/src/com/sheepit/client/os/Linux.java

278 lines
8.2 KiB
Java
Raw Normal View History

/*
* Copyright (C) 2010-2014 Laurent CLOUET
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sheepit.client.os;
Fix: EEVEE renders with CPU instead of GPU in Linux clients (#229) * Fix: EEVEE renders with CPU instead of GPU in Linux clients In Linux systems, setting the env LD_LIBRARY_PATH var to point the /lib folder included in the sheepit binary compressed .zip, mandates Blender to swap whatever openGL library is already in use by the OS. Modern GPU drivers install their own optimised version of the OpenGL library and replacing it creates incompatibilities that avoid EEVEE to run. To detect if Blender already uses the standard OS provided OpenGL library is via _ldd_ Linux command. The execution in a system with OpenGL libraries already in use delivers an output similar to this: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fefefb9c000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) While a system with no OS OpenGL libraries that requires the shipped default OpenGL lib to work returns this instead: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => not found libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) In the former case, the SheepIt client will set the LD_LIBRARY_PATH env var to point the /lib folder to allow Blender to execute properly.
2020-05-25 06:12:02 +10:00
import java.io.BufferedReader;
import java.io.File;
Fix: EEVEE renders with CPU instead of GPU in Linux clients (#229) * Fix: EEVEE renders with CPU instead of GPU in Linux clients In Linux systems, setting the env LD_LIBRARY_PATH var to point the /lib folder included in the sheepit binary compressed .zip, mandates Blender to swap whatever openGL library is already in use by the OS. Modern GPU drivers install their own optimised version of the OpenGL library and replacing it creates incompatibilities that avoid EEVEE to run. To detect if Blender already uses the standard OS provided OpenGL library is via _ldd_ Linux command. The execution in a system with OpenGL libraries already in use delivers an output similar to this: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fefefb9c000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) While a system with no OS OpenGL libraries that requires the shipped default OpenGL lib to work returns this instead: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => not found libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) In the former case, the SheepIt client will set the LD_LIBRARY_PATH env var to point the /lib folder to allow Blender to execute properly.
2020-05-25 06:12:02 +10:00
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import com.sheepit.client.Log;
import com.sheepit.client.hardware.cpu.CPU;
public class Linux extends OS {
private final String NICE_BINARY_PATH = "nice";
private Boolean hasNiceBinary;
public Linux() {
super();
this.hasNiceBinary = null;
}
public String name() {
return "linux";
}
@Override
public String getRenderBinaryPath() {
return "rend.exe";
}
@Override
public CPU getCPU() {
CPU ret = new CPU();
try {
String filePath = "/proc/cpuinfo";
Scanner scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("model name")) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setName(buf[1].trim());
}
}
if (line.startsWith("cpu family")) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setFamily(buf[1].trim());
}
}
if (line.startsWith("model") && line.startsWith("model name") == false) {
String buf[] = line.split(":");
if (buf.length > 1) {
ret.setModel(buf[1].trim());
}
}
}
scanner.close();
}
catch (java.lang.NoClassDefFoundError e) {
2015-03-02 18:03:58 +00:00
System.err.println("OS.Linux::getCPU error " + e + " mostly because Scanner class was introduced by Java 5 and you are running a lower version");
}
catch (Exception e) {
e.printStackTrace();
}
return ret;
}
@Override
public long getMemory() {
try {
String filePath = "/proc/meminfo";
Scanner scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("MemTotal")) {
String buf[] = line.split(":");
if (buf.length > 0) {
Integer buf2 = new Integer(buf[1].trim().split(" ")[0]);
return (((buf2 / 262144) + 1) * 262144); // 256*1024 = 262144
}
}
}
scanner.close();
}
catch (java.lang.NoClassDefFoundError e) {
2014-12-23 20:05:29 +01:00
System.err.println("Machine::type error " + e + " mostly because Scanner class was introducted by Java 5 and you are running a lower version");
}
catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public long getFreeMemory() {
try {
String filePath = "/proc/meminfo";
Scanner scanner = new Scanner(new File(filePath));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("MemAvailable")) {
String buf[] = line.split(":");
if (buf.length > 0) {
Integer buf2 = new Integer(buf[1].trim().split(" ")[0]);
return (((buf2 / 262144) + 1) * 262144); // 256*1024 = 262144
}
}
}
scanner.close();
}
catch (java.lang.NoClassDefFoundError e) {
System.err.println("OS::Linux::getFreeMemory error " + e + " mostly because Scanner class was introducted by Java 5 and you are running a lower version");
}
catch (Exception e) {
e.printStackTrace();
}
return 0;
}
@Override
public String getCUDALib() {
return "cuda";
}
@Override
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
Map<String, String> new_env = new HashMap<String, String>();
new_env.putAll(java.lang.System.getenv()); // clone the env
Fix: EEVEE renders with CPU instead of GPU in Linux clients (#229) * Fix: EEVEE renders with CPU instead of GPU in Linux clients In Linux systems, setting the env LD_LIBRARY_PATH var to point the /lib folder included in the sheepit binary compressed .zip, mandates Blender to swap whatever openGL library is already in use by the OS. Modern GPU drivers install their own optimised version of the OpenGL library and replacing it creates incompatibilities that avoid EEVEE to run. To detect if Blender already uses the standard OS provided OpenGL library is via _ldd_ Linux command. The execution in a system with OpenGL libraries already in use delivers an output similar to this: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fefefb9c000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) While a system with no OS OpenGL libraries that requires the shipped default OpenGL lib to work returns this instead: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => not found libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) In the former case, the SheepIt client will set the LD_LIBRARY_PATH env var to point the /lib folder to allow Blender to execute properly.
2020-05-25 06:12:02 +10:00
// if Blender is already loading an OpenGL library, don't need to load Blender's default one (it will
// create system incompatibilities). If no OpenGL library is found, then load the one included in the binary
// zip file
if (isOpenGLAreadyInstalled(command.get(0)) == false) {
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
if (has_ld_library_path == false) {
new_env.put("LD_LIBRARY_PATH", lib_dir);
}
else {
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
}
}
List<String> actual_command = command;
if (this.hasNiceBinary == null) {
this.checkNiceAvailability();
}
if (this.hasNiceBinary.booleanValue()) {
// launch the process in lowest priority
if (env_overight != null) {
actual_command.add(0, env_overight.get("PRIORITY"));
}
else {
actual_command.add(0, "19");
}
actual_command.add(0, "-n");
actual_command.add(0, NICE_BINARY_PATH);
}
else {
2015-01-05 23:05:45 +01:00
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
}
ProcessBuilder builder = new ProcessBuilder(actual_command);
builder.redirectErrorStream(true);
Map<String, String> env = builder.environment();
env.putAll(new_env);
if (env_overight != null) {
env.putAll(env_overight);
}
return builder.start();
}
@Override
public boolean getSupportHighPriority() {
// only the root user can create process with high (negative nice) value
String logname = System.getenv("LOGNAME");
String user = System.getenv("USER");
if ((logname != null && logname.equals("root")) || (user != null && user.equals("root"))) {
return true;
}
return false;
}
protected void checkNiceAvailability() {
ProcessBuilder builder = new ProcessBuilder();
builder.command(NICE_BINARY_PATH);
builder.redirectErrorStream(true);
Process process = null;
try {
process = builder.start();
this.hasNiceBinary = true;
}
catch (IOException e) {
this.hasNiceBinary = false;
2015-01-05 23:05:45 +01:00
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
}
finally {
if (process != null) {
process.destroy();
}
}
}
Fix: EEVEE renders with CPU instead of GPU in Linux clients (#229) * Fix: EEVEE renders with CPU instead of GPU in Linux clients In Linux systems, setting the env LD_LIBRARY_PATH var to point the /lib folder included in the sheepit binary compressed .zip, mandates Blender to swap whatever openGL library is already in use by the OS. Modern GPU drivers install their own optimised version of the OpenGL library and replacing it creates incompatibilities that avoid EEVEE to run. To detect if Blender already uses the standard OS provided OpenGL library is via _ldd_ Linux command. The execution in a system with OpenGL libraries already in use delivers an output similar to this: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007fefefb9c000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) While a system with no OS OpenGL libraries that requires the shipped default OpenGL lib to work returns this instead: ldd rend.exe linux-vdso.so.1 (0x00007ffda6bf9000) ... libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fefefe3a000) libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fefefc30000) libGL.so.1 => not found libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fefefa4d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fefef85c000) ... libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fefef6e7000) In the former case, the SheepIt client will set the LD_LIBRARY_PATH env var to point the /lib folder to allow Blender to execute properly.
2020-05-25 06:12:02 +10:00
protected boolean isOpenGLAreadyInstalled(String pathToRendEXE) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("bash", "-c", "ldd '" + pathToRendEXE + "'"); // support for paths with an space
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
StringBuilder screenOutput = new StringBuilder();
while ((line = reader.readLine()) != null) {
// check the shared libraries that Blender is loading at run time. If it already loads an existing
// version of OpenGL (ie the one shipped with NVIDIA drivers) then return false to avoid the client
// replacing them (and glitching the EEVEE render). Otherwise return true and load the /lib folder
// to ensure that Blender works correctly
if (line.toLowerCase().contains("libgl.so")) {
return !line.toLowerCase().contains("not found");
}
// In case of error we can later check the screen output from ldd
screenOutput.append(line);
}
int exitCode = process.waitFor();
if (exitCode != 0) {
System.err.println(String.format("ERROR Linux::isOpenGLAreadyInstalled Unable to execute ldd command. Exit code %d", exitCode));
System.err.println(String.format("Screen output from ldd execution: %s", screenOutput.toString()));
}
}
catch (IOException e) {
System.err.println(String.format("ERROR Linux::isOpenGLAreadyInstalled Unable to execute ldd command. IOException %s", e.getMessage()));
}
catch (InterruptedException e) {
System.err.println(String.format("ERROR Linux::isOpenGLAreadyInstalled Unable to execute ldd command. InterruptedException %s", e.getMessage()));
}
return false;
}
}