Skip to content

Commit

Permalink
zOS AttachAPI doesn't use FileLockWatchdogTask for CommonControlFiles
Browse files Browse the repository at this point in the history
Added a system property com.ibm.tools.attach.useFileLockWatchdog;
Setting -Dcom.ibm.tools.attach.useFileLockWatchdog=[true|false] takes
precedence, if no such system property is specified, always set false on
z/OS, defaults to true on non-z/OS platforms.

Signed-off-by: Jason Feng <[email protected]>
  • Loading branch information
JasonFengJ9 committed Apr 5, 2023
1 parent ff3512b commit f40f665
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*[INCLUDE-IF Sidecar18-SE]*/
/*[INCLUDE-IF JAVA_SPEC_VERSION >= 8]*/
/*******************************************************************************
* Copyright IBM Corp. and others 2009
*
Expand Down Expand Up @@ -150,7 +150,7 @@ public static void obtainControllerLock(String callSite) throws IOException {
}
}
if (null != controllerLockCopy) { /* first entry */
controllerLockCopy.lockFile(true, callSite + "_obtainControllerLock"); //$NON-NLS-1$
controllerLockCopy.lockFile(true, callSite + "_obtainControllerLock", IPC.useFileLockWatchdog); //$NON-NLS-1$
}
}

Expand All @@ -166,7 +166,7 @@ static boolean tryObtainControllerLock(String callSite) {
++controllerLockCount; /* optimistically assume we enter the lock */
if (1 == controllerLockCount) { /* first time in */
try {
controllerLockEntered = getControllerLock().lockFile(false, callSite + "_tryObtainControllerLock"); //$NON-NLS-1$
controllerLockEntered = getControllerLock().lockFile(false, callSite + "_tryObtainControllerLock", IPC.useFileLockWatchdog); //$NON-NLS-1$
if (!controllerLockEntered) { /* lock failed, so revert */
--controllerLockCount;
}
Expand Down Expand Up @@ -205,7 +205,7 @@ public static void releaseControllerLock(String callSite) {
*/

public static void obtainAttachLock(String callSite) throws IOException {
getAttachLock().lockFile(true, callSite + "_obtainAttachLock"); //$NON-NLS-1$
getAttachLock().lockFile(true, callSite + "_obtainAttachLock", IPC.useFileLockWatchdog); //$NON-NLS-1$
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ public FileLock(String filePath, int mode) {
* locks a file using the J9 port library functions.
* @param blocking if true, the function waits until the it obtains the file lock or times out.
* @param callSite caller info
* @param useWatchdog use FileLockWatchdogTask or not
* @return true is file lock obtained.
* @throws IOException if the file is already locked.
* @note locking and unlocking must be done by the same thread.
*/
public boolean lockFile(boolean blocking, String callSite) throws IOException {
String lockFileMsg = blocking ? "locking file ": "non-blocking locking file "; //$NON-NLS-1$//$NON-NLS-2$
public boolean lockFile(boolean blocking, String callSite, boolean useWatchdog) throws IOException {
String lockFileMsg = (blocking ? "locking file " : "non-blocking locking file ") //$NON-NLS-1$//$NON-NLS-2$
+ (useWatchdog ? "using watchdog" : "NOT using watchdog"); //$NON-NLS-1$//$NON-NLS-2$
IPC.logMessage(callSite + " : " + lockFileMsg, lockFilepath); //$NON-NLS-1$

final int FILE_LOCK_TIMEOUT = 20 * 1000; /* time in milliseconds */
Expand All @@ -80,26 +82,29 @@ public boolean lockFile(boolean blocking, String callSite) throws IOException {
locked = (0 <= fileDescriptor); /* negative values indicate error, non-negative values (including 0) are valid FDs */

if (!locked && blocking) { /* try again, this time with a blocking lock and a timeout */
FileLockWatchdogTask wdog = new FileLockWatchdogTask();
FileLockWatchdogTask wdog = null;
IPC.logMessage("lock failed, trying blocking lock, fileDescriptor = " + fileDescriptor); //$NON-NLS-1$
synchronized (shutdownSync) { /* shutdown is called from a different thread */
/*[PR Jazz 30075] inlined createFileLockWatchdogTimer*/
if (!terminated && (null == fileLockWatchdogTimer)) {
fileLockWatchdogTimer = new FilelockTimer("file lock watchdog"); //$NON-NLS-1$
}
if (null != fileLockWatchdogTimer) { /* check if the VM is shutting down */
/*
* The file lock timeout is to recover from pathological conditions such as a hung process which is holding the file lock.
* Under this condition, the process will break the lock.
* This timeout affects only the operation of the attach API. It may delay the start of the attach API (but will not affect
* other aspects of the VM or application launch) or delay an attach attempt. It will not delay the VM or attach API shutdown.
*/
IPC.logMessage("FileLock.lockFile() FILE_LOCK_TIMEOUT = " + FILE_LOCK_TIMEOUT, new Throwable("")); //$NON-NLS-1$ //$NON-NLS-2$
fileLockWatchdogTimer.schedule(wdog, FILE_LOCK_TIMEOUT);
}
else {
IPC.logMessage("FileLock.lockFile() returns false."); //$NON-NLS-1$
return false;
if (useWatchdog) {
wdog = new FileLockWatchdogTask();
synchronized (shutdownSync) { /* shutdown is called from a different thread */
/*[PR Jazz 30075] inlined createFileLockWatchdogTimer*/
if (!terminated && (null == fileLockWatchdogTimer)) {
fileLockWatchdogTimer = new FilelockTimer("file lock watchdog"); //$NON-NLS-1$
}
if (null != fileLockWatchdogTimer) { /* check if the VM is shutting down */
/*
* The file lock timeout is to recover from pathological conditions such as a hung process which is holding the file lock.
* Under this condition, the process will break the lock.
* This timeout affects only the operation of the attach API. It may delay the start of the attach API (but will not affect
* other aspects of the VM or application launch) or delay an attach attempt. It will not delay the VM or attach API shutdown.
*/
IPC.logMessage("FileLock.lockFile() FILE_LOCK_TIMEOUT = " + FILE_LOCK_TIMEOUT, new Throwable("")); //$NON-NLS-1$ //$NON-NLS-2$
fileLockWatchdogTimer.schedule(wdog, FILE_LOCK_TIMEOUT);
}
else {
IPC.logMessage("FileLock.lockFile() returns false."); //$NON-NLS-1$
return false;
}
}
}

Expand All @@ -116,9 +121,11 @@ public boolean lockFile(boolean blocking, String callSite) throws IOException {
unlockFile("lockFile_IOException"); //$NON-NLS-1$
IPC.logMessage("FileLock.lockFile() blocking lock failed with lockFilepath = " + lockFilepath + ", exception message: " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
}
synchronized (shutdownSync) {
if (null != fileLockWatchdogTimer) {
wdog.cancel();
if (useWatchdog) {
synchronized (shutdownSync) {
if (null != fileLockWatchdogTimer) {
wdog.cancel();
}
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*[INCLUDE-IF Sidecar18-SE]*/
/*[INCLUDE-IF JAVA_SPEC_VERSION >= 8]*/
/*******************************************************************************
* Copyright IBM Corp. and others 2009
*
Expand All @@ -22,6 +22,8 @@
*******************************************************************************/
package openj9.internal.tools.attach.target;

import com.ibm.oti.vm.VM;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
Expand Down Expand Up @@ -53,6 +55,7 @@
public class IPC {

private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; //$NON-NLS-1$
private static final String COM_IBM_TOOLS_ATTACH_USE_FILELOCK_WATCHDOG = "com.ibm.tools.attach.useFileLockWatchdog"; //$NON-NLS-1$
/**
* Successful return code from natives.
*/
Expand Down Expand Up @@ -85,8 +88,17 @@ public class IPC {
*/
public static final boolean isZOS;

/**
* Controls use of the FileLockWatchdogTask.
* Setting -Dcom.ibm.tools.attach.useFileLockWatchdog=[true|false] takes
* precedence, if no such system property is specified, always set false on
* z/OS, defaults to true on non-z/OS platforms.
*/
public static final boolean useFileLockWatchdog;

static {
String osName = com.ibm.oti.vm.VM.getVMLangAccess().internalGetProperties().getProperty("os.name"); //$NON-NLS-1$
Properties props = VM.getVMLangAccess().internalGetProperties();
String osName = props.getProperty("os.name"); //$NON-NLS-1$
boolean tempIsZos = false;
boolean tempIsWindows = false;
if (null != osName) {
Expand All @@ -98,6 +110,14 @@ public class IPC {
}
isZOS = tempIsZos;
isWindows = tempIsWindows;

String propUseFileLockWatchdog = props.getProperty(COM_IBM_TOOLS_ATTACH_USE_FILELOCK_WATCHDOG);
if (propUseFileLockWatchdog == null) {
// no system property com.ibm.tools.attach.useFileLockWatchdog is specified
useFileLockWatchdog = !isZOS;
} else {
useFileLockWatchdog = "true".equalsIgnoreCase(propUseFileLockWatchdog);
}
}

private static Random randomGen; /* Cleanup. this is used by multiple threads */
Expand Down Expand Up @@ -325,7 +345,7 @@ static String getTmpDir() {
String tmpDir = getTempDirImpl();
if (null == tmpDir) {
logMessage("Could not get system temporary directory. Trying " + JAVA_IO_TMPDIR); //$NON-NLS-1$
tmpDir = com.ibm.oti.vm.VM.getVMLangAccess().internalGetProperties().getProperty(JAVA_IO_TMPDIR);
tmpDir = VM.getVMLangAccess().internalGetProperties().getProperty(JAVA_IO_TMPDIR);
}
return tmpDir;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ private static Attachment checkReplyAndCreateAttachment() throws IOException {
if (LOGGING_DISABLED != loggingStatus) {
IPC.logMessage("checkReplyAndCreateAttachment iteration "+ AttachHandler.notificationCount+" waitForNotification obtainLock"); //$NON-NLS-1$ //$NON-NLS-2$
}
/* the sync file is missing. */
if (!AttachHandler.mainHandler.syncFileLock.lockFile(true, "WaitLoop.checkReplyAndCreateAttachment")) { //$NON-NLS-1$
/* the sync file is missing, use FileLockWatchdogTask for non-CommonControlFile */
if (!AttachHandler.mainHandler.syncFileLock.lockFile(true, "WaitLoop.checkReplyAndCreateAttachment", true)) { //$NON-NLS-1$
TargetDirectory.createMySyncFile();
/* don't bother locking this since the attacher will not have locked it. */
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ private void lockAllAttachNotificationSyncFiles(
IPC.logMessage("lockAllAttachNotificationSyncFiles locking targetLocks[", vmdIndex, "] ", attachSyncFile); //$NON-NLS-1$ //$NON-NLS-2$
targetLocks[vmdIndex] = new FileLock(attachSyncFile, TargetDirectory.SYNC_FILE_PERMISSIONS);
try {
targetLocks[vmdIndex].lockFile(true, "OpenJ9VirtualMachine.lockAllAttachNotificationSyncFiles"); //$NON-NLS-1$
/* use FileLockWatchdogTask for non-CommonControlFile */
targetLocks[vmdIndex].lockFile(true, "OpenJ9VirtualMachine.lockAllAttachNotificationSyncFiles", true); //$NON-NLS-1$
} catch (IOException e) {
targetLocks[vmdIndex] = null;
IPC.logMessage("lockAllAttachNotificationSyncFiles locking targetLocks[", vmdIndex, "] ", "already locked"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public NativeFileLock(File lockFile, int mode) throws Exception {
nflConstructor.setAccessible(true);
fileLockObject = nflConstructor.newInstance(lockFile.getAbsolutePath(), Integer.valueOf(mode));
lockFileMethod = nativeFileLock.getDeclaredMethod("lockFile",
boolean.class, String.class);
boolean.class, String.class, boolean.class);
lockFileMethod.setAccessible(true);
unlockFileMethod = nativeFileLock.getDeclaredMethod("unlockFile", String.class);
unlockFileMethod.setAccessible(true);
Expand All @@ -53,7 +53,8 @@ public NativeFileLock(File lockFile, int mode) throws Exception {
public boolean lockFile(boolean blocking) throws Exception {
Boolean result = Boolean.valueOf(true);
TestFileLocking.logger.debug("lockfile blocking =" + blocking);
result = (Boolean) lockFileMethod.invoke(fileLockObject, Boolean.valueOf(blocking), "NativeFileLock.lockFile()");
// The test has no different user involved, always locks file with FileLockWatchdogTask.
result = (Boolean) lockFileMethod.invoke(fileLockObject, Boolean.valueOf(blocking), "NativeFileLock.lockFile()", true);
return result.booleanValue();
}

Expand Down

0 comments on commit f40f665

Please sign in to comment.