Author: atm
Date: Thu Jan 31 07:29:46 2013
New Revision: 1440865
URL: http://svn.apache.org/viewvc?rev=1440865&view=rev
Log:
HDFS-4428. FsDatasetImpl should disclose what the error is when a rename fails. Contributed
by Colin Patrick McCabe.
Modified:
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/Errno.java
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/errno_enum.c
hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/nativeio/TestNativeIO.java
Modified: hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/Errno.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/Errno.java?rev=1440865&r1=1440864&r2=1440865&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/Errno.java
(original)
+++ hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/Errno.java
Thu Jan 31 07:29:46 2013
@@ -55,6 +55,9 @@ public enum Errno {
EPIPE,
EDOM,
ERANGE,
+ ELOOP,
+ ENAMETOOLONG,
+ ENOTEMPTY,
UNKNOWN;
}
Modified: hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java?rev=1440865&r1=1440864&r2=1440865&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java
(original)
+++ hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java
Thu Jan 31 07:29:46 2013
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.io.nativeio;
+import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Map;
@@ -293,4 +294,35 @@ public class NativeIO {
stat.group = getName(IdCache.GROUP, stat.groupId);
return stat;
}
+
+ /**
+ * A version of renameTo that throws a descriptive exception when it fails.
+ *
+ * @param src The source path
+ * @param dst The destination path
+ *
+ * @throws NativeIOException On failure.
+ */
+ public static void renameTo(File src, File dst)
+ throws IOException {
+ if (!nativeLoaded) {
+ if (!src.renameTo(dst)) {
+ throw new IOException("renameTo(src=" + src + ", dst=" +
+ dst + ") failed.");
+ }
+ } else {
+ renameTo0(src.getAbsolutePath(), dst.getAbsolutePath());
+ }
+ }
+
+ /**
+ * A version of renameTo that throws a descriptive exception when it fails.
+ *
+ * @param src The source path
+ * @param dst The destination path
+ *
+ * @throws NativeIOException On failure.
+ */
+ private static native void renameTo0(String src, String dst)
+ throws NativeIOException;
}
Modified: hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c?rev=1440865&r1=1440864&r2=1440865&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c
(original)
+++ hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c
Thu Jan 31 07:29:46 2013
@@ -24,11 +24,12 @@
#include <grp.h>
#include <jni.h>
#include <pwd.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#include <sys/types.h>
#include <sys/syscall.h>
+#include <sys/types.h>
#include <unistd.h>
#include "config.h"
@@ -502,6 +503,26 @@ ssize_t get_pw_buflen() {
#endif
return (ret > 512) ? ret : 512;
}
+
+JNIEXPORT void JNICALL
+Java_org_apache_hadoop_io_nativeio_NativeIO_renameTo0(JNIEnv *env,
+jclass clazz, jstring jsrc, jstring jdst)
+{
+ const char *src = NULL, *dst = NULL;
+
+ src = (*env)->GetStringUTFChars(env, jsrc, NULL);
+ if (!src) goto done; // exception was thrown
+ dst = (*env)->GetStringUTFChars(env, jdst, NULL);
+ if (!dst) goto done; // exception was thrown
+ if (rename(src, dst)) {
+ throw_ioe(env, errno);
+ }
+
+done:
+ if (src) (*env)->ReleaseStringUTFChars(env, jsrc, src);
+ if (dst) (*env)->ReleaseStringUTFChars(env, jdst, dst);
+}
+
/**
* vim: sw=2: ts=2: et:
*/
Modified: hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/errno_enum.c
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/errno_enum.c?rev=1440865&r1=1440864&r2=1440865&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/errno_enum.c
(original)
+++ hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/errno_enum.c
Thu Jan 31 07:29:46 2013
@@ -63,6 +63,9 @@ static errno_mapping_t ERRNO_MAPPINGS[]
MAPPING(EPIPE),
MAPPING(EDOM),
MAPPING(ERANGE),
+ MAPPING(ELOOP),
+ MAPPING(ENAMETOOLONG),
+ MAPPING(ENOTEMPTY),
{-1, NULL}
};
Modified: hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/nativeio/TestNativeIO.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/nativeio/TestNativeIO.java?rev=1440865&r1=1440864&r2=1440865&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/nativeio/TestNativeIO.java
(original)
+++ hadoop/common/trunk/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/nativeio/TestNativeIO.java
Thu Jan 31 07:29:46 2013
@@ -25,11 +25,14 @@ import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.ArrayList;
import java.util.List;
+
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assume.*;
import static org.junit.Assert.*;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
@@ -293,4 +296,40 @@ public class TestNativeIO {
assertFalse(NativeIO.getGroupName(0).isEmpty());
}
+ @Test
+ public void testRenameTo() throws Exception {
+ final File TEST_DIR = new File(new File(
+ System.getProperty("test.build.data","build/test/data")), "renameTest");
+ assumeTrue(TEST_DIR.mkdirs());
+ File nonExistentFile = new File(TEST_DIR, "nonexistent");
+ File targetFile = new File(TEST_DIR, "target");
+ // Test attempting to rename a nonexistent file.
+ try {
+ NativeIO.renameTo(nonExistentFile, targetFile);
+ Assert.fail();
+ } catch (NativeIOException e) {
+ Assert.assertEquals(e.getErrno(), Errno.ENOENT);
+ }
+
+ // Test renaming a file to itself. It should succeed and do nothing.
+ File sourceFile = new File(TEST_DIR, "source");
+ Assert.assertTrue(sourceFile.createNewFile());
+ NativeIO.renameTo(sourceFile, sourceFile);
+
+ // Test renaming a source to a destination.
+ NativeIO.renameTo(sourceFile, targetFile);
+
+ // Test renaming a source to a path which uses a file as a directory.
+ sourceFile = new File(TEST_DIR, "source");
+ Assert.assertTrue(sourceFile.createNewFile());
+ File badTarget = new File(targetFile, "subdir");
+ try {
+ NativeIO.renameTo(sourceFile, badTarget);
+ Assert.fail();
+ } catch (NativeIOException e) {
+ Assert.assertEquals(e.getErrno(), Errno.ENOTDIR);
+ }
+
+ FileUtils.deleteQuietly(TEST_DIR);
+ }
}
|