From c47ed828560cbbfc06c0dedce9fd8a0a7d5671d8 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Date: Wed, 2 Nov 2011 15:12:28 +0900
Subject: [RFC PATCH] crash: Support LZO compression format

---
 defs.h     |    1 +
 diskdump.c |   20 +++++++++++++++++++-
 diskdump.h |    3 ++-
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/defs.h b/defs.h
index 66d844b..a05391b 100755
--- a/defs.h
+++ b/defs.h
@@ -47,6 +47,7 @@
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <execinfo.h> /* backtrace() */
+#include <lzo/lzo1x.h>
 
 #ifndef ATTRIBUTE_UNUSED
 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
diff --git a/diskdump.c b/diskdump.c
index 5519af7..620d3f1 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -66,6 +66,7 @@ struct diskdump_data {
 	ulong	cached_reads;
 	ulong  *valid_pages;
 	ulong   accesses;
+	int	lzo_supported;
 };
 
 static struct diskdump_data diskdump_data = { 0 };
@@ -641,6 +642,8 @@ is_diskdump(char *file)
 	if (pc->flags2 & GET_OSRELEASE) 
 		diskdump_get_osrelease();
 
+	dd->lzo_supported = lzo_init() == LZO_E_OK;
+
 	return TRUE;
 }
 
@@ -795,13 +798,28 @@ cache_page(physaddr_t paddr)
 			return READ_ERROR;
 	}
 
-	if (pd.flags & DUMP_DH_COMPRESSED) {
+	if (pd.flags & DUMP_DH_COMPRESSED_ZLIB) {
 		retlen = block_size;
 		ret = uncompress((unsigned char *)dd->page_cache_hdr[i].pg_bufptr,
 		                 &retlen,
 		                 (unsigned char *)dd->compressed_page,
 		                 pd.size);
 		if ((ret != Z_OK) || (retlen != block_size)) {
+			error(INFO, "%s: uncompress failed: %d\n",
+				DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
+				ret);
+			return READ_ERROR;
+		}
+	} else if (pd.flags & DUMP_DH_COMPRESSED_LZO) {
+
+		if (!dd->lzo_supported)
+			return READ_ERROR;
+
+		retlen = block_size;
+		ret = lzo1x_decompress_safe(dd->compressed_page, pd.size,
+					    dd->page_cache_hdr[i].pg_bufptr,
+					    &retlen, LZO1X_MEM_DECOMPRESS);
+		if ((ret != LZO_E_OK) || (retlen != block_size)) {
 			error(INFO, "%s: uncompress failed: %d\n", 
 				DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
 				ret);
diff --git a/diskdump.h b/diskdump.h
index c7cc4fc..bd99fbd 100644
--- a/diskdump.h
+++ b/diskdump.h
@@ -72,7 +72,8 @@ struct kdump_sub_header {
 };
 
 /* page flags */
-#define DUMP_DH_COMPRESSED	0x1	/* page is compressed               */
+#define DUMP_DH_COMPRESSED_ZLIB	0x1	/* page is compressed with zlib */
+#define DUMP_DH_COMPRESSED_LZO	0x2	/* page is compressed with lzo */
 
 /* descriptor of each page for vmcore */
 typedef struct page_desc {
-- 
1.7.4.4

