diff --git a/NEWS b/NEWS
index c562912fd84ef46e1a2992d9bced7affada67017..8e081cf2a0943558d7a294440e593d41e825a674 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ documents those changes that are of interest to users and administrators.
     getenv where the name was given a prefix of "SPANK_". That prefix has
     been removed for consistency with the environment variables available in
     the Prolog and Epilog scripts.
+ -- Major additions to the layouts framework code.
 
 * Changes in Slurm 15.08.0pre3
 ==============================
diff --git a/configure b/configure
index fd51929e075579cd3ea4fe6e1338ba45a252c845..447c48b889649afb457973502b5a6a3c193d13a4 100755
--- a/configure
+++ b/configure
@@ -23994,7 +23994,7 @@ fi
 
 
 
-ac_config_files="$ac_config_files Makefile config.xml auxdir/Makefile contribs/Makefile contribs/cray/Makefile contribs/lua/Makefile contribs/mic/Makefile contribs/pam/Makefile contribs/perlapi/Makefile contribs/perlapi/libslurm/Makefile contribs/perlapi/libslurm/perl/Makefile.PL contribs/perlapi/libslurmdb/Makefile contribs/perlapi/libslurmdb/perl/Makefile.PL contribs/torque/Makefile contribs/phpext/Makefile contribs/phpext/slurm_php/config.m4 contribs/sgather/Makefile contribs/sgi/Makefile contribs/sjobexit/Makefile contribs/slurmdb-direct/Makefile contribs/pmi2/Makefile doc/Makefile doc/man/Makefile doc/man/man1/Makefile doc/man/man3/Makefile doc/man/man5/Makefile doc/man/man8/Makefile doc/html/Makefile doc/html/configurator.html doc/html/configurator.easy.html etc/cgroup.release_common.example etc/init.d.slurm etc/init.d.slurmdbd etc/slurmctld.service etc/slurmd.service etc/slurmdbd.service src/Makefile src/api/Makefile src/common/Makefile src/db_api/Makefile src/database/Makefile src/sacct/Makefile src/sacctmgr/Makefile src/sreport/Makefile src/salloc/Makefile src/sbatch/Makefile src/sbcast/Makefile src/sattach/Makefile src/scancel/Makefile src/scontrol/Makefile src/sdiag/Makefile src/sinfo/Makefile src/slurmctld/Makefile src/slurmd/Makefile src/slurmd/common/Makefile src/slurmd/slurmd/Makefile src/slurmd/slurmstepd/Makefile src/slurmdbd/Makefile src/smap/Makefile src/smd/Makefile src/sprio/Makefile src/squeue/Makefile src/srun/Makefile src/srun/libsrun/Makefile src/srun_cr/Makefile src/sshare/Makefile src/sstat/Makefile src/strigger/Makefile src/sview/Makefile src/plugins/Makefile src/plugins/accounting_storage/Makefile src/plugins/accounting_storage/common/Makefile src/plugins/accounting_storage/filetxt/Makefile src/plugins/accounting_storage/mysql/Makefile src/plugins/accounting_storage/none/Makefile src/plugins/accounting_storage/slurmdbd/Makefile src/plugins/acct_gather_energy/Makefile src/plugins/acct_gather_energy/cray/Makefile src/plugins/acct_gather_energy/rapl/Makefile src/plugins/acct_gather_energy/ipmi/Makefile src/plugins/acct_gather_energy/none/Makefile src/plugins/acct_gather_infiniband/Makefile src/plugins/acct_gather_infiniband/ofed/Makefile src/plugins/acct_gather_infiniband/none/Makefile src/plugins/acct_gather_filesystem/Makefile src/plugins/acct_gather_filesystem/lustre/Makefile src/plugins/acct_gather_filesystem/none/Makefile src/plugins/acct_gather_profile/Makefile src/plugins/acct_gather_profile/hdf5/Makefile src/plugins/acct_gather_profile/hdf5/sh5util/Makefile src/plugins/acct_gather_profile/none/Makefile src/plugins/auth/Makefile src/plugins/auth/authd/Makefile src/plugins/auth/munge/Makefile src/plugins/auth/none/Makefile src/plugins/burst_buffer/Makefile src/plugins/burst_buffer/common/Makefile src/plugins/burst_buffer/cray/Makefile src/plugins/burst_buffer/generic/Makefile src/plugins/checkpoint/Makefile src/plugins/checkpoint/aix/Makefile src/plugins/checkpoint/blcr/Makefile src/plugins/checkpoint/blcr/cr_checkpoint.sh src/plugins/checkpoint/blcr/cr_restart.sh src/plugins/checkpoint/none/Makefile src/plugins/checkpoint/ompi/Makefile src/plugins/checkpoint/poe/Makefile src/plugins/core_spec/Makefile src/plugins/core_spec/cray/Makefile src/plugins/core_spec/none/Makefile src/plugins/crypto/Makefile src/plugins/crypto/munge/Makefile src/plugins/crypto/openssl/Makefile src/plugins/ext_sensors/Makefile src/plugins/ext_sensors/rrd/Makefile src/plugins/ext_sensors/none/Makefile src/plugins/gres/Makefile src/plugins/gres/gpu/Makefile src/plugins/gres/nic/Makefile src/plugins/gres/mic/Makefile src/plugins/jobacct_gather/Makefile src/plugins/jobacct_gather/common/Makefile src/plugins/jobacct_gather/linux/Makefile src/plugins/jobacct_gather/aix/Makefile src/plugins/jobacct_gather/cgroup/Makefile src/plugins/jobacct_gather/none/Makefile src/plugins/jobcomp/Makefile src/plugins/jobcomp/filetxt/Makefile src/plugins/jobcomp/none/Makefile src/plugins/jobcomp/script/Makefile src/plugins/jobcomp/mysql/Makefile src/plugins/job_container/Makefile src/plugins/job_container/cncu/Makefile src/plugins/job_container/none/Makefile src/plugins/job_submit/Makefile src/plugins/job_submit/all_partitions/Makefile src/plugins/job_submit/cnode/Makefile src/plugins/job_submit/cray/Makefile src/plugins/job_submit/defaults/Makefile src/plugins/job_submit/logging/Makefile src/plugins/job_submit/lua/Makefile src/plugins/job_submit/partition/Makefile src/plugins/job_submit/pbs/Makefile src/plugins/job_submit/require_timelimit/Makefile src/plugins/job_submit/throttle/Makefile src/plugins/launch/Makefile src/plugins/launch/aprun/Makefile src/plugins/launch/poe/Makefile src/plugins/launch/runjob/Makefile src/plugins/launch/slurm/Makefile src/plugins/power/Makefile src/plugins/power/common/Makefile src/plugins/power/cray/Makefile src/plugins/power/none/Makefile src/plugins/preempt/Makefile src/plugins/preempt/job_prio/Makefile src/plugins/preempt/none/Makefile src/plugins/preempt/partition_prio/Makefile src/plugins/preempt/qos/Makefile src/plugins/priority/Makefile src/plugins/priority/basic/Makefile src/plugins/priority/multifactor/Makefile src/plugins/proctrack/Makefile src/plugins/proctrack/aix/Makefile src/plugins/proctrack/cray/Makefile src/plugins/proctrack/cgroup/Makefile src/plugins/proctrack/pgid/Makefile src/plugins/proctrack/linuxproc/Makefile src/plugins/proctrack/sgi_job/Makefile src/plugins/proctrack/lua/Makefile src/plugins/route/Makefile src/plugins/route/default/Makefile src/plugins/route/topology/Makefile src/plugins/sched/Makefile src/plugins/sched/backfill/Makefile src/plugins/sched/builtin/Makefile src/plugins/sched/hold/Makefile src/plugins/sched/wiki/Makefile src/plugins/sched/wiki2/Makefile src/plugins/select/Makefile src/plugins/select/alps/Makefile src/plugins/select/alps/libalps/Makefile src/plugins/select/alps/libemulate/Makefile src/plugins/select/bluegene/Makefile src/plugins/select/bluegene/ba/Makefile src/plugins/select/bluegene/ba_bgq/Makefile src/plugins/select/bluegene/bl/Makefile src/plugins/select/bluegene/bl_bgq/Makefile src/plugins/select/bluegene/sfree/Makefile src/plugins/select/cons_res/Makefile src/plugins/select/cray/Makefile src/plugins/select/linear/Makefile src/plugins/select/other/Makefile src/plugins/select/serial/Makefile src/plugins/slurmctld/Makefile src/plugins/slurmctld/nonstop/Makefile src/plugins/slurmd/Makefile src/plugins/switch/Makefile src/plugins/switch/cray/Makefile src/plugins/switch/generic/Makefile src/plugins/switch/none/Makefile src/plugins/switch/nrt/Makefile src/plugins/switch/nrt/libpermapi/Makefile src/plugins/mpi/Makefile src/plugins/mpi/mpich1_p4/Makefile src/plugins/mpi/mpich1_shmem/Makefile src/plugins/mpi/mpichgm/Makefile src/plugins/mpi/mpichmx/Makefile src/plugins/mpi/mvapich/Makefile src/plugins/mpi/lam/Makefile src/plugins/mpi/none/Makefile src/plugins/mpi/openmpi/Makefile src/plugins/mpi/pmi2/Makefile src/plugins/task/Makefile src/plugins/task/affinity/Makefile src/plugins/task/cgroup/Makefile src/plugins/task/cray/Makefile src/plugins/task/none/Makefile src/plugins/topology/Makefile src/plugins/topology/3d_torus/Makefile src/plugins/topology/hypercube/Makefile src/plugins/topology/node_rank/Makefile src/plugins/topology/none/Makefile src/plugins/topology/tree/Makefile testsuite/Makefile testsuite/expect/Makefile testsuite/slurm_unit/Makefile testsuite/slurm_unit/api/Makefile testsuite/slurm_unit/api/manual/Makefile testsuite/slurm_unit/common/Makefile"
+ac_config_files="$ac_config_files Makefile config.xml auxdir/Makefile contribs/Makefile contribs/cray/Makefile contribs/lua/Makefile contribs/mic/Makefile contribs/pam/Makefile contribs/perlapi/Makefile contribs/perlapi/libslurm/Makefile contribs/perlapi/libslurm/perl/Makefile.PL contribs/perlapi/libslurmdb/Makefile contribs/perlapi/libslurmdb/perl/Makefile.PL contribs/torque/Makefile contribs/phpext/Makefile contribs/phpext/slurm_php/config.m4 contribs/sgather/Makefile contribs/sgi/Makefile contribs/sjobexit/Makefile contribs/slurmdb-direct/Makefile contribs/pmi2/Makefile doc/Makefile doc/man/Makefile doc/man/man1/Makefile doc/man/man3/Makefile doc/man/man5/Makefile doc/man/man8/Makefile doc/html/Makefile doc/html/configurator.html doc/html/configurator.easy.html etc/cgroup.release_common.example etc/init.d.slurm etc/init.d.slurmdbd etc/slurmctld.service etc/slurmd.service etc/slurmdbd.service src/Makefile src/api/Makefile src/common/Makefile src/db_api/Makefile src/layouts/Makefile src/layouts/unit/Makefile src/database/Makefile src/sacct/Makefile src/sacctmgr/Makefile src/sreport/Makefile src/salloc/Makefile src/sbatch/Makefile src/sbcast/Makefile src/sattach/Makefile src/scancel/Makefile src/scontrol/Makefile src/sdiag/Makefile src/sinfo/Makefile src/slurmctld/Makefile src/slurmd/Makefile src/slurmd/common/Makefile src/slurmd/slurmd/Makefile src/slurmd/slurmstepd/Makefile src/slurmdbd/Makefile src/smap/Makefile src/smd/Makefile src/sprio/Makefile src/squeue/Makefile src/srun/Makefile src/srun/libsrun/Makefile src/srun_cr/Makefile src/sshare/Makefile src/sstat/Makefile src/strigger/Makefile src/sview/Makefile src/plugins/Makefile src/plugins/accounting_storage/Makefile src/plugins/accounting_storage/common/Makefile src/plugins/accounting_storage/filetxt/Makefile src/plugins/accounting_storage/mysql/Makefile src/plugins/accounting_storage/none/Makefile src/plugins/accounting_storage/slurmdbd/Makefile src/plugins/acct_gather_energy/Makefile src/plugins/acct_gather_energy/cray/Makefile src/plugins/acct_gather_energy/rapl/Makefile src/plugins/acct_gather_energy/ipmi/Makefile src/plugins/acct_gather_energy/none/Makefile src/plugins/acct_gather_infiniband/Makefile src/plugins/acct_gather_infiniband/ofed/Makefile src/plugins/acct_gather_infiniband/none/Makefile src/plugins/acct_gather_filesystem/Makefile src/plugins/acct_gather_filesystem/lustre/Makefile src/plugins/acct_gather_filesystem/none/Makefile src/plugins/acct_gather_profile/Makefile src/plugins/acct_gather_profile/hdf5/Makefile src/plugins/acct_gather_profile/hdf5/sh5util/Makefile src/plugins/acct_gather_profile/none/Makefile src/plugins/auth/Makefile src/plugins/auth/authd/Makefile src/plugins/auth/munge/Makefile src/plugins/auth/none/Makefile src/plugins/burst_buffer/Makefile src/plugins/burst_buffer/common/Makefile src/plugins/burst_buffer/cray/Makefile src/plugins/burst_buffer/generic/Makefile src/plugins/checkpoint/Makefile src/plugins/checkpoint/aix/Makefile src/plugins/checkpoint/blcr/Makefile src/plugins/checkpoint/blcr/cr_checkpoint.sh src/plugins/checkpoint/blcr/cr_restart.sh src/plugins/checkpoint/none/Makefile src/plugins/checkpoint/ompi/Makefile src/plugins/checkpoint/poe/Makefile src/plugins/core_spec/Makefile src/plugins/core_spec/cray/Makefile src/plugins/core_spec/none/Makefile src/plugins/crypto/Makefile src/plugins/crypto/munge/Makefile src/plugins/crypto/openssl/Makefile src/plugins/ext_sensors/Makefile src/plugins/ext_sensors/rrd/Makefile src/plugins/ext_sensors/none/Makefile src/plugins/gres/Makefile src/plugins/gres/gpu/Makefile src/plugins/gres/nic/Makefile src/plugins/gres/mic/Makefile src/plugins/jobacct_gather/Makefile src/plugins/jobacct_gather/common/Makefile src/plugins/jobacct_gather/linux/Makefile src/plugins/jobacct_gather/aix/Makefile src/plugins/jobacct_gather/cgroup/Makefile src/plugins/jobacct_gather/none/Makefile src/plugins/jobcomp/Makefile src/plugins/jobcomp/filetxt/Makefile src/plugins/jobcomp/none/Makefile src/plugins/jobcomp/script/Makefile src/plugins/jobcomp/mysql/Makefile src/plugins/job_container/Makefile src/plugins/job_container/cncu/Makefile src/plugins/job_container/none/Makefile src/plugins/job_submit/Makefile src/plugins/job_submit/all_partitions/Makefile src/plugins/job_submit/cnode/Makefile src/plugins/job_submit/cray/Makefile src/plugins/job_submit/defaults/Makefile src/plugins/job_submit/logging/Makefile src/plugins/job_submit/lua/Makefile src/plugins/job_submit/partition/Makefile src/plugins/job_submit/pbs/Makefile src/plugins/job_submit/require_timelimit/Makefile src/plugins/job_submit/throttle/Makefile src/plugins/launch/Makefile src/plugins/launch/aprun/Makefile src/plugins/launch/poe/Makefile src/plugins/launch/runjob/Makefile src/plugins/launch/slurm/Makefile src/plugins/power/Makefile src/plugins/power/common/Makefile src/plugins/power/cray/Makefile src/plugins/power/none/Makefile src/plugins/preempt/Makefile src/plugins/preempt/job_prio/Makefile src/plugins/preempt/none/Makefile src/plugins/preempt/partition_prio/Makefile src/plugins/preempt/qos/Makefile src/plugins/priority/Makefile src/plugins/priority/basic/Makefile src/plugins/priority/multifactor/Makefile src/plugins/proctrack/Makefile src/plugins/proctrack/aix/Makefile src/plugins/proctrack/cray/Makefile src/plugins/proctrack/cgroup/Makefile src/plugins/proctrack/pgid/Makefile src/plugins/proctrack/linuxproc/Makefile src/plugins/proctrack/sgi_job/Makefile src/plugins/proctrack/lua/Makefile src/plugins/route/Makefile src/plugins/route/default/Makefile src/plugins/route/topology/Makefile src/plugins/sched/Makefile src/plugins/sched/backfill/Makefile src/plugins/sched/builtin/Makefile src/plugins/sched/hold/Makefile src/plugins/sched/wiki/Makefile src/plugins/sched/wiki2/Makefile src/plugins/select/Makefile src/plugins/select/alps/Makefile src/plugins/select/alps/libalps/Makefile src/plugins/select/alps/libemulate/Makefile src/plugins/select/bluegene/Makefile src/plugins/select/bluegene/ba/Makefile src/plugins/select/bluegene/ba_bgq/Makefile src/plugins/select/bluegene/bl/Makefile src/plugins/select/bluegene/bl_bgq/Makefile src/plugins/select/bluegene/sfree/Makefile src/plugins/select/cons_res/Makefile src/plugins/select/cray/Makefile src/plugins/select/linear/Makefile src/plugins/select/other/Makefile src/plugins/select/serial/Makefile src/plugins/slurmctld/Makefile src/plugins/slurmctld/nonstop/Makefile src/plugins/slurmd/Makefile src/plugins/switch/Makefile src/plugins/switch/cray/Makefile src/plugins/switch/generic/Makefile src/plugins/switch/none/Makefile src/plugins/switch/nrt/Makefile src/plugins/switch/nrt/libpermapi/Makefile src/plugins/mpi/Makefile src/plugins/mpi/mpich1_p4/Makefile src/plugins/mpi/mpich1_shmem/Makefile src/plugins/mpi/mpichgm/Makefile src/plugins/mpi/mpichmx/Makefile src/plugins/mpi/mvapich/Makefile src/plugins/mpi/lam/Makefile src/plugins/mpi/none/Makefile src/plugins/mpi/openmpi/Makefile src/plugins/mpi/pmi2/Makefile src/plugins/task/Makefile src/plugins/task/affinity/Makefile src/plugins/task/cgroup/Makefile src/plugins/task/cray/Makefile src/plugins/task/none/Makefile src/plugins/topology/Makefile src/plugins/topology/3d_torus/Makefile src/plugins/topology/hypercube/Makefile src/plugins/topology/node_rank/Makefile src/plugins/topology/none/Makefile src/plugins/topology/tree/Makefile testsuite/Makefile testsuite/expect/Makefile testsuite/slurm_unit/Makefile testsuite/slurm_unit/api/Makefile testsuite/slurm_unit/api/manual/Makefile testsuite/slurm_unit/common/Makefile"
 
 
 cat >confcache <<\_ACEOF
@@ -25331,6 +25331,8 @@ do
     "src/api/Makefile") CONFIG_FILES="$CONFIG_FILES src/api/Makefile" ;;
     "src/common/Makefile") CONFIG_FILES="$CONFIG_FILES src/common/Makefile" ;;
     "src/db_api/Makefile") CONFIG_FILES="$CONFIG_FILES src/db_api/Makefile" ;;
+    "src/layouts/Makefile") CONFIG_FILES="$CONFIG_FILES src/layouts/Makefile" ;;
+    "src/layouts/unit/Makefile") CONFIG_FILES="$CONFIG_FILES src/layouts/unit/Makefile" ;;
     "src/database/Makefile") CONFIG_FILES="$CONFIG_FILES src/database/Makefile" ;;
     "src/sacct/Makefile") CONFIG_FILES="$CONFIG_FILES src/sacct/Makefile" ;;
     "src/sacctmgr/Makefile") CONFIG_FILES="$CONFIG_FILES src/sacctmgr/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index ca6810fb7d3beeb0198aca5f3cf53a6cd3b6528c..9b381924df0aba43e258a9261e913da7e1a9e205 100644
--- a/configure.ac
+++ b/configure.ac
@@ -463,6 +463,8 @@ AC_CONFIG_FILES([Makefile
 		 src/api/Makefile
 		 src/common/Makefile
 		 src/db_api/Makefile
+		 src/layouts/Makefile
+		 src/layouts/unit/Makefile
 		 src/database/Makefile
 		 src/sacct/Makefile
 		 src/sacctmgr/Makefile
diff --git a/slurm.spec b/slurm.spec
index 052e96e505051768dc5005c5ac05876b110733f6..9849389442f29b7319f8786e6d2122346414ce1b 100644
--- a/slurm.spec
+++ b/slurm.spec
@@ -896,6 +896,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/slurm/jobcomp_filetxt.so
 %{_libdir}/slurm/jobcomp_none.so
 %{_libdir}/slurm/jobcomp_script.so
+%{_libdir}/slurm/layouts_unit_default.so
 %if ! %{slurm_with bluegene}
 %{_libdir}/slurm/mpi_lam.so
 %{_libdir}/slurm/mpi_mpich1_p4.so
diff --git a/src/Makefile.am b/src/Makefile.am
index 24bd9624f8336ac644da843981bc4422a340cfd7..47807fc658ad0badbb3b1e9f16a6cc2f373cadba 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,6 +3,7 @@ SUBDIRS =		\
 	common		\
 	database	\
 	db_api		\
+	layouts		\
 	plugins		\
 	sacct		\
 	sacctmgr	\
diff --git a/src/Makefile.in b/src/Makefile.in
index d0133a3d116c8c4d396092b2534d5e8585181bc3..80ddf555838637f0af30a570115918a48261decc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -184,9 +184,9 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = api common database db_api plugins sacct sacctmgr \
-	salloc sattach sbatch sbcast scancel scontrol sdiag sinfo \
-	slurmctld slurmd slurmdbd smap smd sprio squeue sreport \
+DIST_SUBDIRS = api common database db_api layouts plugins sacct \
+	sacctmgr salloc sattach sbatch sbcast scancel scontrol sdiag \
+	sinfo slurmctld slurmd slurmdbd smap smd sprio squeue sreport \
 	srun_cr sshare sstat strigger sview srun
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
@@ -455,10 +455,10 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-SUBDIRS = api common database db_api plugins sacct sacctmgr salloc \
-	sattach sbatch sbcast scancel scontrol sdiag sinfo slurmctld \
-	slurmd slurmdbd smap smd sprio squeue sreport srun_cr sshare \
-	sstat strigger sview $(am__append_1)
+SUBDIRS = api common database db_api layouts plugins sacct sacctmgr \
+	salloc sattach sbatch sbcast scancel scontrol sdiag sinfo \
+	slurmctld slurmd slurmdbd smap smd sprio squeue sreport \
+	srun_cr sshare sstat strigger sview $(am__append_1)
 all: all-recursive
 
 .SUFFIXES:
diff --git a/src/common/entity.c b/src/common/entity.c
index d8587a078b7ed394c7f93edcd4004a409dc2bb61..c7e31ddfb9dbe97ff0b10347a7ca1ab61808934a 100644
--- a/src/common/entity.c
+++ b/src/common/entity.c
@@ -35,6 +35,11 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 \*****************************************************************************/
 
+#include "string.h"
+
+#include "slurm/slurm.h"
+#include "slurm/slurm_errno.h"
+
 #include "src/common/entity.h"
 #include "src/common/layout.h"
 #include "src/common/xmalloc.h"
@@ -43,7 +48,7 @@
 
 
 /*****************************************************************************\
- *                                 FUNCTIONS                                 *
+ *                                 HELPERS                                   *
 \*****************************************************************************/
 
 static const char* _entity_data_identify(void* item)
@@ -52,6 +57,15 @@ static const char* _entity_data_identify(void* item)
 	return data_item->key;
 }
 
+static void _entity_data_destroy(void* x)
+{
+	entity_data_t* entity_data = (entity_data_t*)x;
+	if (entity_data) {
+		xfree(entity_data->value);
+		xfree(entity_data);
+	}
+}
+
 static void _entity_node_destroy(void* x)
 {
 	entity_node_t* entity_node = (entity_node_t*)x;
@@ -61,11 +75,58 @@ static void _entity_node_destroy(void* x)
 	}
 }
 
+static int _entity_add_data(const entity_t* entity, const char* key,
+			    void* value, size_t size,
+			    void (*_free)(void*), bool byreference)
+{
+	entity_data_t* result;
+	entity_data_t* new_data_item;
+
+	if (!key || !*key || !value)
+		return SLURM_ERROR;
+
+	result = (entity_data_t*)xhash_get(entity->data, key);
+	if (result != NULL) {
+		/* update existing value by ref or by override */
+		if (byreference) {
+			if (_free)
+				_free(result->value);
+			result->value = value;
+		} else {
+			memcpy(result->value, value, size);
+		}
+		return SLURM_SUCCESS;
+	}
+
+	/* add a new KV if not already existing, by ref or allocating
+	 * a new buffer and dumping the provided input */
+	new_data_item = (entity_data_t*)xmalloc(sizeof(entity_data_t));
+	new_data_item->key = key;
+	if (byreference) {
+		new_data_item->value = value;
+	} else {
+		new_data_item->value = (void*) xmalloc(size);
+		memcpy(new_data_item->value, value, size);
+	}
+	result = xhash_add(entity->data, new_data_item);
+	if (result == NULL) {
+		xfree(new_data_item);
+		return SLURM_ERROR;
+	}
+	return SLURM_SUCCESS;
+}
+
+/*****************************************************************************\
+ *                                 FUNCTIONS                                 *
+\*****************************************************************************/
+
 void entity_init(entity_t* entity, const char* name, const char* type)
 {
 	entity->name = xstrdup(name);
 	entity->type = xstrdup(type);
-	entity->data = xhash_init(_entity_data_identify, NULL, NULL, 0);
+	entity->data = xhash_init(_entity_data_identify,
+				  (xhash_freefunc_t)_entity_data_destroy,
+				  NULL, 0);
 	entity->nodes = list_create(_entity_node_destroy);
 	entity->ptr = NULL;
 }
@@ -90,38 +151,37 @@ const char* entity_get_type(const entity_t* entity)
 	return entity->type;
 }
 
-void** entity_get_data(const entity_t* entity, const char* key)
+int entity_get_data(const entity_t* entity, const char* key,
+		    void* value, size_t size)
+{
+	void* data = NULL;
+	data = entity_get_data_ref(entity, key);
+	if (data != NULL) {
+		memcpy(value, data, size);
+		return SLURM_SUCCESS;
+	}
+	return SLURM_ERROR;
+}
+
+void* entity_get_data_ref(const entity_t* entity, const char* key)
 {
 	entity_data_t* data = (entity_data_t*)xhash_get(entity->data, key);
 	if (data) {
-		return &data->value;
+		return data->value;
 	}
 	return NULL;
 }
 
-int entity_add_data(entity_t* entity, const char* key, void* value,
-		    void (*_free)(void*))
+int entity_set_data(const entity_t* entity, const char* key,
+		    void* value, size_t size)
 {
-	entity_data_t* result;
-	entity_data_t* new_data_item;
-	if (!key || !*key || !value)
-		return 0;
-	result = (entity_data_t*)xhash_get(entity->data, key);
-	if (result != NULL) {
-		if (_free)
-			_free(result->value);
-		result->value = value;
-		return 1;
-	}
-	new_data_item = (entity_data_t*)xmalloc(sizeof(entity_data_t));
-	new_data_item->key = key;
-	new_data_item->value = value;
-	result = xhash_add(entity->data, new_data_item);
-	if (result == NULL) {
-		xfree(new_data_item);
-		return 0;
-	}
-	return 1;
+	return _entity_add_data(entity, key, value, size, NULL, false);
+}
+
+int entity_set_data_ref(const entity_t* entity, const char* key, void* value,
+			void (*_free)(void*))
+{
+	return _entity_add_data(entity, key, value, 0, _free, true);
 }
 
 void entity_delete_data(entity_t* entity, const char* key)
@@ -134,47 +194,76 @@ void entity_clear_data(entity_t* entity)
 	xhash_clear(entity->data);
 }
 
-void entity_add_node(entity_t* entity, layout_t* layout, void* node)
+entity_node_t* entity_add_node(entity_t* entity, layout_t* layout)
 {
 
 	entity_node_t* entity_node = (entity_node_t*)xmalloc(
 		sizeof(entity_node_t));
 	entity_node->layout = layout;
-	entity_node->node = node;
-	list_append(entity->nodes, entity_node);
+	entity_node->entity = entity;
+	entity_node->node = NULL;
+	entity_node = list_append(entity->nodes, entity_node);
+	return entity_node;
 }
 
-static int _entity_node_find(void* x, void* key)
+typedef struct _entity_get_node_walk_st {
+	layout_t* layout;
+	entity_node_t* node;
+} _entity_get_node_walk_t;
+
+static void _entity_get_node_walkfunc(layout_t* layout,
+				      entity_node_t* node, void* arg)
 {
-	entity_node_t* entity_node = (entity_node_t*)x;
-	return entity_node->node == key;
+	_entity_get_node_walk_t* real_arg =
+		(_entity_get_node_walk_t*) arg;
+	/* Note that if multiple nodes of the same layout are added
+	 * to a single entity, the last one will be returned.
+	 * An entity MUST NOT be added more than once /!\ */
+	if (layout == real_arg->layout) {
+		real_arg->node = node;
+	}
 }
 
-void entity_delete_node(entity_t* entity, void* node)
+entity_node_t* entity_get_node(entity_t* entity, layout_t* layout)
 {
-	ListIterator i = list_iterator_create(entity->nodes);
-	if (list_find(i, _entity_node_find, node))
-		list_delete_item(i);
-	list_iterator_destroy(i);
+	_entity_get_node_walk_t arg;
+	arg.layout = layout;
+	arg.node = NULL;
+	entity_nodes_walk(entity, _entity_get_node_walkfunc, (void*) &arg);
+	return arg.node;
 }
 
-void entity_clear_nodes(entity_t* entity)
+static int _entity_node_find(void* x, void* key)
 {
-	list_flush(entity->nodes);
+	entity_node_t* entity_node = (entity_node_t*)x;
+	return entity_node->node == key;
 }
 
-int entity_has_node(entity_t* entity, void* node)
+int entity_delete_node(entity_t* entity, layout_t* layout)
 {
+	int rc = SLURM_ERROR;
+	entity_node_t* node;
 	ListIterator i;
-	void* result;
+	node = entity_get_node(entity, layout);
+	if (node == NULL)
+		return rc;
 	i = list_iterator_create(entity->nodes);
-	result = list_find(i, _entity_node_find, node);
+	if (list_find(i, _entity_node_find, node)) {
+		list_delete_item(i);
+		rc = SLURM_SUCCESS;
+	}
 	list_iterator_destroy(i);
-	return result != NULL;
+	return rc;
+}
+
+int entity_clear_nodes(entity_t* entity)
+{
+	list_flush(entity->nodes);
+	return SLURM_SUCCESS;
 }
 
 typedef struct _entity_nodes_walkstruct_st {
-	void (*callback)(layout_t* layout, void* node, void* arg);
+	void (*callback)(layout_t* layout, entity_node_t* node, void* arg);
 	void* arg;
 } _entity_nodes_walkstruct_t;
 
@@ -184,14 +273,14 @@ static int _entity_nodes_walkfunc(void* x, void* arg)
 	_entity_nodes_walkstruct_t* real_arg =
 		(_entity_nodes_walkstruct_t*)arg;
 	real_arg->callback(entity_node->layout,
-			   entity_node->node,
+			   entity_node,
 			   real_arg->arg);
 	return 0;
 }
 
 void entity_nodes_walk(entity_t* entity,
 		       void (*callback)(layout_t* layout,
-					void* node,
+					entity_node_t* node,
 					void* arg),
 		       void* arg)
 {
diff --git a/src/common/entity.h b/src/common/entity.h
index 03650a6af2af62143dbbfe65b4f7e515e3306d29..c43c10be1382caf2fee8e4bef7880c29eb48c886 100644
--- a/src/common/entity.h
+++ b/src/common/entity.h
@@ -67,9 +67,10 @@ typedef struct entity_data_st {
  * to represent the layout nodes that are linked to them */
 typedef struct entity_node_st {
 	layout_t* layout; /* layout containing a relationnal structure holding
-			   * a reference to this entity */
+			   * a reference to the entity */
+	entity_t* entity; /* pointer to the associated entity */
 	void* node;       /* pointer to the relational node referencing
-			     this entity */
+			     this entity node */
 } entity_node_t;
 
 /*****************************************************************************\
@@ -111,7 +112,21 @@ const char* entity_get_name(const entity_t* entity);
 const char* entity_get_type(const entity_t* entity);
 
 /*
- * entity_get_data - get the address of the pointer to the data associated
+ * entity_get_data - copy the content of the data associated to a particular key
+ *       of an entity into a buffer up to the requested size
+ *
+ * IN entity - the entity struct to use
+ * IN key - the targeted key
+ * IN value - ponter to the mem area to fill
+ * IN size - size of the mem area to copy
+ *
+ * Return SLURM_SUCCESS or SLURM_ERROR if no element found
+ */
+int entity_get_data(const entity_t* entity, const char* key,
+		    void* value, size_t size);
+
+/*
+ * entity_get_data_ref - get the address of the pointer to the data associated
  *       with a particular key of an entity
  *
  * IN entity - the entity struct to use
@@ -120,10 +135,28 @@ const char* entity_get_type(const entity_t* entity);
  * Return value is the address of the (void*) pointer to the data associated to
  *       the key or NULL in case of error
  */
-void** entity_get_data(const entity_t* entity, const char* key);
+void* entity_get_data_ref(const entity_t* entity, const char* key);
 
 /*
- * entity_add_data - associate data to a particular key of an entity
+ * entity_set_data - copy the content of the input buffer up to the requested
+ *       size into the the buffer associated to a particular key of an entity
+ *       (note that the entity key value's buffer is allocated internally if
+ *       necessary)
+ *
+ * IN entity - the entity struct to use
+ * IN key - the targeted key
+ * IN value - ponter to the mem area to fill with
+ * IN size - size of the mem area to copy
+ *
+ * Return SLURM_SUCCESS or SLURM_ERROR if no element found
+ */
+int entity_set_data(const entity_t* entity, const char* key,
+		    void* value, size_t size);
+
+/*
+ * entity_set_data_ref - associate a particular key of an entity with the
+ *       input buffer, 
+ *       with a particular key of an entity
  *
  * IN entity - the entity struct to use
  * IN key - the key the data must be associated to
@@ -132,10 +165,10 @@ void** entity_get_data(const entity_t* entity, const char* key);
  * IN _free - a function to apply on the former value in case it exists
  *       before overriding
  *
- * Return 1 if the value was successfully associated or 0 otherwise
+ * Return SLURM_SUCCESS or SLURM_ERROR in case of error
  */
-int entity_add_data(entity_t* entity, const char* key, void* value,
-		    void (*_free)(void*));
+int entity_set_data_ref(const entity_t* entity, const char* key, void* value,
+			void (*_free)(void*));
 
 /*
  * entity_delete_data - delete the data associated with a particular key
@@ -157,48 +190,49 @@ void entity_delete_data(entity_t* entity, const char* key);
 void entity_clear_data(entity_t* entity);
 
 /*
- * entity_add_node - add a relational node to the list of nodes referring to
- *       this entity
+ * entity_add_node - add a per layout entity node to the list of nodes referring
+ *       to this entity
  *
  * IN entity - the entity struct to use
- * IN layout - the layout having a node referring to this entity
- * IN node - the node referring to it
+ * IN layout - the layout to create an entity node referring to this entity
  *
- * Notes: the entity does not own the memory of the relationnal nodes.
+ * Notes: - the returned entity_node does not point to anything at that point.
+ *          it will be added to a relational structure and will then have to 
+ *          be associated to the underlying relational node afterwards.
+ *        - the entity node will not own the memory of the relationnal node.
  */
-void entity_add_node(entity_t* entity, layout_t* layout, void* node);
+entity_node_t* entity_add_node(entity_t* entity, layout_t* layout);
 
 /*
- * entity_delete_node - remove a relational node from the list of nodes
- *       referring to this entity
+ * entity_get_node - get the entity node referring to a particular layout in
+ *       the list of entity nodes associated to an entity.
  *
  * IN entity - the entity struct to use
- * IN node - the node referring to it
+ * IN layout - the layout having an entity node referring to this entity
  *
- * Notes: the memory of the node data is not freed.
+ * Return value is the entity node of the layout or NULL if not found
  */
-void entity_delete_node(entity_t* entity, void* node);
+entity_node_t* entity_get_node(entity_t* entity, layout_t* layout);
 
 /*
- * entity_clear_nodes - remove all the relational node from the list of nodes
- *       referring to this entity
+ * entity_delete_node - remove the entity node referring to a particular layout
+ *       from the list of entity nodes associated to an entity
  *
  * IN entity - the entity struct to use
+ * IN layout - the layout having an entity node referring to this entity
  *
- * Notes: the memory of the nodes data is not freed.
+ * Return SLURM_SUCCESS or SLURM_ERROR
  */
-void entity_clear_nodes(entity_t* entity);
+int entity_delete_node(entity_t* entity, layout_t* layout);
 
 /*
- * entity_has_node - check wether or not a relational node is in the
- *       list of nodes referring to this entity
+ * entity_clear_nodes - remove all the entity node associated to an entity
  *
  * IN entity - the entity struct to use
- * IN node - the node to check for
  *
- * Return 1 if found, 0 otherwise
+ * Return SLURM_SUCCESS or SLURM_ERROR
  */
-int entity_has_node(entity_t* entity, void* node);
+int entity_clear_nodes(entity_t* entity);
 
 /*
  * entity_nodes_walk - iterate over the nodes referring to this entity
@@ -213,7 +247,7 @@ int entity_has_node(entity_t* entity, void* node);
  * IN arg - the arg to pass to the callback function for every node.
  */
 void entity_nodes_walk(entity_t* entity,
-		       void (*callback)(layout_t*, void*, void*),
+		       void (*callback)(layout_t*, entity_node_t*, void*),
 		       void* arg);
 
 /*
diff --git a/src/common/hostlist.h b/src/common/hostlist.h
index 6f7be2593f4cf2540224c4e008a5206ab553dd09..cea134bf2ac54ee548ea40931e6ce0b088591698 100644
--- a/src/common/hostlist.h
+++ b/src/common/hostlist.h
@@ -50,7 +50,7 @@
  * expressions that can consume all of the memory on a system and crash the
  * daemons (e.g. "a[0-999999999].b[0-9]", which generates 1 billion distinct
  * prefix records in the hostlist) */
-#define MAX_PREFIX_CNT 1024
+#define MAX_PREFIX_CNT 64*1024
 
 #if (SYSTEM_DIMENSIONS > 1)
 #define HOSTLIST_BASE 36
diff --git a/src/common/layouts_mgr.c b/src/common/layouts_mgr.c
index 857f82ced4e65dc18ccb0f4a830ea4403b5f737e..1eaf0d1098e331f38887b787b40203fefda36239 100644
--- a/src/common/layouts_mgr.c
+++ b/src/common/layouts_mgr.c
@@ -4,6 +4,7 @@
  *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
  *  at Bull for slurm-2.6.
  *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *  Enhanced by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-15.x.
  *
  *  This file is part of SLURM, a resource management program.
  *  For details, see <http://slurm.schedmd.com/>.
@@ -39,6 +40,7 @@
 #include <string.h>
 #include <strings.h>
 #include <ctype.h>
+#include <sys/stat.h>
 
 #include "layouts_mgr.h"
 
@@ -50,15 +52,24 @@
 #include "src/common/hostlist.h"
 #include "src/common/list.h"
 #include "src/common/node_conf.h"
+#include "src/common/pack.h"
 #include "src/common/plugin.h"
 #include "src/common/read_config.h"
 #include "src/common/slurm_protocol_api.h"
+#include "src/common/timers.h"
 #include "src/common/xstring.h"
 #include "src/common/xtree.h"
 #include "src/common/xmalloc.h"
 
 #define PATHLEN 256
 
+/* use to specify which layout callbacks to perform while loading data
+ * from conf files, state files or input buffers */
+#define CONF_DONE       0x00000001
+#define PARSE_ENTITY    0x00000002
+#define UPDATE_DONE     0x00000004
+#define PARSE_RELATIONS 0x00000008
+
 /*****************************************************************************\
  *                            STRUCTURES AND TYPES                           *
 \*****************************************************************************/
@@ -86,12 +97,12 @@ static void layouts_conf_spec_free(void* x)
 /*
  * layout ops - operations associated to layout plugins
  *
- * This struct is populated while opening the plugin and linking the 
+ * This struct is populated while opening the plugin and linking the
  * associated symbols. See layout_syms description for the name of the "public"
  * symbols associated to this structure fields.
  *
  * Notes : the layouts plugins are able to access the entities hashtable in order
- * to read/create/modify entities as necessary during the load_entities and 
+ * to read/create/modify entities as necessary during the load_entities and
  * build_layout API calls.
  *
  */
@@ -101,6 +112,8 @@ typedef struct layout_ops_st {
 			  s_p_hashtbl_t* tbl);
 	void (*entity_parsing) (entity_t* e, s_p_hashtbl_t* etbl,
 				layout_t* layout);
+	int (*update_done) (layout_t* layout, entity_t** e_array,
+			    int e_cnt);
 } layout_ops_t;
 
 /*
@@ -112,6 +125,7 @@ const char *layout_syms[] = {
 	"plugin_spec",             /* holds constants, definitions, ... */
 	"layouts_p_conf_done",     /* */
 	"layouts_p_entity_parsing",
+	"layouts_p_update_done",
 };
 
 /*
@@ -127,13 +141,12 @@ typedef struct layout_plugin_st {
 	layout_ops_t* ops;
 } layout_plugin_t;
 
-static void _layout_plugins_destroy(layout_plugin_t *lp) {
+static void _layout_plugins_destroy(layout_plugin_t *lp)
+{
 	plugin_context_destroy(lp->context);
 	/* it might be interesting to also dlclose the ops here */
-	layout_free(lp->layout);
 	xfree(lp->name);
 	xfree(lp->ops);
-	xfree(lp->layout);
 }
 /*
  * layouts_keydef_t - entities similar keys share a same key definition
@@ -141,18 +154,29 @@ static void _layout_plugins_destroy(layout_plugin_t *lp) {
  *       like the key str itself and custom destroy/dump functions.
  *
  * The layouts manager keeps an hash table of the various keydefs and use
- * the factorized details while parsing the configuration and creating the 
+ * the factorized details while parsing the configuration and creating the
  * entity_data_t structs associated to the entities.
  *
- * Note custom_* functions are used if they are not NULL* and type equals 
+ * Note custom_* functions are used if they are not NULL* and type equals
  * L_T_CUSTOM
  */
 typedef struct layouts_keydef_st {
-	char*			key; /* normalize to lower or upper case */
+	char*			key; /* lower case key prefixed by the
+					"%layout_type%." string */
+	char*			shortkey; /* original key as defined in
+					     the layout keys definition */
 	layouts_keydef_types_t	type;
+	uint32_t                flags;
 	void			(*custom_destroy)(void* value);
 	char*			(*custom_dump)(void* value);
 	layout_plugin_t*	plugin;
+	char*			ref_key; /* lower case reference key prefixed by
+					    the "%layout_type%." might be NULL 
+					    if not defined. */
+	char*			ref_shortkey; /* original ref key as defined in
+						 the layout keys definition,
+						 might be null too. */
+
 } layouts_keydef_t;
 
 /*
@@ -166,7 +190,7 @@ static const char* layouts_keydef_idfunc(void* item)
 }
 
 /*
- * layouts_mgr_t - the main structure holding all the layouts, entities and 
+ * layouts_mgr_t - the main structure holding all the layouts, entities and
  *        shared keydefs as well as conf elements and plugins details.
  */
 typedef struct layouts_mgr_st {
@@ -215,6 +239,9 @@ static void _layouts_keydef_free(void* x)
 {
 	layouts_keydef_t* keydef = (layouts_keydef_t*)x;
 	xfree(keydef->key);
+	xfree(keydef->shortkey);
+	xfree(keydef->ref_key);
+	xfree(keydef->ref_shortkey);
 	xfree(keydef);
 }
 
@@ -318,24 +345,455 @@ static void _normalize_keydef_mgrkey(char* buffer, uint32_t size,
 
 static void _entity_add_data(entity_t* e, const char* key, void* data)
 {
-	int rc;
 	layouts_keydef_t* hkey = xhash_get(mgr->keydefs, key);
 	xassert(hkey);
 	void (*freefunc)(void* p) = xfree_as_callback;
-	if (hkey->type == L_T_CUSTOM) {
+	if (hkey && hkey->type == L_T_CUSTOM) {
 		freefunc = hkey->custom_destroy;
 	}
-	rc = entity_add_data(e, hkey->key, data, freefunc);
-	xassert(rc);
+	entity_set_data_ref(e, hkey->key, data, freefunc);
+}
+
+/*
+ * used in both automerge and autoupdate calls when dealing with
+ * advanced operations (SUM,MIN,MAX,AVG,...) while setting new key values
+ */
+#define _entity_update_kv_helper(type_t, operator)			\
+	type_t* lvalue = (type_t*) oldvalue;				\
+	type_t* rvalue = (type_t*) value;				\
+	uint32_t* divider;						\
+	switch (operator) {						\
+	case S_P_OPERATOR_SET:						\
+		*lvalue = *rvalue;					\
+		break;							\
+	case S_P_OPERATOR_ADD:						\
+		*lvalue += *rvalue;					\
+		break;							\
+	case S_P_OPERATOR_SUB:						\
+		*lvalue -= *rvalue;					\
+		break;							\
+	case S_P_OPERATOR_MUL:						\
+		*lvalue *= *rvalue;					\
+		break;							\
+	case S_P_OPERATOR_DIV:						\
+		if (*rvalue != (type_t) 0)				\
+			*lvalue /= *rvalue;				\
+		else {							\
+			error("layouts: entity_update: "		\
+			      "key=%s val=0 operator="			\
+			      "DIV !! skipping !!",			\
+			      keydef->key);				\
+		}							\
+		break;							\
+	case S_P_OPERATOR_AVG:						\
+		divider = (uint32_t*) value;				\
+		if (*divider != (uint32_t) 0)				\
+			*lvalue /= (type_t) *divider;			\
+		else {							\
+			error("layouts: entity_update: "		\
+			      "key=%s val=0 operator="			\
+			      "AVG !! skipping !!",			\
+			      keydef->key);				\
+		}							\
+		break;							\
+	case S_P_OPERATOR_SET_IF_MIN:					\
+		if (*rvalue < *lvalue)					\
+			*lvalue = *rvalue;				\
+		break;							\
+	case S_P_OPERATOR_SET_IF_MAX:					\
+		if (*rvalue > *lvalue)					\
+			*lvalue = *rvalue;				\
+		break;							\
+	default:							\
+		break;							\
+	}
+
+static int _layouts_autoupdate_layout(layout_t* layout);
+static int _layouts_autoupdate_layout_if_allowed(layout_t* layout);
+
+/*****************************************************************************\
+ *                       LAYOUTS INTERNAL LOCKLESS API                       *
+\*****************************************************************************/
+
+layouts_keydef_t* _layouts_entity_get_kv_keydef(layout_t* l, entity_t* e,
+						char* key)
+{
+	char keytmp[PATHLEN];
+	if (l == NULL || e == NULL || key == NULL)
+		return NULL;
+	_normalize_keydef_key(keytmp, PATHLEN, key, l->type);
+	return xhash_get(mgr->keydefs, keytmp);
+}
+
+int _layouts_entity_get_kv_type(layout_t* l, entity_t* e, char* key)
+{
+	layouts_keydef_t* keydef;
+	keydef = _layouts_entity_get_kv_keydef(l, e, key);
+	if (keydef != NULL) {
+		return keydef->type;
+	}
+	return SLURM_ERROR;
+}
+
+int _layouts_entity_get_kv_flags(layout_t* l, entity_t* e, char* key)
+{
+	layouts_keydef_t* keydef;
+	keydef = _layouts_entity_get_kv_keydef(l, e, key);
+	if (keydef != NULL) {
+		return keydef->flags;
+	}
+	return SLURM_ERROR;
+}
+
+int _layouts_entity_get_kv_size(layout_t* l, entity_t* e, char* key, size_t *size)
+{
+	layouts_keydef_t* keydef;
+	keydef = _layouts_entity_get_kv_keydef(l, e, key);
+	if (keydef != NULL) {
+		switch(keydef->type) {
+		case L_T_ERROR:
+			return SLURM_ERROR;
+		case L_T_STRING:
+			*size = sizeof(void*);
+			break;
+		case L_T_CUSTOM:
+			*size = sizeof(void*);
+			break;
+		case L_T_LONG:
+			*size = sizeof(long);
+			break;
+		case L_T_UINT16:
+			*size = sizeof(uint16_t);
+			break;
+		case L_T_UINT32:
+			*size = sizeof(uint32_t);
+			break;
+		case L_T_BOOLEAN:
+			*size = sizeof(bool);
+			break;
+		case L_T_FLOAT:
+			*size = sizeof(float);
+			break;
+		case L_T_DOUBLE:
+			*size = sizeof(double);
+			break;
+		case L_T_LONG_DOUBLE:
+			*size = sizeof(long double);
+			break;
+		}
+	} else
+		return SLURM_ERROR;
+	return SLURM_SUCCESS;
+}
+
+bool _layouts_entity_check_kv_keytype(layout_t* l, entity_t* e, char* key,
+				      layouts_keydef_types_t key_type)
+{
+	layouts_keydef_types_t real_type;
+	if (l == NULL || e == NULL || key == NULL)
+		return SLURM_ERROR;
+	if (key_type) {
+		real_type = _layouts_entity_get_kv_type(l, e, key);
+		return (real_type == key_type);
+	}
+	/* no key type provided, consider that as a no-check request */
+	return true;
+}
+
+int _layouts_entity_push_kv(layout_t* l, entity_t* e, char* key)
+{
+	/* a more advanced implementation should only pull what is necessary
+	 * instead of forcing a full autoupdate */
+	return _layouts_autoupdate_layout_if_allowed(l);
+}
+
+int _layouts_entity_pull_kv(layout_t* l, entity_t* e, char* key)
+{
+	/* a more advanced implementation should only pull what is necessary
+	 * instead of forcing a full autoupdate */
+	return _layouts_autoupdate_layout_if_allowed(l);
+}
+
+int _layouts_entity_set_kv(layout_t* l, entity_t* e, char* key, void* value,
+			   layouts_keydef_types_t key_type)
+{
+	void* data;
+	size_t size;
+	layouts_keydef_types_t real_type;
+	char key_keydef[PATHLEN];
+
+	if (l == NULL || e == NULL || key == NULL || value == NULL)
+		return SLURM_ERROR;
+
+	real_type = _layouts_entity_get_kv_type(l, e, key);
+	if (key_type > 0 && real_type != key_type)
+		return SLURM_ERROR;
+
+	_normalize_keydef_key(key_keydef, PATHLEN, key, l->type);
+
+	switch(real_type) {
+	case L_T_ERROR:
+		return SLURM_ERROR;
+	case L_T_STRING:
+		data = xstrdup(value);
+		return entity_set_data_ref(e, key_keydef, data,
+					   xfree_as_callback);
+	case L_T_CUSTOM:
+		/* TBD : add a custom_set call */
+		value = NULL;
+		return SLURM_ERROR;
+	case L_T_LONG:
+		size = sizeof(long);
+		break;
+	case L_T_UINT16:
+		size = sizeof(uint16_t);
+		break;
+	case L_T_UINT32:
+		size = sizeof(uint32_t);
+		break;
+	case L_T_BOOLEAN:
+		size = sizeof(bool);
+		break;
+	case L_T_FLOAT:
+		size = sizeof(float);
+		break;
+	case L_T_DOUBLE:
+		size = sizeof(double);
+		break;
+	case L_T_LONG_DOUBLE:
+		size = sizeof(long double);
+		break;
+	}
+	return entity_set_data(e, key_keydef, value, size);
+}
+
+int _layouts_entity_set_kv_ref(layout_t* l, entity_t* e, char* key, void* value,
+			       layouts_keydef_types_t key_type)
+{
+	int rc = SLURM_ERROR;
+	char key_keydef[PATHLEN];
+
+	if (l == NULL || e == NULL || key == NULL || value == NULL)
+		return rc;
+
+	if (!_layouts_entity_check_kv_keytype(l, e, key, key_type))
+		return rc;
+
+	_normalize_keydef_key(key_keydef, PATHLEN, key, l->type);
+	return entity_set_data_ref(e, key_keydef, value, xfree_as_callback);
+}
+
+int _layouts_entity_setpush_kv(layout_t* l, entity_t* e, char* key, void* value,
+			       layouts_keydef_types_t key_type)
+{
+	int rc = SLURM_ERROR;
+	if (_layouts_entity_set_kv(l, e, key, value, key_type) == SLURM_SUCCESS)
+		rc = _layouts_entity_push_kv(l, e, key);
+	return rc;
+}
+
+int _layouts_entity_setpush_kv_ref(layout_t* l, entity_t* e, char* key,
+				   void* value, layouts_keydef_types_t key_type)
+{
+	int rc = SLURM_ERROR;
+	if (_layouts_entity_set_kv_ref(l, e, key, value, key_type) ==
+	    SLURM_SUCCESS)
+		rc = _layouts_entity_push_kv(l, e, key);
+	return rc;
+}
+
+int _layouts_entity_get_kv(layout_t* l, entity_t* e, char* key, void* value,
+			   layouts_keydef_types_t key_type)
+{
+	void* data;
+	size_t size;
+	layouts_keydef_types_t real_type;
+	char key_keydef[PATHLEN];
+	char ** pstr;
+
+	if (l == NULL || e == NULL || key == NULL || value == NULL)
+		return SLURM_ERROR;
+
+	real_type = _layouts_entity_get_kv_type(l, e, key);
+	if (key_type > 0 && real_type != key_type)
+		return SLURM_ERROR;
+
+	_normalize_keydef_key(key_keydef, PATHLEN, key, l->type);
+
+	data = entity_get_data_ref(e, key_keydef);
+	if (data == NULL) {
+		return SLURM_ERROR;
+	}
+
+	switch(real_type) {
+	case L_T_ERROR:
+		return SLURM_ERROR;
+	case L_T_STRING:
+		pstr = (char**) value;
+		if (data)
+			*pstr = xstrdup(data);
+		else
+			*pstr = NULL;
+		return SLURM_SUCCESS;
+	case L_T_CUSTOM:
+		/* TBD : add a custom_get call */
+		pstr = (char**) value;
+		*pstr = NULL;
+		return SLURM_ERROR;
+	case L_T_LONG:
+		size = sizeof(long);
+		break;
+	case L_T_UINT16:
+		size = sizeof(uint16_t);
+		break;
+	case L_T_UINT32:
+		size = sizeof(uint32_t);
+		break;
+	case L_T_BOOLEAN:
+		size = sizeof(bool);
+		break;
+	case L_T_FLOAT:
+		size = sizeof(float);
+		break;
+	case L_T_DOUBLE:
+		size = sizeof(double);
+		break;
+	case L_T_LONG_DOUBLE:
+		size = sizeof(long double);
+		break;
+	}
+	memcpy(value, data, size);
+	return SLURM_SUCCESS;
+}
+
+int _layouts_entity_get_mkv(layout_t* l, entity_t* e, char* keys, void* value,
+			    size_t length, layouts_keydef_types_t key_type)
+{
+	char *key = NULL;
+	hostlist_t kl;
+	size_t processed = 0;
+	size_t elt_size = sizeof(void*);;
+	int rc = 0;
+
+	/* expand in order the requested keys (in hostlist format)
+	 * and iterate over each one of them, collecting the different
+	 * values into the provided buffer.
+	 * if no more space is available in the buffer, then just count
+	 * the missing elements for the exit code.
+	 * the first error encountered fakes a full buffer to just add
+	 * the remaining keys to the missing elements count before
+	 * exiting. */
+	kl = hostlist_create(keys);
+	while ((key = hostlist_shift(kl))) {
+		if (processed >= length) {
+			rc++;
+			continue;
+		}
+		if (_layouts_entity_get_kv_size(l, e, key, &elt_size) ||
+		    (processed + elt_size) > length ||
+		    _layouts_entity_get_kv(l, e, key, value, key_type)) {
+			rc++;
+			processed = length;
+			continue;
+		}
+		value += elt_size;
+		processed += elt_size;
+	}
+	hostlist_destroy(kl);
+
+	return rc;
+}
+
+int _layouts_entity_get_kv_ref(layout_t* l, entity_t* e,
+			       char* key, void** value,
+			       layouts_keydef_types_t key_type)
+{
+	int rc = SLURM_ERROR;
+	char key_keydef[PATHLEN];
+	void* data;
+
+	if (l == NULL || e == NULL || key == NULL || value == NULL)
+		return rc;
+
+	if (!_layouts_entity_check_kv_keytype(l, e, key, key_type))
+		return rc;
+
+	_normalize_keydef_key(key_keydef, PATHLEN, key, l->type);
+	data = entity_get_data_ref(e, key_keydef);
+	if (data != NULL) {
+		*value = data;
+		rc = SLURM_SUCCESS;
+	}
+	return rc;
+}
+
+int _layouts_entity_get_mkv_ref(layout_t* l, entity_t* e, char* keys,
+				void* value, size_t length,
+				layouts_keydef_types_t key_type)
+{
+	char *key = NULL;
+	hostlist_t kl;
+	size_t processed = 0;
+	size_t elt_size = sizeof(void*);
+	int rc = 0;
+
+	/* expand in order the requested keys (in hostlist format)
+	 * and iterate over each one of them, collecting the different
+	 * references into the provided buffer.
+	 * if no more space is available in the buffer, then just count
+	 * the missing elements for the exit code.
+	 * the first error encountered fakes a full buffer to just add
+	 * the remaining keys to the missing elements count before
+	 * exiting. */
+	kl = hostlist_create(keys);
+	while ((key = hostlist_shift(kl))) {
+		if (processed >= length) {
+			rc++;
+			continue;
+		}
+		if (_layouts_entity_get_kv_ref(l, e, key, value, key_type)) {
+			rc++;
+			processed = length;
+			continue;
+		}
+		value += elt_size;
+		processed += elt_size;
+	}
+	hostlist_destroy(kl);
+
+	return rc;
+}
+
+int _layouts_entity_pullget_kv(layout_t* l, entity_t* e, char* key, void* value,
+			       layouts_keydef_types_t key_type)
+{
+	int rc = SLURM_ERROR;
+	if (!_layouts_entity_check_kv_keytype(l, e, key, key_type))
+		return rc;
+	if (_layouts_entity_pull_kv(l, e, key) == SLURM_SUCCESS)
+		rc = _layouts_entity_get_kv(l, e, key, value, key_type);
+	return rc;
+}
+
+int _layouts_entity_pullget_kv_ref(layout_t* l, entity_t* e,
+				   char* key, void** value,
+				   layouts_keydef_types_t key_type)
+{
+	int rc = SLURM_ERROR;
+	if (!_layouts_entity_check_kv_keytype(l, e, key, key_type))
+		return rc;
+	if (_layouts_entity_pull_kv(l, e, key) == SLURM_SUCCESS)
+		rc = _layouts_entity_get_kv_ref(l, e, key, value, key_type);
+	return rc;
 }
 
 /*****************************************************************************\
  *                                MANAGER INIT                               *
 \*****************************************************************************/
 
-static void _slurm_layouts_init_keydef(xhash_t* keydefs,
-				       const layouts_keyspec_t* plugin_keyspec,
-				       layout_plugin_t* plugin)
+static void _layouts_init_keydef(xhash_t* keydefs,
+				 const layouts_keyspec_t* plugin_keyspec,
+				 layout_plugin_t* plugin)
 {
 	char keytmp[PATHLEN];
 
@@ -356,10 +814,21 @@ static void _slurm_layouts_init_keydef(xhash_t* keydefs,
 		nkeydef = (layouts_keydef_t*)
 			xmalloc(sizeof(layouts_keydef_t));
 		nkeydef->key = xstrdup(keytmp);
+		nkeydef->shortkey = xstrdup(current->key);
 		nkeydef->type = current->type;
+		nkeydef->flags = current->flags;
 		nkeydef->custom_destroy = current->custom_destroy;
 		nkeydef->custom_dump = current->custom_dump;
 		nkeydef->plugin = plugin;
+		if (current->ref_key != NULL) {
+			_normalize_keydef_key(keytmp, PATHLEN, current->ref_key,
+					      plugin->layout->type);
+			nkeydef->ref_key = xstrdup(keytmp);
+			nkeydef->ref_shortkey = xstrdup(current->ref_key);
+		} else {
+			nkeydef->ref_key = NULL;
+			nkeydef->ref_shortkey = NULL;
+		}
 		xhash_add(keydefs, nkeydef);
 	}
 
@@ -372,6 +841,7 @@ static void _slurm_layouts_init_keydef(xhash_t* keydefs,
 		nkeydef = (layouts_keydef_t*)
 			xmalloc(sizeof(layouts_keydef_t));
 		nkeydef->key = xstrdup(keytmp);
+		nkeydef->shortkey = xstrdup("Enclosed");
 		nkeydef->type = L_T_STRING;
 		nkeydef->plugin = plugin;
 		xhash_add(keydefs, nkeydef);
@@ -379,7 +849,7 @@ static void _slurm_layouts_init_keydef(xhash_t* keydefs,
 	}
 }
 
-static int _slurm_layouts_init_layouts_walk_helper(void* x, void* arg)
+static int _layouts_init_layouts_walk_helper(void* x, void* arg)
 {
 	layouts_conf_spec_t* spec = (layouts_conf_spec_t*)x;
 	int* i = (int*)arg;
@@ -388,6 +858,7 @@ static int _slurm_layouts_init_layouts_walk_helper(void* x, void* arg)
 	char plugin_name[PATHLEN];
 	void* inserted_item;
 	plugin_context_t* plugin_context;
+
 	snprintf(plugin_name, PATHLEN,
 		 "layouts/%s_%s", spec->type, spec->name);
 	plugin->ops = (layout_ops_t*)xmalloc(sizeof(layout_ops_t));
@@ -414,9 +885,9 @@ static int _slurm_layouts_init_layouts_walk_helper(void* x, void* arg)
 		    plugin->ops->spec->struct_type);
 	inserted_item = xhash_add(mgr->layouts, plugin->layout);
 	xassert(inserted_item == plugin->layout);
-	_slurm_layouts_init_keydef(mgr->keydefs,
-				   plugin->ops->spec->keyspec,
-				   plugin);
+	_layouts_init_keydef(mgr->keydefs,
+			     plugin->ops->spec->keyspec,
+			     plugin);
 	++*i;
 	return SLURM_SUCCESS;
 }
@@ -491,6 +962,13 @@ static char* _conf_get_filename(const char* type)
 	return final_path;
 }
 
+static char* _state_get_filename(const char* type)
+{
+	return xstrdup_printf("%s/layouts_state_%s",
+			      slurmctld_conf.state_save_location,
+			      type);
+}
+
 static s_p_hashtbl_t* _conf_make_hashtbl(int struct_type,
 					 const s_p_options_t* layout_options)
 {
@@ -529,7 +1007,7 @@ static s_p_hashtbl_t* _conf_make_hashtbl(int struct_type,
 		relational_options = tree_options;
 		break;
 	default:
-		fatal("layouts: does not know what relation structure to"
+		fatal("layouts: does not know what relation structure to "
 		      "use for type %d", struct_type);
 	}
 
@@ -546,28 +1024,32 @@ static s_p_hashtbl_t* _conf_make_hashtbl(int struct_type,
 	return tbl;
 }
 
-#define _layouts_load_merge(type_t, s_p_get_type) { \
-	type_t newvalue; \
-	type_t** oldvalue; \
-	if (!s_p_get_type(&newvalue, option_key, etbl)) { \
-		/* no value to merge/create */ \
-		continue; \
-	} \
-	oldvalue = (type_t**)entity_get_data(e, key_keydef); \
-	if (oldvalue) { \
-		**oldvalue = newvalue; \
-	} else { \
-		type_t* newalloc = (type_t*)xmalloc(sizeof(type_t)); \
-		*newalloc = newvalue; \
-		_entity_add_data(e, key_keydef, newalloc); \
-	} \
-}
-
-#define _layouts_merge_check(type1, type2) \
+#define _layouts_load_merge(type_t, s_p_get_type) {			\
+		type_t  rvalue;						\
+		type_t* value = &rvalue;				\
+		type_t* oldvalue;					\
+		slurm_parser_operator_t operator = S_P_OPERATOR_SET;	\
+		if (!s_p_get_type(&rvalue, option_key, etbl)) {		\
+			/* no value to merge/create */			\
+			continue;					\
+		}							\
+		s_p_get_operator(&operator, option_key, etbl);		\
+		oldvalue = (type_t*)entity_get_data_ref(e, key_keydef); \
+		if (oldvalue) {						\
+			_entity_update_kv_helper(type_t, operator);	\
+		} else {						\
+			type_t* newalloc = (type_t*)			\
+				xmalloc(sizeof(type_t));		\
+			*newalloc = *value;				\
+			_entity_add_data(e, key_keydef, newalloc);	\
+		}							\
+	}								\
+
+#define _layouts_merge_check(type1, type2)			\
 	(entity_option->type == type1 && keydef->type == type2)
 
 static void _layouts_load_automerge(layout_plugin_t* plugin, entity_t* e,
-		s_p_hashtbl_t* etbl)
+				    s_p_hashtbl_t* etbl, uint32_t flags)
 {
 	const s_p_options_t* layout_option;
 	const s_p_options_t* entity_option;
@@ -576,22 +1058,29 @@ static void _layouts_load_automerge(layout_plugin_t* plugin, entity_t* e,
 	char* option_key;
 
 	for (layout_option = plugin->ops->spec->options;
-		layout_option && strcasecmp("Entity", layout_option->key);
-		++layout_option);
+	     layout_option && strcasecmp("Entity", layout_option->key);
+	     ++layout_option);
 	xassert(layout_option);
 
 	for (entity_option = layout_option->line_options;
-			entity_option->key;
-			++entity_option) {
+	     entity_option->key;
+	     ++entity_option) {
 		option_key = entity_option->key;
 		_normalize_keydef_key(key_keydef, PATHLEN, option_key,
-				plugin->layout->type);
+				      plugin->layout->type);
 		keydef = xhash_get(mgr->keydefs, key_keydef);
 		if (!keydef) {
 			/* key is not meant to be automatically handled,
 			 * ignore it for this function */
 			continue;
 		}
+		/* do not perform automerge on updates for read-only keys */
+		if (flags & UPDATE_DONE &&
+		    keydef->flags & KEYSPEC_RDONLY) {
+			debug4("layouts: do not try to merge RDONLY key '%s'",
+			       keydef->key);
+			continue;
+		}
 		if (_layouts_merge_check(S_P_LONG, L_T_LONG)) {
 			_layouts_load_merge(long, s_p_get_long);
 		} else if (_layouts_merge_check(S_P_UINT16, L_T_UINT16)) {
@@ -602,6 +1091,13 @@ static void _layouts_load_automerge(layout_plugin_t* plugin, entity_t* e,
 			_layouts_load_merge(bool, s_p_get_boolean);
 		} else if (_layouts_merge_check(S_P_LONG, L_T_LONG)) {
 			_layouts_load_merge(long, s_p_get_long);
+		} else if (_layouts_merge_check(S_P_FLOAT, L_T_FLOAT)) {
+			_layouts_load_merge(float, s_p_get_float);
+		} else if (_layouts_merge_check(S_P_DOUBLE, L_T_DOUBLE)) {
+			_layouts_load_merge(double, s_p_get_double);
+		} else if (_layouts_merge_check(S_P_LONG_DOUBLE,
+						L_T_LONG_DOUBLE)) {
+			_layouts_load_merge(long double, s_p_get_long_double);
 		} else if (_layouts_merge_check(S_P_STRING, L_T_STRING)) {
 			char* newvalue;
 			if (s_p_get_string(&newvalue, option_key, etbl)) {
@@ -616,38 +1112,39 @@ static void _layouts_parse_relations(layout_plugin_t* plugin, entity_t* e,
 				     s_p_hashtbl_t* entity_tbl)
 {
 	char* e_enclosed;
-	char** e_already_enclosed;
+	char* e_already_enclosed;
+	char* e_new_enclosed;
 	char key[PATHLEN];
 	switch(plugin->layout->struct_type) {
 	case LAYOUT_STRUCT_TREE:
 		if (s_p_get_string(&e_enclosed, "Enclosed", entity_tbl)) {
 			_normalize_keydef_mgrkey(key, PATHLEN, "enclosed",
-					plugin->layout->type);
-			e_already_enclosed = (char**)entity_get_data(e, key);
+						 plugin->layout->type);
+			e_already_enclosed = (char*)
+				entity_get_data_ref(e, key);
 			if (e_already_enclosed) {
-				/* FC expressed warnings about that section,
-				 * should be checked more */
-				*e_already_enclosed = xrealloc(
-						*e_already_enclosed,
-						strlen(*e_already_enclosed) +
-						strlen(e_enclosed) + 2);
-				strcat(*e_already_enclosed, ",");
-				strcat(*e_already_enclosed, e_enclosed);
+				e_new_enclosed = (char*) xmalloc(
+					strlen(e_already_enclosed) +
+					strlen(e_enclosed) + 2);
+				strcat(e_new_enclosed, e_already_enclosed);
+				strcat(e_new_enclosed, ",");
+				strcat(e_new_enclosed, e_enclosed);
 				xfree(e_enclosed);
-			} else {
-				_entity_add_data(e, key, e_enclosed);
+				e_enclosed = e_new_enclosed;
 			}
+			_entity_add_data(e, key, e_enclosed);
 		}
 		break;
 	}
 }
 
 static int _layouts_read_config_post(layout_plugin_t* plugin,
-		s_p_hashtbl_t* tbl)
+				     s_p_hashtbl_t* tbl)
 {
 	char* root_nodename;
 	entity_t* e;
-	xtree_node_t* root_node,* inserted_node;
+	entity_node_t* enode;
+	xtree_node_t* root_node;
 	xtree_t* tree;
 	switch(plugin->layout->struct_type) {
 	case LAYOUT_STRUCT_TREE:
@@ -667,36 +1164,32 @@ static int _layouts_read_config_post(layout_plugin_t* plugin,
 			return SLURM_ERROR;
 		}
 		xfree(root_nodename);
-		root_node = xtree_add_child(tree, NULL, e, XTREE_APPEND);
+		enode = entity_add_node(e, plugin->layout);
+		xassert(enode);
+		root_node = xtree_add_child(tree, NULL, enode, XTREE_APPEND);
 		xassert(root_node);
-		inserted_node = list_append(e->nodes, root_node);
-		xassert(inserted_node == root_node);
+		enode->node = (void*) root_node;
 		break;
 	}
 	return SLURM_SUCCESS;
 }
 
 /*
- * _layouts_read_config - called after base entities are loaded successfully
- *
- * This function is the stage 1 of the layouts loading stage, where we collect
- * info on all the entities and store them in a global hash table.
- * Entities that do not already exist are created, otherwise updated.
- *
- * Information concerning the relations among entities provided by the
- * 'Enclosed' conf pragma are also extracted here for further usage in stage 2.
- *
- * When layout plugins callbacks are called, relational structures among
- * entities are not yet built.
+ * _layouts_load_config_common - called by layouts_read_config,
+ *       layouts_read_state or layouts_update_config with either a
+ *       filename or a buffer as well as a flag to indicate if it
+ *       is a full load or not (state save only)
  */
-static int _layouts_read_config(layout_plugin_t* plugin)
+static int _layouts_load_config_common(layout_plugin_t* plugin,
+				       char* filename, Buf buffer,
+				       uint32_t flags)
 {
 	s_p_hashtbl_t* tbl = NULL;
 	s_p_hashtbl_t** entities_tbl = NULL;
 	s_p_hashtbl_t* entity_tbl = NULL;
 	int entities_tbl_count = 0, i;
+	entity_t** updated_entities = NULL;
 	int rc = SLURM_ERROR;
-	char* filename = NULL;
 
 	uint32_t l_priority;
 
@@ -711,16 +1204,25 @@ static int _layouts_read_config(layout_plugin_t* plugin)
 
 	tbl = _conf_make_hashtbl(plugin->layout->struct_type,
 				 plugin->ops->spec->options);
-	filename = _conf_get_filename(plugin->layout->type);
-	if (!filename) {
-		fatal("layouts: cannot find configuration file for "
-		      "required layout '%s'", plugin->name);
-	}
-	if (s_p_parse_file(tbl, NULL, filename, false) == SLURM_ERROR) {
-		fatal("layouts: something went wrong when opening/reading "
-		      "'%s': %m", filename);
+	if (filename) {
+		if (s_p_parse_file(tbl, NULL, filename, false) == SLURM_ERROR) {
+			fatal("layouts: something went wrong when opening/reading "
+			      "'%s': %m", filename);
+		}
+		debug3("layouts: configuration file '%s' is loaded", filename);
+	} else if (buffer) {
+		if (s_p_parse_buffer(tbl, NULL, buffer, false) == SLURM_ERROR) {
+			error("layouts: something went wrong when parsing "
+			      "buffer : %m");
+			rc =  SLURM_ERROR;
+			goto cleanup;
+		}
+		debug3("layouts: buffer loaded");
+	} else {
+		error("layouts: invalid usage of _layouts_load_config_common");
+		rc = SLURM_ERROR;
+		goto cleanup;
 	}
-	debug3("layouts: configuration file '%s' is loaded", filename);
 
 	if (s_p_get_uint32(&l_priority, "Priority", tbl)) {
 		plugin->layout->priority = l_priority;
@@ -728,15 +1230,21 @@ static int _layouts_read_config(layout_plugin_t* plugin)
 
 	/* get the config hash tables of the defined entities */
 	if (!s_p_get_expline(&entities_tbl, &entities_tbl_count,
-				"Entity", tbl)) {
+			     "Entity", tbl)) {
 		error("layouts: no valid Entity found, can not append any "
 		      "information nor construct relations for %s/%s",
 		      plugin->layout->type, plugin->layout->name);
 		goto cleanup;
 	}
 
+	/* stage 0: xmalloc an array of entity_t* to save the updated entity_t
+	 * and give their references in the update_done layout callback */
+	updated_entities = (entity_t**)
+		xmalloc(entities_tbl_count*sizeof(entity_t*));
+
 	/* stage 1: create the described entities or update them */
 	for (i = 0; i < entities_tbl_count; ++i) {
+		updated_entities[i] = NULL;
 		entity_tbl = entities_tbl[i];
 		xfree(e_name);
 		xfree(e_type);
@@ -745,7 +1253,7 @@ static int _layouts_read_config(layout_plugin_t* plugin)
 			      "skipping...", i);
 			continue;
 		}
-		
+
 		/* look for the entity in the entities hash table*/
 		e = xhash_get(mgr->entities, e_name);
 		if (!e) {
@@ -775,18 +1283,20 @@ static int _layouts_read_config(layout_plugin_t* plugin)
 				      "invalid, skipping", e_name, e_type);
 				continue;
 			}
-			if (!strcmp(e_type, e->type)) {
+			if (!e->type || strcmp(e_type, e->type)) {
 				error("layouts: entity '%s' type (%s) differs "
 				      "from already registered entity type (%s)"
-				      "skipping", e_name, e_type, e->type);
+				      " skipping", e_name, e_type, e->type);
 				continue;
 			}
 		}
 
-		/* look for "Enclosed" pragmas identifying the relations
+		/* ** Full load config only (flags==0) **
+		 * look for "Enclosed" pragmas identifying the relations
 		 * among entities and kep that along with the entity for
 		 * stage 2 */
-		_layouts_parse_relations(plugin, e, entity_tbl);
+		if (flags & PARSE_RELATIONS)
+			_layouts_parse_relations(plugin, e, entity_tbl);
 
 		/*
 		 * if the layout plugin requests automerge, try to automatically
@@ -795,33 +1305,41 @@ static int _layouts_read_config(layout_plugin_t* plugin)
 		 * type and adding them to the entity key hash table.
 		 */
 		if (plugin->ops->spec->automerge) {
-			_layouts_load_automerge(plugin, e, entity_tbl);
+			_layouts_load_automerge(plugin, e, entity_tbl, flags);
 		}
 
 		/*
 		 * in case the automerge was not sufficient, the layout parsing
 		 * callback is called for further actions.
 		 */
-		if (plugin->ops->entity_parsing) {
+		if ((flags & PARSE_ENTITY) && plugin->ops->entity_parsing) {
 			plugin->ops->entity_parsing(e, entity_tbl,
 						    plugin->layout);
 		}
+
+		/* add the entity ref to the array for further usage when
+		 * calling the update_done layout callback */
+		updated_entities[i] = e;
 	}
+	xfree(e_name);
+	xfree(e_type);
 
-	/* post-read-and-build (post stage 1)
+	/* ** Full load config only (flags==0) **
+	 * post-read-and-build (post stage 1)
 	 * ensure that a Root entity was defined and set it as the root of
 	 * the relational structure of the layout.
 	 * fails in case of error as a root is mandatory to walk the relational
 	 * structure of the layout */
-	if (_layouts_read_config_post(plugin, tbl) != SLURM_SUCCESS) {
+	if ((flags & CONF_DONE) &&
+	    _layouts_read_config_post(plugin, tbl) != SLURM_SUCCESS) {
 		goto cleanup;
 	}
 
-	/*
+	/* ** Full load config only (flags==0) **
 	 * call the layout plugin conf_done callback for further
 	 * layout specific actions.
 	 */
-	if (plugin->ops->conf_done) {
+	if ((flags & CONF_DONE) && plugin->ops->conf_done) {
 		if (!plugin->ops->conf_done(mgr->entities, plugin->layout,
 					    tbl)) {
 			error("layouts: plugin %s/%s has an error parsing its"
@@ -830,37 +1348,141 @@ static int _layouts_read_config(layout_plugin_t* plugin)
 			goto cleanup;
 		}
 	}
-	
+
+	/*
+	 * In case we are processing an update (not a startup configuration)
+	 * if the layout plugin requests autoupdate, call the autoupdate
+	 * function on the current layout in order to set the inherited values
+	 * according to the newly modified ones.
+	 * (in startup configuration, the autoupdate is performed in stage 3
+	 *  when the relational structures are available)
+	 */
+	if ((flags & UPDATE_DONE) && plugin->ops->spec->autoupdate) {
+		_layouts_autoupdate_layout(plugin->layout);
+	}
+
+	/*
+	 * Call the layout plugin update_done callback for further
+	 * layout specific actions.
+	 * Note : some entries of the updated_entities array might be NULL
+	 * reflecting an issue while trying to analyze the corresponding
+	 * parsed hash table.
+	 */
+	if ((flags & UPDATE_DONE) && plugin->ops->update_done) {
+		if (!plugin->ops->update_done(plugin->layout, updated_entities,
+					      entities_tbl_count)) {
+			error("layouts: plugin %s/%s has an error reacting to"
+			      " entities update", plugin->layout->type,
+			      plugin->layout->name);
+			goto cleanup;
+		}
+	}
+	xfree(updated_entities);
+
 	rc = SLURM_SUCCESS;
 
 cleanup:
 	s_p_hashtbl_destroy(tbl);
-	xfree(filename);
 
 	return rc;
 }
 
-typedef struct _layouts_build_xtree_walk_st {
-	char* enclosed_key;
-	xtree_t* tree;
-} _layouts_build_xtree_walk_t;
-
-uint8_t _layouts_build_xtree_walk(xtree_node_t* node,
-					 uint8_t which,
-					 uint32_t level,
-					 void* arg)
+/*
+ * _layouts_read_config - called after base entities are loaded successfully
+ *
+ * This function is the stage 1 of the layouts loading stage, where we collect
+ * info on all the entities and store them in a global hash table.
+ * Entities that do not already exist are created, otherwise updated.
+ *
+ * Information concerning the relations among entities provided by the
+ * 'Enclosed' conf pragma are also extracted here for further usage in stage 2.
+ *
+ * When layout plugins callbacks are called, relational structures among
+ * entities are not yet built.
+ */
+static int _layouts_read_config(layout_plugin_t* plugin)
 {
-	_layouts_build_xtree_walk_t* p = (_layouts_build_xtree_walk_t*)arg;
-	entity_t* e;
-	char** enclosed_str;
+	int rc;
+	char* filename = _conf_get_filename(plugin->layout->type);
+	if (!filename) {
+		fatal("layouts: cannot find configuration file for "
+		      "required layout '%s'", plugin->name);
+	}
+	rc = _layouts_load_config_common(plugin, filename, NULL,
+					 CONF_DONE |
+					 PARSE_ENTITY | PARSE_RELATIONS);
+	xfree(filename);
+	return rc;
+}
+
+/*
+ * _layouts_read_state - called to restore saved state of layout entities
+ *
+ * This function is the stage 1.1 of the layouts loading stage, where we collect
+ * info on all the entities stored in the state of the layout and store/update
+ * them in the global hash table.
+ *
+ * Information concerning the relations among entities provided by the
+ * 'Enclosed' conf pragma are not taken into account for now and will be those
+ * loaded during stage 1.
+ *
+ * No layout plugins callbacks are called when doing that for now.
+ */
+static int _layouts_read_state(layout_plugin_t* plugin)
+{
+	int rc = SLURM_SUCCESS;
+	struct stat stat_buf;
+	char *filename = _state_get_filename(plugin->layout->type);
+	if (!filename) {
+		error("layouts: unable to build read state filename of layout"
+		      " '%s/%s'", plugin->layout->type, plugin->layout->name);
+		return SLURM_ERROR;
+	}
+	/* check availability of the file otherwise it will later block
+	 * waiting for a file to appear (in s_p_parse_file) */
+	if (stat(filename, &stat_buf) < 0) {
+		debug("layouts: skipping non existent state file for '%s/%s'",
+		      plugin->layout->type, plugin->layout->name);
+	} else {
+		rc = _layouts_load_config_common(plugin, filename, NULL,
+						 PARSE_ENTITY);
+	}
+	xfree(filename);
+	return rc;
+}
+
+static int _layouts_update_state(layout_plugin_t* plugin, Buf buffer)
+{
+	return _layouts_load_config_common(plugin, NULL, buffer,
+					   PARSE_ENTITY | UPDATE_DONE);
+}
+
+typedef struct _layouts_build_xtree_walk_st {
+	layout_t* layout;
+	char* enclosed_key;
+	xtree_t* tree;
+} _layouts_build_xtree_walk_t;
+
+uint8_t _layouts_build_xtree_walk(xtree_node_t* node,
+				  uint8_t which,
+				  uint32_t level,
+				  void* arg)
+{
+	_layouts_build_xtree_walk_t* p = (_layouts_build_xtree_walk_t*)arg;
+	entity_t* e;
+	entity_node_t* enode;
+	char* enclosed_str;
 	char* enclosed_name;
 	hostlist_t enclosed_hostlist;
 	entity_t* enclosed_e;
-	xtree_node_t* enclosed_node,* inserted_node;
+	xtree_node_t* enclosed_node;
 
 	xassert(arg);
 
-	e = xtree_node_get_data(node);
+	/* get the entity from the entity node associated with the tree node */
+	enode = (entity_node_t*) xtree_node_get_data(node);
+	xassert(enode);
+	e = enode->entity;
 	xassert(e);
 
 	/*
@@ -873,11 +1495,10 @@ uint8_t _layouts_build_xtree_walk(xtree_node_t* node,
 	if (which != XTREE_GROWING && which != XTREE_PREORDER)
 		return 1;
 
-	enclosed_str = (char**)entity_get_data(e, p->enclosed_key);
+	enclosed_str = (char*) entity_get_data_ref(e, p->enclosed_key);
 
 	if (enclosed_str) {
-		enclosed_hostlist = hostlist_create(*enclosed_str);
-		xfree(*enclosed_str);
+		enclosed_hostlist = hostlist_create(enclosed_str);
 		entity_delete_data(e, p->enclosed_key);
 		while ((enclosed_name = hostlist_shift(enclosed_hostlist))) {
 			enclosed_e = xhash_get(mgr->entities, enclosed_name);
@@ -890,13 +1511,18 @@ uint8_t _layouts_build_xtree_walk(xtree_node_t* node,
 				continue;
 			}
 			free(enclosed_name);
+			/* create an entity node associated to the entity 
+			 * for this layout */
+			enode = entity_add_node(enclosed_e, p->layout);
+			xassert(enode);
+			/* add it to the tree, getting an xtree_node_t ref */
 			enclosed_node = xtree_add_child(p->tree, node,
-							enclosed_e, 
-							XTREE_APPEND);
+							enode, XTREE_APPEND);
 			xassert(enclosed_node);
-			inserted_node = list_append(enclosed_e->nodes,
-						    enclosed_node);
-			xassert(inserted_node == enclosed_node);
+			/* store the xtree_node_t ref in the entity node. It
+			 * will be used to access this layout tree from the
+			 * entity when necessary through the entity node */
+			enode->node = enclosed_node;
 		}
 		hostlist_destroy(enclosed_hostlist);
 	}
@@ -928,6 +1554,7 @@ static int _layouts_build_relations(layout_plugin_t* plugin)
 		_normalize_keydef_mgrkey(key, PATHLEN, "enclosed",
 					 plugin->layout->type);
 		_layouts_build_xtree_walk_t p = {
+			plugin->layout,
 			key,
 			tree
 		};
@@ -942,6 +1569,526 @@ static int _layouts_build_relations(layout_plugin_t* plugin)
 	return SLURM_SUCCESS;
 }
 
+/*****************************************************************************\
+ *                                  STATE DUMP                               *
+\*****************************************************************************/
+
+/*
+ * _pack_args_t : helper struct/type used when passing args among the various
+ * functions used when packing layouts into a buffer as a set of strings.
+ */
+typedef struct _pack_args {
+	Buf       buffer;
+	char      *current_line;
+	layout_t* layout;
+} _pack_args_t;
+
+/*
+ * _pack_data_key : internal function used to get the key=val
+ * string representation of a particular entity data value
+ */
+static char* _pack_data_key(layouts_keydef_t* keydef, void* value)
+{
+	char val;
+	if (!keydef) {
+		return NULL;
+	}
+	switch(keydef->type) {
+	case L_T_ERROR:
+		return NULL;
+	case L_T_STRING:
+		return xstrdup_printf("%s=%s", keydef->shortkey,
+				      (char*)value);
+	case L_T_LONG:
+		return xstrdup_printf("%s=%ld", keydef->shortkey,
+				      *(long*)value);
+	case L_T_UINT16:
+		return xstrdup_printf("%s=%u", keydef->shortkey,
+				      *(uint16_t*)value);
+	case L_T_UINT32:
+		return xstrdup_printf("%s=%"PRIu32, keydef->shortkey,
+				      *(uint32_t*)value);
+	case L_T_BOOLEAN:
+		val = *(bool*)value;
+		return xstrdup_printf("%s=%s", keydef->shortkey,
+				      val ? "true" : "false");
+	case L_T_FLOAT:
+		return xstrdup_printf("%s=%f", keydef->shortkey,
+				      *(float*)value);
+	case L_T_DOUBLE:
+		return xstrdup_printf("%s=%f", keydef->shortkey,
+				      *(double*)value);
+	case L_T_LONG_DOUBLE:
+		return xstrdup_printf("%s=%Lf", keydef->shortkey,
+				      *(long double*)value);
+	case L_T_CUSTOM:
+		if (keydef->custom_dump) {
+			return keydef->custom_dump(value);
+		} else
+			return NULL;
+	}
+	return NULL;
+}
+
+/*
+ * _pack_entity_layout_data : internal function used to append the
+ * key/value of a entity data element corresponding to the targeted
+ * layout when walking an entity list of entity data elements
+ *
+ * - append the " %key%=%val%" to the char* received as an input arg member
+ *
+ */
+static void _pack_entity_layout_data(void* item, void* arg)
+{
+	entity_data_t* data;
+	_pack_args_t *pargs;
+
+	layouts_keydef_t* keydef;
+	char *data_dump;
+
+	xassert(item);
+	xassert(arg);
+
+	data = (entity_data_t*) item;
+	pargs = (_pack_args_t *) arg;
+
+	/* the pack args must contain a valid char* to append to */
+	xassert(pargs->current_line);
+
+	/* we must be able to get the keydef associated to the data key */
+	xassert(data);
+	keydef = xhash_get(mgr->keydefs, data->key);
+	xassert(keydef);
+
+	/* only dump keys related to the targeted layout */
+	if (!strncmp(keydef->plugin->name, pargs->layout->type, PATHLEN)) {
+		data_dump = _pack_data_key(keydef, data->value);
+		/* avoid printing any error in case of NULL pointer returned */
+		if (data_dump) {
+			xstrcat(pargs->current_line, " ");
+			xstrcat(pargs->current_line, data_dump);
+			xfree(data_dump);
+		}
+	}
+
+	return;
+}
+
+/*
+ * _pack_layout_tree : internal function used when walking a layout tree
+ *
+ * - print one line per entity with the following pattern :
+ *  Entity=%name% [Type=%type%] [Enclosed=%childrens%] [key1=val1 ...]
+ *
+ * - potentially print an header line if the entity is the root like :
+ *  Root=%name%
+ *
+ */
+static uint8_t _pack_layout_tree(xtree_node_t* node, uint8_t which,
+				 uint32_t level, void* arg)
+{
+	_pack_args_t *pargs;
+	xtree_node_t* child;
+	entity_node_t* enode;
+	hostlist_t enclosed;
+	char *enclosed_str = NULL, *e_name = NULL, *e_type = NULL;
+	Buf buffer;
+	char *strdump, *str;
+
+	/* only need to work for preorder and leaf cases */
+	if (which != XTREE_PREORDER && which != XTREE_LEAF) {
+		return 1;
+	}
+
+	/* get the buffer we need to pack the data too */
+	pargs = (_pack_args_t *) arg;
+	buffer = pargs->buffer;
+
+	/* aggregate children names to build the Enclosed=.. value */
+	if (which == XTREE_PREORDER) {
+		enclosed = hostlist_create(NULL);
+		child = node->start;
+		while (child) {
+			enode = (entity_node_t*) xtree_node_get_data(child);
+			if (!enode || !enode->entity) {
+				hostlist_push(enclosed, "NULL");
+			} else {
+				hostlist_push(enclosed, enode->entity->name);
+			}
+			child = child->next;
+		}
+		hostlist_uniq(enclosed);
+		if (hostlist_count(enclosed) > 0) {
+			enclosed_str = hostlist_ranged_string_xmalloc(enclosed);
+		}
+		hostlist_destroy(enclosed);
+	}
+
+	/* get the entity associated to this xtree node */
+	enode = (entity_node_t*) xtree_node_get_data(node);
+	if (!enode || !enode->entity) {
+		e_name = (char*) "NULL";
+		e_type = NULL;
+	}
+	else {
+		e_name = enode->entity->name;
+		e_type = enode->entity->type;
+	}
+
+	/* print this entity as root if necessary */
+	if (level == 0) {
+		str = xstrdup_printf("Root=%s\n", e_name);
+		packstr(str, buffer);
+		xfree(str);
+	}
+
+	/* print entity name and type when possible */
+	str = xstrdup_printf("Entity=%s", e_name);
+	if (e_type) {
+		strdump = xstrdup_printf("%s Type=%s", str, e_type);
+		xfree(str);
+		str = strdump;
+	}
+
+	/* add entity keys matching the layout to the current str */
+	pargs->current_line = str;
+	if (enode && enode->entity)
+		xhash_walk(enode->entity->data, _pack_entity_layout_data,
+			   pargs);
+	/* the current line might have been extended/remalloced, so
+	 * we need to sync it again in str for further actions */
+	str = pargs->current_line;
+	pargs->current_line = NULL;
+
+	/* print enclosed entities if any */
+	if (!enclosed_str) {
+		xstrcat(str, "\n");
+	} else {
+		strdump = xstrdup_printf("%s Enclosed=%s\n", str, enclosed_str);
+		xfree(enclosed_str);
+		xfree(str);
+		str = strdump;
+	}
+	packstr(str, buffer);
+	xfree(str);
+
+	return 1;
+}
+
+/* helper function used by layouts_save_state when walking through
+ * the various layouts to save their state in Slurm state save location */
+static void _state_save_layout(void* item, void* arg)
+{
+	layout_t* layout = (layout_t*)item;
+	layouts_state_save_layout(layout->type);
+}
+
+/*****************************************************************************\
+ *                            ENTITIES KVs AUTOUPDATE                        *
+\*****************************************************************************/
+
+/*
+ * helper structure used when walking the tree of relational nodes in order
+ * to automatically update the entities KVs based on their inheritance
+ * relationships
+ */
+typedef struct _autoupdate_tree_args {
+	entity_node_t* enode;
+	uint8_t which;
+	uint32_t level;
+} _autoupdate_tree_args_t;
+
+/*
+ * helper function used to update a particular KV value of an entity according
+ * to a particular operator looking for the right type to apply during the 
+ * operation
+ */
+static int _autoupdate_entity_kv(layouts_keydef_t* keydef,
+				 layouts_keydef_t* ref_keydef,
+				 slurm_parser_operator_t operator,
+				 void* oldvalue, void* value)
+{
+	int rc = SLURM_ERROR;
+
+	if (keydef->type != ref_keydef->type)
+		return rc;
+
+	if (keydef->type == L_T_LONG) {
+		_entity_update_kv_helper(long, operator);
+	} else if (keydef->type == L_T_UINT16) {
+		_entity_update_kv_helper(uint16_t, operator);
+	} else if (keydef->type == L_T_UINT32) {
+		_entity_update_kv_helper(uint32_t, operator);
+	} else if (keydef->type == L_T_FLOAT) {
+		_entity_update_kv_helper(float, operator);
+	} else if (keydef->type == L_T_DOUBLE) {
+		_entity_update_kv_helper(double, operator);
+	} else if (keydef->type == L_T_LONG_DOUBLE) {
+		_entity_update_kv_helper(long double, operator);
+	} else {
+		// L_T_BOOLEAN, L_T_STRING, L_T_CUSTOM not yet supported
+		return rc;
+	}
+
+	return SLURM_SUCCESS;
+}
+
+/*
+ * helper function used to update KVs of an entity using its xtree_node
+ * looking for known inheritance in the neighborhood (parents/children) */
+static void _tree_update_node_entity_data(void* item, void* arg) {
+
+	uint32_t action;
+	entity_data_t* data;
+	_autoupdate_tree_args_t *pargs;
+	layouts_keydef_t* keydef;
+	layouts_keydef_t* ref_keydef;
+	slurm_parser_operator_t operator;
+	xtree_node_t *node, *child;
+	entity_node_t *enode, *cnode;
+	void* oldvalue;
+	void* value;
+	uint32_t count;
+	int setter;
+
+	xassert(item);
+	xassert(arg);
+
+	data = (entity_data_t*) item;
+	pargs = (_autoupdate_tree_args_t *) arg;
+	cnode = pargs->enode;
+
+	/* we must be able to get the keydef associated to the data key */
+	xassert(data);
+	keydef = xhash_get(mgr->keydefs, data->key);
+	xassert(keydef);
+
+	/* only work on keys that depend of their neighborhood */
+	if (!(keydef->flags & KEYSPEC_UPDATE_CHILDREN_MASK) &&
+	    !(keydef->flags & KEYSPEC_UPDATE_PARENTS_MASK)) {
+		return;
+	}
+
+	/* if children dependant and we are at leaf level, nothing to do */
+	if (keydef->flags & KEYSPEC_UPDATE_CHILDREN_MASK &&
+	    pargs->which == XTREE_LEAF)
+		return;
+
+	/* only work on keys related to the targeted layout */
+	if (strncmp(keydef->plugin->name, pargs->enode->layout->type,
+		    PATHLEN)) {
+		return;
+	}
+
+	/* get ref_key (identical if not defined) */
+	if (keydef->ref_key != NULL) {
+		ref_keydef = xhash_get(mgr->keydefs, keydef->ref_key);
+		if (!ref_keydef) {
+			debug2("layouts: autoupdate: key='%s': invalid "
+			       "ref_key='%s'", keydef->key, keydef->ref_key);
+			return;
+		}
+	} else {
+		ref_keydef = keydef;
+	}
+
+	/* process parents aggregation
+	 * for now, xtree only provides one parent so any update op
+	 * (MAX, MIN, FSHARE, ...) is a setter */
+	if ((action = keydef->flags & KEYSPEC_UPDATE_PARENTS_MASK) &&
+	    (pargs->which == XTREE_PREORDER || pargs->which == XTREE_LEAF) &&
+	    (node = ((xtree_node_t*)pargs->enode->node)->parent) != NULL ) {
+
+		/* get current node value reference */
+		oldvalue = entity_get_data_ref(cnode->entity, keydef->key);
+
+		/* get siblings count */
+		child = node->start;
+		count = 0;
+		while (child) {
+			count++;
+			child = child->next;
+		}
+
+		/* get parent node KV data ref */
+		enode = (entity_node_t*) xtree_node_get_data(node);
+		value = entity_get_data_ref(enode->entity, ref_keydef->key);
+		if (!value)
+			return;
+
+		/* only set operation currently provided for parents except
+		 * for fshare action */
+		_autoupdate_entity_kv(keydef, ref_keydef, S_P_OPERATOR_SET,
+				      oldvalue, value);
+		if (action == KEYSPEC_UPDATE_PARENTS_FSHARE) {
+			_autoupdate_entity_kv(keydef, ref_keydef,
+					      S_P_OPERATOR_AVG,
+					      oldvalue, (void*) &count);
+		}
+
+		return;
+	}
+
+	/* process children aggregation */
+	if ((action = keydef->flags & KEYSPEC_UPDATE_CHILDREN_MASK) &&
+	    pargs->which == XTREE_ENDORDER) {
+
+		/* get current node value reference */
+		oldvalue = entity_get_data_ref(cnode->entity, keydef->key);
+
+		/* get children count */
+		node = (xtree_node_t*)cnode->node;
+		child = node->start;
+		count = 0;
+		while (child) {
+			count++;
+			child = child->next;
+		}
+
+		/* no action if no children */
+		if (count == 0)
+			return;
+
+		/* if count action, do what is necessary and return */
+		if (action == KEYSPEC_UPDATE_CHILDREN_COUNT) {
+			_autoupdate_entity_kv(keydef, ref_keydef,
+					      S_P_OPERATOR_SET,
+					      oldvalue, (void*) &count);
+			return;
+		}
+
+		/* iterate on the children */
+		setter = 1;
+		child = node->start;
+		while (child) {
+			/* get child node KV data ref */
+			enode = (entity_node_t*) xtree_node_get_data(child);
+			value = entity_get_data_ref(enode->entity,
+						    ref_keydef->key);
+
+			if (!value) {
+				/* try next child */
+				child = child-> next;
+				continue;
+			}
+
+			switch (action) {
+			case KEYSPEC_UPDATE_CHILDREN_SUM:
+			case KEYSPEC_UPDATE_CHILDREN_AVG:
+				/* first child is a setter */
+				if (setter) {
+					operator = S_P_OPERATOR_SET;
+					setter = 0;
+				}
+				else
+					operator = S_P_OPERATOR_ADD;
+				break;
+			case KEYSPEC_UPDATE_CHILDREN_MIN:
+				operator = S_P_OPERATOR_SET_IF_MIN;
+				break;
+			case KEYSPEC_UPDATE_CHILDREN_MAX:
+				operator = S_P_OPERATOR_SET_IF_MAX;
+				break;
+			default:
+				/* should not be called! */
+				return;
+			}
+
+			/* update the value according to the operator */
+			_autoupdate_entity_kv(keydef, ref_keydef, operator,
+					      oldvalue, value);
+
+			/* then next child */
+			child = child-> next;
+		}
+
+		/* if average action, do what is necessary before return */
+		if (action == KEYSPEC_UPDATE_CHILDREN_AVG) {
+			_autoupdate_entity_kv(keydef, ref_keydef,
+					      S_P_OPERATOR_AVG,
+					      oldvalue, (void*) &count);
+			return;
+		}
+
+		return;
+	}
+
+}
+
+/*
+ * _autoupdate_layout_tree : internal function used when automatically
+ * updating elements of a layout tree using _layouts_autoupdate_layout */
+static uint8_t _autoupdate_layout_tree(xtree_node_t* node, uint8_t which,
+				       uint32_t level, void* arg)
+{
+	entity_node_t* cnode;
+	_autoupdate_tree_args_t sync_args;
+
+	/* only need to work for preorder, leaf and endorder cases */
+	if (which != XTREE_PREORDER &&
+	    which != XTREE_LEAF &&
+	    which != XTREE_ENDORDER) {
+		return 1;
+	}
+
+	/* extract current node entity_node to next browsing */
+	cnode = (entity_node_t*) xtree_node_get_data(node);
+	if (!cnode)
+		return 1;
+
+	/* prepare downcall args */
+	sync_args.enode = cnode;
+	sync_args.which = which;
+	sync_args.level = level;
+
+	/* iterate over the K/V of the entity, syncing them according
+	 * to their autoupdate flags */
+	xhash_walk(cnode->entity->data, _tree_update_node_entity_data,
+		   &sync_args);
+
+	return 1;
+}
+
+/* helper function used to automatically update a layout internal
+ * entities KVs based on inheritance relations (parents/children) */
+static int _layouts_autoupdate_layout(layout_t* layout)
+{
+	/* autoupdate according to the layout struct type */
+	switch(layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		xtree_walk(layout->tree, NULL, 0,
+			   XTREE_LEVEL_MAX,
+			   _autoupdate_layout_tree, NULL);
+		break;
+	}
+
+	return SLURM_SUCCESS;
+}
+
+/* helper function used to automatically update a layout internal
+ * entities KVs based on inheritance relations (parents/children)
+ * only when allowed by the associated plugin */
+static int _layouts_autoupdate_layout_if_allowed(layout_t* layout)
+{
+	int i, rc = SLURM_ERROR;
+	/* look if the corresponding layout plugin enables autoupdate */
+	for (i = 0; i < mgr->plugins_count; i++) {
+		if (mgr->plugins[i].layout == layout) {
+			/* no autoupdate allowed, return success */
+			if (!mgr->plugins[i].ops->spec->autoupdate)
+				rc = SLURM_SUCCESS;
+			else
+				rc = _layouts_autoupdate_layout(layout);
+			break;
+		}
+	}
+	return rc;
+}
+
+/*****************************************************************************\
+ *                                   DEBUG DUMP                              *
+\*****************************************************************************/
+
 /*
  * For debug purposes, dump functions helping to print the layout mgr
  * internal states in a file after the load.
@@ -1015,15 +2162,16 @@ static uint8_t _dump_layout_tree(xtree_node_t* node, uint8_t which,
 {
 	FILE* fdump = (FILE*)arg;
 	entity_t* e;
+	entity_node_t* enode;
 	if (which != XTREE_PREORDER && which != XTREE_LEAF) {
 		return 1;
 	}
-	e = xtree_node_get_data(node);
-	if (!e) {
+	enode = (entity_node_t*) xtree_node_get_data(node);
+	if (!enode || !enode->entity) {
 		fprintf(fdump, "NULL_entity\n");
 	}
 	else {
-		fprintf(fdump, "%*s%s\n", level, " ", e->name);
+		fprintf(fdump, "%*s%s\n", level, " ", enode->entity->name);
 	}
 	return 1;
 }
@@ -1054,16 +2202,17 @@ static void _dump_layouts(void* item, void* arg)
 }
 #endif
 
+
 /*****************************************************************************\
  *                             SLURM LAYOUTS API                             *
 \*****************************************************************************/
 
-int slurm_layouts_init(void)
+int layouts_init(void)
 {
 	int i = 0;
 	uint32_t layouts_count;
 
-	debug3("layouts: slurm_layouts_init()...");
+	debug3("layouts: layouts_init()...");
 
 	if (mgr->plugins) {
 		return SLURM_SUCCESS;
@@ -1080,8 +2229,8 @@ int slurm_layouts_init(void)
 
 	mgr->plugins = xmalloc(sizeof(layout_plugin_t) * layouts_count);
 	list_for_each(layouts_mgr.layouts_desc,
-			_slurm_layouts_init_layouts_walk_helper,
-			&i);
+		      _layouts_init_layouts_walk_helper,
+		      &i);
 	mgr->plugins_count = i;
 
 	if (mgr->plugins_count != layouts_count) {
@@ -1093,7 +2242,7 @@ int slurm_layouts_init(void)
 		xfree(mgr->plugins);
 		mgr->plugins = NULL;
 	} else if (layouts_count > 0) {
-		info("layouts: slurm_layouts_init done : %d layout(s) "
+		info("layouts: layouts_init done : %d layout(s) "
 		     "initialized", layouts_count);
 	}
 
@@ -1103,14 +2252,22 @@ int slurm_layouts_init(void)
 		SLURM_SUCCESS : SLURM_ERROR;
 }
 
-int slurm_layouts_fini(void)
+int layouts_fini(void)
 {
 	int i;
 
-	debug3("layouts: slurm_layouts_fini()...");
+	debug3("layouts: layouts_fini()...");
+
+	/* push layouts states to the state save location */
+	layouts_state_save();
 
 	slurm_mutex_lock(&mgr->lock);
 
+	/* free the layouts before destroying the plugins,
+	 * otherwise we will get trouble xfreeing the layouts whose
+	 * memory is owned by the plugins structs */
+	layouts_mgr_free(mgr);
+
 	for (i = 0; i < mgr->plugins_count; i++) {
 		_layout_plugins_destroy(&mgr->plugins[i]);
 	}
@@ -1118,8 +2275,6 @@ int slurm_layouts_fini(void)
 	mgr->plugins = NULL;
 	mgr->plugins_count = 0;
 
-	layouts_mgr_free(mgr);
-
 	slurm_mutex_unlock(&mgr->lock);
 
 	info("layouts: all layouts are now unloaded.");
@@ -1127,13 +2282,14 @@ int slurm_layouts_fini(void)
 	return SLURM_SUCCESS;
 }
 
-int slurm_layouts_load_config(void)
+int layouts_load_config(int recover)
 {
 	int i, rc, inx;
 	struct node_record *node_ptr;
 	layout_t *layout;
 	uint32_t layouts_count;
 	entity_t *entity;
+	entity_node_t *enode;
 	void *ptr;
 
 	info("layouts: loading entities/relations information");
@@ -1164,12 +2320,13 @@ int slurm_layouts_load_config(void)
 	 */
 	for (inx = 0, node_ptr = node_record_table_ptr; inx < node_record_count;
 	     inx++, node_ptr++) {
+		debug3("layouts: loading node %s", node_ptr->name);
 		xassert (node_ptr->magic == NODE_MAGIC);
 		xassert (node_ptr->config_ptr->magic == CONFIG_MAGIC);
 
 		/* init entity structure on the heap */
 		entity = (entity_t*) xmalloc(sizeof(struct entity_st));
-		entity_init(entity, node_ptr->name, 0); 
+		entity_init(entity, node_ptr->name, "Node");
 		entity->ptr = node_ptr;
 
 		/* add to mgr entity hashtable */
@@ -1184,8 +2341,9 @@ int slurm_layouts_load_config(void)
 
 		/* add to the base layout (storing a callback ref to the
 		 * layout node pointing to it) */
+		enode = entity_add_node(entity, layout);
 		ptr = xtree_add_child(layout->tree, layout->tree->root,
-				      (void*)entity, XTREE_APPEND);
+				      (void*)enode, XTREE_APPEND);
 		if (!ptr) {
 			error("layouts: unable to add entity of node %s"
 			      "in the hashtable, aborting", node_ptr->name);
@@ -1194,8 +2352,7 @@ int slurm_layouts_load_config(void)
 			rc = SLURM_ERROR;
 			break;
 		} else {
-			debug3("layouts: loading node %s", node_ptr->name);
-			entity_add_node(entity, layout, ptr);
+			enode->node = ptr;
 		}
 	}
 	debug("layouts: %d/%d nodes in hash table, rc=%d",
@@ -1241,6 +2398,14 @@ exit:
 				break;
 			}
 		}
+		if (recover) {
+			debug("layouts: loading stage 1.1 (restore state)");
+			for (i = 0; i < mgr->plugins_count; ++i) {
+				debug3("layouts: reading state of %s",
+				       mgr->plugins[i].name);
+				_layouts_read_state(&mgr->plugins[i]);
+			}
+		}
 		debug("layouts: loading stage 2");
 		for (i = 0; i < mgr->plugins_count; ++i) {
 			debug3("layouts: creating relations for %s",
@@ -1251,6 +2416,19 @@ exit:
 				break;
 			}
 		}
+		debug("layouts: loading stage 3");
+		for (i = 0; i < mgr->plugins_count; ++i) {
+			debug3("layouts: autoupdating %s",
+			       mgr->plugins[i].name);
+			if (mgr->plugins[i].ops->spec->autoupdate) {
+				if (_layouts_autoupdate_layout(mgr->plugins[i].
+							       layout) !=
+				    SLURM_SUCCESS) {
+					rc = SLURM_ERROR;
+					break;
+				}
+			}
+		}
 	}
 
 /*
@@ -1273,14 +2451,292 @@ exit:
 	return rc;
 }
 
-layout_t* slurm_layouts_get_layout(const char* type)
+layout_t* layouts_get_layout_nolock(const char* type)
 {
-	layout_t* layout = (layout_t*)xhash_get(mgr->layouts, type);
+	return (layout_t*)xhash_get(mgr->layouts, type);
+}
+
+layout_t* layouts_get_layout(const char* type)
+{
+	layout_t *layout = NULL;
+	slurm_mutex_lock(&mgr->lock);
+	layout = layouts_get_layout_nolock(type);
+	slurm_mutex_unlock(&mgr->lock);
 	return layout;
 }
 
-entity_t* slurm_layouts_get_entity(const char* name)
+entity_t* layouts_get_entity_nolock(const char* name)
+{
+	return (entity_t*)xhash_get(mgr->entities, name);
+}
+
+entity_t* layouts_get_entity(const char* name)
 {
-	entity_t* e = (entity_t*)xhash_get(mgr->entities, name);
+	entity_t* e;
+	slurm_mutex_lock(&mgr->lock);
+	e = layouts_get_entity_nolock(name);
+	slurm_mutex_unlock(&mgr->lock);
 	return e;
 }
+
+int layouts_pack_layout(char *l_type, Buf buffer)
+{
+	_pack_args_t pargs;
+	layout_t* layout;
+	char *str;
+
+	slurm_mutex_lock(&mgr->lock);
+
+	layout = layouts_get_layout_nolock(l_type);
+	if (layout == NULL) {
+		error("unable to get layout of type '%s'", l_type);
+		return SLURM_ERROR;
+	}
+
+	/* initialize args for recursive packing */
+	pargs.buffer = buffer;
+	pargs.layout = layout;
+	pargs.current_line = NULL;
+
+	/* start by packing the layout priority */
+	str = xstrdup_printf("Priority=%u\n", layout->priority);
+	packstr(str, buffer);
+	xfree(str);
+
+	/* pack according to the layout struct type */
+	switch(layout->struct_type) {
+	case LAYOUT_STRUCT_TREE:
+		xtree_walk(layout->tree, NULL, 0, XTREE_LEVEL_MAX,
+			   _pack_layout_tree, &pargs);
+		break;
+	}
+
+	/* EOF */
+	packstr("", buffer);
+
+	slurm_mutex_unlock(&mgr->lock);
+
+	return SLURM_SUCCESS;
+}
+
+int layouts_update_layout(char *l_type, Buf buffer)
+{
+	int i, rc;
+	slurm_mutex_lock(&mgr->lock);
+	for (i = 0; i < mgr->plugins_count; i++) {
+		if (!strcmp(mgr->plugins[i].name, l_type)) {
+			rc = _layouts_update_state((layout_plugin_t*)
+						   &mgr->plugins[i],
+						   buffer);
+			slurm_mutex_unlock(&mgr->lock);
+			return rc;
+		}
+	}
+	error("layouts: update layout : no plugin matching layout=%s, skipping",
+	      l_type);
+	slurm_mutex_unlock(&mgr->lock);
+	return SLURM_ERROR;
+}
+
+int layouts_autoupdate_layout(char *l_type)
+{
+	int rc = SLURM_ERROR;
+	layout_t* layout;
+
+	slurm_mutex_lock(&mgr->lock);
+	layout = layouts_get_layout_nolock(l_type);
+	if (layout == NULL) {
+		error("unable to get layout of type '%s'", l_type);
+	} else {
+		rc = _layouts_autoupdate_layout(layout);
+	}
+	slurm_mutex_unlock(&mgr->lock);
+
+	return rc;
+}
+
+int layouts_state_save_layout(char* l_type)
+{
+	int error_code = 0, log_fd;
+	char *old_file = NULL, *new_file = NULL, *reg_file = NULL;
+	static int high_buffer_size = (1024 * 1024);
+	Buf buffer = init_buf(high_buffer_size);
+	FILE* fdump;
+	uint32_t utmp32;
+	char *tmp_str = NULL;
+
+	DEF_TIMERS;
+	START_TIMER;
+
+	/* pack the targeted layout into a tmp buffer */
+	error_code = layouts_pack_layout(l_type, buffer);
+	if (error_code != SLURM_SUCCESS) {
+		error("unable to save layout[%s] state", l_type);
+		return error_code;
+	}
+
+	/* rewind the freshly created buffer to unpack it into a file */
+	set_buf_offset(buffer, 0);
+
+	/* create working files */
+	reg_file = _state_get_filename(l_type);
+	old_file = xstrdup_printf("%s.old", reg_file);
+	new_file = xstrdup_printf("%s.new", reg_file);
+	log_fd = creat(new_file, 0600);
+	if (log_fd < 0 || !(fdump = fdopen(log_fd, "w"))) {
+		error("Can't save state, create file %s error %m",
+		      new_file);
+		error_code = errno;
+	} else {
+		/* start dumping packed strings into the temporary file */
+		while (remaining_buf(buffer) > 0) {
+			safe_unpackstr_xmalloc(&tmp_str, &utmp32, buffer);
+			if (tmp_str != NULL) {
+				if (*tmp_str == '\0') {
+					xfree(tmp_str);
+					break;
+				}
+				fprintf(fdump, "%s", tmp_str);
+				xfree(tmp_str);
+				continue;
+			}
+		unpack_error:
+			break;
+		}
+		fflush(fdump);
+		fsync(log_fd);
+		fclose(fdump);
+	}
+	if (error_code)
+		(void) unlink(new_file);
+	else {			/* file shuffle */
+		(void) unlink(old_file);
+		if (link(reg_file, old_file))
+			debug4("unable to create link for %s -> %s: %m",
+			       reg_file, old_file);
+		(void) unlink(reg_file);
+		if (link(new_file, reg_file))
+			debug4("unable to create link for %s -> %s: %m",
+			       new_file, reg_file);
+		(void) unlink(new_file);
+	}
+	xfree(old_file);
+	xfree(reg_file);
+	xfree(new_file);
+
+	free_buf(buffer);
+
+	END_TIMER2("layouts_state_save_layout");
+
+	return SLURM_SUCCESS;
+}
+
+int layouts_state_save(void)
+{
+	DEF_TIMERS;
+	START_TIMER;
+	xhash_walk(mgr->layouts,  _state_save_layout, NULL);
+	END_TIMER2("layouts_state_save");
+	return SLURM_SUCCESS;
+}
+
+#define _layouts_entity_wrapper(func, l, e, r...)			\
+	layout_t* layout;						\
+	entity_t* entity;						\
+	int rc;								\
+	slurm_mutex_lock(&mgr->lock);					\
+	layout = layouts_get_layout_nolock(l);				\
+	entity = layouts_get_entity_nolock(e);				\
+	rc = func(layout, entity, ##r);					\
+	slurm_mutex_unlock(&mgr->lock);					\
+	return rc;							\
+
+int layouts_entity_get_kv_type(char* l, char* e, char* key)
+{
+	_layouts_entity_wrapper(_layouts_entity_get_kv_type,l,e,key);
+}
+
+int layouts_entity_get_kv_flags(char* l, char* e, char* key)
+{
+	_layouts_entity_wrapper(_layouts_entity_get_kv_flags, l, e, key);
+}
+
+int layouts_entity_push_kv(char* l, char* e, char* key)
+{
+	_layouts_entity_wrapper(_layouts_entity_push_kv, l, e, key);
+}
+
+int layouts_entity_pull_kv(char* l, char* e, char* key)
+{
+	_layouts_entity_wrapper(_layouts_entity_pull_kv, l, e, key);
+}
+
+int layouts_entity_set_kv(char* l, char* e, char* key, void* value,
+			  layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_set_kv, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_set_kv_ref(char* l, char* e, char* key, void* value,
+			      layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_set_kv_ref, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_setpush_kv(char* l, char* e, char* key, void* value,
+			      layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_setpush_kv, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_setpush_kv_ref(char* l, char* e, char* key, void* value,
+				  layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_setpush_kv_ref, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_get_kv(char* l, char* e, char* key, void* value,
+			  layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_get_kv, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_get_mkv(char* l, char* e, char* keys, void* value,
+			   size_t size, layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_get_mkv, l, e,
+				keys, value, size, key_type);
+}
+
+int layouts_entity_get_kv_ref(char* l, char* e, char* key, void** value,
+			      layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_get_kv_ref, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_get_mkv_ref(char* l, char* e, char* keys, void* value,
+			       size_t size, layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_get_mkv_ref, l, e,
+				keys, value, size, key_type);
+}
+
+int layouts_entity_pullget_kv(char* l, char* e, char* key, void* value,
+			      layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_pullget_kv, l, e,
+				key, value, key_type);
+}
+
+int layouts_entity_pullget_kv_ref(char* l, char* e, char* key, void** value,
+				  layouts_keydef_types_t key_type)
+{
+	_layouts_entity_wrapper(_layouts_entity_pullget_kv_ref, l, e,
+				key, value, key_type);
+}
diff --git a/src/common/layouts_mgr.h b/src/common/layouts_mgr.h
index 357ab5f19bc032ceca31d9a58d81dad6a8c58418..51218c601fc680645014eabc9854a811d271af01 100644
--- a/src/common/layouts_mgr.h
+++ b/src/common/layouts_mgr.h
@@ -4,6 +4,7 @@
  *  Initially written by Francois Chevallier <chevallierfrancois@free.fr>
  *  at Bull for slurm-2.6.
  *  Adapted by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-14.11.
+ *  Enhanced by Matthieu Hautreux <matthieu.hautreux@cea.fr> for slurm-15.x.
  *
  *  This file is part of SLURM, a resource management program.
  *  For details, see <http://slurm.schedmd.com/>.
@@ -41,6 +42,7 @@
 #include "src/common/list.h"
 #include "src/common/xhash.h"
 #include "src/common/xtree.h"
+#include "src/common/pack.h"
 #include "src/common/parse_config.h"
 
 #include "src/common/layout.h"
@@ -52,12 +54,12 @@
  * The layouts_mgr_t manages the layouts and entities loaded through the list
  * of layouts specified in the Slurm configuration file (slurm.conf)
  *
- * At startup, Slurm initialize one layouts_mgr_t using slurm_layouts_init()
+ * At startup, Slurm initialize one layouts_mgr_t using layouts_init()
  * and then load the required layouts defined in the configuration using
- * slurm_layouts_load_config().
+ * layouts_load_config().
  *
  * The different layouts and entities can then be queried using either
- * slurm_layouts_get_layout() and slurm_layouts_get_entity().
+ * layouts_get_layout() and layouts_get_entity().
  *
  * Note that each entity contains a list of nodes appearing inside the
  * associated layouts.
@@ -82,9 +84,30 @@ typedef enum layouts_keydef_types_en {
 	L_T_CUSTOM,
 } layouts_keydef_types_t;
 
+/* keyspec flags */
+#define KEYSPEC_RDONLY        0x00000001
+
+#define KEYSPEC_UPDATE_CHILDREN_SUM   0x00010000
+#define KEYSPEC_UPDATE_CHILDREN_AVG   0x00020000
+#define KEYSPEC_UPDATE_CHILDREN_MIN   0x00040000
+#define KEYSPEC_UPDATE_CHILDREN_MAX   0x00080000
+#define KEYSPEC_UPDATE_CHILDREN_COUNT 0x00110000
+#define KEYSPEC_UPDATE_CHILDREN_MASK  0x00FF0000
+
+#define KEYSPEC_UPDATE_PARENTS_SUM    0x01000000
+#define KEYSPEC_UPDATE_PARENTS_AVG    0x02000000
+#define KEYSPEC_UPDATE_PARENTS_MIN    0x04000000
+#define KEYSPEC_UPDATE_PARENTS_MAX    0x08000000
+#define KEYSPEC_UPDATE_PARENTS_FSHARE 0x11000000
+#define KEYSPEC_UPDATE_PARENTS_MASK   0xFF000000
+
 typedef struct layouts_keyspec_st {
 	char*			key;
 	layouts_keydef_types_t	type;
+	uint32_t                flags;
+	char*			ref_key; /* reference key to use for update
+					  * NULL means use the same key in my
+					  * neighborhood */
 	void			(*custom_destroy)(void*);
 	char*			(*custom_dump)(void*);
 } layouts_keyspec_t;
@@ -95,6 +118,7 @@ typedef struct layouts_plugin_spec_st {
 	int				struct_type;
 	const char**			etypes;
 	bool				automerge;
+	bool				autoupdate;
 } layouts_plugin_spec_t;
 
 /*****************************************************************************\
@@ -102,7 +126,7 @@ typedef struct layouts_plugin_spec_st {
 \*****************************************************************************/
 
 /*
- * slurm_layouts_init - intialize the layouts mgr, load the required plugins
+ * layouts_init - intialize the layouts mgr, load the required plugins
  *        and initialize the internal hash tables for entities, keydefs and
  *        layouts.
  *
@@ -112,40 +136,362 @@ typedef struct layouts_plugin_spec_st {
  * Notes: this call do not try to read and parse the layouts configuration
  * files. It only loads the layouts plugins, dlsym the layout API and conf
  * elements to prepare the reading and parsing performed in the adhoc call
- * slurm_layouts_load_config()
+ * layouts_load_config()
  *
  */
-int slurm_layouts_init(void);
+int layouts_init(void);
 
 /*
- * slurm_layouts_fini - uninitialize the layouts mgr and free the internal
+ * layouts_fini - uninitialize the layouts mgr and free the internal
  *        hash tables.
  */
-int slurm_layouts_fini(void);
+int layouts_fini(void);
 
 /*
- * slurm_layouts_load_config - use the layouts plugins details loaded during
- *        slurm_layouts_init() and read+parse the different layouts
+ * layouts_load_config - use the layouts plugins details loaded during
+ *        layouts_init() and read+parse the different layouts
  *        configuration files, creating the entities and the relational
  *        structures associated the eaf of them.
  *
+ * IN recover - update entities information with the latest available
+ *              information depending upon value
+ *              0 = use no saved state information, rebuild everything from
+ *		    layouts conf files contents
+ *              1 = recover saved entities information
+ *              2 = recover saved entities information
+ *
  * Return SLURM_SUCCESS or SLURM_ERROR if all the required layouts were not
  * loaded correctly.
  */
-int slurm_layouts_load_config(void);
+int layouts_load_config(int recover);
 
 /*
- * slurm_layouts_get_layout - return the layout from a given type
+ * layouts_get_layout - return the layout from a given type
  *
  * Return a pointer to the layout_t struct of the layout or NULL if not found
  */
-layout_t* slurm_layouts_get_layout(const char* type);
+layout_t* layouts_get_layout(const char* type);
 
 /*
- * slurm_layouts_get_entity - return the entity from a given name
+ * layouts_get_entity - return the entity from a given name
  *
  * Return a pointer to the entity_t struct of the entity or NULL if not found
  */
-entity_t* slurm_layouts_get_entity(const char* name);
+entity_t* layouts_get_entity(const char* name);
+
+/*
+ * layouts_pack_layout - pack the layout of the target type into the provided
+ *        buffer.
+ *
+ * The buffer will be appended with multiple strings representing an expanded
+ * form of its configuration element, terminated by a "\0" string.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_pack_layout(char *l_type, Buf buffer);
+
+/*
+ * layouts_update_layout - update a particular layout loading the information
+ *        provided in the input buffer.
+ *
+ * The buffer must contain multiple strings corresponding to the different
+ * configuration lines similar to those that can be put in a configuration
+ * file that will be parsed and integrated.
+ *
+ * Note that the entities key/value entries will be updated only.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_update_layout(char *l_type, Buf buffer);
+
+/*
+ * layouts_state_save_layout - save the state of a particular layout
+ *        in the adhoc file in slurm state save location.
+ *
+ * The file produced will be an ASCII file created from the configuration
+ * strings packed using layouts_pack_layout(). Thus it will be the expanded
+ * form of the current configuration of the layout that could be used as
+ * a perfect updated replacement of the layout configuration file.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_state_save_layout(char* l_type);
+
+/*
+ * layouts_state_save - save the state of all the loaded layouts iterating
+ *        over each one of them and applying layouts_state_save_layout().
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_state_save(void);
+
+/*
+ * layouts_entity_get_kv_type - get the type of the value associated with a key
+ *        of an entity in a particular layout.
+ *
+ * The returned type is a member of the layouts_keydef_types_t enum :
+ * L_T_ERROR, L_T_STRING, L_T_LONG, L_T_UINT16, ...
+ *
+ * Return the requested type or SLURM_ERROR in case of failure
+ */
+int layouts_entity_get_kv_type(char* layout, char* entity,
+			       char* key);
+
+/*
+ * layouts_entity_get_kv_flags - get the keyspec flags associated with the
+ *        targeted key/value pair of an entity in a particular layout.
+ *
+ * Return the associated flags or SLURM_ERROR in case of failure
+ */
+int layouts_entity_get_kv_flags(char* layout, char* entity,
+				char* key);
+
+/*
+ * layouts_entity_push_kv - update the layout internal states to take into
+ *        account the current state of the targeted key/value pair.
+ *
+ * This ensures that the child and/or parents of the targeted entity in the
+ * targeted layout are synchronized with the current value associated with
+ * the key.
+ *
+ * Note: this call only makes sense when the targeted k/v is a k/v that helps
+ *       to dynamically compute its parents and/or children. It is a
+ *       no-op otherwise that just returns SLURM_SUCCESS.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_push_kv(char* layout, char* entity,
+			   char* key);
+
+/*
+ * layouts_entity_pull_kv - synchronize the targeted key/value pair based on
+ *        the states of their neighborhood in the targeted layout.
+ *
+ * This ensures that the K/V is up-to-date and correspond to the values that
+ *        its neighborhood in the layout think it should have.
+ *
+ * Note: this call only makes sense when the targeted k/v is a k/v that is
+ *       dynamically computed based on its parents and/or children. It is a
+ *       no-op otherwise that just returns SLURM_SUCCESS.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_pull_kv(char* layout, char* entity,
+			   char* key);
+
+/*
+ * layouts_entity_set_kv - update an entity with a new value for a particular
+ *        key in the targeted layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note : in case the key/value is already set for the entity, the content of
+ * the provided buffer will override the current content. In case the key/value
+ * already exists, it will be xfree and a new memory allocation will be
+ * performed and the content of the provided buffer dumped into it.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_set_kv(char* layout, char* entity,
+			  char* key, void* value,
+			  layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_set_kv_ref - replace an entity key value with a new memory
+ *        area for a particular key in the targeted layout
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note : in case the key/value is already set for the entity, the older value
+ * will be free and the provided buffer will be associated to the new value.
+ * Once done, the caller must not free the provided buffer has it will then
+ * be owned by the layout logic and will be free automatically when the layout
+ * framework will be unloaded or at a next call to that function.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_set_kv_ref(char* layout, char* entity,
+			      char* key, void* value,
+			      layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_setpush_kv - combination of layouts_entity_set_kv and
+ *        layouts_entity_push_kv to update an entity with a new value and force
+ *        the synchronization of its neighborhood in the layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note: see layouts_entity_push_kv.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_setpush_kv(char* layout, char* entity,
+			      char* key, void* value,
+			      layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_setpush_kv - combination of layouts_entity_set_kv_ref and
+ *        layouts_entity_push_kv to replace an entity key value with a new
+ *        memory area and force the synchronization of its neighborhood in
+ *        the layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note: see layouts_entity_push_kv.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_setpush_kv_ref(char* layout, char* entity,
+				  char* key, void* value,
+				  layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_get_kv - get the value associated with a key of an entity
+ *        in a particular layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note : the destination buffer will be filled with the content of the
+ * value associated with the requested key in the entity except for these
+ * types for which :
+ *   L_T_STRING  : value must be the address of the char* that will be
+ *                 xstrduped with the key value. The char* will have to be
+ *                 xfree() after that.
+ *   L_T_CUSTOM : value must be the address of the char* that will result
+ *                of the custom_dump function. The char* will have to be
+ *                xfree() after that.
+ *   L_T_ERROR : will return SLURM_ERROR in all cases.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_get_kv(char* layout, char* entity,
+			  char* key, void* value,
+			  layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_get_kv_ref - get a pointer to the value associated with a key
+ *        of an entity in a particular layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note : this call must be used with caution as the pointer could be free
+ * sooner or later by the underlying layout engine in reply to the execution
+ * of the layouts_entity_set_kv_ref().
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_get_kv_ref(char* layout, char* entity,
+			      char* key, void** pvalue,
+			      layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_pullget_kv - combination of layouts_entity_pull_kv and
+ *        layouts_entity_get_kv to retrieve the up-to-date value of a particular
+ *        entity key in the targeted layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note: see layouts_entity_pull_kv.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_pullget_kv(char* layout, char* entity,
+			      char* key, void* value,
+			      layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_pullget_kv - combination of layouts_entity_pull_kv_ref and
+ *        layouts_entity_get_kv to retrieve a reference to the up-to-date value
+ *        of a particular entity key in the targeted layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value.
+ *
+ * Note: see layouts_entity_pull_kv_ref.
+ *
+ * Return SLURM_SUCCES or SLURM_ERROR in case of failure
+ */
+int layouts_entity_pullget_kv_ref(char* layout, char* entity,
+				  char* key, void** value,
+				  layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_get_mkv - get the values associated with a set of keys of an
+ *        entity in a particular layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspec associated with the key. To skip
+ * that check the caller will have to pass a 0 value. This is mandatory for
+ * cases where the keyspecs of the requested keys do not share the same type.
+ *
+ * Note : the destination buffer will be sequentially filled with the content of
+ * the values associated with the requested keys in the entity.
+ * If the length of the buffer is too small, the remaining references will not
+ * be added and the counter of missed keys incremented as necessary.
+ * The first encountered error terminates the logic and the missing elements
+ * counter will reflect all the unprocessed elements including the faulty one.
+
+ * Special care must be taken for the following types of key :
+ *   L_T_STRING  : a char* will be added to the buffer. It will be xstrduped
+ *                 with the associated key value. The char* will have to be
+ *                 xfree() after that.
+ *   L_T_CUSTOM : a char* will be added to the buffer. It will be xstrduped
+ *                with the result of the custom_dump function. It will have to
+ *                be xfree() after that.
+ *   L_T_ERROR : will generate an error that will force the function to return
+ *               the count of missing elements (at least 1, depending on where
+ *               this type first appeared in the ordered list of keys to get.
+ *
+ * Note: keys correspond to a list of keys that can be represented as
+ * an hostlist expression (i.e. keys[1-10]).
+ *
+ * Return SLURM_SUCCES or the count of missed keys/references
+ */
+int layouts_entity_get_mkv(char* layout, char* entity,
+			   char* keys, void* value, size_t length,
+			   layouts_keydef_types_t key_type);
+
+/*
+ * layouts_entity_get_mkv_ref - get a set of pointers to the values associated
+ *        with a set of keys of an entity in a particular layout.
+ *
+ * The input key_type will force the call to check types consistency between
+ * the requester and the underlying keyspecs associated with the keys. To skip
+ * that check the caller will have to pass a 0 value. This is mandatory for cases
+ * where the keyspecs of the requested keys do not share the same type.
+ *
+ * The output buffer will be filled with the different references.
+ * If the length of the buffer is too small, the remaining references will not
+ * be added and the counter of missed keys incremented as necessary.
+ * The first encountered error terminates the logic and the missing elements
+ * counter will reflect all the unprocessed elements including the faulty one.
+ *
+ * Note: this call must be used with caution as the pointers could be free
+ * sooner or later by the underlying layout engine in reply to the execution
+ * of the layouts_entity_set_kv_ref().
+ *
+ * Note: keys correspond to a list of keys that can be represented as
+ * an hostlist expression (i.e. keys[1-10]).
+ *
+ * Return SLURM_SUCCES or the count of missed keys/references
+ */
+int layouts_entity_get_mkv_ref(char* layout, char* entity,
+			       char* keys, void* buffer, size_t length,
+			       layouts_keydef_types_t key_type);
 
 #endif /* end of include guard: __LAYOUTS_MGR_1NRINRSD__INC__ */
diff --git a/src/common/parse_config.c b/src/common/parse_config.c
index eec0cb1a4b23d9e84659789960b80cb30eff5e5f..5ca756d95fe59db0d30fb0e5a58a03948fac77c8 100644
--- a/src/common/parse_config.c
+++ b/src/common/parse_config.c
@@ -55,6 +55,7 @@
 #include "src/common/hostlist.h"
 #include "src/common/log.h"
 #include "src/common/macros.h"
+#include "src/common/pack.h"
 #include "src/common/parse_config.h"
 #include "src/common/parse_value.h"
 #include "src/common/read_config.h"
@@ -67,6 +68,7 @@
 
 strong_alias(s_p_hashtbl_create,	slurm_s_p_hashtbl_create);
 strong_alias(s_p_hashtbl_destroy,	slurm_s_p_hashtbl_destroy);
+strong_alias(s_p_parse_buffer,		slurm_s_p_parse_buffer);
 strong_alias(s_p_parse_file,		slurm_s_p_parse_file);
 strong_alias(s_p_parse_pair,		slurm_s_p_parse_pair);
 strong_alias(s_p_parse_line,		slurm_s_p_parse_line);
@@ -75,6 +77,9 @@ strong_alias(s_p_get_string,		slurm_s_p_get_string);
 strong_alias(s_p_get_long,		slurm_s_p_get_long);
 strong_alias(s_p_get_uint16,		slurm_s_p_get_uint16);
 strong_alias(s_p_get_uint32,		slurm_s_p_get_uint32);
+strong_alias(s_p_get_float,		slurm_s_p_get_float);
+strong_alias(s_p_get_double,		slurm_s_p_get_double);
+strong_alias(s_p_get_long_double,	slurm_s_p_get_long_double);
 strong_alias(s_p_get_pointer,		slurm_s_p_get_pointer);
 strong_alias(s_p_get_array,		slurm_s_p_get_array);
 strong_alias(s_p_get_boolean,		slurm_s_p_get_boolean);
@@ -88,8 +93,8 @@ strong_alias(transfer_s_p_options,	slurm_transfer_s_p_options);
 static regex_t keyvalue_re;
 static char *keyvalue_pattern =
 	"^[[:space:]]*"
-	"([[:alnum:]]+)" /* key */
-	"[[:space:]]*=[[:space:]]*"
+	"([[:alnum:]_.]+)" /* key */
+	"[[:space:]]*([-*+/]?)=[[:space:]]*"
 	"((\"([^\"]*)\")|([^[:space:]]+))" /* value: quoted with whitespace,
 					    * or unquoted and no whitespace */
 	"([[:space:]]|$)";
@@ -98,6 +103,7 @@ static bool keyvalue_initialized = false;
 struct s_p_values {
 	char *key;
 	int type;
+	slurm_parser_operator_t operator;
 	int data_count;
 	void *data;
 	int (*handler)(void **data, slurm_parser_enum_t type,
@@ -172,6 +178,7 @@ s_p_hashtbl_t *s_p_hashtbl_create(const s_p_options_t options[])
 	for (op = options; op->key != NULL; op++) {
 		value = xmalloc(sizeof(s_p_values_t));
 		value->key = xstrdup(op->key);
+		value->operator = S_P_OPERATOR_SET;
 		value->type = op->type;
 		value->data_count = 0;
 		value->data = NULL;
@@ -240,6 +247,7 @@ static void _conf_file_values_free(s_p_values_t *p)
 			for (i = 0; i < p->data_count; ++i) {
 				s_p_hashtbl_destroy(v->values[i]);
 			}
+			xfree(v->values);
 			xfree(p->data);
 			break;
 		default:
@@ -292,14 +300,17 @@ static void _keyvalue_regex_init(void)
  * Return 0 when a key-value pair is found, and -1 otherwise.
  */
 static int _keyvalue_regex(const char *line,
-			   char **key, char **value, char **remaining)
+			   char **key, char **value, char **remaining,
+			   slurm_parser_operator_t *operator)
 {
 	size_t nmatch = 8;
 	regmatch_t pmatch[8];
+	char op;
 
 	*key = NULL;
 	*value = NULL;
 	*remaining = (char *)line;
+	*operator = S_P_OPERATOR_SET;
 	memset(pmatch, 0, sizeof(regmatch_t)*nmatch);
 
 	if (regexec(&keyvalue_re, line, nmatch, pmatch, 0)
@@ -309,18 +320,30 @@ static int _keyvalue_regex(const char *line,
 
 	*key = (char *)(xstrndup(line + pmatch[1].rm_so,
 				 pmatch[1].rm_eo - pmatch[1].rm_so));
-
-	if (pmatch[4].rm_so != -1) {
-		*value = (char *)(xstrndup(line + pmatch[4].rm_so,
-					   pmatch[4].rm_eo - pmatch[4].rm_so));
-	} else if (pmatch[5].rm_so != -1) {
+	if (pmatch[2].rm_so != -1 &&
+	    (pmatch[2].rm_so != pmatch[2].rm_eo)) {
+		op = *(line + pmatch[2].rm_so);
+		if (op == '+') {
+			*operator = S_P_OPERATOR_ADD;
+		} else if (op == '-') {
+			*operator = S_P_OPERATOR_SUB;
+		} else if (op == '*') {
+			*operator = S_P_OPERATOR_MUL;
+		} else if (op == '/') {
+			*operator = S_P_OPERATOR_DIV;
+		}
+	}
+	if (pmatch[5].rm_so != -1) {
 		*value = (char *)(xstrndup(line + pmatch[5].rm_so,
 					   pmatch[5].rm_eo - pmatch[5].rm_so));
+	} else if (pmatch[6].rm_so != -1) {
+		*value = (char *)(xstrndup(line + pmatch[6].rm_so,
+					   pmatch[6].rm_eo - pmatch[6].rm_so));
 	} else {
 		*value = xstrdup("");
 	}
 
-	*remaining = (char *)(line + pmatch[2].rm_eo);
+	*remaining = (char *)(line + pmatch[3].rm_eo);
 
 	return 0;
 }
@@ -488,16 +511,16 @@ s_p_hashtbl_t* _hashtbl_copy_keys(const s_p_hashtbl_t* from_hashtbl,
 	int len, i;
 
 	xassert(from_hashtbl);
-	xassert(to_hashtbl);
 
 	len = CONF_HASH_LEN * sizeof(s_p_values_t *);
 	to_hashtbl = (s_p_hashtbl_t *)xmalloc(len);
 
 	for (i = 0; i < CONF_HASH_LEN; ++i) {
-		for (val_ptr = from_hashtbl[i]; val_ptr; val_ptr =
-			     val_ptr->next) {
+		for (val_ptr = from_hashtbl[i]; val_ptr;
+		     val_ptr = val_ptr->next) {
 			val_copy = xmalloc(sizeof(s_p_values_t));
 			val_copy->key = xstrdup(val_ptr->key);
+			val_copy->operator = val_ptr->operator;
 			val_copy->type = val_ptr->type;
 			val_copy->handler = val_ptr->handler;
 			val_copy->destroy = val_ptr->destroy;
@@ -584,6 +607,29 @@ static void* _handle_boolean(const char* key, const char* value)
 	return data;
 }
 
+static void* _handle_float(const char* key, const char* value)
+{
+	float* data = (float*)xmalloc(sizeof(float));
+	if (s_p_handle_float(data, key, value) == SLURM_ERROR)
+		return NULL;
+	return data;
+}
+
+static void* _handle_double(const char* key, const char* value)
+{
+	double* data = (double*)xmalloc(sizeof(double));
+	if (s_p_handle_double(data, key, value) == SLURM_ERROR)
+		return NULL;
+	return data;
+}
+
+static void* _handle_ldouble(const char* key, const char* value)
+{
+	long double* data = (long double*)xmalloc(sizeof(long double));
+	if (s_p_handle_long_double(data, key, value) == SLURM_ERROR)
+		return NULL;
+	return data;
+}
 
 static int _handle_pointer(s_p_values_t *v, const char *value,
 			   const char *line, char **leftover)
@@ -679,6 +725,18 @@ static int _handle_expline_cmp_uint32(const void* v1, const void* v2)
 {
 	return *((uint32_t*)v1) != *((uint32_t*)v2);
 }
+static int _handle_expline_cmp_float(const void* v1, const void* v2)
+{
+	return *((float*)v1) != *((float*)v2);
+}
+static int _handle_expline_cmp_double(const void* v1, const void* v2)
+{
+	return *((double*)v1) != *((double*)v2);
+}
+static int _handle_expline_cmp_ldouble(const void* v1, const void* v2)
+{
+	return *((long double*)v1) != *((long double*)v2);
+}
 
 /* ac = array case
  * the master key type is not string. Iterate over the tables looking
@@ -752,6 +810,21 @@ static void _handle_expline_merge(_expline_values_t* v_data,
 				   _handle_expline_cmp_uint32, &v_data->values,
 				   tables_count);
 		break;
+	case S_P_FLOAT:
+		_handle_expline_ac(current_tbl, master_key, matchp->data,
+				   _handle_expline_cmp_float, &v_data->values,
+				   tables_count);
+		break;
+	case S_P_DOUBLE:
+		_handle_expline_ac(current_tbl, master_key, matchp->data,
+				   _handle_expline_cmp_double, &v_data->values,
+				   tables_count);
+		break;
+	case S_P_LONG_DOUBLE:
+		_handle_expline_ac(current_tbl, master_key, matchp->data,
+				   _handle_expline_cmp_ldouble, &v_data->values,
+				   tables_count);
+		break;
 	}
 }
 
@@ -841,7 +914,15 @@ static void _handle_keyvalue_match(s_p_values_t *v,
 	case S_P_EXPLINE:
 		_handle_expline(v, value, line, leftover);
 		break;
-
+	case S_P_FLOAT:
+		_handle_common(v, value, line, leftover, _handle_float);
+		break;
+	case S_P_DOUBLE:
+		_handle_common(v, value, line, leftover, _handle_double);
+		break;
+	case S_P_LONG_DOUBLE:
+		_handle_common(v, value, line, leftover, _handle_ldouble);
+		break;
 	}
 }
 
@@ -876,11 +957,13 @@ int s_p_parse_line(s_p_hashtbl_t *hashtbl, const char *line, char **leftover)
 	char *ptr = (char *)line;
 	s_p_values_t *p;
 	char *new_leftover;
+	slurm_parser_operator_t op;
 
 	_keyvalue_regex_init();
 
-	while (_keyvalue_regex(ptr, &key, &value, &new_leftover) == 0) {
+	while (_keyvalue_regex(ptr, &key, &value, &new_leftover, &op) == 0) {
 		if ((p = _conf_hashtbl_lookup(hashtbl, key))) {
+			p->operator = op;
 			_handle_keyvalue_match(p, value,
 					       new_leftover, &new_leftover);
 			*leftover = ptr = new_leftover;
@@ -907,11 +990,13 @@ static int _parse_next_key(s_p_hashtbl_t *hashtbl,
 	char *key, *value;
 	s_p_values_t *p;
 	char *new_leftover;
+	slurm_parser_operator_t op;
 
 	_keyvalue_regex_init();
 
-	if (_keyvalue_regex(line, &key, &value, &new_leftover) == 0) {
+	if (_keyvalue_regex(line, &key, &value, &new_leftover, &op) == 0) {
 		if ((p = _conf_hashtbl_lookup(hashtbl, key))) {
+			p->operator = op;
 			_handle_keyvalue_match(p, value,
 					       new_leftover, &new_leftover);
 			*leftover = new_leftover;
@@ -1176,6 +1261,59 @@ int s_p_parse_file(s_p_hashtbl_t *hashtbl, uint32_t *hash_val, char *filename,
 	return rc;
 }
 
+int s_p_parse_buffer(s_p_hashtbl_t *hashtbl, uint32_t *hash_val,
+		     Buf buffer, bool ignore_new)
+{
+	char *leftover = NULL;
+	int rc = SLURM_SUCCESS;
+	int line_number;
+	uint32_t utmp32;
+	char *tmp_str = NULL;
+
+	if (!buffer) {
+		error("s_p_parse_buffer: No buffer given.");
+		return SLURM_ERROR;
+	}
+
+	line_number = 0;
+	_keyvalue_regex_init();
+	while (remaining_buf(buffer) > 0) {
+		safe_unpackstr_xmalloc(&tmp_str, &utmp32, buffer);
+		if (tmp_str != NULL) {
+			line_number++;
+			if (*tmp_str == '\0') {
+				xfree(tmp_str);
+				continue;
+			}
+			_parse_next_key(hashtbl, tmp_str, &leftover, ignore_new);
+			/* Make sure that after parsing only whitespace
+			   is left over */
+			if (!_line_is_space(leftover)) {
+				char *ptr = xstrdup(leftover);
+				_strip_cr_nl(ptr);
+				if (ignore_new) {
+					debug("s_p_parse_buffer : error in line"
+					      " %d: \"%s\"", line_number, ptr);
+				} else {
+					error("s_p_parse_buffer : error in line"
+					      " %d: \"%s\"", line_number, ptr);
+					rc = SLURM_ERROR;
+				}
+				xfree(ptr);
+			}
+			xfree(tmp_str);
+			if (rc == SLURM_SUCCESS)
+				continue;
+		}
+	unpack_error:
+		debug3("s_p_parse_buffer: ending after line %u",
+		       line_number);
+		break;
+	}
+
+	return rc;
+}
+
 /*
  * s_p_hashtbl_merge
  *
@@ -1288,6 +1426,11 @@ void s_p_hashtbl_merge_keys(s_p_hashtbl_t *to_hashtbl,
 					s_p_hashtbl_merge_keys(
 							t_expline->template,
 							f_expline->template);
+					/* Keys merged, free container memory */
+					s_p_hashtbl_destroy(f_expline->template);
+					s_p_hashtbl_destroy(f_expline->index);
+					//FIXME: Destroy "values" ?
+					xfree(f_expline);
 				}
 				pp = &p->next;
 				p = p->next;
@@ -1368,6 +1511,7 @@ static s_p_hashtbl_t* _parse_expline_adapt_table(const s_p_hashtbl_t* hashtbl)
 		for (val_ptr = hashtbl[i]; val_ptr; val_ptr = val_ptr->next) {
 			val_copy = xmalloc(sizeof(s_p_values_t));
 			val_copy->key = xstrdup(val_ptr->key);
+			val_copy->operator = val_ptr->operator;
 			if (val_ptr->type == S_P_PLAIN_STRING) {
 				val_copy->type = S_P_STRING;
 			} else {
@@ -1467,17 +1611,26 @@ static int _parse_expline_doexpand(s_p_hashtbl_t** tables,
 	for (i = 0; i < tables_count; ++i) {
 		if (item_count > 0) {
 			--item_count;
-			free(item_str);
+			if (item_str)
+				free(item_str);
 			item_str = hostlist_shift(item_hl);
 		}
-		if (!s_p_parse_pair(tables[i], item->key, item_str)) {
+		/*
+		 * The destination tables are created without any info on the
+		 * operator associated with the key in s_p_parse_line_expanded.
+		 * So, parse the targeted pair injecting that information to
+		 * push it into the destination table.
+		 */
+		if (!s_p_parse_pair_with_op(tables[i], item->key, item_str,
+					    item->operator)) {
 			error("Error parsing %s = %s.", item->key, item_str);
 			free(item_str);
 			return 0;
 		}
 	}
 
-	free(item_str);
+	if (item_str)
+		free(item_str);
 	return 1;
 }
 
@@ -1526,7 +1679,7 @@ int s_p_parse_line_expanded(const s_p_hashtbl_t *hashtbl,
 	 */
 	tables = (s_p_hashtbl_t**)xmalloc(tables_count *
 					  sizeof(s_p_hashtbl_t*));
-	for (i = 0; i < tables_count; ++i) {
+	for (i = 0; i < tables_count; i++) {
 		free(value_str);
 		value_str = hostlist_shift(value_hl);
 		tables[i] = _hashtbl_copy_keys(hashtbl,
@@ -1564,9 +1717,10 @@ cleanup:
 	if (strhashtbl)
 		s_p_hashtbl_destroy(strhashtbl);
 
-	if (status == SLURM_ERROR) {
-		for (i = 0; i < tables_count; ++i)
-			s_p_hashtbl_destroy(tables[i]);
+	if (status == SLURM_ERROR && tables) {
+		for (i = 0; i < tables_count; i++)
+			if (tables[i])
+				s_p_hashtbl_destroy(tables[i]);
 		xfree(tables);
 	}
 	else {
@@ -1578,16 +1732,24 @@ cleanup:
 
 /*
  * Returns 1 if the line is parsed cleanly, and 0 otherwise.
+ * Set the operator of the targeted s_p_values_t to the provided value.
  */
-int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value)
+int s_p_parse_pair_with_op(s_p_hashtbl_t *hashtbl, const char *key,
+			   const char *value, slurm_parser_operator_t operator)
 {
 	s_p_values_t *p;
 	char *leftover, *v;
 
 	if ((p = _conf_hashtbl_lookup(hashtbl, key)) == NULL) {
-		error("Parsing error at unrecognized key: %s", key);
+		error("%s: Parsing error at unrecognized key: %s",
+		      __func__, key);
+		return 0;
+	}
+	if (!value) {
+		error("%s: Value pointer is NULL for key %s", __func__, key);
 		return 0;
 	}
+	p-> operator = operator;
 	/* we have value separated from key here so parse it different way */
 	while (*value != '\0' && isspace(*value))
 		value++; /* skip spaces at start if any */
@@ -1614,6 +1776,14 @@ int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value)
 	return 1;
 }
 
+/*
+ * Returns 1 if the line is parsed cleanly, and 0 otherwise.
+ */
+int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value)
+{
+	return s_p_parse_pair_with_op(hashtbl, key, value, S_P_OPERATOR_SET);
+}
+
 /* common checks for s_p_get_* returns NULL if invalid.
  *
  * Information concerning theses function can be found in the header file.
@@ -1689,6 +1859,21 @@ int s_p_get_uint32(uint32_t *num, const char *key,
 	return 0;
 }
 
+int s_p_get_operator(slurm_parser_operator_t *operator, const char *key,
+		     const s_p_hashtbl_t *hashtbl)
+{
+	s_p_values_t *p;
+	if (!hashtbl)
+		return 0;
+	p = _conf_hashtbl_lookup(hashtbl, key);
+	if (p) {
+		*operator = p->operator;
+		return 1;
+	}
+	error("Invalid key \"%s\"", key);
+	return 0;
+}
+
 int s_p_get_pointer(void **ptr, const char *key, const s_p_hashtbl_t *hashtbl)
 {
 	s_p_values_t *p = _get_check(S_P_POINTER, key, hashtbl);
@@ -1756,6 +1941,44 @@ int s_p_get_boolean(bool *flag, const char *key, const s_p_hashtbl_t *hashtbl)
 	return 0;
 }
 
+int s_p_get_float(float *num, const char *key,
+		  const s_p_hashtbl_t *hashtbl)
+{
+	s_p_values_t *p = _get_check(S_P_FLOAT, key, hashtbl);
+
+	if (p) {
+		*num = *(float *)p->data;
+		return 1;
+	}
+
+	return 0;
+}
+
+int s_p_get_double(double *num, const char *key,
+		  const s_p_hashtbl_t *hashtbl)
+{
+	s_p_values_t *p = _get_check(S_P_DOUBLE, key, hashtbl);
+
+	if (p) {
+		*num = *(double *)p->data;
+		return 1;
+	}
+
+	return 0;
+}
+
+int s_p_get_long_double(long double *num, const char *key,
+			const s_p_hashtbl_t *hashtbl)
+{
+	s_p_values_t *p = _get_check(S_P_LONG_DOUBLE, key, hashtbl);
+
+	if (p) {
+		*num = *(long double *)p->data;
+		return 1;
+	}
+
+	return 0;
+}
 
 /*
  * Given an "options" array, print the current values of all
@@ -1770,6 +1993,9 @@ void s_p_dump_values(const s_p_hashtbl_t *hashtbl,
 	long num;
 	uint16_t num16;
 	uint32_t num32;
+	float numf;
+	double numd;
+	long double numld;
 	char *str;
 	void *ptr;
 	void **ptr_array;
@@ -1843,6 +2069,24 @@ void s_p_dump_values(const s_p_hashtbl_t *hashtbl,
 				verbose("%s", op->key);
 			}
 			break;
+		case S_P_FLOAT:
+			if (s_p_get_float(&numf, op->key, hashtbl))
+				verbose("%s = %f", op->key, numf);
+			else
+				verbose("%s", op->key);
+			break;
+		case S_P_DOUBLE:
+			if (s_p_get_double(&numd, op->key, hashtbl))
+				verbose("%s = %f", op->key, numd);
+			else
+				verbose("%s", op->key);
+			break;
+		case S_P_LONG_DOUBLE:
+			if (s_p_get_long_double(&numld, op->key, hashtbl))
+				verbose("%s = %Lf", op->key, numld);
+			else
+				verbose("%s", op->key);
+			break;
 		case S_P_IGNORE:
 			break;
 		}
diff --git a/src/common/parse_config.h b/src/common/parse_config.h
index 39e9888164be4885b331774f867469fcc1bed32b..b0900c53d80e58e60bc953b0f4bb4cee75e029c7 100644
--- a/src/common/parse_config.h
+++ b/src/common/parse_config.h
@@ -45,6 +45,7 @@
 
 #include <stdint.h>
 #include "slurm/slurm.h"
+#include "src/common/pack.h"
 
 /*
  * This slurm file parser provides a method for parsing a file
@@ -253,9 +254,38 @@ typedef enum slurm_parser_enum {
 	S_P_BOOLEAN,
 	S_P_LINE,
 	S_P_EXPLINE,
-	S_P_PLAIN_STRING /* useful only within S_P_EXPLINE */
+	S_P_PLAIN_STRING /* useful only within S_P_EXPLINE */,
+	S_P_FLOAT,
+	S_P_DOUBLE,
+	S_P_LONG_DOUBLE
+
 } slurm_parser_enum_t;
 
+/*
+ * Standard Slurm conf files use key=value elements.
+ * slurm_parser_operator_t extends that concept to cover additionnal
+ * use cases like :
+ *        key+=value
+ *        key-=value
+ *        key*=value
+ *        key/=value
+ *
+ * this feature is for now dedicated to the layouts framework. It enables
+ * to have advanced modifications of entities reusing the traditional
+ * Slurm parser with the new operator information to manage updates.
+ *
+ */
+typedef enum slurm_parser_operator {
+	S_P_OPERATOR_SET = 0,
+	S_P_OPERATOR_ADD,
+	S_P_OPERATOR_SUB,
+	S_P_OPERATOR_MUL,
+	S_P_OPERATOR_DIV,
+	S_P_OPERATOR_SET_IF_MIN,
+	S_P_OPERATOR_SET_IF_MAX,
+	S_P_OPERATOR_AVG
+} slurm_parser_operator_t;
+
 typedef struct conf_file_options {
 	char *key;
 	slurm_parser_enum_t type;
@@ -279,11 +309,29 @@ void s_p_hashtbl_destroy(s_p_hashtbl_t *hashtbl);
 int s_p_parse_file(s_p_hashtbl_t *hashtbl, uint32_t *hash_val, char *filename,
 		   bool ignore_new);
 
+/* Returns SLURM_SUCCESS if buffer was opened and parse correctly.
+ * buffer must be a valid Buf bufferonly containing strings.The parsing
+ * stops at the first non string content extracted.
+ * OUT hash_val - cyclic redundancy check (CRC) character-wise value
+ *                of file.
+ * IN ignore_new - do not treat unrecognized keywords as a fatal error,
+ *                 print debug() message and continue
+ */
+int s_p_parse_buffer(s_p_hashtbl_t *hashtbl, uint32_t *hash_val,
+		     Buf buffer, bool ignore_new);
+
 /*
  * Returns 1 if the line is parsed cleanly, and 0 otherwise.
  */
 int s_p_parse_pair(s_p_hashtbl_t *hashtbl, const char *key, const char *value);
 
+/*
+ * Returns 1 if the line is parsed cleanly, and 0 otherwise.
+ * Set the operator of the updated s_p_values_t to the provided one.
+ */
+int s_p_parse_pair_with_op(s_p_hashtbl_t *hashtbl, const char *key,
+			   const char *value, slurm_parser_operator_t operator);
+
 /*
  * Returns 1 if the line is parsed cleanly, and 0 otherwise.
  */
@@ -416,6 +464,75 @@ int s_p_get_uint16(uint16_t *num, const char *key,
 int s_p_get_uint32(uint32_t *num, const char *key,
 		   const s_p_hashtbl_t *hashtbl);
 
+/*
+ * s_p_get_float
+ *
+ * Search for a key in a s_p_hashtbl_t with value of type
+ * float.  If the key is found and has a set value, the
+ * value is retuned in "num".
+ *
+ * OUT num - pointer to a float where the value is returned
+ * IN key - hash table key
+ * IN hashtbl - hash table created by s_p_hashtbl_create()
+ *
+ * Returns 1 when a value was set for "key" during parsing and "num"
+ *   was successfully set, otherwise returns 0;
+ */
+int s_p_get_float(float *num, const char *key,
+		  const s_p_hashtbl_t *hashtbl);
+
+/*
+ * s_p_get_double
+ *
+ * Search for a key in a s_p_hashtbl_t with value of type
+ * double.  If the key is found and has a set value, the
+ * value is retuned in "num".
+ *
+ * OUT num - pointer to a double where the value is returned
+ * IN key - hash table key
+ * IN hashtbl - hash table created by s_p_hashtbl_create()
+ *
+ * Returns 1 when a value was set for "key" during parsing and "num"
+ *   was successfully set, otherwise returns 0;
+ */
+int s_p_get_double(double *num, const char *key,
+		   const s_p_hashtbl_t *hashtbl);
+
+/*
+ * s_p_get_long_double
+ *
+ * Search for a key in a s_p_hashtbl_t with value of type
+ * long double.  If the key is found and has a set value, the
+ * value is retuned in "num".
+ *
+ * OUT num - pointer to a long double where the value is returned
+ * IN key - hash table key
+ * IN hashtbl - hash table created by s_p_hashtbl_create()
+ *
+ * Returns 1 when a value was set for "key" during parsing and "num"
+ *   was successfully set, otherwise returns 0;
+ */
+int s_p_get_long_double(long double *num, const char *key,
+			const s_p_hashtbl_t *hashtbl);
+
+/*
+ * s_p_get_operator
+ *
+ * Search for a key in a s_p_hashtbl_t and return the operator
+ * associated with that key in the configuration file. The operator
+ * is one of the slurm_parser_operator_t enum possible values.
+ *
+ * OUT operator - pointer to a slurm_parser_operator_t where the
+ *     operator is returned
+ * IN key - hash table key
+ * IN hashtbl - hash table created by s_p_hashtbl_create()
+ *
+ * Returns 1 when a operator was set for "key" during parsing and
+ *     "operator" was successfully set, otherwise returns 0;
+ */
+int s_p_get_operator(slurm_parser_operator_t *operator, const char *key,
+		     const s_p_hashtbl_t *hashtbl);
+
 /*
  * s_p_get_pointer
  *
diff --git a/src/common/parse_value.c b/src/common/parse_value.c
index 4243af2b324037156bd7bbd3e94902cef9c41f4c..5e1e1ed4eedb2e1c691e4c7892f5d5f06bc4ded7 100644
--- a/src/common/parse_value.c
+++ b/src/common/parse_value.c
@@ -157,11 +157,13 @@ int s_p_handle_boolean(bool* data, const char* key, const char* value)
 
 	if (!strcasecmp(value, "yes")
 		|| !strcasecmp(value, "up")
+		|| !strcasecmp(value, "true")
 		|| !strcasecmp(value, "1")) {
 		flag = true;
 	} else if (!strcasecmp(value, "no")
-			|| !strcasecmp(value, "down")
-			|| !strcasecmp(value, "0")) {
+		   || !strcasecmp(value, "down")
+		   || !strcasecmp(value, "false")
+		   || !strcasecmp(value, "0")) {
 		flag = false;
 	} else {
 		error("\"%s\" is not a valid option for \"%s\"",
@@ -223,7 +225,8 @@ int s_p_handle_double(double* data, const char* key, const char* value)
 	return SLURM_SUCCESS;
 }
 
-int s_p_handle_ldouble(long double* data, const char* key, const char* value)
+int s_p_handle_long_double(long double* data, const char* key,
+			   const char* value)
 {
 	char *endptr;
 	long double num;
diff --git a/src/common/parse_value.h b/src/common/parse_value.h
index b7dc223e02f7d297fa82ed16a8b250edae1c7f75..5326a9c2400a940f9e6cf1f17c5106215d706bca 100644
--- a/src/common/parse_value.h
+++ b/src/common/parse_value.h
@@ -49,6 +49,7 @@ int s_p_handle_uint32(uint32_t* data, const char* key, const char* value);
 int s_p_handle_boolean(bool* data, const char* key, const char* value);
 int s_p_handle_float(float* data, const char* key, const char* value);
 int s_p_handle_double(double* data, const char* key, const char* value);
-int s_p_handle_ldouble(long double* data, const char* key, const char* value);
+int s_p_handle_long_double(long double* data, const char* key,
+			   const char* value);
 
 #endif /* !_PARSE_VALUE_H */
diff --git a/src/layouts/Makefile.am b/src/layouts/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..54f8ba015f63a6bef632339d13bce850f687ee65
--- /dev/null
+++ b/src/layouts/Makefile.am
@@ -0,0 +1,4 @@
+# Makefile for layouts plugins
+
+SUBDIRS = unit
+#basic racking energy power topology
diff --git a/src/layouts/Makefile.in b/src/layouts/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..2aa360e1231cbcebabf72b2b2a6f926da58b5694
--- /dev/null
+++ b/src/layouts/Makefile.in
@@ -0,0 +1,771 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for layouts plugins
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/layouts
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/auxdir/ax_lib_hdf5.m4 \
+	$(top_srcdir)/auxdir/ax_pthread.m4 \
+	$(top_srcdir)/auxdir/libtool.m4 \
+	$(top_srcdir)/auxdir/ltoptions.m4 \
+	$(top_srcdir)/auxdir/ltsugar.m4 \
+	$(top_srcdir)/auxdir/ltversion.m4 \
+	$(top_srcdir)/auxdir/lt~obsolete.m4 \
+	$(top_srcdir)/auxdir/slurm.m4 \
+	$(top_srcdir)/auxdir/x_ac__system_configuration.m4 \
+	$(top_srcdir)/auxdir/x_ac_affinity.m4 \
+	$(top_srcdir)/auxdir/x_ac_aix.m4 \
+	$(top_srcdir)/auxdir/x_ac_blcr.m4 \
+	$(top_srcdir)/auxdir/x_ac_bluegene.m4 \
+	$(top_srcdir)/auxdir/x_ac_cflags.m4 \
+	$(top_srcdir)/auxdir/x_ac_cray.m4 \
+	$(top_srcdir)/auxdir/x_ac_databases.m4 \
+	$(top_srcdir)/auxdir/x_ac_debug.m4 \
+	$(top_srcdir)/auxdir/x_ac_dlfcn.m4 \
+	$(top_srcdir)/auxdir/x_ac_env.m4 \
+	$(top_srcdir)/auxdir/x_ac_freeipmi.m4 \
+	$(top_srcdir)/auxdir/x_ac_gpl_licensed.m4 \
+	$(top_srcdir)/auxdir/x_ac_hwloc.m4 \
+	$(top_srcdir)/auxdir/x_ac_iso.m4 \
+	$(top_srcdir)/auxdir/x_ac_json.m4 \
+	$(top_srcdir)/auxdir/x_ac_lua.m4 \
+	$(top_srcdir)/auxdir/x_ac_man2html.m4 \
+	$(top_srcdir)/auxdir/x_ac_munge.m4 \
+	$(top_srcdir)/auxdir/x_ac_ncurses.m4 \
+	$(top_srcdir)/auxdir/x_ac_netloc.m4 \
+	$(top_srcdir)/auxdir/x_ac_nrt.m4 \
+	$(top_srcdir)/auxdir/x_ac_ofed.m4 \
+	$(top_srcdir)/auxdir/x_ac_pam.m4 \
+	$(top_srcdir)/auxdir/x_ac_printf_null.m4 \
+	$(top_srcdir)/auxdir/x_ac_ptrace.m4 \
+	$(top_srcdir)/auxdir/x_ac_readline.m4 \
+	$(top_srcdir)/auxdir/x_ac_rrdtool.m4 \
+	$(top_srcdir)/auxdir/x_ac_setpgrp.m4 \
+	$(top_srcdir)/auxdir/x_ac_setproctitle.m4 \
+	$(top_srcdir)/auxdir/x_ac_sgi_job.m4 \
+	$(top_srcdir)/auxdir/x_ac_slurm_ssl.m4 \
+	$(top_srcdir)/auxdir/x_ac_sun_const.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/slurm/slurm.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTHD_CFLAGS = @AUTHD_CFLAGS@
+AUTHD_LIBS = @AUTHD_LIBS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BGL_LOADED = @BGL_LOADED@
+BGQ_LOADED = @BGQ_LOADED@
+BG_INCLUDES = @BG_INCLUDES@
+BG_LDFLAGS = @BG_LDFLAGS@
+BG_L_P_LOADED = @BG_L_P_LOADED@
+BLCR_CPPFLAGS = @BLCR_CPPFLAGS@
+BLCR_HOME = @BLCR_HOME@
+BLCR_LDFLAGS = @BLCR_LDFLAGS@
+BLCR_LIBS = @BLCR_LIBS@
+BLUEGENE_LOADED = @BLUEGENE_LOADED@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CMD_LDFLAGS = @CMD_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRAY_JOB_CPPFLAGS = @CRAY_JOB_CPPFLAGS@
+CRAY_JOB_LDFLAGS = @CRAY_JOB_LDFLAGS@
+CRAY_SELECT_CPPFLAGS = @CRAY_SELECT_CPPFLAGS@
+CRAY_SELECT_LDFLAGS = @CRAY_SELECT_LDFLAGS@
+CRAY_SWITCH_CPPFLAGS = @CRAY_SWITCH_CPPFLAGS@
+CRAY_SWITCH_LDFLAGS = @CRAY_SWITCH_LDFLAGS@
+CRAY_TASK_CPPFLAGS = @CRAY_TASK_CPPFLAGS@
+CRAY_TASK_LDFLAGS = @CRAY_TASK_LDFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FREEIPMI_CPPFLAGS = @FREEIPMI_CPPFLAGS@
+FREEIPMI_LDFLAGS = @FREEIPMI_LDFLAGS@
+FREEIPMI_LIBS = @FREEIPMI_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+H5CC = @H5CC@
+H5FC = @H5FC@
+HAVEMYSQLCONFIG = @HAVEMYSQLCONFIG@
+HAVE_AIX = @HAVE_AIX@
+HAVE_MAN2HTML = @HAVE_MAN2HTML@
+HAVE_NRT = @HAVE_NRT@
+HAVE_OPENSSL = @HAVE_OPENSSL@
+HAVE_SOME_CURSES = @HAVE_SOME_CURSES@
+HDF5_CC = @HDF5_CC@
+HDF5_CFLAGS = @HDF5_CFLAGS@
+HDF5_CPPFLAGS = @HDF5_CPPFLAGS@
+HDF5_FC = @HDF5_FC@
+HDF5_FFLAGS = @HDF5_FFLAGS@
+HDF5_FLIBS = @HDF5_FLIBS@
+HDF5_LDFLAGS = @HDF5_LDFLAGS@
+HDF5_LIBS = @HDF5_LIBS@
+HDF5_VERSION = @HDF5_VERSION@
+HWLOC_CPPFLAGS = @HWLOC_CPPFLAGS@
+HWLOC_LDFLAGS = @HWLOC_LDFLAGS@
+HWLOC_LIBS = @HWLOC_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JSON_CPPFLAGS = @JSON_CPPFLAGS@
+JSON_LDFLAGS = @JSON_LDFLAGS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_LDFLAGS = @LIB_LDFLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MUNGE_CPPFLAGS = @MUNGE_CPPFLAGS@
+MUNGE_DIR = @MUNGE_DIR@
+MUNGE_LDFLAGS = @MUNGE_LDFLAGS@
+MUNGE_LIBS = @MUNGE_LIBS@
+MYSQL_CFLAGS = @MYSQL_CFLAGS@
+MYSQL_LIBS = @MYSQL_LIBS@
+NCURSES = @NCURSES@
+NETLOC_CPPFLAGS = @NETLOC_CPPFLAGS@
+NETLOC_LDFLAGS = @NETLOC_LDFLAGS@
+NETLOC_LIBS = @NETLOC_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NRT_CPPFLAGS = @NRT_CPPFLAGS@
+NUMA_LIBS = @NUMA_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OFED_CPPFLAGS = @OFED_CPPFLAGS@
+OFED_LDFLAGS = @OFED_LDFLAGS@
+OFED_LIBS = @OFED_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_DIR = @PAM_DIR@
+PAM_LIBS = @PAM_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROCTRACKDIR = @PROCTRACKDIR@
+PROJECT = @PROJECT@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+REAL_BGQ_LOADED = @REAL_BGQ_LOADED@
+REAL_BG_L_P_LOADED = @REAL_BG_L_P_LOADED@
+RELEASE = @RELEASE@
+RRDTOOL_CPPFLAGS = @RRDTOOL_CPPFLAGS@
+RRDTOOL_LDFLAGS = @RRDTOOL_LDFLAGS@
+RRDTOOL_LIBS = @RRDTOOL_LIBS@
+RUNJOB_LDFLAGS = @RUNJOB_LDFLAGS@
+SED = @SED@
+SEMAPHORE_LIBS = @SEMAPHORE_LIBS@
+SEMAPHORE_SOURCES = @SEMAPHORE_SOURCES@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SLURMCTLD_PORT = @SLURMCTLD_PORT@
+SLURMCTLD_PORT_COUNT = @SLURMCTLD_PORT_COUNT@
+SLURMDBD_PORT = @SLURMDBD_PORT@
+SLURMD_PORT = @SLURMD_PORT@
+SLURM_API_AGE = @SLURM_API_AGE@
+SLURM_API_CURRENT = @SLURM_API_CURRENT@
+SLURM_API_MAJOR = @SLURM_API_MAJOR@
+SLURM_API_REVISION = @SLURM_API_REVISION@
+SLURM_API_VERSION = @SLURM_API_VERSION@
+SLURM_MAJOR = @SLURM_MAJOR@
+SLURM_MICRO = @SLURM_MICRO@
+SLURM_MINOR = @SLURM_MINOR@
+SLURM_PREFIX = @SLURM_PREFIX@
+SLURM_VERSION_NUMBER = @SLURM_VERSION_NUMBER@
+SLURM_VERSION_STRING = @SLURM_VERSION_STRING@
+SO_LDFLAGS = @SO_LDFLAGS@
+SSL_CPPFLAGS = @SSL_CPPFLAGS@
+SSL_LDFLAGS = @SSL_LDFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STRIP = @STRIP@
+UTIL_LIBS = @UTIL_LIBS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_have_man2html = @ac_have_man2html@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lua_CFLAGS = @lua_CFLAGS@
+lua_LIBS = @lua_LIBS@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = unit
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/layouts/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/layouts/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am clean clean-generic clean-libtool cscopelist-am ctags \
+	ctags-am distclean distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am
+
+#basic racking energy power topology
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/layouts/unit/Makefile.am b/src/layouts/unit/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..ac5f50cc99c273e6cefe1072e98039f8461ea6d5
--- /dev/null
+++ b/src/layouts/unit/Makefile.am
@@ -0,0 +1,10 @@
+AUTOMAKE_OPTIONS = foreign
+
+PLUGIN_FLAGS = -module -avoid-version --export-dynamic
+
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src/common
+
+pkglib_LTLIBRARIES = layouts_unit_default.la
+
+layouts_unit_default_la_SOURCES = default.c
+layouts_unit_default_la_LDFLAGS = $(SO_LDFLAGS) $(PLUGIN_FLAGS)
diff --git a/src/layouts/unit/Makefile.in b/src/layouts/unit/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..0afc10b4231445decb314a2ccc537d0f32670e3c
--- /dev/null
+++ b/src/layouts/unit/Makefile.in
@@ -0,0 +1,801 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/layouts/unit
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/auxdir/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/auxdir/ax_lib_hdf5.m4 \
+	$(top_srcdir)/auxdir/ax_pthread.m4 \
+	$(top_srcdir)/auxdir/libtool.m4 \
+	$(top_srcdir)/auxdir/ltoptions.m4 \
+	$(top_srcdir)/auxdir/ltsugar.m4 \
+	$(top_srcdir)/auxdir/ltversion.m4 \
+	$(top_srcdir)/auxdir/lt~obsolete.m4 \
+	$(top_srcdir)/auxdir/slurm.m4 \
+	$(top_srcdir)/auxdir/x_ac__system_configuration.m4 \
+	$(top_srcdir)/auxdir/x_ac_affinity.m4 \
+	$(top_srcdir)/auxdir/x_ac_aix.m4 \
+	$(top_srcdir)/auxdir/x_ac_blcr.m4 \
+	$(top_srcdir)/auxdir/x_ac_bluegene.m4 \
+	$(top_srcdir)/auxdir/x_ac_cflags.m4 \
+	$(top_srcdir)/auxdir/x_ac_cray.m4 \
+	$(top_srcdir)/auxdir/x_ac_databases.m4 \
+	$(top_srcdir)/auxdir/x_ac_debug.m4 \
+	$(top_srcdir)/auxdir/x_ac_dlfcn.m4 \
+	$(top_srcdir)/auxdir/x_ac_env.m4 \
+	$(top_srcdir)/auxdir/x_ac_freeipmi.m4 \
+	$(top_srcdir)/auxdir/x_ac_gpl_licensed.m4 \
+	$(top_srcdir)/auxdir/x_ac_hwloc.m4 \
+	$(top_srcdir)/auxdir/x_ac_iso.m4 \
+	$(top_srcdir)/auxdir/x_ac_json.m4 \
+	$(top_srcdir)/auxdir/x_ac_lua.m4 \
+	$(top_srcdir)/auxdir/x_ac_man2html.m4 \
+	$(top_srcdir)/auxdir/x_ac_munge.m4 \
+	$(top_srcdir)/auxdir/x_ac_ncurses.m4 \
+	$(top_srcdir)/auxdir/x_ac_netloc.m4 \
+	$(top_srcdir)/auxdir/x_ac_nrt.m4 \
+	$(top_srcdir)/auxdir/x_ac_ofed.m4 \
+	$(top_srcdir)/auxdir/x_ac_pam.m4 \
+	$(top_srcdir)/auxdir/x_ac_printf_null.m4 \
+	$(top_srcdir)/auxdir/x_ac_ptrace.m4 \
+	$(top_srcdir)/auxdir/x_ac_readline.m4 \
+	$(top_srcdir)/auxdir/x_ac_rrdtool.m4 \
+	$(top_srcdir)/auxdir/x_ac_setpgrp.m4 \
+	$(top_srcdir)/auxdir/x_ac_setproctitle.m4 \
+	$(top_srcdir)/auxdir/x_ac_sgi_job.m4 \
+	$(top_srcdir)/auxdir/x_ac_slurm_ssl.m4 \
+	$(top_srcdir)/auxdir/x_ac_sun_const.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h $(top_builddir)/slurm/slurm.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+LTLIBRARIES = $(pkglib_LTLIBRARIES)
+layouts_unit_default_la_LIBADD =
+am_layouts_unit_default_la_OBJECTS = default.lo
+layouts_unit_default_la_OBJECTS =  \
+	$(am_layouts_unit_default_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+layouts_unit_default_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(layouts_unit_default_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/slurm
+depcomp = $(SHELL) $(top_srcdir)/auxdir/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(layouts_unit_default_la_SOURCES)
+DIST_SOURCES = $(layouts_unit_default_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTHD_CFLAGS = @AUTHD_CFLAGS@
+AUTHD_LIBS = @AUTHD_LIBS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BGL_LOADED = @BGL_LOADED@
+BGQ_LOADED = @BGQ_LOADED@
+BG_INCLUDES = @BG_INCLUDES@
+BG_LDFLAGS = @BG_LDFLAGS@
+BG_L_P_LOADED = @BG_L_P_LOADED@
+BLCR_CPPFLAGS = @BLCR_CPPFLAGS@
+BLCR_HOME = @BLCR_HOME@
+BLCR_LDFLAGS = @BLCR_LDFLAGS@
+BLCR_LIBS = @BLCR_LIBS@
+BLUEGENE_LOADED = @BLUEGENE_LOADED@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+CMD_LDFLAGS = @CMD_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRAY_JOB_CPPFLAGS = @CRAY_JOB_CPPFLAGS@
+CRAY_JOB_LDFLAGS = @CRAY_JOB_LDFLAGS@
+CRAY_SELECT_CPPFLAGS = @CRAY_SELECT_CPPFLAGS@
+CRAY_SELECT_LDFLAGS = @CRAY_SELECT_LDFLAGS@
+CRAY_SWITCH_CPPFLAGS = @CRAY_SWITCH_CPPFLAGS@
+CRAY_SWITCH_LDFLAGS = @CRAY_SWITCH_LDFLAGS@
+CRAY_TASK_CPPFLAGS = @CRAY_TASK_CPPFLAGS@
+CRAY_TASK_LDFLAGS = @CRAY_TASK_LDFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FREEIPMI_CPPFLAGS = @FREEIPMI_CPPFLAGS@
+FREEIPMI_LDFLAGS = @FREEIPMI_LDFLAGS@
+FREEIPMI_LIBS = @FREEIPMI_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+H5CC = @H5CC@
+H5FC = @H5FC@
+HAVEMYSQLCONFIG = @HAVEMYSQLCONFIG@
+HAVE_AIX = @HAVE_AIX@
+HAVE_MAN2HTML = @HAVE_MAN2HTML@
+HAVE_NRT = @HAVE_NRT@
+HAVE_OPENSSL = @HAVE_OPENSSL@
+HAVE_SOME_CURSES = @HAVE_SOME_CURSES@
+HDF5_CC = @HDF5_CC@
+HDF5_CFLAGS = @HDF5_CFLAGS@
+HDF5_CPPFLAGS = @HDF5_CPPFLAGS@
+HDF5_FC = @HDF5_FC@
+HDF5_FFLAGS = @HDF5_FFLAGS@
+HDF5_FLIBS = @HDF5_FLIBS@
+HDF5_LDFLAGS = @HDF5_LDFLAGS@
+HDF5_LIBS = @HDF5_LIBS@
+HDF5_VERSION = @HDF5_VERSION@
+HWLOC_CPPFLAGS = @HWLOC_CPPFLAGS@
+HWLOC_LDFLAGS = @HWLOC_LDFLAGS@
+HWLOC_LIBS = @HWLOC_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JSON_CPPFLAGS = @JSON_CPPFLAGS@
+JSON_LDFLAGS = @JSON_LDFLAGS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_LDFLAGS = @LIB_LDFLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MUNGE_CPPFLAGS = @MUNGE_CPPFLAGS@
+MUNGE_DIR = @MUNGE_DIR@
+MUNGE_LDFLAGS = @MUNGE_LDFLAGS@
+MUNGE_LIBS = @MUNGE_LIBS@
+MYSQL_CFLAGS = @MYSQL_CFLAGS@
+MYSQL_LIBS = @MYSQL_LIBS@
+NCURSES = @NCURSES@
+NETLOC_CPPFLAGS = @NETLOC_CPPFLAGS@
+NETLOC_LDFLAGS = @NETLOC_LDFLAGS@
+NETLOC_LIBS = @NETLOC_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NRT_CPPFLAGS = @NRT_CPPFLAGS@
+NUMA_LIBS = @NUMA_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OFED_CPPFLAGS = @OFED_CPPFLAGS@
+OFED_LDFLAGS = @OFED_LDFLAGS@
+OFED_LIBS = @OFED_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_DIR = @PAM_DIR@
+PAM_LIBS = @PAM_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROCTRACKDIR = @PROCTRACKDIR@
+PROJECT = @PROJECT@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+REAL_BGQ_LOADED = @REAL_BGQ_LOADED@
+REAL_BG_L_P_LOADED = @REAL_BG_L_P_LOADED@
+RELEASE = @RELEASE@
+RRDTOOL_CPPFLAGS = @RRDTOOL_CPPFLAGS@
+RRDTOOL_LDFLAGS = @RRDTOOL_LDFLAGS@
+RRDTOOL_LIBS = @RRDTOOL_LIBS@
+RUNJOB_LDFLAGS = @RUNJOB_LDFLAGS@
+SED = @SED@
+SEMAPHORE_LIBS = @SEMAPHORE_LIBS@
+SEMAPHORE_SOURCES = @SEMAPHORE_SOURCES@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SLURMCTLD_PORT = @SLURMCTLD_PORT@
+SLURMCTLD_PORT_COUNT = @SLURMCTLD_PORT_COUNT@
+SLURMDBD_PORT = @SLURMDBD_PORT@
+SLURMD_PORT = @SLURMD_PORT@
+SLURM_API_AGE = @SLURM_API_AGE@
+SLURM_API_CURRENT = @SLURM_API_CURRENT@
+SLURM_API_MAJOR = @SLURM_API_MAJOR@
+SLURM_API_REVISION = @SLURM_API_REVISION@
+SLURM_API_VERSION = @SLURM_API_VERSION@
+SLURM_MAJOR = @SLURM_MAJOR@
+SLURM_MICRO = @SLURM_MICRO@
+SLURM_MINOR = @SLURM_MINOR@
+SLURM_PREFIX = @SLURM_PREFIX@
+SLURM_VERSION_NUMBER = @SLURM_VERSION_NUMBER@
+SLURM_VERSION_STRING = @SLURM_VERSION_STRING@
+SO_LDFLAGS = @SO_LDFLAGS@
+SSL_CPPFLAGS = @SSL_CPPFLAGS@
+SSL_LDFLAGS = @SSL_LDFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STRIP = @STRIP@
+UTIL_LIBS = @UTIL_LIBS@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_have_man2html = @ac_have_man2html@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lua_CFLAGS = @lua_CFLAGS@
+lua_LIBS = @lua_LIBS@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+PLUGIN_FLAGS = -module -avoid-version --export-dynamic
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src/common
+pkglib_LTLIBRARIES = layouts_unit_default.la
+layouts_unit_default_la_SOURCES = default.c
+layouts_unit_default_la_LDFLAGS = $(SO_LDFLAGS) $(PLUGIN_FLAGS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/layouts/unit/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/layouts/unit/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+	}
+
+uninstall-pkglibLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+	done
+
+clean-pkglibLTLIBRARIES:
+	-test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+	@list='$(pkglib_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+layouts_unit_default.la: $(layouts_unit_default_la_OBJECTS) $(layouts_unit_default_la_DEPENDENCIES) $(EXTRA_layouts_unit_default_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(layouts_unit_default_la_LINK) -rpath $(pkglibdir) $(layouts_unit_default_la_OBJECTS) $(layouts_unit_default_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/default.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(pkglibdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkglibLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-pkglibLTLIBRARIES cscopelist-am ctags \
+	ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-pkglibLTLIBRARIES install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-pkglibLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/layouts/unit/default.c b/src/layouts/unit/default.c
new file mode 100644
index 0000000000000000000000000000000000000000..e88c733e57b078489fb4f09ef4dc2b85077453dd
--- /dev/null
+++ b/src/layouts/unit/default.c
@@ -0,0 +1,225 @@
+/** TODO: copyright notice */
+
+#include "slurm/slurm.h"
+
+#include "src/common/layouts_mgr.h"
+#include "src/common/entity.h"
+#include "src/common/log.h"
+
+const char plugin_name[] = "Unit Tests layouts plugin";
+const char plugin_type[] = "layouts/unit";
+const uint32_t plugin_version = SLURM_VERSION_NUMBER;
+
+/* specific options for unit tests layout */
+s_p_options_t entity_options[] = {
+	/* base keys */
+	{"string", S_P_STRING},
+	{"long", S_P_LONG},
+	{"uint16", S_P_UINT16},
+	{"uint32", S_P_UINT32},
+	{"float", S_P_FLOAT},
+	{"double", S_P_DOUBLE},
+	{"ldouble", S_P_LONG_DOUBLE},
+	{"readonly", S_P_BOOLEAN},
+	/* parents aggregated keys */
+	{"parents_sum_long", S_P_LONG},
+	{"parents_fshare_long", S_P_LONG},
+	{"parents_sum_uint16", S_P_UINT16},
+	{"parents_fshare_uint16", S_P_UINT16},
+	{"parents_sum_uint32", S_P_UINT32},
+	{"parents_fshare_uint32", S_P_UINT32},
+	{"parents_sum_float", S_P_FLOAT},
+	{"parents_fshare_float", S_P_FLOAT},
+	{"parents_sum_double", S_P_DOUBLE},
+	{"parents_fshare_double", S_P_DOUBLE},
+	{"parents_sum_ldouble", S_P_LONG_DOUBLE},
+	{"parents_fshare_ldouble", S_P_LONG_DOUBLE},
+	/* children aggregated keys */
+	{"children_count", S_P_UINT32},
+	{"children_sum_long", S_P_LONG},
+	{"children_avg_long", S_P_LONG},
+	{"children_min_long", S_P_LONG},
+	{"children_max_long", S_P_LONG},
+	{"children_sum_uint16", S_P_UINT16},
+	{"children_avg_uint16", S_P_UINT16},
+	{"children_min_uint16", S_P_UINT16},
+	{"children_max_uint16", S_P_UINT16},
+	{"children_sum_uint32", S_P_UINT32},
+	{"children_avg_uint32", S_P_UINT32},
+	{"children_min_uint32", S_P_UINT32},
+	{"children_max_uint32", S_P_UINT32},
+	{"children_sum_float", S_P_FLOAT},
+	{"children_avg_float", S_P_FLOAT},
+	{"children_min_float", S_P_FLOAT},
+	{"children_max_float", S_P_FLOAT},
+	{"children_sum_double", S_P_DOUBLE},
+	{"children_avg_double", S_P_DOUBLE},
+	{"children_min_double", S_P_DOUBLE},
+	{"children_max_double", S_P_DOUBLE},
+	{"children_sum_ldouble", S_P_LONG_DOUBLE},
+	{"children_avg_ldouble", S_P_LONG_DOUBLE},
+	{"children_min_ldouble", S_P_LONG_DOUBLE},
+	{"children_max_ldouble", S_P_LONG_DOUBLE},
+	{NULL}
+};
+s_p_options_t options[] = {
+	{"Entity", S_P_EXPLINE, NULL, NULL, entity_options},
+	{NULL}
+};
+
+const layouts_keyspec_t keyspec[] = {
+	/* base keys */
+	{"string", L_T_STRING},
+	{"long", L_T_LONG},
+	{"uint16", L_T_UINT16},
+	{"uint32", L_T_UINT32},
+	{"float", L_T_FLOAT},
+	{"double", L_T_DOUBLE},
+	{"ldouble", L_T_LONG_DOUBLE},
+	{"readonly", L_T_BOOLEAN, KEYSPEC_RDONLY},
+	/* parents aggregated keys */
+	{"parents_sum_long", L_T_LONG,
+	 KEYSPEC_UPDATE_PARENTS_SUM, "long"},
+	{"parents_fshare_long", L_T_LONG,
+	 KEYSPEC_UPDATE_PARENTS_FSHARE, "long"},
+	{"parents_sum_uint16", L_T_UINT16,
+	 KEYSPEC_UPDATE_PARENTS_SUM, "uint16"},
+	{"parents_fshare_uint16", L_T_UINT16,
+	 KEYSPEC_UPDATE_PARENTS_FSHARE, "uint16"},
+	{"parents_sum_uint32", L_T_UINT32,
+	 KEYSPEC_UPDATE_PARENTS_SUM, "uint32"},
+	{"parents_fshare_uint32", L_T_UINT32,
+	 KEYSPEC_UPDATE_PARENTS_FSHARE, "uint32"},
+	{"parents_sum_float", L_T_FLOAT,
+	 KEYSPEC_UPDATE_PARENTS_SUM, "float"},
+	{"parents_fshare_float", L_T_FLOAT,
+	 KEYSPEC_UPDATE_PARENTS_FSHARE, "float"},
+	{"parents_sum_double", L_T_DOUBLE,
+	 KEYSPEC_UPDATE_PARENTS_SUM, "double"},
+	{"parents_fshare_double", L_T_DOUBLE,
+	 KEYSPEC_UPDATE_PARENTS_FSHARE, "double"},
+	{"parents_sum_ldouble", L_T_LONG_DOUBLE,
+	 KEYSPEC_UPDATE_PARENTS_SUM, "ldouble"},
+	{"parents_fshare_ldouble", L_T_LONG_DOUBLE,
+	 KEYSPEC_UPDATE_PARENTS_FSHARE, "ldouble"},
+	/* children aggregated keys */
+	{"children_count", L_T_UINT32, KEYSPEC_UPDATE_CHILDREN_COUNT},
+	{"children_sum_long", L_T_LONG,
+	 KEYSPEC_UPDATE_CHILDREN_SUM, "long"},
+	{"children_avg_long", L_T_LONG,
+	 KEYSPEC_UPDATE_CHILDREN_AVG, "long"},
+	{"children_min_long", L_T_LONG,
+	 KEYSPEC_UPDATE_CHILDREN_MIN, "long"},
+	{"children_max_long", L_T_LONG,
+	 KEYSPEC_UPDATE_CHILDREN_MAX, "long"},
+	{"children_sum_uint16", L_T_UINT16,
+	 KEYSPEC_UPDATE_CHILDREN_SUM, "uint16"},
+	{"children_avg_uint16", L_T_UINT16,
+	 KEYSPEC_UPDATE_CHILDREN_AVG, "uint16"},
+	{"children_min_uint16", L_T_UINT16,
+	 KEYSPEC_UPDATE_CHILDREN_MIN, "uint16"},
+	{"children_max_uint16", L_T_UINT16,
+	 KEYSPEC_UPDATE_CHILDREN_MAX, "uint16"},
+	{"children_sum_uint32", L_T_UINT32,
+	 KEYSPEC_UPDATE_CHILDREN_SUM, "uint32"},
+	{"children_avg_uint32", L_T_UINT32,
+	 KEYSPEC_UPDATE_CHILDREN_AVG, "uint32"},
+	{"children_min_uint32", L_T_UINT32,
+	 KEYSPEC_UPDATE_CHILDREN_MIN, "uint32"},
+	{"children_max_uint32", L_T_UINT32,
+	 KEYSPEC_UPDATE_CHILDREN_MAX, "uint32"},
+	{"children_sum_float", L_T_FLOAT,
+	 KEYSPEC_UPDATE_CHILDREN_SUM, "float"},
+	{"children_avg_float", L_T_FLOAT,
+	 KEYSPEC_UPDATE_CHILDREN_AVG, "float"},
+	{"children_min_float", L_T_FLOAT,
+	 KEYSPEC_UPDATE_CHILDREN_MIN, "float"},
+	{"children_max_float", L_T_FLOAT,
+	 KEYSPEC_UPDATE_CHILDREN_MAX, "float"},
+	{"children_sum_double", L_T_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_SUM, "double"},
+	{"children_avg_double", L_T_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_AVG, "double"},
+	{"children_min_double", L_T_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_MIN, "double"},
+	{"children_max_double", L_T_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_MAX, "double"},
+	{"children_sum_ldouble", L_T_LONG_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_SUM, "ldouble"},
+	{"children_avg_ldouble", L_T_LONG_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_AVG, "ldouble"},
+	{"children_min_ldouble", L_T_LONG_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_MIN, "ldouble"},
+	{"children_max_ldouble", L_T_LONG_DOUBLE,
+	 KEYSPEC_UPDATE_CHILDREN_MAX, "ldouble"},
+	{NULL}
+};
+
+/* types allowed in the entity's "type" field */
+const char* etypes[] = {
+	"UnitTestPass",
+	"UnitTest",
+	NULL
+};
+
+const layouts_plugin_spec_t plugin_spec = {
+	options,
+	keyspec,
+	LAYOUT_STRUCT_TREE,
+	etypes,
+	true, /* if this evalued to true, keys inside plugin_keyspec present in
+	       * plugin_options having corresponding types, are automatically
+	       * handled by the layouts manager.
+	       */
+	true  /* if this evalued to true, keys updates trigger an automatic
+	       * update of their entities neighborhoods based on their
+	       * KEYSPEC_UPDATE_* set flags
+	       */
+};
+
+/* manager is lock when this function is called */
+/* disable this callback by setting it to NULL, warn: not every callback can
+ * be desactivated this way */
+int layouts_p_conf_done(
+		xhash_t* entities, layout_t* layout, s_p_hashtbl_t* tbl)
+{
+	return 1;
+}
+
+
+/* disable this callback by setting it to NULL, warn: not every callback can
+ * be desactivated this way */
+void layouts_p_entity_parsing(
+		entity_t* e, s_p_hashtbl_t* etbl, layout_t* layout)
+{
+}
+
+/* manager is lock then this function is called */
+/* disable this callback by setting it to NULL, warn: not every callback can
+ * be desactivated this way */
+int layouts_p_update_done(layout_t* layout, entity_t** e_array, int e_cnt)
+{
+	int i;
+	debug3("layouts/unit: receiving update callback for %d entities",
+	       e_cnt);
+	for (i = 0; i < e_cnt; i++) {
+		if (e_array[i] == NULL) {
+			debug3("layouts/unit: skipping update of nullified"
+			       "entity[%d]", i);
+		} else {
+			debug3("layouts/unit: updating entity[%d]=%s",
+			       i, e_array[i]->name);
+		}
+	}
+	return 1;
+}
+
+int init(void)
+{
+	return SLURM_SUCCESS;
+}
+
+int fini(void)
+{
+	return SLURM_SUCCESS;
+}
diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index 002fb335197a89a08d1f1e6bfac6d77da900172d..9e368a126df8f91b88986cd9a9a7c2718b50d76e 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -617,7 +617,7 @@ int main(int argc, char *argv[])
 		recover = 2;
 	}
 
-	slurm_layouts_fini();
+	layouts_fini();
 
 	/* Since pidfile is created as user root (its owner is
 	 *   changed to SlurmUser) SlurmUser may not be able to
diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c
index 47fb7d632974cb2356a71f4b4c3a740cdd59142d..e71ce3c8278c53f64d79574efc0f29f158c6acfa 100644
--- a/src/slurmctld/read_config.c
+++ b/src/slurmctld/read_config.c
@@ -912,7 +912,7 @@ int read_slurm_conf(int recover, bool reconfig)
 		return error_code;
 	}
 
-	if (slurm_layouts_init() != SLURM_SUCCESS)
+	if (layouts_init() != SLURM_SUCCESS)
 		fatal("Failed to initialize the layouts framework");
 
 	if (slurm_topo_init() != SLURM_SUCCESS)
@@ -986,7 +986,7 @@ int read_slurm_conf(int recover, bool reconfig)
 	 * Only load it at init time, not during reconfiguration stages.
 	 * It requires a full restart to switch to a new configuration for now.
 	 */
-	if (!reconfig && (slurm_layouts_load_config() != SLURM_SUCCESS))
+	if (!reconfig && (layouts_load_config(recover) != SLURM_SUCCESS))
 		fatal("Failed to load the layouts framework configuration");
 
 	if (reconfig) {		/* Preserve state from memory */