--- /dev/null
+#!/bin/sh
+# Script to remove the loopback device and temp file created in newtest.sh
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+[ "$LOOPDEV" ] && losetup -d $LOOPDEV
+[ "$TMPFILE" ] && rm $TMPFILE
+
--- /dev/null
+#! /bin/sh
+# Get the locations for the files from a single place to avoid confusion
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+#if [ "$TMPFILE" -a -f $TMPFILE ]; then
+# echo "$TMPFILE exists; I'm unwilling to overwrite it." 1>&2
+# exit 1
+#fi
+
+# We assume the loop module will be installed by kerneld if required.
+# If not, the following line should be uncommented.
+#insmod loop
+
+if [ "$LOOPDEV" -a "`losetup $LOOPDEV 2> /dev/null`" ]; then
+ echo "It appears that $LOOPDEV is in use. Unable to continue" 1>&2
+ echo "You need to clean up $LOOPDEV (via cleanup.sh),"
+ echo "or you can change which device is used in demos/config.sh" 1>&2
+ exit 2
+fi
+
+[ "$TMPFILE" ] && dd if=/dev/zero of=$TMPFILE bs=1k count=10k
+
+[ "$LOOPDEV" ] && losetup $LOOPDEV $TMPFILE
+if [ "$BASEDEV" ]; then
+ mke2fs -b 4096 $BASEDEV
+else
+ echo "\$BASEDEV not defined in demos/config.sh. Please fix!"
+ exit 1
+fi
--- /dev/null
+#!/bin/sh
+# File which holds configuation parameters in a single place to avoid any
+# mismatch between scripts (especially the cleanup scripts, which are
+# destructive).
+#set -vx
+
+# If LOOPDEV is empty (""), then no loopback device will be configured.
+# If TMPFILE is empty (""), then no temporary file will be created for loop.
+TMPFILE="/tmp/obdfs.tmpfile"
+LOOPDEV="/dev/loop0"
+
+# If LOOPDEV is empty, then it is assumed that BASEDEV is a real block device
+# that doesn't mind being overwritten - don't use a partition with data on it!!
+BASEDEV="$LOOPDEV"
+
+# The following are mount points for the filesystems during the test.
+MNTOBD="/mnt/obd"
+MNTSNAP="/mnt/snap"
+MNTSNAP2="/mnt/snap2"
+
+# This is where the snapshot table will be stored:
+SNAPTABLE="/tmp/obdfs.snaptable"
+
+# A simple routine called by most of the scripts to help debugging. The
+# kernel code has a lot of debugging statements, so this helps us keep
+# track of what is going on in user-land to generate the kernel messages.
+plog () {
+ LOGMETH="kern.debug"
+ if [ "$1" = "log" ]; then
+ logger -p $LOGMETH "******** $* **********"
+ shift
+ echo "$*"
+ else
+ logger -p $LOGMETH "****start**** $* *****"
+ echo "$*"
+ $*
+ sleep 3
+ logger -p $LOGMETH "*****end***** $* *****"
+ fi
+}
+
--- /dev/null
+#!/bin/sh
+# Utility script for cleaning up a simple OBDFS mounted filesystem
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+umount $MNTOBD
+rmmod obdfs
+
+$OBDDIR/class/obdcontrol -f << EOF
+cleanup
+detach
+quit
+EOF
+
+rmmod obdext2
+rmmod obdclass
+
+$OBDDIR/demos/baseclean.sh
--- /dev/null
+#! /bin/bash
+# Utility script for configuring a simple OBDFS mount
+
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/basesetup.sh
+
+insmod $OBDDIR/class/obdclass.o
+insmod $OBDDIR/ext2obd/obdext2.o
+insmod $OBDDIR/obdfs/obdfs.o
+
+plog log "CREATING /dev/obd0"
+$OBDDIR/class/obdcontrol -f << EOF
+attach ext2_obd $BASEDEV
+setup
+quit
+EOF
+[ ! -d $MNTOBD ] && mkdir $MNTOBD
+plog mount -t obdfs -odevice=/dev/obd0 /dev/obd0 $MNTOBD
--- /dev/null
+#!/bin/sh
+# Utility script for cleaning up a third snapshot created by setup3.sh
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+plog umount $MNTSNAP2
+
+plog log "CLEANUP /dev/obd3"
+$OBDDIR/class/obdcontrol -f << EOF
+device /dev/obd3
+cleanup
+detach
+quit
+EOF
+
+$OBDDIR/demos/snapclean.sh
--- /dev/null
+#!/bin/sh
+# Utility script for creating a third snapshot.
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+[ ! -d $MNTSNAP/lost+found ] && $OBDDIR/demos/snapsetup.sh
+
+$OBDDIR/demos/snaptest.sh
+
+sync
+sleep 5 # let syslog logs get written
+
+plog log "CREATING /dev/obd3 snapshot"
+$OBDDIR/class/obdcontrol -f << EOF
+snaptable
+$SNAPTABLE
+a
+3
+now
+q
+y
+snapset 0 $SNAPTABLE
+device /dev/obd3
+attach snap_obd 0 3 0
+setup
+quit
+EOF
+
+[ ! -d "$MNTSNAP2" ] && mkdir $MNTSNAP2
+plog mount -t obdfs -oro,device=/dev/obd3 /dev/obd3 $MNTSNAP2
--- /dev/null
+#! /bin/bash
+# Utility script for cleaning up snapshots and removing modules.
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+plog umount $MNTOBD
+plog umount $MNTSNAP
+
+plog log "CLEANUP /dev/obd2 /dev/obd1"
+$OBDDIR/class/obdcontrol -f << EOF
+device /dev/obd2
+cleanup
+detach
+device /dev/obd1
+cleanup
+detach
+quit
+EOF
+
+rmmod obdsnap
+
+$OBDDIR/demos/obdclean.sh
--- /dev/null
+#!/bin/sh
+# Utility script to test deleting a snapshot that has been previously
+# created as the setup.sh script does.
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+[ ! -d $MNTSNAP/lost+found ] && echo "need to run obdsetup.sh first" && exit 1
+plog umount $MNTSNAP
+plog umount $MNTOBD
+
+sync
+sleep 1
+plog log "STARTING snapdelete"
+$OBDDIR/class/obdcontrol -f << EOF
+device /dev/obd2
+connect
+snapdelete
+disconnect
+cleanup
+detach
+snaptable
+$SNAPTABLE
+d
+2
+q
+y
+snapset 0 $SNAPTABLE
+EOF
+plog log "COMPLETE snapdelete"
+plog mount -t obdfs -odevice=/dev/obd1 /dev/obd1 $MNTOBD
--- /dev/null
+#!/bin/sh
+# Utility script to test restoring a previous snapshot. This will destroy
+# the "current" snapshot and restore the old one in its place.
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+[ ! -d $MNTSNAP/lost+found ] && echo "need to run snapsetup.sh first" && exit 1
+
+plog umount $MNTSNAP
+plog umount $MNTOBD
+
+sync
+sleep 1
+rm $SNAPTABLE
+plog log "STARTING snaprestore"
+$OBDDIR/class/obdcontrol -f << EOF
+snaptable
+$SNAPTABLE
+a
+1
+now
+a
+2
+current
+q
+y
+snapset 0 $SNAPTABLE
+device /dev/obd2
+connect
+snaprestore 1
+disconnect
+EOF
+plog log "COMPLETE snaprestore"
+
+plog mount -t obdfs -odevice=/dev/obd1 /dev/obd1 $MNTOBD
--- /dev/null
+#! /bin/bash
+# Utility script to create an OBD snapshot. If an existing filesystem is
+# not already mounted on /mnt/obd, we call the basic OBD setup script to
+# create and mount a filesystem for us.
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+[ ! -d $MNTOBD/lost+found ] && $OBDDIR/demos/obdsetup.sh
+
+[ ! -f $MNTDIR/hello ] && $OBDDIR/demos/obdtest.sh
+
+umount $MNTOBD
+
+insmod $OBDDIR/snap/obdsnap.o
+
+rm -f $SNAPTABLE
+
+plog log "NEW SNAP SETUP"
+# Create two snapshots using the OBD snapshot driver. One will be the
+# "current" snapshot (in obd device 1), where changes will take place.
+# The current snapshot is required in order to use the filesystem. The
+# second will be a snapshot of the filesystem taken "now" (in obd device 2)
+# that will remain static (historical read-only) filesystem as changes
+# are made to the current snapshot.
+$OBDDIR/class/obdcontrol -f << EOF
+snaptable
+$SNAPTABLE
+a
+1
+current
+a
+2
+now
+q
+y
+snapset 0 $SNAPTABLE
+device /dev/obd1
+attach snap_obd 0 1 0
+setup snap_obd
+device /dev/obd2
+attach snap_obd 0 2 0
+setup snap_obd
+quit
+EOF
+
+# Mount the two filesystems. The filesystem under $MNTOBD will be the
+# one where changes are made, while $MNTSNAP will contain the original
+# files at the point when the snapshot was taken.
+[ ! -d $MNTOBD ] && mkdir $MNTOBD
+plog mount -t obdfs -odevice=/dev/obd1 /dev/obd1 $MNTOBD
+[ ! -d $MNTSNAP ] && mkdir $MNTSNAP
+plog mount -t obdfs -oro,device=/dev/obd2 /dev/obd2 $MNTSNAP
--- /dev/null
+#!/bin/sh
+# Utility script to perform minor modifications to the read-write mounted
+# snapshot in order to demonstrate the changes w.r.t. the read-only snapshot
+OBDDIR="`dirname $0`/.."
+[ "$OBDDIR" = "" ] && OBDDIR=".."
+. $OBDDIR/demos/config.sh
+
+plog chmod 777 $MNTOBD # change attributes on an existing file
+plog rm $MNTOBD/a # delete an existing file
+plog echo "today" >> $MNTOBD/hello # modify an existing file
+plog cp /etc/group $MNTOBD # create a new file
+plog ln -s goodbye $MNTOBD/newlink # create a new symlink
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <asm/statfs.h>
+#include <unistd.h>
+
+#define OBD_IOC_CREATE _IOR('f', 3, long)
+#define OBD_IOC_SETUP _IOW('f', 4, long)
+#define OBD_IOC_SYNC _IOR('f', 16, long)
+#define OBD_IOC_DESTROY _IOW('f', 6, long)
+#define OBD_IOC_STATFS _IORW('f', 15, long)
+
+#define LOOP_DEVICE "/dev/loop0"
+#define OBD_DEVICE "/dev/obd"
+
+int main (int argc, char * argv[])
+{
+ int fd, rc, err = -1;
+ struct stat stat_buf;
+ struct statfs stfs;
+
+
+ if (argc < 2) {
+ printf("syntax: %s command [argument]\n", argv[0]);
+ printf("Where command is one of \"setup\", \"create\", \"destroy\", or \"sync\".\n");
+ exit(1);
+ }
+ if (stat(LOOP_DEVICE, &stat_buf)) {
+ printf("Couldn't stat(" LOOP_DEVICE ").\n");
+ exit(1);
+ }
+ printf("Device: %u\n", (unsigned int) stat_buf.st_rdev);
+
+ fd = open (OBD_DEVICE, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open " OBD_DEVICE ".\n");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "setup")) {
+ rc = ioctl(fd, OBD_IOC_SETUP, &stat_buf.st_rdev);
+ fprintf(stderr, "rc = %d, errno = %d\n", rc, errno);
+ } else if (!strcmp(argv[1], "create")) {
+ int iter, i;
+
+ if (argc < 3) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+
+ iter = atoi(argv[2]);
+ if (iter < 1) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+ printf("creating %d objects...\n", iter);
+
+ for (i = 0; i < iter; i++) {
+ if ((rc = ioctl(fd, OBD_IOC_CREATE, &err))) {
+ fprintf(stderr, "Error; aborting.\n");
+ break;
+ }
+ if ((rc = ioctl(fd, OBD_IOC_DESTROY, &err))) {
+ fprintf(stderr, "Error; aborting.\n");
+ break;
+ }
+ }
+ fprintf(stderr, "rc = %d, errno = %d, err = %d\n",
+ rc, errno, err);
+ } else if (!strcmp(argv[1], "sync")) {
+ rc = ioctl(fd, OBD_IOC_SYNC, &err);
+ fprintf(stderr, "rc = %d, errno = %d, err = %d\n",
+ rc, errno, err);
+ } else if (!strcmp(argv[1], "destroy")) {
+ int ino;
+
+ if (argc < 3) {
+ printf("destroy requires a nonzero inode number.\n");
+ exit(1);
+ }
+
+ ino = atoi(argv[2]);
+ if (ino < 1) {
+ printf("destroy requires a nonzero inode number.\n");
+ exit(1);
+ }
+
+ rc = ioctl(fd, OBD_IOC_DESTROY, &ino);
+ fprintf(stderr, "rc = %d, errno = %d\n", rc, errno);
+ } else {
+ printf("Invalid command, run with no arguments for help.\n");
+ }
+ close(fd);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Beware when setting FSROOT that I've not made any attempts to avoid buffer
+ * overruns below--this is a test program, it's a static buffer. */
+#define FSROOT "/mnt"
+#define OBD_ITERATIONS 10000
+
+int main (int argc, char * argv[])
+{
+ int fd, rc, err = -1;
+ struct stat stat_buf;
+
+ if (argc < 2) {
+ printf("syntax: %s command\n", argv[0]);
+ printf("Where command is one of \"setup\" or \"create\".\n");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "setup")) {
+ printf("This is silly.\n");
+ } else if (!strcmp(argv[1], "create")) {
+ int i, iter;
+
+ if (argc < 3) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+
+ iter = atoi(argv[2]);
+
+ if (iter < 1) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+ printf("creating %d files...\n", iter);
+
+ for (i = 0; i < iter; i++) {
+ fd = creat(FSROOT "/foo123", S_IRWXU);
+ close(fd);
+ unlink(FSROOT "/foo123");
+ }
+ } else {
+ printf("Invalid command, run with no arguments for help.\n");
+ }
+
+ return 0;
+}
+++ /dev/null
-#!/bin/sh
-
-umount /mnt/obd
-rmmod obdfs
-
-../class/obdcontrol -f << EOF
-cleanup
-detach
-quit
-EOF
-
-rmmod obdext2
-rmmod obdclass
-[ "`lsmod | grep loop`" ] && rmmod loop
my %commands =
('device' => {func => "Device", doc => "device <dev>: open another OBD device"},
- 'filesystem' => {func => "Filesystem", doc => "filesystem <dev>: partition for direct OBD device"},
'create' => {func => "Create", doc => "create: creates a new inode"},
- 'attach' => {func => "Attach", doc => "attach type [adapter bus tid lun]"},
+ 'attach' => {func => "Attach", doc => "attach { ext2_obd | snap_obd snapdev snapidx tableno}"}, # | scsi_obd adapter bus tid lun |
'detach' => {func => "Detach", doc => "detach this device"},
- 'testext2iterator' => {func => "TestExt2Iterator", doc => ""},
- 'snapattach' => {func => "SnapAttach", doc => "snapattach snapdev snapidx tableno"},
+ 'testext2iterator' => {func => "TestExt2Iterator", doc => "test ext2 iterator function"},
'snapset' => {func => "SnapSetTable", doc => "snapset tableno file" },
'snapprint' => {func => "SnapPrint", doc => "snapprint tableno"},
'snapdelete' => {func => "SnapDelete", doc => "snapdelete: delete connected snap obd"},
'migrate' => {func => "Migrate", doc => "migrate srcid tgtid"},
'format' => {func => "Format", doc => "format type adapter bus tid lun size"},
'partition' => {func => "Partition", doc => "partition type adapter bus tid lun partition size"},
- 'setup' => {func => "Setup", doc => "setup [type]: link this OBD device to the underlying device (default type ext2_obd, filesystem /dev/loop0)"},
+ 'setup' => {func => "Setup", doc => "setup [type]: link this OBD device to the underlying device (default type ext2_obd)"},
'connect' => {func => "Connect", doc => "connect: allocates client ID for this session"},
'disconnect' => {func => "Disconnect", doc => "disconnect [id]: frees client resources"},
'sync' => {func => "Sync", doc => "sync: flushes buffers to disk"},
my $str = <STDIN>;
chop($str);
return $str;
- } else {
- return $term->readline(@_);
- }
+ } else {
+ return $term->readline(@_);
+ }
}
if ( $file ) {
- while ( <STDIN> ) {
- print $_;
- execute_line($_);
- }
- exit 0;
+ while ( <STDIN> ) {
+ print $_;
+ execute_line($_);
+ }
+ exit 0;
} else {
$term = new Term::ReadLine 'obdcontrol ';
$attribs = $term->Attribs;
my $datalen = 0;
if ( ! $type ) {
- print "Usage \"attach type (ext2_obd)\";
+ print "error: missing type\n";
+usage:
+ print "usage: attach {ext2_obd | snap_obd}\n"; # XXX add scsi_obd later
+ return;
+ }
- if ($type eq "obdscsi" ) {
+ if ($type eq "scsi_obd" ) {
my $adapter = shift;
my $bus = shift;
my $tid = shift;
my $lun = shift;
- $data = pack("iiiii", $adapter, $bus, $tid, $lun, $size);
+
+ $data = pack("iiii", $adapter, $bus, $tid, $lun);
$datalen = 4 * 4;
+ } elsif ($type eq "snap_obd" ) {
+ my $snapdev = shift;
+ my $snapidx = shift;
+ my $tableno = shift;
+
+ $data = pack("iii", $snapdev, $snapidx, $tableno);
+ $datalen = 3 * 4;
+ } elsif ($type eq "ext2_obd") {
+ my $basedev = shift;
+ # $basedev = "/dev/loop0" unless $basedev;
+
+ if (!defined($::st = stat($basedev))) {
+ die "Unable to stat $basedev.\n";
+ }
+ } else {
+ print "error: unknown attach type $type\n";
+ goto usage;
}
+ my $len = length($type);
+ my $cl = length($data);
+
+ print "type $type (len $len), datalen $datalen ($cl)\n";
my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
}
-sub SnapAttach {
- my $err = 0;
- my $type = "snap_obd";
- my $snapdev = shift;
- my $snapidx = shift;
- my $tableno = shift;
- my $snapcount;
- my $data;
- my $datalen = 0;
-
- $data = pack("iii", $snapdev, $snapidx, $tableno);
- $datalen = 3 * 4;
-
- my $len = length($type);
- my $cl = length($data);
- my $add = pack("p", $data);
- print "type $type (len $len), datalen $datalen ($cl)\n";
- my $packed = pack("Lipip", $::client_id, length($type), $type, $datalen, $data);
-
- my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
-
- if (!defined $rc) {
- print STDERR "ioctl failed: $!\n";
- } elsif ($rc eq "0 but true") {
- print "Finished (success)\n";
- } else {
- print "ioctl returned error code $rc.\n";
- }
-}
-
-
sub SnapShotTable {
my $file = &readl("enter file name: ");
done:
my $ok = &readl("OK with new table? [Yn]: ");
unless ( $ok eq "no" ) {
- WriteSnapShotTable($file, $table);
- }
+ WriteSnapShotTable($file, $table);
+ }
}
sub SnapFindTimeFromIdx {
if ( $type eq "ext2_obd" ) {
my $dev = shift;
- my $st = stat($dev);
- $dev = $st->rdev() unless $dev;
+ $dev = $::st->rdev() unless $dev;
$data = pack("i", $dev);
$datalen = 4;
}
my $rc;
my $prealloc = 0;
- if (defined($quiet) && !($quiet eq "quiet")) {
+ if (defined($quiet) && $quiet ne "quiet") {
print "syntax: create [number of objects [quiet]]\n";
return;
}
for ($i = 0; $i < scalar($arg); $i++) {
$rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $packed);
my $ino = unpack("L", $packed);
- if (!($rc eq "0 but true")) {
+ if ($rc ne "0 but true") {
last;
$packed = pack("IL", $::client_id, $prealloc);
} elsif (!defined($quiet)) {
+++ /dev/null
-#! /bin/bash
-if [ -f /tmp/fs ]; then
- echo "/tmp/fs exists; I'm unwilling to overwrite it"
- exit
-fi
-
-dd if=/dev/zero of=/tmp/fs bs=1k count=10k
-
-#insmod loop
-losetup /dev/loop0 /tmp/fs
-
-mke2fs -b 4096 /dev/loop0
-
-insmod ../class/obdclass.o
-insmod ../ext2obd/obdext2.o
-insmod ../obdfs/obdfs.o
-
-echo "NEW OBDFS setup..." >> /var/log/messages
-
-../class/obdcontrol -f << EOF
-attach ext2_obd
-setup
-quit
-EOF
-echo "NEW OBDFS mount..." >> /var/log/messages
-mount -t obdfs -odevice=/dev/obd0 /dev/obd0 /mnt/obd
-echo "NEW OBDFS usage..." >> /var/log/messages