testisofs: restore & test ISO filesystem
. to restore isofs: fix a bug in isofs, allow non-pagesize-multiple blocksizes (but disable peek, i.e. mmap, functionality in that case). . to test isofs: prepare an ISO FS image using writeisofs, copy it to a RAM device, mount it using the iso9660fs server, compare the SHA1 contents of the files on the ISO with the inputs. . use su to run certain commands in the script as root Change-Id: I81c5c64a0073410197f3e442e23f8ddc1f9d216c
This commit is contained in:
parent
8704807cb3
commit
48be52fddd
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
/* writeisofs - simple ISO9660-format-image writing utility */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
|
@ -12,6 +13,7 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <partition.h>
|
||||
#include <minix/minlib.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
|
@ -277,10 +279,10 @@ void
|
|||
maketree(struct node *thisdir, char *name, int level)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *e;
|
||||
struct node *dirnodes = NULL;
|
||||
int reserved_dirnodes = 0, used_dirnodes = 0;
|
||||
int reserved_dirnodes = 0, used_dirnodes = 0, nentries;
|
||||
struct node *child;
|
||||
struct me_dirent *entries, *e;
|
||||
|
||||
thisdir->firstchild = NULL;
|
||||
thisdir->isdir = 1;
|
||||
|
|
@ -298,11 +300,11 @@ maketree(struct node *thisdir, char *name, int level)
|
|||
}
|
||||
|
||||
/* how many entries do we need to allocate? */
|
||||
while(readdir(dir)) reserved_dirnodes++;
|
||||
if(!reserved_dirnodes) {
|
||||
if(!(entries = minix_readdir(dir, &reserved_dirnodes))) {
|
||||
closedir(dir);
|
||||
return;
|
||||
}
|
||||
nentries = reserved_dirnodes;
|
||||
|
||||
if(!(dirnodes = malloc(sizeof(*dirnodes)*reserved_dirnodes))) {
|
||||
fprintf(stderr, "couldn't allocate dirnodes (%d bytes)\n",
|
||||
|
|
@ -315,7 +317,7 @@ maketree(struct node *thisdir, char *name, int level)
|
|||
rewinddir(dir);
|
||||
|
||||
child = dirnodes;
|
||||
while((e=readdir(dir))) {
|
||||
for(e = entries; nentries--; e++) {
|
||||
struct stat st;
|
||||
mode_t type;
|
||||
if(!strcmp(e->d_name, CURRENTDIR) || !strcmp(e->d_name, PARENTDIR))
|
||||
|
|
@ -328,10 +330,6 @@ maketree(struct node *thisdir, char *name, int level)
|
|||
|
||||
type = st.st_mode & S_IFMT;
|
||||
|
||||
/*
|
||||
printf("%s type: %x dir: %x file: %x\n",
|
||||
e->d_name, type, S_IFDIR, S_IFREG);
|
||||
*/
|
||||
if(type != S_IFDIR && type != S_IFREG)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
#ifndef _MINLIB
|
||||
#define _MINLIB
|
||||
|
||||
#if defined(_NETBSD_SOURCE)
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/* Miscellaneous BSD. */
|
||||
char *itoa(int _n);
|
||||
|
|
@ -16,6 +19,15 @@ int load_mtab(char *_prog_name);
|
|||
int get_mtab_entry(char dev[PATH_MAX], char mount_point[PATH_MAX],
|
||||
char type[MNTNAMELEN], char flags[MNTFLAGLEN]);
|
||||
|
||||
/* Returned by minix_readdir */
|
||||
#define ME_MAXNAME 256
|
||||
struct me_dirent {
|
||||
char d_name[ME_MAXNAME];
|
||||
};
|
||||
|
||||
struct me_dirent *minix_readdir(DIR *, int *n);
|
||||
void minix_free_readdir(struct me_dirent *md, int n);
|
||||
|
||||
/* read_tsc() and friends */
|
||||
void read_tsc(u32_t *hi, u32_t *lo);
|
||||
void read_tsc_64(u64_t *t);
|
||||
|
|
@ -27,3 +39,5 @@ void read_tsc_64(u64_t *t);
|
|||
#define FSVERSION_EXT2 0x10002
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -161,8 +161,12 @@ free_unused_blocks(void)
|
|||
static void
|
||||
lmfs_alloc_block(struct buf *bp)
|
||||
{
|
||||
int len;
|
||||
ASSERT(!bp->data);
|
||||
ASSERT(bp->lmfs_bytes == 0);
|
||||
|
||||
len = roundup(fs_block_size, PAGE_SIZE);
|
||||
|
||||
if((bp->data = minix_mmap(0, fs_block_size,
|
||||
PROT_READ|PROT_WRITE, MAP_PREALLOC|MAP_ANON, -1, 0)) == MAP_FAILED) {
|
||||
free_unused_blocks();
|
||||
|
|
@ -191,9 +195,12 @@ void minix_munmap_t(void *a, int len)
|
|||
assert(a);
|
||||
assert(a != MAP_FAILED);
|
||||
assert(len > 0);
|
||||
assert(!(len % PAGE_SIZE));
|
||||
assert(!(av % PAGE_SIZE));
|
||||
|
||||
len = roundup(len, PAGE_SIZE);
|
||||
|
||||
assert(!(len % PAGE_SIZE));
|
||||
|
||||
if(minix_munmap(a, len) < 0)
|
||||
panic("libminixfs cache: munmap failed");
|
||||
}
|
||||
|
|
@ -638,9 +645,8 @@ void lmfs_rw_scattered(
|
|||
}
|
||||
|
||||
assert(dev != NO_DEV);
|
||||
assert(!(fs_block_size % PAGE_SIZE));
|
||||
assert(fs_block_size > 0);
|
||||
iov_per_block = fs_block_size / PAGE_SIZE;
|
||||
iov_per_block = roundup(fs_block_size, PAGE_SIZE) / PAGE_SIZE;
|
||||
|
||||
/* (Shell) sort buffers on lmfs_blocknr. */
|
||||
gap = 1;
|
||||
|
|
@ -669,19 +675,24 @@ void lmfs_rw_scattered(
|
|||
int r;
|
||||
for (iop = iovec; nblocks < bufqsize; nblocks++) {
|
||||
int p;
|
||||
vir_bytes vdata;
|
||||
vir_bytes vdata, blockrem;
|
||||
bp = bufq[nblocks];
|
||||
if (bp->lmfs_blocknr != (block_t) bufq[0]->lmfs_blocknr + nblocks)
|
||||
break;
|
||||
if(niovecs >= NR_IOREQS-iov_per_block) break;
|
||||
vdata = (vir_bytes) bp->data;
|
||||
blockrem = fs_block_size;
|
||||
for(p = 0; p < iov_per_block; p++) {
|
||||
vir_bytes chunk = blockrem < PAGE_SIZE ? blockrem : PAGE_SIZE;
|
||||
iop->iov_addr = vdata;
|
||||
iop->iov_size = PAGE_SIZE;
|
||||
iop->iov_size = chunk;
|
||||
vdata += PAGE_SIZE;
|
||||
blockrem -= chunk;
|
||||
iop++;
|
||||
niovecs++;
|
||||
}
|
||||
assert(p == iov_per_block);
|
||||
assert(blockrem == 0);
|
||||
}
|
||||
|
||||
assert(nblocks > 0);
|
||||
|
|
@ -825,7 +836,7 @@ void lmfs_set_blocksize(int new_block_size, int major)
|
|||
|
||||
vmcache = 0;
|
||||
|
||||
if(may_use_vmcache)
|
||||
if(may_use_vmcache && !(new_block_size % PAGE_SIZE))
|
||||
vmcache = 1;
|
||||
}
|
||||
|
||||
|
|
@ -932,6 +943,10 @@ int lmfs_do_bpeek(message *m)
|
|||
assert(fs_block_size > 0);
|
||||
assert(dev != NO_DEV);
|
||||
|
||||
if(!vmcache) { return ENXIO; }
|
||||
|
||||
assert(!(fs_block_size % PAGE_SIZE));
|
||||
|
||||
if((extra=(pos % fs_block_size))) {
|
||||
pos -= extra;
|
||||
len += extra;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
#include <minix/config.h> /* for unused stuff in <minix/type.h> :-( */
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h> /* for unshort :-( */
|
||||
|
|
@ -11,6 +14,7 @@
|
|||
#include "mfs/inode.h" /* ditto */
|
||||
#include "mfs/super.h"
|
||||
#include <minix/fslib.h>
|
||||
#include <minix/minlib.h>
|
||||
|
||||
/* The next routine is copied from fsck.c and mkfs.c... (Re)define some
|
||||
* things for consistency. Some things should be done better.
|
||||
|
|
@ -188,3 +192,61 @@ int norm; /* TRUE = do not swap bytes; FALSE = swap */
|
|||
dip->d2_zone[i] = conv4(norm, (long) rip->i_zone[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare dirent objects for order */
|
||||
static int cmp_dirent(const void *d1, const void *d2)
|
||||
{
|
||||
struct me_dirent *dp1 = (struct me_dirent *) d1,
|
||||
*dp2 = (struct me_dirent *) d2;
|
||||
return strcmp(dp1->d_name, dp2->d_name);
|
||||
}
|
||||
|
||||
/* Return array of me_dirents. */
|
||||
struct me_dirent *minix_readdir(DIR *dirp, int *n)
|
||||
{
|
||||
struct dirent *rdp;
|
||||
struct me_dirent *dp;
|
||||
struct me_dirent *dirents = NULL;
|
||||
int reserved_dirents = 0;
|
||||
int entries = 0;
|
||||
|
||||
while((rdp = readdir(dirp)) != NULL) {
|
||||
if(entries >= reserved_dirents) {
|
||||
struct me_dirent *newdirents;
|
||||
int newreserved = (2*(reserved_dirents+1));
|
||||
if(!(newdirents = realloc(dirents, newreserved *
|
||||
sizeof(*dirents)))) {
|
||||
free(dirents);
|
||||
return NULL;
|
||||
}
|
||||
dirents = newdirents;
|
||||
reserved_dirents = newreserved;
|
||||
}
|
||||
|
||||
assert(entries < reserved_dirents);
|
||||
assert(strlen(rdp->d_name) < sizeof(dp->d_name));
|
||||
dp = &dirents[entries];
|
||||
memset(dp, 0, sizeof(*dp));
|
||||
strcpy(dp->d_name, rdp->d_name);
|
||||
entries++;
|
||||
}
|
||||
|
||||
/* Assume directories contain at least "." and "..", and
|
||||
* therefore the array exists.
|
||||
*/
|
||||
assert(entries > 0);
|
||||
assert(dirents);
|
||||
|
||||
/* normalize (sort) them */
|
||||
qsort(dirents, entries, sizeof(*dp), cmp_dirent);
|
||||
|
||||
/* Return no. of entries. */
|
||||
*n = entries;
|
||||
|
||||
return dirents;
|
||||
}
|
||||
|
||||
void minix_free_readdir(struct me_dirent *md, int n)
|
||||
{
|
||||
free(md);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ int fs_read(void) {
|
|||
int rw;
|
||||
|
||||
switch(fs_m_in.m_type) {
|
||||
case REQ_READ: rw = READING;
|
||||
case REQ_PEEK: rw = PEEKING;
|
||||
case REQ_READ: rw = READING; break;
|
||||
case REQ_PEEK: rw = PEEKING; break;
|
||||
default: panic("odd m_type");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ PROGS+= test${t}
|
|||
PROGS+= t10a t11a t11b t40a t40b t40c t40d t40e t40f t60a t60b \
|
||||
t67a t67b t68a t68b
|
||||
|
||||
SCRIPTS+= run testinterp.sh testsh1.sh testsh2.sh testfs.sh
|
||||
SCRIPTS+= run testinterp.sh testsh1.sh testsh2.sh testfs.sh testisofs.sh
|
||||
|
||||
.if ${MKPIC} == "yes"
|
||||
# Build them as dynamic executables by default if shared libraries
|
||||
|
|
|
|||
2
test/run
2
test/run
|
|
@ -25,7 +25,7 @@ alltests=" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
|
|||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
|
||||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
|
||||
61 62 63 64 65 66 67 68 69 70 71 72 75 \
|
||||
sh1.sh sh2.sh interp.sh fs.sh"
|
||||
sh1.sh sh2.sh interp.sh fs.sh isofs.sh"
|
||||
tests_no=`expr 0`
|
||||
|
||||
# test mmap only if enabled in sysenv
|
||||
|
|
|
|||
68
test/testisofs.sh
Normal file
68
test/testisofs.sh
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Create and verify a simple ISO filesystem
|
||||
#
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
|
||||
set -e
|
||||
|
||||
echo -n "isofs test "
|
||||
|
||||
ramdev=/dev/ram
|
||||
mp=/mnt
|
||||
testdir=isofstest
|
||||
fsimage=isofsimage
|
||||
contents=CONTENTS
|
||||
out1=v1
|
||||
out2=v2
|
||||
rm -rf $testdir $fsimage $out1 $out2
|
||||
|
||||
if [ -d $testdir ]
|
||||
then echo "dir?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $testdir $testdir/$contents
|
||||
|
||||
if [ ! -d $testdir ]
|
||||
then echo "no dir?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make some small & big & bigger files
|
||||
|
||||
prevf=$testdir/$contents/FILE
|
||||
echo "Test contents 123" >$prevf
|
||||
for double in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
do fn=$testdir/$contents/FN.$double
|
||||
cat $prevf $prevf >$fn
|
||||
prevf=$fn
|
||||
done
|
||||
|
||||
# Make an ISO filesystem image out of it
|
||||
writeisofs -s0x0 -l MINIX $testdir $fsimage >/dev/null 2>&1
|
||||
|
||||
# umount previous things
|
||||
su root -c "umount $ramdev 2>/dev/null || true"
|
||||
su root -c "umount $mp 2>/dev/null || true"
|
||||
|
||||
# Mount it on a RAM disk
|
||||
su root -c "ramdisk 50000 $ramdev >/dev/null 2>&1"
|
||||
su root -c "cp $fsimage $ramdev"
|
||||
su root -c "mount -t isofs $ramdev $mp >/dev/null 2>&1"
|
||||
|
||||
# compare contents
|
||||
(cd $testdir/$contents && sha1 * | sort) >$out1
|
||||
(cd $mp/$contents && sha1 * | sort) >$out2
|
||||
|
||||
diff -u v1 v2
|
||||
|
||||
echo ok
|
||||
|
||||
su root -c 'umount $ramdev >/dev/null 2>&1'
|
||||
|
||||
# cleanup
|
||||
rm -rf $testdir $fsimage $out1 $out2
|
||||
|
||||
exit 0
|
||||
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
PROG= mkproto
|
||||
MAN=
|
||||
|
||||
LDADD+= -lminlib
|
||||
DPADD+= ${LIBMINLIB}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <minix/minlib.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -43,12 +44,6 @@ void display_attrib(const char *name, struct stat *st);
|
|||
void usage(char *binname);
|
||||
void open_outfile(void);
|
||||
|
||||
#define MAXNAME 256
|
||||
|
||||
struct mkproto_dirent {
|
||||
char d_name[MAXNAME];
|
||||
};
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
|
|
@ -135,27 +130,18 @@ char *argv[];
|
|||
return(0);
|
||||
}
|
||||
|
||||
/* Compare dirent objects for order */
|
||||
static int cmp_dirent(const void *d1, const void *d2)
|
||||
{
|
||||
struct mkproto_dirent *dp1 = (struct mkproto_dirent *) d1,
|
||||
*dp2 = (struct mkproto_dirent *) d2;
|
||||
return strcmp(dp1->d_name, dp2->d_name);
|
||||
}
|
||||
|
||||
/* Output the prototype spec for this directory. */
|
||||
void descend(dirname)
|
||||
char *dirname;
|
||||
{
|
||||
struct dirent *rdp;
|
||||
struct mkproto_dirent *dirents = NULL, *dp;
|
||||
int reserved_dirents = 0;
|
||||
struct me_dirent *dirents;
|
||||
DIR *dirp;
|
||||
char *name, *temp, *tempend;
|
||||
int i;
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
int entries = 0;
|
||||
int entries = 0, orig_entries;
|
||||
struct me_dirent *dp;
|
||||
|
||||
dirp = opendir(dirname);
|
||||
if (dirp == NULL) {
|
||||
|
|
@ -169,26 +155,11 @@ char *dirname;
|
|||
tempend = &temp[strlen(temp)];
|
||||
|
||||
/* read all directory entries */
|
||||
for (rdp = readdir(dirp); rdp != NULL; rdp = readdir(dirp)) {
|
||||
if(entries >= reserved_dirents) {
|
||||
int newreserved = (2*(reserved_dirents+1));
|
||||
if(!(dirents = realloc(dirents, newreserved *
|
||||
sizeof(*dirents)))) {
|
||||
errx(1, "realloc failed on dirents");
|
||||
}
|
||||
reserved_dirents = newreserved;
|
||||
}
|
||||
assert(entries < reserved_dirents);
|
||||
assert(strlen(rdp->d_name) < sizeof(dp->d_name));
|
||||
dp = &dirents[entries];
|
||||
strcpy(dp->d_name, rdp->d_name);
|
||||
entries++;
|
||||
}
|
||||
if(!(dirents = minix_readdir(dirp, &entries)))
|
||||
errx(1, "minix_readdir failed");
|
||||
orig_entries = entries;
|
||||
closedir(dirp);
|
||||
|
||||
/* normalize (sort) them */
|
||||
qsort(dirents, entries, sizeof(*dp), cmp_dirent);
|
||||
|
||||
for (dp = dirents; entries > 0; dp++, entries--) {
|
||||
name = dp->d_name;
|
||||
|
||||
|
|
@ -243,7 +214,7 @@ char *dirname;
|
|||
fprintf(stderr,"File\n\t%s\n has an invalid mode, made empty.\n",temp);
|
||||
}
|
||||
free(temp);
|
||||
free(dirents);
|
||||
minix_free_readdir(dirents, orig_entries);
|
||||
tabs--;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user