diff --git a/NEWS b/NEWS
index 05ad901293c43adc52922f98b41507c08f1687e4..15053d617a0dbae96fdbe4035dce0ac473e1ef4f 100644
--- a/NEWS
+++ b/NEWS
@@ -117,6 +117,7 @@ documents those changes that are of interest to users and administrators.
     --export sbatch/srun command line option, propagate the users'
     environ to the execution side.
  -- Fix job array scheduling anomaly that can stop scheduling of valid tasks.
+ -- Fix perl api tests for libslurmdb to work correctly.
 
 * Changes in Slurm 14.11.3
 ==========================
diff --git a/contribs/perlapi/libslurmdb/Makefile.am b/contribs/perlapi/libslurmdb/Makefile.am
index 92754461199945ac0fb34c97d2a0222ecbc5d975..e4c6c9303765a3926d452c06abc65bd13cd02ef7 100644
--- a/contribs/perlapi/libslurmdb/Makefile.am
+++ b/contribs/perlapi/libslurmdb/Makefile.am
@@ -26,6 +26,10 @@ $(perl_dir)/Makefile:	$(perl_dir)/Makefile.PL
 		for f in ${perl_sources}; do \
 			${LN_S} -f ${abs_srcdir}/$$f $$f; \
 		done; \
+		for f in ${test_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
 	fi
 	@cd $(perl_dir) && $(perlpath) Makefile.PL $(PERL_MM_PARAMS) prefix=${prefix} INSTALL_BASE= PERL_MM_OPT=
 
@@ -72,8 +76,21 @@ uninstall-local:
 clean-generic:
 	@cd $(perl_dir); \
 	$(MAKE) clean; \
-	cd ..; \
-	rm -f *.so
+	if test "x${top_srcdir}" != "x${top_builddir}"; then \
+		rm -fr lib t *c *h *xs typemap classmap; \
+	fi; \
+	cd ..;
+
+	@if test "x${top_srcdir}" != "x${top_builddir}"; then \
+		for f in ${perl_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
+		for f in ${test_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
+	fi
 
 distclean-generic:
 	@cd $(perl_dir); \
@@ -89,6 +106,10 @@ distclean-generic:
 		for f in ${perl_sources}; do \
 			${LN_S} -f ${abs_srcdir}/$$f $$f; \
 		done; \
+		for f in ${test_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
 	fi
 
 AM_CPPFLAGS = \
diff --git a/contribs/perlapi/libslurmdb/Makefile.in b/contribs/perlapi/libslurmdb/Makefile.in
index 72b4ebc88bebcb7d766a81b6f387d6ea132cd7af..3a3a2365693cef4412f72fd2ab196f2a35fd4f2f 100644
--- a/contribs/perlapi/libslurmdb/Makefile.in
+++ b/contribs/perlapi/libslurmdb/Makefile.in
@@ -611,6 +611,10 @@ $(perl_dir)/Makefile:	$(perl_dir)/Makefile.PL
 		for f in ${perl_sources}; do \
 			${LN_S} -f ${abs_srcdir}/$$f $$f; \
 		done; \
+		for f in ${test_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
 	fi
 	@cd $(perl_dir) && $(perlpath) Makefile.PL $(PERL_MM_PARAMS) prefix=${prefix} INSTALL_BASE= PERL_MM_OPT=
 
@@ -654,8 +658,21 @@ uninstall-local:
 clean-generic:
 	@cd $(perl_dir); \
 	$(MAKE) clean; \
-	cd ..; \
-	rm -f *.so
+	if test "x${top_srcdir}" != "x${top_builddir}"; then \
+		rm -fr lib t *c *h *xs typemap classmap; \
+	fi; \
+	cd ..;
+
+	@if test "x${top_srcdir}" != "x${top_builddir}"; then \
+		for f in ${perl_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
+		for f in ${test_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
+	fi
 
 distclean-generic:
 	@cd $(perl_dir); \
@@ -671,6 +688,10 @@ distclean-generic:
 		for f in ${perl_sources}; do \
 			${LN_S} -f ${abs_srcdir}/$$f $$f; \
 		done; \
+		for f in ${test_sources}; do \
+			$(mkdir_p) `dirname $$f`; \
+			${LN_S} -f ${abs_srcdir}/$$f $$f; \
+		done; \
 	fi
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/contribs/perlapi/libslurmdb/perl/Makefile.PL.in b/contribs/perlapi/libslurmdb/perl/Makefile.PL.in
index 72b288cc274dc6813768b3d1df74a361b5b75a07..b8dae55c9e16c47571af1caa69a3c54369dd6c2a 100644
--- a/contribs/perlapi/libslurmdb/perl/Makefile.PL.in
+++ b/contribs/perlapi/libslurmdb/perl/Makefile.PL.in
@@ -93,27 +93,223 @@ WriteMakefile(
     # Un-comment this if you add C files to link with later:
     OBJECT            => '$(O_FILES)', # link all the C files too
     CCFLAGS           => '-g',
-    PM                => {'Slurmdb.pm' => '$(INST_LIBDIR)/Slurmdb.pm'},
     dynamic_lib       => {'OTHERLDFLAGS' => $other_ld_flags},
 );
+
 if  (eval {require ExtUtils::Constant; 1}) {
-  # If you edit these definitions to change the constants used by this module,
-  # you will need to use the generated const-c.inc and const-xs.inc
-  # files to replace their "fallback" counterparts before distributing your
-  # changes.
-  my @names = (qw(SLURMDB_CLASSIFIED_FLAG
+	# If you edit these definitions to change the constants used by this module,
+	# you will need to use the generated const-c.inc and const-xs.inc
+	# files to replace their "fallback" counterparts before distributing your
+	# changes.
+	my @names = (qw(SLURMDB_CLASSIFIED_FLAG
 		 SLURMDB_CLASS_BASE SLURMDB_PURGE_ARCHIVE SLURMDB_PURGE_BASE
 		 SLURMDB_PURGE_DAYS SLURMDB_PURGE_FLAGS SLURMDB_PURGE_HOURS
 		 SLURMDB_PURGE_MONTHS),
-              );
-  ExtUtils::Constant::WriteConstants(
-                                     NAME         => 'Slurmdb',
-                                     NAMES        => \@names,
-                                     C_FILE       => 'const-c.inc',
-                                     XS_FILE      => 'const-xs.inc',
-                                  );
+		);
+	ExtUtils::Constant::WriteConstants(
+		NAME         => 'Slurmdb',
+		NAMES        => \@names,
+		C_FILE       => 'const-c.inc',
+		XS_FILE      => 'const-xs.inc',
+		);
+}
+
+# Override the install routine to add our additional install dirs and
+# hack DESTDIR support into old EU::MMs.
+sub MY::install {
+	package MY;
+	my $self = shift;
+	my @code = split(/\n/, $self->SUPER::install(@_));
+	init_MY_globals($self);
+
+	foreach (@code) {
+		# Write the correct path to perllocal.pod
+		next if /installed into/;
+
+		# Replace all other $(INSTALL*) vars (except $(INSTALLDIRS) of course)
+		# with their $(DESTINSTALL*) counterparts
+		s/\Q$(\E(INSTALL(?!DIRS)${MACRO_RE})\Q)\E/\$(DEST$1)/g;
+	 }
+
+	 clean_MY_globals($self);
+	 return join("\n", @code);
+}
+
+# Now override the constants routine to add our own macros.
+sub MY::constants {
+	package MY;
+	my $self = shift;
+	my @code = split(/\n/, $self->SUPER::constants(@_));
+	init_MY_globals($self);
+
+	foreach my $line (@code) {
+		# Skip comments
+		next if $line =~ /^\s*\#/;
+		# Skip everything which isn't a var assignment.
+		next unless line_has_macro_def($line);
+
+		#tore the assignment string if necessary.
+		set_EQ_from_line($line);
+
+		# Add some "dummy" (PERL|SITE|VENDOR)PREFIX macros for later use (only if
+		# necessary for old EU::MMs of course)
+		if (line_has_macro_def($line, 'PREFIX')) {
+			foreach my $r (@REPOSITORIES) {
+				my $rprefix = "${r}PREFIX";
+
+				if (!defined(get_macro($rprefix))) {
+					set_macro($rprefix, macro_ref('PREFIX'));
+					$line .= "\n" . macro_def($rprefix);
+				}
+			}
+		}
+
+ 		# fix problem with /usr(/local) being used as a prefix
+		# instead of the real thing.
+
+		if ($line =~ 'INSTALL') {
+			$line =~ s/= \/usr\/local/= \$(PREFIX)/;
+			$line =~ s/= \/usr/= \$(PREFIX)/;
+		}
+
+		# Add DESTDIR support if necessary
+		if (line_has_macro_def($line, 'INSTALLDIRS')) {
+			if(!get_macro('DESTDIR')) {
+				$line .= "\n" . macro_def('DESTDIR');
+			}
+		} elsif (line_has_macro_def($line,
+					    qr/INSTALL${MACRO_RE}/)) {
+			my $macro = get_macro_name_from_line($line);
+			if(!get_macro('DEST' . $macro,
+				      macro_ref('DESTDIR')
+				      . macro_ref($macro))) {
+				$line .= "\n"
+					. macro_def('DEST' . $macro,
+						    macro_ref('DESTDIR')
+						    . macro_ref($macro));
+			}
+		}
+	}
+	push(@code, qq{});
 
+	clean_MY_globals($self);
+	return join("\n", @code);
 }
-else {
-	die "Error creating constant files: $!";
+
+
+package MY;
+
+use vars qw(
+  @REPOSITORIES
+
+  $MY_GLOBALS_ARE_SANE
+
+  $MACRO_RE
+  $EQ_RE
+  $EQ
+
+  $SELF
+);
+
+
+sub line_has_macro_def {
+	my($line, $name) = (@_, undef);
+	$name = $MACRO_RE unless defined $name;
+
+	return $line =~ /^($name)${EQ_RE}/;
+}
+
+
+sub macro_def {
+	my($name, $val) = (@_, undef);
+	my $error_message = "Problems building report error.";
+
+	die $error_message  unless defined $name;
+	die $error_message  unless defined $EQ;
+	$val = $SELF->{$name} unless defined $val;
+
+	return $name . $EQ . $val;
+}
+
+sub set_EQ_from_line {
+	my($line) = (@_);
+
+	return if defined($EQ);
+
+	$line =~ /\S(${EQ_RE})/;
+	$EQ = $1;
+}
+
+# Reads the name of the macro defined on the given line.
+#
+# The first parameter must be the line to be expected. If the line doesn't
+# contain a macro definition, weird things may happen. So check with
+# line_has_macro_def() before!
+sub get_macro_name_from_line {
+	my($line) = (@_);
+
+	$line =~ /^(${MACRO_RE})${EQ_RE}/;
+	return $1;
+}
+
+sub macro_ref {
+	my($name) = (@_);
+
+	return sprintf('$(%s)', $name);
+}
+
+# Reads the value of the given macro from the current instance of EU::MM.
+#
+# The first parameter must be the name of a macro.
+sub get_macro {
+	my($name) = (@_);
+
+	return $SELF->{$name};
+}
+
+# Sets the value of the macro with the given name to the given value in the
+# current instance of EU::MM. Just sets, doesn't write to the Makefile!
+#
+# The first parameter must be the macro's name, the second the value.
+sub set_macro {
+	my($name, $val) = (@_);
+
+	$SELF->{$name} = $val;
+}
+
+# For some reason initializing the vars on the global scope doesn't work;
+# guess its some weird Perl behaviour in combination with bless().
+sub init_MY_globals {
+	my $self = shift;
+
+	# Keep a reference to ourselves so we don't have to feed it to the helper
+	# scripts.
+	$SELF = $self;
+
+	return if $MY_GLOBALS_ARE_SANE;
+
+	$MY_GLOBALS_ARE_SANE = 1;
+
+	@REPOSITORIES = qw(
+			   PERL
+			   SITE
+			   VENDOR
+			   );
+
+	# Macro names follow this RE -- at least stricly enough for our purposes.
+	$MACRO_RE = qr/[A-Z0-9_]+/;
+	# Normally macros are assigned via FOO = bar. But the part with the equal
+	# sign might differ from platform to platform. So we use this RE:
+	$EQ_RE = qr/\s*:?=\s*/;
+	# To assign or own macros we'll follow the first assignment string we find;
+	# normally " = ".
+	$EQ = undef;
+
+}
+
+# Unset $SELF to avoid any leaking memory.
+sub clean_MY_globals {
+	my $self = shift;
+
+	$SELF = undef;
 }
diff --git a/contribs/perlapi/libslurmdb/perl/t/01-clusters_get.t b/contribs/perlapi/libslurmdb/perl/t/01-clusters_get.t
index 3dbcf0bb1cb4cba68447fbb67e94ae92ce456e75..af32b6ccc8c297cac1be16c68d2a7fef8a956ff4 100755
--- a/contribs/perlapi/libslurmdb/perl/t/01-clusters_get.t
+++ b/contribs/perlapi/libslurmdb/perl/t/01-clusters_get.t
@@ -35,5 +35,5 @@ for (my $i = 0; $i < @$clusters; $i++) {
       print "rpc_version    $clusters->[$i]{'rpc_version'}\n\n";
 }
 
-my $rc = Slurmdb::connection_close($db_conn);
+my $rc = Slurmdb::connection_close(\$db_conn);
 ok( $rc == 0, 'connection_close' );
diff --git a/contribs/perlapi/libslurmdb/perl/t/02-report_cluster_account_by_user.t b/contribs/perlapi/libslurmdb/perl/t/02-report_cluster_account_by_user.t
index dd93b8477bf3146ef74fc876bcf0f00cd2fe808e..d5f5622e3828dce5ab696e3b3ea4d8bcc88fb68f 100755
--- a/contribs/perlapi/libslurmdb/perl/t/02-report_cluster_account_by_user.t
+++ b/contribs/perlapi/libslurmdb/perl/t/02-report_cluster_account_by_user.t
@@ -63,5 +63,5 @@ for (my $i = 0; $i < @$clusters; $i++) {
     print "\n";
 }
 
-my $rc = Slurmdb::connection_close($db_conn);
+my $rc = Slurmdb::connection_close(\$db_conn);
 ok( $rc == 0, 'connection_close' );
diff --git a/contribs/perlapi/libslurmdb/perl/t/03-report_cluster_user_by_account.t b/contribs/perlapi/libslurmdb/perl/t/03-report_cluster_user_by_account.t
index c0d6af5ad0706394f520effab0aeab250b603b85..97af36e65d4db3a86fa1c151b91cadd5025c4403 100755
--- a/contribs/perlapi/libslurmdb/perl/t/03-report_cluster_user_by_account.t
+++ b/contribs/perlapi/libslurmdb/perl/t/03-report_cluster_user_by_account.t
@@ -63,5 +63,5 @@ for (my $i = 0; $i < @$clusters; $i++) {
     print "\n";
 }
 
-my $rc = Slurmdb::connection_close($db_conn);
+my $rc = Slurmdb::connection_close(\$db_conn);
 ok( $rc == 0, 'connection_close' );
diff --git a/contribs/perlapi/libslurmdb/perl/t/04-report_job_sizes_grouped_by_top_account.t b/contribs/perlapi/libslurmdb/perl/t/04-report_job_sizes_grouped_by_top_account.t
index 1b216790752313ab6e7797bb0219db69e84fa14e..bc3d9a505de590fab7e357330f0b4f4f20a11a96 100755
--- a/contribs/perlapi/libslurmdb/perl/t/04-report_job_sizes_grouped_by_top_account.t
+++ b/contribs/perlapi/libslurmdb/perl/t/04-report_job_sizes_grouped_by_top_account.t
@@ -46,5 +46,5 @@ for (my $i = 0; $i < @$clusters; $i++) {
     print "\n";
 }
 
-my $rc = Slurmdb::connection_close($db_conn);
+my $rc = Slurmdb::connection_close(\$db_conn);
 ok( $rc == 0, 'connection_close' );
diff --git a/contribs/perlapi/libslurmdb/perl/t/05-report_user_top_usage.t b/contribs/perlapi/libslurmdb/perl/t/05-report_user_top_usage.t
index 67d446affd15eb047fcf477ffc0a2da0a698cfdf..e3765c2080d0a887ef20f84e70d64df39f49325d 100755
--- a/contribs/perlapi/libslurmdb/perl/t/05-report_user_top_usage.t
+++ b/contribs/perlapi/libslurmdb/perl/t/05-report_user_top_usage.t
@@ -65,5 +65,5 @@ for (my $i = 0; $i < @$clusters; $i++) {
     print "\n";
 }
 
-my $rc = Slurmdb::connection_close($db_conn);
+my $rc = Slurmdb::connection_close(\$db_conn);
 ok( $rc == 0, 'connection_close' );
diff --git a/doc/html/download.shtml b/doc/html/download.shtml
index 85bf2d302ec48054c9df82340655ded976b01d5c..05510c4f22a48307e4a6e84bdd3652f5f06bc52b 100644
--- a/doc/html/download.shtml
+++ b/doc/html/download.shtml
@@ -9,11 +9,6 @@ Slurm has also been packaged for
 <a href="http://packages.ubuntu.com/src:slurm-llnl">Ubuntu</a>
 (both named <i>slurm-llnl</i>).</p>
 
-<p>A <a href="http://www.bsc.es/marenostrum-support-services/services/slurm-simulator">Slurm simulator</a>
-is available to assess various scheduling policies.
-Under simulation, jobs are not actually executed. Instead, a job execution trace
-from a real system, or a synthetic trace, are used.</p>
-
 <!--
 Slurm interface to PHP
 https://github.com/jcftang/slurm/commits/php-slurm
@@ -159,6 +154,13 @@ http://io-watchdog.googlecode.com/files/io-watchdog-0.6.tar.bz2</a></li><br>
 <li><a href="http://www.quadrics.com/">Quadrics MPI</a></li>
 </ul><br>
 
+<li><b>Workload Simulator</b><br>
+A <a href="http://www.bsc.es/marenostrum-support-services/services/slurm-simulator">Slurm simulator</a>
+is available to assess various scheduling policies using historic workload data.
+Under simulation, jobs are not actually executed. Instead, a job execution trace
+from a real system, or a synthetic trace, are used.<br>
+<b>NOTE:</b> This sofware is currently not maintained.</li><br>
+
 <li><b>PAM Module (pam_slurm)</b><br>
 Pluggable Authentication Module (PAM) for restricting access to compute nodes
 where Slurm performs workload management. Access to the node is restricted to
@@ -356,6 +358,6 @@ easy and elegantly manner.
 
 </ul>
 
-<p style="text-align:center;">Last modified 16 January 2015</p>
+<p style="text-align:center;">Last modified 22 January 2015</p>
 
 <!--#include virtual="footer.txt"-->
diff --git a/src/common/timers.c b/src/common/timers.c
index f5c9bc24524a6b4cb79d26f71447c244a2068fcb..1c07b097a819c32df28a94757c0e0e953eacb951 100644
--- a/src/common/timers.c
+++ b/src/common/timers.c
@@ -56,21 +56,36 @@ extern void slurm_diff_tv_str(struct timeval *tv1, struct timeval *tv2,
 {
 	char p[64] = "";
 	struct tm tm;
+	int debug_limit = limit;
 
 	(*delta_t)  = (tv2->tv_sec  - tv1->tv_sec) * 1000000;
 	(*delta_t) +=  tv2->tv_usec - tv1->tv_usec;
 	snprintf(tv_str, len_tv_str, "usec=%ld", *delta_t);
 	if (from) {
-		if (!limit)
-			limit = 1000000;
-		if (*delta_t > limit) {
+		if (!limit) {
+			/* NOTE: The slurmctld scheduler's default run time
+			 * limit is 4 seconds, but that would not typically
+			 * be reached. See "max_sched_time=" logic in
+			 * src/slurmctld/job_scheduler.c */
+			limit = 3000000;
+			debug_limit = 1000000;
+		}
+		if ((*delta_t > debug_limit) || (*delta_t > limit)) {
 			if (!localtime_r(&tv1->tv_sec, &tm))
-				fprintf(stderr, "localtime_r() failed\n");
+				error("localtime_r(): %m");
 			if (strftime(p, sizeof(p), "%T", &tm) == 0)
-				fprintf(stderr, "strftime() returned 0\n");
-			verbose("Warning: Note very large processing "
-				"time from %s: %s began=%s.%3.3d",
-				from, tv_str, p, (int)(tv1->tv_usec / 1000));
+				error("strftime(): %m");
+			if (*delta_t > limit) {
+				verbose("Warning: Note very large processing "
+					"time from %s: %s began=%s.%3.3d",
+					from, tv_str, p,
+					(int)(tv1->tv_usec / 1000));
+			} else {	/* Log anything over 1 second here */
+				debug("Note large processing time from %s: "
+				      "%s began=%s.%3.3d",
+				      from, tv_str, p,
+				      (int)(tv1->tv_usec / 1000));
+			}
 		}
 	}
 }