Thu, 17 Oct 2013 09:40:51 -0700
Added tag jdk8-b112 for changeset 0ed9a90f45e1
allwin@5412 | 1 | /* |
allwin@5412 | 2 | * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. |
allwin@5412 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
allwin@5412 | 4 | * |
allwin@5412 | 5 | * This code is free software; you can redistribute it and/or modify it |
allwin@5412 | 6 | * under the terms of the GNU General Public License version 2 only, as |
allwin@5412 | 7 | * published by the Free Software Foundation. |
allwin@5412 | 8 | * |
allwin@5412 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
allwin@5412 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
allwin@5412 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
allwin@5412 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
allwin@5412 | 13 | * accompanied this code). |
allwin@5412 | 14 | * |
allwin@5412 | 15 | * You should have received a copy of the GNU General Public License version |
allwin@5412 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
allwin@5412 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
allwin@5412 | 18 | * |
allwin@5412 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
allwin@5412 | 20 | * or visit www.oracle.com if you need additional information or have any |
allwin@5412 | 21 | * questions. |
allwin@5412 | 22 | */ |
allwin@5412 | 23 | |
allwin@5412 | 24 | /* |
allwin@5412 | 25 | * @test |
allwin@5412 | 26 | * @bug 7162400 |
allwin@5412 | 27 | * @key regression |
allwin@5412 | 28 | * @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues |
allwin@5412 | 29 | * @library /testlibrary |
allwin@5412 | 30 | * @compile AttachWithStalePidFileTarget.java |
allwin@5412 | 31 | * @run main AttachWithStalePidFile |
allwin@5412 | 32 | */ |
allwin@5412 | 33 | |
allwin@5412 | 34 | import com.oracle.java.testlibrary.*; |
allwin@5412 | 35 | import com.sun.tools.attach.VirtualMachine; |
allwin@5412 | 36 | import sun.tools.attach.HotSpotVirtualMachine; |
allwin@5412 | 37 | import java.lang.reflect.Field; |
allwin@5412 | 38 | import java.nio.file.*; |
allwin@5412 | 39 | import java.nio.file.attribute.*; |
allwin@5412 | 40 | import java.io.*; |
allwin@5412 | 41 | |
allwin@5412 | 42 | public class AttachWithStalePidFile { |
allwin@5412 | 43 | public static void main(String... args) throws Exception { |
allwin@5412 | 44 | |
allwin@5412 | 45 | // this test is only valid on non-Windows platforms |
allwin@5412 | 46 | if(Platform.isWindows()) { |
allwin@5412 | 47 | System.out.println("This test is only valid on non-Windows platforms."); |
allwin@5412 | 48 | return; |
allwin@5412 | 49 | } |
allwin@5412 | 50 | |
allwin@5412 | 51 | // Since there might be stale pid-files owned by different |
allwin@5412 | 52 | // users on the system we may need to retry the test in case we |
allwin@5412 | 53 | // are unable to remove the existing file. |
allwin@5412 | 54 | int retries = 5; |
allwin@5412 | 55 | while(!runTest() && --retries > 0); |
allwin@5412 | 56 | |
allwin@5412 | 57 | if(retries == 0) { |
allwin@5412 | 58 | throw new RuntimeException("Test failed after 5 retries. " + |
allwin@5412 | 59 | "Remove any /tmp/.java_pid* files and retry."); |
allwin@5412 | 60 | } |
allwin@5412 | 61 | } |
allwin@5412 | 62 | |
allwin@5412 | 63 | public static boolean runTest() throws Exception { |
allwin@5412 | 64 | ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( |
allwin@5412 | 65 | "-XX:+UnlockDiagnosticVMOptions", "-XX:+PauseAtStartup", "AttachWithStalePidFileTarget"); |
allwin@5412 | 66 | Process target = pb.start(); |
allwin@5412 | 67 | Path pidFile = null; |
allwin@5412 | 68 | |
allwin@5412 | 69 | try { |
allwin@5412 | 70 | int pid = getUnixProcessId(target); |
allwin@5412 | 71 | |
allwin@5412 | 72 | // create the stale .java_pid file. use hard-coded /tmp path as in th VM |
allwin@5412 | 73 | pidFile = createJavaPidFile(pid); |
allwin@5412 | 74 | if(pidFile == null) { |
allwin@5412 | 75 | return false; |
allwin@5412 | 76 | } |
allwin@5412 | 77 | |
allwin@5412 | 78 | // wait for vm.paused file to be created and delete it once we find it. |
allwin@5412 | 79 | waitForAndResumeVM(pid); |
allwin@5412 | 80 | |
allwin@5412 | 81 | // unfortunately there's no reliable way to know the VM is ready to receive the |
allwin@5412 | 82 | // attach request so we have to do an arbitrary sleep. |
allwin@5412 | 83 | Thread.sleep(5000); |
allwin@5412 | 84 | |
allwin@5412 | 85 | HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString()); |
allwin@5412 | 86 | BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(vm.remoteDataDump())); |
allwin@5412 | 87 | String line = null; |
allwin@5412 | 88 | while((line = remoteDataReader.readLine()) != null); |
allwin@5412 | 89 | |
allwin@5412 | 90 | vm.detach(); |
allwin@5412 | 91 | return true; |
allwin@5412 | 92 | } |
allwin@5412 | 93 | finally { |
allwin@5412 | 94 | target.destroy(); |
allwin@5412 | 95 | target.waitFor(); |
allwin@5412 | 96 | |
allwin@5412 | 97 | if(pidFile != null && Files.exists(pidFile)) { |
allwin@5412 | 98 | Files.delete(pidFile); |
allwin@5412 | 99 | } |
allwin@5412 | 100 | } |
allwin@5412 | 101 | } |
allwin@5412 | 102 | |
allwin@5412 | 103 | private static Path createJavaPidFile(int pid) throws Exception { |
allwin@5412 | 104 | Path pidFile = Paths.get("/tmp/.java_pid" + pid); |
allwin@5412 | 105 | if(Files.exists(pidFile)) { |
allwin@5412 | 106 | try { |
allwin@5412 | 107 | Files.delete(pidFile); |
allwin@5412 | 108 | } |
allwin@5412 | 109 | catch(FileSystemException e) { |
allwin@5412 | 110 | if(e.getReason().equals("Operation not permitted")) { |
allwin@5412 | 111 | System.out.println("Unable to remove exisiting stale PID file" + pidFile); |
allwin@5412 | 112 | return null; |
allwin@5412 | 113 | } |
allwin@5412 | 114 | throw e; |
allwin@5412 | 115 | } |
allwin@5412 | 116 | } |
allwin@5412 | 117 | return Files.createFile(pidFile, |
allwin@5412 | 118 | PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------"))); |
allwin@5412 | 119 | } |
allwin@5412 | 120 | |
allwin@5412 | 121 | private static void waitForAndResumeVM(int pid) throws Exception { |
allwin@5412 | 122 | Path pauseFile = Paths.get("vm.paused." + pid); |
allwin@5412 | 123 | int retries = 60; |
allwin@5412 | 124 | while(!Files.exists(pauseFile) && --retries > 0) { |
allwin@5412 | 125 | Thread.sleep(1000); |
allwin@5412 | 126 | } |
allwin@5412 | 127 | if(retries == 0) { |
allwin@5412 | 128 | throw new RuntimeException("Timeout waiting for VM to start. " + |
allwin@5412 | 129 | "vm.paused file not created within 60 seconds."); |
allwin@5412 | 130 | } |
allwin@5412 | 131 | Files.delete(pauseFile); |
allwin@5412 | 132 | } |
allwin@5412 | 133 | |
allwin@5412 | 134 | private static int getUnixProcessId(Process unixProcess) throws Exception { |
allwin@5412 | 135 | Field pidField = unixProcess.getClass().getDeclaredField("pid"); |
allwin@5412 | 136 | pidField.setAccessible(true); |
allwin@5412 | 137 | return (Integer)pidField.get(unixProcess); |
allwin@5412 | 138 | } |
allwin@5412 | 139 | } |