git: 0f01337e3af4 - stable/13 - bhyve: Add support for handling disk resize events to block_if.

John Baldwin jhb at FreeBSD.org
Thu Aug 12 17:02:31 UTC 2021


The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=0f01337e3af4c013f3ef81401a56d420fa4de997

commit 0f01337e3af4c013f3ef81401a56d420fa4de997
Author:     John Baldwin <jhb at FreeBSD.org>
AuthorDate: 2021-06-12 00:59:25 +0000
Commit:     John Baldwin <jhb at FreeBSD.org>
CommitDate: 2021-08-12 15:56:23 +0000

    bhyve: Add support for handling disk resize events to block_if.
    
    Allow clients of blockif to register a resize callback handler.  When
    a callback is registered, register an EVFILT_VNODE kevent watching the
    backing store for a change in the file's attributes.  If the size has
    changed when the kevent fires, invoke the clients' callback.
    
    Currently resize detection is limited to backing stores that support
    EVFILT_VNODE kevents such as regular files.
    
    Reviewed by:    grehan, markj
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D30504
    
    (cherry picked from commit 8794846a91c5429c612ba939c61ebf8f1ff1a628)
---
 usr.sbin/bhyve/block_if.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++-
 usr.sbin/bhyve/block_if.h |  5 ++++
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/bhyve/block_if.c b/usr.sbin/bhyve/block_if.c
index ae09bc71d622..98c0f9f5f38b 100644
--- a/usr.sbin/bhyve/block_if.c
+++ b/usr.sbin/bhyve/block_if.c
@@ -115,6 +115,9 @@ struct blockif_ctxt {
 	pthread_cond_t		bc_cond;
 	pthread_cond_t		bc_paused_cond;
 	pthread_cond_t		bc_work_done_cond;
+	blockif_resize_cb	*bc_resize_cb;
+	void			*bc_resize_cb_arg;
+	struct mevent		*bc_resize_event;
 
 	/* Request elements and free/pending/busy queues */
 	TAILQ_HEAD(, blockif_elem) bc_freeq;       
@@ -532,7 +535,7 @@ blockif_open(nvlist_t *nvl, const char *ident)
 
 #ifndef WITHOUT_CAPSICUM
 	cap_rights_init(&rights, CAP_FSYNC, CAP_IOCTL, CAP_READ, CAP_SEEK,
-	    CAP_WRITE);
+	    CAP_WRITE, CAP_FSTAT, CAP_EVENT);
 	if (ro)
 		cap_rights_clear(&rights, CAP_FSYNC, CAP_WRITE);
 
@@ -643,6 +646,62 @@ err:
 	return (NULL);
 }
 
+static void
+blockif_resized(int fd, enum ev_type type, void *arg)
+{
+	struct blockif_ctxt *bc;
+	struct stat sb;
+
+	if (fstat(fd, &sb) != 0)
+		return;
+
+	bc = arg;
+	pthread_mutex_lock(&bc->bc_mtx);
+	if (sb.st_size != bc->bc_size) {
+		bc->bc_size = sb.st_size;
+		bc->bc_resize_cb(bc, bc->bc_resize_cb_arg, bc->bc_size);
+	}
+	pthread_mutex_unlock(&bc->bc_mtx);
+}
+
+int
+blockif_register_resize_callback(struct blockif_ctxt *bc, blockif_resize_cb *cb,
+    void *cb_arg)
+{
+	struct stat sb;
+	int err;
+
+	if (cb == NULL)
+		return (EINVAL);
+
+	pthread_mutex_lock(&bc->bc_mtx);
+	if (bc->bc_resize_cb != NULL) {
+		err = EBUSY;
+		goto out;
+	}
+
+	assert(bc->bc_closing == 0);
+
+	if (fstat(bc->bc_fd, &sb) != 0) {
+		err = errno;
+		goto out;
+	}
+
+	bc->bc_resize_event = mevent_add_flags(bc->bc_fd, EVF_VNODE,
+	    EVFF_ATTRIB, blockif_resized, bc);
+	if (bc->bc_resize_event == NULL) {
+		err = ENXIO;
+		goto out;
+	}
+
+	bc->bc_resize_cb = cb;
+	bc->bc_resize_cb_arg = cb_arg;
+out:
+	pthread_mutex_unlock(&bc->bc_mtx);
+
+	return (err);
+}
+
 static int
 blockif_request(struct blockif_ctxt *bc, struct blockif_req *breq,
 		enum blockop op)
@@ -796,6 +855,8 @@ blockif_close(struct blockif_ctxt *bc)
 	 */
 	pthread_mutex_lock(&bc->bc_mtx);
 	bc->bc_closing = 1;
+	if (bc->bc_resize_event != NULL)
+		mevent_disable(bc->bc_resize_event);
 	pthread_mutex_unlock(&bc->bc_mtx);
 	pthread_cond_broadcast(&bc->bc_cond);
 	for (i = 0; i < BLOCKIF_NUMTHR; i++)
diff --git a/usr.sbin/bhyve/block_if.h b/usr.sbin/bhyve/block_if.h
index 87ae4d169969..0407ff43cf94 100644
--- a/usr.sbin/bhyve/block_if.h
+++ b/usr.sbin/bhyve/block_if.h
@@ -63,8 +63,13 @@ struct blockif_req {
 };
 
 struct blockif_ctxt;
+
+typedef void blockif_resize_cb(struct blockif_ctxt *, void *, size_t);
+
 int	blockif_legacy_config(nvlist_t *nvl, const char *opts);
 struct blockif_ctxt *blockif_open(nvlist_t *nvl, const char *ident);
+int	blockif_register_resize_callback(struct blockif_ctxt *bc,
+    blockif_resize_cb *cb, void *cb_arg);
 off_t	blockif_size(struct blockif_ctxt *bc);
 void	blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h,
     uint8_t *s);


More information about the dev-commits-src-branches mailing list