* [PATCH] add support for loading lzma compressed kernels
@ 2009-11-15 23:53 Florian Fainelli
2009-11-16 13:37 ` wilbur.chan
2009-11-17 3:04 ` Simon Horman
0 siblings, 2 replies; 10+ messages in thread
From: Florian Fainelli @ 2009-11-15 23:53 UTC (permalink / raw)
To: kexec; +Cc: Eric W. Biederman
Hi Eric,
This patch allows one to load a lzma compressed kernel using kexec -l.
As I wanted the lzma code to be very similar to the existing
zlib slurp_decompress I took lzread and associated routines
from the cpio lzma support. Tested on my x86 laptop using the
following commands:
lzma e bzImage bzImage.lzma
kexec -l bzImage.lzma
Having lzma support is particularly useful on some embedded
systems on which we have the kernel already lzma compressed
and available on a mtd partition.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
--
diff -urN kexec-tools-2.0.1/configure.ac kexec-tools-2.0.1.lzma/configure.ac
--- kexec-tools-2.0.1/configure.ac 2009-08-13 01:28:04.000000000 +0200
+++ kexec-tools-2.0.1.lzma/configure.ac 2009-11-16 00:30:42.000000000 +0100
@@ -79,6 +79,9 @@
AC_ARG_WITH([zlib], AC_HELP_STRING([--without-zlib],[disable zlib support]),
[ with_zlib="$withval"], [ with_zlib=yes ] )
+AC_ARG_WITH([lzma], AC_HELP_STRING([--without-lzma],[disable lzma support]),
+ [ with_lzma="$withval"], [ with_lzma=yes ] )
+
AC_ARG_WITH([xen], AC_HELP_STRING([--without-xen],
[disable extended xen support]), [ with_xen="$withval"], [ with_xen=yes ] )
@@ -142,6 +145,12 @@
AC_MSG_NOTICE([zlib support disabled])))
fi
+dnl See if I have a usable copy of lzma available
+if test "$with_lzma" = yes ; then
+ AC_CHECK_HEADER(lzma.h,
+ AC_CHECK_LIB(lzma, lzma_code_, ,
+ AC_MSG_NOTICE([lzma support disabled])))
+
dnl find Xen control stack libraries
if test "$with_xen" = yes ; then
AC_CHECK_HEADER(xenctrl.h,
diff -urN kexec-tools-2.0.1/include/kexec_lzma.h kexec-tools-2.0.1.lzma/include/kexec_lzma.h
--- kexec-tools-2.0.1/include/kexec_lzma.h 1970-01-01 01:00:00.000000000 +0100
+++ kexec-tools-2.0.1.lzma/include/kexec_lzma.h 2009-11-16 00:45:23.000000000 +0100
@@ -0,0 +1,24 @@
+#ifndef __KEXEC_LZMA_H
+#define __KEXEC_LZMA_H
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <lzma.h>
+
+#define kBufferSize (1 << 15)
+
+typedef struct lzfile {
+ uint8_t buf[kBufferSize];
+ lzma_stream strm;
+ FILE *file;
+ int encoding;
+ int eof;
+} LZFILE;
+
+LZFILE *lzopen(const char *path, const char *mode);
+int lzclose(LZFILE *lzfile);
+ssize_t lzread(LZFILE *lzfile, void *buf, size_t len);
+
+#endif /* __KEXEC_LZMA_H */
Files kexec-tools-2.0.1/kexec/.kexec.c.swo and kexec-tools-2.0.1.lzma/kexec/.kexec.c.swo differ
diff -urN kexec-tools-2.0.1/kexec/Makefile kexec-tools-2.0.1.lzma/kexec/Makefile
--- kexec-tools-2.0.1/kexec/Makefile 2008-10-09 00:32:14.000000000 +0200
+++ kexec-tools-2.0.1.lzma/kexec/Makefile 2009-11-15 20:36:37.000000000 +0100
@@ -22,6 +22,7 @@
KEXEC_SRCS += kexec/crashdump.c
KEXEC_SRCS += kexec/crashdump-xen.c
KEXEC_SRCS += kexec/phys_arch.c
+KEXEC_SRCS += kexec/lzma.c
KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C)
diff -urN kexec-tools-2.0.1/kexec/kexec.c kexec-tools-2.0.1.lzma/kexec/kexec.c
--- kexec-tools-2.0.1/kexec/kexec.c 2009-03-18 09:38:55.000000000 +0100
+++ kexec-tools-2.0.1.lzma/kexec/kexec.c 2009-11-16 00:50:37.000000000 +0100
@@ -41,6 +41,9 @@
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
+#ifdef HAVE_LIBLZMA
+#include <kexec_lzma.h>
+#endif
#include <sha256.h>
#include "kexec.h"
#include "kexec-syscall.h"
@@ -609,6 +612,47 @@
*r_size = size;
return buf;
}
+#elif defined (HAVE_LIBLZMA)
+char *slurp_decompress_file(const char *filename, off_t *r_size)
+{
+ LZFILE *fp;
+ char *buf;
+ off_t size, allocated;
+ ssize_t result;
+
+ if (!filename) {
+ *r_size = 0;
+ return 0;
+ }
+ fp = lzopen(filename, "rb");
+ if (fp == 0) {
+ die("Cannot open `%s': %s\n", filename);
+ }
+ size = 0;
+ allocated = 65536;
+ buf = xmalloc(allocated);
+ do {
+ if (size == allocated) {
+ allocated <<= 1;
+ buf = xrealloc(buf, allocated);
+ }
+ result = lzread(fp, buf + size, allocated - size);
+ if (result < 0) {
+ if ((errno == EINTR) || (errno == EAGAIN))
+ continue;
+
+ die ("read on %s of %ld bytes failed\n",
+ filename, (allocated - size) + 0UL);
+ }
+ size += result;
+ } while(result > 0);
+ result = lzclose(fp);
+ if (result != LZMA_OK) {
+ die ("Close of %s failed\n", filename);
+ }
+ *r_size = size;
+ return buf;
+}
#else
char *slurp_decompress_file(const char *filename, off_t *r_size)
{
diff -urN kexec-tools-2.0.1/kexec/lzma.c kexec-tools-2.0.1.lzma/kexec/lzma.c
--- kexec-tools-2.0.1/kexec/lzma.c 1970-01-01 01:00:00.000000000 +0100
+++ kexec-tools-2.0.1.lzma/kexec/lzma.c 2009-11-16 00:44:56.000000000 +0100
@@ -0,0 +1,132 @@
+#include <sys/types.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+#include <lzma.h>
+#include <kexec_lzma.h>
+
+#ifdef HAVE_LIBLZMA
+static LZFILE *lzopen_internal(const char *path, const char *mode, int fd)
+{
+ int level = 5;
+ int encoding = 0;
+ FILE *fp;
+ LZFILE *lzfile;
+ lzma_ret ret;
+ lzma_stream lzma_strm_tmp = LZMA_STREAM_INIT;
+
+ for (; *mode; mode++) {
+ if (*mode == 'w')
+ encoding = 1;
+ else if (*mode == 'r')
+ encoding = 0;
+ else if (*mode >= '1' && *mode <= '9')
+ level = *mode - '0';
+ }
+ if (fd != -1)
+ fp = fdopen(fd, encoding ? "w" : "r");
+ else
+ fp = fopen(path, encoding ? "w" : "r");
+ if (!fp)
+ return NULL;
+
+ lzfile = calloc(1, sizeof(*lzfile));
+
+ if (!lzfile) {
+ fclose(fp);
+ return NULL;
+ }
+
+ lzfile->file = fp;
+ lzfile->encoding = encoding;
+ lzfile->eof = 0;
+ lzfile->strm = lzma_strm_tmp;
+ if (encoding) {
+ lzma_options_lzma opt_lzma;
+ if (lzma_lzma_preset(&opt_lzma, level - 1))
+ return NULL;
+ ret = lzma_alone_encoder(&lzfile->strm, &opt_lzma);
+ } else {
+ ret = lzma_auto_decoder(&lzfile->strm,
+ UINT64_C(64) * 1024 * 1024, 0);
+ }
+ if (ret != LZMA_OK) {
+ fclose(fp);
+ free(lzfile);
+ return NULL;
+ }
+ return lzfile;
+}
+
+LZFILE *lzopen(const char *path, const char *mode)
+{
+ return lzopen_internal(path, mode, -1);
+}
+
+int lzclose(LZFILE *lzfile)
+{
+ lzma_ret ret;
+ int n;
+
+ if (!lzfile)
+ return -1;
+
+ if (lzfile->encoding) {
+ for (;;) {
+ lzfile->strm.avail_out = kBufferSize;
+ lzfile->strm.next_out = lzfile->buf;
+ ret = lzma_code(&lzfile->strm, LZMA_FINISH);
+ if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+ return -1;
+ n = kBufferSize - lzfile->strm.avail_out;
+ if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n)
+ return -1;
+ if (ret == LZMA_STREAM_END)
+ break;
+ }
+ }
+ lzma_end(&lzfile->strm);
+
+ return fclose(lzfile->file);
+ free(lzfile);
+}
+
+ssize_t lzread(LZFILE *lzfile, void *buf, size_t len)
+{
+ lzma_ret ret;
+ int eof = 0;
+
+ if (!lzfile || lzfile->encoding)
+ return -1;
+
+ if (lzfile->eof)
+ return 0;
+
+ lzfile->strm.next_out = buf;
+ lzfile->strm.avail_out = len;
+
+ for (;;) {
+ if (!lzfile->strm.avail_in) {
+ lzfile->strm.next_in = lzfile->buf;
+ lzfile->strm.avail_in = fread(lzfile->buf, 1, kBufferSize, lzfile->file);
+ if (!lzfile->strm.avail_in)
+ eof = 1;
+ }
+
+ ret = lzma_code(&lzfile->strm, LZMA_RUN);
+ if (ret == LZMA_STREAM_END) {
+ lzfile->eof = 1;
+ return len - lzfile->strm.avail_out;
+ }
+
+ if (ret != LZMA_OK)
+ return -1;
+
+ if (!lzfile->strm.avail_out)
+ return len;
+
+ if (eof)
+ return -1;
+ }
+}
+#endif /* HAVE_LIBLZMA */
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-15 23:53 [PATCH] add support for loading lzma compressed kernels Florian Fainelli @ 2009-11-16 13:37 ` wilbur.chan 2009-11-17 3:04 ` Simon Horman 1 sibling, 0 replies; 10+ messages in thread From: wilbur.chan @ 2009-11-16 13:37 UTC (permalink / raw) To: Florian Fainelli; +Cc: kexec 2009/11/16 Florian Fainelli <florian@openwrt.org> > > Hi Eric, > > This patch allows one to load a lzma compressed kernel using kexec -l. > As I wanted the lzma code to be very similar to the existing > zlib slurp_decompress I took lzread and associated routines > from the cpio lzma support. Tested on my x86 laptop using the > following commands: > > lzma e bzImage bzImage.lzma > kexec -l bzImage.lzma > > Having lzma support is particularly useful on some embedded > systems on which we have the kernel already lzma compressed > and available on a mtd partition. Good. btw, is there any solution to uImage format ? :D _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-15 23:53 [PATCH] add support for loading lzma compressed kernels Florian Fainelli 2009-11-16 13:37 ` wilbur.chan @ 2009-11-17 3:04 ` Simon Horman 2009-11-17 14:08 ` Florian Fainelli 1 sibling, 1 reply; 10+ messages in thread From: Simon Horman @ 2009-11-17 3:04 UTC (permalink / raw) To: Florian Fainelli; +Cc: kexec, Eric W. Biederman On Mon, Nov 16, 2009 at 12:53:06AM +0100, Florian Fainelli wrote: > Hi Eric, > > This patch allows one to load a lzma compressed kernel using kexec -l. > As I wanted the lzma code to be very similar to the existing > zlib slurp_decompress I took lzread and associated routines > from the cpio lzma support. Tested on my x86 laptop using the > following commands: > > lzma e bzImage bzImage.lzma > kexec -l bzImage.lzma > > Having lzma support is particularly useful on some embedded > systems on which we have the kernel already lzma compressed > and available on a mtd partition. > > Signed-off-by: Florian Fainelli <florian@openwrt.org> > -- > diff -urN kexec-tools-2.0.1/configure.ac kexec-tools-2.0.1.lzma/configure.ac > --- kexec-tools-2.0.1/configure.ac 2009-08-13 01:28:04.000000000 +0200 > +++ kexec-tools-2.0.1.lzma/configure.ac 2009-11-16 00:30:42.000000000 +0100 > @@ -79,6 +79,9 @@ > AC_ARG_WITH([zlib], AC_HELP_STRING([--without-zlib],[disable zlib support]), > [ with_zlib="$withval"], [ with_zlib=yes ] ) > > +AC_ARG_WITH([lzma], AC_HELP_STRING([--without-lzma],[disable lzma support]), > + [ with_lzma="$withval"], [ with_lzma=yes ] ) > + > AC_ARG_WITH([xen], AC_HELP_STRING([--without-xen], > [disable extended xen support]), [ with_xen="$withval"], [ with_xen=yes ] ) > > @@ -142,6 +145,12 @@ > AC_MSG_NOTICE([zlib support disabled]))) > fi > > +dnl See if I have a usable copy of lzma available > +if test "$with_lzma" = yes ; then > + AC_CHECK_HEADER(lzma.h, > + AC_CHECK_LIB(lzma, lzma_code_, , Should lzma_code_ be lzma_code. The former doesn't seem to work with liblzma 4.999.9beta+20091016-1 from Debian. > + AC_MSG_NOTICE([lzma support disabled]))) The trailing "fi" line appears to be missing. > + > dnl find Xen control stack libraries > if test "$with_xen" = yes ; then > AC_CHECK_HEADER(xenctrl.h, > diff -urN kexec-tools-2.0.1/include/kexec_lzma.h kexec-tools-2.0.1.lzma/include/kexec_lzma.h > --- kexec-tools-2.0.1/include/kexec_lzma.h 1970-01-01 01:00:00.000000000 +0100 > +++ kexec-tools-2.0.1.lzma/include/kexec_lzma.h 2009-11-16 00:45:23.000000000 +0100 > @@ -0,0 +1,24 @@ > +#ifndef __KEXEC_LZMA_H > +#define __KEXEC_LZMA_H > + > +#include <sys/types.h> > +#include <stdio.h> > +#include <unistd.h> > +#include <inttypes.h> > +#include <lzma.h> > + > +#define kBufferSize (1 << 15) > + > +typedef struct lzfile { > + uint8_t buf[kBufferSize]; > + lzma_stream strm; > + FILE *file; > + int encoding; > + int eof; > +} LZFILE; > + > +LZFILE *lzopen(const char *path, const char *mode); > +int lzclose(LZFILE *lzfile); > +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); > + > +#endif /* __KEXEC_LZMA_H */ > Files kexec-tools-2.0.1/kexec/.kexec.c.swo and kexec-tools-2.0.1.lzma/kexec/.kexec.c.swo differ > diff -urN kexec-tools-2.0.1/kexec/Makefile kexec-tools-2.0.1.lzma/kexec/Makefile > --- kexec-tools-2.0.1/kexec/Makefile 2008-10-09 00:32:14.000000000 +0200 > +++ kexec-tools-2.0.1.lzma/kexec/Makefile 2009-11-15 20:36:37.000000000 +0100 > @@ -22,6 +22,7 @@ > KEXEC_SRCS += kexec/crashdump.c > KEXEC_SRCS += kexec/crashdump-xen.c > KEXEC_SRCS += kexec/phys_arch.c > +KEXEC_SRCS += kexec/lzma.c > > KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) > > diff -urN kexec-tools-2.0.1/kexec/kexec.c kexec-tools-2.0.1.lzma/kexec/kexec.c > --- kexec-tools-2.0.1/kexec/kexec.c 2009-03-18 09:38:55.000000000 +0100 > +++ kexec-tools-2.0.1.lzma/kexec/kexec.c 2009-11-16 00:50:37.000000000 +0100 > @@ -41,6 +41,9 @@ > #ifdef HAVE_LIBZ > #include <zlib.h> > #endif > +#ifdef HAVE_LIBLZMA > +#include <kexec_lzma.h> > +#endif > #include <sha256.h> > #include "kexec.h" > #include "kexec-syscall.h" > @@ -609,6 +612,47 @@ > *r_size = size; > return buf; > } > +#elif defined (HAVE_LIBLZMA) > +char *slurp_decompress_file(const char *filename, off_t *r_size) Does this imply that zlib compression isn't supported if lzma compression support is enabled? > +{ > + LZFILE *fp; > + char *buf; > + off_t size, allocated; > + ssize_t result; > + > + if (!filename) { > + *r_size = 0; > + return 0; > + } > + fp = lzopen(filename, "rb"); > + if (fp == 0) { > + die("Cannot open `%s': %s\n", filename); > + } > + size = 0; > + allocated = 65536; > + buf = xmalloc(allocated); > + do { > + if (size == allocated) { > + allocated <<= 1; > + buf = xrealloc(buf, allocated); > + } > + result = lzread(fp, buf + size, allocated - size); > + if (result < 0) { > + if ((errno == EINTR) || (errno == EAGAIN)) > + continue; > + > + die ("read on %s of %ld bytes failed\n", > + filename, (allocated - size) + 0UL); > + } > + size += result; > + } while(result > 0); > + result = lzclose(fp); > + if (result != LZMA_OK) { > + die ("Close of %s failed\n", filename); > + } > + *r_size = size; > + return buf; > +} > #else > char *slurp_decompress_file(const char *filename, off_t *r_size) > { > diff -urN kexec-tools-2.0.1/kexec/lzma.c kexec-tools-2.0.1.lzma/kexec/lzma.c > --- kexec-tools-2.0.1/kexec/lzma.c 1970-01-01 01:00:00.000000000 +0100 > +++ kexec-tools-2.0.1.lzma/kexec/lzma.c 2009-11-16 00:44:56.000000000 +0100 > @@ -0,0 +1,132 @@ > +#include <sys/types.h> > +#include <inttypes.h> > +#include <string.h> > +#include <stdlib.h> > +#include <lzma.h> > +#include <kexec_lzma.h> > + > +#ifdef HAVE_LIBLZMA #include <kexec_lzma.h> needs to be inside HAVE_LIBLZMA, it seems just as well to move the #ifdef to the top of the file. > +static LZFILE *lzopen_internal(const char *path, const char *mode, int fd) > +{ > + int level = 5; > + int encoding = 0; > + FILE *fp; > + LZFILE *lzfile; > + lzma_ret ret; > + lzma_stream lzma_strm_tmp = LZMA_STREAM_INIT; > + > + for (; *mode; mode++) { > + if (*mode == 'w') > + encoding = 1; > + else if (*mode == 'r') > + encoding = 0; > + else if (*mode >= '1' && *mode <= '9') > + level = *mode - '0'; > + } > + if (fd != -1) > + fp = fdopen(fd, encoding ? "w" : "r"); > + else > + fp = fopen(path, encoding ? "w" : "r"); > + if (!fp) > + return NULL; > + > + lzfile = calloc(1, sizeof(*lzfile)); > + > + if (!lzfile) { > + fclose(fp); > + return NULL; > + } > + > + lzfile->file = fp; > + lzfile->encoding = encoding; > + lzfile->eof = 0; > + lzfile->strm = lzma_strm_tmp; > + if (encoding) { > + lzma_options_lzma opt_lzma; > + if (lzma_lzma_preset(&opt_lzma, level - 1)) > + return NULL; > + ret = lzma_alone_encoder(&lzfile->strm, &opt_lzma); > + } else { > + ret = lzma_auto_decoder(&lzfile->strm, > + UINT64_C(64) * 1024 * 1024, 0); > + } > + if (ret != LZMA_OK) { > + fclose(fp); > + free(lzfile); > + return NULL; > + } > + return lzfile; > +} > + > +LZFILE *lzopen(const char *path, const char *mode) > +{ > + return lzopen_internal(path, mode, -1); > +} > + > +int lzclose(LZFILE *lzfile) > +{ > + lzma_ret ret; > + int n; > + > + if (!lzfile) > + return -1; > + > + if (lzfile->encoding) { > + for (;;) { > + lzfile->strm.avail_out = kBufferSize; > + lzfile->strm.next_out = lzfile->buf; > + ret = lzma_code(&lzfile->strm, LZMA_FINISH); > + if (ret != LZMA_OK && ret != LZMA_STREAM_END) > + return -1; > + n = kBufferSize - lzfile->strm.avail_out; > + if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n) > + return -1; > + if (ret == LZMA_STREAM_END) > + break; > + } > + } > + lzma_end(&lzfile->strm); > + > + return fclose(lzfile->file); > + free(lzfile); > +} > + > +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len) > +{ > + lzma_ret ret; > + int eof = 0; > + > + if (!lzfile || lzfile->encoding) > + return -1; > + > + if (lzfile->eof) > + return 0; > + > + lzfile->strm.next_out = buf; > + lzfile->strm.avail_out = len; > + > + for (;;) { > + if (!lzfile->strm.avail_in) { > + lzfile->strm.next_in = lzfile->buf; > + lzfile->strm.avail_in = fread(lzfile->buf, 1, kBufferSize, lzfile->file); > + if (!lzfile->strm.avail_in) > + eof = 1; > + } > + > + ret = lzma_code(&lzfile->strm, LZMA_RUN); > + if (ret == LZMA_STREAM_END) { > + lzfile->eof = 1; > + return len - lzfile->strm.avail_out; > + } > + > + if (ret != LZMA_OK) > + return -1; > + > + if (!lzfile->strm.avail_out) > + return len; > + > + if (eof) > + return -1; > + } > +} > +#endif /* HAVE_LIBLZMA */ > > _______________________________________________ > kexec mailing list > kexec@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/kexec _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-17 3:04 ` Simon Horman @ 2009-11-17 14:08 ` Florian Fainelli 2009-11-17 14:23 ` Florian Fainelli 0 siblings, 1 reply; 10+ messages in thread From: Florian Fainelli @ 2009-11-17 14:08 UTC (permalink / raw) To: kexec; +Cc: Simon Horman, Eric W. Biederman Hello Simon, On Tuesday 17 November 2009 04:04:38 Simon Horman wrote: > On Mon, Nov 16, 2009 at 12:53:06AM +0100, Florian Fainelli wrote: > > Hi Eric, > > > > This patch allows one to load a lzma compressed kernel using kexec -l. > > As I wanted the lzma code to be very similar to the existing > > zlib slurp_decompress I took lzread and associated routines > > from the cpio lzma support. Tested on my x86 laptop using the > > following commands: > > > > lzma e bzImage bzImage.lzma > > kexec -l bzImage.lzma > > > > Having lzma support is particularly useful on some embedded > > systems on which we have the kernel already lzma compressed > > and available on a mtd partition. > > > > Signed-off-by: Florian Fainelli <florian@openwrt.org> > > Should lzma_code_ be lzma_code. The former doesn't seem to work with > liblzma 4.999.9beta+20091016-1 from Debian. You are right it's actually lzma_code (without the trailing _). > > > + AC_MSG_NOTICE([lzma support disabled]))) > > The trailing "fi" line appears to be missing. Fixed too. [snip] > Does this imply that zlib compression isn't supported if > lzma compression support is enabled? Indeed, we might want to support both at runtime. Would you agree with the following proposal: - rename slurp_decompress_file to zlib/lzma_decompress_file - in case gzopen fails, do not die, but return NULL - test the return value of zlib_decompress_file and try lzma_decompress_file > > > +{ > > + LZFILE *fp; > > + char *buf; > > + off_t size, allocated; > > + ssize_t result; > > + > > + if (!filename) { > > + *r_size = 0; > > + return 0; > > + } > > + fp = lzopen(filename, "rb"); > > + if (fp == 0) { > > + die("Cannot open `%s': %s\n", filename); > > + } > > + size = 0; > > + allocated = 65536; > > + buf = xmalloc(allocated); > > + do { > > + if (size == allocated) { > > + allocated <<= 1; > > + buf = xrealloc(buf, allocated); > > + } > > + result = lzread(fp, buf + size, allocated - size); > > + if (result < 0) { > > + if ((errno == EINTR) || (errno == EAGAIN)) > > + continue; > > + > > + die ("read on %s of %ld bytes failed\n", > > + filename, (allocated - size) + 0UL); > > + } > > + size += result; > > + } while(result > 0); > > + result = lzclose(fp); > > + if (result != LZMA_OK) { > > + die ("Close of %s failed\n", filename); > > + } > > + *r_size = size; > > + return buf; > > +} > > #else > > char *slurp_decompress_file(const char *filename, off_t *r_size) > > { > > diff -urN kexec-tools-2.0.1/kexec/lzma.c > > kexec-tools-2.0.1.lzma/kexec/lzma.c --- > > kexec-tools-2.0.1/kexec/lzma.c 1970-01-01 01:00:00.000000000 +0100 +++ > > kexec-tools-2.0.1.lzma/kexec/lzma.c 2009-11-16 00:44:56.000000000 +0100 > > @@ -0,0 +1,132 @@ > > +#include <sys/types.h> > > +#include <inttypes.h> > > +#include <string.h> > > +#include <stdlib.h> > > +#include <lzma.h> > > +#include <kexec_lzma.h> > > + > > +#ifdef HAVE_LIBLZMA > > #include <kexec_lzma.h> needs to be inside HAVE_LIBLZMA, > it seems just as well to move the #ifdef to the top of the file. Fixed. -- WBR, Florian _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-17 14:08 ` Florian Fainelli @ 2009-11-17 14:23 ` Florian Fainelli 2009-11-18 3:55 ` Simon Horman 0 siblings, 1 reply; 10+ messages in thread From: Florian Fainelli @ 2009-11-17 14:23 UTC (permalink / raw) To: kexec; +Cc: Simon Horman, Eric W. Biederman On Tuesday 17 November 2009 15:08:29 Florian Fainelli wrote: > Hello Simon, > > On Tuesday 17 November 2009 04:04:38 Simon Horman wrote: > > On Mon, Nov 16, 2009 at 12:53:06AM +0100, Florian Fainelli wrote: > > > Hi Eric, > > > > > > This patch allows one to load a lzma compressed kernel using kexec -l. > > > As I wanted the lzma code to be very similar to the existing > > > zlib slurp_decompress I took lzread and associated routines > > > from the cpio lzma support. Tested on my x86 laptop using the > > > following commands: > > > > > > lzma e bzImage bzImage.lzma > > > kexec -l bzImage.lzma > > > > > > Having lzma support is particularly useful on some embedded > > > systems on which we have the kernel already lzma compressed > > > and available on a mtd partition. > > > > > > Signed-off-by: Florian Fainelli <florian@openwrt.org> > > > > Should lzma_code_ be lzma_code. The former doesn't seem to work with > > liblzma 4.999.9beta+20091016-1 from Debian. > > You are right it's actually lzma_code (without the trailing _). > > > > + AC_MSG_NOTICE([lzma support disabled]))) > > > > The trailing "fi" line appears to be missing. > > Fixed too. > [snip] > > > Does this imply that zlib compression isn't supported if > > lzma compression support is enabled? > > Indeed, we might want to support both at runtime. Would you agree with the > following proposal: > > - rename slurp_decompress_file to zlib/lzma_decompress_file > - in case gzopen fails, do not die, but return NULL > - test the return value of zlib_decompress_file and try > lzma_decompress_file We would also have to modify the call sites of slurp_decompress file this might become pretty heavy if we support more decompression algorithms. What do you think? -- WBR, Florian _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-17 14:23 ` Florian Fainelli @ 2009-11-18 3:55 ` Simon Horman 2009-11-18 23:17 ` Florian Fainelli 0 siblings, 1 reply; 10+ messages in thread From: Simon Horman @ 2009-11-18 3:55 UTC (permalink / raw) To: Florian Fainelli; +Cc: kexec, Eric W. Biederman On Tue, Nov 17, 2009 at 03:23:15PM +0100, Florian Fainelli wrote: > On Tuesday 17 November 2009 15:08:29 Florian Fainelli wrote: > > Hello Simon, > > > > On Tuesday 17 November 2009 04:04:38 Simon Horman wrote: > > > On Mon, Nov 16, 2009 at 12:53:06AM +0100, Florian Fainelli wrote: > > > > Hi Eric, > > > > > > > > This patch allows one to load a lzma compressed kernel using kexec -l. > > > > As I wanted the lzma code to be very similar to the existing > > > > zlib slurp_decompress I took lzread and associated routines > > > > from the cpio lzma support. Tested on my x86 laptop using the > > > > following commands: > > > > > > > > lzma e bzImage bzImage.lzma > > > > kexec -l bzImage.lzma > > > > > > > > Having lzma support is particularly useful on some embedded > > > > systems on which we have the kernel already lzma compressed > > > > and available on a mtd partition. > > > > > > > > Signed-off-by: Florian Fainelli <florian@openwrt.org> > > > > > > Should lzma_code_ be lzma_code. The former doesn't seem to work with > > > liblzma 4.999.9beta+20091016-1 from Debian. > > > > You are right it's actually lzma_code (without the trailing _). > > > > > > + AC_MSG_NOTICE([lzma support disabled]))) > > > > > > The trailing "fi" line appears to be missing. > > > > Fixed too. > > [snip] > > > > > Does this imply that zlib compression isn't supported if > > > lzma compression support is enabled? > > > > Indeed, we might want to support both at runtime. Would you agree with the > > following proposal: > > > > - rename slurp_decompress_file to zlib/lzma_decompress_file > > - in case gzopen fails, do not die, but return NULL > > - test the return value of zlib_decompress_file and try > > lzma_decompress_file Something along those lines sounds entirely reasonable to me. > We would also have to modify the call sites of slurp_decompress file this might > become pretty heavy if we support more decompression algorithms. What do you > think? Perhaps slurp_decompress could be a wrapper which tries each algorithm in turn as necessary? Also, I'd like to get rid of the #ifdef around what is currently slurp_decompress_file() if possible. My idea would be to move zlib_decompress_file and lzma_decompress_file into, for instance zlib.c and lzma.c respectively and have zlib.h and lzma.h provide more-or-less null functions for the case where the algorithm in question isn't supported. _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-18 3:55 ` Simon Horman @ 2009-11-18 23:17 ` Florian Fainelli 2009-11-19 0:03 ` Eric W. Biederman 0 siblings, 1 reply; 10+ messages in thread From: Florian Fainelli @ 2009-11-18 23:17 UTC (permalink / raw) To: Simon Horman; +Cc: kexec, Eric W. Biederman Hello Simon, Le mercredi 18 novembre 2009 04:55:18, Simon Horman a écrit : > On Tue, Nov 17, 2009 at 03:23:15PM +0100, Florian Fainelli wrote: > > On Tuesday 17 November 2009 15:08:29 Florian Fainelli wrote: > > > Hello Simon, > > > > > > On Tuesday 17 November 2009 04:04:38 Simon Horman wrote: > > > > On Mon, Nov 16, 2009 at 12:53:06AM +0100, Florian Fainelli wrote: > > > > > Hi Eric, > > > > > > > > > > This patch allows one to load a lzma compressed kernel using kexec > > > > > -l. As I wanted the lzma code to be very similar to the existing > > > > > zlib slurp_decompress I took lzread and associated routines from > > > > > the cpio lzma support. Tested on my x86 laptop using the following > > > > > commands: > > > > > > > > > > lzma e bzImage bzImage.lzma > > > > > kexec -l bzImage.lzma > > > > > > > > > > Having lzma support is particularly useful on some embedded > > > > > systems on which we have the kernel already lzma compressed > > > > > and available on a mtd partition. > > > > > > > > > > Signed-off-by: Florian Fainelli <florian@openwrt.org> > > > > > > > > Should lzma_code_ be lzma_code. The former doesn't seem to work with > > > > liblzma 4.999.9beta+20091016-1 from Debian. > > > > > > You are right it's actually lzma_code (without the trailing _). > > > > > > > > + AC_MSG_NOTICE([lzma support disabled]))) > > > > > > > > The trailing "fi" line appears to be missing. > > > > > > Fixed too. > > > [snip] > > > > > > > Does this imply that zlib compression isn't supported if > > > > lzma compression support is enabled? > > > > > > Indeed, we might want to support both at runtime. Would you agree with > > > the following proposal: > > > > > > - rename slurp_decompress_file to zlib/lzma_decompress_file > > > - in case gzopen fails, do not die, but return NULL > > > - test the return value of zlib_decompress_file and try > > > lzma_decompress_file > > Something along those lines sounds entirely reasonable to me. > > > We would also have to modify the call sites of slurp_decompress file this > > might become pretty heavy if we support more decompression algorithms. > > What do you think? > > Perhaps slurp_decompress could be a wrapper which tries each algorithm in > turn as necessary? > > Also, I'd like to get rid of the #ifdef around what is currently > slurp_decompress_file() if possible. My idea would be to move > zlib_decompress_file and lzma_decompress_file into, for instance > zlib.c and lzma.c respectively and have zlib.h and lzma.h provide > more-or-less null functions for the case where the algorithm > in question isn't supported. Please find below a version which should address your comments. Thanks for reviewing the patch. -- From: Florian Fainelli <florian@openwrt.org> Subject: [PATCH] add support for loading lzma compressed kernels This patch allows one to load a lzma compressed kernel using kexec -l. As I wanted the lzma code to be very similar to the existing zlib slurp_decompress I took lzread and associated routines from the cpio lzma support. Tested on my x86 laptop using the following commands: lzma e bzImage bzImage.lzma kexec -l bzImage.lzma Having lzma support is particularly useful on some embedded systems on which we have the kernel already lzma compressed and available on a mtd partition. Signed-off-by: Florian Fainelli <florian@openwrt.org> --- diff -urN kexec-tools-2.0.1/configure.ac kexec-tools-2.0.1.lzma/configure.ac --- kexec-tools-2.0.1/configure.ac 2009-11-18 23:11:36.000000000 +0100 +++ kexec-tools-2.0.1.lzma/configure.ac 2009-11-18 23:11:21.000000000 +0100 @@ -79,6 +79,9 @@ AC_ARG_WITH([zlib], AC_HELP_STRING([--without-zlib],[disable zlib support]), [ with_zlib="$withval"], [ with_zlib=yes ] ) +AC_ARG_WITH([lzma], AC_HELP_STRING([--without-lzma],[disable lzma support]), + [ with_lzma="$withval"], [ with_lzma=yes ] ) + AC_ARG_WITH([xen], AC_HELP_STRING([--without-xen], [disable extended xen support]), [ with_xen="$withval"], [ with_xen=yes ] ) @@ -142,6 +145,13 @@ AC_MSG_NOTICE([zlib support disabled]))) fi +dnl See if I have a usable copy of lzma available +if test "$with_lzma" = yes ; then + AC_CHECK_HEADER(lzma.h, + AC_CHECK_LIB(lzma, lzma_code, , + AC_MSG_NOTICE([lzma support disabled]))) +fi + dnl find Xen control stack libraries if test "$with_xen" = yes ; then AC_CHECK_HEADER(xenctrl.h, diff -urN kexec-tools-2.0.1/kexec/Makefile kexec-tools-2.0.1.lzma/kexec/Makefile --- kexec-tools-2.0.1/kexec/Makefile 2009-11-18 23:11:37.000000000 +0100 +++ kexec-tools-2.0.1.lzma/kexec/Makefile 2009-11-18 23:15:21.000000000 +0100 @@ -22,6 +22,8 @@ KEXEC_SRCS += kexec/crashdump.c KEXEC_SRCS += kexec/crashdump-xen.c KEXEC_SRCS += kexec/phys_arch.c +KEXEC_SRCS += kexec/lzma.c +KEXEC_SRCS += kexec/zlib.c KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) diff -urN kexec-tools-2.0.1/kexec/kexec-lzma.h kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h --- kexec-tools-2.0.1/kexec/kexec-lzma.h 1970-01-01 01:00:00.000000000 +0100 +++ kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h 2009-11-19 00:06:24.000000000 +0100 @@ -0,0 +1,29 @@ +#ifndef __KEXEC_LZMA_H +#define __KEXEC_LZMA_H + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <inttypes.h> +#include <lzma.h> + +#include "config.h" + +#ifdef HAVE_LIBLZMA +#define kBufferSize (1 << 15) + +typedef struct lzfile { + uint8_t buf[kBufferSize]; + lzma_stream strm; + FILE *file; + int encoding; + int eof; +} LZFILE; + +LZFILE *lzopen(const char *path, const char *mode); +int lzclose(LZFILE *lzfile); +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); +#endif /* HAVE_LIBLZMA */ + +char *lzma_decompress_file(const char *filename, off_t *r_size); +#endif /* __KEXEC_LZMA_H */ diff -urN kexec-tools-2.0.1/kexec/kexec-zlib.h kexec-tools-2.0.1.lzma/kexec/kexec-zlib.h --- kexec-tools-2.0.1/kexec/kexec-zlib.h 1970-01-01 01:00:00.000000000 +0100 +++ kexec-tools-2.0.1.lzma/kexec/kexec-zlib.h 2009-11-19 00:04:38.000000000 +0100 @@ -0,0 +1,10 @@ +#ifndef __KEXEC_ZLIB_H +#define __KEXEC_ZLIB_H + +#include <stdio.h> +#include <sys/types.h> + +#include "config.h" + +char *zlib_decompress_file(const char *filename, off_t *r_size); +#endif /* __KEXEC_ZLIB_H */ diff -urN kexec-tools-2.0.1/kexec/kexec.c kexec-tools-2.0.1.lzma/kexec/kexec.c --- kexec-tools-2.0.1/kexec/kexec.c 2009-11-18 23:11:45.000000000 +0100 +++ kexec-tools-2.0.1.lzma/kexec/kexec.c 2009-11-18 23:19:46.000000000 +0100 @@ -38,14 +38,13 @@ #include "config.h" -#ifdef HAVE_LIBZ -#include <zlib.h> -#endif #include <sha256.h> #include "kexec.h" #include "kexec-syscall.h" #include "kexec-elf.h" #include "kexec-sha256.h" +#include "kexec-zlib.h" +#include "kexec-lzma.h" #include <arch/options.h> unsigned long long mem_min = 0; @@ -554,67 +553,18 @@ return buf; } -#if HAVE_LIBZ char *slurp_decompress_file(const char *filename, off_t *r_size) { - gzFile fp; - int errnum; - const char *msg; - char *buf; - off_t size, allocated; - ssize_t result; - - if (!filename) { - *r_size = 0; - return 0; - } - fp = gzopen(filename, "rb"); - if (fp == 0) { - msg = gzerror(fp, &errnum); - if (errnum == Z_ERRNO) { - msg = strerror(errno); - } - die("Cannot open `%s': %s\n", filename, msg); - } - size = 0; - allocated = 65536; - buf = xmalloc(allocated); - do { - if (size == allocated) { - allocated <<= 1; - buf = xrealloc(buf, allocated); - } - result = gzread(fp, buf + size, allocated - size); - if (result < 0) { - if ((errno == EINTR) || (errno == EAGAIN)) - continue; + char *kernel_buf; - msg = gzerror(fp, &errnum); - if (errnum == Z_ERRNO) { - msg = strerror(errno); - } - die ("read on %s of %ld bytes failed: %s\n", - filename, (allocated - size) + 0UL, msg); - } - size += result; - } while(result > 0); - result = gzclose(fp); - if (result != Z_OK) { - msg = gzerror(fp, &errnum); - if (errnum == Z_ERRNO) { - msg = strerror(errno); - } - die ("Close of %s failed: %s\n", filename, msg); + kernel_buf = zlib_decompress_file(filename, r_size); + if (!kernel_buf) { + kernel_buf = lzma_decompress_file(filename, r_size); + if (!kernel_buf) + return slurp_file(filename, r_size); } - *r_size = size; - return buf; + return kernel_buf; } -#else -char *slurp_decompress_file(const char *filename, off_t *r_size) -{ - return slurp_file(filename, r_size); -} -#endif static void update_purgatory(struct kexec_info *info) { diff -urN kexec-tools-2.0.1/kexec/lzma.c kexec-tools-2.0.1.lzma/kexec/lzma.c --- kexec-tools-2.0.1/kexec/lzma.c 1970-01-01 01:00:00.000000000 +0100 +++ kexec-tools-2.0.1.lzma/kexec/lzma.c 2009-11-19 00:03:54.000000000 +0100 @@ -0,0 +1,187 @@ +#include "kexec-lzma.h" +#ifdef HAVE_LIBLZMA +#define _GNU_SOURCE +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <ctype.h> +#include <lzma.h> + +#include "kexec.h" + +static LZFILE *lzopen_internal(const char *path, const char *mode, int fd) +{ + int level = 5; + int encoding = 0; + FILE *fp; + LZFILE *lzfile; + lzma_ret ret; + lzma_stream lzma_strm_tmp = LZMA_STREAM_INIT; + + for (; *mode; mode++) { + if (*mode == 'w') + encoding = 1; + else if (*mode == 'r') + encoding = 0; + else if (*mode >= '1' && *mode <= '9') + level = *mode - '0'; + } + if (fd != -1) + fp = fdopen(fd, encoding ? "w" : "r"); + else + fp = fopen(path, encoding ? "w" : "r"); + if (!fp) + return NULL; + + lzfile = calloc(1, sizeof(*lzfile)); + + if (!lzfile) { + fclose(fp); + return NULL; + } + + lzfile->file = fp; + lzfile->encoding = encoding; + lzfile->eof = 0; + lzfile->strm = lzma_strm_tmp; + if (encoding) { + lzma_options_lzma opt_lzma; + if (lzma_lzma_preset(&opt_lzma, level - 1)) + return NULL; + ret = lzma_alone_encoder(&lzfile->strm, &opt_lzma); + } else { + ret = lzma_auto_decoder(&lzfile->strm, + UINT64_C(64) * 1024 * 1024, 0); + } + if (ret != LZMA_OK) { + fclose(fp); + free(lzfile); + return NULL; + } + return lzfile; +} + +LZFILE *lzopen(const char *path, const char *mode) +{ + return lzopen_internal(path, mode, -1); +} + +int lzclose(LZFILE *lzfile) +{ + lzma_ret ret; + int n; + + if (!lzfile) + return -1; + + if (lzfile->encoding) { + for (;;) { + lzfile->strm.avail_out = kBufferSize; + lzfile->strm.next_out = lzfile->buf; + ret = lzma_code(&lzfile->strm, LZMA_FINISH); + if (ret != LZMA_OK && ret != LZMA_STREAM_END) + return -1; + n = kBufferSize - lzfile->strm.avail_out; + if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n) + return -1; + if (ret == LZMA_STREAM_END) + break; + } + } + lzma_end(&lzfile->strm); + + return fclose(lzfile->file); + free(lzfile); +} + +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len) +{ + lzma_ret ret; + int eof = 0; + + if (!lzfile || lzfile->encoding) + return -1; + + if (lzfile->eof) + return 0; + + lzfile->strm.next_out = buf; + lzfile->strm.avail_out = len; + + for (;;) { + if (!lzfile->strm.avail_in) { + lzfile->strm.next_in = lzfile->buf; + lzfile->strm.avail_in = fread(lzfile->buf, 1, kBufferSize, lzfile->file); + if (!lzfile->strm.avail_in) + eof = 1; + } + + ret = lzma_code(&lzfile->strm, LZMA_RUN); + if (ret == LZMA_STREAM_END) { + lzfile->eof = 1; + return len - lzfile->strm.avail_out; + } + + if (ret != LZMA_OK) + return -1; + + if (!lzfile->strm.avail_out) + return len; + + if (eof) + return -1; + } +} + +char *lzma_decompress_file(const char *filename, off_t *r_size) +{ + LZFILE *fp; + char *buf; + off_t size, allocated; + ssize_t result; + + if (!filename) { + *r_size = 0; + return 0; + } + fp = lzopen(filename, "rb"); + if (fp == 0) { + die("Cannot open `%s': %s\n", filename); + } + size = 0; + allocated = 65536; + buf = xmalloc(allocated); + do { + if (size == allocated) { + allocated <<= 1; + buf = xrealloc(buf, allocated); + } + result = lzread(fp, buf + size, allocated - size); + if (result < 0) { + if ((errno == EINTR) || (errno == EAGAIN)) + continue; + + die ("read on %s of %ld bytes failed\n", + filename, (allocated - size) + 0UL); + } + size += result; + } while(result > 0); + result = lzclose(fp); + if (result != LZMA_OK) { + die ("Close of %s failed\n", filename); + } + *r_size = size; + return buf; +} +#else +char *lzma_decompress_file(const char *filename, off_t *r_size) +{ + return NULL; +} +#endif /* HAVE_LIBLZMA */ diff -urN kexec-tools-2.0.1/kexec/zlib.c kexec-tools-2.0.1.lzma/kexec/zlib.c --- kexec-tools-2.0.1/kexec/zlib.c 1970-01-01 01:00:00.000000000 +0100 +++ kexec-tools-2.0.1.lzma/kexec/zlib.c 2009-11-19 00:05:28.000000000 +0100 @@ -0,0 +1,78 @@ +#include "kexec-zlib.h" +#ifdef HAVE_LIBZ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <ctype.h> +#include <zlib.h> + +#include "kexec.h" + +char *zlib_decompress_file(const char *filename, off_t *r_size) +{ + gzFile fp; + int errnum; + const char *msg; + char *buf; + off_t size, allocated; + ssize_t result; + + if (!filename) { + *r_size = 0; + return 0; + } + fp = gzopen(filename, "rb"); + if (fp == 0) { + msg = gzerror(fp, &errnum); + if (errnum == Z_ERRNO) { + msg = strerror(errno); + } + fprintf(stderr, "Cannot open `%s': %s\n", filename, msg); + return NULL; + } + size = 0; + allocated = 65536; + buf = xmalloc(allocated); + do { + if (size == allocated) { + allocated <<= 1; + buf = xrealloc(buf, allocated); + } + result = gzread(fp, buf + size, allocated - size); + if (result < 0) { + if ((errno == EINTR) || (errno == EAGAIN)) + continue; + + msg = gzerror(fp, &errnum); + if (errnum == Z_ERRNO) { + msg = strerror(errno); + } + die ("read on %s of %ld bytes failed: %s\n", + filename, (allocated - size) + 0UL, msg); + } + size += result; + } while(result > 0); + result = gzclose(fp); + if (result != Z_OK) { + msg = gzerror(fp, &errnum); + if (errnum == Z_ERRNO) { + msg = strerror(errno); + } + die ("Close of %s failed: %s\n", filename, msg); + } + *r_size = size; + return buf; +} +#else +char *zlib_decompress_file(const char *filename, off_t *r_size) +{ + return NULL; +} +#endif /* HAVE_ZLIB */ _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-18 23:17 ` Florian Fainelli @ 2009-11-19 0:03 ` Eric W. Biederman 2009-11-30 5:51 ` Simon Horman 0 siblings, 1 reply; 10+ messages in thread From: Eric W. Biederman @ 2009-11-19 0:03 UTC (permalink / raw) To: Florian Fainelli; +Cc: Simon Horman, kexec Florian Fainelli <florian@openwrt.org> writes: > Please find below a version which should address your comments. > Thanks for reviewing the patch. > -- > From: Florian Fainelli <florian@openwrt.org> > Subject: [PATCH] add support for loading lzma compressed kernels > > This patch allows one to load a lzma compressed kernel using kexec -l. > As I wanted the lzma code to be very similar to the existing > zlib slurp_decompress I took lzread and associated routines > from the cpio lzma support. Tested on my x86 laptop using the > following commands: > > lzma e bzImage bzImage.lzma > kexec -l bzImage.lzma > > Having lzma support is particularly useful on some embedded > systems on which we have the kernel already lzma compressed > and available on a mtd partition. Yes. I don't think it is particularly useful on x86 (as we have a decompressor built into the kernel) but on other arches it makes a lot of sense. A few minor comments inline. > diff -urN kexec-tools-2.0.1/kexec/kexec-lzma.h kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h > --- kexec-tools-2.0.1/kexec/kexec-lzma.h 1970-01-01 01:00:00.000000000 +0100 > +++ kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h 2009-11-19 00:06:24.000000000 +0100 > @@ -0,0 +1,29 @@ > +#ifndef __KEXEC_LZMA_H > +#define __KEXEC_LZMA_H > + > +#include <stdio.h> > +#include <sys/types.h> > +#include <unistd.h> > +#include <inttypes.h> > +#include <lzma.h> > + > +#include "config.h" > + > +#ifdef HAVE_LIBLZMA > +#define kBufferSize (1 << 15) > + > +typedef struct lzfile { > + uint8_t buf[kBufferSize]; > + lzma_stream strm; > + FILE *file; > + int encoding; > + int eof; > +} LZFILE; > + > +LZFILE *lzopen(const char *path, const char *mode); > +int lzclose(LZFILE *lzfile); > +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); I don't think we need any of these definitions in the header file. > +#endif /* HAVE_LIBLZMA */ > + > +char *lzma_decompress_file(const char *filename, off_t *r_size); Ideally the lzma_decompress_file stub would live here and would not even compile kexec/lzma.c if we don't have lzma. > +#endif /* __KEXEC_LZMA_H */ Eric _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-19 0:03 ` Eric W. Biederman @ 2009-11-30 5:51 ` Simon Horman 2009-11-30 10:08 ` Florian Fainelli 0 siblings, 1 reply; 10+ messages in thread From: Simon Horman @ 2009-11-30 5:51 UTC (permalink / raw) To: Eric W. Biederman; +Cc: kexec, Florian Fainelli On Wed, Nov 18, 2009 at 04:03:27PM -0800, Eric W. Biederman wrote: > Florian Fainelli <florian@openwrt.org> writes: > > > Please find below a version which should address your comments. > > Thanks for reviewing the patch. Thanks, Applied. > > -- > > From: Florian Fainelli <florian@openwrt.org> > > Subject: [PATCH] add support for loading lzma compressed kernels > > > > This patch allows one to load a lzma compressed kernel using kexec -l. > > As I wanted the lzma code to be very similar to the existing > > zlib slurp_decompress I took lzread and associated routines > > from the cpio lzma support. Tested on my x86 laptop using the > > following commands: > > > > lzma e bzImage bzImage.lzma > > kexec -l bzImage.lzma > > > > Having lzma support is particularly useful on some embedded > > systems on which we have the kernel already lzma compressed > > and available on a mtd partition. > > Yes. I don't think it is particularly useful on x86 (as we have > a decompressor built into the kernel) but on other arches > it makes a lot of sense. > > A few minor comments inline. > > > diff -urN kexec-tools-2.0.1/kexec/kexec-lzma.h kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h > > --- kexec-tools-2.0.1/kexec/kexec-lzma.h 1970-01-01 01:00:00.000000000 +0100 > > +++ kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h 2009-11-19 00:06:24.000000000 +0100 > > @@ -0,0 +1,29 @@ > > +#ifndef __KEXEC_LZMA_H > > +#define __KEXEC_LZMA_H > > + > > +#include <stdio.h> > > +#include <sys/types.h> > > +#include <unistd.h> > > +#include <inttypes.h> > > +#include <lzma.h> > > + > > +#include "config.h" > > + > > +#ifdef HAVE_LIBLZMA > > +#define kBufferSize (1 << 15) > > + > > +typedef struct lzfile { > > + uint8_t buf[kBufferSize]; > > + lzma_stream strm; > > + FILE *file; > > + int encoding; > > + int eof; > > +} LZFILE; > > + > > +LZFILE *lzopen(const char *path, const char *mode); > > +int lzclose(LZFILE *lzfile); > > +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); > > I don't think we need any of these definitions in the header file. > > > +#endif /* HAVE_LIBLZMA */ > > + > > +char *lzma_decompress_file(const char *filename, off_t *r_size); > > Ideally the lzma_decompress_file stub would live here and would not > even compile kexec/lzma.c if we don't have lzma. > > > +#endif /* __KEXEC_LZMA_H */ I have also applied the following change ---------------------------------------------------------------------- lzma: Move the bulk of kexec-lzma.h into lzma.c There isn't any need for anything in kexec-lzma.h other than a declaration of zlib_decompress_file(). Other being cleaner it also fixes a build problem when lzma support isn't being compiled in. $ make all i686-unknown-linux-gnu-gcc -Wall -Wextra -O2 -fomit-frame-pointer -pipe -fno-strict-aliasing -Wall -Wstrict-prototypes -I/home/horms/local/opt/crosstool/i686/gcc-3.4.5-glibc-2.3.6/i686-unknown-linux-gnu/include -I./include -I./util_lib/include -Iinclude/ -I./kexec/arch/i386/include -c -MD -o kexec/kexec.o kexec/kexec.c In file included from kexec/kexec.c:47: kexec/kexec-lzma.h:8:18: lzma.h: No such file or directory kexec/kexec.c: In function `locate_hole': kexec/kexec.c:203: warning: comparison between signed and unsigned It ought to be possible to just provide a stub for zlib_decompress_file() in kexec-lzma.h and not compile lzma.c at all in the case where lzma support isn't being compiled in. However I see no obvious way to do this with the existing build system. So I'd like to deal with that as a separate possible change. Changes as suggested by Eric W. Biederman. Cc: Florian Fainelli <florian@openwrt.org> Cc: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Simon Horman <horms@verge.net.au> Index: kexec-tools/kexec/kexec-lzma.h =================================================================== --- kexec-tools.orig/kexec/kexec-lzma.h 2009-11-30 16:43:38.000000000 +1100 +++ kexec-tools/kexec/kexec-lzma.h 2009-11-30 16:44:15.000000000 +1100 @@ -1,29 +1,8 @@ #ifndef __KEXEC_LZMA_H #define __KEXEC_LZMA_H -#include <stdio.h> #include <sys/types.h> -#include <unistd.h> -#include <inttypes.h> -#include <lzma.h> - -#include "config.h" - -#ifdef HAVE_LIBLZMA -#define kBufferSize (1 << 15) - -typedef struct lzfile { - uint8_t buf[kBufferSize]; - lzma_stream strm; - FILE *file; - int encoding; - int eof; -} LZFILE; - -LZFILE *lzopen(const char *path, const char *mode); -int lzclose(LZFILE *lzfile); -ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); -#endif /* HAVE_LIBLZMA */ char *lzma_decompress_file(const char *filename, off_t *r_size); + #endif /* __KEXEC_LZMA_H */ Index: kexec-tools/kexec/lzma.c =================================================================== --- kexec-tools.orig/kexec/lzma.c 2009-11-30 16:43:38.000000000 +1100 +++ kexec-tools/kexec/lzma.c 2009-11-30 16:44:15.000000000 +1100 @@ -1,4 +1,9 @@ +#include <unistd.h> +#include <sys/types.h> + #include "kexec-lzma.h" +#include "config.h" + #ifdef HAVE_LIBLZMA #define _GNU_SOURCE #include <stdio.h> @@ -7,14 +12,26 @@ #include <stdlib.h> #include <errno.h> #include <limits.h> -#include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> #include <ctype.h> #include <lzma.h> #include "kexec.h" +#define kBufferSize (1 << 15) + +typedef struct lzfile { + uint8_t buf[kBufferSize]; + lzma_stream strm; + FILE *file; + int encoding; + int eof; +} LZFILE; + +LZFILE *lzopen(const char *path, const char *mode); +int lzclose(LZFILE *lzfile); +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); + static LZFILE *lzopen_internal(const char *path, const char *mode, int fd) { int level = 5; _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] add support for loading lzma compressed kernels 2009-11-30 5:51 ` Simon Horman @ 2009-11-30 10:08 ` Florian Fainelli 0 siblings, 0 replies; 10+ messages in thread From: Florian Fainelli @ 2009-11-30 10:08 UTC (permalink / raw) To: Simon Horman; +Cc: kexec, Eric W. Biederman Hello Simon, On Monday 30 November 2009 06:51:39 Simon Horman wrote: > On Wed, Nov 18, 2009 at 04:03:27PM -0800, Eric W. Biederman wrote: > > Florian Fainelli <florian@openwrt.org> writes: > > > Please find below a version which should address your comments. > > > Thanks for reviewing the patch. > > Thanks, Applied. Oh thanks, I was about to respin with the changes Eric suggested. > > > > -- > > > From: Florian Fainelli <florian@openwrt.org> > > > Subject: [PATCH] add support for loading lzma compressed kernels > > > > > > This patch allows one to load a lzma compressed kernel using kexec -l. > > > As I wanted the lzma code to be very similar to the existing > > > zlib slurp_decompress I took lzread and associated routines > > > from the cpio lzma support. Tested on my x86 laptop using the > > > following commands: > > > > > > lzma e bzImage bzImage.lzma > > > kexec -l bzImage.lzma > > > > > > Having lzma support is particularly useful on some embedded > > > systems on which we have the kernel already lzma compressed > > > and available on a mtd partition. > > > > Yes. I don't think it is particularly useful on x86 (as we have > > a decompressor built into the kernel) but on other arches > > it makes a lot of sense. > > > > A few minor comments inline. > > > > > diff -urN kexec-tools-2.0.1/kexec/kexec-lzma.h > > > kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h --- > > > kexec-tools-2.0.1/kexec/kexec-lzma.h 1970-01-01 01:00:00.000000000 > > > +0100 +++ kexec-tools-2.0.1.lzma/kexec/kexec-lzma.h 2009-11-19 > > > 00:06:24.000000000 +0100 @@ -0,0 +1,29 @@ > > > +#ifndef __KEXEC_LZMA_H > > > +#define __KEXEC_LZMA_H > > > + > > > +#include <stdio.h> > > > +#include <sys/types.h> > > > +#include <unistd.h> > > > +#include <inttypes.h> > > > +#include <lzma.h> > > > + > > > +#include "config.h" > > > + > > > +#ifdef HAVE_LIBLZMA > > > +#define kBufferSize (1 << 15) > > > + > > > +typedef struct lzfile { > > > + uint8_t buf[kBufferSize]; > > > + lzma_stream strm; > > > + FILE *file; > > > + int encoding; > > > + int eof; > > > +} LZFILE; > > > + > > > +LZFILE *lzopen(const char *path, const char *mode); > > > +int lzclose(LZFILE *lzfile); > > > +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); > > > > I don't think we need any of these definitions in the header file. > > > > > +#endif /* HAVE_LIBLZMA */ > > > + > > > +char *lzma_decompress_file(const char *filename, off_t *r_size); > > > > Ideally the lzma_decompress_file stub would live here and would not > > even compile kexec/lzma.c if we don't have lzma. > > > > > +#endif /* __KEXEC_LZMA_H */ > > I have also applied the following change > > ---------------------------------------------------------------------- > > lzma: Move the bulk of kexec-lzma.h into lzma.c > > There isn't any need for anything in kexec-lzma.h other > than a declaration of zlib_decompress_file(). > > Other being cleaner it also fixes a build problem when > lzma support isn't being compiled in. > > $ make all > i686-unknown-linux-gnu-gcc -Wall -Wextra -O2 -fomit-frame-pointer -pipe > -fno-strict-aliasing -Wall -Wstrict-prototypes > -I/home/horms/local/opt/crosstool/i686/gcc-3.4.5-glibc-2.3.6/i686-unknown- > linux-gnu/include -I./include -I./util_lib/include -Iinclude/ > -I./kexec/arch/i386/include -c -MD -o kexec/kexec.o kexec/kexec.c > In file included from kexec/kexec.c:47: > kexec/kexec-lzma.h:8:18: lzma.h: No such file or directory > kexec/kexec.c: In function `locate_hole': > kexec/kexec.c:203: warning: comparison between signed and unsigned > > It ought to be possible to just provide a stub for zlib_decompress_file() > in kexec-lzma.h and not compile lzma.c at all in the case where > lzma support isn't being compiled in. However I see no obvious way > to do this with the existing build system. So I'd like to deal > with that as a separate possible change. > > Changes as suggested by Eric W. Biederman. > > Cc: Florian Fainelli <florian@openwrt.org> > Cc: Eric W. Biederman <ebiederm@xmission.com> > Signed-off-by: Simon Horman <horms@verge.net.au> > > Index: kexec-tools/kexec/kexec-lzma.h > =================================================================== > --- kexec-tools.orig/kexec/kexec-lzma.h 2009-11-30 16:43:38.000000000 +1100 > +++ kexec-tools/kexec/kexec-lzma.h 2009-11-30 16:44:15.000000000 +1100 > @@ -1,29 +1,8 @@ > #ifndef __KEXEC_LZMA_H > #define __KEXEC_LZMA_H > > -#include <stdio.h> > #include <sys/types.h> > -#include <unistd.h> > -#include <inttypes.h> > -#include <lzma.h> > - > -#include "config.h" > - > -#ifdef HAVE_LIBLZMA > -#define kBufferSize (1 << 15) > - > -typedef struct lzfile { > - uint8_t buf[kBufferSize]; > - lzma_stream strm; > - FILE *file; > - int encoding; > - int eof; > -} LZFILE; > - > -LZFILE *lzopen(const char *path, const char *mode); > -int lzclose(LZFILE *lzfile); > -ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); > -#endif /* HAVE_LIBLZMA */ > > char *lzma_decompress_file(const char *filename, off_t *r_size); > + > #endif /* __KEXEC_LZMA_H */ > Index: kexec-tools/kexec/lzma.c > =================================================================== > --- kexec-tools.orig/kexec/lzma.c 2009-11-30 16:43:38.000000000 +1100 > +++ kexec-tools/kexec/lzma.c 2009-11-30 16:44:15.000000000 +1100 > @@ -1,4 +1,9 @@ > +#include <unistd.h> > +#include <sys/types.h> > + > #include "kexec-lzma.h" > +#include "config.h" > + > #ifdef HAVE_LIBLZMA > #define _GNU_SOURCE > #include <stdio.h> > @@ -7,14 +12,26 @@ > #include <stdlib.h> > #include <errno.h> > #include <limits.h> > -#include <sys/types.h> > #include <sys/stat.h> > -#include <unistd.h> > #include <ctype.h> > #include <lzma.h> > > #include "kexec.h" > > +#define kBufferSize (1 << 15) > + > +typedef struct lzfile { > + uint8_t buf[kBufferSize]; > + lzma_stream strm; > + FILE *file; > + int encoding; > + int eof; > +} LZFILE; > + > +LZFILE *lzopen(const char *path, const char *mode); > +int lzclose(LZFILE *lzfile); > +ssize_t lzread(LZFILE *lzfile, void *buf, size_t len); > + > static LZFILE *lzopen_internal(const char *path, const char *mode, int fd) > { > int level = 5; > -- WBR, Florian _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-11-30 10:09 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-15 23:53 [PATCH] add support for loading lzma compressed kernels Florian Fainelli 2009-11-16 13:37 ` wilbur.chan 2009-11-17 3:04 ` Simon Horman 2009-11-17 14:08 ` Florian Fainelli 2009-11-17 14:23 ` Florian Fainelli 2009-11-18 3:55 ` Simon Horman 2009-11-18 23:17 ` Florian Fainelli 2009-11-19 0:03 ` Eric W. Biederman 2009-11-30 5:51 ` Simon Horman 2009-11-30 10:08 ` Florian Fainelli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox