Obsolete mkulzma(8) and geom_uncompress(4), their functionality
is now provided by mkuzip(8) and geom_uzip(4) respectively. MFC after: 1 month
This commit is contained in:
parent
361e1fb408
commit
5497acc527
@ -38,6 +38,8 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20160223: functionality from mkulzma(1) merged into mkuzip(1)
|
||||
OLD_FILES+=usr/bin/mkulzma
|
||||
# 20160211: Remove obsolete unbound-control-setup
|
||||
OLD_FILES+=usr/sbin/unbound-control-setup
|
||||
# 20160116: Update mandoc to cvs snapshot 20160116
|
||||
|
@ -165,7 +165,6 @@ MAN= aac.4 \
|
||||
geom_fox.4 \
|
||||
geom_linux_lvm.4 \
|
||||
geom_map.4 \
|
||||
geom_uncompress.4 \
|
||||
geom_uzip.4 \
|
||||
gif.4 \
|
||||
gpio.4 \
|
||||
|
@ -78,7 +78,7 @@ or by using
|
||||
0 DISK cfid0 8388608 4 hd 0 sc 0
|
||||
1 MAP map/config 131072 4 i 5 o 8257536 entry 0 dsize 131072
|
||||
1 MAP map/rootfs 6881280 4 i 4 o 1376256 entry 0 dsize 6881280
|
||||
2 UNCOMPRESS map/rootfs.uncompress 18677760 512
|
||||
2 UZIP map/rootfs.uzip 18677760 512
|
||||
1 MAP map/kernel 1114112 4 i 3 o 262144 entry 0 dsize 1114112
|
||||
1 MAP map/upgrade 7995392 4 i 2 o 262144 entry 0 dsize 7995392
|
||||
1 MAP map/factory 65536 4 i 1 o 196608 entry 0 dsize 65536
|
||||
|
@ -1,118 +0,0 @@
|
||||
.\" Copyright (c) 2006, Ceri Davies <ceri@FreeBSD.org>
|
||||
.\" Copyright (c) 2014, Luiz Otavio O Souza <loos@FreeBSD.org>
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 9, 2014
|
||||
.Dt GEOM_UNCOMPRESS 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm geom_uncompress
|
||||
.Nd "GEOM based compressed disk images"
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel, place the following line in your
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "options GEOM_UNCOMPRESS"
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a module at boot time, place the
|
||||
following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
geom_uncompress_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
framework provides support for compressed read-only disk images.
|
||||
This allows significant storage savings at the expense of a little CPU
|
||||
time on each read.
|
||||
Data written in the GEOM label area allows
|
||||
.Nm
|
||||
to detect compressed images which have been created with
|
||||
.Xr mkulzma 8
|
||||
or
|
||||
.Xr mkuzip 8
|
||||
and presented to the kernel as a logical disk device via
|
||||
.Xr md 4 .
|
||||
.Nm
|
||||
creates a unique
|
||||
.Pa md#.uncompress
|
||||
device for each image.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
device is subsequently used by the
|
||||
.Fx
|
||||
kernel to access the disk images.
|
||||
The
|
||||
.Nm
|
||||
driver does not allow write operations to the underlying disk image.
|
||||
To check which
|
||||
.Xr md 4
|
||||
devices match a given
|
||||
.Nm
|
||||
device:
|
||||
.Bd -literal -offset indent
|
||||
# geom uncompress list
|
||||
Geom name: md0.uncompress
|
||||
Providers:
|
||||
1. Name: md0.uncompress
|
||||
Mediasize: 52428800 (50M)
|
||||
Sectorsize: 512
|
||||
Mode: r1w0e0
|
||||
Consumers:
|
||||
1. Name: md0
|
||||
Mediasize: 20864000 (20M)
|
||||
Sectorsize: 512
|
||||
Mode: r1w0e0
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr GEOM 4 ,
|
||||
.Xr md 4 ,
|
||||
.Xr geom 8 ,
|
||||
.Xr mkulzma 8 ,
|
||||
.Xr mkuzip 8
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Max Khon Aq Mt fjoe@FreeBSD.org
|
||||
as
|
||||
.Xr geom_uzip 4 .
|
||||
.An Aleksandr Rybalko Aq Mt ray@FreeBSD.org
|
||||
copied it over as
|
||||
.Nm
|
||||
and added LZMA functionality .
|
||||
This manual page was written by
|
||||
.An Ceri Davies Aq Mt ceri@FreeBSD.org
|
||||
for the
|
||||
.Xr geom_uzip 4 ,
|
||||
and modified by
|
||||
.An Luiz Otavio O Souza Aq Mt loos@FreeBSD.org
|
||||
to match
|
||||
.Nm .
|
@ -238,7 +238,6 @@ geom_nop_load="NO" # Transparent disk driver (see gnop(8))
|
||||
geom_raid3_load="NO" # RAID3 disk driver (see graid3(8))
|
||||
geom_shsec_load="NO" # Shared secret disk driver (see gshsec(8))
|
||||
geom_stripe_load="NO" # RAID0 disk driver (see gstripe(8))
|
||||
geom_uncompress_load="NO" # Compressed disk images driver (see mkulzma(8))
|
||||
geom_uzip_load="NO" # Compressed disk images driver (see mkuzip(8))
|
||||
geom_vinum_load="NO" # Concatenated/mirror/raid driver (see vinum(4))
|
||||
|
||||
|
@ -3081,21 +3081,20 @@ geom/raid3/g_raid3.c optional geom_raid3
|
||||
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
|
||||
contrib/xz-embedded/freebsd/xz_malloc.c \
|
||||
optional xz_embedded | geom_uncompress | geom_uzip \
|
||||
optional xz_embedded | geom_uzip \
|
||||
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/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_crc32.c \
|
||||
optional xz_embedded | geom_uncompress | geom_uzip \
|
||||
optional xz_embedded | geom_uzip \
|
||||
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/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_dec_bcj.c \
|
||||
optional xz_embedded | geom_uncompress | geom_uzip \
|
||||
optional xz_embedded | geom_uzip \
|
||||
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/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c \
|
||||
optional xz_embedded | geom_uncompress | geom_uzip \
|
||||
optional xz_embedded | geom_uzip \
|
||||
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/"
|
||||
contrib/xz-embedded/linux/lib/xz/xz_dec_stream.c \
|
||||
optional xz_embedded | geom_uncompress | geom_uzip \
|
||||
optional xz_embedded | geom_uzip \
|
||||
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/"
|
||||
geom/uzip/g_uzip.c optional geom_uzip
|
||||
geom/uzip/g_uzip_lzma.c optional geom_uzip
|
||||
@ -3458,7 +3457,7 @@ libkern/strvalid.c standard
|
||||
libkern/timingsafe_bcmp.c standard
|
||||
libkern/zlib.c optional crypto | geom_uzip | ipsec | \
|
||||
mxge | netgraph_deflate | \
|
||||
ddb_ctf | gzio | geom_uncompress
|
||||
ddb_ctf | gzio
|
||||
net/altq/altq_cbq.c optional altq
|
||||
net/altq/altq_cdnr.c optional altq
|
||||
net/altq/altq_codel.c optional altq
|
||||
|
@ -1,684 +0,0 @@
|
||||
/*-
|
||||
* 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 UNCOMPRESS module - simple decompression module for use with read-only
|
||||
* copressed images maked by mkuzip(8) or mkulzma(8) utilities.
|
||||
*
|
||||
* To enable module in kernel config, put this line:
|
||||
* device geom_uncompress
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/zlib.h>
|
||||
|
||||
#include <geom/geom.h>
|
||||
|
||||
#include <contrib/xz-embedded/linux/include/linux/xz.h>
|
||||
|
||||
#ifdef GEOM_UNCOMPRESS_DEBUG
|
||||
#define DPRINTF(a) printf a
|
||||
extern int g_debugflags;
|
||||
#else
|
||||
#define DPRINTF(a)
|
||||
#endif
|
||||
|
||||
static 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)
|
||||
*/
|
||||
#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
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
struct mtx last_mtx;
|
||||
uint32_t last_blk; /* last blk no */
|
||||
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 void
|
||||
g_uncompress_softc_free(struct g_uncompress_softc *sc, struct g_geom *gp)
|
||||
{
|
||||
|
||||
if (gp != NULL) {
|
||||
DPRINTF(("%s: %d requests, %d cached\n",
|
||||
gp->name, sc->req_total, sc->req_cached));
|
||||
}
|
||||
if (sc->offsets != NULL) {
|
||||
free(sc->offsets, M_GEOM_UNCOMPRESS);
|
||||
sc->offsets = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
mtx_destroy(&sc->last_mtx);
|
||||
free(sc->last_buf, M_GEOM_UNCOMPRESS);
|
||||
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;
|
||||
struct g_provider *pp, *pp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
struct bio *bp2;
|
||||
uint32_t start_blk, i;
|
||||
off_t iolen, pos, upos;
|
||||
size_t bsize;
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
bp2 = bp->bio_parent;
|
||||
pp = bp2->bio_to;
|
||||
gp = pp->geom;
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
pp2 = cp->provider;
|
||||
sc = gp->softc;
|
||||
DPRINTF(("%s: done\n", gp->name));
|
||||
|
||||
bp2->bio_error = bp->bio_error;
|
||||
if (bp2->bio_error != 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Example:
|
||||
* Uncompressed block size = 65536
|
||||
* User request: 65540-261632
|
||||
* (4 uncompressed blocks -4B at start, -512B at end)
|
||||
*
|
||||
* We have 512(secsize)*63(nsec) = 32256B at offset 1024
|
||||
* From: 1024 bp->bio_offset = 1024
|
||||
* To: 33280 bp->bio_length = 33280 - 1024 = 32256
|
||||
* Compressed blocks: 0-1020, 1020-1080, 1080-4845, 4845-12444,
|
||||
* 12444-33210, 33210-44100, ...
|
||||
*
|
||||
* Get start_blk from user request:
|
||||
* start_blk = bp2->bio_offset / 65536 = 65540/65536 = 1
|
||||
* bsize (block size of parent) = pp2->sectorsize (Now is 4B)
|
||||
* pos(in stream from parent) = sc->offsets[start_blk] % bsize =
|
||||
* = sc->offsets[1] % 4 = 1020 % 4 = 0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Uncompress data.
|
||||
*/
|
||||
start_blk = bp2->bio_offset / sc->blksz;
|
||||
bsize = pp2->sectorsize;
|
||||
iolen = bp->bio_completed;
|
||||
pos = sc->offsets[start_blk] % bsize;
|
||||
upos = 0;
|
||||
|
||||
DPRINTF(("%s: done: bio_length %jd bio_completed %jd start_blk %d, "
|
||||
"pos %jd, upos %jd (%jd, %d, %zu)\n",
|
||||
gp->name, (intmax_t)bp->bio_length, (intmax_t)bp->bio_completed,
|
||||
start_blk, (intmax_t)pos, (intmax_t)upos,
|
||||
(intmax_t)bp2->bio_offset, sc->blksz, bsize));
|
||||
|
||||
for (i = start_blk; upos < bp2->bio_length; i++) {
|
||||
off_t len, ulen, uoff;
|
||||
|
||||
uoff = i == start_blk ? bp2->bio_offset % sc->blksz : 0;
|
||||
ulen = MIN(sc->blksz - uoff, bp2->bio_length - upos);
|
||||
len = sc->offsets[i + 1] - sc->offsets[i];
|
||||
|
||||
DPRINTF((
|
||||
"%s: done: inflate block %d, start %ju, end %ju len %jd\n",
|
||||
gp->name, i, (uintmax_t)sc->offsets[i],
|
||||
(uintmax_t)sc->offsets[i + 1], (intmax_t)len));
|
||||
|
||||
if (len == 0) {
|
||||
/* All zero block: no cache update */
|
||||
bzero(bp2->bio_data + upos, ulen);
|
||||
upos += ulen;
|
||||
bp2->bio_completed += ulen;
|
||||
continue;
|
||||
}
|
||||
if (len > iolen) {
|
||||
DPRINTF(("%s: done: early termination: len (%jd) > "
|
||||
"iolen (%jd)\n",
|
||||
gp->name, (intmax_t)len, (intmax_t)iolen));
|
||||
break;
|
||||
}
|
||||
mtx_lock(&sc->last_mtx);
|
||||
|
||||
#ifdef GEOM_UNCOMPRESS_DEBUG
|
||||
if (g_debugflags & 32)
|
||||
hexdump(bp->bio_data + pos, len, 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 = len;
|
||||
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 = len;
|
||||
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) {
|
||||
sc->last_blk = -1;
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
DPRINTF(("%s: done: inflate failed, code=%d\n",
|
||||
gp->name, err));
|
||||
bp2->bio_error = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef GEOM_UNCOMPRESS_DEBUG
|
||||
if (g_debugflags & 32)
|
||||
hexdump(sc->last_buf, sc->b->out_size, 0, 0);
|
||||
#endif
|
||||
|
||||
sc->last_blk = i;
|
||||
DPRINTF(("%s: done: inflated \n", gp->name));
|
||||
memcpy(bp2->bio_data + upos, sc->last_buf + uoff, ulen);
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
|
||||
pos += len;
|
||||
iolen -= len;
|
||||
upos += ulen;
|
||||
bp2->bio_completed += ulen;
|
||||
}
|
||||
|
||||
done:
|
||||
/*
|
||||
* Finish processing the request.
|
||||
*/
|
||||
DPRINTF(("%s: done: (%d, %jd, %ld)\n",
|
||||
gp->name, bp2->bio_error, (intmax_t)bp2->bio_completed,
|
||||
bp2->bio_resid));
|
||||
free(bp->bio_data, M_GEOM_UNCOMPRESS);
|
||||
g_destroy_bio(bp);
|
||||
g_io_deliver(bp2, bp2->bio_error);
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_start(struct bio *bp)
|
||||
{
|
||||
struct g_uncompress_softc *sc;
|
||||
struct g_provider *pp, *pp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
struct bio *bp2;
|
||||
uint32_t start_blk, end_blk;
|
||||
size_t bsize;
|
||||
|
||||
pp = bp->bio_to;
|
||||
gp = pp->geom;
|
||||
DPRINTF(("%s: start (%d:%s) to %s off=%jd len=%jd\n",
|
||||
gp->name, bp->bio_cmd,
|
||||
(bp->bio_cmd == BIO_READ) ? "BIO_READ" : "NOTSUPPORTED",
|
||||
pp->name, (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length));
|
||||
|
||||
if (bp->bio_cmd != BIO_READ) {
|
||||
g_io_deliver(bp, EOPNOTSUPP);
|
||||
return;
|
||||
}
|
||||
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
pp2 = cp->provider;
|
||||
sc = gp->softc;
|
||||
|
||||
start_blk = bp->bio_offset / sc->blksz;
|
||||
end_blk = howmany(bp->bio_offset + bp->bio_length, sc->blksz);
|
||||
KASSERT(start_blk < sc->nblocks, ("start_blk out of range"));
|
||||
KASSERT(end_blk <= sc->nblocks, ("end_blk out of range"));
|
||||
|
||||
sc->req_total++;
|
||||
if (start_blk + 1 == end_blk) {
|
||||
mtx_lock(&sc->last_mtx);
|
||||
if (start_blk == sc->last_blk) {
|
||||
off_t uoff;
|
||||
|
||||
uoff = bp->bio_offset % sc->blksz;
|
||||
KASSERT(bp->bio_length <= sc->blksz - uoff,
|
||||
("cached data error"));
|
||||
memcpy(bp->bio_data, sc->last_buf + uoff,
|
||||
bp->bio_length);
|
||||
sc->req_cached++;
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
|
||||
DPRINTF(("%s: start: cached 0 + %jd, %jd + 0 + %jd\n",
|
||||
gp->name, (intmax_t)bp->bio_length, (intmax_t)uoff,
|
||||
(intmax_t)bp->bio_length));
|
||||
bp->bio_completed = bp->bio_length;
|
||||
g_io_deliver(bp, 0);
|
||||
return;
|
||||
}
|
||||
mtx_unlock(&sc->last_mtx);
|
||||
}
|
||||
|
||||
bp2 = g_clone_bio(bp);
|
||||
if (bp2 == NULL) {
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
return;
|
||||
}
|
||||
DPRINTF(("%s: start (%d..%d), %s: %d + %jd, %s: %d + %jd\n",
|
||||
gp->name, start_blk, end_blk,
|
||||
pp->name, pp->sectorsize, (intmax_t)pp->mediasize,
|
||||
pp2->name, pp2->sectorsize, (intmax_t)pp2->mediasize));
|
||||
bsize = pp2->sectorsize;
|
||||
bp2->bio_done = g_uncompress_done;
|
||||
bp2->bio_offset = rounddown(sc->offsets[start_blk], bsize);
|
||||
while (1) {
|
||||
bp2->bio_length = roundup(sc->offsets[end_blk], bsize) -
|
||||
bp2->bio_offset;
|
||||
if (bp2->bio_length < MAXPHYS)
|
||||
break;
|
||||
|
||||
end_blk--;
|
||||
DPRINTF((
|
||||
"%s: bio_length (%jd) > MAXPHYS: lowering end_blk to %u\n",
|
||||
gp->name, (intmax_t)bp2->bio_length, end_blk));
|
||||
}
|
||||
DPRINTF(("%s: start %jd + %jd -> %ju + %ju -> %jd + %jd\n",
|
||||
gp->name,
|
||||
(intmax_t)bp->bio_offset, (intmax_t)bp->bio_length,
|
||||
(uintmax_t)sc->offsets[start_blk],
|
||||
(uintmax_t)sc->offsets[end_blk] - sc->offsets[start_blk],
|
||||
(intmax_t)bp2->bio_offset, (intmax_t)bp2->bio_length));
|
||||
bp2->bio_data = malloc(bp2->bio_length, M_GEOM_UNCOMPRESS, M_NOWAIT);
|
||||
if (bp2->bio_data == NULL) {
|
||||
g_destroy_bio(bp2);
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
g_io_request(bp2, cp);
|
||||
DPRINTF(("%s: start ok\n", gp->name));
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_orphan(struct g_consumer *cp)
|
||||
{
|
||||
struct g_geom *gp;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->provider->name);
|
||||
g_topology_assert();
|
||||
|
||||
gp = cp->geom;
|
||||
g_uncompress_softc_free(gp->softc, gp);
|
||||
gp->softc = NULL;
|
||||
g_wither_geom(gp, ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uncompress_access(struct g_provider *pp, int dr, int dw, int de)
|
||||
{
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
|
||||
gp = pp->geom;
|
||||
cp = LIST_FIRST(&gp->consumer);
|
||||
KASSERT (cp != NULL, ("g_uncompress_access but no consumer"));
|
||||
|
||||
if (cp->acw + dw > 0)
|
||||
return (EROFS);
|
||||
|
||||
return (g_access(cp, dr, dw, de));
|
||||
}
|
||||
|
||||
static void
|
||||
g_uncompress_spoiled(struct g_consumer *cp)
|
||||
{
|
||||
struct g_geom *gp;
|
||||
|
||||
gp = cp->geom;
|
||||
g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, gp->name);
|
||||
g_topology_assert();
|
||||
|
||||
g_uncompress_softc_free(gp->softc, gp);
|
||||
gp->softc = NULL;
|
||||
g_wither_geom(gp, ENXIO);
|
||||
}
|
||||
|
||||
static struct g_geom *
|
||||
g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
||||
{
|
||||
struct cloop_header *header;
|
||||
struct g_uncompress_softc *sc;
|
||||
struct g_provider *pp2;
|
||||
struct g_consumer *cp;
|
||||
struct g_geom *gp;
|
||||
uint64_t *offsets;
|
||||
uint32_t i, r, total, total_offsets, type;
|
||||
uint8_t *buf;
|
||||
int error;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name);
|
||||
g_topology_assert();
|
||||
|
||||
/* Skip providers that are already open for writing. */
|
||||
if (pp->acw > 0)
|
||||
return (NULL);
|
||||
|
||||
buf = NULL;
|
||||
|
||||
/*
|
||||
* Create geom instance.
|
||||
*/
|
||||
gp = g_new_geomf(mp, "%s.uncompress", pp->name);
|
||||
cp = g_new_consumer(gp);
|
||||
error = g_attach(cp, pp);
|
||||
if (error == 0)
|
||||
error = g_access(cp, 1, 0, 0);
|
||||
if (error) {
|
||||
g_detach(cp);
|
||||
g_destroy_consumer(cp);
|
||||
g_destroy_geom(gp);
|
||||
return (NULL);
|
||||
}
|
||||
g_topology_unlock();
|
||||
|
||||
/*
|
||||
* Read cloop header, look for CLOOP magic, perform
|
||||
* other validity checks.
|
||||
*/
|
||||
DPRINTF(("%s: media sectorsize %u, mediasize %jd\n",
|
||||
gp->name, pp->sectorsize, (intmax_t)pp->mediasize));
|
||||
total = roundup(sizeof(struct cloop_header), pp->sectorsize);
|
||||
buf = g_read_data(cp, 0, total, NULL);
|
||||
if (buf == NULL)
|
||||
goto err;
|
||||
header = (struct cloop_header *) buf;
|
||||
if (strncmp(header->magic, CLOOP_MAGIC_START,
|
||||
sizeof(CLOOP_MAGIC_START) - 1) != 0) {
|
||||
DPRINTF(("%s: no CLOOP magic\n", gp->name));
|
||||
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));
|
||||
goto err;
|
||||
}
|
||||
DPRINTF(("%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;
|
||||
}
|
||||
DPRINTF(("%s: GEOM_UZIP image found\n", gp->name));
|
||||
break;
|
||||
default:
|
||||
DPRINTF(("%s: unsupported image type\n", gp->name));
|
||||
goto err;
|
||||
}
|
||||
|
||||
DPRINTF(("%s: found CLOOP magic\n", gp->name));
|
||||
/*
|
||||
* Initialize softc and read offsets.
|
||||
*/
|
||||
sc = malloc(sizeof(*sc), M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
|
||||
gp->softc = sc;
|
||||
sc->type = type;
|
||||
sc->blksz = ntohl(header->blksz);
|
||||
sc->nblocks = ntohl(header->nblocks);
|
||||
if (sc->blksz % 4 != 0) {
|
||||
printf("%s: block size (%u) should be multiple of 4.\n",
|
||||
gp->name, sc->blksz);
|
||||
goto err;
|
||||
}
|
||||
if (sc->blksz > MAX_BLKSZ) {
|
||||
printf("%s: block size (%u) should not be larger than %d.\n",
|
||||
gp->name, sc->blksz, MAX_BLKSZ);
|
||||
}
|
||||
total_offsets = sc->nblocks + 1;
|
||||
if (sizeof(struct cloop_header) +
|
||||
total_offsets * sizeof(uint64_t) > pp->mediasize) {
|
||||
printf("%s: media too small for %u blocks\n",
|
||||
gp->name, sc->nblocks);
|
||||
goto err;
|
||||
}
|
||||
g_free(buf);
|
||||
|
||||
sc->offsets = malloc(total_offsets * sizeof(uint64_t),
|
||||
M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
|
||||
total = roundup((sizeof(struct cloop_header) +
|
||||
total_offsets * sizeof(uint64_t)), pp->sectorsize);
|
||||
#define RSZ ((total - r) > MAXPHYS ? MAXPHYS: (total - r))
|
||||
for (r = 0, i = 0; r < total; r += MAXPHYS) {
|
||||
buf = g_read_data(cp, r, RSZ, &error);
|
||||
if (buf == NULL) {
|
||||
free(sc->offsets, M_GEOM_UNCOMPRESS);
|
||||
goto err;
|
||||
}
|
||||
offsets = (uint64_t *)buf;
|
||||
if (r == 0)
|
||||
offsets +=
|
||||
sizeof(struct cloop_header) / sizeof(uint64_t);
|
||||
for (; i < total_offsets && offsets < (uint64_t *)(buf + RSZ);
|
||||
i++, offsets++)
|
||||
sc->offsets[i] = be64toh(*offsets);
|
||||
g_free(buf);
|
||||
}
|
||||
#undef RSZ
|
||||
buf = NULL;
|
||||
DPRINTF(("%s: done reading offsets\n", gp->name));
|
||||
mtx_init(&sc->last_mtx, "geom_uncompress cache", NULL, MTX_DEF);
|
||||
sc->last_blk = -1;
|
||||
sc->last_buf = malloc(sc->blksz, M_GEOM_UNCOMPRESS, M_WAITOK);
|
||||
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;
|
||||
}
|
||||
|
||||
g_topology_lock();
|
||||
pp2 = g_new_providerf(gp, "%s", gp->name);
|
||||
pp2->sectorsize = 512;
|
||||
pp2->mediasize = (off_t)sc->nblocks * sc->blksz;
|
||||
if (pp->stripesize > 0) {
|
||||
pp2->stripesize = pp->stripesize;
|
||||
pp2->stripeoffset = pp->stripeoffset;
|
||||
}
|
||||
g_error_provider(pp2, 0);
|
||||
g_access(cp, -1, 0, 0);
|
||||
|
||||
DPRINTF(("%s: taste ok (%d, %jd), (%d, %d), %x\n",
|
||||
gp->name,
|
||||
pp2->sectorsize, (intmax_t)pp2->mediasize,
|
||||
pp2->stripeoffset, pp2->stripesize, pp2->flags));
|
||||
DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz));
|
||||
return (gp);
|
||||
|
||||
err:
|
||||
g_topology_lock();
|
||||
g_access(cp, -1, 0, 0);
|
||||
if (buf != NULL)
|
||||
g_free(buf);
|
||||
if (gp->softc != NULL) {
|
||||
g_uncompress_softc_free(gp->softc, NULL);
|
||||
gp->softc = NULL;
|
||||
}
|
||||
g_detach(cp);
|
||||
g_destroy_consumer(cp);
|
||||
g_destroy_geom(gp);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
g_uncompress_destroy_geom(struct gctl_req *req, struct g_class *mp,
|
||||
struct g_geom *gp)
|
||||
{
|
||||
struct g_provider *pp;
|
||||
|
||||
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, gp->name);
|
||||
g_topology_assert();
|
||||
|
||||
if (gp->softc == NULL) {
|
||||
DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
KASSERT(gp != NULL, ("NULL geom"));
|
||||
pp = LIST_FIRST(&gp->provider);
|
||||
KASSERT(pp != NULL, ("NULL provider"));
|
||||
if (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)
|
||||
return (EBUSY);
|
||||
|
||||
g_uncompress_softc_free(gp->softc, gp);
|
||||
gp->softc = NULL;
|
||||
g_wither_geom(gp, ENXIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct g_class g_uncompress_class = {
|
||||
.name = UNCOMPRESS_CLASS_NAME,
|
||||
.version = G_VERSION,
|
||||
.taste = g_uncompress_taste,
|
||||
.destroy_geom = g_uncompress_destroy_geom,
|
||||
|
||||
.start = g_uncompress_start,
|
||||
.orphan = g_uncompress_orphan,
|
||||
.access = g_uncompress_access,
|
||||
.spoiled = g_uncompress_spoiled,
|
||||
};
|
||||
|
||||
DECLARE_GEOM_CLASS(g_uncompress_class, g_uncompress);
|
||||
MODULE_DEPEND(g_uncompress, zlib, 1, 1, 1);
|
@ -49,11 +49,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -43,11 +43,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -46,8 +46,8 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -64,7 +64,7 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -43,11 +43,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -38,9 +38,9 @@ options NO_SWAPPING
|
||||
# options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Not enough space for these..
|
||||
nooptions INVARIANTS
|
||||
|
@ -26,9 +26,9 @@ options AR71XX_ENV_UBOOT
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
@ -27,9 +27,9 @@ options AR71XX_ENV_UBOOT
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
@ -45,11 +45,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -38,8 +38,8 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -51,4 +51,4 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -41,8 +41,8 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -52,7 +52,7 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -54,11 +54,11 @@ options NO_SYSCTL_DESCR
|
||||
|
||||
# GEOM modules
|
||||
device geom_map # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem hackery!
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip # compressed in-memory filesystem hackery!
|
||||
options GEOM_UZIP
|
||||
options GEOM_PART_GPT
|
||||
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
options AR71XX_REALMEM=64*1024*1024
|
||||
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
@ -58,11 +58,11 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# In order to netboot, you have to build the mfsroot into the kernel
|
||||
# 19443712 or 19M is the biggest rootfs via netboot this thing supports
|
||||
#options MD_ROOT # md device usable as a potential root device
|
||||
#options MD_ROOT_SIZE=19444
|
||||
#makeoptions MFS_IMAGE=/tftpboot/mfsroot-dir825c1.img.ulzma
|
||||
#options ROOTDEVNAME=\"ufs:md0.uncompress\"
|
||||
#options ROOTDEVNAME=\"ufs:md0.uzip\"
|
||||
|
@ -26,9 +26,9 @@ options AR71XX_ENV_UBOOT
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
@ -65,7 +65,7 @@ options PSEUDOFS #Pseudo-filesystem framework
|
||||
#options BOOTP_WIRED_TO=rt0
|
||||
#options BOOTP_COMPAT
|
||||
#options CD9660 # ISO 9660 Filesystem
|
||||
#options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uncompress\"
|
||||
#options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uzip\"
|
||||
#options TMPFS # TMP Memory Filesystem
|
||||
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
|
@ -45,11 +45,11 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -32,11 +32,11 @@ options AR71XX_REALMEM=64*1024*1024
|
||||
options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -54,9 +54,9 @@ options FFS #Berkeley Fast Filesystem
|
||||
#options UFS_DIRHASH #Improve performance on big directories
|
||||
|
||||
# Support uncompress lzma rootfs
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# PCI bus
|
||||
device pci
|
||||
|
@ -38,9 +38,9 @@ options NO_SWAPPING
|
||||
# options MSDOSFS
|
||||
|
||||
# uncompress - to boot read-only lzma natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
# Not enough space for these..
|
||||
nooptions INVARIANTS
|
||||
|
@ -14,8 +14,8 @@ hints "ROUTERSTATION.hints"
|
||||
|
||||
# GEOM modules
|
||||
device geom_redboot # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem support
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip # compressed in-memory filesystem support
|
||||
options GEOM_UZIP
|
||||
|
||||
# For DOS
|
||||
options MSDOSFS
|
||||
@ -27,4 +27,4 @@ device etherswitch
|
||||
device ukswitch
|
||||
|
||||
# Boot path - redboot MFS
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uzip\"
|
||||
|
@ -15,8 +15,8 @@ device pcf2123_rtc
|
||||
|
||||
# GEOM modules
|
||||
device geom_redboot # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem support
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip # compressed in-memory filesystem support
|
||||
options GEOM_UZIP
|
||||
|
||||
# For DOS
|
||||
options MSDOSFS
|
||||
@ -28,5 +28,5 @@ device etherswitch
|
||||
device arswitch
|
||||
|
||||
# Boot off of flash
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:redboot/rootfs.uzip\"
|
||||
|
||||
|
@ -64,7 +64,7 @@ options BOOTP_NFSV3
|
||||
options BOOTP_WIRED_TO=rt0
|
||||
options BOOTP_COMPAT
|
||||
options CD9660 # ISO 9660 Filesystem
|
||||
options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"cd9660:/dev/map/rootfs.uzip\"
|
||||
options TMPFS # TMP Memory Filesystem
|
||||
|
||||
#options FFS #Berkeley Fast Filesystem
|
||||
|
@ -67,10 +67,10 @@ options TMPFS # TMP Memory Filesystem
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
#options ROOTDEVNAME=\"nfs:193.178.153.200:/bsdmips\"
|
||||
|
||||
#device geom_uncompress
|
||||
#options GEOM_UNCOMPRESS
|
||||
#device geom_uzip
|
||||
#options GEOM_UZIP
|
||||
#options MD_ROOT
|
||||
#options ROOTDEVNAME=\"ufs:md0.uncompress\"
|
||||
#options ROOTDEVNAME=\"ufs:md0.uzip\"
|
||||
|
||||
# Options for making kernel less hangry
|
||||
makeoptions INLINE_LIMIT=1024
|
||||
|
@ -46,8 +46,8 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -64,7 +64,7 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -38,8 +38,8 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -51,4 +51,4 @@ device firmware # Used by the above
|
||||
options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
@ -34,8 +34,8 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
@ -47,7 +47,7 @@ device geom_map
|
||||
#options ATH_EEPROM_FIRMWARE
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# Default to accept
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
@ -43,13 +43,13 @@ device arswitch
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uzip - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
# options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
# options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
# Note: we don't fit in 4MB flash, so the rootfs must be on USB for now
|
||||
options ROOTDEVNAME=\"ufs:da0\"
|
||||
|
@ -37,14 +37,14 @@ options MSDOSFS
|
||||
options AR71XX_ENV_UBOOT
|
||||
|
||||
# uncompress - to boot natively from flash
|
||||
device geom_uncompress
|
||||
options GEOM_UNCOMPRESS
|
||||
device geom_uzip
|
||||
options GEOM_UZIP
|
||||
|
||||
# Used for the static uboot partition map
|
||||
device geom_map
|
||||
|
||||
# Boot off of the rootfs, as defined in the geom_map setup.
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:map/rootfs.uzip\"
|
||||
|
||||
# We bite the performance overhead for now; the kernel won't
|
||||
# fit if the mutexes are inlined.
|
||||
|
@ -26,9 +26,9 @@ options BOOTVERBOSE
|
||||
|
||||
# GEOM modules
|
||||
device geom_map # to get access to the SPI flash partitions
|
||||
device geom_uncompress # compressed in-memory filesystem hackery!
|
||||
device geom_uzip # compressed in-memory filesystem hackery!
|
||||
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
options AR71XX_ATH_EEPROM # Fetch EEPROM/PCI config from flash
|
||||
options ATH_EEPROM_FIRMWARE # Use EEPROM from flash
|
||||
|
@ -25,10 +25,10 @@ options AR71XX_ENV_UBOOT
|
||||
options BOOTVERBOSE
|
||||
|
||||
# GEOM modules
|
||||
device geom_uncompress # compressed in-memory filesystem hackery!
|
||||
device geom_uzip # compressed in-memory filesystem hackery!
|
||||
device geom_map # to get access to the SPI flash partitions
|
||||
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\"
|
||||
options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uzip\"
|
||||
|
||||
options AR71XX_ATH_EEPROM # Fetch EEPROM/PCI config from flash
|
||||
options ATH_EEPROM_FIRMWARE # Use EEPROM from flash
|
||||
|
@ -21,7 +21,6 @@ SUBDIR= geom_bde \
|
||||
geom_sched \
|
||||
geom_shsec \
|
||||
geom_stripe \
|
||||
geom_uncompress \
|
||||
geom_uzip \
|
||||
geom_vinum \
|
||||
geom_virstor \
|
||||
|
@ -1,17 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../geom/uncompress \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/freebsd/ \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/ \
|
||||
${.CURDIR}/../../../contrib/xz-embedded/linux/include/linux/ \
|
||||
${.CURDIR}/../../../net
|
||||
|
||||
KMOD= geom_uncompress
|
||||
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
|
||||
SRCS+= xz.h xz_config.h xz_lzma2.h xz_malloc.h xz_private.h xz_stream.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -297,7 +297,6 @@ DIRDEPS+= \
|
||||
usr.bin/mklocale \
|
||||
usr.bin/mkstr \
|
||||
usr.bin/mktemp \
|
||||
usr.bin/mkulzma \
|
||||
usr.bin/mkuzip \
|
||||
usr.bin/msgs \
|
||||
usr.bin/mt \
|
||||
|
@ -99,7 +99,6 @@ SUBDIR= alias \
|
||||
mkimg \
|
||||
mklocale \
|
||||
mktemp \
|
||||
mkulzma \
|
||||
mkuzip \
|
||||
mt \
|
||||
ncal \
|
||||
|
@ -1,8 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= mkulzma
|
||||
MAN= mkulzma.8
|
||||
|
||||
LIBADD= lzma
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,20 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
gnu/lib/libgcc \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
lib/liblzma \
|
||||
lib/libthr \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -1,107 +0,0 @@
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\" Derived from mkuzip.8 by Aleksandr Rybalko <ray@ddteam.net>
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\" "THE BEER-WARE LICENSE" (Revision 42):
|
||||
.\" <sobomax@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
||||
.\" can do whatever you want with this stuff. If we meet some day, and you think
|
||||
.\" this stuff is worth it, you can buy me a beer in return. Maxim Sobolev
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 17, 2006
|
||||
.Dt MKULZMA 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mkulzma
|
||||
.Nd compress disk image for use with
|
||||
.Xr geom_uncompress 4
|
||||
class
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl v
|
||||
.Op Fl o Ar outfile
|
||||
.Op Fl s Ar cluster_size
|
||||
.Ar infile
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility compresses a disk image file so that the
|
||||
.Xr geom_uncompress 4
|
||||
class will be able to decompress the resulting image at run-time.
|
||||
This allows for a significant reduction of size of disk image at
|
||||
the expense of some CPU time required to decompress the data each
|
||||
time it is read.
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
works in two phases:
|
||||
.Bl -enum
|
||||
.It
|
||||
An
|
||||
.Ar infile
|
||||
image is split into clusters; each cluster is compressed using liblzma.
|
||||
.It
|
||||
The resulting set of compressed clusters along with headers that allow
|
||||
locating each individual cluster is written to the output file.
|
||||
.El
|
||||
.Pp
|
||||
The options are:
|
||||
.Bl -tag -width indent
|
||||
.It Fl o Ar outfile
|
||||
Name of the output file
|
||||
.Ar outfile .
|
||||
The default is to use the input name with the suffix
|
||||
.Pa .ulzma .
|
||||
.It Fl s Ar cluster_size
|
||||
Split the image into clusters of
|
||||
.Ar cluster_size
|
||||
bytes, 16384 bytes by default.
|
||||
The
|
||||
.Ar cluster_size
|
||||
should be a multiple of 512 bytes.
|
||||
.It Fl v
|
||||
Display verbose messages.
|
||||
.El
|
||||
.Sh NOTES
|
||||
The compression ratio largely depends on the cluster size used.
|
||||
.\" The following two sentences are unclear: how can xz(1) be
|
||||
.\" used in a comparable fashion, and wouldn't a lzma-compressed
|
||||
.\" image suffer from larger cluster sizes as well?
|
||||
For large cluster sizes (16K and higher), typical compression ratios
|
||||
are only 1-2% less than those achieved with
|
||||
.Xr lzma 1 .
|
||||
However, it should be kept in mind that larger cluster
|
||||
sizes lead to higher overhead in the
|
||||
.Xr geom_uncompress 4
|
||||
class, as the class has to decompress the whole cluster even if
|
||||
only a few bytes from that cluster have to be read.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
inserts a short shell script at the beginning of the generated image,
|
||||
which makes it possible to
|
||||
.Dq run
|
||||
the image just like any other shell script.
|
||||
The script tries to load the
|
||||
.Xr geom_uncompress 4
|
||||
class if it is not loaded, configure the image as an
|
||||
.Xr md 4
|
||||
disk device using
|
||||
.Xr mdconfig 8 ,
|
||||
and automatically mount it using
|
||||
.Xr mount_cd9660 8
|
||||
on the mount point provided as the first argument to the script.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr lzma 1 ,
|
||||
.Xr geom 4 ,
|
||||
.Xr geom_uncompress 4 ,
|
||||
.Xr md 4 ,
|
||||
.Xr mdconfig 8 ,
|
||||
.Xr mount_cd9660 8
|
||||
.Sh AUTHORS
|
||||
.An Maxim Sobolev Aq Mt sobomax@FreeBSD.org
|
||||
.An Aleksandr Rybalko Aq Mt ray@ddteam.net
|
@ -1,330 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Derived from mkuzip.c by Aleksandr Rybalko <ray@ddteam.net>
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <sobomax@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Maxim Sobolev
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/disk.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <lzma.h>
|
||||
|
||||
#define CLSTSIZE 16384
|
||||
#define DEFAULT_SUFX ".ulzma"
|
||||
|
||||
#define USED_BLOCKSIZE DEV_BSIZE
|
||||
|
||||
#define CLOOP_MAGIC_LEN 128
|
||||
/* Format L3.0, since we move to XZ API */
|
||||
static char CLOOP_MAGIC_START[] =
|
||||
"#!/bin/sh\n"
|
||||
"#L3.0\n"
|
||||
"n=uncompress\n"
|
||||
"m=geom_$n\n"
|
||||
"(kldstat -m $m 2>&-||kldload $m)>&-&&"
|
||||
"mount_cd9660 /dev/`mdconfig -af $0`.$n $1\n"
|
||||
"exit $?\n";
|
||||
|
||||
static char *readblock(int, char *, u_int32_t);
|
||||
static void usage(void);
|
||||
static void *safe_malloc(size_t);
|
||||
static void cleanup(void);
|
||||
|
||||
static char *cleanfile = NULL;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *iname, *oname, *obuf, *ibuf;
|
||||
int fdr, fdw, i, opt, verbose, tmp;
|
||||
struct iovec iov[2];
|
||||
struct stat sb;
|
||||
uint32_t destlen;
|
||||
uint64_t offset;
|
||||
uint64_t *toc;
|
||||
lzma_filter filters[2];
|
||||
lzma_options_lzma opt_lzma;
|
||||
lzma_ret ret;
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
struct cloop_header {
|
||||
char magic[CLOOP_MAGIC_LEN]; /* cloop magic */
|
||||
uint32_t blksz; /* block size */
|
||||
uint32_t nblocks; /* number of blocks */
|
||||
} hdr;
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.blksz = CLSTSIZE;
|
||||
strcpy(hdr.magic, CLOOP_MAGIC_START);
|
||||
oname = NULL;
|
||||
verbose = 0;
|
||||
|
||||
while((opt = getopt(argc, argv, "o:s:v")) != -1) {
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
oname = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
tmp = atoi(optarg);
|
||||
if (tmp <= 0) {
|
||||
errx(1,
|
||||
"invalid cluster size specified: %s",
|
||||
optarg);
|
||||
/* Not reached */
|
||||
}
|
||||
if (tmp % USED_BLOCKSIZE != 0) {
|
||||
errx(1,
|
||||
"cluster size should be multiple of %d",
|
||||
USED_BLOCKSIZE);
|
||||
/* Not reached */
|
||||
}
|
||||
if ( tmp > MAXPHYS) {
|
||||
errx(1, "cluster size is too large");
|
||||
/* Not reached */
|
||||
}
|
||||
hdr.blksz = tmp;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* Not reached */
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1) {
|
||||
usage();
|
||||
/* Not reached */
|
||||
}
|
||||
|
||||
iname = argv[0];
|
||||
if (oname == NULL) {
|
||||
asprintf(&oname, "%s%s", iname, DEFAULT_SUFX);
|
||||
if (oname == NULL) {
|
||||
err(1, "can't allocate memory");
|
||||
/* Not reached */
|
||||
}
|
||||
}
|
||||
|
||||
obuf = safe_malloc(hdr.blksz*2);
|
||||
ibuf = safe_malloc(hdr.blksz);
|
||||
|
||||
signal(SIGHUP, exit);
|
||||
signal(SIGINT, exit);
|
||||
signal(SIGTERM, exit);
|
||||
signal(SIGXCPU, exit);
|
||||
signal(SIGXFSZ, exit);
|
||||
atexit(cleanup);
|
||||
|
||||
fdr = open(iname, O_RDONLY);
|
||||
if (fdr < 0) {
|
||||
err(1, "open(%s)", iname);
|
||||
/* Not reached */
|
||||
}
|
||||
if (fstat(fdr, &sb) != 0) {
|
||||
err(1, "fstat(%s)", iname);
|
||||
/* Not reached */
|
||||
}
|
||||
if (S_ISCHR(sb.st_mode)) {
|
||||
off_t ms;
|
||||
|
||||
if (ioctl(fdr, DIOCGMEDIASIZE, &ms) < 0) {
|
||||
err(1, "ioctl(DIOCGMEDIASIZE)");
|
||||
/* Not reached */
|
||||
}
|
||||
sb.st_size = ms;
|
||||
} else if (!S_ISREG(sb.st_mode)) {
|
||||
fprintf(stderr,
|
||||
"%s: not a character device or regular file\n",
|
||||
iname);
|
||||
exit(1);
|
||||
}
|
||||
hdr.nblocks = sb.st_size / hdr.blksz;
|
||||
if ((sb.st_size % hdr.blksz) != 0) {
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "file size is not multiple "
|
||||
"of %d, padding data\n", hdr.blksz);
|
||||
hdr.nblocks++;
|
||||
}
|
||||
toc = safe_malloc((hdr.nblocks + 1) * sizeof(*toc));
|
||||
|
||||
fdw = open(oname, O_WRONLY | O_TRUNC | O_CREAT,
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
if (fdw < 0) {
|
||||
err(1, "open(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
cleanfile = oname;
|
||||
|
||||
/*
|
||||
* Prepare header that we will write later when we have index ready.
|
||||
*/
|
||||
iov[0].iov_base = (char *)&hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[1].iov_base = (char *)toc;
|
||||
iov[1].iov_len = (hdr.nblocks + 1) * sizeof(*toc);
|
||||
offset = iov[0].iov_len + iov[1].iov_len;
|
||||
|
||||
/* Reserve space for header */
|
||||
lseek(fdw, offset, SEEK_SET);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "data size %ju bytes, number of clusters "
|
||||
"%u, index length %zu bytes\n", sb.st_size,
|
||||
hdr.nblocks, iov[1].iov_len);
|
||||
|
||||
/* Init lzma encoder */
|
||||
if (lzma_lzma_preset(&opt_lzma, LZMA_PRESET_DEFAULT))
|
||||
errx(1, "Error loading LZMA preset");
|
||||
|
||||
filters[0].id = LZMA_FILTER_LZMA2;
|
||||
filters[0].options = &opt_lzma;
|
||||
filters[1].id = LZMA_VLI_UNKNOWN;
|
||||
|
||||
for(i = 0; i == 0 || ibuf != NULL; i++) {
|
||||
ibuf = readblock(fdr, ibuf, hdr.blksz);
|
||||
if (ibuf != NULL) {
|
||||
destlen = hdr.blksz*2;
|
||||
|
||||
ret = lzma_stream_encoder(&strm, filters,
|
||||
LZMA_CHECK_CRC32);
|
||||
if (ret != LZMA_OK) {
|
||||
if (ret == LZMA_MEMLIMIT_ERROR)
|
||||
errx(1, "can't compress data: "
|
||||
"LZMA_MEMLIMIT_ERROR");
|
||||
|
||||
errx(1, "can't compress data: "
|
||||
"LZMA compressor ERROR");
|
||||
}
|
||||
|
||||
strm.next_in = ibuf;
|
||||
strm.avail_in = hdr.blksz;
|
||||
strm.next_out = obuf;
|
||||
strm.avail_out = hdr.blksz*2;
|
||||
|
||||
ret = lzma_code(&strm, LZMA_FINISH);
|
||||
|
||||
if (ret != LZMA_STREAM_END) {
|
||||
/* Error */
|
||||
errx(1, "lzma_code FINISH failed, code=%d, "
|
||||
"pos(in=%zd, out=%zd)",
|
||||
ret,
|
||||
(hdr.blksz - strm.avail_in),
|
||||
(hdr.blksz*2 - strm.avail_out));
|
||||
}
|
||||
|
||||
destlen -= strm.avail_out;
|
||||
|
||||
lzma_end(&strm);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "cluster #%d, in %u bytes, "
|
||||
"out %u bytes\n", i, hdr.blksz, destlen);
|
||||
} else {
|
||||
destlen = USED_BLOCKSIZE - (offset % USED_BLOCKSIZE);
|
||||
memset(obuf, 0, destlen);
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "padding data with %u bytes"
|
||||
" so that file size is multiple of %d\n",
|
||||
destlen,
|
||||
USED_BLOCKSIZE);
|
||||
}
|
||||
if (write(fdw, obuf, destlen) < 0) {
|
||||
err(1, "write(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
toc[i] = htobe64(offset);
|
||||
offset += destlen;
|
||||
}
|
||||
close(fdr);
|
||||
|
||||
if (verbose != 0)
|
||||
fprintf(stderr, "compressed data to %ju bytes, saved %lld "
|
||||
"bytes, %.2f%% decrease.\n", offset,
|
||||
(long long)(sb.st_size - offset),
|
||||
100.0 * (long long)(sb.st_size - offset) /
|
||||
(float)sb.st_size);
|
||||
|
||||
/* Convert to big endian */
|
||||
hdr.blksz = htonl(hdr.blksz);
|
||||
hdr.nblocks = htonl(hdr.nblocks);
|
||||
/* Write headers into pre-allocated space */
|
||||
lseek(fdw, 0, SEEK_SET);
|
||||
if (writev(fdw, iov, 2) < 0) {
|
||||
err(1, "writev(%s)", oname);
|
||||
/* Not reached */
|
||||
}
|
||||
cleanfile = NULL;
|
||||
close(fdw);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static char *
|
||||
readblock(int fd, char *ibuf, u_int32_t clstsize)
|
||||
{
|
||||
int numread;
|
||||
|
||||
bzero(ibuf, clstsize);
|
||||
numread = read(fd, ibuf, clstsize);
|
||||
if (numread < 0) {
|
||||
err(1, "read() failed");
|
||||
/* Not reached */
|
||||
}
|
||||
if (numread == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: mkulzma [-v] [-o outfile] [-s cluster_size] "
|
||||
"infile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void *
|
||||
safe_malloc(size_t size)
|
||||
{
|
||||
void *retval;
|
||||
|
||||
retval = malloc(size);
|
||||
if (retval == NULL) {
|
||||
err(1, "can't allocate memory");
|
||||
/* Not reached */
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
|
||||
if (cleanfile != NULL)
|
||||
unlink(cleanfile);
|
||||
}
|
Loading…
Reference in New Issue
Block a user