# HG changeset patch # User Simon Tooke # Date 1494479022 14400 # Node ID 3b82970e37a4b8119471241cfdeeb5ef9778ed38 # Parent 9d83a097c50cbbdf50d2bb4f02153b97504a8db3 This patch adds a thread to the command-channel process checking that its parent agent process is still running. On Windows, the death of a parent doesn't kill its child processes. Once the parent process no long exists, the new thread will exit the current process. The process watcher thread does not start on Linux. diff -r 9d83a097c50c -r 3b82970e37a4 agent/command-server/src/main/java/com/redhat/thermostat/agent/command/server/internal/CommandChannelServerMain.java --- a/agent/command-server/src/main/java/com/redhat/thermostat/agent/command/server/internal/CommandChannelServerMain.java Fri Apr 14 11:23:45 2017 -0400 +++ b/agent/command-server/src/main/java/com/redhat/thermostat/agent/command/server/internal/CommandChannelServerMain.java Thu May 11 01:03:42 2017 -0400 @@ -43,6 +43,7 @@ import com.redhat.thermostat.agent.ipc.client.ClientIPCService; import com.redhat.thermostat.agent.ipc.client.ClientIPCServiceFactory; import com.redhat.thermostat.agent.ipc.client.IPCMessageChannel; +import com.redhat.thermostat.common.portability.ProcessWatcher; import com.redhat.thermostat.shared.config.NativeLibraryResolver; import com.redhat.thermostat.shared.config.OS; import com.redhat.thermostat.shared.config.SSLConfiguration; @@ -52,7 +53,11 @@ static final String IPC_SERVER_NAME = "command-channel"; static final String CONFIG_FILE_PROP = "ipcConfigFile"; - + + private static final int HOSTNAME_ARG_POS = 0; + private static final int HOSTPORT_ARG_POS = 1; + private static final int PARENT_PID_ARG_POS = 2; + private static SSLConfigurationParser sslConfParser = new SSLConfigurationParser(); private static ServerCreator serverCreator = new ServerCreator(); private static ShutdownHookHandler shutdownHandler = new ShutdownHookHandler(); @@ -62,13 +67,13 @@ // TODO Add some keep alive check public static void main(String[] args) throws IOException { - if (args.length != 2) { - throw new IOException("usage: thermostat-command-channel "); + if (args.length != 2 && args.length != 3) { + throw new IOException("usage: thermostat-command-channel []"); } - String hostname = args[0]; + String hostname = args[HOSTNAME_ARG_POS]; Integer port; try { - port = Integer.valueOf(args[1]); + port = Integer.valueOf(args[HOSTPORT_ARG_POS]); } catch (NumberFormatException e) { throw new IOException("Port number must be a valid integer"); } @@ -89,7 +94,22 @@ } // Connect to IPC server IPCMessageChannel channel = ipcService.connectToServer(IPC_SERVER_NAME); - + + + // if there's a parent pid, watch for it to exit and then shutdown. + final int parentPid = (args.length == 3) ? Integer.parseInt(args[PARENT_PID_ARG_POS]) : 0; + final int SLEEP_TIME_MS = 5000; // 5 seconds between checks + if (parentPid > 0) { + final ProcessWatcher watcher = new ProcessWatcher(parentPid, SLEEP_TIME_MS) { + @Override + public void onProcessExit() { + // tell myself to exit + System.exit(1); + } + }; + watcher.start(); + } + try { // Notify server has started sendMessage(channel, CommandChannelConstants.SERVER_STARTED_TOKEN); diff -r 9d83a097c50c -r 3b82970e37a4 agent/command/pom.xml --- a/agent/command/pom.xml Fri Apr 14 11:23:45 2017 -0400 +++ b/agent/command/pom.xml Thu May 11 01:03:42 2017 -0400 @@ -131,6 +131,43 @@ + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy + generate-resources + + copy-resources + + + true + ${project.build.directory} + + + ../../common/portability/target + + ${sharedlib.prefix}thermostat-common-portability${sharedlib.suffix} + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.build.directory} + + + diff -r 9d83a097c50c -r 3b82970e37a4 agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java --- a/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java Fri Apr 14 11:23:45 2017 -0400 +++ b/agent/command/src/main/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegate.java Thu May 11 01:03:42 2017 -0400 @@ -50,6 +50,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.redhat.thermostat.common.portability.PortableProcessFactory; import org.apache.commons.codec.binary.Base64; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -230,7 +231,7 @@ ? new String[]{ binPath.getAbsolutePath() + File.separator + CMD_NAME, hostname, String.valueOf(port), ipcConfig.getAbsolutePath() } : new String[] { "cmd", "/c", binPath.getAbsolutePath() + File.separator + CMD_NAME + ".cmd", hostname, - String.valueOf(port), ipcConfig.getAbsolutePath() }; + String.valueOf(port), ipcConfig.getAbsolutePath(), "" + PortableProcessFactory.getInstance().getCurrentProcessPid()}; ProcessBuilder builder = new ProcessBuilder(processArgs); // This has the problem of some messages/Exceptions not diff -r 9d83a097c50c -r 3b82970e37a4 agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java --- a/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java Fri Apr 14 11:23:45 2017 -0400 +++ b/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/CommandChannelDelegateTest.java Thu May 11 01:03:42 2017 -0400 @@ -58,6 +58,7 @@ import java.util.List; import java.util.concurrent.CountDownLatch; +import com.redhat.thermostat.common.portability.PortableProcessFactory; import org.apache.commons.codec.binary.Base64; import org.junit.Before; import org.junit.Test; @@ -277,14 +278,16 @@ }; // in Windows we need to ensure the drive letter appears - by calling getAbsolutePath() - String[] winArgs = new String[] { + // avoid this call in non-windows to simplify test setup + String[] winArgs = OS.IS_WINDOWS ? new String[] { "cmd", "/c", new File("/path/to/thermostat/home/thermostat-command-channel.cmd").getAbsolutePath(), "127.0.0.1", "123", - new File("/path/to/ipc/config").getAbsolutePath() - }; + new File("/path/to/ipc/config").getAbsolutePath(), + Integer.toString(PortableProcessFactory.getInstance().getCurrentProcessPid()) + } : null; final String[] expectedArgs = OS.IS_UNIX ? linuxArgs : winArgs; diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/Makefile --- a/common/portability/Makefile Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/Makefile Thu May 11 01:03:42 2017 -0400 @@ -30,9 +30,9 @@ INCLUDE = -I $(TARGET_DIR) -I "$(JAVA_HOME)/include/" -I "$(JAVA_HOME)/include/$(JNI_PLATFORM)" -HOSTNAME_SOURCES = src/main/native/HostName.c -HOSTNAME_TARGET = $(TARGET_DIR)/HostName.c -HOSTNAME_OBJECTS = $(HOSTNAME_TARGET:.c=.o) +POSIX_HELPER_SOURCES = src/main/native/PosixHelperImpl.c +POSIX_HELPER_TARGET = $(TARGET_DIR)/PosixHelperImpl.c +POSIX_HELPER_OBJECTS = $(POSIX_HELPER_TARGET:.c=.o) USERNAME_SOURCES = src/main/native/UserNameUtilImpl.c USERNAME_TARGET = $(TARGET_DIR)/UserNameUtilImpl.c @@ -53,7 +53,7 @@ EXECUTABLES = $(EXECUTABLE) .PHONY:UserNameUtilImpl -JNI_LIST = com.redhat.thermostat.common.portability.HostName com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl +JNI_LIST = com.redhat.thermostat.common.portability.internal.PosixHelperImpl com.redhat.thermostat.common.portability.internal.linux.UserNameUtilImpl ifeq ($(JNI_PLATFORM),win32) JNI_LIST += com.redhat.thermostat.common.portability.internal.windows.WindowsHelperImpl @@ -67,19 +67,18 @@ $(JNI_LIST): $(JAVAH) -force -classpath $(CLASSPATH) -d $(TARGET_DIR) $(JNI_LIST) -all: $(JNI_LIST) init $(HOSTNAME_SOURCES) $(USERNAME_SOURCES) $(HELPER_SOURCES) $(EXECUTABLES) +all: $(JNI_LIST) init $(POSIX_HELPER_SOURCES) $(USERNAME_SOURCES) $(HELPER_SOURCES) $(EXECUTABLES) .PHONY: init: - $(COPY) $(HOSTNAME_SOURCES) $(HOSTNAME_TARGET) + $(COPY) $(POSIX_HELPER_SOURCES) $(POSIX_HELPER_TARGET) $(COPY) $(USERNAME_SOURCES) $(USERNAME_TARGET) ifneq ($(strip $(HELPER_SOURCES)),) $(COPY) $(HELPER_SOURCES) $(HELPER_TARGET) endif -$(EXECUTABLE): $(HOSTNAME_OBJECTS) $(USERNAME_OBJECTS) $(HELPER_OBJECTS) - $(CC) $(MYLDFLAGS) $(LDFLAGS) $(HOSTNAME_OBJECTS) $(USERNAME_OBJECTS) $(HELPER_OBJECTS) $(PLATFORM_LIBS) $(HELPER_LIBS) -o $(TARGET_DIR)/$@ - +$(EXECUTABLE): $(POSIX_HELPER_OBJECTS) $(USERNAME_OBJECTS) $(HELPER_OBJECTS) + $(CC) $(MYLDFLAGS) $(LDFLAGS) $(POSIX_HELPER_OBJECTS) $(USERNAME_OBJECTS) $(HELPER_OBJECTS) $(PLATFORM_LIBS) $(HELPER_LIBS) -o $(TARGET_DIR)/$@ .c.o: $(CC) $(MYCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@ @@ -91,7 +90,7 @@ rm -f $(TARGET_DIR)/$(EXECUTABLE) clean-obj: - rm -f $(HOSTNAME_OBJECTS) + rm -f $(POSIX_HELPER_OBJECTS) rm -f $(USERNAME_OBJECTS) rm -f $(HELPER_OBJECTS) diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/HostName.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/HostName.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/HostName.java Thu May 11 01:03:42 2017 -0400 @@ -37,16 +37,17 @@ package com.redhat.thermostat.common.portability; import com.redhat.thermostat.common.portability.internal.PortableNativeLibraryLoader; +import com.redhat.thermostat.common.portability.internal.PosixHelperImpl; /** * Finds the current host name without doing a DNS lookup */ public class HostName extends PortableNativeLibraryLoader { + private static PosixHelperImpl helper = new PosixHelperImpl(); + public static String getLocalHostName() { - return getHostName(); + return helper.getLocalHostName(); } - - private static native String getHostName(); } diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/PortableProcess.java Thu May 11 01:03:42 2017 -0400 @@ -59,4 +59,6 @@ boolean terminateProcess(int pid, boolean wait); boolean terminateProcess(int pid, int exitcode, int waitMillis); + + int getCurrentProcessPid(); } diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessWaiterMain.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessWaiterMain.java Thu May 11 01:03:42 2017 -0400 @@ -0,0 +1,64 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability; + +public class ProcessWaiterMain { + + private static final boolean verbose = false; + private static final int TICKTIME = 1000; + + public static void main(String args[]) { + for (String pidStr : args) { + final int pid = Integer.parseInt(pidStr); + if (pid != 0) { + ProcessWatcher watcher = new ProcessWatcher(pid, TICKTIME) { + @Override + public void onProcessExit() { + if (verbose) { + System.err.println("process " + pid + " no longer exists"); + } + } + }; + watcher.start(); + try { + watcher.join(); + } catch (InterruptedException ignored) { + } + } + } + } +} diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessWatcher.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/ProcessWatcher.java Thu May 11 01:03:42 2017 -0400 @@ -0,0 +1,70 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability; + +public abstract class ProcessWatcher extends Thread { + + private final int pidToWatch; + private final long sleepTimeMs; + private PortableProcess processChecker = PortableProcessFactory.getInstance(); + + protected ProcessWatcher(int pid, long sleepTimeMs) { + this.pidToWatch = pid; + this.sleepTimeMs = sleepTimeMs; + setName("process watcher"); + setDaemon(true); + } + + public void run() { + boolean parentIsRunning = true; + while (parentIsRunning) { + parentIsRunning = processChecker.exists(pidToWatch); + if (parentIsRunning) { + tick(); + try { + Thread.sleep(sleepTimeMs); + } catch (InterruptedException ignored) { + } + } + } + onProcessExit(); + } + + public void tick() {} + + abstract public void onProcessExit(); +} diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/PosixHelperImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/PosixHelperImpl.java Thu May 11 01:03:42 2017 -0400 @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.common.portability.internal; + +public class PosixHelperImpl { + + public int getCurrentProcessPid() { + return getCurrentProcessID0(); + } + + public String getLocalHostName() { + return getHostName0(); + } + + private static native int getCurrentProcessID0(); + private static native String getHostName0(); +} diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImpl.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableHostImpl.java Thu May 11 01:03:42 2017 -0400 @@ -45,9 +45,9 @@ import com.redhat.thermostat.common.Size; import com.redhat.thermostat.common.Size.Unit; -import com.redhat.thermostat.common.portability.HostName; import com.redhat.thermostat.common.portability.PortableHost; import com.redhat.thermostat.common.portability.PortableMemoryStat; +import com.redhat.thermostat.common.portability.internal.PosixHelperImpl; import com.redhat.thermostat.common.portability.internal.UnimplementedError; import com.redhat.thermostat.common.portability.linux.ProcDataSource; import com.redhat.thermostat.common.utils.LoggingUtils; @@ -86,7 +86,6 @@ } } - LinuxPortableHostImpl(ProcDataSource dataSource) { this.dataSource = dataSource; } @@ -145,7 +144,7 @@ // if fails, try to get hostname without dns lookup if (hostname == null) { - hostname = HostName.getLocalHostName(); + hostname = new PosixHelperImpl().getLocalHostName(); } // still null, use localhost diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/linux/LinuxPortableProcessImpl.java Thu May 11 01:03:42 2017 -0400 @@ -42,6 +42,7 @@ import com.redhat.thermostat.common.portability.PortableProcessStat; import com.redhat.thermostat.common.portability.PortableVmIoStat; import com.redhat.thermostat.common.portability.ProcessChecker; +import com.redhat.thermostat.common.portability.internal.PosixHelperImpl; import com.redhat.thermostat.common.portability.internal.UnimplementedError; import com.redhat.thermostat.common.portability.internal.linux.vmio.LinuxVmIoStatBuilderImpl; import com.redhat.thermostat.common.portability.internal.linux.vmio.ProcIoDataReader; @@ -54,6 +55,7 @@ private LinuxPortableProcessStatBuilderImpl procStatHelper; private LinuxProcessEnvironmentBuilderImpl procEnvHelper; private LinuxVmIoStatBuilderImpl vmioHelper; + private PosixHelperImpl posixHelper; public static LinuxPortableProcessImpl INSTANCE = new LinuxPortableProcessImpl(new SystemClock(), new ProcDataSource()); @@ -65,6 +67,7 @@ procStatHelper = new LinuxPortableProcessStatBuilderImpl(dataSource); procEnvHelper = new LinuxProcessEnvironmentBuilderImpl(dataSource); vmioHelper = new LinuxVmIoStatBuilderImpl(clock, new ProcIoDataReader(dataSource)); + posixHelper = new PosixHelperImpl(); } @Override @@ -111,4 +114,9 @@ public boolean terminateProcess(int pid, int exitcode, int waitMillis) { throw new UnimplementedError("terminateProcess()"); } + + @Override + public int getCurrentProcessPid() { + return posixHelper.getCurrentProcessPid(); + } } diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/macos/MacOSProcessImpl.java Thu May 11 01:03:42 2017 -0400 @@ -40,6 +40,7 @@ import com.redhat.thermostat.common.portability.PortableProcess; import com.redhat.thermostat.common.portability.PortableProcessStat; import com.redhat.thermostat.common.portability.PortableVmIoStat; +import com.redhat.thermostat.common.portability.internal.PosixHelperImpl; import java.util.Map; @@ -47,6 +48,7 @@ public static final MacOSProcessImpl INSTANCE = new MacOSProcessImpl(); private static final MacOSHelperImpl helper = MacOSHelperImpl.INSTANCE; + private PosixHelperImpl posixHelper = new PosixHelperImpl(); @Override public boolean exists(int pid) { @@ -95,4 +97,9 @@ public boolean terminateProcess(int pid, int exitcode, int waitMillis) { return helper.terminateProcess(pid, exitcode, waitMillis); } + + @Override + public int getCurrentProcessPid() { + return posixHelper.getCurrentProcessPid(); + } } diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsHelperImpl.java Thu May 11 01:03:42 2017 -0400 @@ -147,11 +147,7 @@ } public boolean exists(int pid) { - final long hnd = getLimitedProcessHandle0(pid); - if (hnd != 0) { - closeHandle0(hnd); - } - return hnd != 0; + return exists0(pid) != 0; } public String getUserName(int pid) { @@ -328,6 +324,7 @@ private static native Object getEnvironment0(long hProcess, int mode); // mode = 0 returns DirectByteBuffer, 1 = String cwd, 2 = String execuatable, 3 = String command line private static native boolean getProcessInfo0(int pid, long[] info); private static native boolean getProcessIOInfo0(int pid, long[] info); + private static native int exists0(int pid); private static native int getCurrentProcessID0(); private static native long getCurrentProcessHandle0(); diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java --- a/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/java/com/redhat/thermostat/common/portability/internal/windows/WindowsPortableProcessImpl.java Thu May 11 01:03:42 2017 -0400 @@ -101,4 +101,9 @@ public boolean terminateProcess(int pid, int exitcode, int waitMillis) { return helper.terminateProcess(pid, exitcode, waitMillis); } + + @Override + public int getCurrentProcessPid() { + return helper.getCurrentProcessPid(); + } } diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/native/HostName.c --- a/common/portability/src/main/native/HostName.c Fri Apr 14 11:23:45 2017 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2017 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat 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; either version 2, or (at your - * option) any later version. - * - * Thermostat 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 Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -#include "com_redhat_thermostat_common_portability_HostName.h" - -#include -#include -#include - -#if !defined(_WIN32) -# include -#else // windows -# include -#endif - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif /* NI_MAXHOST */ - -JNIEXPORT jstring JNICALL -Java_com_redhat_thermostat_common_portability_HostName_getHostName - (JNIEnv *env, jclass HostNameClass) -{ - char hostname[NI_MAXHOST]; - memset(hostname, 0, sizeof(hostname)); - - if (gethostname(hostname, sizeof(hostname)) == 0) { - return (*env)->NewStringUTF(env, hostname); - } - return NULL; -} - diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/native/PosixHelperImpl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/portability/src/main/native/PosixHelperImpl.c Thu May 11 01:03:42 2017 -0400 @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2017 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat 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; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +#include "com_redhat_thermostat_common_portability_internal_PosixHelperImpl.h" + +#include +#include +#include + +#if !defined(_WIN32) +# include +#else // windows +# include +#endif + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif /* NI_MAXHOST */ + +JNIEXPORT jstring JNICALL +Java_com_redhat_thermostat_common_portability_internal_PosixHelperImpl_getHostName0 + (JNIEnv *env, jclass HostNameClass) +{ + char hostname[NI_MAXHOST]; + memset(hostname, 0, sizeof(hostname)); + + if (gethostname(hostname, sizeof(hostname)) == 0) { + return (*env)->NewStringUTF(env, hostname); + } + return NULL; +} + + +JNIEXPORT jint JNICALL +Java_com_redhat_thermostat_common_portability_internal_PosixHelperImpl_getCurrentProcessID0 + (JNIEnv *env, jclass posixHelperClass) +{ + return (jint)getpid(); +} diff -r 9d83a097c50c -r 3b82970e37a4 common/portability/src/main/native/WindowsHelperImpl.c --- a/common/portability/src/main/native/WindowsHelperImpl.c Fri Apr 14 11:23:45 2017 -0400 +++ b/common/portability/src/main/native/WindowsHelperImpl.c Thu May 11 01:03:42 2017 -0400 @@ -930,6 +930,30 @@ /* * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl + * Method: exists0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl_exists0 + (JNIEnv *env, jclass winHelperClass, jint pid) { + + if (pid == 0) + return 1; + HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid); + if (hProcess == 0) + return 0; + LPDWORD ret = 0; + int rc = GetExitCodeProcess(hProcess, &ret); + CloseHandle(hProcess); + if (rc) { + return ret == STILL_ACTIVE; + } + else { + return 0; + } +} + +/* + * Class: com_redhat_thermostat_common_portability_internal_windows_WindowsHelperImpl * Method: closeHandle0 * Signature: (J)V */ diff -r 9d83a097c50c -r 3b82970e37a4 distribution/scripts/thermostat-command-channel --- a/distribution/scripts/thermostat-command-channel Fri Apr 14 11:23:45 2017 -0400 +++ b/distribution/scripts/thermostat-command-channel Thu May 11 01:03:42 2017 -0400 @@ -61,6 +61,7 @@ IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/thermostat-shared-config-@project.version@.jar" IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/thermostat-agent-command-@project.version@.jar" IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/thermostat-common-command-@project.version@.jar" +IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/thermostat-common-portability-@project.version@.jar" IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/thermostat-agent-command-server-@project.version@.jar" IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/netty-buffer-@netty.version@.jar" IPC_CLASSPATH="${IPC_CLASSPATH}:${THERMOSTAT_LIBS}/netty-common-@netty.version@.jar" diff -r 9d83a097c50c -r 3b82970e37a4 distribution/windows/scripts/thermostat-command-channel.cmd --- a/distribution/windows/scripts/thermostat-command-channel.cmd Fri Apr 14 11:23:45 2017 -0400 +++ b/distribution/windows/scripts/thermostat-command-channel.cmd Thu May 11 01:03:42 2017 -0400 @@ -36,13 +36,13 @@ setlocal -if "%3"=="" goto usage -if not "%4"=="" goto usage +if "%4"=="" goto usage +if not "%5"=="" goto usage goto skipfuncdefs :usage - echo "usage: %~f0 " + echo "usage: %~f0 " exit /b 1 :skipfuncdefs @@ -50,6 +50,7 @@ set HOSTNAME=%1 set PORT=%2 set CONFIG_FILE=%3 +set PARENT_PID=%4 :: Source thermostat-ipc-client-common from same directory as this script :: Defines IPC_CLASSPATH variable with JARs necessary for the IPC service @@ -68,6 +69,7 @@ set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-shared-config-@project.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-agent-command-@project.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-common-command-@project.version@.jar +set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-common-portability-@project.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\thermostat-agent-command-server-@project.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\netty-buffer-@netty.version@.jar set IPC_CLASSPATH=%IPC_CLASSPATH%;%THERMOSTAT_LIBS%\netty-common-@netty.version@.jar @@ -87,7 +89,7 @@ :: Start server set CONFIG_FILE_ARG=-DipcConfigFile=%CONFIG_FILE% -%JAVA% %CONFIG_FILE_ARG% %LOGGING_ARGS% -cp %IPC_CLASSPATH% %DEBUG_OPTS% %CMD_CHANNEL_CLASS% %HOSTNAME% %PORT% +%JAVA% %CONFIG_FILE_ARG% %LOGGING_ARGS% -cp %IPC_CLASSPATH% %DEBUG_OPTS% %CMD_CHANNEL_CLASS% %HOSTNAME% %PORT% %PARENT_PID% diff -r 9d83a097c50c -r 3b82970e37a4 integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java --- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java Fri Apr 14 11:23:45 2017 -0400 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java Thu May 11 01:03:42 2017 -0400 @@ -81,6 +81,8 @@ Spawn service = spawnResult.spawn; try { + + service.expect("Agent started."); // Give agent some time to startup before killing it Thread.sleep(2000l);