Bug 1210912 - sfdisk 2.26 does not retain existing boot flag when resizing a partition
Summary: sfdisk 2.26 does not retain existing boot flag when resizing a partition
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: util-linux
Version: 22
Hardware: All
OS: All
unspecified
high
Target Milestone: ---
Assignee: Karel Zak
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-04-10 22:46 UTC by Adam Williamson
Modified: 2015-04-17 02:30 UTC (History)
2 users (show)

Fixed In Version: util-linux-2.26.1-1.fc22
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-04-17 02:30:39 UTC


Attachments (Terms of Use)
patch to fix the bug (1.42 KB, patch)
2015-04-11 04:51 UTC, Adam Williamson
no flags Details | Diff

Description Adam Williamson 2015-04-10 22:46:47 UTC
'man sfdisk' claims this:

"But when the -N option (change a single parti‐
              tion) is given, the default  for  each  field  is  its  previous
              value."

So if I do this:

echo ',+' | sfdisk -N1 /dev/sde

when /dev/sde1 has the boot flag set, then it should remain set, right? As I did not specify the 'bootable' value in the sfdisk input (it's field 4). However, it actually unsets it:

------------------------
[root@adam spin-kickstarts (f22 %)]# echo ',+' | sfdisk -N1 /dev/sde
Checking that no-one is using this disk right now ... OK

Disk /dev/sde: 29.8 GiB, 32019316736 bytes, 62537728 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x1b6fd906

Old situation:

Device     Boot Start    End Sectors Size Id Type
/dev/sde1  *     2048 204800  202753  99M 83 Linux

/dev/sde1: 
New situation:

Device     Boot Start      End  Sectors  Size Id Type
/dev/sde1        2048 62537727 62535680 29.8G 83 Linux
-------------------------

Well, OK. Let's try explicitly telling it to set the bootable flag in the input:

echo ',+,,*' | sfdisk -N1 /dev/sde

surely that'll work, right? Apparently not:

-------------------------
[root@adam spin-kickstarts (f22 %)]# echo ',+,,*' | sfdisk -N1 /dev/sde
Checking that no-one is using this disk right now ... OK

Disk /dev/sde: 29.8 GiB, 32019316736 bytes, 62537728 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x1b6fd906

Old situation:

Device     Boot Start      End  Sectors  Size Id Type
/dev/sde1  *     2048 62537727 62535680 29.8G 83 Linux

/dev/sde1: 
New situation:

Device     Boot Start      End  Sectors  Size Id Type
/dev/sde1        2048 62537727 62535680 29.8G 83 Linux
-----------------------------

So, it seems basically impossible to use sfdisk to resize a partition that's marked bootable, without unsetting the bootable flag. I have to run a separate command after the resize to restore the bootable flag.

This is with:

util-linux-2.26-1.fc22.x86_64

and it adds some more messiness to https://bugzilla.redhat.com/show_bug.cgi?id=1210428 .

Comment 1 Adam Williamson 2015-04-11 04:08:04 UTC
OK, so at least one of the problems is (sort of) user error. It seems the commas don't really *delimit* the fields, they rather mean "use default value for this field". So this:

,+,,*

doesn't mean:

field 1: default
field 2: +
field 3: default
field 4: *

it means:

field 1: default
field 2: +
field 3: default
field 4: default
field 5: *

This is not at all what the doc says, though; it says the comma acts as a delimiter, but it clearly does not. If you look at the code, it does this:

	enum { ITEM_START, ITEM_SIZE, ITEM_TYPE, ITEM_BOOTABLE };
	int item = -1;
...
	while (rc == 0 && p && *p) {
		uint64_t num;
		char *begin;

		p = (char *) skip_blank(p);
		item++;
...
		switch (item) {
		case ITEM_START:
...
		case ITEM_SIZE:
...
		case ITEM_TYPE:
...
		case ITEM_BOOTABLE:

each character other than a blank in the input string is counted as an 'item', and the first four 'items' are used as the values for the fields. commas are 'items', they are not delimiters between field values.

This isn't *at all* what the man page says, though, it clearly claims that commas are delimiters:

"             Fields  are  separated  by  whitespace, or by comma or semicolon
              possibly followed by whitespace"

Once I figured that out, I found that this *does* work:

echo ',+,*' | sfdisk -N1 /dev/sde

that sets the bootable flag. However, leaving the value for the 'bootable' field unspecified in any way - e.g. ',+' or ',+,,' - which should result in it remaining at whatever its current setting is does not work, instead it *always* disables it.

Comment 2 Adam Williamson 2015-04-11 04:51:43 UTC
Created attachment 1013337 [details]
patch to fix the bug

OK, I spent a couple of hours poking at this and I think I've figured out the problem. Attached patch fixes it for me.

Comment 3 Karel Zak 2015-04-13 08:32:29 UTC
Thanks, the patch looks correct.

Fixed by upstream commit 4d156d92eb538f9dbc077a2dd181a48d8fdc65cd.

Comment 4 Fedora Update System 2015-04-13 16:20:29 UTC
util-linux-2.26.1-1.fc22 has been submitted as an update for Fedora 22.
https://admin.fedoraproject.org/updates/util-linux-2.26.1-1.fc22

Comment 5 Fedora Update System 2015-04-17 02:30:39 UTC
util-linux-2.26.1-1.fc22 has been pushed to the Fedora 22 stable repository.  If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.