Introduction
When you open man
<https://manpages.debian.org/unstable/parted/parted.8.en.html> page or gnu
<https://www.gnu.org/software/parted/manual/html_node/unit.html> documentation,
you may refer to "unit" command and think that "KiB" is a correct
interpretation of, whatever its name, 1024 bytes. And it actually works for
using this command as well as creating a single partition with "mkpart"
command. Then, there is a BIG one: you can’t create adjacent partitions
while encountering a weird error:


*parted -s /dev/nvme1n1 mkpart primary 128KiB 28692352KiB mkpart primary
28692352KiB 29216640KiB*
*Error: You requested a partition from 29.4GB to 29.9GB (sectors
7173088..7304160).*
*The closest location we can manage is 29.4GB to 29.9GB (sectors
7173089..7304160).*

However, if you proceed with "unit" command as in documentation and keep
the case of "KiB", then partitions are created successfully:

*parted -s /dev/nvme1n1 unit KiB mkpart primary 128 28692352 mkpart primary
28692352 29216640*

Where could be the catch?

   1. The code of the above-mentioned "unit" command contains a static
   constant array of units. It looks like this and has "kiB" with lower case
   “k”, though further down checks names without case sensitivity.

*static const char* unit_names[] = {*
*    "s",*
*    "B",*
*    "kB",*
*    "MB",*
*    "GB",*
*    "TB",*
*    "compact",*
*    "cyl",*
*    "chs",*
*    "%",*
*    "kiB",*
*    "MiB",*
*    "GiB",*
*    "TiB"*
*};*


   1. There is adjustment to be called whenever the partition is created or
   resized. It looks like this and also checks for "kiB", though with case
   sensitivity this time.

*/* Return true, if str ends with [kMGTPEZY]iB, i.e. IEC units.  */*
*static bool*
*_string_ends_with_iec_unit(const char *str)*
*{*
*        /* 3 characters for the IEC unit and at least 1 digit */*
*        if (!str || strlen(str) < 4)*
*                return false;*

*        char const *p = str + strlen(str) - 3;*
*        return strchr ("kMGTPEZY", *p) && c_strcasecmp (p+1, "iB") == 0;*
*}*

*/* If the selected unit is one of kiB, MiB, GiB or TiB and the partition
is not*
* * only 1 sector long, then adjust the end so that it is one sector before
the*
* * given position. Also adjust range_end accordingly. Thus next partition
can*
* * start immediately after this one.*
* **
* * To be called after end sector is read from the user.*
* **
* * https://lists.gnu.org/archive/html/bug-parted/2011-10/msg00009.html
<https://lists.gnu.org/archive/html/bug-parted/2011-10/msg00009.html>*
* */*
*static void*
*_adjust_end_if_iec (PedSector* start, PedSector* end,*
*                    PedGeometry* range_end, char* end_input)*
*{*
*        ...*
*        if (_string_ends_with_iec_unit(end_input) || ...) {*
*                *end -= 1;*
*                range_end->start -= 1;*
*                range_end->end -= 1;*
*        }*
*}*


Suggestion
Even though units are parsed case-insensitively in most cases, it may be
crucial in other cases and lead to the original issue. As such, whether
this is a following ICE standard or archaeology, the documentation of
"parted" utility could clarify this point and eliminate such problems in
the future. Alternatively, both catches could be consistent with each other
and treat case sensitivity in the same manner, according to documentation.

Reply via email to