merge in mnc-release history after reset to mnc-dev
diff --git a/ext4_utils/canned_fs_config.c b/ext4_utils/canned_fs_config.c
index 69646b1..2165feb 100644
--- a/ext4_utils/canned_fs_config.c
+++ b/ext4_utils/canned_fs_config.c
@@ -80,7 +80,7 @@
 	return 0;
 }
 
-void canned_fs_config(const char* path, int dir,
+void canned_fs_config(const char* path, int dir, const char* target_out_path,
 					  unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) {
 	Path key;
 	key.path = path+1;   // canned paths lack the leading '/'
@@ -99,7 +99,7 @@
 
 	unsigned c_uid, c_gid, c_mode;
 	uint64_t c_capabilities;
-	fs_config(path, dir, &c_uid, &c_gid, &c_mode, &c_capabilities);
+	fs_config(path, dir, target_out_path, &c_uid, &c_gid, &c_mode, &c_capabilities);
 
 	if (c_uid != *uid) printf("%s uid %d %d\n", path, *uid, c_uid);
 	if (c_gid != *gid) printf("%s gid %d %d\n", path, *gid, c_gid);
diff --git a/ext4_utils/canned_fs_config.h b/ext4_utils/canned_fs_config.h
index aec923b..d9f51ca 100644
--- a/ext4_utils/canned_fs_config.h
+++ b/ext4_utils/canned_fs_config.h
@@ -20,7 +20,7 @@
 #include <inttypes.h>
 
 int load_canned_fs_config(const char* fn);
-void canned_fs_config(const char* path, int dir,
+void canned_fs_config(const char* path, int dir, const char* target_out_path,
                       unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities);
 
 #endif
diff --git a/ext4_utils/ext4_utils.h b/ext4_utils/ext4_utils.h
index ea95446..8a4ad8f 100644
--- a/ext4_utils/ext4_utils.h
+++ b/ext4_utils/ext4_utils.h
@@ -150,12 +150,12 @@
 void ext4_parse_sb_info(struct ext4_super_block *sb);
 u16 ext4_crc16(u16 crc_in, const void *buf, int size);
 
-typedef void (*fs_config_func_t)(const char *path, int dir, unsigned *uid, unsigned *gid,
-		unsigned *mode, uint64_t *capabilities);
+typedef void (*fs_config_func_t)(const char *path, int dir, const char *target_out_path,
+        unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities);
 
 struct selabel_handle;
 
-int make_ext4fs_internal(int fd, const char *directory,
+int make_ext4fs_internal(int fd, const char *directory, const char *_target_out_directory,
 						 const char *mountpoint, fs_config_func_t fs_config_func, int gzip,
 						 int sparse, int crc, int wipe, int real_uuid,
 						 struct selabel_handle *sehnd, int verbose, time_t fixed_time,
diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c
index c089d25..669d080 100644
--- a/ext4_utils/make_ext4fs.c
+++ b/ext4_utils/make_ext4fs.c
@@ -123,7 +123,7 @@
    that does not exist on disk (e.g. lost+found).
    dir_path is an absolute path, with trailing slash, to the same directory
    if the image were mounted at the specified mount point */
-static u32 build_directory_structure(const char *full_path, const char *dir_path,
+static u32 build_directory_structure(const char *full_path, const char *dir_path, const char *target_out_path,
 		u32 dir_inode, fs_config_func_t fs_config_func,
 		struct selabel_handle *sehnd, int verbose, time_t fixed_time)
 {
@@ -201,7 +201,7 @@
 			unsigned int uid = 0;
 			unsigned int gid = 0;
 			int dir = S_ISDIR(stat.st_mode);
-			fs_config_func(dentries[i].path, dir, &uid, &gid, &mode, &capabilities);
+			fs_config_func(dentries[i].path, dir, target_out_path, &uid, &gid, &mode, &capabilities);
 			dentries[i].mode = mode;
 			dentries[i].uid = uid;
 			dentries[i].gid = gid;
@@ -285,8 +285,8 @@
 			ret = asprintf(&subdir_dir_path, "%s/", dentries[i].path);
 			if (ret < 0)
 				critical_error_errno("asprintf");
-			entry_inode = build_directory_structure(subdir_full_path,
-					subdir_dir_path, inode, fs_config_func, sehnd, verbose, fixed_time);
+			entry_inode = build_directory_structure(subdir_full_path, subdir_dir_path, target_out_path,
+					inode, fs_config_func, sehnd, verbose, fixed_time);
 			free(subdir_full_path);
 			free(subdir_dir_path);
 		} else if (dentries[i].file_type == EXT4_FT_SYMLINK) {
@@ -404,7 +404,7 @@
 	reset_ext4fs_info();
 	info.len = len;
 
-	return make_ext4fs_internal(fd, NULL, mountpoint, NULL, 0, 1, 0, 0, 0, sehnd, 0, -1, NULL);
+	return make_ext4fs_internal(fd, NULL, NULL, mountpoint, NULL, 0, 1, 0, 0, 0, sehnd, 0, -1, NULL);
 }
 
 int make_ext4fs(const char *filename, long long len,
@@ -422,7 +422,7 @@
 		return EXIT_FAILURE;
 	}
 
-	status = make_ext4fs_internal(fd, NULL, mountpoint, NULL, 0, 0, 0, 1, 0, sehnd, 0, -1, NULL);
+	status = make_ext4fs_internal(fd, NULL, NULL, mountpoint, NULL, 0, 0, 0, 1, 0, sehnd, 0, -1, NULL);
 	close(fd);
 
 	return status;
@@ -488,7 +488,7 @@
 	return canonicalize_slashes(str, false);
 }
 
-int make_ext4fs_internal(int fd, const char *_directory,
+int make_ext4fs_internal(int fd, const char *_directory, const char *_target_out_directory,
 						 const char *_mountpoint, fs_config_func_t fs_config_func, int gzip,
 						 int sparse, int crc, int wipe, int real_uuid,
 						 struct selabel_handle *sehnd, int verbose, time_t fixed_time,
@@ -498,6 +498,7 @@
 	u16 root_mode;
 	char *mountpoint;
 	char *directory = NULL;
+	char *target_out_directory = NULL;
 
 	if (setjmp(setjmp_env))
 		return EXIT_FAILURE; /* Handle a call to longjmp() */
@@ -512,6 +513,10 @@
 		directory = canonicalize_rel_slashes(_directory);
 	}
 
+	if (_target_out_directory) {
+		target_out_directory = canonicalize_rel_slashes(_target_out_directory);
+	}
+
 	if (info.len <= 0)
 		info.len = get_file_size(fd);
 
@@ -600,7 +605,7 @@
 	root_inode_num = build_default_directory_structure(mountpoint, sehnd);
 #else
 	if (directory)
-		root_inode_num = build_directory_structure(directory, mountpoint, 0,
+		root_inode_num = build_directory_structure(directory, mountpoint, target_out_directory, 0,
 			fs_config_func, sehnd, verbose, fixed_time);
 	else
 		root_inode_num = build_default_directory_structure(mountpoint, sehnd);
diff --git a/ext4_utils/make_ext4fs_main.c b/ext4_utils/make_ext4fs_main.c
index f28e1b2..03872db 100644
--- a/ext4_utils/make_ext4fs_main.c
+++ b/ext4_utils/make_ext4fs_main.c
@@ -57,7 +57,7 @@
 	fprintf(stderr, "    [ -L <label> ] [ -f ] [ -a <android mountpoint> ] [ -u ]\n");
 	fprintf(stderr, "    [ -S file_contexts ] [ -C fs_config ] [ -T timestamp ]\n");
 	fprintf(stderr, "    [ -z | -s ] [ -w ] [ -c ] [ -J ] [ -v ] [ -B <block_list_file> ]\n");
-	fprintf(stderr, "    <filename> [<directory>]\n");
+	fprintf(stderr, "    <filename> [[<directory>] <target_out_directory>]\n");
 }
 
 int main(int argc, char **argv)
@@ -65,6 +65,7 @@
 	int opt;
 	const char *filename = NULL;
 	const char *directory = NULL;
+	const char *target_out_directory = NULL;
 	char *mountpoint = NULL;
 	fs_config_func_t fs_config_func = NULL;
 	const char *fs_config_file = NULL;
@@ -216,6 +217,9 @@
 	if (optind < argc)
 		directory = argv[optind++];
 
+	if (optind < argc)
+		target_out_directory = argv[optind++];
+
 	if (optind < argc) {
 		fprintf(stderr, "Unexpected argument: %s\n", argv[optind]);
 		usage(argv[0]);
@@ -232,7 +236,7 @@
 		fd = STDOUT_FILENO;
 	}
 
-	exitcode = make_ext4fs_internal(fd, directory, mountpoint, fs_config_func, gzip,
+	exitcode = make_ext4fs_internal(fd, directory, target_out_directory, mountpoint, fs_config_func, gzip,
 		sparse, crc, wipe, real_uuid, sehnd, verbose, fixed_time, block_list_file);
 	close(fd);
 	if (block_list_file)
diff --git a/ext4_utils/mkuserimg.sh b/ext4_utils/mkuserimg.sh
index 3a6006e..8667013 100755
--- a/ext4_utils/mkuserimg.sh
+++ b/ext4_utils/mkuserimg.sh
@@ -6,7 +6,7 @@
 cat<<EOT
 Usage:
 mkuserimg.sh [-s] SRC_DIR OUTPUT_FILE EXT_VARIANT MOUNT_POINT SIZE [-j <journal_size>]
-             [-T TIMESTAMP] [-C FS_CONFIG] [-B BLOCK_LIST_FILE] [-L LABEL] [FILE_CONTEXTS]
+             [-T TIMESTAMP] [-C FS_CONFIG] [-D PRODUCT_OUT] [-B BLOCK_LIST_FILE] [-L LABEL] [FILE_CONTEXTS]
 EOT
 }
 
@@ -55,6 +55,12 @@
   shift; shift
 fi
 
+PRODUCT_OUT=
+if [[ "$1" == "-D" ]]; then
+  PRODUCT_OUT=$2
+  shift; shift
+fi
+
 BLOCK_LIST=
 if [[ "$1" == "-B" ]]; then
   BLOCK_LIST=$2
@@ -98,7 +104,7 @@
   OPT="$OPT -L $LABEL"
 fi
 
-MAKE_EXT4FS_CMD="make_ext4fs $ENABLE_SPARSE_IMAGE -T $TIMESTAMP $OPT -l $SIZE $JOURNAL_FLAGS -a $MOUNT_POINT $OUTPUT_FILE $SRC_DIR"
+MAKE_EXT4FS_CMD="make_ext4fs $ENABLE_SPARSE_IMAGE -T $TIMESTAMP $OPT -l $SIZE $JOURNAL_FLAGS -a $MOUNT_POINT $OUTPUT_FILE $SRC_DIR $PRODUCT_OUT"
 echo $MAKE_EXT4FS_CMD
 $MAKE_EXT4FS_CMD
 if [ $? -ne 0 ]; then
diff --git a/simpleperf/workload.cpp b/simpleperf/workload.cpp
index f8e4edd..999e315 100644
--- a/simpleperf/workload.cpp
+++ b/simpleperf/workload.cpp
@@ -93,10 +93,11 @@
     TEMP_FAILURE_RETRY(write(exec_child_fd, &exec_child_failed, 1));
     close(exec_child_fd);
     errno = saved_errno;
-    PLOG(FATAL) << "execvp(" << argv[0] << ") failed";
+    PLOG(ERROR) << "execvp(" << argv[0] << ") failed";
   } else {
-    PLOG(FATAL) << "child process failed to receive start_signal, nread = " << nread;
+    PLOG(DEBUG) << "child process failed to receive start_signal, nread = " << nread;
   }
+  exit(1);
 }
 
 bool Workload::Start() {
diff --git a/squashfs_utils/mksquashfsimage.sh b/squashfs_utils/mksquashfsimage.sh
index 260a0fd..1bc2b83 100755
--- a/squashfs_utils/mksquashfsimage.sh
+++ b/squashfs_utils/mksquashfsimage.sh
@@ -5,7 +5,7 @@
 function usage() {
 cat<<EOT
 Usage:
-${0##*/} SRC_DIR OUTPUT_FILE [-s] [-m MOUNT_POINT] [-c FILE_CONTEXTS] [-b BLOCK_SIZE] [-z COMPRESSOR] [-zo COMPRESSOR_OPT]
+${0##*/} SRC_DIR OUTPUT_FILE [-s] [-m MOUNT_POINT] [-d PRODUCT_OUT] [-c FILE_CONTEXTS] [-b BLOCK_SIZE] [-z COMPRESSOR] [-zo COMPRESSOR_OPT]
 EOT
 }
 
@@ -36,6 +36,12 @@
     shift; shift
 fi
 
+PRODUCT_OUT=
+if [[ "$1" == "-d" ]]; then
+    PRODUCT_OUT=$2
+    shift; shift
+fi
+
 FILE_CONTEXTS=
 if [[ "$1" == "-c" ]]; then
     FILE_CONTEXTS=$2
@@ -65,6 +71,9 @@
 if [ -n "$MOUNT_POINT" ]; then
   OPT="$OPT -mount-point $MOUNT_POINT"
 fi
+if [ -n "$PRODUCT_OUT" ]; then
+  OPT="$OPT -product-out $PRODUCT_OUT"
+fi
 if [ -n "$FILE_CONTEXTS" ]; then
   OPT="$OPT -context-file $FILE_CONTEXTS"
 fi