Skip to content

Instantly share code, notes, and snippets.

@mattf
Created March 23, 2013 14:51
Show Gist options
  • Save mattf/5227989 to your computer and use it in GitHub Desktop.
Save mattf/5227989 to your computer and use it in GitHub Desktop.
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