[RFC] geom_uncompress(4) changes
Luiz Otavio O Souza
lists.br at gmail.com
Tue Apr 29 11:50:03 UTC 2014
Hi,
I've the attached changes to geom_uncompress(4) that modularise the
compression support.
It can now be built with support to mkuzip(8) or mkulzma(8) (or both)
independently.
It also make a lot easier to add the support to new compression
methods on geom_uncompress.
Now, building a kernel with 'options GEOM_UNCOMPRESS' (kept for
backward compatibility) adds only the support to read mkulzma images.
Building a kernel with 'options GEOM_UNCOMPRESS_UZIP' will add the
support to read mkuzip images.
The both options can be combined and they will produce a kernel which
can read both formats.
The geom_uncompress module is built with both compression methods
enabled keeping the backward compatibility.
I think we could eventually retire geom_uzip(8) as they are doing
essentially the same thing (with the same implementation and code...).
But this lets a lot of open questions regarding backward
compatibility.
Regards,
Luiz
-------------- next part --------------
Index: sys/conf/files
===================================================================
--- sys/conf/files (revision 265013)
+++ sys/conf/files (working copy)
@@ -2742,7 +2742,9 @@
geom/raid3/g_raid3_ctl.c optional geom_raid3
geom/shsec/g_shsec.c optional geom_shsec
geom/stripe/g_stripe.c optional geom_stripe
-geom/uncompress/g_uncompress.c optional geom_uncompress
+geom/uncompress/g_uncompress.c optional geom_uncompress | geom_uncompress_uzip
+geom/uncompress/g_uncompress_ulzma.c optional geom_uncompress
+geom/uncompress/g_uncompress_uzip.c optional geom_uncompress_uzip
contrib/xz-embedded/freebsd/xz_malloc.c \
optional xz_embedded | geom_uncompress \
compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/"
@@ -3139,7 +3141,7 @@
net/vnet.c optional vimage
net/zlib.c optional crypto | geom_uzip | ipsec | \
mxge | netgraph_deflate | \
- ddb_ctf | gzio | geom_uncompress
+ ddb_ctf | gzio | geom_uncompress_uzip
net80211/ieee80211.c optional wlan
net80211/ieee80211_acl.c optional wlan wlan_acl
net80211/ieee80211_action.c optional wlan
Index: sys/conf/options
===================================================================
--- sys/conf/options (revision 265013)
+++ sys/conf/options (working copy)
@@ -124,6 +124,7 @@
GEOM_STRIPE opt_geom.h
GEOM_SUNLABEL opt_geom.h
GEOM_UNCOMPRESS opt_geom.h
+GEOM_UNCOMPRESS_UZIP opt_geom.h
GEOM_UZIP opt_geom.h
GEOM_VIRSTOR opt_geom.h
GEOM_VOL opt_geom.h
Index: sys/geom/uncompress/g_uncompress.c
===================================================================
--- sys/geom/uncompress/g_uncompress.c (revision 265013)
+++ sys/geom/uncompress/g_uncompress.c (working copy)
@@ -27,15 +27,19 @@
/*
* GEOM UNCOMPRESS module - simple decompression module for use with read-only
- * copressed images maked by mkuzip(8) or mkulzma(8) utilities.
+ * compressed images created by mkuzip(8) or mkulzma(8) utilities.
*
- * To enable module in kernel config, put this line:
- * device geom_uncompress
+ * To enable uncompress support in kernel config, add these lines (for ulzma
+ * and uzip support respectively):
+ * options geom_uncompress
+ * options geom_uncompress_uzip
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_geom.h"
+
#include <sys/param.h>
#include <sys/bio.h>
#include <sys/endian.h>
@@ -47,10 +51,8 @@
#include <sys/systm.h>
#include <geom/geom.h>
+#include <geom/uncompress/g_uncompress.h>
-#include <net/zlib.h>
-#include <contrib/xz-embedded/linux/include/linux/xz.h>
-
#ifdef GEOM_UNCOMPRESS_DEBUG
#define DPRINTF(a) printf a
extern int g_debugflags;
@@ -58,12 +60,10 @@
#define DPRINTF(a)
#endif
-static MALLOC_DEFINE(M_GEOM_UNCOMPRESS, "geom_uncompress",
+MALLOC_DEFINE(M_GEOM_UNCOMPRESS, "geom_uncompress",
"GEOM UNCOMPRESS data structures");
#define UNCOMPRESS_CLASS_NAME "UNCOMPRESS"
-#define GEOM_UZIP_MAJVER '2'
-#define GEOM_ULZMA_MAJVER '3'
/*
* Maximum allowed valid block size (to prevent foot-shooting)
@@ -71,28 +71,17 @@
#define MAX_BLKSZ (MAXPHYS)
/*
- * Integer values (block size, number of blocks, offsets)
- * are stored in big-endian (network) order on disk and struct cloop_header
- * and in native order in struct g_uncompress_softc
+ * Integer values (block size, number of blocks, offsets) are stored in native
+ * order in struct g_uncompress_softc.
*/
-#define CLOOP_MAGIC_LEN 128
static char CLOOP_MAGIC_START[] = "#!/bin/sh\n";
-struct cloop_header {
- char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
- uint32_t blksz; /* block size */
- uint32_t nblocks; /* number of blocks */
-};
-
struct g_uncompress_softc {
uint32_t blksz; /* block size */
uint32_t nblocks; /* number of blocks */
uint64_t *offsets;
- enum {
- GEOM_UZIP = 1,
- GEOM_ULZMA
- } type;
+ int type;
struct mtx last_mtx;
uint32_t last_blk; /* last blk no */
@@ -99,11 +88,16 @@
char *last_buf; /* last blk data */
int req_total; /* total requests */
int req_cached; /* cached requests */
+};
- /* XZ decoder structs */
- struct xz_buf *b;
- struct xz_dec *s;
- z_stream *zs;
+static struct g_uncompress_desc *g_uncompress[] = {
+#ifdef GEOM_UNCOMPRESS
+ &g_uncompress_ulzma,
+#endif
+#ifdef GEOM_UNCOMPRESS_UZIP
+ &g_uncompress_uzip,
+#endif
+ NULL
};
static void
@@ -119,25 +113,8 @@
sc->offsets = 0;
}
- switch (sc->type) {
- case GEOM_ULZMA:
- if (sc->b) {
- free(sc->b, M_GEOM_UNCOMPRESS);
- sc->b = 0;
- }
- if (sc->s) {
- xz_dec_end(sc->s);
- sc->s = 0;
- }
- break;
- case GEOM_UZIP:
- if (sc->zs) {
- inflateEnd(sc->zs);
- free(sc->zs, M_GEOM_UNCOMPRESS);
- sc->zs = 0;
- }
- break;
- }
+ /* Call the free method. */
+ g_uncompress[sc->type]->d_free(g_uncompress[sc->type]);
mtx_destroy(&sc->last_mtx);
free(sc->last_buf, M_GEOM_UNCOMPRESS);
@@ -144,23 +121,7 @@
free(sc, M_GEOM_UNCOMPRESS);
}
-static void *
-z_alloc(void *nil, u_int type, u_int size)
-{
- void *ptr;
-
- ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
- return (ptr);
-}
-
static void
-z_free(void *nil, void *ptr)
-{
-
- free(ptr, M_GEOM_UNCOMPRESS);
-}
-
-static void
g_uncompress_done(struct bio *bp)
{
struct g_uncompress_softc *sc;
@@ -254,33 +215,9 @@
hexdump(bp->bio_data + pos, dlen, 0, 0);
#endif
- switch (sc->type) {
- case GEOM_ULZMA:
- sc->b->in = bp->bio_data + pos;
- sc->b->out = sc->last_buf;
- sc->b->in_pos = sc->b->out_pos = 0;
- sc->b->in_size = dlen;
- sc->b->out_size = (size_t)-1;
-
- err = (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END) ?
- 1 : 0;
- /* TODO decoder recovery, if needed */
- break;
- case GEOM_UZIP:
- sc->zs->next_in = bp->bio_data + pos;
- sc->zs->avail_in = dlen;
- sc->zs->next_out = sc->last_buf;
- sc->zs->avail_out = sc->blksz;
-
- err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?
- 1 : 0;
- if ((err) || (inflateReset(sc->zs) != Z_OK))
- printf("%s: UZIP decoder reset failed\n",
- gp->name);
- break;
- }
-
- if (err) {
+ if (g_uncompress[sc->type]->d_decom(g_uncompress[sc->type],
+ gp->name, bp->bio_data + pos, len, sc->last_buf,
+ sc->blksz) != 0) {
sc->last_blk = -1;
mtx_unlock(&sc->last_mtx);
DPRINTF(("%s: done: inflate failed, code=%d\n",
@@ -291,7 +228,7 @@
#ifdef GEOM_UNCOMPRESS_DEBUG
if (g_debugflags & 32)
- hexdump(sc->last_buf, sc->b->out_size, 0, 0);
+ hexdump(sc->last_buf, sc->blksz, 0, 0);
#endif
sc->last_blk = i;
@@ -521,24 +458,16 @@
goto err;
}
- switch (header->magic[0x0b]) {
- case 'L':
- type = GEOM_ULZMA;
- if (header->magic[0x0c] < GEOM_ULZMA_MAJVER) {
- DPRINTF(("%s: image version too old\n", gp->name));
+ for (i = 0; g_uncompress[i] != NULL; i++) {
+ error = g_uncompress[i]->d_taste(header, gp->name);
+ if (error == 1) {
+ /* Match. */
+ type = i;
+ break;
+ } else if (error == -1)
goto err;
- }
- printf("%s: GEOM_ULZMA image found\n", gp->name);
- break;
- case 'V':
- type = GEOM_UZIP;
- if (header->magic[0x0c] < GEOM_UZIP_MAJVER) {
- DPRINTF(("%s: image version too old\n", gp->name));
- goto err;
- }
- printf("%s: GEOM_UZIP image found\n", gp->name);
- break;
- default:
+ }
+ if (g_uncompress[i] == NULL) {
DPRINTF(("%s: unsupported image type\n", gp->name));
goto err;
}
@@ -588,23 +517,9 @@
sc->req_total = 0;
sc->req_cached = 0;
- switch (sc->type) {
- case GEOM_ULZMA:
- xz_crc32_init();
- sc->s = xz_dec_init(XZ_SINGLE, 0);
- sc->b = (struct xz_buf*)malloc(sizeof(struct xz_buf),
- M_GEOM_UNCOMPRESS, M_WAITOK);
- break;
- case GEOM_UZIP:
- sc->zs = (z_stream *)malloc(sizeof(z_stream),
- M_GEOM_UNCOMPRESS, M_WAITOK);
- sc->zs->zalloc = z_alloc;
- sc->zs->zfree = z_free;
- if (inflateInit(sc->zs) != Z_OK) {
- goto err;
- }
- break;
- }
+ /* Initialize the compression method. */
+ if (g_uncompress[sc->type]->d_init(g_uncompress[sc->type]) != 0)
+ goto err;
g_topology_lock();
pp2 = g_new_providerf(gp, "%s", gp->name);
Index: sys/modules/geom/geom_uncompress/Makefile
===================================================================
--- sys/modules/geom/geom_uncompress/Makefile (revision 265013)
+++ sys/modules/geom/geom_uncompress/Makefile (working copy)
@@ -10,8 +10,9 @@
CFLAGS+= -I${.CURDIR}/../../../geom/uncompress/ \
-I${.CURDIR}/../../../contrib/xz-embedded/freebsd \
-I${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/
-SRCS= g_uncompress.c xz_crc32.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c \
- xz_malloc.c
+CFLAGS+=-DGEOM_UNCOMPRESS -DGEOM_UNCOMPRESS_UZIP
+SRCS= g_uncompress.c g_uncompress_ulzma.c g_uncompress_uzip.c opt_geom.h
+SRCS+= xz_crc32.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c xz_malloc.c
SRCS+= xz.h xz_config.h xz_lzma2.h xz_malloc.h xz_private.h xz_stream.h
.include <bsd.kmod.mk>
--- /dev/null 2014-04-27 10:33:00.000000000 -0300
+++ sys/geom/uncompress/g_uncompress.h 2014-04-26 16:18:34.821549524 -0300
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2010-2012 Aleksandr Rybalko
+ * Copyright (c) 2004 Max Khon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _G_UNCOMPRESS_H_
+#define _G_UNCOMPRESS_H_
+
+MALLOC_DECLARE(M_GEOM_UNCOMPRESS);
+
+#define CLOOP_MAGIC_LEN 128
+#define CLOOP_TYPE 0x0b
+#define CLOOP_VERSION 0x0c
+
+/*
+ * Integer values (block size, number of blocks, offsets) are stored in
+ * big-endian (network) order on disk and struct cloop_header.
+ */
+struct cloop_header {
+ char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
+ uint32_t blksz; /* block size */
+ uint32_t nblocks; /* number of blocks */
+};
+
+struct g_uncompress_desc;
+
+typedef int g_uncompress_decom_t (struct g_uncompress_desc *, char *,
+ caddr_t, off_t, caddr_t, off_t);
+typedef void g_uncompress_free_t (struct g_uncompress_desc *);
+typedef int g_uncompress_init_t (struct g_uncompress_desc *);
+typedef int g_uncompress_taste_t (struct cloop_header *, char *);
+
+struct g_uncompress_desc {
+ void *d_data;
+ g_uncompress_decom_t *d_decom;
+ g_uncompress_free_t *d_free;
+ g_uncompress_init_t *d_init;
+ g_uncompress_taste_t *d_taste;
+};
+
+/* Supported compression methods. */
+#ifdef GEOM_UNCOMPRESS
+extern struct g_uncompress_desc g_uncompress_ulzma;
+#endif
+#ifdef GEOM_UNCOMPRESS_UZIP
+extern struct g_uncompress_desc g_uncompress_uzip;
+#endif
+
+#endif /* _G_UNCOMPRESS_H_ */
--- /dev/null 2014-04-27 10:33:00.000000000 -0300
+++ sys/geom/uncompress/g_uncompress_ulzma.c 2014-04-26 16:19:04.003547710 -0300
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 2010-2012 Aleksandr Rybalko
+ * Copyright (c) 2004 Max Khon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * GEOM ULZMA module - simple decompression module for use with read-only
+ * compressed images created by mkulzma(8).
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <geom/uncompress/g_uncompress.h>
+
+#include <contrib/xz-embedded/linux/include/linux/xz.h>
+
+#define GEOM_ULZMA_MAJVER '3'
+
+struct g_uncompress_ulzma_softc {
+ /* XZ decoder structs */
+ struct xz_buf *b;
+ struct xz_dec *s;
+};
+
+static void
+g_uncompress_ulzma_free(struct g_uncompress_desc *uncompress)
+{
+ struct g_uncompress_ulzma_softc *sc;
+
+ sc = (struct g_uncompress_ulzma_softc *)uncompress->d_data;
+ if (sc) {
+ if (sc->b) {
+ free(sc->b, M_GEOM_UNCOMPRESS);
+ sc->b = NULL;
+ }
+ if (sc->s) {
+ xz_dec_end(sc->s);
+ sc->s = NULL;
+ }
+ free(sc, M_GEOM_UNCOMPRESS);
+ uncompress->d_data = NULL;
+ }
+}
+
+static int
+g_uncompress_ulzma_init(struct g_uncompress_desc *uncompress)
+{
+ struct g_uncompress_ulzma_softc *sc;
+
+ sc = (struct g_uncompress_ulzma_softc *)malloc(sizeof(*sc),
+ M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
+ xz_crc32_init();
+ sc->s = xz_dec_init(XZ_SINGLE, 0);
+ sc->b = (struct xz_buf *)malloc(sizeof(struct xz_buf),
+ M_GEOM_UNCOMPRESS, M_WAITOK);
+
+ uncompress->d_data = (void *)sc;
+
+ return (0);
+}
+
+static int
+g_uncompress_ulzma_decom(struct g_uncompress_desc *uncompress, char *provider,
+ caddr_t in, off_t inlen, caddr_t out, off_t outlen)
+{
+ struct g_uncompress_ulzma_softc *sc;
+
+ sc = (struct g_uncompress_ulzma_softc *)uncompress->d_data;
+ sc->b->in = in;
+ sc->b->out = out;
+ sc->b->in_pos = sc->b->out_pos = 0;
+ sc->b->in_size = inlen;
+ sc->b->out_size = (size_t)-1;
+
+ if (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END)
+ return (-1);
+
+ return (0);
+}
+
+static int
+g_uncompress_ulzma_taste(struct cloop_header *header, char *provider)
+{
+
+ if (header->magic[CLOOP_TYPE] != 'L')
+ return (0);
+ if (header->magic[CLOOP_VERSION] < GEOM_ULZMA_MAJVER) {
+ printf("%s: image version too old\n", provider);
+ return (-1);
+ }
+ printf("%s: GEOM_ULZMA image found\n", provider);
+
+ return (1);
+}
+
+struct g_uncompress_desc g_uncompress_ulzma = {
+ .d_decom = g_uncompress_ulzma_decom,
+ .d_free = g_uncompress_ulzma_free,
+ .d_init = g_uncompress_ulzma_init,
+ .d_taste = g_uncompress_ulzma_taste,
+};
--- /dev/null 2014-04-27 10:33:00.000000000 -0300
+++ sys/geom/uncompress/g_uncompress_uzip.c 2014-04-26 16:40:11.413462855 -0300
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 2010-2012 Aleksandr Rybalko
+ * Copyright (c) 2004 Max Khon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * GEOM UZIP module - simple decompression module for use with read-only
+ * compressed images created by mkuzip(8).
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <geom/uncompress/g_uncompress.h>
+
+#include <net/zlib.h>
+
+#define GEOM_UZIP_MAJVER '2'
+
+struct g_uncompress_uzip_softc {
+ z_stream *zs;
+};
+
+static void
+g_uncompress_uzip_free(struct g_uncompress_desc *uncompress)
+{
+ struct g_uncompress_uzip_softc *sc;
+
+ sc = (struct g_uncompress_uzip_softc *)uncompress->d_data;
+ if (sc) {
+ if (sc->zs) {
+ inflateEnd(sc->zs);
+ free(sc->zs, M_GEOM_UNCOMPRESS);
+ sc->zs = NULL;
+ }
+ free(sc, M_GEOM_UNCOMPRESS);
+ uncompress->d_data = NULL;
+ }
+}
+
+static void *
+z_alloc(void *nil, u_int type, u_int size)
+{
+ void *ptr;
+
+ ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
+ return (ptr);
+}
+
+static void
+z_free(void *nil, void *ptr)
+{
+
+ free(ptr, M_GEOM_UNCOMPRESS);
+}
+
+static int
+g_uncompress_uzip_init(struct g_uncompress_desc *uncompress)
+{
+ struct g_uncompress_uzip_softc *sc;
+
+ sc = (struct g_uncompress_uzip_softc *)malloc(sizeof(*sc),
+ M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
+ sc->zs = (z_stream *)malloc(sizeof(z_stream),
+ M_GEOM_UNCOMPRESS, M_WAITOK);
+ sc->zs->zalloc = z_alloc;
+ sc->zs->zfree = z_free;
+ if (inflateInit(sc->zs) != Z_OK) {
+ free (sc->zs, M_GEOM_UNCOMPRESS);
+ free (sc, M_GEOM_UNCOMPRESS);
+ return (-1);
+ }
+
+ uncompress->d_data = (void *)sc;
+
+ return (0);
+}
+
+static int
+g_uncompress_uzip_decom(struct g_uncompress_desc *uncompress, char *provider,
+ caddr_t in, off_t inlen, caddr_t out, off_t outlen)
+{
+ int err;
+ struct g_uncompress_uzip_softc *sc;
+
+ sc = (struct g_uncompress_uzip_softc *)uncompress->d_data;
+ sc->zs->next_in = in;
+ sc->zs->avail_in = inlen;
+ sc->zs->next_out = out;
+ sc->zs->avail_out = outlen;
+
+ err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ? 1 : 0;
+ if (err || inflateReset(sc->zs) != Z_OK) {
+ printf("%s: UZIP decoder reset failed\n", provider);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+g_uncompress_uzip_taste(struct cloop_header *header, char *provider)
+{
+
+ if (header->magic[CLOOP_TYPE] != 'V')
+ return (0);
+ if (header->magic[CLOOP_VERSION] < GEOM_UZIP_MAJVER) {
+ printf("%s: image version too old\n", provider);
+ return (-1);
+ }
+ printf("%s: GEOM_UZIP image found\n", provider);
+
+ return (1);
+}
+
+struct g_uncompress_desc g_uncompress_uzip = {
+ .d_decom = g_uncompress_uzip_decom,
+ .d_free = g_uncompress_uzip_free,
+ .d_init = g_uncompress_uzip_init,
+ .d_taste = g_uncompress_uzip_taste,
+};
Index: share/man/man4/geom_uncompress.4
===================================================================
--- share/man/man4/geom_uncompress.4 (revision 265013)
+++ share/man/man4/geom_uncompress.4 (working copy)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 9, 2014
+.Dd April 27, 2014
.Dt GEOM_UNCOMPRESS 4
.Os
.Sh NAME
@@ -31,10 +31,11 @@
.Nm geom_uncompress
.Nd "GEOM based compressed disk images"
.Sh SYNOPSIS
-To compile this driver into the kernel, place the following line in your
+To compile this driver into the kernel, place the following lines in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "options GEOM_UNCOMPRESS"
+.Cd "options GEOM_UNCOMPRESS_UZIP"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the
@@ -89,6 +90,18 @@
Sectorsize: 512
Mode: r1w0e0
.Ed
+.Pp
+The compression support can be chosen in kernel configuration:
+.Bl -tag -width ".Sy options GEOM_UNCOMPRESS_UZIP"
+.It Sy options GEOM_UNCOMPRESS
+Enable the support for mkulzma(8) images.
+.It Sy options GEOM_UNCOMPRESS_UZIP
+Enable the support for mkuzip(8) images.
+.El
+.Pp
+The
+.Nm
+module is built with both compression methods enabled.
.Sh SEE ALSO
.Xr GEOM 4 ,
.Xr md 4 ,
More information about the freebsd-embedded
mailing list