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)
This commit is contained in:
parent
513bdd96d7
commit
98c9a35de3
@ -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 *sc, struct vqueue_info *vq)
|
||||
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 *sc, struct vqueue_info *vq)
|
||||
}
|
||||
|
||||
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 pci_devinst *pi, char *opts)
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user