Found this while working on some virtio stuff. My original
implementation as part of the multi-process redesign didn't handle if
imsg_flush failed due to resource shortages (EAGAIN), so adopt the
do/while idiom used by other daemons like iked(8).

Manifests with errors from the vm process looking like:

  virtio_pci_io: imsg_flush (write)
  vmd: pci i/o access function failed

ok?

diff refs/heads/master refs/heads/vmd-imsg_flush
commit - 40d57955f2f1a3a65c42ea374f86c74cf879d76d
commit + 2c42dedb675f013276cdbd47464f656e2451b92c
blob - 798b5fea6d589d43083c134a040df6272037869f
blob + ff1ab5fdcb52866f10a14df38d30abde277619df
--- usr.sbin/vmd/virtio.c
+++ usr.sbin/vmd/virtio.c
@@ -825,8 +825,11 @@ virtio_shutdown(struct vmd_vm *vm)
                if (ret == -1)
                        fatalx("%s: failed to send shutdown to device",
                            __func__);
-               if (imsg_flush(ibuf) == -1)
-                       fatalx("%s: imsg_flush", __func__);
+               do {
+                       ret = imsg_flush(ibuf);
+               } while (ret == -1 && errno == EAGAIN);
+               if (ret == -1)
+                       fatal("%s: imsg_flush", __func__);
        }

        /*
@@ -1132,8 +1135,11 @@ vionet_dump(int fd)
                            __func__, dev->vionet.idx);
                        return (-1);
                }
-               if (imsg_flush(ibuf) == -1) {
-                       log_warnx("%s: imsg_flush", __func__);
+               do {
+                       ret = imsg_flush(ibuf);
+               } while (ret == -1 && errno == EAGAIN);
+               if (ret == -1) {
+                       log_warn("%s: imsg_flush", __func__);
                        return (-1);
                }

@@ -1189,12 +1195,14 @@ vioblk_dump(int fd)
                            __func__, dev->vioblk.idx);
                        return (-1);
                }
-               if (imsg_flush(ibuf) == -1) {
-                       log_warnx("%s: imsg_flush", __func__);
+               do {
+                       ret = imsg_flush(ibuf);
+               } while (ret == -1 && errno == EAGAIN);
+               if (ret == -1) {
+                       log_warn("%s: imsg_flush", __func__);
                        return (-1);
                }

-
                sz = atomicio(read, dev->sync_fd, &temp, sizeof(temp));
                if (sz != sizeof(temp)) {
                        log_warnx("%s: failed to dump vioblk[%d]", __func__,
@@ -1660,8 +1668,11 @@ virtio_pci_io(int dir, uint16_t reg, uint32_t *data, u
                            " device", __func__);
                        return (ret);
                }
-               if (imsg_flush(ibuf) == -1) {
-                       log_warnx("%s: imsg_flush (write)", __func__);
+               do {
+                       ret = imsg_flush(ibuf);
+               } while (ret == -1 && errno == EAGAIN);
+               if (ret == -1) {
+                       log_warn("%s: imsg_flush (write)", __func__);
                        return (-1);
                }
        } else {
@@ -1675,8 +1686,11 @@ virtio_pci_io(int dir, uint16_t reg, uint32_t *data, u
                            " device", __func__);
                        return (ret);
                }
-               if (imsg_flush(ibuf) == -1) {
-                       log_warnx("%s: imsg_flush (read)", __func__);
+               do {
+                       ret = imsg_flush(ibuf);
+               } while (ret == -1 && errno == EAGAIN);
+               if (ret == -1) {
+                       log_warn("%s: imsg_flush (read)", __func__);
                        return (-1);
                }

Reply via email to