Bug 237392

Summary: growfs : operation not permitted
Product: Base System Reporter: Gonéri Le Bouder <goneri>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: New ---    
Severity: Affects Only Me CC: kiboto6933, tofig
Priority: ---    
Version: 12.0-STABLE   
Hardware: amd64   
OS: Any   

Description Gonéri Le Bouder 2019-04-19 17:27:31 UTC
Hi,

I face the same problem describe here when I try to resize my root file system:
https://lists.freebsd.org/pipermail/freebsd-questions/2017-August/278360.html


# growfs /dev/vtbd0p4
It's strongly recommended to make a backup before growing the file system.
OK to grow filesystem on /dev/vtbd0p4 from 5.0GB to 31GB? [yes/no] yes
growfs: /dev/vtbd0p4: Operation not permitted
# gpart show
=>       3  67108853  vtbd0  GPT  (32G)
         3      1600      1  efi  (800K)
      1603       123      2  freebsd-boot  (62K)
      1726   2097152      3  freebsd-swap  (1.0G)
   2098878  65009978      4  freebsd-ufs  (31G)

# growfs /
Device is mounted read-write; resizing will result in temporary write suspension for /.
It's strongly recommended to make a backup before growing the file system.
OK to grow filesystem on /dev/gpt/rootfs, mounted on /, from 5.0GB to 31GB? [yes/no] yes
super-block backups (for fsck_ffs -b #) at:
 10758208, 12551232, 14344256, 16137280, 17930304, 19723328, 21516352, 23309376, 25102400, 26895424, 28688448, 30481472, 32274496, 34067520,
 35860544, 37653568, 39446592, 41239616, 43032640, 44825664, 46618688, 48411712, 50204736, 51997760, 53790784, 55583808, 57376832, 59169856,
 60962880, 62755904, 64548928

# cat /etc/fstab 
# Custom /etc/fstab for FreeBSD VM images
/dev/gpt/rootfs   /       ufs     rw      1       1
/dev/gpt/swapfs  none    swap    sw      0       0
# gpart show
=>       3  67108853  vtbd0  GPT  (32G)
         3      1600      1  efi  (800K)
      1603       123      2  freebsd-boot  (62K)
      1726   2097152      3  freebsd-swap  (1.0G)
   2098878  65009978      4  freebsd-ufs  (31G)
# gpart list -a
Geom name: vtbd0
modified: false
state: OK
fwheads: 16
fwsectors: 63
last: 67108855
first: 3
entries: 4
scheme: GPT
Providers:
1. Name: vtbd0p1
   Mediasize: 819200 (800K)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 1536
   Mode: r0w0e0
   efimedia: HD(1,GPT,cd68eff5-62c1-11e9-b524-fd16338c0df8,0x3,0x640)
   rawuuid: cd68eff5-62c1-11e9-b524-fd16338c0df8
   rawtype: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
   label: (null)
   length: 819200
   offset: 1536
   type: efi
   index: 1
   end: 1602
   start: 3
2. Name: vtbd0p2
   Mediasize: 62976 (62K)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 820736
   Mode: r0w0e0
   efimedia: HD(2,GPT,cd68f05a-62c1-11e9-b524-fd16338c0df8,0x643,0x7b)
   rawuuid: cd68f05a-62c1-11e9-b524-fd16338c0df8
   rawtype: 83bd6b9d-7f41-11dc-be0b-001560b84f0f
   label: (null)
   length: 62976
   offset: 820736
   type: freebsd-boot
   index: 2
   end: 1725
   start: 1603
3. Name: vtbd0p3
   Mediasize: 1073741824 (1.0G)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 883712
   Mode: r0w0e0
   efimedia: HD(3,GPT,cd68f095-62c1-11e9-b524-fd16338c0df8,0x6be,0x200000)
   rawuuid: cd68f095-62c1-11e9-b524-fd16338c0df8
   rawtype: 516e7cb5-6ecf-11d6-8ff8-00022d09712b
   label: (null)
   length: 1073741824
   offset: 883712
   type: freebsd-swap
   index: 3
   end: 2098877
   start: 1726
4. Name: vtbd0p4
   Mediasize: 33285108736 (31G)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 1074625536
   Mode: r1w1e2
   efimedia: HD(4,GPT,cd68f0ca-62c1-11e9-b524-fd16338c0df8,0x2006be,0x3dff93a)
   rawuuid: cd68f0ca-62c1-11e9-b524-fd16338c0df8
   rawtype: 516e7cb6-6ecf-11d6-8ff8-00022d09712b
   label: rootfs
   length: 33285108736
   offset: 1074625536
   type: freebsd-ufs
   index: 4
   end: 67108855
   start: 2098878
Consumers:
1. Name: vtbd0
   Mediasize: 34359738368 (32G)
   Sectorsize: 512
   Mode: r1w1e3

#
Comment 1 Gonéri Le Bouder 2019-04-19 17:44:32 UTC
It's ok if I use the gtp/rootfs naming:

# growfs /dev/gpt/rootfs
Device is mounted read-write; resizing will result in temporary write suspension for /.
It's strongly recommended to make a backup before growing the file system.
OK to grow filesystem on /dev/gpt/rootfs, mounted on /, from 5.0GB to 31GB? [yes/no] yes
super-block backups (for fsck_ffs -b #) at:
 10758208, 12551232, 14344256, 16137280, 17930304, 19723328, 21516352, 23309376, 25102400, 26895424, 28688448, 30481472, 32274496, 34067520,
 35860544, 37653568, 39446592, 41239616, 43032640, 44825664, 46618688, 48411712, 50204736, 51997760, 53790784, 55583808, 57376832, 59169856,
 60962880, 62755904, 64548928
Comment 2 tofig 2022-08-20 23:52:14 UTC
This issue is still present on RELEASE-13.1 with the following uname -a output:

FreeBSD parent 13.1-RELEASE FreeBSD 13.1-RELEASE releng/13.1-n250148-fc952ac2212 GENERIC arm64


I've done some bug triaging and hopefully it helps to fix it.

Growfs calls dev_to_statfs() to find out the mountpoint on which the device is currently mounted. This is the listing for dev_to_statfs:

https://github.com/freebsd/freebsd-src/blob/main/sbin/growfs/growfs.c#L1437

Inside dev_to_statfs(), getmntinfo() returns the list of all active mounts along with the information for each of them. /dev/vtbd0p4 is likely not in the list of mounted devices; instead /dev/gpt/rootfs is. Therefore dev_to_statfs() is not able to find the mountpoint under which /dev/vtbd0p4 is mounted, and hence returns NULL.

Later on, there is a check for the return value from dev_to_statfs():

https://github.com/freebsd/freebsd-src/blob/main/sbin/growfs/growfs.c#L1576

This check is to differentiate for 2 separate cases: 1) device is mounted and 2) device is not mounted. In your case, though the device is mounted (but under a different name) the second case is taken and we attempt to open the device directly:

fso = open(device, O_WRONLY);

This operation fails with the error that you were seeing in your test.

If getmntinfo() was able to detect that your device /dev/vtbd0p4 was mounted under a different name (likely / ?), then the ufs-suspend mechanism would be used and that would possibly work just fine. 

I am not quite sure how dev_to_statfs() is supposed to derive the information about /dev/vtbd0p4 being mounted using a different device name like /dev/gpt/rootfs.