funkiness when resizing a BSD slice

Don Lewis truckman at FreeBSD.org
Wed Jun 26 07:31:37 UTC 2013


I've got a machine that used to dual boot FreeBSD and a Fedora.  It had
one disk slice for FreeBSD, another slice for Fedora, and a third slice
that was marked as Linux swap that both FreeBSD and Linux used as swap.
The FreeBSD slice had only an "a" ufs partition that covered the entire
slice (in addition to the "c" partition).

FreeBSD outgrew its available space.  Since I wasn't using the Fedora
slice anymore, I wanted to delete the Fedora slice, grow the FreeBSD
slice, grow the "a" partition, and the run growfs to expand the ufs
filesystem.  Things started off smoothly, but I ran into problems after
I grew the FreeBSD slice.  I eventually stumbled around until I expanded
the "a" partition, but then bsdlabel whined about the size of the "c"
partition until I manually edited its size, contrary to the
instructions.

The system is running a fairly recent version of 10-CURRENT, but I don't
think this matters much.

The following script will reproduce the problem:

#!/bin/sh -x
provider=`mdconfig -a -t swap -s 100m`
unit=`echo $provider | sed -e 's/md//'`
gpart create -s mbr $provider
gpart add -t freebsd -s 50m -i 1 $provider
gpart create -s bsd ${provider}s1
gpart add -t freebsd-ufs -i 1 ${provider}s1
gpart show $provider
gpart show ${provider}s1
bsdlabel ${provider}s1

gpart resize -i 1 $provider
gpart show $provider
gpart show ${provider}s1
bsdlabel ${provider}s1

gpart resize -i 3 ${provider}s1
gpart resize -i 1 ${provider}s1
gpart show ${provider}s1
bsdlabel ${provider}s1

echo q | env EDITOR=/bin/ed bsdlabel -e /dev/${provider}s1
gpart show ${provider}s1
bsdlabel ${provider}s1

gpart resize -i 1 ${provider}s1
gpart show ${provider}s1
bsdlabel ${provider}s1

mdconfig -d -u $unit


If I run it, I get the following output:

+ mdconfig -a -t swap -s 100m
+ provider=md0
+ echo md0
+ sed -e s/md//
+ unit=0
+ gpart create -s mbr md0
md0 created
+ gpart add -t freebsd -s 50m -i 1 md0
md0s1 added
+ gpart create -s bsd md0s1
md0s1 created
+ gpart add -t freebsd-ufs -i 1 md0s1
md0s1a added
+ gpart show md0
=>     9  204791  md0  MBR  (100M)
       9  102393    1  freebsd  (50M)
  102402  102398       - free -  (50M)

+ gpart show md0s1
=>     0  102393  md0s1  BSD  (50M)
       0  102393      1  freebsd-ufs  (50M)

+ bsdlabel md0s1
# /dev/md0s1:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:     102393          0    4.2BSD        0     0     0
  c:     102393          0    unused        0     0     # "raw" part, don't edit


Everything looks fine so far ...

+ gpart resize -i 1 md0
md0s1 resized
+ gpart show md0
=>     9  204791  md0  MBR  (100M)
       9  204786    1  freebsd  (100M)
  204795       5       - free -  (2.5k)


This looks fine, too ...


+ gpart show md0s1
=>     0  102393  md0s1  BSD  (100M)
       0  102393      1  freebsd-ufs  (50M)

Hmn ... the mediasize of md0s1 has changed, but not its last sector
number.

+ bsdlabel md0s1
# /dev/md0s1:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:     102393          0    4.2BSD        0     0     0
  c:     102393          0    unused        0     0     # "raw" part, don't edit


Bsdlabel doesn't see anything change ...


+ gpart resize -i 3 md0s1
gpart: invalid partition index

It won't let me resize the "c" partition because the gpe_internal flag
is set on it.

+ gpart resize -i 1 md0s1
md0s1a resized

... it lies ...

+ gpart show md0s1
=>     0  102393  md0s1  BSD  (100M)
       0  102393      1  freebsd-ufs  (50M)

+ bsdlabel md0s1
# /dev/md0s1:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:     102393          0    4.2BSD        0     0     0
  c:     102393          0    unused        0     0     # "raw" part, don't edit


... no change in the size of the "a" partition.


+ echo q
+ env EDITOR=/bin/ed bsdlabel -e /dev/md0s1
228
bsdlabel: partition c doesn't cover the whole unit!
bsdlabel: An incorrect partition c may cause problems for standard system utilities
+ gpart show md0s1
=>     0  204786  md0s1  BSD  (100M)
       0  102393      1  freebsd-ufs  (50M)
  102393  102393         - free -  (50M)

Now the last sector number of md0s1 has been updated (because a retaste
was triggered?), but ...

+ bsdlabel md0s1
# /dev/md0s1:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:     102393          0    4.2BSD        0     0     0
  c:     102393          0    unused        0     0     # "raw" part, don't edit
bsdlabel: partition c doesn't cover the whole unit!
bsdlabel: An incorrect partition c may cause problems for standard system utilities

... the size of the "c" partition hasn't and bsdlabel is unhappy.


+ gpart resize -i 1 md0s1
md0s1a resized
+ gpart show md0s1
=>     0  204786  md0s1  BSD  (100M)
       0  204786      1  freebsd-ufs  (100M)

+ bsdlabel md0s1
# /dev/md0s1:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:     204786          0    4.2BSD        0     0     0
  c:     102393          0    unused        0     0     # "raw" part, don't edit
bsdlabel: partition c doesn't cover the whole unit!
bsdlabel: An incorrect partition c may cause problems for standard system utilities

... but I finally managed to grow the "a" partition.

The "c" partition is still messed up and the only way to fix it is to
ignore the instructions that say not to edit it.


+ mdconfig -d -u 0


I poked around inside the twistly little passages inside geom and I
*think* the proper way to fix this is to add a resize method to
g_bsd_class in geom_bsd.c.  I *think* this resize method should update
d_secperunit in the disklabel at the start of the bsd slice, update
gpt_last in the basetable, and update p_size in the "c" partition entry.



More information about the freebsd-geom mailing list