You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by sh...@apache.org on 2017/06/10 01:13:35 UTC

hadoop git commit: YARN-5121. fix some container-executor portability issues. Contributed by Allen Wittenauer. Backport YARN-6698 by Akira Ajisaka

Repository: hadoop
Updated Branches:
  refs/heads/branch-2.7 b5f25a1a5 -> b6f3e1aca


YARN-5121. fix some container-executor portability issues. Contributed by Allen Wittenauer. Backport YARN-6698 by  Akira Ajisaka

(cherry picked from commit ef501b1a0b4c34a2cc43eb082d1c2364684cd7f1)
(cherry picked from commit 384803d09ac45886e74a0501f4b419a2b756c20c)

Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/b6f3e1ac
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/b6f3e1ac
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/b6f3e1ac

Branch: refs/heads/branch-2.7
Commit: b6f3e1acae59a045aab4d0799e685368735a3928
Parents: b5f25a1
Author: Chris Nauroth <cn...@apache.org>
Authored: Sat Jul 30 08:26:00 2016 -0700
Committer: Konstantin V Shvachko <sh...@apache.org>
Committed: Fri Jun 9 18:04:46 2017 -0700

----------------------------------------------------------------------
 LICENSE.txt                                     |  32 +++++
 hadoop-yarn-project/CHANGES.txt                 |   3 +
 .../hadoop-yarn-server-nodemanager/pom.xml      |  12 ++
 .../src/CMakeLists.txt                          |  18 ++-
 .../src/config.h.cmake                          |   8 +-
 .../container-executor/impl/compat/fchmodat.h   |  56 ++++++++
 .../container-executor/impl/compat/fdopendir.h  |  52 ++++++++
 .../container-executor/impl/compat/fstatat.h    |  67 ++++++++++
 .../container-executor/impl/compat/openat.h     |  74 +++++++++++
 .../container-executor/impl/compat/unlinkat.h   |  67 ++++++++++
 .../container-executor/impl/configuration.c     |  15 ++-
 .../container-executor/impl/configuration.h     |   6 +-
 .../impl/container-executor.c                   |  95 +++++++-------
 .../impl/container-executor.h                   |   2 +-
 .../container-executor/impl/get_executable.c    | 127 +++++++++++++++++++
 .../main/native/container-executor/impl/main.c  |  48 ++++++-
 .../test/test-container-executor.c              | 119 ++++++++++++-----
 17 files changed, 709 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/LICENSE.txt
----------------------------------------------------------------------
diff --git a/LICENSE.txt b/LICENSE.txt
index 6f81d0e..bc7ef3d 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -345,6 +345,38 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+For hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/{fstatat|openat|unlinkat}.h:
+
+Copyright (c) 2012 The FreeBSD Foundation
+All rights reserved.
+
+This software was developed by Pawel Jakub Dawidek under sponsorship from
+the FreeBSD Foundation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+=============
+
 The binary distribution of this product bundles binaries of leveldb
 (http://code.google.com/p/leveldb/), which is available under the following
 license:

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/CHANGES.txt
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt
index 57e1228..a7d393d 100644
--- a/hadoop-yarn-project/CHANGES.txt
+++ b/hadoop-yarn-project/CHANGES.txt
@@ -118,6 +118,9 @@ Release 2.7.4 - UNRELEASED
     YARN-4017. container-executor overuses PATH_MAX.
     (Sidharta Seethana via vvasudev)
 
+    YARN-5121. fix some container-executor portability issues.
+    (Allen Wittenauer) Backport YARN-6698 by  Akira Ajisaka.
+
 Release 2.7.3 - 2016-08-25
 
   INCOMPATIBLE CHANGES

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml
index 2238e5a..9605c5a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/pom.xml
@@ -280,6 +280,18 @@
       </plugin>
 
       <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>src/main/native/container-executor/impl/compat/fstatat.h</exclude>
+            <exclude>src/main/native/container-executor/impl/compat/openat.h</exclude>
+            <exclude>src/main/native/container-executor/impl/compat/unlinkat.h</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+
+      <plugin>
         <groupId>org.apache.hadoop</groupId>
         <artifactId>hadoop-maven-plugins</artifactId>
         <executions>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/CMakeLists.txt b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/CMakeLists.txt
index f691a9c..ba2eae2 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/CMakeLists.txt
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/CMakeLists.txt
@@ -21,7 +21,20 @@ set(CMAKE_BUILD_TYPE, Release)
 include(../../../../../hadoop-common-project/hadoop-common/src/JNIFlags.cmake NO_POLICY_SCOPE)
 
 include(CheckFunctionExists)
-CHECK_FUNCTION_EXISTS(fcloseall HAVE_FCLOSEALL)
+check_function_exists(canonicalize_file_name HAVE_CANONICALIZE_FILE_NAME)
+check_function_exists(fcloseall HAVE_FCLOSEALL)
+check_function_exists(fchmodat HAVE_FCHMODAT)
+check_function_exists(fdopendir HAVE_FDOPENDIR)
+check_function_exists(fstatat HAVE_FSTATAT)
+check_function_exists(openat HAVE_OPENAT)
+check_function_exists(unlinkat HAVE_UNLINKAT)
+
+if(APPLE)
+  include_directories( /System/Library/Frameworks )
+  find_library(COCOA_LIBRARY Cocoa)
+  mark_as_advanced(COCOA_LIBRARY)
+  set(EXTRA_LIBS ${COCOA_LIBRARY})
+endif(APPLE)
 
 function(output_directory TGT DIR)
     SET_TARGET_PROPERTIES(${TGT} PROPERTIES
@@ -47,6 +60,7 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
 add_library(container
     main/native/container-executor/impl/configuration.c
     main/native/container-executor/impl/container-executor.c
+    main/native/container-executor/impl/get_executable.c
 )
 
 add_executable(container-executor
@@ -61,6 +75,6 @@ add_executable(test-container-executor
     main/native/container-executor/test/test-container-executor.c
 )
 target_link_libraries(test-container-executor
-    container
+    container ${EXTRA_LIBS}
 )
 output_directory(test-container-executor target/usr/local/bin)

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/config.h.cmake
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/config.h.cmake b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/config.h.cmake
index 0f7a490..0ab7bbd 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/config.h.cmake
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/config.h.cmake
@@ -20,6 +20,12 @@
 
 #cmakedefine HADOOP_CONF_DIR "@HADOOP_CONF_DIR@"
 
-#cmakedefine HAVE_FCLOSEALL "@HAVE_FCLOSEALL@"
+#cmakedefine HAVE_CANONICALIZE_FILE_NAME @HAVE_CANONICALIZE_FILE_NAME@
+#cmakedefine HAVE_FCHMODAT @HAVE_FCHMODAT@
+#cmakedefine HAVE_FCLOSEALL @HAVE_FCLOSEALL@
+#cmakedefine HAVE_FDOPENDIR @HAVE_FDOPENDIR@
+#cmakedefine HAVE_FSTATAT @HAVE_FSTATAT@
+#cmakedefine HAVE_OPENAT @HAVE_OPENAT@
+#cmakedefine HAVE_UNLINKAT @HAVE_UNLINKAT@
 
 #endif

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fchmodat.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fchmodat.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fchmodat.h
new file mode 100644
index 0000000..7812b5d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fchmodat.h
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _FCHMODAT_H_
+#define _FCHMODAT_H_
+
+#include <sys/stat.h>
+
+#include <unistd.h>
+
+#define AT_SYMLINK_NOFOLLOW 0x01
+
+static int
+fchmodat(int fd, const char *path, mode_t mode, int flag)
+{
+  int cfd, error, ret;
+
+  cfd = open(".", O_RDONLY | O_DIRECTORY);
+  if (cfd == -1)
+    return (-1);
+
+  if (fchdir(fd) == -1) {
+    error = errno;
+    (void)close(cfd);
+    errno = error;
+    return (-1);
+  }
+
+  if (flag == AT_SYMLINK_NOFOLLOW)
+    ret = lchmod(path, mode);
+  else
+    ret = chmod(path, mode);
+
+  error = errno;
+  (void)fchdir(cfd);
+  (void)close(cfd);
+  errno = error;
+  return (ret);
+}
+
+#endif  /* !_FCHMODAT_H_ */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fdopendir.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fdopendir.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fdopendir.h
new file mode 100644
index 0000000..1f9bdc3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fdopendir.h
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _FDOPENDIR_H_
+#define _FDOPENDIR_H_
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+DIR *
+fdopendir(int fd)
+{
+  int cfd, error;
+  DIR *dfd;
+
+  cfd = open(".", O_RDONLY | O_DIRECTORY);
+  if (cfd == -1)
+    return (NULL);
+
+  if (fchdir(fd) == -1) {
+    error = errno;
+    (void)close(cfd);
+    errno = error;
+    return (NULL);
+  }
+
+  dfd=opendir(".");
+  error = errno;
+  (void)fchdir(cfd);
+  (void)close(cfd);
+  errno = error;
+  return (dfd);
+}
+
+#endif  /* !_FDOPENDIR_H_ */
+

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fstatat.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fstatat.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fstatat.h
new file mode 100644
index 0000000..e1b1658
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/fstatat.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Pawel Jakub Dawidek under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _FSTATAT_H_
+#define _FSTATAT_H_
+
+#include <sys/stat.h>
+
+#include <unistd.h>
+
+#define AT_SYMLINK_NOFOLLOW 0x01
+
+static int
+fstatat(int fd, const char *path, struct stat *buf, int flag)
+{
+  int cfd, error, ret;
+
+  cfd = open(".", O_RDONLY | O_DIRECTORY);
+  if (cfd == -1)
+    return (-1);
+
+  if (fchdir(fd) == -1) {
+    error = errno;
+    (void)close(cfd);
+    errno = error;
+    return (-1);
+  }
+
+  if (flag == AT_SYMLINK_NOFOLLOW)
+    ret = lstat(path, buf);
+  else
+    ret = stat(path, buf);
+
+  error = errno;
+  (void)fchdir(cfd);
+  (void)close(cfd);
+  errno = error;
+  return (ret);
+}
+
+#endif  /* !_FSTATAT_H_ */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/openat.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/openat.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/openat.h
new file mode 100644
index 0000000..005be37
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/openat.h
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Pawel Jakub Dawidek under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _OPENAT_H_
+#define _OPENAT_H_
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+static int
+openat(int fd, const char *path, int flags, ...)
+{
+  int cfd, ffd, error;
+
+  cfd = open(".", O_RDONLY | O_DIRECTORY);
+  if (cfd == -1)
+    return (-1);
+
+  if (fchdir(fd) == -1) {
+    error = errno;
+    (void)close(cfd);
+    errno = error;
+    return (-1);
+  }
+
+  if ((flags & O_CREAT) != 0) {
+    va_list ap;
+    int mode;
+
+    va_start(ap, flags);
+    mode = va_arg(ap, int);
+    va_end(ap);
+
+    ffd = open(path, flags, mode);
+  } else {
+    ffd = open(path, flags);
+  }
+
+  error = errno;
+  (void)fchdir(cfd);
+  (void)close(cfd);
+  errno = error;
+  return (ffd);
+}
+
+#endif  /* !_OPENAT_H_ */
+

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/unlinkat.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/unlinkat.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/unlinkat.h
new file mode 100644
index 0000000..a4977a1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/compat/unlinkat.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Pawel Jakub Dawidek under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _UNLINKAT_H_
+#define _UNLINKAT_H_
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#define AT_REMOVEDIR  0x01
+
+static int
+unlinkat(int fd, const char *path, int flag)
+{
+  int cfd, error, ret;
+
+  cfd = open(".", O_RDONLY | O_DIRECTORY);
+  if (cfd == -1)
+    return (-1);
+
+  if (fchdir(fd) == -1) {
+    error = errno;
+    (void)close(cfd);
+    errno = error;
+    return (-1);
+  }
+
+  if (flag == AT_REMOVEDIR)
+    ret = rmdir(path);
+  else
+    ret = unlink(path);
+
+  error = errno;
+  (void)fchdir(cfd);
+  (void)close(cfd);
+  errno = error;
+  return (ret);
+}
+
+#endif  /* !_UNLINKAT_H_ */
+

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c
index 9199f1f..7645d86 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c
@@ -17,7 +17,7 @@
  */
 
 // ensure we get the posix version of dirname by including this first
-#include <libgen.h> 
+#include <libgen.h>
 
 #include "configuration.h"
 #include "container-executor.h"
@@ -79,7 +79,7 @@ static int is_only_root_writable(const char *file) {
     return 0;
   }
   if ((file_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
-    fprintf(ERRORFILE, 
+    fprintf(ERRORFILE,
 	    "File %s must not be world or group writable, but is %03o\n",
 	    file, file_stat.st_mode & (~S_IFMT));
     return 0;
@@ -103,8 +103,13 @@ char *resolve_config_path(const char* file_name, const char *root) {
     real_fname = buffer;
   }
 
+#ifdef HAVE_CANONICALIZE_FILE_NAME
+  char * ret = (real_fname == NULL) ? NULL : canonicalize_file_name(real_fname);
+#else
   char * ret = (real_fname == NULL) ? NULL : realpath(real_fname, NULL);
+#endif
 #ifdef DEBUG
+  fprintf(stderr,"ret = %s\n", ret);
   fprintf(stderr, "resolve_config_path(file_name=%s,root=%s)=%s\n",
           file_name, root ? root : "null", ret ? ret : "null");
 #endif
@@ -113,7 +118,7 @@ char *resolve_config_path(const char* file_name, const char *root) {
 
 /**
  * Ensure that the configuration file and all of the containing directories
- * are only writable by root. Otherwise, an attacker can change the 
+ * are only writable by root. Otherwise, an attacker can change the
  * configuration and potentially cause damage.
  * returns 0 if permissions are ok
  */
@@ -166,7 +171,7 @@ void read_config(const char* file_name) {
       exit(OUT_OF_MEMORY);
     }
     size_read = getline(&line,&linesize,conf_file);
- 
+
     //feof returns true only after we read past EOF.
     //so a file with no new line, at last can reach this place
     //if size_read returns negative check for eof condition
@@ -244,7 +249,7 @@ void read_config(const char* file_name) {
     config.size++;
     free(line);
   }
- 
+
   //close the file
   fclose(conf_file);
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.h
index 892af3a..e4daf65 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.h
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.h
@@ -24,7 +24,7 @@
 
 /**
  * Ensure that the configuration file and all of the containing directories
- * are only writable by root. Otherwise, an attacker can change the 
+ * are only writable by root. Otherwise, an attacker can change the
  * configuration and potentially cause damage.
  * returns 0 if permissions are ok
  */
@@ -58,7 +58,7 @@ void free_configurations();
 
 /**
  * If str is a string of the form key=val, find 'key'
- * 
+ *
  * @param input    The input string
  * @param out      Where to put the output string.
  * @param out_len  The length of the output buffer.
@@ -71,7 +71,7 @@ int get_kv_key(const char *input, char *out, size_t out_len);
 
 /**
  * If str is a string of the form key=val, find 'val'
- * 
+ *
  * @param input    The input string
  * @param out      Where to put the output string.
  * @param out_len  The length of the output buffer.

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
index 756618f..e7cdb13 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
@@ -36,6 +36,28 @@
 #include <sys/mount.h>
 #include <sys/wait.h>
 
+#include "config.h"
+
+#ifndef HAVE_FCHMODAT
+#include "compat/fchmodat.h"
+#endif
+
+#ifndef HAVE_FDOPENDIR
+#include "compat/fdopendir.h"
+#endif
+
+#ifndef HAVE_FSTATAT
+#include "compat/fstatat.h"
+#endif
+
+#ifndef HAVE_OPENAT
+#include "compat/openat.h"
+#endif
+
+#ifndef HAVE_UNLINKAT
+#include "compat/unlinkat.h"
+#endif
+
 static const int DEFAULT_MIN_USERID = 1000;
 
 static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0};
@@ -57,31 +79,14 @@ void set_nm_uid(uid_t user, gid_t group) {
   nm_gid = group;
 }
 
-/**
- * get the executable filename.
- */
-char* get_executable() {
-  char buffer[EXECUTOR_PATH_MAX];
-  snprintf(buffer, EXECUTOR_PATH_MAX, "/proc/%u/exe", getpid());
-  char *filename = malloc(EXECUTOR_PATH_MAX);
-  ssize_t len = readlink(buffer, filename, EXECUTOR_PATH_MAX);
-  if (len == -1) {
-    fprintf(ERRORFILE, "Can't get executable name from %s - %s\n", buffer,
-            strerror(errno));
-    exit(-1);
-  } else if (len >= EXECUTOR_PATH_MAX) {
-    fprintf(ERRORFILE, "Executable name %.*s is longer than %d characters.\n",
-            EXECUTOR_PATH_MAX, filename, EXECUTOR_PATH_MAX);
-    exit(-1);
-  }
-  filename[len] = '\0';
-  return filename;
-}
-
 int check_executor_permissions(char *executable_file) {
 
   errno = 0;
+#ifdef HAVE_CANONICALIZE_FILE_NAME
+  char * resolved_path = canonicalize_file_name(executable_file);
+#else
   char * resolved_path = realpath(executable_file, NULL);
+#endif
   if (resolved_path == NULL) {
     fprintf(ERRORFILE,
         "Error resolving the canonical name for the executable : %s!",
@@ -92,7 +97,7 @@ int check_executor_permissions(char *executable_file) {
   struct stat filestat;
   errno = 0;
   if (stat(resolved_path, &filestat) != 0) {
-    fprintf(ERRORFILE, 
+    fprintf(ERRORFILE,
             "Could not stat the executable : %s!.\n", strerror(errno));
     return -1;
   }
@@ -154,6 +159,7 @@ static int change_effective_user(uid_t user, gid_t group) {
   return 0;
 }
 
+#ifdef __linux
 /**
  * Write the pid of the current process to the cgroup file.
  * cgroup_file: Path to cgroup file where pid needs to be written to.
@@ -191,6 +197,7 @@ static int write_pid_to_cgroup_as_root(const char* cgroup_file, pid_t pid) {
 
   return 0;
 }
+#endif
 
 /**
  * Write the pid of the current process into the pid file.
@@ -330,7 +337,7 @@ static int wait_and_write_exit_code(pid_t pid, const char* exit_code_file) {
  * priviledges.
  */
 int change_user(uid_t user, gid_t group) {
-  if (user == getuid() && user == geteuid() && 
+  if (user == getuid() && user == geteuid() &&
       group == getgid() && group == getegid()) {
     return 0;
   }
@@ -342,7 +349,7 @@ int change_user(uid_t user, gid_t group) {
     return SETUID_OPER_FAILED;
   }
   if (setgid(group) != 0) {
-    fprintf(LOGFILE, "unable to set group to %d - %s\n", group, 
+    fprintf(LOGFILE, "unable to set group to %d - %s\n", group,
             strerror(errno));
     fprintf(LOGFILE, "Real: %d:%d; Effective: %d:%d\n",
 	    getuid(), getgid(), geteuid(), getegid());
@@ -361,7 +368,7 @@ int change_user(uid_t user, gid_t group) {
 /**
  * Utility function to concatenate argB to argA using the concat_pattern.
  */
-char *concatenate(char *concat_pattern, char *return_path_name, 
+char *concatenate(char *concat_pattern, char *return_path_name,
                   int numArgs, ...) {
   va_list ap;
   va_start(ap, numArgs);
@@ -537,12 +544,12 @@ int check_dir(char* npath, mode_t st_mode, mode_t desired, int finalComponent) {
  * Function to prepare the container directories.
  * It creates the container work and log directories.
  */
-static int create_container_directories(const char* user, const char *app_id, 
+static int create_container_directories(const char* user, const char *app_id,
     const char *container_id, char* const* local_dir, char* const* log_dir, const char *work_dir) {
   // create dirs as 0750
   const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP;
   if (app_id == NULL || container_id == NULL || user == NULL || user_detail == NULL || user_detail->pw_name == NULL) {
-    fprintf(LOGFILE, 
+    fprintf(LOGFILE,
             "Either app_id, container_id or the user passed is null.\n");
     return -1;
   }
@@ -550,7 +557,7 @@ static int create_container_directories(const char* user, const char *app_id,
   int result = -1;
   char* const* local_dir_ptr;
   for(local_dir_ptr = local_dir; *local_dir_ptr != NULL; ++local_dir_ptr) {
-    char *container_dir = get_container_work_directory(*local_dir_ptr, user, app_id, 
+    char *container_dir = get_container_work_directory(*local_dir_ptr, user, app_id,
                                                 container_id);
     if (container_dir == NULL) {
       return -1;
@@ -662,7 +669,7 @@ struct passwd* check_user(const char *user) {
     char *end_ptr = NULL;
     min_uid = strtol(min_uid_str, &end_ptr, 10);
     if (min_uid_str == end_ptr || *end_ptr != '\0') {
-      fprintf(LOGFILE, "Illegal value of %s for %s in configuration\n", 
+      fprintf(LOGFILE, "Illegal value of %s for %s in configuration\n",
 	      min_uid_str, MIN_USERID_KEY);
       fflush(LOGFILE);
       free(min_uid_str);
@@ -790,7 +797,7 @@ int create_directory_for_user(const char* path) {
   }
   if (change_effective_user(user, group) != 0) {
     fprintf(LOGFILE, "Failed to change user to %i - %i\n", user, group);
- 
+
     ret = -1;
   }
   return ret;
@@ -823,13 +830,13 @@ static int open_file_as_nm(const char* filename) {
  * The input stream is closed.
  * Return 0 if everything is ok.
  */
-static int copy_file(int input, const char* in_filename, 
+static int copy_file(int input, const char* in_filename,
 		     const char* out_filename, mode_t perm) {
   const int buffer_size = 128*1024;
   char buffer[buffer_size];
   int out_fd = open(out_filename, O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW, perm);
   if (out_fd == -1) {
-    fprintf(LOGFILE, "Can't open %s for output - %s\n", out_filename, 
+    fprintf(LOGFILE, "Can't open %s for output - %s\n", out_filename,
             strerror(errno));
     return -1;
   }
@@ -849,13 +856,13 @@ static int copy_file(int input, const char* in_filename,
     len = read(input, buffer, buffer_size);
   }
   if (len < 0) {
-    fprintf(LOGFILE, "Failed to read file %s - %s\n", in_filename, 
+    fprintf(LOGFILE, "Failed to read file %s - %s\n", in_filename,
 	    strerror(errno));
     close(out_fd);
     return -1;
   }
   if (close(out_fd) != 0) {
-    fprintf(LOGFILE, "Failed to close file %s - %s\n", out_filename, 
+    fprintf(LOGFILE, "Failed to close file %s - %s\n", out_filename,
 	    strerror(errno));
     return -1;
   }
@@ -1051,7 +1058,7 @@ int launch_container_as_user(const char *user, const char *app_id,
     goto cleanup;
   }
 
-  // setsid 
+  // setsid
   pid_t pid = setsid();
   if (pid == -1) {
     exit_code = SETSID_OPER_FAILED;
@@ -1065,12 +1072,14 @@ int launch_container_as_user(const char *user, const char *app_id,
     goto cleanup;
   }
 
+#ifdef __linux
+  fprintf(LOGFILE, "Writing to cgroup task files...\n");
   // cgroups-based resource enforcement
   if (resources_key != NULL && ! strcmp(resources_key, "cgroups")) {
 
     // write pid to cgroups
     char* const* cgroup_ptr;
-    for (cgroup_ptr = resources_values; cgroup_ptr != NULL && 
+    for (cgroup_ptr = resources_values; cgroup_ptr != NULL &&
          *cgroup_ptr != NULL; ++cgroup_ptr) {
       if (strcmp(*cgroup_ptr, "none") != 0 &&
             write_pid_to_cgroup_as_root(*cgroup_ptr, pid) != 0) {
@@ -1079,6 +1088,7 @@ int launch_container_as_user(const char *user, const char *app_id,
       }
     }
   }
+#endif
 
   // create the user directory on all disks
   int result = initialize_user(user, local_dirs);
@@ -1168,11 +1178,8 @@ int signal_container_as_user(const char *user, int pid, int sig) {
 
   if (kill(-pid, sig) < 0) {
     if(errno != ESRCH) {
-      fprintf(LOGFILE, 
-              "Error signalling process group %d with signal %d - %s\n", 
-              -pid, sig, strerror(errno));
-      fprintf(stderr, 
-              "Error signalling process group %d with signal %d - %s\n", 
+      fprintf(LOGFILE,
+              "Error signalling process group %d with signal %d - %s\n",
               -pid, sig, strerror(errno));
       fflush(LOGFILE);
       return UNABLE_TO_SIGNAL_CONTAINER;
@@ -1209,7 +1216,7 @@ static int rmdir_as_nm(const char* path) {
  * full_path : the path to delete
  * needs_tt_user: the top level directory must be deleted by the tt user.
  */
-static int delete_path(const char *full_path, 
+static int delete_path(const char *full_path,
                        int needs_tt_user) {
   int exit_code = 0;
 
@@ -1402,7 +1409,7 @@ void chown_dir_contents(const char *dir_path, uid_t uid, gid_t gid) {
 
   char *buf = stpncpy(path_tmp, dir_path, strlen(dir_path));
   *buf++ = '/';
-     
+
   dp = opendir(dir_path);
   if (dp != NULL) {
     while (ep = readdir(dp)) {
@@ -1436,7 +1443,7 @@ int mount_cgroup(const char *pair, const char *hierarchy) {
       get_kv_value(pair, mount_path, strlen(pair)) < 0) {
     fprintf(LOGFILE, "Failed to mount cgroup controller; invalid option: %s\n",
               pair);
-    result = -1; 
+    result = -1;
   } else {
     if (mount("none", mount_path, "cgroup", 0, controller) == 0) {
       char *buf = stpncpy(hier_path, mount_path, strlen(mount_path));

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
index b1efd6a..2645dda 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
@@ -138,7 +138,7 @@ int signal_container_as_user(const char *user, int pid, int sig);
 // delete a directory (or file) recursively as the user. The directory
 // could optionally be relative to the baseDir set of directories (if the same
 // directory appears on multiple disk volumes, the disk volumes should be passed
-// as the baseDirs). If baseDirs is not specified, then dir_to_be_deleted is 
+// as the baseDirs). If baseDirs is not specified, then dir_to_be_deleted is
 // assumed as the absolute path
 int delete_as_user(const char *user,
                    const char *dir_to_be_deleted,

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/get_executable.c
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/get_executable.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/get_executable.c
new file mode 100644
index 0000000..cd89735
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/get_executable.c
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This code implements OS-specific ways to get the absolute
+ * filename of the executable.  Typically, one would use
+ * realpath(argv[0]) (or equivalent), however, because this
+ * code runs as setuid and will be used later on to determine
+ * relative paths, we want something a big more secure
+ * since argv[0] is replaceable by malicious code.
+ *
+ * NOTE! The value returned will be free()'d later on!
+ *
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "config.h"
+#include "configuration.h"
+#include "container-executor.h"
+
+/*
+ * A generic function to read a link and return
+ * the value for use with System V procfs.
+ * With much thanks to Tom Killian, Roger Faulkner,
+ * and Ron Gomes, this is pretty generic code.
+ *
+ * The various BSDs do not have (reliably)
+ * have /proc. Custom implementations follow.
+ */
+
+char *__get_exec_readproc(char *procfn) {
+  char *filename;
+  ssize_t len;
+
+  filename = malloc(EXECUTOR_PATH_MAX);
+  if (!filename) {
+    fprintf(ERRORFILE,"cannot allocate memory for filename: %s\n",strerror(errno));
+    exit(-1);
+  }
+  len = readlink(procfn, filename, EXECUTOR_PATH_MAX);
+  if (len == -1) {
+    fprintf(ERRORFILE,"Can't get executable name from %s - %s\n", procfn,
+            strerror(errno));
+    exit(-1);
+  } else if (len >= EXECUTOR_PATH_MAX) {
+    fprintf(ERRORFILE,"Executable name %.*s is longer than %d characters.\n",
+            EXECUTOR_PATH_MAX, filename, EXECUTOR_PATH_MAX);
+    exit(-1);
+  }
+  filename[len] = '\0';
+  return filename;
+}
+
+#ifdef __APPLE__
+
+/*
+ * Mac OS X doesn't have a procfs, but there is
+ * libproc which we can use instead.  It is available
+ * in most modern versions of OS X as of this writing (2016).
+ */
+
+#include <libproc.h>
+
+char* get_executable() {
+  char *filename;
+  pid_t pid;
+
+  filename = malloc(PROC_PIDPATHINFO_MAXSIZE);
+  if (!filename) {
+    fprintf(ERRORFILE,"cannot allocate memory for filename: %s\n",strerror(errno));
+    exit(-1);
+  }
+  pid = getpid();
+  if (proc_pidpath(pid,filename,PROC_PIDPATHINFO_MAXSIZE) <= 0) {
+    fprintf(ERRORFILE,"Can't get executable name from pid %u - %s\n", pid,
+            strerror(errno));
+    exit(-1);
+  }
+  return filename;
+}
+
+#elif defined(__linux)
+
+
+char* get_executable() {
+  return __get_exec_readproc("/proc/self/exe");
+}
+
+#elif defined(__sun)
+
+/*
+ * It's tempting to use getexecname(), but there is no guarantee
+ * we will get a full path and worse, we'd be reliant on getcwd()
+ * being where our exec is at. Instead, we'll use the /proc
+ * method, using the "invisible" /proc/self link that only the
+ * process itself can see. (Anyone that tells you /proc/self
+ * doesn't exist on Solaris hasn't read the proc(4) man page.)
+ */
+
+char* get_executable() {
+  return __get_exec_readproc("/proc/self/path/a.out");
+}
+
+#else
+
+#error Cannot safely determine executable path on this operating system.
+
+#endif

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
index 9b5e784..468aa76 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
@@ -63,6 +63,19 @@ void display_usage(FILE *stream) {
 	  DELETE_AS_USER);
 }
 
+static void flush_and_close_log_files() {
+  if (LOGFILE != NULL) {
+    fflush(LOGFILE);
+    fclose(LOGFILE);
+    LOGFILE = NULL;
+  }
+  if (ERRORFILE != NULL) {
+    fflush(ERRORFILE);
+    fclose(ERRORFILE);
+    ERRORFILE = NULL;
+  }
+}
+
 int main(int argc, char **argv) {
   int invalid_args = 0; 
   int do_check_setup = 0;
@@ -109,6 +122,11 @@ int main(int argc, char **argv) {
   char * dir_to_be_deleted = NULL;
 
   char *executable_file = get_executable();
+  if (!executable_file) {
+    fprintf(ERRORFILE,"realpath of executable: %s\n",strerror(errno));
+    flush_and_close_log_files();
+    exit(-1);
+  }
 
   char *orig_conf_file = HADOOP_CONF_DIR "/" CONF_FILENAME;
   char *conf_file = resolve_config_path(orig_conf_file, argv[0]);
@@ -116,10 +134,14 @@ int main(int argc, char **argv) {
   char *resources, *resources_key, *resources_value;
 
   if (conf_file == NULL) {
+    free(executable_file);
     fprintf(ERRORFILE, "Configuration file %s not found.\n", orig_conf_file);
+    flush_and_close_log_files();
     exit(INVALID_CONFIG_FILE);
   }
   if (check_configuration_permissions(conf_file) != 0) {
+    free(executable_file);
+    flush_and_close_log_files();
     exit(INVALID_CONFIG_FILE);
   }
   read_config(conf_file);
@@ -128,26 +150,42 @@ int main(int argc, char **argv) {
   // look up the node manager group in the config file
   char *nm_group = get_value(NM_GROUP_KEY);
   if (nm_group == NULL) {
+    free(executable_file);
     fprintf(ERRORFILE, "Can't get configured value for %s.\n", NM_GROUP_KEY);
+    flush_and_close_log_files();
     exit(INVALID_CONFIG_FILE);
   }
   struct group *group_info = getgrnam(nm_group);
   if (group_info == NULL) {
+    free(executable_file);
     fprintf(ERRORFILE, "Can't get group information for %s - %s.\n", nm_group,
             strerror(errno));
-    fflush(LOGFILE);
+    flush_and_close_log_files();
     exit(INVALID_CONFIG_FILE);
   }
   set_nm_uid(getuid(), group_info->gr_gid);
-  // if we are running from a setuid executable, make the real uid root
-  setuid(0);
-  // set the real and effective group id to the node manager group
-  setgid(group_info->gr_gid);
+  /*
+   * if we are running from a setuid executable, make the real uid root
+   * we're going to ignore this result just in case we aren't.
+   */
+  int ignore=setuid(0);
+
+  /*
+   * set the real and effective group id to the node manager group
+   * we're going to ignore this result just in case we aren't
+   */
+  ignore=setgid(group_info->gr_gid);
+
+  /* make the unused var warning to away */
+  ignore++;
 
   if (check_executor_permissions(executable_file) != 0) {
+    free(executable_file);
     fprintf(ERRORFILE, "Invalid permissions on container-executor binary.\n");
+    flush_and_close_log_files();
     return INVALID_CONTAINER_EXEC_PERMISSIONS;
   }
+  free(executable_file);
 
   if (do_check_setup != 0) {
     // basic setup checks done

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b6f3e1ac/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
index d748b85..bb52b4e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c
@@ -28,7 +28,19 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 
-#define TEST_ROOT "/tmp/test-container-executor"
+#ifdef __APPLE__
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFPreferences.h>
+
+#define TMPDIR "/private/tmp"
+#define RELTMPDIR "../.."
+#else
+#define RELTMPDIR ".."
+#define TMPDIR "/tmp"
+#endif
+
+#define TEST_ROOT TMPDIR "/test-container-executor"
+
 #define DONT_TOUCH_FILE "dont-touch-me"
 #define NM_LOCAL_DIRS       TEST_ROOT "/local-1," TEST_ROOT "/local-2," \
                TEST_ROOT "/local-3," TEST_ROOT "/local-4," TEST_ROOT "/local-5"
@@ -153,8 +165,8 @@ void check_pid_file(const char* pid_file, pid_t mypid) {
 }
 
 void test_get_user_directory() {
-  char *user_dir = get_user_directory("/tmp", "user");
-  char *expected = "/tmp/usercache/user";
+  char *user_dir = get_user_directory(TMPDIR, "user");
+  char *expected = TMPDIR "/usercache/user";
   if (strcmp(user_dir, expected) != 0) {
     printf("test_get_user_directory expected %s got %s\n", expected, user_dir);
     exit(1);
@@ -163,8 +175,8 @@ void test_get_user_directory() {
 }
 
 void test_get_app_directory() {
-  char *expected = "/tmp/usercache/user/appcache/app_200906101234_0001";
-  char *app_dir = (char *) get_app_directory("/tmp", "user",
+  char *expected = TMPDIR "/usercache/user/appcache/app_200906101234_0001";
+  char *app_dir = (char *) get_app_directory(TMPDIR, "user",
       "app_200906101234_0001");
   if (strcmp(app_dir, expected) != 0) {
     printf("test_get_app_directory expected %s got %s\n", expected, app_dir);
@@ -174,9 +186,9 @@ void test_get_app_directory() {
 }
 
 void test_get_container_directory() {
-  char *container_dir = get_container_work_directory("/tmp", "owen", "app_1",
+  char *container_dir = get_container_work_directory(TMPDIR, "owen", "app_1",
 						 "container_1");
-  char *expected = "/tmp/usercache/owen/appcache/app_1/container_1";
+  char *expected = TMPDIR"/usercache/owen/appcache/app_1/container_1";
   if (strcmp(container_dir, expected) != 0) {
     printf("Fail get_container_work_directory got %s expected %s\n",
 	   container_dir, expected);
@@ -186,9 +198,9 @@ void test_get_container_directory() {
 }
 
 void test_get_container_launcher_file() {
-  char *expected_file = ("/tmp/usercache/user/appcache/app_200906101234_0001"
+  char *expected_file = (TMPDIR"/usercache/user/appcache/app_200906101234_0001"
 			 "/launch_container.sh");
-  char *app_dir = get_app_directory("/tmp", "user",
+  char *app_dir = get_app_directory(TMPDIR, "user",
                                     "app_200906101234_0001");
   char *container_file =  get_container_launcher_file(app_dir);
   if (strcmp(container_file, expected_file) != 0) {
@@ -210,15 +222,15 @@ void test_get_app_log_dir() {
   free(logdir);
 }
 
-void test_check_user() {
+void test_check_user(int expectedFailure) {
   printf("\nTesting test_check_user\n");
   struct passwd *user = check_user(username);
-  if (user == NULL) {
+  if (user == NULL && !expectedFailure) {
     printf("FAIL: failed check for user %s\n", username);
     exit(1);
   }
   free(user);
-  if (check_user("lp") != NULL) {
+  if (check_user("lp") != NULL && !expectedFailure) {
     printf("FAIL: failed check for system user lp\n");
     exit(1);
   }
@@ -226,7 +238,7 @@ void test_check_user() {
     printf("FAIL: failed check for system user root\n");
     exit(1);
   }
-  if (check_user("daemon") == NULL) {
+  if (check_user("daemon") == NULL && !expectedFailure) {
     printf("FAIL: failed check for whitelisted system user daemon\n");
     exit(1);
   }
@@ -238,8 +250,9 @@ void test_resolve_config_path() {
     printf("FAIL: failed to resolve config_name on an absolute path name: /bin/ls\n");
     exit(1);
   }
-  if (strcmp(resolve_config_path("../bin/ls", "/bin/ls"), "/bin/ls") != 0) {
-    printf("FAIL: failed to resolve config_name on a relative path name: ../bin/ls (relative to /bin/ls)");
+  if (strcmp(resolve_config_path(RELTMPDIR TEST_ROOT, TEST_ROOT), TEST_ROOT) != 0) {
+    printf("FAIL: failed to resolve config_name on a relative path name: "
+           RELTMPDIR TEST_ROOT " (relative to " TEST_ROOT ")");
     exit(1);
   }
 }
@@ -262,9 +275,9 @@ void test_delete_container() {
     exit(1);
   }
   char* app_dir = get_app_directory(TEST_ROOT "/local-2", yarn_username, "app_1");
-  char* dont_touch = get_app_directory(TEST_ROOT "/local-2", yarn_username, 
+  char* dont_touch = get_app_directory(TEST_ROOT "/local-2", yarn_username,
                                        DONT_TOUCH_FILE);
-  char* container_dir = get_container_work_directory(TEST_ROOT "/local-2", 
+  char* container_dir = get_container_work_directory(TEST_ROOT "/local-2",
 					      yarn_username, "app_1", "container_1");
   char buffer[100000];
   sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", container_dir);
@@ -324,9 +337,9 @@ void test_delete_container() {
 
 void test_delete_app() {
   char* app_dir = get_app_directory(TEST_ROOT "/local-2", yarn_username, "app_2");
-  char* dont_touch = get_app_directory(TEST_ROOT "/local-2", yarn_username, 
+  char* dont_touch = get_app_directory(TEST_ROOT "/local-2", yarn_username,
                                        DONT_TOUCH_FILE);
-  char* container_dir = get_container_work_directory(TEST_ROOT "/local-2", 
+  char* container_dir = get_container_work_directory(TEST_ROOT "/local-2",
 					      yarn_username, "app_2", "container_1");
   char buffer[100000];
   sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", container_dir);
@@ -484,7 +497,7 @@ void test_signal_container_group() {
     exit(0);
   }
   printf("Child container launched as %d\n", child);
-  // there's a race condition for child calling change_user and us 
+  // there's a race condition for child calling change_user and us
   // calling signal_container_as_user, hence sleeping
   sleep(3);
   if (signal_container_as_user(yarn_username, child, SIGKILL) != 0) {
@@ -500,7 +513,7 @@ void test_signal_container_group() {
     exit(1);
   }
   if (WTERMSIG(status) != SIGKILL) {
-    printf("FAIL: child was killed with %d instead of %d\n", 
+    printf("FAIL: child was killed with %d instead of %d\n",
 	   WTERMSIG(status), SIGKILL);
     exit(1);
   }
@@ -546,7 +559,7 @@ void test_init_app() {
   fflush(stderr);
   pid_t child = fork();
   if (child == -1) {
-    printf("FAIL: failed to fork process for init_app - %s\n", 
+    printf("FAIL: failed to fork process for init_app - %s\n",
 	   strerror(errno));
     exit(1);
   } else if (child == 0) {
@@ -628,7 +641,7 @@ void test_run_container() {
     printf("FAIL: failed to seteuid back to user - %s\n", strerror(errno));
     exit(1);
   }
-  if (fprintf(script, "#!/bin/bash\n"
+  if (fprintf(script, "#!/usr/bin/env bash\n"
                      "touch foobar\n"
                      "exit 0") < 0) {
     printf("FAIL: fprintf failed - %s\n", strerror(errno));
@@ -640,17 +653,17 @@ void test_run_container() {
   }
   fflush(stdout);
   fflush(stderr);
-  char* container_dir = get_container_work_directory(TEST_ROOT "/local-1", 
+  char* container_dir = get_container_work_directory(TEST_ROOT "/local-1",
 					      yarn_username, "app_4", "container_1");
   const char * pid_file = TEST_ROOT "/pid.txt";
 
   pid_t child = fork();
   if (child == -1) {
-    printf("FAIL: failed to fork process for init_app - %s\n", 
+    printf("FAIL: failed to fork process for init_app - %s\n",
 	   strerror(errno));
     exit(1);
   } else if (child == 0) {
-    if (launch_container_as_user(yarn_username, "app_4", "container_1", 
+    if (launch_container_as_user(yarn_username, "app_4", "container_1",
           container_dir, script_name, TEST_ROOT "/creds.txt", pid_file,
           local_dirs, log_dirs,
           "cgroups", cgroups_pids) != 0) {
@@ -704,7 +717,7 @@ void test_run_container() {
 // effective user id. If executed by a super-user everything
 // gets tested. Here are different ways of execing the test binary:
 // 1. regular user assuming user == yarn user
-//    $ test-container-executor     
+//    $ test-container-executor
 // 2. regular user with a given yarn user
 //    $ test-container-executor yarn_user
 // 3. super user with a given user and assuming user == yarn user
@@ -712,6 +725,7 @@ void test_run_container() {
 // 4. super user with a given user and a given yarn user
 //    # test-container-executor user yarn_user
 int main(int argc, char **argv) {
+  int ret;
   LOGFILE = stdout;
   ERRORFILE = stderr;
 
@@ -719,7 +733,7 @@ int main(int argc, char **argv) {
   if (system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT)) {
     exit(1);
   }
-  
+
   if (mkdirs(TEST_ROOT "/logs/userlogs", 0755) != 0) {
     exit(1);
   }
@@ -778,12 +792,38 @@ int main(int argc, char **argv) {
   printf("\nTesting delete_app()\n");
   test_delete_app();
 
-  test_check_user();
+  test_check_user(0);
+
+#ifdef __APPLE__
+   printf("OS X: disabling CrashReporter\n");
+  /*
+   * disable the "unexpectedly quit" dialog box
+   * because we know we're going to make our container
+   * do exactly that.
+   */
+  CFStringRef crashType      = CFSTR("DialogType");
+  CFStringRef crashModeNone  = CFSTR("None");
+  CFStringRef crashAppID     = CFSTR("com.apple.CrashReporter");
+  CFStringRef crashOldMode   = CFPreferencesCopyAppValue(CFSTR("DialogType"), CFSTR("com.apple.CrashReporter"));
+
+  CFPreferencesSetAppValue(crashType, crashModeNone, crashAppID);
+  CFPreferencesAppSynchronize(crashAppID);
+#endif
 
   // the tests that change user need to be run in a subshell, so that
   // when they change user they don't give up our privs
   run_test_in_child("test_signal_container_group", test_signal_container_group);
 
+#ifdef __APPLE__
+  /*
+   * put the "unexpectedly quit" dialog back
+   */
+
+  CFPreferencesSetAppValue(crashType, crashOldMode, crashAppID);
+  CFPreferencesAppSynchronize(crashAppID);
+  printf("OS X: CrashReporter re-enabled\n");
+#endif
+
   // init app and run container can't be run if you aren't testing as root
   if (getuid() == 0) {
     // these tests do internal forks so that the change_owner and execs
@@ -792,7 +832,13 @@ int main(int argc, char **argv) {
     test_run_container();
   }
 
-  seteuid(0);
+  /*
+   * try to seteuid(0).  if it doesn't work, carry on anyway.
+   * we're going to capture the return value to get rid of a
+   * compiler warning.
+   */
+  ret=seteuid(0);
+  ret++;
   // test_delete_user must run as root since that's how we use the delete_as_user
   test_delete_user();
   free_configurations();
@@ -803,8 +849,19 @@ int main(int argc, char **argv) {
   }
 
   read_config(TEST_ROOT "/test.cfg");
+#ifdef __APPLE__
+  username = "_uucp";
+  test_check_user(1);
+
+  username = "_networkd";
+  test_check_user(1);
+#else
   username = "bin";
-  test_check_user();
+  test_check_user(1);
+
+  username = "sys";
+  test_check_user(1);
+#endif
 
   run("rm -fr " TEST_ROOT);
   printf("\nFinished tests\n");


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org