Bug 849748 - vgs --units handling is not accurate
Summary: vgs --units handling is not accurate
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: lvm2
Version: 5.8
Hardware: Unspecified
OS: Unspecified
low
low
Target Milestone: rc
: ---
Assignee: LVM and device-mapper development team
QA Contact: Cluster QE
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2012-08-20 18:34 UTC by Jaroslav Kortus
Modified: 2012-08-21 16:26 UTC (History)
9 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-08-21 16:21:15 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Jaroslav Kortus 2012-08-20 18:34:26 UTC
Description of problem:
$ vgs --noheadings -o vg_free brawl
  99.99G
$ vgs --noheadings -o vg_free --units 100G brawl
  1.07U
$ vgs --noheadings -o vg_free --units 100g brawl
  1.00U
$ lvcreate -n brawl0 -L 100G brawl 
  Volume group "brawl" has insufficient free space (25598 extents): 25600 required.

Notice the 100G giving 1.07U while smaller g gives 1.00U. Capital G should match what the first command printed, or is this somehow reversed?

Also notice that it actually does not have 1.00U, 1U is more than 99.99G available, which causes the failure of the last command. I'd prefer more conservative approach here and round it down and not up.

Version-Release number of selected component (if applicable):
lvm2-2.02.88-9.el5, both RHEL5 and 6 seem to be affected.

How reproducible:
100%

Steps to Reproduce:
1. create VG sized as in description and additional info
2. repeat the commands as in description
3.
  
Actual results:
* optimistic rounding causing unexpected results when the output is used
* g/G  mismatch in commands output/input

Expected results:
* conservative rounding down (so it yields 0.99U in commands above)
* g/G match (second command must print 0.99U instead of 1.07U)

Additional info:

SCSI device sda: 104857600 512-byte hdwr sectors (53687 MB)
sda: Write Protect is off
sda: Mode Sense: 49 00 00 08
SCSI device sda: drive cache: write back
 sda: sda1
SCSI device sdb: 104857600 512-byte hdwr sectors (53687 MB)
sdb: Write Protect is off
sdb: Mode Sense: 49 00 00 08
SCSI device sdb: drive cache: write back
 sdb: sdb1
$ pvs
  PV         VG         Fmt  Attr PSize  PFree 
  /dev/sda1  brawl      lvm2 a--  50.00G 50.00G
  /dev/sdb1  brawl      lvm2 a--  50.00G 50.00G

Comment 1 Alasdair Kergon 2012-08-20 22:16:04 UTC
It uses sprintf() rounding of floats for output, which I think is sensible.

If you need the exact size, use, for example --units s or b.

    # Default value for --units argument
    units = "h"

    # Since version 2.02.54, the tools distinguish between powers of
    # 1024 bytes (e.g. KiB, MiB, GiB) and powers of 1000 bytes (e.g.
    # KB, MB, GB).

The only extension I'd still like to make one day is:
       /* FIXME Make precision configurable */

I don't think it's worth making the rounding configurable, since if you're doing anything where it actually matters, you'd want to know the exact size, and if you're just using lvcreate as in your example, you should be using the %FREE syntax anyway rather than specifying the exact size.

Input has always used case-insensitive multiples of 1024 (not 1000) and I considered the major upheaval of trying to update this to offer both 1024 and 1000 a few years ago, but felt it would cause far more trouble than it's worth, whichever way we did it.

Comment 2 Jaroslav Kortus 2012-08-21 16:02:06 UTC
Thanks for the comment Alasdair.

sprintf() rounding is good until you actually want to use the result. It should be possible to do floor() on the argument before supplying it to sprintf(). I was not asking for this to be configurable, but always use conservative (i.e. floor) approach.

The output should probably print small "g" (as it seems to do in rhel6) also in rhel5.

These two fixes would make --units actually reliable and it's output usable. I know there are workarounds but if this feature is present, it should be doing it's job correctly.

Can you please implement these two fixes?

Comment 3 Alasdair Kergon 2012-08-21 16:21:15 UTC
Sorry, I don't plan to change these things.

Always rounding down assumes you aren't going to use the data in a case where you need to round up: we would *have* to make this configurable (probably per-field).  I repeat: you should not be using that output field as input to something else except where you know the units divide exactly (e.g. extent size) and your 'lvcreate' example is not something anybody should be using.

Output used to be inconsistent and we fixed it upstream and in RHEL6 to use S.I. units. I pasted the bit from lvm.conf that has a flag to let you switch between the two behaviours.  (We can't change the default during the life of RHEL5, but you can toggle it yourself.)

Comment 4 Alasdair Kergon 2012-08-21 16:26:57 UTC
In case you didn't understand, the command you should be using (as explained in the lvcreate man page) is:
lvcreate -n brawl0 -l100%FREE brawl


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