Add -l option as one of the command-line options users can specify. If
-l option is specified, then makedumpfile generates dumpfile in
kdump-compressed format with lzo compression by each page.

Signed-off-by: HATAYAMA Daisuke <[email protected]>
---

 diskdump_mod.h |    3 ++-
 makedumpfile.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++---------
 makedumpfile.h |    2 ++
 3 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/diskdump_mod.h b/diskdump_mod.h
index c1de972..e672485 100644
--- a/diskdump_mod.h
+++ b/diskdump_mod.h
@@ -78,7 +78,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     /* paged is compressed with lzo */
 
 /* descriptor of each page for vmcore */
 typedef struct page_desc {
diff --git a/makedumpfile.c b/makedumpfile.c
index c51fda3..e0079b8 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -257,7 +257,7 @@ readpmem_kdump_compressed(unsigned long long paddr, void 
*bufptr, size_t size)
                goto error;
        }
 
-       if (pd.flags & DUMP_DH_COMPRESSED) {
+       if (pd.flags & DUMP_DH_COMPRESSED_ZLIB) {
                retlen = info->page_size;
                ret = uncompress((unsigned char *)buf2, &retlen,
                                        (unsigned char *)buf, pd.size);
@@ -266,6 +266,17 @@ readpmem_kdump_compressed(unsigned long long paddr, void 
*bufptr, size_t size)
                        goto error;
                }
                memcpy(bufptr, buf2 + page_offset, size);
+       } else if (info->flag_lzo_support
+                  && (pd.flags & DUMP_DH_COMPRESSED_LZO)) {
+               retlen = info->page_size;
+               ret = lzo1x_decompress_safe((unsigned char *)buf, pd.size,
+                                           (unsigned char *)buf2, &retlen,
+                                           LZO1X_MEM_DECOMPRESS);
+               if ((ret != LZO_E_OK) || (retlen != info->page_size)) {
+                       ERRMSG("Uncompress failed: %d\n", ret);
+                       goto error;
+               }
+               memcpy(bufptr, buf2 + page_offset, size);
        } else
                memcpy(bufptr, buf + page_offset, size);
 
@@ -2498,6 +2509,9 @@ initial(void)
        unsigned long size;
        int debug_info = FALSE;
 
+       if (lzo_init() == LZO_E_OK)
+               info->flag_lzo_support = TRUE;
+
        if (!is_xen_memory() && info->flag_exclude_xen_dom) {
                MSG("'-X' option is disable,");
                MSG("because %s is not Xen's memory core image.\n", 
info->name_memory);
@@ -4665,10 +4679,11 @@ write_kdump_pages(struct cache_data *cd_header, struct 
cache_data *cd_page)
        off_t offset_data = 0;
        struct disk_dump_header *dh = info->dump_header;
        unsigned char buf[info->page_size], *buf_out = NULL;
-       unsigned long len_buf_out;
+       unsigned long len_buf_out, len_buf_out_zlib, len_buf_out_lzo;
        struct dump_bitmap bitmap2;
        struct timeval tv_start;
        const off_t failed = (off_t)-1;
+       lzo_bytep wrkmem = NULL;
 
        int ret = FALSE;
 
@@ -4677,7 +4692,16 @@ write_kdump_pages(struct cache_data *cd_header, struct 
cache_data *cd_page)
 
        initialize_2nd_bitmap(&bitmap2);
 
-       len_buf_out = compressBound(info->page_size);
+       if ((wrkmem = malloc(LZO1X_1_MEM_COMPRESS)) == NULL) {
+               ERRMSG("Can't allocate memory for the working memory. %s\n",
+                      strerror(errno));
+               goto out;
+       }
+
+       len_buf_out_zlib = compressBound(info->page_size);
+       len_buf_out_lzo = info->page_size + info->page_size / 16 + 64 + 3;
+       len_buf_out = MAX(len_buf_out_zlib, len_buf_out_lzo);
+
        if ((buf_out = malloc(len_buf_out)) == NULL) {
                ERRMSG("Can't allocate memory for the compression buffer. %s\n",
                    strerror(errno));
@@ -4759,11 +4783,21 @@ write_kdump_pages(struct cache_data *cd_header, struct 
cache_data *cd_page)
                 * Compress the page data.
                 */
                size_out = len_buf_out;
-               if (info->flag_compress
-                   && (compress2(buf_out, &size_out, buf,
-                   info->page_size, Z_BEST_SPEED) == Z_OK)
+               if ((info->flag_compress & DUMP_DH_COMPRESSED_ZLIB)
+                   && ((size_out = len_buf_out),
+                       compress2(buf_out, &size_out, buf, info->page_size,
+                                 Z_BEST_SPEED) == Z_OK)
                    && (size_out < info->page_size)) {
-                       pd.flags = 1;
+                       pd.flags = DUMP_DH_COMPRESSED_ZLIB;
+                       pd.size  = size_out;
+                       memcpy(buf, buf_out, pd.size);
+               } else if (info->flag_lzo_support
+                          && (info->flag_compress & DUMP_DH_COMPRESSED_LZO)
+                          && ((size_out = info->page_size),
+                              lzo1x_1_compress(buf, info->page_size, buf_out,
+                                               &size_out, wrkmem) == LZO_E_OK)
+                          && (size_out < info->page_size)) {
+                       pd.flags = DUMP_DH_COMPRESSED_LZO;
                        pd.size  = size_out;
                        memcpy(buf, buf_out, pd.size);
                } else {
@@ -4806,6 +4840,8 @@ write_kdump_pages(struct cache_data *cd_header, struct 
cache_data *cd_page)
 out:
        if (buf_out != NULL)
                free(buf_out);
+       if (wrkmem != NULL)
+               free(wrkmem);
 
        return ret;
 }
@@ -6896,7 +6932,7 @@ main(int argc, char *argv[])
 
        info->block_order = DEFAULT_ORDER;
        message_level = DEFAULT_MSG_LEVEL;
-       while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:MRrsvXx:", 
longopts,
+       while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:lMRrsvXx:", 
longopts,
            NULL)) != -1) {
                switch (opt) {
                case 'b':
@@ -6906,7 +6942,7 @@ main(int argc, char *argv[])
                        info->name_filterconfig = optarg;
                        break;
                case 'c':
-                       info->flag_compress = 1;
+                       info->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
                        break;
                case 'D':
                        flag_debug = TRUE;
@@ -6945,6 +6981,9 @@ main(int argc, char *argv[])
                                goto out;
                        info->flag_sadump_diskset = 1;
                        break;
+               case 'l':
+                       info->flag_compress = DUMP_DH_COMPRESSED_LZO;
+                       break;
                case 'm':
                        message_level = atoi(optarg);
                        break;
diff --git a/makedumpfile.h b/makedumpfile.h
index ebb8929..9594ca7 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -31,6 +31,7 @@
 #include <libelf.h>
 #include <byteswap.h>
 #include <getopt.h>
+#include <lzo/lzo1x.h>
 #include "common.h"
 #include "dwarf_info.h"
 #include "diskdump_mod.h"
@@ -767,6 +768,7 @@ struct DumpInfo {
        int             num_dump_level;      /* number of dump level */
        int             array_dump_level[NUM_ARRAY_DUMP_LEVEL];
        int             flag_compress;       /* flag of compression */
+       int             flag_lzo_support;    /* flag of LZO compression support 
*/
        int             flag_elf_dumpfile;   /* flag of creating ELF dumpfile */
        int             flag_generate_vmcoreinfo;/* flag of generating 
vmcoreinfo file */
        int             flag_read_vmcoreinfo;    /* flag of reading vmcoreinfo 
file */


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to