vmd(8): improve error messages when out of tap devices.
authordv <dv@openbsd.org>
Wed, 3 Jan 2024 22:34:39 +0000 (22:34 +0000)
committerdv <dv@openbsd.org>
Wed, 3 Jan 2024 22:34:39 +0000 (22:34 +0000)
The logging and the (lack of) errno don't describe the actual reason
a vm fails to start when there are not enough tap(4) special files
in /dev. Improve the log message to specify the tap file in question
and set ENOENT so vmctl(8) gets something other than an undefined
errno value to report.

ok bluhm@

usr.sbin/vmd/config.c
usr.sbin/vmd/vmm.c

index 3bb246a..e2f3679 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.72 2023/07/13 18:31:59 dv Exp $  */
+/*     $OpenBSD: config.c,v 1.73 2024/01/03 22:34:39 dv Exp $  */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -417,7 +417,8 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid)
                        s = ifname;
                }
                if (tapfds[i] == -1) {
-                       log_warnx("%s: can't open tap %s", __func__, s);
+                       ret = errno;
+                       log_warnx("%s: can't open /dev/%s", __func__, s);
                        goto fail;
                }
                if ((vif->vif_name = strdup(s)) == NULL) {
index b6b138a..87d200c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmm.c,v 1.115 2023/09/26 01:53:54 dv Exp $    */
+/*     $OpenBSD: vmm.c,v 1.116 2024/01/03 22:34:39 dv Exp $    */
 
 /*
  * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -586,26 +586,41 @@ terminate_vm(struct vm_terminate_params *vtp)
  * Parameters
  *  ifname: a buffer of at least IF_NAMESIZE bytes.
  *
- * Returns a file descriptor to the tap node opened, or -1 if no tap
- * devices were available.
+ * Returns a file descriptor to the tap node opened or -1 if no tap devices were
+ * available, setting errno to the open(2) error.
  */
 int
 opentap(char *ifname)
 {
-       int i, fd;
+       int err = 0, i, fd;
        char path[PATH_MAX];
 
        for (i = 0; i < MAX_TAP; i++) {
                snprintf(path, PATH_MAX, "/dev/tap%d", i);
+
+               errno = 0;
                fd = open(path, O_RDWR | O_NONBLOCK);
-               if (fd != -1) {
-                       snprintf(ifname, IF_NAMESIZE, "tap%d", i);
-                       return (fd);
+               if (fd != -1)
+                       break;
+               err = errno;
+               if (err == EBUSY) {
+                       /* Busy...try next tap. */
+                       continue;
+               } else if (err == ENOENT) {
+                       /* Ran out of /dev/tap* special files. */
+                       break;
+               } else {
+                       log_warn("%s: unexpected error", __func__);
+                       break;
                }
        }
-       strlcpy(ifname, "tap", IF_NAMESIZE);
 
-       return (-1);
+       /* Record the last opened tap device. */
+       snprintf(ifname, IF_NAMESIZE, "tap%d", i);
+
+       if (err)
+               errno = err;
+       return (fd);
 }
 
 /*