Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/sysinst PR 56310: if we fail to create a wedge this...



details:   https://anonhg.NetBSD.org/src/rev/054b6959b790
branches:  trunk
changeset: 984697:054b6959b790
user:      martin <martin%NetBSD.org@localhost>
date:      Sat Jul 17 18:07:22 2021 +0000

description:
PR 56310: if we fail to create a wedge this either means there is
a bug here (and we requested something nonsensial), or there are pre-
existing "foreign" wedges which disturb our work.
So remove all wedges on this disk that we do not know about and retry
to add our new wedge.

diffstat:

 usr.sbin/sysinst/gpt.c |  79 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 74 insertions(+), 5 deletions(-)

diffs (119 lines):

diff -r b70386a3d795 -r 054b6959b790 usr.sbin/sysinst/gpt.c
--- a/usr.sbin/sysinst/gpt.c    Sat Jul 17 16:31:51 2021 +0000
+++ b/usr.sbin/sysinst/gpt.c    Sat Jul 17 18:07:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gpt.c,v 1.24 2021/07/17 11:32:50 martin Exp $  */
+/*     $NetBSD: gpt.c,v 1.25 2021/07/17 18:07:22 martin Exp $  */
 
 /*
  * Copyright 2018 The NetBSD Foundation, Inc.
@@ -32,6 +32,7 @@
 #include "md.h"
 #include "gpt_uuid.h"
 #include <assert.h>
+#include <errno.h>
 #include <err.h>
 #include <paths.h>
 #include <sys/param.h>
@@ -1325,8 +1326,71 @@
        return (str);
 }
 
+/*
+ * diskfd is an open file descriptor for a disk we had trouble with
+ * creating some new wedges.
+ * Go through all wedges actually on that disk, check if we have a
+ * record for them and remove all others.
+ * This should sync our internal model of partitions with the real state.
+ */
+static void
+gpt_sanitize(int diskfd, const struct gpt_disk_partitions *parts,
+    struct gpt_part_entry *ignore)
+{
+       struct dkwedge_info *dkw, delw;
+       struct dkwedge_list dkwl;
+       size_t bufsize;
+       u_int i;
+
+       dkw = NULL;
+       dkwl.dkwl_buf = dkw;
+       dkwl.dkwl_bufsize = 0;
+
+       /* get a list of all wedges */
+       for (;;) {
+               if (ioctl(diskfd, DIOCLWEDGES, &dkwl) == -1)
+                       return;
+               if (dkwl.dkwl_nwedges == dkwl.dkwl_ncopied)
+                       break;
+               bufsize = dkwl.dkwl_nwedges * sizeof(*dkw);
+               if (dkwl.dkwl_bufsize < bufsize) {
+                       dkw = realloc(dkwl.dkwl_buf, bufsize);
+                       if (dkw == NULL)
+                               return;
+                       dkwl.dkwl_buf = dkw;
+                       dkwl.dkwl_bufsize = bufsize;
+               }
+       }
+
+       /* try to remove all the ones we do not know about */
+       for (i = 0; i < dkwl.dkwl_nwedges; i++) {
+               bool found = false;
+               const char *devname = dkw[i].dkw_devname;
+
+               for (struct gpt_part_entry *pe = parts->partitions;
+                   pe != NULL; pe = pe->gp_next) {
+                       if (pe == ignore)
+                               continue;
+                       if ((pe->gp_flags & GPEF_WEDGE) &&
+                           strcmp(pe->gp_dev_name, devname) == 0) {
+                               found = true;
+                               break;
+                       }
+               }
+               if (found)
+                       continue;
+               memset(&delw, 0, sizeof(delw));
+               strncpy(delw.dkw_devname, devname, sizeof(delw.dkw_devname));
+               (void)ioctl(diskfd, DIOCDWEDGE, &delw);
+       }
+
+       /* cleanup */
+       free(dkw);
+}
+
 static bool
-gpt_add_wedge(const char *disk, struct gpt_part_entry *p)
+gpt_add_wedge(const char *disk, struct gpt_part_entry *p,
+    const struct gpt_disk_partitions *parts)
 {
        struct dkwedge_info dkw;
        const char *tname;
@@ -1355,9 +1419,16 @@
        if (fd < 0)
                return false;
        if (ioctl(fd, DIOCAWEDGE, &dkw) == -1) {
+               if (errno == EINVAL) {
+                       /* sanitize existing wedges and try again */
+                       gpt_sanitize(fd, parts, p);
+                       if (ioctl(fd, DIOCAWEDGE, &dkw) == 0)
+                               goto ok;
+               }
                close(fd);
                return false;
        }
+ok:
        close(fd);
 
        strlcpy(p->gp_dev_name, dkw.dkw_devname, sizeof(p->gp_dev_name));
@@ -1405,10 +1476,8 @@
        if (usage == plain_name || usage == raw_dev_name)
                life = true;
        if (!(p->gp_flags & GPEF_WEDGE) && life &&
-           !gpt_add_wedge(arg->disk, p)) {
-               devname[0] = 0;
+           !gpt_add_wedge(arg->disk, p, parts))
                return false;
-       }
 
        switch (usage) {
        case logical_name:



Home | Main Index | Thread Index | Old Index