Created
March 23, 2013 14:51
-
-
Save mattf/5227989 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.apache.hadoop.fs.glusterfs; | |
import java.net.URI; | |
import java.io.File; | |
import java.io.RandomAccessFile; | |
import java.io.IOException; | |
import java.nio.channels.FileLock; | |
import org.apache.hadoop.conf.Configuration; | |
import org.apache.hadoop.fs.Path; | |
import org.apache.hadoop.fs.permission.FsPermission; | |
// | |
// This class provides a per mount lock coordinated at the JVM | |
// level. It does not provide a per mount lock coordinated at the JVM | |
// thread level. Two threads within a single JVM will share the lock. | |
// | |
public class LockingGlusterFileSystem extends GlusterFileSystem | |
{ | |
private RandomAccessFile lockFile; | |
private int lockCount; | |
private FileLock fileLock; | |
public void initialize(URI uri, Configuration conf) | |
throws IOException | |
{ | |
super.initialize(uri, conf); | |
// XXX: Want the mount directory, only available as "working directory" | |
String lockFileName = "/var/tmp/" + | |
getWorkingDirectory().toUri().getPath().replace('/', '_'); | |
// Note: Not deleting the lock file on exit. Doing so would create | |
// a situation where two JVMs can both think they have the lock. | |
// JVM 0 starts and creates lock file P | |
// JVM 1 starts and opens existing lock file P | |
// JVM 0 exits and deletes lock file P | |
// JVM 2 starts and creates lock file Q | |
// JVM 1 and 2 now have different lock files (P & Q) | |
// The result here is mount lock files are not cleaned. A system | |
// with multiple mounts over time will accumulate lock | |
// files. This makes periodically cleaned /var/tmp a more | |
// attractive option than /var/lock, which is arguably a more | |
// appropriate location. | |
lockFile = new RandomAccessFile(lockFileName, "rw"); | |
fileLock = null; | |
lockCount = 0; | |
} | |
private synchronized void lock() | |
throws IOException | |
{ | |
if (null != fileLock) { | |
lockCount++; | |
return; | |
} | |
fileLock = lockFile.getChannel().lock(); | |
lockCount++; | |
} | |
private synchronized void release() | |
throws IOException | |
{ | |
assert(null != fileLock); | |
lockCount--; | |
if (0 == lockCount) { | |
fileLock.release(); | |
fileLock = null; | |
} | |
} | |
public boolean mkdirs(Path path, FsPermission permission) | |
throws IOException { | |
try { | |
lock(); | |
return super.mkdirs(path, permission); | |
} finally { | |
release(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment