Browse Source

Import upstream version 22

Ed Cashin 9 years ago
parent
commit
a4dcd7e4af
11 changed files with 130 additions and 41 deletions
  1. 4 0
      .gitignore
  2. 8 2
      HACKING
  3. 14 0
      NEWS
  4. 8 3
      README
  5. 33 2
      aoe.c
  6. 22 13
      ata.c
  7. 11 16
      bpf.c
  8. 2 1
      dat.h
  9. 17 1
      freebsd.c
  10. 3 3
      linux.c
  11. 8 0
      vblade.8

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+*.orig
+cscope.*
+*.rej
+*~

+ 8 - 2
HACKING

@@ -1,4 +1,4 @@
-Contributions to the vblade are welcome.  
+Contributions to the vblade are welcome.
 
 
 In contributing, though, please stay true to the original simplicity
 In contributing, though, please stay true to the original simplicity
 of the software.  Many open source projects suffer from the "creeping
 of the software.  Many open source projects suffer from the "creeping
@@ -7,7 +7,8 @@ feature, first seriously try to think of a way to accomplish your goal
 without adding to the vblade itself.
 without adding to the vblade itself.
 
 
 Patches should be clean (to the point and easy to read) and should do
 Patches should be clean (to the point and easy to read) and should do
-one thing.  Send multiple patches if necessary.  Patches should be
+one thing.  (Avoid, for example, mixing style changes with substantive
+changes.)  Send multiple patches if necessary.  Patches should be
 generated with "diff -uprN" if possible, and should be designed to be
 generated with "diff -uprN" if possible, and should be designed to be
 applied with "patch -p1".
 applied with "patch -p1".
 
 
@@ -28,3 +29,8 @@ When you send your patch, here are some things to cover:
 
 
   * If your changes affect the end-user experience, have you updated
   * If your changes affect the end-user experience, have you updated
     the vblade documentation?
     the vblade documentation?
+
+  * Is your email client able to send a patch without changing it?
+    Many email clients and servers corrupt patches.  Please test your
+    email chain by sending an applying a patch before sending your
+    patch to the mailing list.

+ 14 - 0
NEWS

@@ -1,4 +1,18 @@
 -*- change-log -*-
 -*- change-log -*-
+2014-08-10 Ed Cashin <ed.cashin@acm.org>
+	vblade-22
+
+2014-06-08 Ed Cashin <ed.cashin@acm.org>
+	update version for v22 release candidate 1
+	buffer boundary cleanups
+	FreeBSD BPF and MTU fixes from Catalin Salgau
+	offset and size options by Christoph Biedl
+	vblade-22rc1
+
+2013-03-18 Ed Cashin <ecashin@coraid.com>
+	add big-endian support from Daniel Mealha Cabrita <dancab@gmx.net>
+	vblade-21
+
 2009-08-14 Sam Hopkins <sah@coraid.com>
 2009-08-14 Sam Hopkins <sah@coraid.com>
 	bugfix: aoe command error did not set Error bit in flags
 	bugfix: aoe command error did not set Error bit in flags
 	add support for AoEr11
 	add support for AoEr11

+ 8 - 3
README

@@ -2,9 +2,14 @@
 INTRODUCTION
 INTRODUCTION
 ------------
 ------------
 
 
-The vblade is the virtual EtherDrive (R) blade, a program that makes a
-seekable file available over an ethernet local area network (LAN) via
-the ATA over Ethernet (AoE) protocol.
+The vblade is a minimal ATA over Ethernet (AoE) storage target.  Its
+focus is simplicity, not performance or richness of features.  It
+exports a seekable file available over an ethernet local area network
+(LAN) via the AoE data storage protocol.
+
+The name, "vblade," is historical: It is a virtual EtherDrive (R)
+blade.  The first AoE target hardware sold by Coraid was in a blade
+form factor, ten to a 4-rack-unit chassis.
 
 
 The seekable file is typically a block device like /dev/md0 but even
 The seekable file is typically a block device like /dev/md0 but even
 regular files will work.  Sparse files can be especially convenient.
 regular files will work.  Sparse files can be especially convenient.

+ 33 - 2
aoe.c

@@ -379,7 +379,7 @@ aoe(void)
 void
 void
 usage(void)
 usage(void)
 {
 {
-	fprintf(stderr, "usage: %s [-b bufcnt] [-d ] [-s] [-r] [ -m mac[,mac...] ] shelf slot netif filename\n", 
+	fprintf(stderr, "usage: %s [-b bufcnt] [-o offset] [-l length] [-d ] [-s] [-r] [ -m mac[,mac...] ] shelf slot netif filename\n", 
 		progname);
 		progname);
 	exit(1);
 	exit(1);
 }
 }
@@ -462,11 +462,14 @@ int
 main(int argc, char **argv)
 main(int argc, char **argv)
 {
 {
 	int ch, omode = 0, readonly = 0;
 	int ch, omode = 0, readonly = 0;
+	vlong length = 0;
+	char *end;
 
 
 	bufcnt = Bufcount;
 	bufcnt = Bufcount;
+	offset = 0;
 	setbuf(stdin, NULL);
 	setbuf(stdin, NULL);
 	progname = *argv;
 	progname = *argv;
-	while ((ch = getopt(argc, argv, "b:dsrm:")) != -1) {
+	while ((ch = getopt(argc, argv, "b:dsrm:o:l:")) != -1) {
 		switch (ch) {
 		switch (ch) {
 		case 'b':
 		case 'b':
 			bufcnt = atoi(optarg);
 			bufcnt = atoi(optarg);
@@ -485,6 +488,16 @@ main(int argc, char **argv)
 		case 'm':
 		case 'm':
 			setmask(optarg);
 			setmask(optarg);
 			break;
 			break;
+		case 'o':
+			offset = strtoll(optarg, &end, 0);
+			if (end == optarg || offset < 0)
+				usage();
+			break;
+		case 'l':
+			length = strtoll(optarg, &end, 0);
+			if (end == optarg || length < 1)
+				usage();
+			break;
 		case '?':
 		case '?':
 		default:
 		default:
 			usage();
 			usage();
@@ -505,6 +518,24 @@ main(int argc, char **argv)
 	setserial(argv[3], shelf, slot);
 	setserial(argv[3], shelf, slot);
 	size = getsize(bfd);
 	size = getsize(bfd);
 	size /= 512;
 	size /= 512;
+	if (size <= offset) {
+                if (offset)
+                        fprintf(stderr,
+                                "Offset %lld too large for %lld-sector export\n",
+                                offset,
+                                size);
+                else
+                        fputs("0-sector file size is too small\n", stderr);
+		exit(1);
+	}
+	size -= offset;
+	if (length) {
+		if (length > size) {
+			fprintf(stderr, "Length %llu too big - exceeds size of file!\n", offset);
+			exit(1);
+		}
+		size = length;
+	}
 	ifname = argv[2];
 	ifname = argv[2];
 	sfd = dial(ifname, bufcnt);
 	sfd = dial(ifname, bufcnt);
 	getea(sfd, ifname, mac);
 	getea(sfd, ifname, mac);

+ 22 - 13
ata.c

@@ -23,16 +23,7 @@ enum {
 	ERR =	1<<0,
 	ERR =	1<<0,
 };
 };
 
 
-static ushort ident[256] = {
-	[47] 0x8000,
-	[49] 0x0200,
-	[50] 0x4000,
-	[83] 0x5400,
-	[84] 0x4000,
-	[86] 0x1400,
-	[87] 0x4000,
-	[93] 0x400b,
-};
+static ushort ident[256];
 
 
 static void
 static void
 setfld(ushort *a, int idx, int len, char *str)	// set field in ident
 setfld(ushort *a, int idx, int len, char *str)	// set field in ident
@@ -79,12 +70,30 @@ setlba48(ushort *ident, vlong lba)
 	*cp++ = lba >>= 8;
 	*cp++ = lba >>= 8;
 	*cp++ = lba >>= 8;
 	*cp++ = lba >>= 8;
 }
 }
-		
+
+static void
+setushort(ushort *a, int i, ushort n)
+{
+	uchar *p;
+
+	p = (uchar *)(a+i);
+	*p++ = n & 0xff;
+	*p++ = n >> 8;
+}
+
 void
 void
 atainit(void)
 atainit(void)
 {
 {
 	char buf[64];
 	char buf[64];
 
 
+	setushort(ident, 47, 0x8000);
+	setushort(ident, 49, 0x0200);
+	setushort(ident, 50, 0x4000);
+	setushort(ident, 83, 0x5400);
+	setushort(ident, 84, 0x4000);
+	setushort(ident, 86, 0x1400);
+	setushort(ident, 87, 0x4000);
+	setushort(ident, 93, 0x400b);
 	setfld(ident, 27, 40, "Coraid EtherDrive vblade");
 	setfld(ident, 27, 40, "Coraid EtherDrive vblade");
 	sprintf(buf, "V%d", VBLADE_VERSION);
 	sprintf(buf, "V%d", VBLADE_VERSION);
 	setfld(ident, 23, 8, buf);
 	setfld(ident, 23, 8, buf);
@@ -155,12 +164,12 @@ atacmd(Ataregs *p, uchar *dp, int ndp, int payload) // do the ata cmd
 		return 0;
 		return 0;
 	}
 	}
 	if (p->cmd == 0x20 || p->cmd == 0x24)
 	if (p->cmd == 0x20 || p->cmd == 0x24)
-		n = getsec(bfd, dp, lba, p->sectors);
+		n = getsec(bfd, dp, lba+offset, p->sectors);
 	else {
 	else {
 		// packet should be big enough to contain the data
 		// packet should be big enough to contain the data
 		if (payload < 512 * p->sectors)
 		if (payload < 512 * p->sectors)
 			return -1;
 			return -1;
-		n = putsec(bfd, dp, lba, p->sectors);
+		n = putsec(bfd, dp, lba+offset, p->sectors);
 	}
 	}
 	n /= 512;
 	n /= 512;
 	if (n != p->sectors) {
 	if (n != p->sectors) {

+ 11 - 16
bpf.c

@@ -82,32 +82,27 @@ create_bpf_program(int shelf, int slot)
 {
 {
 	struct bpf_program *bpf_program;
 	struct bpf_program *bpf_program;
 	struct bpf_insn insns[] = {
 	struct bpf_insn insns[] = {
-		/* Load the type into register */
+		/* CHECKTYPE: Load the type into register */
 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
 		/* Does it match AoE Type (0x88a2)? No, goto INVALID */
 		/* Does it match AoE Type (0x88a2)? No, goto INVALID */
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 12),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x88a2, 0, 10),
 		/* Load the flags into register */
 		/* Load the flags into register */
 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14),
 		/* Check to see if the Resp flag is set */
 		/* Check to see if the Resp flag is set */
 		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
 		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, Resp),
 		/* Yes, goto INVALID */
 		/* Yes, goto INVALID */
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 9),
-		/* Load the shelf number into register */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 7),
+		/* CHECKSHELF: Load the shelf number into register */
 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
 		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-		/* Does it match shelf number? No, goto CHECKBROADCAST */
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, shelf, 0, 2),
-		/* Load the slot number into register */
+		/* Does it match shelf number? Yes, goto CHECKSLOT */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, shelf, 1, 0),
+		/* Does it match broadcast? No, goto INVALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xffff, 0, 4),
+		/* CHECKSLOT: Load the slot number into register */
 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
 		/* Does it match shelf number? Yes, goto VALID */
 		/* Does it match shelf number? Yes, goto VALID */
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, slot, 4, 0),
-		/* CHECKBROADCAST: is (shelf, slot) == (0xffff, 0xff)? */
-		/* Load the shelf number into register */
-		BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 16),
-		/* Is it 0xffff? No, goto INVALID */
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xffff, 0, 3),
-		/* Load the slot number into register */
-		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 18),
-		/* Is it 0xff? No, goto INVALID */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, slot, 1, 0),
+		/* Does it match broadcast? No, goto INVALID */
 		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xff, 0, 1),
 		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xff, 0, 1),
 		/* VALID: return -1 (allow the packet to be read) */
 		/* VALID: return -1 (allow the packet to be read) */
 		BPF_STMT(BPF_RET+BPF_K, -1),
 		BPF_STMT(BPF_RET+BPF_K, -1),

+ 2 - 1
dat.h

@@ -6,7 +6,7 @@
  */
  */
 
 
 enum {
 enum {
-	VBLADE_VERSION		= 20,
+	VBLADE_VERSION		= 22,
 
 
 	// Firmware version
 	// Firmware version
 	FWV			= 0x4000 + VBLADE_VERSION,
 	FWV			= 0x4000 + VBLADE_VERSION,
@@ -169,6 +169,7 @@ uchar	mac[6];
 int	bfd;		// block file descriptor
 int	bfd;		// block file descriptor
 int	sfd;		// socket file descriptor
 int	sfd;		// socket file descriptor
 vlong	size;		// size of vblade
 vlong	size;		// size of vblade
+vlong	offset;
 char	*progname;
 char	*progname;
 char	serial[Nserial+1];
 char	serial[Nserial+1];
 
 

+ 17 - 1
freebsd.c

@@ -261,7 +261,23 @@ putpkt(int fd, uchar *buf, int sz)
 int
 int
 getmtu(int fd, char *name)
 getmtu(int fd, char *name)
 {
 {
-	return 1500;
+	struct ifreq xx;
+	int s, n;
+
+	s = socket(AF_INET, SOCK_RAW, 0);
+	if (s == -1) {
+		perror("Can't get mtu");
+		return 1500;
+	}
+	xx.ifr_addr.sa_family = AF_INET;
+	snprintf(xx.ifr_name, sizeof xx.ifr_name, "%s", name);
+	n = ioctl(s,SIOCGIFMTU, &xx);
+	if (n == -1) {
+		perror("Can't get mtu");
+		return 1500;
+	}
+	close(s);
+	return xx.ifr_mtu;
 }
 }
 
 
 vlong
 vlong

+ 3 - 3
linux.c

@@ -78,7 +78,7 @@ getindx(int s, char *name)	// return the index of device 'name'
 	struct ifreq xx;
 	struct ifreq xx;
 	int n;
 	int n;
 
 
-	strcpy(xx.ifr_name, name);
+	snprintf(xx.ifr_name, sizeof xx.ifr_name, "%s", name);
 	n = ioctl(s, SIOCGIFINDEX, &xx);
 	n = ioctl(s, SIOCGIFINDEX, &xx);
 	if (n == -1)
 	if (n == -1)
 		return -1;
 		return -1;
@@ -91,7 +91,7 @@ getea(int s, char *name, uchar *ea)
 	struct ifreq xx;
 	struct ifreq xx;
 	int n;
 	int n;
 
 
-        strcpy(xx.ifr_name, name);
+        snprintf(xx.ifr_name, sizeof xx.ifr_name, "%s", name);
 	n = ioctl(s, SIOCGIFHWADDR, &xx);
 	n = ioctl(s, SIOCGIFHWADDR, &xx);
 	if (n == -1) {
 	if (n == -1) {
 		perror("Can't get hw addr");
 		perror("Can't get hw addr");
@@ -107,7 +107,7 @@ getmtu(int s, char *name)
 	struct ifreq xx;
 	struct ifreq xx;
 	int n;
 	int n;
 
 
-	strcpy(xx.ifr_name, name);
+	snprintf(xx.ifr_name, sizeof xx.ifr_name, "%s", name);
 	n = ioctl(s, SIOCGIFMTU, &xx);
 	n = ioctl(s, SIOCGIFMTU, &xx);
 	if (n == -1) {
 	if (n == -1) {
 		perror("Can't get mtu");
 		perror("Can't get mtu");

+ 8 - 0
vblade.8

@@ -55,6 +55,14 @@ The -r flag restricts the export of the device to be read-only.
 The -m flag takes an argument, a comma separated list of MAC addresses
 The -m flag takes an argument, a comma separated list of MAC addresses
 permitted access to the vblade.  A MAC address can be specified in upper
 permitted access to the vblade.  A MAC address can be specified in upper
 or lower case, with or without colons.
 or lower case, with or without colons.
+.TP
+\fB-o\fP
+The -o flag takes an argument, the number of sectors at the beginning
+of the exported file that are excluded from AoE export (default zero).
+.TP
+\fB-l\fP
+The -l flag takes an argument, the number of sectors to export.
+Defaults to the file size in sectors minus the offset.
 .SH EXAMPLE
 .SH EXAMPLE
 In this example, the root user on a host named
 In this example, the root user on a host named
 .I nai
 .I nai