YARN-5121. fix some container-executor portability issues. Contributed by Allen Wittenauer.
diff --git a/LICENSE.txt b/LICENSE.txt
index f4d869d..6910a09 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -414,6 +414,38 @@
(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:
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 a2f81d1..f10fa08 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
@@ -274,6 +274,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>
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 d4d6ae1..204b3ca 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
@@ -24,7 +24,20 @@
string(REPLACE "-D_FILE_OFFSET_BITS=64" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
include(CheckFunctionExists)
+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
@@ -46,6 +59,7 @@
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
@@ -60,6 +74,6 @@
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)
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
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_ */
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_ */
+
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_ */
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_ */
+
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_ */
+
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 3447524..69ceaf6 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"
@@ -68,7 +68,7 @@
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 %03lo\n",
file, (unsigned long)file_stat.st_mode & (~S_IFMT));
return 0;
@@ -92,8 +92,13 @@
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
@@ -102,7 +107,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
*/
@@ -155,7 +160,7 @@
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
@@ -235,7 +240,7 @@
free(line);
}
-
+
//close the file
fclose(conf_file);
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 8f87cb2..e7e5710 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
*/
@@ -78,7 +78,7 @@
/**
* 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.
@@ -91,7 +91,7 @@
/**
* 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.
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 e40101c..fef7173 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
@@ -40,6 +40,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[] = {"yarn", "mapred", "hdfs", "bin", 0};
@@ -84,31 +106,14 @@
return get_value(NM_GROUP_KEY, &executor_cfg);
}
-/**
- * get the executable filename.
- */
-char* get_executable() {
- char buffer[EXECUTOR_PATH_MAX];
- snprintf(buffer, EXECUTOR_PATH_MAX, "/proc/%" PRId64 "/exe", (int64_t)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!",
@@ -119,7 +124,7 @@
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;
}
@@ -181,6 +186,7 @@
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.
@@ -218,6 +224,7 @@
return 0;
}
+#endif
/**
* Write the pid of the current process into the pid file.
@@ -384,7 +391,7 @@
* 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;
}
@@ -396,7 +403,7 @@
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());
@@ -415,7 +422,7 @@
/**
* 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);
@@ -592,12 +599,12 @@
* 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;
}
@@ -605,7 +612,7 @@
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;
@@ -720,7 +727,7 @@
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);
@@ -848,7 +855,7 @@
}
if (change_effective_user(user, group) != 0) {
fprintf(LOGFILE, "Failed to change user to %i - %i\n", user, group);
-
+
ret = -1;
}
return ret;
@@ -881,14 +888,14 @@
* 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));
fflush(LOGFILE);
return -1;
@@ -910,13 +917,13 @@
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;
}
@@ -1328,20 +1335,22 @@
}
if (pid != 0) {
+#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 &&
+ // write pid to cgroups
+ char* const* cgroup_ptr;
+ for (cgroup_ptr = resources_values; cgroup_ptr != NULL &&
*cgroup_ptr != NULL; ++cgroup_ptr) {
- if (strcmp(*cgroup_ptr, "none") != 0 &&
+ if (strcmp(*cgroup_ptr, "none") != 0 &&
write_pid_to_cgroup_as_root(*cgroup_ptr, pid) != 0) {
- exit_code = WRITE_CGROUP_FAILED;
- goto cleanup;
- }
- }
+ exit_code = WRITE_CGROUP_FAILED;
+ goto cleanup;
+ }
+ }
}
+#endif
// write pid to pidfile
fprintf(LOGFILE, "Writing pid file...\n");
@@ -1481,7 +1490,7 @@
goto cleanup;
}
- // setsid
+ // setsid
pid_t pid = setsid();
if (pid == -1) {
exit_code = SETSID_OPER_FAILED;
@@ -1496,12 +1505,13 @@
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) {
@@ -1510,6 +1520,7 @@
}
}
}
+#endif
fprintf(LOGFILE, "Creating local dirs...\n");
exit_code = create_local_dirs(user, app_id, container_id,
@@ -1569,11 +1580,8 @@
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;
@@ -1794,7 +1802,7 @@
* 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 ret;
@@ -1900,7 +1908,7 @@
char *buf = stpncpy(path_tmp, dir_path, strlen(dir_path));
*buf++ = '/';
-
+
dp = opendir(dir_path);
if (dp != NULL) {
while ((ep = readdir(dp)) != NULL) {
@@ -1934,7 +1942,7 @@
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));
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 df5b7d8..1bfa3a5 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
@@ -177,7 +177,7 @@
// 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,
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
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 222467a..6fade5c 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
@@ -83,7 +83,7 @@
fclose(LOGFILE);
LOGFILE = NULL;
}
-
+
if (ERRORFILE != NULL) {
fflush(ERRORFILE);
fclose(ERRORFILE);
@@ -96,19 +96,27 @@
This function is to be called in every invocation of container-executor, irrespective
of whether an explicit checksetup operation is requested. */
-static void assert_valid_setup(char *current_executable) {
+static void assert_valid_setup() {
+ int ret;
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, current_executable);
+ char *conf_file = resolve_config_path(orig_conf_file, executable_file);
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);
}
@@ -118,28 +126,42 @@
// look up the node manager group in the config file
char *nm_group = get_nodemanager_group();
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));
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.
+ */
+ ret=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
+ */
+ ret=setgid(group_info->gr_gid);
+
+ /* make the unused var warning to away */
+ ret++;
if (check_executor_permissions(executable_file) != 0) {
+ free(executable_file);
fprintf(ERRORFILE, "Invalid permissions on container-executor binary.\n");
flush_and_close_log_files();
exit(INVALID_CONTAINER_EXEC_PERMISSIONS);
}
+ free(executable_file);
}
@@ -407,7 +429,7 @@
int main(int argc, char **argv) {
open_log_files();
- assert_valid_setup(argv[0]);
+ assert_valid_setup();
int operation;
int ret = validate_arguments(argc, argv, &operation);
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 e9ad370..a2dead2 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
@@ -29,7 +29,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"
@@ -155,8 +167,8 @@
}
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);
@@ -165,8 +177,8 @@
}
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);
@@ -176,9 +188,9 @@
}
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);
@@ -188,9 +200,9 @@
}
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) {
@@ -241,9 +253,9 @@
TEST_ROOT "\n");
exit(1);
}
- if (strcmp(resolve_config_path(".." TEST_ROOT, TEST_ROOT), TEST_ROOT) != 0) {
+ 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: "
- ".." TEST_ROOT " (relative to " TEST_ROOT ")");
+ RELTMPDIR TEST_ROOT " (relative to " TEST_ROOT ")");
exit(1);
}
}
@@ -266,9 +278,9 @@
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);
@@ -328,9 +340,9 @@
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);
@@ -488,7 +500,7 @@
exit(0);
}
printf("Child container launched as %" PRId64 "\n", (int64_t)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) {
@@ -504,7 +516,7 @@
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);
}
@@ -550,7 +562,7 @@
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) {
@@ -632,7 +644,7 @@
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));
@@ -644,17 +656,17 @@
}
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) {
@@ -802,7 +814,7 @@
// 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
@@ -810,6 +822,7 @@
// 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;
@@ -817,7 +830,7 @@
if (system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT)) {
exit(1);
}
-
+
if (mkdirs(TEST_ROOT "/logs/userlogs", 0755) != 0) {
exit(1);
}
@@ -881,10 +894,36 @@
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
@@ -893,7 +932,13 @@
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_executor_configurations();
@@ -904,11 +949,19 @@
}
read_executor_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(1);
username = "sys";
test_check_user(1);
+#endif
run("rm -fr " TEST_ROOT);
printf("\nFinished tests\n");