[condor: 17/31] LCMAPS and a few other development items.

Brian Bockelman bbockelm at fedoraproject.org
Fri Mar 8 01:21:03 UTC 2013


commit e23cb0470f96b822c5ca11bff92e352c3475b920
Author: Brian Bockelman <bbockelm at cse.unl.edu>
Date:   Thu Aug 16 07:22:38 2012 -0500

    LCMAPS and a few other development items.

 ...ser-s-condor_config-last-rather-than-firs.patch |  106 ++++++
 condor-lcmaps-env.sysconfig                        |   11 +
 condor.spec                                        |   17 +-
 condor_config.generic.patch                        |   11 -
 condor_oom_v2.patch                                |  340 ++++++++++++++++++++
 lcmaps_env_in_init_script.patch                    |   14 +
 zkm-782.patch                                      |   96 ++++++
 7 files changed, 582 insertions(+), 13 deletions(-)
---
diff --git a/0001-Apply-the-user-s-condor_config-last-rather-than-firs.patch b/0001-Apply-the-user-s-condor_config-last-rather-than-firs.patch
new file mode 100644
index 0000000..46ecc9a
--- /dev/null
+++ b/0001-Apply-the-user-s-condor_config-last-rather-than-firs.patch
@@ -0,0 +1,106 @@
+From 9cdc4723117927ecac26cc1ceca977063bf5de77 Mon Sep 17 00:00:00 2001
+From: Brian Bockelman <bbockelm at cse.unl.edu>
+Date: Tue, 24 Jul 2012 09:40:06 -0500
+Subject: [PATCH] Apply the user's condor_config last, rather than first.
+
+---
+ src/condor_utils/condor_config.cpp |   57 +++++++++++++++++++++++++++++-------
+ 1 files changed, 46 insertions(+), 11 deletions(-)
+
+diff --git a/src/condor_utils/condor_config.cpp b/src/condor_utils/condor_config.cpp
+index fc760fa..72ad7b8 100644
+--- a/src/condor_utils/condor_config.cpp
++++ b/src/condor_utils/condor_config.cpp
+@@ -110,6 +110,7 @@ void check_params();
+ // External variables
+ extern int	ConfigLineNo;
+ }  /* End extern "C" */
++bool find_user_file(std::string &);
+ 
+ // Global variables
+ BUCKET	*ConfigTab[TABLESIZE];
+@@ -708,7 +709,15 @@ real_config(char* host, int wantsQuiet, bool wantExtraInfo)
+     if ( param_boolean("NET_REMAP_ENABLE", false) ) {
+         condor_net_remap_config();
+     }
+-			
++
++		// Now, insert overrides from the user config file
++	std::string file_location;
++	if (find_user_file(file_location))
++	{
++		process_config_source( file_location.c_str(), "user local source", host, false );
++		local_config_sources.append(file_location.c_str());
++	}
++	
+ 		// Now, insert any macros defined in the environment.
+ 	char **my_environ = GetEnviron();
+ 	for( int i = 0; my_environ[i]; i++ ) {
+@@ -1051,6 +1060,38 @@ find_global()
+ }
+ 
+ 
++// Find user-specific location of a file
++// Returns true if found, and puts the location in the file_location argument.
++// If not found, returns false.  The contents of file_location are undefined.
++bool
++find_user_file(std::string &file_location)
++{
++#ifdef UNIX
++	// $HOME/.condor/condor_config
++	struct passwd *pw = getpwuid( geteuid() );
++	std::stringstream ss;
++	if ( can_switch_ids() || !pw || !pw->pw_dir ) {
++		return false;
++	}
++	ss << pw->pw_dir << "/." << myDistro->Get() << "/" << myDistro->Get() << "_config";
++	file_location = ss.str();
++
++	int fd;
++	if ((fd = safe_open_wrapper_follow(file_location.c_str(), O_RDONLY)) < 0) {
++		return false;
++	} else {
++		close(fd);
++		dprintf(D_FULLDEBUG, "Reading condor configuration from '%s'\n", file_location.c_str());
++	}
++
++	return true;
++#else
++	// To get rid of warnings...
++	file_location = "";
++	return false;
++#endif
++}
++
+ // Find location of specified file
+ char*
+ find_file(const char *env_name, const char *file_name)
+@@ -1107,21 +1148,15 @@ find_file(const char *env_name, const char *file_name)
+ 	if (!config_source) {
+ 			// List of condor_config file locations we'll try to open.
+ 			// As soon as we find one, we'll stop looking.
+-		const int locations_length = 4;
++		const int locations_length = 3;
+ 		MyString locations[locations_length];
+-			// 1) $HOME/.condor/condor_config
+-		struct passwd *pw = getpwuid( geteuid() );
+-		if ( !can_switch_ids() && pw && pw->pw_dir ) {
+-			sprintf( locations[0], "%s/.%s/%s", pw->pw_dir, myDistro->Get(),
+-					 file_name );
+-		}
+ 			// 2) /etc/condor/condor_config
+-		locations[1].sprintf( "/etc/%s/%s", myDistro->Get(), file_name );
++		locations[0].sprintf( "/etc/%s/%s", myDistro->Get(), file_name );
+ 			// 3) /usr/local/etc/condor_config (FreeBSD)
+-		locations[2].sprintf( "/usr/local/etc/%s", file_name );
++		locations[1].sprintf( "/usr/local/etc/%s", file_name );
+ 		if (tilde) {
+ 				// 4) ~condor/condor_config
+-			locations[3].sprintf( "%s/%s", tilde, file_name );
++			locations[2].sprintf( "%s/%s", tilde, file_name );
+ 		}
+ 
+ 		int ctr;	
+-- 
+1.7.4.1
+
diff --git a/condor-lcmaps-env.sysconfig b/condor-lcmaps-env.sysconfig
new file mode 100644
index 0000000..3fc576a
--- /dev/null
+++ b/condor-lcmaps-env.sysconfig
@@ -0,0 +1,11 @@
+export LLGT_LOG_IDENT=Condor-lcmaps
+export LLGT_VOMS_DISABLE_CREDENTIAL_CHECK=1
+export LCMAPS_DB_FILE=/etc/lcmaps.db
+export LCMAPS_POLICY_NAME=authorize_only
+#level 0: no messages, 1: errors, 2: also warnings, 3: also notices,
+#  4: also info, 5: maximum debug
+export LCMAPS_DEBUG_LEVEL=3
+
+# Condor does not want LCMAPS to change user for it
+export LLGT4_NO_CHANGE_USER=1
+
diff --git a/condor.spec b/condor.spec
index 8a61fd8..1907edf 100644
--- a/condor.spec
+++ b/condor.spec
@@ -33,12 +33,12 @@
 %define git_build 1
 # If building with git tarball, Fedora requests us to record the rev.  Use:
 # git log -1 --pretty=format:'%h'
-%define git_rev 70b9542
+%define git_rev ecc9193
 
 Summary: Condor: High Throughput Computing
 Name: condor
 Version: 7.9.1
-%define condor_base_release 0.8
+%define condor_base_release 0.11
 %if %git_build
 	%define condor_release %condor_base_release.%{git_rev}.git
 %else
@@ -111,6 +111,8 @@ Patch8: lcmaps_env_in_init_script.patch
 # See gt3158
 Patch9: 0001-Apply-the-user-s-condor_config-last-rather-than-firs.patch
 Patch11: condor_oom_v3.patch
+# From ZKM
+Patch12: zkm-782.patch
 
 BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 
@@ -402,6 +404,7 @@ exit 0
 %patch9 -p1
 #%patch10 -p1
 %patch11 -p1
+%patch12 -p1
 
 %if %systemd
 cp %{SOURCE2} %{name}-tmpfiles.conf
@@ -417,6 +420,7 @@ find src -perm /a+x -type f -name "*.[Cch]" -exec chmod a-x {} \;
 %build
 
 %cmake -DNO_PHONE_HOME:BOOL=TRUE \
+       -DBUILD_TESTING:BOOL=FALSE \
        -DHAVE_BACKFILL:BOOL=FALSE \
        -DHAVE_BOINC:BOOL=FALSE \
        -DWITH_GSOAP:BOOL=FALSE \
@@ -1096,6 +1100,15 @@ fi
 %endif
 
 %changelog
+* Wed Aug 15 2012 Brian Bockelman <bbockelm at cse.unl.edu> - 7.9.1-0.11.ecc9193.git
+- Fixes to the JobRouter configuration.
+
+* Tue Aug 14 2012 Brian Bockelman <bbockelm at cse.unl.edu> - 7.9.1-0.10.9e05bd9.git
+- Update to latest trunk so we can get the EditInPlace JobRouter configs.
+
+* Tue Aug 14 2012 Brian Bockelman <bbockelm at cse.unl.edu> - 7.9.1-0.9.70b9542.git
+- Fix to IP-verify from ZKM.
+
 * Tue Jul 24 2012 Brian Bockelman <bbockelm at cse.unl.edu> - 7.9.1-0.6.ceb6a0a.git
 - Fix per-user condor config to be more useful.  See gt3158
 
diff --git a/condor_config.generic.patch b/condor_config.generic.patch
index 7f141af..4cf69c1 100644
--- a/condor_config.generic.patch
+++ b/condor_config.generic.patch
@@ -209,17 +209,6 @@
  
  ##  JAVA_CLASSPATH_ARGUMENT describes the command-line parameter
  ##  used to introduce a new classpath:
-@@ -2275,8 +2326,8 @@
- 
- ## What kind of virtual machine program will be used for 
- ## the VM universe?
--## The two options are vmware and xen.  (Required)
--#VM_TYPE = vmware
-+## The three primary options are KVM, Xen and VMware.  (Required: no default)
-+#VM_TYPE = kvm
- 
- ## How much memory can be used for the VM universe? (Required)
- ## This value is the maximum amount of memory that can be used by the 
 @@ -2503,7 +2554,7 @@
  #SSH_TO_JOB_SSHD_ARGS = "-i -e -f %f"
  
diff --git a/condor_oom_v2.patch b/condor_oom_v2.patch
new file mode 100644
index 0000000..0521be6
--- /dev/null
+++ b/condor_oom_v2.patch
@@ -0,0 +1,340 @@
+diff --git a/build/cmake/CondorConfigure.cmake b/build/cmake/CondorConfigure.cmake
+index e61fb4f..1094cb3 100644
+--- a/build/cmake/CondorConfigure.cmake
++++ b/build/cmake/CondorConfigure.cmake
+@@ -164,6 +164,7 @@ if( NOT WINDOWS)
+ 	check_function_exists("setlinebuf" HAVE_SETLINEBUF)
+ 	check_function_exists("snprintf" HAVE_SNPRINTF)
+ 	check_function_exists("snprintf" HAVE_WORKING_SNPRINTF)
++	check_function_exists("eventfd" HAVE_EVENTFD)
+ 
+ 	check_function_exists("stat64" HAVE_STAT64)
+ 	check_function_exists("_stati64" HAVE__STATI64)
+diff --git a/src/condor_includes/config.h.cmake b/src/condor_includes/config.h.cmake
+index b083945..3bd92b0 100644
+--- a/src/condor_includes/config.h.cmake
++++ b/src/condor_includes/config.h.cmake
+@@ -438,6 +438,9 @@
+ /* Define to 1 if you have the 'snprintf' function. (USED)*/
+ #cmakedefine HAVE_SNPRINTF 1
+ 
++/* Define to 1 if you have the 'eventfd' function. (USED)*/
++#cmakedefine HAVE_EVENTFD 1
++
+ /* Define to 1 if you have the 'stat64' function. (USED)*/
+ #cmakedefine HAVE_STAT64 1
+ 
+diff --git a/src/condor_starter.V6.1/vanilla_proc.cpp b/src/condor_starter.V6.1/vanilla_proc.cpp
+index 2e5538f..fe02dd3 100644
+--- a/src/condor_starter.V6.1/vanilla_proc.cpp
++++ b/src/condor_starter.V6.1/vanilla_proc.cpp
+@@ -42,9 +42,16 @@
+ extern dynuser* myDynuser;
+ #endif
+ 
++#if defined(HAVE_EVENTFD)
++#include <sys/eventfd.h>
++#endif
++
+ extern CStarter *Starter;
+ 
+-VanillaProc::VanillaProc(ClassAd* jobAd) : OsProc(jobAd)
++VanillaProc::VanillaProc(ClassAd* jobAd) : OsProc(jobAd),
++	m_memory_limit(-1),
++	m_oom_fd(-1),
++	m_oom_efd(-1)
+ {
+ #if !defined(WIN32)
+ 	m_escalation_tid = -1;
+@@ -215,6 +222,12 @@ VanillaProc::StartJob()
+ 		}
+ 		fi.group_ptr = &tracking_gid;
+ 	}
++
++	// Increase the OOM score of this process; the child will inherit it.
++	// This way, the job will be heavily preferred to be killed over a normal process.
++	// OOM score is currently exponential - a score of 4 is a factor-16 increase in
++	// the OOM score.
++	setupOOMScore(4);
+ #endif
+ 
+ #if defined(HAVE_EXT_LIBCGROUP)
+@@ -406,6 +419,7 @@ VanillaProc::StartJob()
+ 			int MemMb;
+ 			if (MachineAd->LookupInteger(ATTR_MEMORY, MemMb)) {
+ 				uint64_t MemMb_big = MemMb;
++				m_memory_limit = MemMb_big;
+ 				climits.set_memory_limit_bytes(1024*1024*MemMb_big, mem_is_soft);
+ 			} else {
+ 				dprintf(D_ALWAYS, "Not setting memory soft limit in cgroup because "
+@@ -425,6 +439,14 @@ VanillaProc::StartJob()
+ 		} else {
+ 			dprintf(D_FULLDEBUG, "Invalid value of SlotWeight in machine ClassAd; ignoring.\n");
+ 		}
++		setupOOMEvent(cgroup);
++	}
++
++	// Now that the job is started, decrease the likelihood that the starter
++	// is killed instead of the job itself.
++	if (retval)
++	{
++		setupOOMScore(-4);
+ 	}
+ 
+ #endif
+@@ -611,5 +633,224 @@ VanillaProc::finishShutdownFast()
+ 	//   -gquinn, 2007-11-14
+ 	daemonCore->Kill_Family(JobPid);
+ 
++	if (m_oom_efd >= 0) {
++		dprintf(D_FULLDEBUG, "Closing event FD pipe in shutdown %d.\n", m_oom_efd);
++		daemonCore->Close_Pipe(m_oom_efd);
++		m_oom_efd = -1;
++	}
++	if (m_oom_fd >= 0) {
++		close(m_oom_fd);
++		m_oom_fd = -1;
++	}
++
+ 	return false;	// shutdown is pending, so return false
+ }
++
++/*
++ * This will be called when the event fd fires, indicating an OOM event.
++ */
++int
++VanillaProc::outOfMemoryEvent(int /* fd */)
++{
++	std::stringstream ss;
++	if (m_memory_limit >= 0) {
++		ss << "Job has gone over memory limit of " << m_memory_limit << " megabytes.";
++	} else {
++		ss << "Job has encountered an out-of-memory event.";
++	}
++	Starter->jic->holdJob(ss.str().c_str(), CONDOR_HOLD_CODE_JobOutOfResources, 0);
++
++	// this will actually clean up the job
++	if ( Starter->Hold( ) ) {
++		dprintf( D_FULLDEBUG, "All jobs were removed due to OOM event.\n" );
++		Starter->allJobsDone();
++	}
++
++	dprintf(D_FULLDEBUG, "Closing event FD pipe %d.\n", m_oom_efd);
++	daemonCore->Close_Pipe(m_oom_efd);
++	close(m_oom_fd);
++	m_oom_efd = -1;
++	m_oom_fd = -1;
++
++	Starter->ShutdownFast();
++
++	return 0;
++}
++
++int
++VanillaProc::setupOOMScore(int new_score)
++{
++#if !defined(LINUX)
++	if (new_score) // Done to suppress compiler warnings.
++		return 0;
++	return 0;
++#endif
++	TemporaryPrivSentry sentry(PRIV_ROOT);
++	// oom_adj is deprecated on modern kernels and causes a deprecation warning when used.
++	int oom_score_fd = open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
++	if (oom_score_fd == -1) {
++		if (errno != ENOENT) {
++			dprintf(D_ALWAYS,
++				"Unable to open oom_score_adj for the starter: (errno=%u, %s)\n",
++				errno, strerror(errno));
++			return 1;
++		} else {
++			int oom_score_fd = open("/proc/self/oom_adj", O_WRONLY | O_CLOEXEC);
++			if (oom_score_fd == -1) {
++				dprintf(D_ALWAYS,
++					"Unable to open oom_adj for the starter: (errno=%u, %s)\n",
++					errno, strerror(errno));
++				return 1;
++			}
++		}
++	} else {
++		// oom_score_adj is linear; oom_adj was exponential.
++		if (new_score > 0)
++			new_score = 1 << new_score;
++		else
++			new_score = -(1 << -new_score);
++	}
++
++	std::stringstream ss;
++	ss << new_score;
++	std::string new_score_str = ss.str();
++        ssize_t nwritten = full_write(oom_score_fd, new_score_str.c_str(), new_score_str.length());
++	if (nwritten < 0) {
++		dprintf(D_ALWAYS,
++			"Unable to write into oom_adj file for the starter: (errno=%u, %s)\n",
++			errno, strerror(errno));
++		close(oom_score_fd);
++		return 1;
++	}
++	close(oom_score_fd);
++	return 0;
++}
++
++int
++VanillaProc::setupOOMEvent(const std::string &cgroup_string)
++{
++#if !(defined(HAVE_EVENTFD) && defined(HAVE_EXT_LIBCGROUP))
++	return 0;
++#endif
++	// Initialize the event descriptor
++	m_oom_efd = eventfd(0, EFD_CLOEXEC);
++	if (m_oom_efd == -1) {
++		dprintf(D_ALWAYS,
++			"Unable to create new event FD for starter: %u %s\n",
++			errno, strerror(errno));
++		return 1;
++	}
++
++	// Find the memcg location on disk
++	void * handle = NULL;
++	struct cgroup_mount_point mount_info;
++	int ret = cgroup_get_controller_begin(&handle, &mount_info);
++	std::stringstream oom_control;
++	std::stringstream event_control;
++	bool found_memcg = false;
++	while (ret == 0) {
++		if (strcmp(mount_info.name, MEMORY_CONTROLLER_STR) == 0) {
++			found_memcg = true;
++			oom_control << mount_info.path << "/";
++			event_control << mount_info.path << "/";
++			break;
++		}
++		cgroup_get_controller_next(&handle, &mount_info);
++	}
++	if (!found_memcg && (ret != ECGEOF)) {
++		dprintf(D_ALWAYS,
++			"Error while locating memcg controller for starter: %u %s\n",
++			ret, cgroup_strerror(ret));
++		return 1;
++	}
++	cgroup_get_controller_end(&handle);
++	if (found_memcg == false) {
++		dprintf(D_ALWAYS,
++			"Memcg is not available; OOM notification disabled for starter.\n");
++		return 1;
++	}
++
++	// Finish constructing the location of the control files
++	oom_control << cgroup_string << "/memory.oom_control";
++	std::string oom_control_str = oom_control.str();
++	event_control << cgroup_string << "/cgroup.event_control";
++	std::string event_control_str = event_control.str();
++
++	// Open the oom_control and event control files
++	TemporaryPrivSentry sentry(PRIV_ROOT);
++	m_oom_fd = open(oom_control_str.c_str(), O_RDONLY | O_CLOEXEC);
++	if (m_oom_fd == -1) {
++		dprintf(D_ALWAYS,
++			"Unable to open the OOM control file for starter: %u %s\n",
++			errno, strerror(errno));
++		return 1;
++	}
++	int event_ctrl_fd = open(event_control_str.c_str(), O_WRONLY | O_CLOEXEC);
++	if (event_ctrl_fd == -1) {
++		dprintf(D_ALWAYS,
++			"Unable to open event control for starter: %u %s\n",
++			errno, strerror(errno));
++		return 1;
++	}
++
++	// Inform Linux we will be handling the OOM events for this container.
++	int oom_fd2 = open(oom_control_str.c_str(), O_WRONLY | O_CLOEXEC);
++	if (oom_fd2 == -1) {
++		dprintf(D_ALWAYS,
++			"Unable to open the OOM control file for writing for starter: %u %s\n",
++			errno, strerror(errno));
++		return 1;
++	}
++	const char limits [] = "1";
++        ssize_t nwritten = full_write(oom_fd2, &limits, 1);
++	if (nwritten < 0) {
++		dprintf(D_ALWAYS,
++			"Unable to set OOM control to %s for starter: %u %s\n",
++				limits, errno, strerror(errno));
++		close(event_ctrl_fd);
++		close(oom_fd2);
++		return 1;
++	}
++	close(oom_fd2);
++
++	// Create the subscription string:
++	std::stringstream sub_ss;
++	sub_ss << m_oom_efd << " " << m_oom_fd;
++	std::string sub_str = sub_ss.str();
++
++	if ((nwritten = full_write(event_ctrl_fd, sub_str.c_str(), sub_str.size())) < 0) {
++		dprintf(D_ALWAYS,
++			"Unable to write into event control file for starter: %u %s\n",
++			errno, strerror(errno));
++		close(event_ctrl_fd);
++		return 1;
++	}
++	close(event_ctrl_fd);
++
++	// Fool DC into talking to the eventfd
++	int pipes[2]; pipes[0] = -1; pipes[1] = -1;
++	int fd_to_replace = -1;
++	if (daemonCore->Create_Pipe(pipes, true) == -1 || pipes[0] == -1) {
++		dprintf(D_ALWAYS, "Unable to create a DC pipe\n");
++		close(m_oom_efd);
++		m_oom_efd = -1;
++		close(m_oom_fd);
++		m_oom_fd = -1;
++		return 1;
++	}
++	if ( daemonCore->Get_Pipe_FD(pipes[0], &fd_to_replace) == -1 || fd_to_replace == -1) {
++		dprintf(D_ALWAYS, "Unable to lookup pipe's FD\n");
++		close(m_oom_efd); m_oom_efd = -1;
++		close(m_oom_fd); m_oom_fd = -1;
++		daemonCore->Close_Pipe(pipes[0]);
++		daemonCore->Close_Pipe(pipes[1]);
++	}
++	dup3(m_oom_efd, fd_to_replace, O_CLOEXEC);
++	close(m_oom_efd);
++	m_oom_efd = pipes[0];
++
++	// Inform DC we want to recieve notifications from this FD.
++	daemonCore->Register_Pipe(pipes[0],"OOM event fd", static_cast<PipeHandlercpp>(&VanillaProc::outOfMemoryEvent),"OOM Event Handler",this,HANDLE_READ);
++	return 0;
++}
++
+diff --git a/src/condor_starter.V6.1/vanilla_proc.h b/src/condor_starter.V6.1/vanilla_proc.h
+index d524cf5..90b4741 100644
+--- a/src/condor_starter.V6.1/vanilla_proc.h
++++ b/src/condor_starter.V6.1/vanilla_proc.h
+@@ -74,6 +74,15 @@ private:
+ #if !defined(WIN32)
+ 	int m_escalation_tid;
+ #endif
++
++	// Configure OOM killer for this job
++	int m_memory_limit; // Memory limit, in MB.
++	int m_oom_fd; // The file descriptor which recieves events
++	int m_oom_efd; // The event FD to watch
++	int setupOOMScore(int new_score);
++	int outOfMemoryEvent(int fd);
++	int setupOOMEvent(const std::string & cgroup_string);
++
+ };
+ 
+ #endif
+diff --git a/src/condor_utils/condor_holdcodes.h b/src/condor_utils/condor_holdcodes.h
+index d788d6e..3083db3 100644
+--- a/src/condor_utils/condor_holdcodes.h
++++ b/src/condor_utils/condor_holdcodes.h
+@@ -128,4 +128,6 @@ const int CONDOR_HOLD_CODE_GlexecChownSandboxToCondor = 30;
+ 
+ const int CONDOR_HOLD_CODE_PrivsepChownSandboxToCondor = 31;
+ 
++const int CONDOR_HOLD_CODE_JobOutOfResources = 32;
++
+ #endif
diff --git a/lcmaps_env_in_init_script.patch b/lcmaps_env_in_init_script.patch
new file mode 100644
index 0000000..eb15981
--- /dev/null
+++ b/lcmaps_env_in_init_script.patch
@@ -0,0 +1,14 @@
+Index: condor-7.8.1/src/condor_examples/condor.init
+===================================================================
+--- condor-7.8.1.orig/src/condor_examples/condor.init	2012-06-18 13:41:42.000000003 -0500
++++ condor-7.8.1/src/condor_examples/condor.init	2012-06-18 13:58:43.000000003 -0500
+@@ -26,6 +26,9 @@
+ # Source function library
+ . /etc/init.d/functions
+ 
++# Source lcmaps environment vars
++[ -f /etc/sysconfig/condor-lcmaps-env ] && . /etc/sysconfig/condor-lcmaps-env
++
+ # Source networking configuration
+ [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
+ 
diff --git a/zkm-782.patch b/zkm-782.patch
new file mode 100644
index 0000000..971721a
--- /dev/null
+++ b/zkm-782.patch
@@ -0,0 +1,96 @@
+diff --git a/src/condor_utils/ipv6_hostname.cpp b/src/condor_utils/ipv6_hostname.cpp
+index cfefb4b..9df81c8 100644
+--- a/src/condor_utils/ipv6_hostname.cpp
++++ b/src/condor_utils/ipv6_hostname.cpp
+@@ -286,16 +286,49 @@ MyString get_hostname(const condor_sockaddr& addr) {
+ 	return ret;
+ }
+ 
++// will this work for ipv6?
++// 1) maybe... even probably.
++// 2) i don't care
++
++bool verify_name_has_ip(MyString name, condor_sockaddr addr){
++	std::vector<condor_sockaddr> addrs;
++	bool found = false;
++
++	addrs = resolve_hostname(name);
++	dprintf(D_FULLDEBUG, "IPVERIFY: checking %s against %s\n", name.Value(), addr.to_ip_string().Value());
++	for(unsigned int i = 0; i < addrs.size(); i++) {
++		// compare MyStrings
++		// addr.to_ip_string
++		if(addrs[i].to_ip_string() == addr.to_ip_string()) {
++			dprintf(D_FULLDEBUG, "IPVERIFY: matched %s to %s\n", addrs[i].to_ip_string().Value(), addr.to_ip_string().Value());
++			found = true;
++		} else {
++			dprintf(D_FULLDEBUG, "IPVERIFY: comparing %s to %s\n", addrs[i].to_ip_string().Value(), addr.to_ip_string().Value());
++		}
++	}
++	dprintf(D_FULLDEBUG, "IPVERIFY: ip found is %i\n", found);
++
++	return found;
++}
++
+ std::vector<MyString> get_hostname_with_alias(const condor_sockaddr& addr)
+ {
+-	std::vector<MyString> ret;
++	std::vector<MyString> prelim_ret;
++	std::vector<MyString> actual_ret;
++
+ 	MyString hostname = get_hostname(addr);
+ 	if (hostname.IsEmpty())
+-		return ret;
+-	ret.push_back(hostname);
++		return prelim_ret;
++
++	// we now start to construct a list (prelim_ret) of the hostname and all
++	// the aliases.  first the name itself.
++	prelim_ret.push_back(hostname);
+ 
+ 	if (nodns_enabled())
+-		return ret; // no need to call further DNS functions.
++		// don't need to verify this... the string is actually an IP here
++		return prelim_ret; // no need to call further DNS functions.
++
++	// now, add the aliases
+ 
+ 	hostent* ent;
+ 		//int aftype = addr.get_aftype();
+@@ -309,14 +342,31 @@ std::vector<MyString> get_hostname_with_alias(const condor_sockaddr& addr)
+ 		// IPv6 addresses?
+ 	ent = gethostbyname(hostname.Value());
+ 
+-	if (!ent)
+-		return ret;
++	if (ent) {
++		char** alias = ent->h_aliases;
++		for (; *alias; ++alias) {
++			prelim_ret.push_back(MyString(*alias));
++		}
++	}
+ 
+-	char** alias = ent->h_aliases;
+-	for (; *alias; ++alias) {
+-		ret.push_back(MyString(*alias));
++	// WARNING! there is a reason this is implimented as two separate loops,
++	// so please don't try to combine them.
++	//
++	// calling verify_name_has_ip() will potentially overwrite static data that
++	// is referred to by ent->h_aliases (man 3 gethostbyname, see notes).  so
++	// first, we push the name and then all aliases into the MyString vector
++	// prelim_ret, and then verify them in the following loop.
++
++	for (unsigned int i = 0; i < prelim_ret.size(); i++) {
++		if(verify_name_has_ip(prelim_ret[i], addr)) {
++			actual_ret.push_back(prelim_ret[i]);
++		} else {
++			dprintf(D_ALWAYS, "WARNING: forward resolution of %s doesn't match %s!\n",
++					prelim_ret[i].Value(), addr.to_ip_string().Value());
++		}
+ 	}
+-	return ret;
++
++	return actual_ret;
+ }
+ 
+ // look up FQDN for hostname and aliases.


More information about the scm-commits mailing list