On Tue, May 26, 2015 at 08:22:23 -0600, Eric Blake wrote:
On 05/26/2015 04:25 AM, Daniel P. Berrange wrote:
> On Mon, May 25, 2015 at 11:11:14AM +0200, Peter Krempa wrote:
>> On Sat, May 23, 2015 at 21:45:56 -0600, Eric Blake wrote:
...
>> Double? Your last proposal used unsigned long long. Using
double with
>> byte sizes seems a bit odd to me. The file size won't exceed unsigned
>> long long for a while so I don't see a reason to use double here.
>
> Yes, I'm inclined to say u long long too, since that's what we use
throughout
> the APIs for representing disk image sizes. So in the unlikely event that
> we do hit the limits of unsigned long long, we'd have countless APIs to
> change regardless.
I intended that:
virDomainSetWriteThreshold(dom, disk, 10*1024*1024*1024, 0)
would be the obvious way of setting a threshold at 10G, and that:
virDomainSetWriteThreshold(dom, disk, 81.47295,
VIR_DOMAIN_BLOCK_SET_WRITE_THRESHOLD_PERCENTAGE)
would set the disk to 81.47295% of the current size (rounded to a
suitable granularity, even if such rounding is merely truncating to the
nearest int).
Basically, the code I added in libvirt-domain.c enforces that value >= 0
(negative and NaN are not permitted; -0.0 behaves the same as +0.0), and
that value <= ULLONG_MAX (for flags == 0) or <= 100.0 (for flags
specifying percentage). When flags is 0, this means that for values <
2^53, the byte value is accurate if the user computes their limit in
unsigned long long and uses automatic conversion to double; for values
between 2^53 and 2^64, you lose precision on the low end [but who needs
that much granularity on disks that big, right?], and values > 2^64
(including +inf) are forbidden - so we are still handling things in
unsigned long long. If someone plays games by passing 12345678.9, the
code will round to a nearby int (whether 12345678 or 12345679 probably
won't matter too much, but the docs tried to make it clear that it is up
to the hypervisor what rounding occurs). And no matter what the user
passes in, the number is converted to unsigned long long before use, and
all output functions report it in ullong.
The main reason I wanted double was to make percentages more natural; by
using a double, the user is in full control of how much precision to use
(100.1, 100.1234564, ...), and for disks smaller than 2^53, the user can
use percentage to get to a specific byte value. Whereas with fixed
point, we are limiting users to a fixed amount of precision (if we take
solely 0-100, the user can't do any less than 1% of disk size; or if we
state the range is 0-100000, where 80123 is 80.123%, then the user still
can't get any finer than a megabyte on a multi-gigabyte image). Again,
querying the threshold will show the user what the actual value in bytes
was computed to be (again allowing for the hypervisor to round to an
appropriate granularity if necessary).
The user still can calculate the ultra-accurate value by polling the
size and calculating it in the mgmt code and passing the size in bytes.
It will save all the logic you described above for almost all use cases
and the rest can calculate the value externally. I doubt that anybody
will use something else as integer percent values though.
But I can convert my code back to taking threshold as ullong, and
providing the flag as fixed point rather than floating point for
requesting percentages, if that is desired. If so, what fixed point
should I pick, a thousandth of a percentage (0-100000)?
1e5 is unnatural. Use parts-per-million or parts-per-billion, that is
widely used. Percentage is the only odd one that does not use a multiple
of 3 as the exponent.
Peter