Commit 3b61ce12 authored by Mike Hibler's avatar Mike Hibler

Add '-f' "filemode" option to imagezip for creating image files from regular

files (as opposed to from disk partitions).  This is almost identical to
rawmode, but also knows how to handle inputs that are not a multiple of the
sector size.  Imagezip will pad out the final sector, but uses a special
relocation entry (SHORTSECTOR) to tell imageunzip/frisbee how many bytes
to write in that final sector.

This is "pretty much" backward compatible.  If an old version of imageunzip
encounters the unknown new relocation entry, it will ignore it, resulting
in imageunzip just writing out the additional pad bytes to the output file.
This may or may not screw over the resulting output file.

Also fixed some lint found by GCC 4.2 on FBSD7.
parent 89be15ec
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2005 University of Utah and the Flux Group.
* Copyright (c) 2000-2009 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -511,6 +511,9 @@ dumpchunk(char *name, char *buf, int chunkno, int checkindex)
case RELOC_LILOCKSUM:
relocstr = "LILOCKSUM";
break;
case RELOC_SHORTSECTOR:
relocstr = "SHORTSECTOR";
break;
default:
relocstr = "??";
break;
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2004 University of Utah and the Flux Group.
* Copyright (c) 2000-2009 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -83,6 +83,7 @@ struct blockreloc {
#define RELOC_LILOSADDR 3 /* LILO sector address */
#define RELOC_LILOMAPSECT 4 /* LILO map sector */
#define RELOC_LILOCKSUM 5 /* LILO descriptor block cksum */
#define RELOC_SHORTSECTOR 6 /* indicated sector < sectsize */
/* XXX potential future alternatives to hard-wiring BSD disklabel knowledge */
#define RELOC_ADDPARTOFFSET 100 /* add partition offset to location */
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2007 University of Utah and the Flux Group.
* Copyright (c) 2000-2009 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -97,7 +97,7 @@ void writedata(off_t offset, size_t count, void *buf);
static void zero_remainder(void);
static void getrelocinfo(const blockhdr_t *hdr);
static void applyrelocs(off_t offset, size_t cc, void *buf);
static size_t applyrelocs(off_t offset, size_t cc, void *buf);
static int seekable;
static off_t nextwriteoffset;
......@@ -198,7 +198,7 @@ dump_stats(int sig)
fprintf(stderr, " ");
fprintf(stderr, "%4ld %6d\n",
estamp.tv_sec, totalchunks - donechunks);
(long)estamp.tv_sec, totalchunks - donechunks);
}
else {
if (sig) {
......@@ -216,7 +216,7 @@ dump_stats(int sig)
donechunks);
}
fprintf(stderr, "Wrote %lld bytes (%lld actual) in %ld seconds\n",
totaledata, totalrdata, estamp.tv_sec);
totaledata, totalrdata, (long)estamp.tv_sec);
}
if (debug)
fprintf(stderr, "decompressor blocked: %lu, "
......@@ -270,7 +270,7 @@ void dodots(int dottype, off_t cc)
gettimeofday(&estamp, 0);
estamp.tv_sec -= stamp.tv_sec;
fprintf(stderr, "%4ld %6d\n",
estamp.tv_sec, totalchunks - donechunks);
(long)estamp.tv_sec, totalchunks - donechunks);
dotcol = 0;
}
}
......@@ -448,7 +448,7 @@ dowrite_request(writebuf_t *wbuf)
/*
* Handle any relocations
*/
applyrelocs(offset, (size_t)size, buf);
size = (off_t)applyrelocs(offset, (size_t)size, buf);
writedata(offset, (size_t)size, buf);
}
free_writebuf(wbuf);
......@@ -467,7 +467,8 @@ dowrite_request(writebuf_t *wbuf)
/*
* Handle any relocations
*/
applyrelocs(offset, (size_t)size, buf);
size = (off_t)applyrelocs(offset, (size_t)size, buf);
wbuf->size = size;
}
/*
......@@ -1609,15 +1610,22 @@ getrelocinfo(const blockhdr_t *hdr)
memcpy(reloctable, relocs, numrelocs * sizeof(struct blockreloc));
}
static void
/*
* Perform relocations that apply to this chunk.
* Return value is the new size of the valid data in buf. This value
* only changes for the special SHORTSECTOR reloc that indicates a chunk
* that is not a multiple of the sector size.
*/
static size_t
applyrelocs(off_t offset, size_t size, void *buf)
{
struct blockreloc *reloc;
off_t roffset;
uint32_t coff;
size_t nsize = size;
if (numrelocs == 0)
return;
return nsize;
offset -= sectobytes(outputminsec);
......@@ -1654,6 +1662,12 @@ applyrelocs(off_t offset, size_t size, void *buf)
case RELOC_LILOCKSUM:
reloc_lilocksum(buf, coff, reloc->size);
break;
case RELOC_SHORTSECTOR:
assert(reloc->sectoff == 0);
assert(reloc->size < SECSIZE);
assert(roffset+SECSIZE == offset+size);
nsize -= (SECSIZE - reloc->size);
break;
default:
fprintf(stderr,
"Ignoring unknown relocation type %d\n",
......@@ -1662,6 +1676,7 @@ applyrelocs(off_t offset, size_t size, void *buf)
}
}
}
return nsize;
}
#ifndef linux
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2006 University of Utah and the Flux Group.
* Copyright (c) 2000-2009 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -54,6 +54,7 @@ int badsectors= 0;
int retrywrites= 1;
int dorelocs = 1;
int metaoptimize = 0;
int filemode = 0;
off_t datawritten;
partmap_t ignore, forceraw;
......@@ -214,7 +215,9 @@ devlseek(int fd, off_t off, int whence)
off_t noff;
assert((off & (DEV_BSIZE-1)) == 0);
noff = lseek(fd, off, whence);
assert(noff == (off_t)-1 || (noff & (DEV_BSIZE-1)) == 0);
if (!filemode) {
assert(noff == (off_t)-1 || (noff & (DEV_BSIZE-1)) == 0);
}
return noff;
}
......@@ -372,7 +375,7 @@ main(int argc, char *argv[])
extern char build_info[];
gettimeofday(&sstamp, 0);
while ((ch = getopt(argc, argv, "vlbnNdihrs:c:z:oI:1F:DR:S:XC:H:M")) != -1)
while ((ch = getopt(argc, argv, "vlbnNdihrs:c:z:ofI:1F:DR:S:XC:H:M")) != -1)
switch(ch) {
case 'v':
version++;
......@@ -459,6 +462,10 @@ main(int argc, char *argv[])
case 'M':
metaoptimize++;
break;
case 'f':
filemode++;
rawmode++;
break;
case 'h':
case '?':
default:
......@@ -507,7 +514,7 @@ main(int argc, char *argv[])
else
outfilename = argv[1];
if (!slicemode && dorelocs)
if (!slicemode && !filemode && dorelocs)
dorelocs = 0;
infilename = argv[0];
......@@ -873,9 +880,16 @@ read_raw(void)
return 1;
}
/*
* Round up the size to a sector boundary
*/
if (filemode)
size = sectobytes(bytestosec(size + secsize-1));
if (debug) {
fprintf(stderr, " Raw Image\n");
fprintf(stderr, " start %12d, size %12lld\n", 0, size);
fprintf(stderr, " start %12d, size %12lld\n",
0, (long long)size);
}
return 0;
}
......@@ -991,7 +1005,7 @@ dumpskips(int verbose)
fprintf(stderr,
"Total Number of Free Sectors: %d (bytes %lld) in %d ranges\n",
total, sectobytes(total), nranges);
total, (long long)sectobytes(total), nranges);
}
#undef DOHISTO
......@@ -1043,7 +1057,7 @@ mergeskips(int verbose)
if (verbose && culled) {
fprintf(stderr,
"\nFree Sectors Ignored: %d (%lld bytes) in %d ranges\n",
total, sectobytes(total), culled);
total, (long long)sectobytes(total), culled);
#ifdef DOHISTO
{
int i;
......@@ -1647,7 +1661,7 @@ compress_image(void)
gettimeofday(&estamp, 0);
estamp.tv_sec -= cstamp.tv_sec;
fprintf(stderr, "%12lld in %ld seconds.\n",
inputoffset + size, estamp.tv_sec);
inputoffset + size, (long)estamp.tv_sec);
}
else if (dots && full) {
static int pos;
......@@ -1657,7 +1671,7 @@ compress_image(void)
gettimeofday(&estamp, 0);
estamp.tv_sec -= cstamp.tv_sec;
fprintf(stderr, " %12lld %4ld\n",
inputoffset+size, estamp.tv_sec);
inputoffset+size, (long)estamp.tv_sec);
pos = 0;
}
fflush(stderr);
......@@ -2045,6 +2059,21 @@ compress_chunk(off_t off, off_t size, int *full, uint32_t *subblksize)
break;
}
/*
* In filemode, a file may not be a multiple of the sector
* size. Pad it so it is.
*/
if (filemode && (cc & (secsize - 1)) != 0) {
int zoff = cc & (secsize - 1);
int zsize = secsize - zoff;
/* XXX minor abuse of reloc: signal short sector */
addreloc(off+total+(cc-zoff), zoff, RELOC_SHORTSECTOR);
memset(&inbuf[cc], 0, zsize);
cc += zsize;
}
if (cc != count && !tileof) {
fprintf(stderr, "Bad count in read, %d != %d at %llu\n",
cc, count,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment