[minicoredumper] [PATCH 09/14] minicoredumper: Write an uncompressed core and a fatcore as a sparse file

Mateusz Moscicki m.moscicki2 at partner.samsung.com
Tue May 21 14:52:45 CEST 2019


The uncompressed core and fatcore may contain large empty areas. In this
case we can write a sparse file to save disk space.

Change-Id: Ib0bfee740bba89dc4d6b97084b775480ba541e39
---
 src/minicoredumper/corestripper.c | 47 +++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/src/minicoredumper/corestripper.c b/src/minicoredumper/corestripper.c
index 74141ce..ed2fd97 100644
--- a/src/minicoredumper/corestripper.c
+++ b/src/minicoredumper/corestripper.c
@@ -127,10 +127,10 @@ static ssize_t read_file_fd(int fd, char *dst, int len)
 	return size;
 }
 
-static ssize_t write_file_fd(int fd, char *src, int len)
+static ssize_t write_file_fd(int fd, char *src, size_t len)
 {
 	size_t size = 0;
-	int r;
+	ssize_t r;
 
 	do {
 		r = write(fd, src + size, len);
@@ -147,6 +147,34 @@ static ssize_t write_file_fd(int fd, char *src, int len)
 	return size;
 }
 
+static bool is_empty_region(char *src, size_t len) {
+	for (size_t i = 0; i < len; i++) {
+		if (src[i] != 0)
+			return false;
+	}
+	return true;
+}
+
+static ssize_t write_sparse_file_fd(int fd, char *src, size_t len)
+{
+	ssize_t ret = -1;
+
+	if (is_empty_region(src, len)) {
+		if (lseek64(fd, len, SEEK_CUR) != -1) {
+			if (len > SSIZE_MAX)
+				ret = SSIZE_MAX;
+			else
+				ret = len;
+		} else {
+			info("lseek64 error (len = %d): %m", len);
+		}
+	}
+	if (ret < 0)
+		ret = write_file_fd(fd, src, len);
+
+	return ret;
+}
+
 static void check_config(struct config *cfg)
 {
 	if (!cfg->base_dir)
@@ -881,6 +909,15 @@ static int parse_vma_info(struct dump_info *di)
 	return 0;
 }
 
+static bool is_file(int fd) {
+	struct stat buf;
+	if (fstat(fd, &buf) == -1) {
+		info("fstat error: %m");
+		return false;
+	}
+	return S_ISREG(buf.st_mode);
+}
+
 /*
  * Copy data from a source core to (optionally) multiple destination cores.
  * Assumes all files are already positioned correctly to begin.
@@ -889,6 +926,8 @@ static int copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
 {
 	size_t chunk;
 	int ret;
+	ssize_t (*const write_func)(int fd, char *src, size_t len) =
+						is_file(dest) ? write_sparse_file_fd : write_file_fd;
 
 	if (len < (size_t)PAGESZ)
 		chunk = len;
@@ -906,7 +945,7 @@ static int copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
 			return -1;
 		}
 
-		ret = write_file_fd(dest, pagebuf, chunk);
+		ret = write_func(dest, pagebuf, chunk);
 		if (ret < 0) {
 			info("write core failed at 0x%lx",
 			     lseek64(dest, 0, SEEK_CUR));
@@ -914,7 +953,7 @@ static int copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
 		}
 
 		if (dest2 >= 0) {
-			ret = write_file_fd(dest2, pagebuf, chunk);
+			ret = write_func(dest2, pagebuf, chunk);
 			if (ret < 0) {
 				info("write core2 failed at 0x%lx",
 				     lseek64(dest2, 0, SEEK_CUR));
-- 
2.7.4




More information about the minicoredumper mailing list