Commit 38b94c09 authored by Mike Hibler's avatar Mike Hibler
Browse files

Prototype SHD changes to imagedump to get it to report the allocated ranges to

the kernel via a magic ioctl (see shd/shd.h).  For example:

	imagedump -C /dev/shdXX /usr/testbed/images/FBSD410-STD.ndz

Would build a list of allocated ranges for the given image and pass them
to /dev/shdXX via an ioctl.
parent fcc9131e
......@@ -123,6 +123,7 @@ ifeq ($(WITH_SHD),1)
CFLAGS += -DWITH_SHD
SUBDIRS += shd
FSLIBS += shd/libshd.a
SHDLIBS += shd/libshd.a
endif
all: $(SUBDIRS) imagezip imageunzip imagedump imagehash
......@@ -145,8 +146,8 @@ imageunzip: imageunzip.o crc.o version.o
imageunzip.o: imageunzip.c
$(CC) -c $(UNZIPCFLAGS) -o imageunzip.o $<
imagedump: imagedump.o version.o
$(CC) $(CFLAGS) imagedump.o version.o $(LIBS) -o imagedump
imagedump: imagedump.o version.o $(SHDLIBS)
$(CC) $(CFLAGS) imagedump.o version.o $(LIBS) $(SHDLIBS) -o imagedump
imagehash: imagehash.o version.o
$(CC) $(CFLAGS) imagehash.o version.o $(HASHLIBS) -o imagehash
......
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2004 University of Utah and the Flux Group.
* Copyright (c) 2000-2005 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -24,6 +24,7 @@ static int detail = 0;
static int dumpmap = 0;
static int ignorev1 = 0;
static int infd = -1;
static char *chkpointdev;
static unsigned long long wasted;
static uint32_t sectinuse;
......@@ -35,6 +36,12 @@ static void usage(void);
static void dumpfile(char *name, int fd);
static int dumpchunk(char *name, char *buf, int chunkno, int checkindex);
#ifdef WITH_SHD
void add_shdrange(u_int32_t start, u_int32_t size);
int write_shd(char *shddev);
int debug = 0;
#endif
#define SECTOBYTES(s) ((unsigned long long)(s) * SECSIZE)
int
......@@ -43,7 +50,7 @@ main(int argc, char **argv)
int ch, version = 0;
extern char build_info[];
while ((ch = getopt(argc, argv, "dimv")) != -1)
while ((ch = getopt(argc, argv, "C:dimv")) != -1)
switch(ch) {
case 'd':
detail++;
......@@ -55,6 +62,9 @@ main(int argc, char **argv)
dumpmap++;
detail = 0;
break;
case 'C':
chkpointdev = optarg;
break;
case 'v':
version++;
break;
......@@ -235,6 +245,14 @@ dumpfile(char *name, int fd)
break;
}
done:
#ifdef WITH_SHD
if (chkpointdev && write_shd(chkpointdev)) {
fprintf(stderr, "Could not record SHD alloc block info\n");
exit(1);
}
#endif
if (filesize == 0)
filesize = (off_t)(chunkno + 1) * SUBBLOCKSIZE;
......@@ -394,6 +412,14 @@ dumpchunk(char *name, char *buf, int chunkno, int checkindex)
franges++;
}
#ifdef WITH_SHD
/*
* Accumulate SHD allocated list info
*/
if (chkpointdev)
add_shdrange(reg->start, reg->size);
#endif
count = reg->size;
sectinuse += count;
if (count < amin)
......
......@@ -88,6 +88,7 @@ void sortrange(struct range *head, int domerge,
int (*rangecmp)(struct range *, struct range *));
void makeranges(void);
void dumpranges(int verbose);
void addvalid(uint32_t start, uint32_t size);
void addreloc(off_t offset, off_t size, int reloctype);
static int cmpfixups(struct range *r1, struct range *r2);
static int read_doslabel(int infd, int lsect, int pstart,
......@@ -100,7 +101,8 @@ int compress_image(void);
void usage(void);
#ifdef WITH_SHD
int read_shd(char *shddev, char *infile, int infd, u_int32_t ssect);
int read_shd(char *shddev, char *infile, int infd, u_int32_t ssect,
void (*add)(uint32_t, uint32_t));
#endif
static SLICEMAP_PROCESS_PROTO(read_slice);
......@@ -503,7 +505,7 @@ main(int argc, char *argv[])
if (rval == 0) {
rval = read_shd(chkpointdev, infilename, infd,
inputminsec);
inputminsec, addvalid);
if (rval == 0)
sortrange(ranges, 1, 0);
}
......
......@@ -34,7 +34,8 @@ int fake_ioctl(int, int, void *);
#endif
int
read_shd(char *shddev, char *infile, int infd, u_int32_t ssect)
read_shd(char *shddev, char *infile, int infd, u_int32_t ssect,
void (*addvalid)(u_int32_t, u_int32_t))
{
int shdfd;
struct shd_modinfo sm;
......@@ -79,7 +80,7 @@ read_shd(char *shddev, char *infile, int infd, u_int32_t ssect)
if (debug > 2)
fprintf(stderr, " %12d %9d\n",
sr->start, (sr->end-sr->start));
addvalid(sr->start + ssect, (sr->end-sr->start));
(*addvalid)(sr->start + ssect, (sr->end-sr->start));
}
sm.command = 2;
......@@ -99,6 +100,55 @@ read_shd(char *shddev, char *infile, int infd, u_int32_t ssect)
return 0;
}
static struct shd_allocinfo alloclist;
int
write_shd(char *shddev)
{
int shdfd;
if (alloclist.buf == 0 || alloclist.bufsiz == 0)
return 0;
/*
* Open the shd device so we can ioctl
*/
shdfd = open(shddev, O_RDWR);
if (shdfd < 0) {
perror(shddev);
return 1;
}
if (SHDIOCTL(shdfd, SHDSETALLOCATEDRANGES, &alloclist) < 0) {
perror(shddev);
close(shdfd);
return 1;
}
close(shdfd);
free(alloclist.buf);
alloclist.buf = 0;
alloclist.bufsiz = 0;
return 0;
}
void
add_shdrange(u_int32_t start, u_int32_t size)
{
size_t nsize = (alloclist.bufsiz + 1) * sizeof(struct shd_range);
alloclist.buf = realloc(alloclist.buf, nsize);
if (alloclist.buf == 0) {
fprintf(stderr, "No memory for SHD alloc ranges\n");
exit(1);
}
alloclist.buf[alloclist.bufsiz].start = start;
alloclist.buf[alloclist.bufsiz].end = start + size;
alloclist.bufsiz++;
}
#ifdef FAKEIT
struct shd_range foo[] = {
......@@ -135,26 +185,47 @@ struct shd_range foo[] = {
int
fake_ioctl(int fd, int cmd, void *data)
{
struct shd_modinfo *sm = data;
static struct shd_range *fooptr, *out;
int i;
switch (sm->command) {
case 1:
fooptr = foo;
case 2:
out = sm->buf;
for (i = 0; i < sm->bufsiz; i++) {
if (fooptr->start == 0 && fooptr->size == 0)
break;
*out++ = *fooptr++;
switch (cmd) {
case SHDGETMODIFIEDRANGES:
{
struct shd_modinfo *sm = data;
switch (sm->command) {
case 1:
fooptr = foo;
case 2:
out = sm->buf;
for (i = 0; i < sm->bufsiz; i++) {
if (fooptr->start == 0 && fooptr->end == 0)
break;
out->start = fooptr->start;
out->end = fooptr->start + fooptr->end;
fooptr++, out++;
}
sm->retsiz = i;
break;
case 3:
break;
}
sm->retsiz = i;
break;
case 3:
break;
return 0;
}
return 0;
case SHDSETALLOCATEDRANGES:
{
struct shd_allocinfo *sa = data;
int i;
printf("SETALLOCATEDRANGES: %ld entries:\n", sa->bufsiz);
out = sa->buf;
for (i = 0; i < sa->bufsiz; i++) {
printf(" [%u-%u]\n", out->start, out->end);
out++;
}
return 0;
}
}
return -1;
}
#endif
......@@ -17,4 +17,10 @@ struct shd_modinfo {
long retsiz; /* size of returned data (in entries) */
};
#define SHDGETMODIFIEDRANGES _IOWR('S', 29, struct shd_modinfo)
struct shd_allocinfo {
struct shd_range *buf; /* range buffer */
long bufsiz; /* buffer size (in entries) */
};
#define SHDGETMODIFIEDRANGES _IOWR('S', 29, struct shd_modinfo)
#define SHDSETALLOCATEDRANGES _IOWR('S', 30, struct shd_allocinfo)
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