HADOOP-7110. Implement chmod with JNI. Contributed by Todd Lipcon

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1063090 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Todd Lipcon 2011-01-25 01:15:41 +00:00
parent a15d473c46
commit 448f8dbb9f
6 changed files with 69 additions and 2 deletions

View File

@ -266,6 +266,8 @@ Release 0.22.0 - Unreleased
HADOOP-6056. Use java.net.preferIPv4Stack to force IPv4.
(Michele Catasta via shv)
HADOOP-7110. Implement chmod with JNI. (todd)
OPTIMIZATIONS
HADOOP-6884. Add LOG.isDebugEnabled() guard for each LOG.debug(..).

View File

@ -36,6 +36,7 @@
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.io.nativeio.NativeIO;
import org.apache.hadoop.util.Progressable;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.StringUtils;
@ -554,8 +555,13 @@ public void setOwner(Path p, String username, String groupname)
@Override
public void setPermission(Path p, FsPermission permission)
throws IOException {
execCommand(pathToFile(p), Shell.SET_PERMISSION_COMMAND,
String.format("%05o", permission.toShort()));
if (NativeIO.isAvailable()) {
NativeIO.chmod(pathToFile(p).getCanonicalPath(),
permission.toShort());
} else {
execCommand(pathToFile(p), Shell.SET_PERMISSION_COMMAND,
String.format("%05o", permission.toShort()));
}
}
private static String execCommand(File f, String... cmd) throws IOException {

View File

@ -74,6 +74,9 @@ public static boolean isAvailable() {
public static native FileDescriptor open(String path, int flags, int mode) throws IOException;
/** Wrapper around fstat(2) */
public static native Stat fstat(FileDescriptor fd) throws IOException;
/** Wrapper around chmod(2) */
public static native void chmod(String path, int mode) throws IOException;
/** Initialize the JNI method ID and class ID cache */
private static native void initNative();

View File

@ -82,6 +82,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION

View File

@ -221,6 +221,25 @@ cleanup:
return ret;
}
/**
* public static native void chmod(String path, int mode) throws IOException;
*/
JNIEXPORT void JNICALL
Java_org_apache_hadoop_io_nativeio_NativeIO_chmod(
JNIEnv *env, jclass clazz, jstring j_path,
jint mode)
{
const char *path = (*env)->GetStringUTFChars(env, j_path, NULL);
if (path == NULL) return; // JVM throws Exception for us
if (chmod(path, mode) != 0) {
throw_ioe(env, errno);
}
(*env)->ReleaseStringUTFChars(env, j_path, path);
}
/*
* Throw a java.IO.IOException, generating the message from errno.
*/

View File

@ -28,7 +28,11 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.NativeCodeLoader;
public class TestNativeIO {
@ -134,4 +138,34 @@ public void testFDDoesntLeak() throws IOException {
}
}
/**
* Test basic chmod operation
*/
@Test
public void testChmod() throws Exception {
try {
NativeIO.chmod("/this/file/doesnt/exist", 777);
fail("Chmod of non-existent file didn't fail");
} catch (NativeIOException nioe) {
assertEquals(Errno.ENOENT, nioe.getErrno());
}
File toChmod = new File(TEST_DIR, "testChmod");
assertTrue("Create test subject",
toChmod.exists() || toChmod.mkdir());
NativeIO.chmod(toChmod.getAbsolutePath(), 0777);
assertPermissions(toChmod, 0777);
NativeIO.chmod(toChmod.getAbsolutePath(), 0000);
assertPermissions(toChmod, 0000);
NativeIO.chmod(toChmod.getAbsolutePath(), 0644);
assertPermissions(toChmod, 0644);
}
private void assertPermissions(File f, int expected) throws IOException {
FileSystem localfs = FileSystem.getLocal(new Configuration());
FsPermission perms = localfs.getFileStatus(
new Path(f.getAbsolutePath())).getPermission();
assertEquals(expected, perms.toShort());
}
}