svn commit: r256389 - head/usr.sbin/bhyve

Peter Grehan grehan at FreeBSD.org
Sat Oct 12 19:31:20 UTC 2013


Author: grehan
Date: Sat Oct 12 19:31:19 2013
New Revision: 256389
URL: http://svnweb.freebsd.org/changeset/base/256389

Log:
  Implement the virtio block 'get-ident' operation. This eliminates the
  annoying verbose boot error of the form
  
     g_handleattr: vtbd0 bio_length 24 len 28 -> EFAULT
  
  The ident returned by bhyve is a text string 'BHYVE-XXXX-XXXX', where
  the X's are the first bytes of the md5 hash of the backing filename.
  
  Reviewed by:	neel
  Approved by:	re (gjb)

Modified:
  head/usr.sbin/bhyve/pci_virtio_block.c

Modified: head/usr.sbin/bhyve/pci_virtio_block.c
==============================================================================
--- head/usr.sbin/bhyve/pci_virtio_block.c	Sat Oct 12 18:24:52 2013	(r256388)
+++ head/usr.sbin/bhyve/pci_virtio_block.c	Sat Oct 12 19:31:19 2013	(r256389)
@@ -46,17 +46,25 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 #include <assert.h>
 #include <pthread.h>
+#include <md5.h>
 
 #include "bhyverun.h"
 #include "pci_emul.h"
 #include "virtio.h"
 
+#ifndef min
+#define	min(a, b)	((a) < (b) ? (a) : (b))
+#endif
+
 #define VTBLK_RINGSZ	64
 
 #define VTBLK_MAXSEGS	32
 
 #define VTBLK_S_OK	0
 #define VTBLK_S_IOERR	1
+#define	VTBLK_S_UNSUPP	2
+
+#define	VTBLK_BLK_ID_BYTES	20
 
 /*
  * Host capabilities
@@ -85,6 +93,7 @@ struct vtblk_config {
 struct virtio_blk_hdr {
 #define	VBH_OP_READ		0
 #define	VBH_OP_WRITE		1
+#define	VBH_OP_IDENT		8		
 #define	VBH_FLAG_BARRIER	0x80000000	/* OR'ed into vbh_type */
 	uint32_t       	vbh_type;
 	uint32_t	vbh_ioprio;
@@ -106,6 +115,7 @@ struct pci_vtblk_softc {
 	struct vqueue_info vbsc_vq;
 	int		vbsc_fd;
 	struct vtblk_config vbsc_cfg;	
+	char vbsc_ident[VTBLK_BLK_ID_BYTES];
 };
 
 static void pci_vtblk_reset(void *);
@@ -180,7 +190,7 @@ pci_vtblk_proc(struct pci_vtblk_softc *s
 	for (i = 1; i < n; i++) {
 		/*
 		 * - write op implies read-only descriptor,
-		 * - read op implies write-only descriptor,
+		 * - read/ident op implies write-only descriptor,
 		 * therefore test the inverse of the descriptor bit
 		 * to the op.
 		 */
@@ -189,14 +199,34 @@ pci_vtblk_proc(struct pci_vtblk_softc *s
 	}
 
 	DPRINTF(("virtio-block: %s op, %d bytes, %d segs, offset %ld\n\r", 
-		 writeop ? "write" : "read", iolen, i - 1, offset));
+		 writeop ? "write" : "read/ident", iolen, i - 1, offset));
 
-	if (writeop)
+	switch (type) {
+	case VBH_OP_WRITE:
 		err = pwritev(sc->vbsc_fd, iov + 1, i - 1, offset);
-	else
+		break;
+	case VBH_OP_READ:
 		err = preadv(sc->vbsc_fd, iov + 1, i - 1, offset);
+		break;
+	case VBH_OP_IDENT:
+		/* Assume a single buffer */
+		strlcpy(iov[1].iov_base, sc->vbsc_ident,
+		    min(iov[1].iov_len, sizeof(sc->vbsc_ident)));
+		err = 0;
+		break;
+	default:
+		err = -ENOSYS;
+		break;
+	}
 
-	*status = err < 0 ? VTBLK_S_IOERR : VTBLK_S_OK;
+	/* convert errno into a virtio block error return */
+	if (err < 0) {
+		if (err == -ENOSYS)
+			*status = VTBLK_S_UNSUPP;
+		else
+			*status = VTBLK_S_IOERR;
+	} else
+		*status = VTBLK_S_OK;
 
 	/*
 	 * Return the descriptor back to the host.
@@ -220,6 +250,8 @@ static int
 pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
 {
 	struct stat sbuf;
+	MD5_CTX mdctx;
+	u_char digest[16];
 	struct pci_vtblk_softc *sc;
 	off_t size;	
 	int fd;
@@ -274,6 +306,16 @@ pci_vtblk_init(struct vmctx *ctx, struct
 	sc->vbsc_vq.vq_qsize = VTBLK_RINGSZ;
 	/* sc->vbsc_vq.vq_notify = we have no per-queue notify */
 
+	/*
+	 * Create an identifier for the backing file. Use parts of the
+	 * md5 sum of the filename
+	 */
+	MD5Init(&mdctx);
+	MD5Update(&mdctx, opts, strlen(opts));
+	MD5Final(digest, &mdctx);	
+	sprintf(sc->vbsc_ident, "BHYVE-%02X%02X-%02X%02X-%02X%02X",
+	    digest[0], digest[1], digest[2], digest[3], digest[4], digest[5]);
+
 	/* setup virtio block config space */
 	sc->vbsc_cfg.vbc_capacity = size / sectsz;
 	sc->vbsc_cfg.vbc_seg_max = VTBLK_MAXSEGS;


More information about the svn-src-head mailing list