Creating Compressed Loop FS from stdin

Peter Pentchev roam at ringlet.net
Thu Dec 30 02:34:36 PST 2004


On Wed, Dec 29, 2004 at 11:15:40PM +0100, Matteo Riondato wrote:
> Hi folks!
> 
> I think you know what FreeSBIE
> is and that we use compressed loop filesystems for /usr and /var
> directories on our LiveCD. 
> At the moment, to create compressed filesystems, we rely on
> sysutils/cloop-utils, but I know /usr/bin/mkuzip is present in HEAD and
> in RELENG_5 and would like to switch to that. However, it seems that I
> cannot create valid cloopfs with mkuzip.
> To create the cloop image, I use:
> 
> /usr/local/bin/mkisofs -lrJL $FREESBIEBASEDIR/usr | /usr/bin/mkuzip -v \
> -o $FREESBIEBASEDIR/cloop/usr.cloop -s 65536 /dev/stdin

Well, as you can see from the very first line output by mkuzip in that
case (if -v is indeed specified), it thinks that the input file is 0 bytes
long.  This is so because the first thing mkuzip does is a stat(2) on
the input file descriptor, and when you point it at /dev/stdin, stat()
returns a length of 0 bytes since it is impossible to determine beforehand
how much data will be produced by the pipe.

This could be fixed by the following patch.  I'm CC'ing Maxim Sobolev,
the author of mkuzip(8); Maxim, do you have any objections to this patch?

G'luck,
Peter

Index: src/usr.bin/mkuzip/mkuzip.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/mkuzip/mkuzip.c,v
retrieving revision 1.2
diff -u -r1.2 mkuzip.c
--- src/usr.bin/mkuzip/mkuzip.c	10 Sep 2004 23:16:05 -0000	1.2
+++ src/usr.bin/mkuzip/mkuzip.c	30 Dec 2004 10:32:38 -0000
@@ -122,10 +122,23 @@
 	signal(SIGXFSZ, exit);
 	atexit(cleanup);
 
-	if (stat(iname, &sb) != 0) {
+	fdr = open(iname, O_RDONLY);
+	if (fdr < 0) {
 		err(1, "%s", iname);
 		/* Not reached */
 	}
+
+	/* Try seeking to the end; if that fails, fall back to fstat() */
+	sb.st_size = lseek(fdr, 0, SEEK_END);
+	if (sb.st_size < 1 && fstat(fdr, &sb) != 0) {
+		err(1, "%s", iname);
+		/* Not reached */
+	}
+	if (sb.st_size < 1) {
+		errx(1, "Could not determine the size of %s", iname);
+		/* Not reached */
+	}
+	lseek(fdr, 0, SEEK_SET);
 	hdr.nblocks = sb.st_size / hdr.blksz;
 	if ((sb.st_size % hdr.blksz) != 0) {
 		if (verbose != 0)
@@ -135,11 +148,6 @@
 	}
 	toc = safe_malloc((hdr.nblocks + 1) * sizeof(*toc));
 
-	fdr = open(iname, O_RDONLY);
-	if (fdr < 0) {
-		err(1, "%s", iname);
-		/* Not reached */
-	}
 	fdw = open(oname, O_WRONLY | O_TRUNC | O_CREAT,
 		   S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 	if (fdw < 0) {

-- 
Peter Pentchev	roam at ringlet.net    roam at cnsys.bg    roam at FreeBSD.org
PGP key:	http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint	FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553
This sentence claims to be an Epimenides paradox, but it is lying.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20041230/edbbdeb3/attachment.bin


More information about the freebsd-hackers mailing list