Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-14 Thread Manos Pitsidianakis

On Wed, Aug 09, 2017 at 05:39:42PM +0200, Kevin Wolf wrote:

Am 09.08.2017 um 16:45 hat Alberto Garcia geschrieben:

On Wed 09 Aug 2017 03:42:07 PM CEST, Manos Pitsidianakis wrote:
> On Wed, Aug 09, 2017 at 02:36:20PM +0200, Alberto Garcia wrote:
>>On Wed 09 Aug 2017 11:36:12 AM CEST, Manos Pitsidianakis wrote:
>>> On Tue, Aug 08, 2017 at 05:04:48PM +0200, Alberto Garcia wrote:
On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:
>>> So basically if we have anonymous groups, we accept limits in the
>>> driver options but only without a group-name.
>>
>>In the commit message you do however have limits and a group name, is
>>that a mistake?
>>
>>-drive driver=throttle,file.filename=foo.qcow2, \
>>   limits.iops-total=...,throttle-group=bar
>
> Sorry this wasn't clear, I'm actually proposing to remove limits from
> the throttle driver options and only create/config throttle groups via
> -object/object-add.

Sorry I think it was me who misunderstood :-) Anyway in the new
command-line API I would be more inclined to have limits defined using
"-object throttle-group" and -drive would only reference the group id.

I understand that this implies that it wouldn't be possible to create
anonymous groups (at least not from the command line), is that a
problem?
>>>
>>> We can accept anonymous groups if a user specifies limits but not a
>>> group name in the throttle driver. (The only case where limits would
>>> be acccepted)
>>
>>Yeah but that's only if we have the limits.iops-total=... options in the
>>throttle driver. If we "remove limits from the throttle driver options
>>and only create/config throttle groups via -object/object-add" we
>>cannot
>>do that.
>
> We can check that groups is not defined at the same time as limits,

I'm not sure if I'm following the conversation anymore :-) let's try to
recap:

  a) Groups are defined like this (with the current patches):

 -object throttle-group,id=foo,x-iops-total=100,x-..

  b) Throttle nodes are defined like this:

 -drive driver=throttle,file.filename=foo.qcow2, \
limits.iops-total=...,throttle-group=bar

  c) Therefore limits can be defined either in (a) or (b)

  d) If we omit throttle-group=... in (b), we would create an anonymous
 group.

  e) The -drive syntax from (b) has the "problem" that it's possible to
 define several nodes with the same throttling group but different
 limits. The last one would win (as the legacy syntax does), but
 that's not something completely straightforward for the end user.

  f) The syntax from (b) also has the problem that there's one more
 place that needs code to parse throttling limits.

  g) We can solve (e) and (f) if we remove the limits.* options
 altogether from the throttling filter. In that case you would need
 to define a throttle-group object and use the throttle-group option
 of the filter node in all cases.

  h) If we remove the limits.* options we cannot have anonymous groups
 anymore (at least not using this API). My question is: is it a
 problem? What would we lose? What benefits do anonymous groups
 bring us?


As I understand it, basically only the convenience of begin able to
specify a limit directly in -drive rather than having to create an
-object and reference its ID.


  i) We can of course maintain the limits.* options, but disallow
 throttle-group when they are present. That way we would allow
 anonymous groups and we would solve the ambiguity problem described
 in (e). My question is: is it worth it?


Maybe not. Depends on how important we consider the convenience feature.


>>> Not creating eponymous throttle groups via the throttle driver means
>>> we don't need throttle_groups anymore, since even anonymous ones
>>> don't need to be accounted for in a list.
>>
>>I don't follow you here, how else do you get a group by its name?
>
> If all eponymous groups are managed by the QOM tree, we should be able
> to iterate over the object root container for all ThrottleGroups just
> like qmp_query_iothreads() in iothread.c

Mmm... can't we actually use the root container now already? (even with
anonymous groups I mean). Why do we need throttle_groups?


Anonymous groups don't have a parent, so they aren't accessible through
the root container.


Anonymous groups wouldn't have to be in any kind of list, since they
shouldn't be accessible by others and they don't have a name. They have
a refcount of 1 and are owned by their filter node.
(throttle_groups is used in throttle_group_incref() to fetch a tg with a
name and increase its reference count). They will also not be accessible
with qom-set and qom-get.

I've prepared the root container change and will include it in the next 
revision.  Do we go with anonymous groups and disallow limits.* with 
throttle-group, or do we drop anonymous groups altogether?


signature.asc

Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-09 Thread Kevin Wolf
Am 09.08.2017 um 16:45 hat Alberto Garcia geschrieben:
> On Wed 09 Aug 2017 03:42:07 PM CEST, Manos Pitsidianakis wrote:
> > On Wed, Aug 09, 2017 at 02:36:20PM +0200, Alberto Garcia wrote:
> >>On Wed 09 Aug 2017 11:36:12 AM CEST, Manos Pitsidianakis wrote:
> >>> On Tue, Aug 08, 2017 at 05:04:48PM +0200, Alberto Garcia wrote:
> On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:
> >>> So basically if we have anonymous groups, we accept limits in the
> >>> driver options but only without a group-name.
> >>
> >>In the commit message you do however have limits and a group name, is
> >>that a mistake?
> >>
> >>-drive driver=throttle,file.filename=foo.qcow2, \
> >>   limits.iops-total=...,throttle-group=bar
> >
> > Sorry this wasn't clear, I'm actually proposing to remove limits from
> > the throttle driver options and only create/config throttle groups via
> > -object/object-add.
> 
> Sorry I think it was me who misunderstood :-) Anyway in the new
> command-line API I would be more inclined to have limits defined using
> "-object throttle-group" and -drive would only reference the group id.
> 
> I understand that this implies that it wouldn't be possible to create
> anonymous groups (at least not from the command line), is that a
> problem?
> >>>
> >>> We can accept anonymous groups if a user specifies limits but not a
> >>> group name in the throttle driver. (The only case where limits would
> >>> be acccepted)
> >>
> >>Yeah but that's only if we have the limits.iops-total=... options in the
> >>throttle driver. If we "remove limits from the throttle driver options
> >>and only create/config throttle groups via -object/object-add" we 
> >>cannot
> >>do that.
> >
> > We can check that groups is not defined at the same time as limits,
> 
> I'm not sure if I'm following the conversation anymore :-) let's try to
> recap:
> 
>   a) Groups are defined like this (with the current patches):
> 
>  -object throttle-group,id=foo,x-iops-total=100,x-..
> 
>   b) Throttle nodes are defined like this:
> 
>  -drive driver=throttle,file.filename=foo.qcow2, \
> limits.iops-total=...,throttle-group=bar
> 
>   c) Therefore limits can be defined either in (a) or (b)
> 
>   d) If we omit throttle-group=... in (b), we would create an anonymous
>  group.
> 
>   e) The -drive syntax from (b) has the "problem" that it's possible to
>  define several nodes with the same throttling group but different
>  limits. The last one would win (as the legacy syntax does), but
>  that's not something completely straightforward for the end user.
> 
>   f) The syntax from (b) also has the problem that there's one more
>  place that needs code to parse throttling limits.
> 
>   g) We can solve (e) and (f) if we remove the limits.* options
>  altogether from the throttling filter. In that case you would need
>  to define a throttle-group object and use the throttle-group option
>  of the filter node in all cases.
> 
>   h) If we remove the limits.* options we cannot have anonymous groups
>  anymore (at least not using this API). My question is: is it a
>  problem? What would we lose? What benefits do anonymous groups
>  bring us?

As I understand it, basically only the convenience of begin able to
specify a limit directly in -drive rather than having to create an
-object and reference its ID.

>   i) We can of course maintain the limits.* options, but disallow
>  throttle-group when they are present. That way we would allow
>  anonymous groups and we would solve the ambiguity problem described
>  in (e). My question is: is it worth it?

Maybe not. Depends on how important we consider the convenience feature.

> >>> Not creating eponymous throttle groups via the throttle driver means
> >>> we don't need throttle_groups anymore, since even anonymous ones
> >>> don't need to be accounted for in a list.
> >>
> >>I don't follow you here, how else do you get a group by its name?
> >
> > If all eponymous groups are managed by the QOM tree, we should be able
> > to iterate over the object root container for all ThrottleGroups just
> > like qmp_query_iothreads() in iothread.c
> 
> Mmm... can't we actually use the root container now already? (even with
> anonymous groups I mean). Why do we need throttle_groups?

Anonymous groups don't have a parent, so they aren't accessible through
the root container.

Kevin



Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-09 Thread Alberto Garcia
On Wed 09 Aug 2017 03:42:07 PM CEST, Manos Pitsidianakis wrote:
> On Wed, Aug 09, 2017 at 02:36:20PM +0200, Alberto Garcia wrote:
>>On Wed 09 Aug 2017 11:36:12 AM CEST, Manos Pitsidianakis wrote:
>>> On Tue, Aug 08, 2017 at 05:04:48PM +0200, Alberto Garcia wrote:
On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:
>>> So basically if we have anonymous groups, we accept limits in the
>>> driver options but only without a group-name.
>>
>>In the commit message you do however have limits and a group name, is
>>that a mistake?
>>
>>-drive driver=throttle,file.filename=foo.qcow2, \
>>   limits.iops-total=...,throttle-group=bar
>
> Sorry this wasn't clear, I'm actually proposing to remove limits from
> the throttle driver options and only create/config throttle groups via
> -object/object-add.

Sorry I think it was me who misunderstood :-) Anyway in the new
command-line API I would be more inclined to have limits defined using
"-object throttle-group" and -drive would only reference the group id.

I understand that this implies that it wouldn't be possible to create
anonymous groups (at least not from the command line), is that a
problem?
>>>
>>> We can accept anonymous groups if a user specifies limits but not a
>>> group name in the throttle driver. (The only case where limits would
>>> be acccepted)
>>
>>Yeah but that's only if we have the limits.iops-total=... options in the
>>throttle driver. If we "remove limits from the throttle driver options
>>and only create/config throttle groups via -object/object-add" we 
>>cannot
>>do that.
>
> We can check that groups is not defined at the same time as limits,

I'm not sure if I'm following the conversation anymore :-) let's try to
recap:

  a) Groups are defined like this (with the current patches):

 -object throttle-group,id=foo,x-iops-total=100,x-..

  b) Throttle nodes are defined like this:

 -drive driver=throttle,file.filename=foo.qcow2, \
limits.iops-total=...,throttle-group=bar

  c) Therefore limits can be defined either in (a) or (b)

  d) If we omit throttle-group=... in (b), we would create an anonymous
 group.

  e) The -drive syntax from (b) has the "problem" that it's possible to
 define several nodes with the same throttling group but different
 limits. The last one would win (as the legacy syntax does), but
 that's not something completely straightforward for the end user.

  f) The syntax from (b) also has the problem that there's one more
 place that needs code to parse throttling limits.

  g) We can solve (e) and (f) if we remove the limits.* options
 altogether from the throttling filter. In that case you would need
 to define a throttle-group object and use the throttle-group option
 of the filter node in all cases.

  h) If we remove the limits.* options we cannot have anonymous groups
 anymore (at least not using this API). My question is: is it a
 problem? What would we lose? What benefits do anonymous groups
 bring us?
 
  i) We can of course maintain the limits.* options, but disallow
 throttle-group when they are present. That way we would allow
 anonymous groups and we would solve the ambiguity problem described
 in (e). My question is: is it worth it?

>>> Not creating eponymous throttle groups via the throttle driver means
>>> we don't need throttle_groups anymore, since even anonymous ones
>>> don't need to be accounted for in a list.
>>
>>I don't follow you here, how else do you get a group by its name?
>
> If all eponymous groups are managed by the QOM tree, we should be able
> to iterate over the object root container for all ThrottleGroups just
> like qmp_query_iothreads() in iothread.c

Mmm... can't we actually use the root container now already? (even with
anonymous groups I mean). Why do we need throttle_groups?

Berto



Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-09 Thread Manos Pitsidianakis

On Wed, Aug 09, 2017 at 02:36:20PM +0200, Alberto Garcia wrote:

On Wed 09 Aug 2017 11:36:12 AM CEST, Manos Pitsidianakis wrote:

On Tue, Aug 08, 2017 at 05:04:48PM +0200, Alberto Garcia wrote:

On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:

So basically if we have anonymous groups, we accept limits in the
driver options but only without a group-name.


In the commit message you do however have limits and a group name, is
that a mistake?

   -drive driver=throttle,file.filename=foo.qcow2, \
  limits.iops-total=...,throttle-group=bar


Sorry this wasn't clear, I'm actually proposing to remove limits from
the throttle driver options and only create/config throttle groups via
-object/object-add.


Sorry I think it was me who misunderstood :-) Anyway in the new
command-line API I would be more inclined to have limits defined using
"-object throttle-group" and -drive would only reference the group id.

I understand that this implies that it wouldn't be possible to create
anonymous groups (at least not from the command line), is that a
problem?


We can accept anonymous groups if a user specifies limits but not a
group name in the throttle driver. (The only case where limits would
be acccepted)


Yeah but that's only if we have the limits.iops-total=... options in the
throttle driver. If we "remove limits from the throttle driver options
and only create/config throttle groups via -object/object-add" we 
cannot

do that.


We can check that groups is not defined at the same time as limits,



Not creating eponymous throttle groups via the throttle driver means
we don't need throttle_groups anymore, since even anonymous ones don't
need to be accounted for in a list.


I don't follow you here, how else do you get a group by its name?


If all eponymous groups are managed by the QOM tree, we should be able 
to iterate over the object root container for all ThrottleGroups just 
like qmp_query_iothreads() in iothread.c


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-09 Thread Alberto Garcia
On Wed 09 Aug 2017 11:36:12 AM CEST, Manos Pitsidianakis wrote:
> On Tue, Aug 08, 2017 at 05:04:48PM +0200, Alberto Garcia wrote:
>>On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:
> So basically if we have anonymous groups, we accept limits in the
> driver options but only without a group-name.

In the commit message you do however have limits and a group name, is
that a mistake?

-drive driver=throttle,file.filename=foo.qcow2, \
   limits.iops-total=...,throttle-group=bar
>>>
>>> Sorry this wasn't clear, I'm actually proposing to remove limits from
>>> the throttle driver options and only create/config throttle groups via
>>> -object/object-add.
>>
>>Sorry I think it was me who misunderstood :-) Anyway in the new
>>command-line API I would be more inclined to have limits defined using
>>"-object throttle-group" and -drive would only reference the group id.
>>
>>I understand that this implies that it wouldn't be possible to create
>>anonymous groups (at least not from the command line), is that a
>>problem?
>
> We can accept anonymous groups if a user specifies limits but not a
> group name in the throttle driver. (The only case where limits would
> be acccepted)

Yeah but that's only if we have the limits.iops-total=... options in the
throttle driver. If we "remove limits from the throttle driver options
and only create/config throttle groups via -object/object-add" we cannot
do that.

> Not creating eponymous throttle groups via the throttle driver means
> we don't need throttle_groups anymore, since even anonymous ones don't
> need to be accounted for in a list.

I don't follow you here, how else do you get a group by its name?

Berto



Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-09 Thread Manos Pitsidianakis

On Tue, Aug 08, 2017 at 05:04:48PM +0200, Alberto Garcia wrote:

On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:

So basically if we have anonymous groups, we accept limits in the
driver options but only without a group-name.


In the commit message you do however have limits and a group name, is
that a mistake?

   -drive driver=throttle,file.filename=foo.qcow2, \
  limits.iops-total=...,throttle-group=bar


Sorry this wasn't clear, I'm actually proposing to remove limits from
the throttle driver options and only create/config throttle groups via
-object/object-add.


Sorry I think it was me who misunderstood :-) Anyway in the new
command-line API I would be more inclined to have limits defined using
"-object throttle-group" and -drive would only reference the group id.

I understand that this implies that it wouldn't be possible to create
anonymous groups (at least not from the command line), is that a
problem?



We can accept anonymous groups if a user specifies limits but not a 
group name in the throttle driver. (The only case where limits would be 
acccepted)


Not creating eponymous throttle groups via the throttle driver means we 
don't need throttle_groups anymore, since even anonymous ones don't need 
to be accounted for in a list. I will send a new revision for this 
series but I can make this change in a later patch if everyone agrees.


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-08 Thread Alberto Garcia
On Tue 08 Aug 2017 04:56:20 PM CEST, Manos Pitsidianakis wrote:
>>> So basically if we have anonymous groups, we accept limits in the
>>> driver options but only without a group-name.
>>
>>In the commit message you do however have limits and a group name, is
>>that a mistake?
>>
>>-drive driver=throttle,file.filename=foo.qcow2, \
>>   limits.iops-total=...,throttle-group=bar
>
> Sorry this wasn't clear, I'm actually proposing to remove limits from
> the throttle driver options and only create/config throttle groups via
> -object/object-add.

Sorry I think it was me who misunderstood :-) Anyway in the new
command-line API I would be more inclined to have limits defined using
"-object throttle-group" and -drive would only reference the group id.

I understand that this implies that it wouldn't be possible to create
anonymous groups (at least not from the command line), is that a
problem?

Berto



Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-08 Thread Manos Pitsidianakis

On Tue, Aug 08, 2017 at 04:53:08PM +0200, Alberto Garcia wrote:

On Tue 08 Aug 2017 03:45:44 PM CEST, Manos Pitsidianakis wrote:

On Tue, Aug 08, 2017 at 03:13:36PM +0200, Alberto Garcia wrote:

On Mon 31 Jul 2017 11:54:41 AM CEST, Manos Pitsidianakis wrote:

block/throttle.c uses existing I/O throttle infrastructure inside a
block filter driver. I/O operations are intercepted in the filter's
read/write coroutines, and referred to block/throttle-groups.c

The driver can be used with the syntax
-drive driver=throttle,file.filename=foo.qcow2, \
limits.iops-total=...,throttle-group=bar


Sorry for not having noticed this earlier, but can't you define the
throttling group (and its limits) using -object throttle-group ... as
shown in the previous patch, and simply reference it here? Or would we
have two alternative ways of setting the throttling limits?

What happens if you have many -drive lines each one with a different set
of limits but with the same throttling group?


The limits of the last one to be processed will win.


That's what the current throttling API does, and I tend to agree that
it's not completely straightforward (a few people have asked me the same
question since this feature is available).

If we're going to add a new API we could eliminate this ambiguity. After
all the previous -drive throttling.iops-total=... would still be
available, wouldn't it?


Indeed, it already is.




So basically if we have anonymous groups, we accept limits in the
driver options but only without a group-name.


In the commit message you do however have limits and a group name, is
that a mistake?

   -drive driver=throttle,file.filename=foo.qcow2, \
  limits.iops-total=...,throttle-group=bar



Sorry this wasn't clear, I'm actually proposing to remove limits from 
the throttle driver options and only create/config throttle groups via 
-object/object-add.


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-08 Thread Alberto Garcia
On Tue 08 Aug 2017 03:45:44 PM CEST, Manos Pitsidianakis wrote:
> On Tue, Aug 08, 2017 at 03:13:36PM +0200, Alberto Garcia wrote:
>>On Mon 31 Jul 2017 11:54:41 AM CEST, Manos Pitsidianakis wrote:
>>> block/throttle.c uses existing I/O throttle infrastructure inside a
>>> block filter driver. I/O operations are intercepted in the filter's
>>> read/write coroutines, and referred to block/throttle-groups.c
>>>
>>> The driver can be used with the syntax
>>> -drive driver=throttle,file.filename=foo.qcow2, \
>>> limits.iops-total=...,throttle-group=bar
>>
>>Sorry for not having noticed this earlier, but can't you define the
>>throttling group (and its limits) using -object throttle-group ... as
>>shown in the previous patch, and simply reference it here? Or would we
>>have two alternative ways of setting the throttling limits?
>>
>>What happens if you have many -drive lines each one with a different set
>>of limits but with the same throttling group?
>
> The limits of the last one to be processed will win.

That's what the current throttling API does, and I tend to agree that
it's not completely straightforward (a few people have asked me the same
question since this feature is available).

If we're going to add a new API we could eliminate this ambiguity. After
all the previous -drive throttling.iops-total=... would still be
available, wouldn't it?

> So basically if we have anonymous groups, we accept limits in the
> driver options but only without a group-name.

In the commit message you do however have limits and a group name, is
that a mistake?

-drive driver=throttle,file.filename=foo.qcow2, \
   limits.iops-total=...,throttle-group=bar

Berto



Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-08 Thread Manos Pitsidianakis

On Tue, Aug 08, 2017 at 03:13:36PM +0200, Alberto Garcia wrote:

On Mon 31 Jul 2017 11:54:41 AM CEST, Manos Pitsidianakis wrote:

block/throttle.c uses existing I/O throttle infrastructure inside a
block filter driver. I/O operations are intercepted in the filter's
read/write coroutines, and referred to block/throttle-groups.c

The driver can be used with the syntax
-drive driver=throttle,file.filename=foo.qcow2, \
limits.iops-total=...,throttle-group=bar


Sorry for not having noticed this earlier, but can't you define the
throttling group (and its limits) using -object throttle-group ... as
shown in the previous patch, and simply reference it here? Or would we
have two alternative ways of setting the throttling limits?

What happens if you have many -drive lines each one with a different set
of limits but with the same throttling group?


The limits of the last one to be processed will win. Quoting a reply I 
made to Kevin on the interface test patch:



You're right, I missed this. The test result shows that this command
succeeds. Do we really want to allow other nodes to be affected with a
blockdev-add? Wouldn't it be cleaner to just forbid the combination of
limits and throtte-group?


So basically only anonymous, immutable groups can be created through the 
driver then. All other shared group configurations must be explicitly 
created with an -object / object-add syntax. I think this is a neat 
separation and compromise if we allow anonymous groups. If not, we can 
ignore limits on the throttle driver.


So basically if we have anonymous groups, we accept limits in the driver 
options but only without a group-name. Without anonymous groups, we 
remove limits from the driver options and only use the 
object-add/-object commands to create throttle groups. Does this sound 
like a good idea? It will be more verbose for the human user. One 
advantage: all throttle groups can then be managed through 
qom-set/qom-get since they are owned by the qom tree.


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-08 Thread Alberto Garcia
On Mon 31 Jul 2017 11:54:41 AM CEST, Manos Pitsidianakis wrote:
> block/throttle.c uses existing I/O throttle infrastructure inside a
> block filter driver. I/O operations are intercepted in the filter's
> read/write coroutines, and referred to block/throttle-groups.c
>
> The driver can be used with the syntax
> -drive driver=throttle,file.filename=foo.qcow2, \
> limits.iops-total=...,throttle-group=bar

Sorry for not having noticed this earlier, but can't you define the
throttling group (and its limits) using -object throttle-group ... as
shown in the previous patch, and simply reference it here? Or would we
have two alternative ways of setting the throttling limits?

What happens if you have many -drive lines each one with a different set
of limits but with the same throttling group?

Berto



Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-03 Thread Manos Pitsidianakis

On Thu, Aug 03, 2017 at 06:58:30AM -0500, Eric Blake wrote:

On 08/03/2017 03:07 AM, Kevin Wolf wrote:

Am 31.07.2017 um 11:54 hat Manos Pitsidianakis geschrieben:

block/throttle.c uses existing I/O throttle infrastructure inside a
block filter driver. I/O operations are intercepted in the filter's
read/write coroutines, and referred to block/throttle-groups.c

The driver can be used with the syntax
-drive driver=throttle,file.filename=foo.qcow2, \
limits.iops-total=...,throttle-group=bar

The configuration flags and their semantics are identical to the
hardcoded throttling ones.

A node can be created referring to an existing group, and will overwrite
its limits if any are specified, otherwise they are retained.

Signed-off-by: Manos Pitsidianakis 
---



+
+.is_filter  =   true,
+};


What about .bdrv_co_get_block_status?


And if so, do you want my byte-based block status to go in first?  (Our
two series conflict, so we need to pick who needs to rebase on top of
the other).


No problem. My patch is in Kevin's branch for 2.11.  Feel free to merge 
first if needed, I can rebase my patch if you do. 


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-03 Thread Kevin Wolf
Am 03.08.2017 um 13:48 hat Manos Pitsidianakis geschrieben:
> On Thu, Aug 03, 2017 at 10:07:41AM +0200, Kevin Wolf wrote:
> > Am 31.07.2017 um 11:54 hat Manos Pitsidianakis geschrieben:
> > > +/* Extract ThrottleConfig options. Assumes cfg is initialized and will be
> > > + * checked for validity.
> > > + */
> > > +static int throttle_extract_options(QemuOpts *opts, ThrottleConfig *cfg,
> > > + Error **errp)
> > > +{
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL)) {
> > > +cfg->buckets[THROTTLE_BPS_TOTAL].avg =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_BPS_TOTAL,
> > > +0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ)) {
> > > +cfg->buckets[THROTTLE_BPS_READ].avg  =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_BPS_READ,
> > > +0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE)) {
> > > +cfg->buckets[THROTTLE_BPS_WRITE].avg =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_BPS_WRITE,
> > > +0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL)) {
> > > +cfg->buckets[THROTTLE_OPS_TOTAL].avg =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_IOPS_TOTAL,
> > > +0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ)) {
> > > +cfg->buckets[THROTTLE_OPS_READ].avg =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_IOPS_READ,
> > > +0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE)) {
> > > +cfg->buckets[THROTTLE_OPS_WRITE].avg =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_IOPS_WRITE,
> > > +0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX)) {
> > > +cfg->buckets[THROTTLE_BPS_TOTAL].max =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_BPS_TOTAL_MAX, 0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX)) {
> > > +cfg->buckets[THROTTLE_BPS_READ].max  =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_BPS_READ_MAX, 0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX)) {
> > > +cfg->buckets[THROTTLE_BPS_WRITE].max =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_BPS_WRITE_MAX, 0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX)) 
> > > {
> > > +cfg->buckets[THROTTLE_OPS_TOTAL].max =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_IOPS_TOTAL_MAX, 0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX)) {
> > > +cfg->buckets[THROTTLE_OPS_READ].max =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_IOPS_READ_MAX, 0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX)) 
> > > {
> > > +cfg->buckets[THROTTLE_OPS_WRITE].max =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_IOPS_WRITE_MAX, 0);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_BPS_TOTAL_MAX_LENGTH)) {
> > > +if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1) > 
> > > UINT_MAX) {
> > > +error_setg(errp, "%s value must be in the range [0, %u]",
> > > +   THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH,
> > > +   UINT_MAX);
> > > +return -1;
> > > +}
> > > +cfg->buckets[THROTTLE_BPS_TOTAL].burst_length =
> > > +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1);
> > > +}
> > > +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX 
> > > QEMU_OPT_BPS_READ_MAX_LENGTH)) {
> > > +if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> > > +QEMU_OPT_BPS_READ_MAX_LENGTH, 1) > 
> > > UINT_MAX) {
> > > +error_setg(errp, "%s must be in the range [0, %u]",
> > > +   THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH,
> > > +   UINT_MAX);
> > > +  

Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-03 Thread Eric Blake
On 08/03/2017 03:07 AM, Kevin Wolf wrote:
> Am 31.07.2017 um 11:54 hat Manos Pitsidianakis geschrieben:
>> block/throttle.c uses existing I/O throttle infrastructure inside a
>> block filter driver. I/O operations are intercepted in the filter's
>> read/write coroutines, and referred to block/throttle-groups.c
>>
>> The driver can be used with the syntax
>> -drive driver=throttle,file.filename=foo.qcow2, \
>> limits.iops-total=...,throttle-group=bar
>>
>> The configuration flags and their semantics are identical to the
>> hardcoded throttling ones.
>>
>> A node can be created referring to an existing group, and will overwrite
>> its limits if any are specified, otherwise they are retained.
>>
>> Signed-off-by: Manos Pitsidianakis 
>> ---

>> +
>> +.is_filter  =   true,
>> +};
> 
> What about .bdrv_co_get_block_status?

And if so, do you want my byte-based block status to go in first?  (Our
two series conflict, so we need to pick who needs to rebase on top of
the other).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-03 Thread Manos Pitsidianakis

On Thu, Aug 03, 2017 at 10:07:41AM +0200, Kevin Wolf wrote:

Am 31.07.2017 um 11:54 hat Manos Pitsidianakis geschrieben:

+/* Extract ThrottleConfig options. Assumes cfg is initialized and will be
+ * checked for validity.
+ */
+static int throttle_extract_options(QemuOpts *opts, ThrottleConfig *cfg,
+ Error **errp)
+{
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL)) {
+cfg->buckets[THROTTLE_BPS_TOTAL].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ)) {
+cfg->buckets[THROTTLE_BPS_READ].avg  =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE)) {
+cfg->buckets[THROTTLE_BPS_WRITE].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL)) {
+cfg->buckets[THROTTLE_OPS_TOTAL].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ)) {
+cfg->buckets[THROTTLE_OPS_READ].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE)) {
+cfg->buckets[THROTTLE_OPS_WRITE].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX)) {
+cfg->buckets[THROTTLE_BPS_TOTAL].max =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_TOTAL_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX)) {
+cfg->buckets[THROTTLE_BPS_READ].max  =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_READ_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX)) {
+cfg->buckets[THROTTLE_BPS_WRITE].max =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_WRITE_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX)) {
+cfg->buckets[THROTTLE_OPS_TOTAL].max =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_IOPS_TOTAL_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX)) {
+cfg->buckets[THROTTLE_OPS_READ].max =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_IOPS_READ_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX)) {
+cfg->buckets[THROTTLE_OPS_WRITE].max =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_IOPS_WRITE_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH)) 
{
+if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1) > UINT_MAX) {
+error_setg(errp, "%s value must be in the range [0, %u]",
+   THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH,
+   UINT_MAX);
+return -1;
+}
+cfg->buckets[THROTTLE_BPS_TOTAL].burst_length =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_TOTAL_MAX_LENGTH, 1);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH)) {
+if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_READ_MAX_LENGTH, 1) > UINT_MAX) {
+error_setg(errp, "%s must be in the range [0, %u]",
+   THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH,
+   UINT_MAX);
+return -1;
+}
+cfg->buckets[THROTTLE_BPS_READ].burst_length  =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_READ_MAX_LENGTH, 1);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX_LENGTH)) 
{
+if (qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_WRITE_MAX_LENGTH, 1) > UINT_MAX) {
+error_setg(errp, "%s must be in the range [0, %u]",
+   THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX_LENGTH,
+   UINT_MAX);
+return -1;
+}
+

Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-03 Thread Kevin Wolf
Am 31.07.2017 um 11:54 hat Manos Pitsidianakis geschrieben:
> block/throttle.c uses existing I/O throttle infrastructure inside a
> block filter driver. I/O operations are intercepted in the filter's
> read/write coroutines, and referred to block/throttle-groups.c
> 
> The driver can be used with the syntax
> -drive driver=throttle,file.filename=foo.qcow2, \
> limits.iops-total=...,throttle-group=bar
> 
> The configuration flags and their semantics are identical to the
> hardcoded throttling ones.
> 
> A node can be created referring to an existing group, and will overwrite
> its limits if any are specified, otherwise they are retained.
> 
> Signed-off-by: Manos Pitsidianakis 
> ---
>  block/Makefile.objs |   1 +
>  block/throttle.c| 395 
> 
>  include/qemu/throttle-options.h |   1 +
>  3 files changed, 397 insertions(+)
>  create mode 100644 block/throttle.c
> 
> diff --git a/block/Makefile.objs b/block/Makefile.objs
> index 2aaede4ae1..6eaf78a046 100644
> --- a/block/Makefile.objs
> +++ b/block/Makefile.objs
> @@ -25,6 +25,7 @@ block-obj-y += accounting.o dirty-bitmap.o
>  block-obj-y += write-threshold.o
>  block-obj-y += backup.o
>  block-obj-$(CONFIG_REPLICATION) += replication.o
> +block-obj-y += throttle.o
>  
>  block-obj-y += crypto.o
>  
> diff --git a/block/throttle.c b/block/throttle.c
> new file mode 100644
> index 00..f3395462fb
> --- /dev/null
> +++ b/block/throttle.c
> @@ -0,0 +1,395 @@
> +/*
> + * QEMU block throttling filter driver infrastructure
> + *
> + * Copyright (c) 2017 Manos Pitsidianakis
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 or
> + * (at your option) version 3 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "block/throttle-groups.h"
> +#include "qemu/throttle-options.h"
> +#include "qapi/error.h"
> +
> +#undef THROTTLE_OPT_PREFIX
> +#define THROTTLE_OPT_PREFIX "limits."
> +static QemuOptsList throttle_opts = {
> +.name = "throttle",
> +.head = QTAILQ_HEAD_INITIALIZER(throttle_opts.head),
> +.desc = {
> +THROTTLE_OPTS,
> +{
> +.name = QEMU_OPT_THROTTLE_GROUP_NAME,
> +.type = QEMU_OPT_STRING,
> +.help = "throttle group name",
> +},
> +{ /* end of list */ }
> +},
> +};
> +
> +/* Extract ThrottleConfig options. Assumes cfg is initialized and will be
> + * checked for validity.
> + */
> +static int throttle_extract_options(QemuOpts *opts, ThrottleConfig *cfg,
> + Error **errp)
> +{
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL)) {
> +cfg->buckets[THROTTLE_BPS_TOTAL].avg =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL,
> +0);
> +}
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ)) {
> +cfg->buckets[THROTTLE_BPS_READ].avg  =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ,
> +0);
> +}
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE)) {
> +cfg->buckets[THROTTLE_BPS_WRITE].avg =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE,
> +0);
> +}
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL)) {
> +cfg->buckets[THROTTLE_OPS_TOTAL].avg =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> QEMU_OPT_IOPS_TOTAL,
> +0);
> +}
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ)) {
> +cfg->buckets[THROTTLE_OPS_READ].avg =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ,
> +0);
> +}
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE)) {
> +cfg->buckets[THROTTLE_OPS_WRITE].avg =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX 
> QEMU_OPT_IOPS_WRITE,
> +0);
> +}
> +if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX)) {
> +cfg->buckets[THROTTLE_BPS_TOTAL].max =
> +qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
> +QEMU_OPT_BPS_TOTAL_MAX, 0);
> +}
> +if (qemu_opt_get(opts, 

Re: [Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-08-01 Thread Stefan Hajnoczi
On Mon, Jul 31, 2017 at 12:54:41PM +0300, Manos Pitsidianakis wrote:
> +static int throttle_configure_tgm(BlockDriverState *bs,
> +  ThrottleGroupMember *tgm,
> +  QDict *options, Error **errp)
> +{
> +int ret;
> +ThrottleConfig cfg;
> +const char *group_name = NULL;
> +Error *local_err = NULL;
> +QemuOpts *opts = qemu_opts_create(_opts, NULL, 0, _err);

If there is no scenario where this can fail please use error_abort.


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v3 5/7] block: add throttle block filter driver

2017-07-31 Thread Manos Pitsidianakis
block/throttle.c uses existing I/O throttle infrastructure inside a
block filter driver. I/O operations are intercepted in the filter's
read/write coroutines, and referred to block/throttle-groups.c

The driver can be used with the syntax
-drive driver=throttle,file.filename=foo.qcow2, \
limits.iops-total=...,throttle-group=bar

The configuration flags and their semantics are identical to the
hardcoded throttling ones.

A node can be created referring to an existing group, and will overwrite
its limits if any are specified, otherwise they are retained.

Signed-off-by: Manos Pitsidianakis 
---
 block/Makefile.objs |   1 +
 block/throttle.c| 395 
 include/qemu/throttle-options.h |   1 +
 3 files changed, 397 insertions(+)
 create mode 100644 block/throttle.c

diff --git a/block/Makefile.objs b/block/Makefile.objs
index 2aaede4ae1..6eaf78a046 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -25,6 +25,7 @@ block-obj-y += accounting.o dirty-bitmap.o
 block-obj-y += write-threshold.o
 block-obj-y += backup.o
 block-obj-$(CONFIG_REPLICATION) += replication.o
+block-obj-y += throttle.o
 
 block-obj-y += crypto.o
 
diff --git a/block/throttle.c b/block/throttle.c
new file mode 100644
index 00..f3395462fb
--- /dev/null
+++ b/block/throttle.c
@@ -0,0 +1,395 @@
+/*
+ * QEMU block throttling filter driver infrastructure
+ *
+ * Copyright (c) 2017 Manos Pitsidianakis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "block/throttle-groups.h"
+#include "qemu/throttle-options.h"
+#include "qapi/error.h"
+
+#undef THROTTLE_OPT_PREFIX
+#define THROTTLE_OPT_PREFIX "limits."
+static QemuOptsList throttle_opts = {
+.name = "throttle",
+.head = QTAILQ_HEAD_INITIALIZER(throttle_opts.head),
+.desc = {
+THROTTLE_OPTS,
+{
+.name = QEMU_OPT_THROTTLE_GROUP_NAME,
+.type = QEMU_OPT_STRING,
+.help = "throttle group name",
+},
+{ /* end of list */ }
+},
+};
+
+/* Extract ThrottleConfig options. Assumes cfg is initialized and will be
+ * checked for validity.
+ */
+static int throttle_extract_options(QemuOpts *opts, ThrottleConfig *cfg,
+ Error **errp)
+{
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL)) {
+cfg->buckets[THROTTLE_BPS_TOTAL].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ)) {
+cfg->buckets[THROTTLE_BPS_READ].avg  =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE)) {
+cfg->buckets[THROTTLE_BPS_WRITE].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL)) {
+cfg->buckets[THROTTLE_OPS_TOTAL].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ)) {
+cfg->buckets[THROTTLE_OPS_READ].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE)) {
+cfg->buckets[THROTTLE_OPS_WRITE].avg =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE,
+0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX)) {
+cfg->buckets[THROTTLE_BPS_TOTAL].max =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_TOTAL_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX)) {
+cfg->buckets[THROTTLE_BPS_READ].max  =
+qemu_opt_get_number(opts, THROTTLE_OPT_PREFIX
+QEMU_OPT_BPS_READ_MAX, 0);
+}
+if (qemu_opt_get(opts, THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX)) {
+