Author: eugen
Date: Mon Sep 21 12:37:41 2020
New Revision: 365944
URL: https://svnweb.freebsd.org/changeset/base/365944

Log:
  MFS r365667,r365920: extend kern.geom.part.check_integrity to work on GPT
  
  There are multiple USB/SATA bridges on the market that unconditionally
  cut some LBAs off connected media. This could be a problem
  for pre-partitioned drives so GEOM complains and does not create
  devices in /dev for slices/partitions preventing access to existing data.
  
  We have a knob kern.geom.part.check_integrity that allows us to correct
  partitioning if changed from default 1 to 0 but it works for MBR only.
  If backup copy of GPT is unavailable due to decreased number of LBAs,
  the kernel does not give access to partitions still and prints to dmesg:
  
  GEOM: md0: corrupt or invalid GPT detected.
  GEOM: md0: GPT rejected -- may not be recoverable.
  
  This change makes it work for GPT too, so it created partitions in /dev
  and prints to dmesg this instead:
  
  GEOM: md0: the secondary GPT table is corrupt or invalid.
  GEOM: md0: using the primary only -- recovery suggested.
  
  Then "gpart recover" re-creates backup copy of GPT
  and allows further manipulations with partitions.
  
  This change is no-op for default configuration having
  kern.geom.part.check_integrity=1
  
  Reported by:  Alex Korchmar
  Approved by:  re (gjb)

Modified:
  releng/12.2/sys/geom/part/g_part.c
  releng/12.2/sys/geom/part/g_part_gpt.c
Directory Properties:
  releng/12.2/   (props changed)

Modified: releng/12.2/sys/geom/part/g_part.c
==============================================================================
--- releng/12.2/sys/geom/part/g_part.c  Mon Sep 21 10:02:11 2020        
(r365943)
+++ releng/12.2/sys/geom/part/g_part.c  Mon Sep 21 12:37:41 2020        
(r365944)
@@ -135,9 +135,9 @@ struct g_part_alias_list {
 SYSCTL_DECL(_kern_geom);
 SYSCTL_NODE(_kern_geom, OID_AUTO, part, CTLFLAG_RW, 0,
     "GEOM_PART stuff");
-static u_int check_integrity = 1;
+u_int geom_part_check_integrity = 1;
 SYSCTL_UINT(_kern_geom_part, OID_AUTO, check_integrity,
-    CTLFLAG_RWTUN, &check_integrity, 1,
+    CTLFLAG_RWTUN, &geom_part_check_integrity, 1,
     "Enable integrity checking");
 static u_int auto_resize = 1;
 SYSCTL_UINT(_kern_geom_part, OID_AUTO, auto_resize,
@@ -420,7 +420,7 @@ g_part_check_integrity(struct g_part_table *table, str
        if (failed != 0) {
                printf("GEOM_PART: integrity check failed (%s, %s)\n",
                    pp->name, table->gpt_scheme->name);
-               if (check_integrity != 0)
+               if (geom_part_check_integrity != 0)
                        return (EINVAL);
                table->gpt_corrupt = 1;
        }
@@ -1846,7 +1846,8 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp
                table = gpp.gpp_geom->softc;
                if (table != NULL && table->gpt_corrupt &&
                    ctlreq != G_PART_CTL_DESTROY &&
-                   ctlreq != G_PART_CTL_RECOVER) {
+                   ctlreq != G_PART_CTL_RECOVER &&
+                   geom_part_check_integrity) {
                        gctl_error(req, "%d table '%s' is corrupt",
                            EPERM, gpp.gpp_geom->name);
                        return;

Modified: releng/12.2/sys/geom/part/g_part_gpt.c
==============================================================================
--- releng/12.2/sys/geom/part/g_part_gpt.c      Mon Sep 21 10:02:11 2020        
(r365943)
+++ releng/12.2/sys/geom/part/g_part_gpt.c      Mon Sep 21 12:37:41 2020        
(r365944)
@@ -64,6 +64,8 @@ SYSCTL_UINT(_kern_geom_part_gpt, OID_AUTO, allow_nesti
 CTASSERT(offsetof(struct gpt_hdr, padding) == 92);
 CTASSERT(sizeof(struct gpt_ent) == 128);
 
+extern u_int geom_part_check_integrity;
+
 #define        EQUUID(a,b)     (memcmp(a, b, sizeof(struct uuid)) == 0)
 
 #define        MBRSIZE         512
@@ -460,8 +462,9 @@ gpt_read_hdr(struct g_part_gpt_table *table, struct g_
        if (hdr->hdr_lba_self != table->lba[elt])
                goto fail;
        hdr->hdr_lba_alt = le64toh(buf->hdr_lba_alt);
-       if (hdr->hdr_lba_alt == hdr->hdr_lba_self ||
-           hdr->hdr_lba_alt > last)
+       if (hdr->hdr_lba_alt == hdr->hdr_lba_self)
+               goto fail;
+       if (hdr->hdr_lba_alt > last && geom_part_check_integrity)
                goto fail;
 
        /* Check the managed area. */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to