-----BEGIN PGP SIGNATURE-----
iQEcBAABAgAGBQJZp8cdAAoJEJykq7OBq3PIyeQIALXlHMTJM+I2dfUZfkIYFrEk Euf0z1URMJ9k5hKy1kIhAVlmGWs2fB1snTCm9tZjCtPqMjH5EDWb8z+zrqmorpcQ LyIccYdT/XrFeU1x+n4PlhaubQKXiAfZbUbgZpbkZwGgX0k51gx3V9z1smHme6AX CIODhgotqbJ0Hy2kuAP8TM2OPgx1tcyel34GuT5e3Rrb8nL0QfHfG4nxcpWBB0q8 iipoJfBvKWpRV0azSg+s51x1FFcB3iDKr81uBVABOyLtVW13nF6EMRIP76rqy5qp relNDo6kdmh0W19motNPjOa4BhnPQakEfF+bdARBOJPbXsFzd5X193yQBKW+nq4= =5ltA -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging # gpg: Signature made Thu 31 Aug 2017 09:21:49 BST # gpg: using RSA key 0x9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/block-pull-request: qcow2: allocate cluster_cache/cluster_data on demand qemu-doc: Add UUID support in initiator name tests: migration/guestperf Python 2.6 argparse compatibility docker.py: Python 2.6 argparse compatibility scripts: add argparse module for Python 2.6 compatibility misc: Remove unused Error variables oslib-posix: Print errors before aborting on qemu_alloc_stack() throttle: Test the valid range of config values throttle: Make burst_length 64bit and add range checks throttle: Make LeakyBucket.avg and LeakyBucket.max integer types throttle: Remove throttle_fix_bucket() / throttle_unfix_bucket() throttle: Make throttle_is_valid() a bit less verbose throttle: Update the throttle_fix_bucket() documentation throttle: Fix wrong variable name in the header documentation nvme: Fix get/set number of queues feature, again Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						1d2a8e0690
					
				| 
						 | 
				
			
			@ -0,0 +1,270 @@
 | 
			
		|||
A. HISTORY OF THE SOFTWARE
 | 
			
		||||
==========================
 | 
			
		||||
 | 
			
		||||
Python was created in the early 1990s by Guido van Rossum at Stichting
 | 
			
		||||
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
 | 
			
		||||
as a successor of a language called ABC.  Guido remains Python's
 | 
			
		||||
principal author, although it includes many contributions from others.
 | 
			
		||||
 | 
			
		||||
In 1995, Guido continued his work on Python at the Corporation for
 | 
			
		||||
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
 | 
			
		||||
in Reston, Virginia where he released several versions of the
 | 
			
		||||
software.
 | 
			
		||||
 | 
			
		||||
In May 2000, Guido and the Python core development team moved to
 | 
			
		||||
BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
 | 
			
		||||
year, the PythonLabs team moved to Digital Creations (now Zope
 | 
			
		||||
Corporation, see http://www.zope.com).  In 2001, the Python Software
 | 
			
		||||
Foundation (PSF, see http://www.python.org/psf/) was formed, a
 | 
			
		||||
non-profit organization created specifically to own Python-related
 | 
			
		||||
Intellectual Property.  Zope Corporation is a sponsoring member of
 | 
			
		||||
the PSF.
 | 
			
		||||
 | 
			
		||||
All Python releases are Open Source (see http://www.opensource.org for
 | 
			
		||||
the Open Source Definition).  Historically, most, but not all, Python
 | 
			
		||||
releases have also been GPL-compatible; the table below summarizes
 | 
			
		||||
the various releases.
 | 
			
		||||
 | 
			
		||||
    Release         Derived     Year        Owner       GPL-
 | 
			
		||||
                    from                                compatible? (1)
 | 
			
		||||
 | 
			
		||||
    0.9.0 thru 1.2              1991-1995   CWI         yes
 | 
			
		||||
    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
 | 
			
		||||
    1.6             1.5.2       2000        CNRI        no
 | 
			
		||||
    2.0             1.6         2000        BeOpen.com  no
 | 
			
		||||
    1.6.1           1.6         2001        CNRI        yes (2)
 | 
			
		||||
    2.1             2.0+1.6.1   2001        PSF         no
 | 
			
		||||
    2.0.1           2.0+1.6.1   2001        PSF         yes
 | 
			
		||||
    2.1.1           2.1+2.0.1   2001        PSF         yes
 | 
			
		||||
    2.2             2.1.1       2001        PSF         yes
 | 
			
		||||
    2.1.2           2.1.1       2002        PSF         yes
 | 
			
		||||
    2.1.3           2.1.2       2002        PSF         yes
 | 
			
		||||
    2.2.1           2.2         2002        PSF         yes
 | 
			
		||||
    2.2.2           2.2.1       2002        PSF         yes
 | 
			
		||||
    2.2.3           2.2.2       2003        PSF         yes
 | 
			
		||||
    2.3             2.2.2       2002-2003   PSF         yes
 | 
			
		||||
    2.3.1           2.3         2002-2003   PSF         yes
 | 
			
		||||
    2.3.2           2.3.1       2002-2003   PSF         yes
 | 
			
		||||
    2.3.3           2.3.2       2002-2003   PSF         yes
 | 
			
		||||
    2.3.4           2.3.3       2004        PSF         yes
 | 
			
		||||
    2.3.5           2.3.4       2005        PSF         yes
 | 
			
		||||
    2.4             2.3         2004        PSF         yes
 | 
			
		||||
    2.4.1           2.4         2005        PSF         yes
 | 
			
		||||
    2.4.2           2.4.1       2005        PSF         yes
 | 
			
		||||
    2.4.3           2.4.2       2006        PSF         yes
 | 
			
		||||
    2.5             2.4         2006        PSF         yes
 | 
			
		||||
    2.7             2.6         2010        PSF         yes
 | 
			
		||||
 | 
			
		||||
Footnotes:
 | 
			
		||||
 | 
			
		||||
(1) GPL-compatible doesn't mean that we're distributing Python under
 | 
			
		||||
    the GPL.  All Python licenses, unlike the GPL, let you distribute
 | 
			
		||||
    a modified version without making your changes open source.  The
 | 
			
		||||
    GPL-compatible licenses make it possible to combine Python with
 | 
			
		||||
    other software that is released under the GPL; the others don't.
 | 
			
		||||
 | 
			
		||||
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
 | 
			
		||||
    because its license has a choice of law clause.  According to
 | 
			
		||||
    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
 | 
			
		||||
    is "not incompatible" with the GPL.
 | 
			
		||||
 | 
			
		||||
Thanks to the many outside volunteers who have worked under Guido's
 | 
			
		||||
direction to make these releases possible.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
 | 
			
		||||
===============================================================
 | 
			
		||||
 | 
			
		||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
 | 
			
		||||
--------------------------------------------
 | 
			
		||||
 | 
			
		||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
 | 
			
		||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
 | 
			
		||||
otherwise using this software ("Python") in source or binary form and
 | 
			
		||||
its associated documentation.
 | 
			
		||||
 | 
			
		||||
2. Subject to the terms and conditions of this License Agreement, PSF
 | 
			
		||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
 | 
			
		||||
license to reproduce, analyze, test, perform and/or display publicly,
 | 
			
		||||
prepare derivative works, distribute, and otherwise use Python
 | 
			
		||||
alone or in any derivative version, provided, however, that PSF's
 | 
			
		||||
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
 | 
			
		||||
2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
 | 
			
		||||
Reserved" are retained in Python alone or in any derivative version 
 | 
			
		||||
prepared by Licensee.
 | 
			
		||||
 | 
			
		||||
3. In the event Licensee prepares a derivative work that is based on
 | 
			
		||||
or incorporates Python or any part thereof, and wants to make
 | 
			
		||||
the derivative work available to others as provided herein, then
 | 
			
		||||
Licensee hereby agrees to include in any such work a brief summary of
 | 
			
		||||
the changes made to Python.
 | 
			
		||||
 | 
			
		||||
4. PSF is making Python available to Licensee on an "AS IS"
 | 
			
		||||
basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
 | 
			
		||||
IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
 | 
			
		||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
 | 
			
		||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
 | 
			
		||||
INFRINGE ANY THIRD PARTY RIGHTS.
 | 
			
		||||
 | 
			
		||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
 | 
			
		||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
 | 
			
		||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
 | 
			
		||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
 | 
			
		||||
 | 
			
		||||
6. This License Agreement will automatically terminate upon a material
 | 
			
		||||
breach of its terms and conditions.
 | 
			
		||||
 | 
			
		||||
7. Nothing in this License Agreement shall be deemed to create any
 | 
			
		||||
relationship of agency, partnership, or joint venture between PSF and
 | 
			
		||||
Licensee.  This License Agreement does not grant permission to use PSF
 | 
			
		||||
trademarks or trade name in a trademark sense to endorse or promote
 | 
			
		||||
products or services of Licensee, or any third party.
 | 
			
		||||
 | 
			
		||||
8. By copying, installing or otherwise using Python, Licensee
 | 
			
		||||
agrees to be bound by the terms and conditions of this License
 | 
			
		||||
Agreement.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
 | 
			
		||||
-------------------------------------------
 | 
			
		||||
 | 
			
		||||
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
 | 
			
		||||
 | 
			
		||||
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
 | 
			
		||||
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
 | 
			
		||||
Individual or Organization ("Licensee") accessing and otherwise using
 | 
			
		||||
this software in source or binary form and its associated
 | 
			
		||||
documentation ("the Software").
 | 
			
		||||
 | 
			
		||||
2. Subject to the terms and conditions of this BeOpen Python License
 | 
			
		||||
Agreement, BeOpen hereby grants Licensee a non-exclusive,
 | 
			
		||||
royalty-free, world-wide license to reproduce, analyze, test, perform
 | 
			
		||||
and/or display publicly, prepare derivative works, distribute, and
 | 
			
		||||
otherwise use the Software alone or in any derivative version,
 | 
			
		||||
provided, however, that the BeOpen Python License is retained in the
 | 
			
		||||
Software, alone or in any derivative version prepared by Licensee.
 | 
			
		||||
 | 
			
		||||
3. BeOpen is making the Software available to Licensee on an "AS IS"
 | 
			
		||||
basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
 | 
			
		||||
IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
 | 
			
		||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
 | 
			
		||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
 | 
			
		||||
INFRINGE ANY THIRD PARTY RIGHTS.
 | 
			
		||||
 | 
			
		||||
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
 | 
			
		||||
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
 | 
			
		||||
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
 | 
			
		||||
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
 | 
			
		||||
 | 
			
		||||
5. This License Agreement will automatically terminate upon a material
 | 
			
		||||
breach of its terms and conditions.
 | 
			
		||||
 | 
			
		||||
6. This License Agreement shall be governed by and interpreted in all
 | 
			
		||||
respects by the law of the State of California, excluding conflict of
 | 
			
		||||
law provisions.  Nothing in this License Agreement shall be deemed to
 | 
			
		||||
create any relationship of agency, partnership, or joint venture
 | 
			
		||||
between BeOpen and Licensee.  This License Agreement does not grant
 | 
			
		||||
permission to use BeOpen trademarks or trade names in a trademark
 | 
			
		||||
sense to endorse or promote products or services of Licensee, or any
 | 
			
		||||
third party.  As an exception, the "BeOpen Python" logos available at
 | 
			
		||||
http://www.pythonlabs.com/logos.html may be used according to the
 | 
			
		||||
permissions granted on that web page.
 | 
			
		||||
 | 
			
		||||
7. By copying, installing or otherwise using the software, Licensee
 | 
			
		||||
agrees to be bound by the terms and conditions of this License
 | 
			
		||||
Agreement.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
 | 
			
		||||
---------------------------------------
 | 
			
		||||
 | 
			
		||||
1. This LICENSE AGREEMENT is between the Corporation for National
 | 
			
		||||
Research Initiatives, having an office at 1895 Preston White Drive,
 | 
			
		||||
Reston, VA 20191 ("CNRI"), and the Individual or Organization
 | 
			
		||||
("Licensee") accessing and otherwise using Python 1.6.1 software in
 | 
			
		||||
source or binary form and its associated documentation.
 | 
			
		||||
 | 
			
		||||
2. Subject to the terms and conditions of this License Agreement, CNRI
 | 
			
		||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
 | 
			
		||||
license to reproduce, analyze, test, perform and/or display publicly,
 | 
			
		||||
prepare derivative works, distribute, and otherwise use Python 1.6.1
 | 
			
		||||
alone or in any derivative version, provided, however, that CNRI's
 | 
			
		||||
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
 | 
			
		||||
1995-2001 Corporation for National Research Initiatives; All Rights
 | 
			
		||||
Reserved" are retained in Python 1.6.1 alone or in any derivative
 | 
			
		||||
version prepared by Licensee.  Alternately, in lieu of CNRI's License
 | 
			
		||||
Agreement, Licensee may substitute the following text (omitting the
 | 
			
		||||
quotes): "Python 1.6.1 is made available subject to the terms and
 | 
			
		||||
conditions in CNRI's License Agreement.  This Agreement together with
 | 
			
		||||
Python 1.6.1 may be located on the Internet using the following
 | 
			
		||||
unique, persistent identifier (known as a handle): 1895.22/1013.  This
 | 
			
		||||
Agreement may also be obtained from a proxy server on the Internet
 | 
			
		||||
using the following URL: http://hdl.handle.net/1895.22/1013".
 | 
			
		||||
 | 
			
		||||
3. In the event Licensee prepares a derivative work that is based on
 | 
			
		||||
or incorporates Python 1.6.1 or any part thereof, and wants to make
 | 
			
		||||
the derivative work available to others as provided herein, then
 | 
			
		||||
Licensee hereby agrees to include in any such work a brief summary of
 | 
			
		||||
the changes made to Python 1.6.1.
 | 
			
		||||
 | 
			
		||||
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
 | 
			
		||||
basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
 | 
			
		||||
IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
 | 
			
		||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
 | 
			
		||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
 | 
			
		||||
INFRINGE ANY THIRD PARTY RIGHTS.
 | 
			
		||||
 | 
			
		||||
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
 | 
			
		||||
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
 | 
			
		||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
 | 
			
		||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
 | 
			
		||||
 | 
			
		||||
6. This License Agreement will automatically terminate upon a material
 | 
			
		||||
breach of its terms and conditions.
 | 
			
		||||
 | 
			
		||||
7. This License Agreement shall be governed by the federal
 | 
			
		||||
intellectual property law of the United States, including without
 | 
			
		||||
limitation the federal copyright law, and, to the extent such
 | 
			
		||||
U.S. federal law does not apply, by the law of the Commonwealth of
 | 
			
		||||
Virginia, excluding Virginia's conflict of law provisions.
 | 
			
		||||
Notwithstanding the foregoing, with regard to derivative works based
 | 
			
		||||
on Python 1.6.1 that incorporate non-separable material that was
 | 
			
		||||
previously distributed under the GNU General Public License (GPL), the
 | 
			
		||||
law of the Commonwealth of Virginia shall govern this License
 | 
			
		||||
Agreement only as to issues arising under or with respect to
 | 
			
		||||
Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
 | 
			
		||||
License Agreement shall be deemed to create any relationship of
 | 
			
		||||
agency, partnership, or joint venture between CNRI and Licensee.  This
 | 
			
		||||
License Agreement does not grant permission to use CNRI trademarks or
 | 
			
		||||
trade name in a trademark sense to endorse or promote products or
 | 
			
		||||
services of Licensee, or any third party.
 | 
			
		||||
 | 
			
		||||
8. By clicking on the "ACCEPT" button where indicated, or by copying,
 | 
			
		||||
installing or otherwise using Python 1.6.1, Licensee agrees to be
 | 
			
		||||
bound by the terms and conditions of this License Agreement.
 | 
			
		||||
 | 
			
		||||
        ACCEPT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
 | 
			
		||||
--------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
 | 
			
		||||
The Netherlands.  All rights reserved.
 | 
			
		||||
 | 
			
		||||
Permission to use, copy, modify, and distribute this software and its
 | 
			
		||||
documentation for any purpose and without fee is hereby granted,
 | 
			
		||||
provided that the above copyright notice appear in all copies and that
 | 
			
		||||
both that copyright notice and this permission notice appear in
 | 
			
		||||
supporting documentation, and that the name of Stichting Mathematisch
 | 
			
		||||
Centrum or CWI not be used in advertising or publicity pertaining to
 | 
			
		||||
distribution of the software without specific, written prior
 | 
			
		||||
permission.
 | 
			
		||||
 | 
			
		||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
 | 
			
		||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
 | 
			
		||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 | 
			
		||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
							
								
								
									
										12
									
								
								block/qcow.c
								
								
								
								
							
							
						
						
									
										12
									
								
								block/qcow.c
								
								
								
								
							| 
						 | 
				
			
			@ -454,13 +454,11 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
 | 
			
		|||
                    start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
 | 
			
		||||
                    for(i = 0; i < s->cluster_sectors; i++) {
 | 
			
		||||
                        if (i < n_start || i >= n_end) {
 | 
			
		||||
                            Error *err = NULL;
 | 
			
		||||
                            memset(s->cluster_data, 0x00, 512);
 | 
			
		||||
                            if (qcrypto_block_encrypt(s->crypto, start_sect + i,
 | 
			
		||||
                                                      s->cluster_data,
 | 
			
		||||
                                                      BDRV_SECTOR_SIZE,
 | 
			
		||||
                                                      &err) < 0) {
 | 
			
		||||
                                error_free(err);
 | 
			
		||||
                                                      NULL) < 0) {
 | 
			
		||||
                                errno = EIO;
 | 
			
		||||
                                return -1;
 | 
			
		||||
                            }
 | 
			
		||||
| 
						 | 
				
			
			@ -572,7 +570,6 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
 | 
			
		|||
    QEMUIOVector hd_qiov;
 | 
			
		||||
    uint8_t *buf;
 | 
			
		||||
    void *orig_buf;
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
 | 
			
		||||
    if (qiov->niov > 1) {
 | 
			
		||||
        buf = orig_buf = qemu_try_blockalign(bs, qiov->size);
 | 
			
		||||
| 
						 | 
				
			
			@ -637,7 +634,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
 | 
			
		|||
            if (bs->encrypted) {
 | 
			
		||||
                assert(s->crypto);
 | 
			
		||||
                if (qcrypto_block_decrypt(s->crypto, sector_num, buf,
 | 
			
		||||
                                          n * BDRV_SECTOR_SIZE, &err) < 0) {
 | 
			
		||||
                                          n * BDRV_SECTOR_SIZE, NULL) < 0) {
 | 
			
		||||
                    goto fail;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -660,7 +657,6 @@ done:
 | 
			
		|||
    return ret;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    error_free(err);
 | 
			
		||||
    ret = -EIO;
 | 
			
		||||
    goto done;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -709,11 +705,9 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
 | 
			
		|||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (bs->encrypted) {
 | 
			
		||||
            Error *err = NULL;
 | 
			
		||||
            assert(s->crypto);
 | 
			
		||||
            if (qcrypto_block_encrypt(s->crypto, sector_num, buf,
 | 
			
		||||
                                      n * BDRV_SECTOR_SIZE, &err) < 0) {
 | 
			
		||||
                error_free(err);
 | 
			
		||||
                                      n * BDRV_SECTOR_SIZE, NULL) < 0) {
 | 
			
		||||
                ret = -EIO;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1516,6 +1516,23 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
 | 
			
		|||
        nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
 | 
			
		||||
        sector_offset = coffset & 511;
 | 
			
		||||
        csize = nb_csectors * 512 - sector_offset;
 | 
			
		||||
 | 
			
		||||
        /* Allocate buffers on first decompress operation, most images are
 | 
			
		||||
         * uncompressed and the memory overhead can be avoided.  The buffers
 | 
			
		||||
         * are freed in .bdrv_close().
 | 
			
		||||
         */
 | 
			
		||||
        if (!s->cluster_data) {
 | 
			
		||||
            /* one more sector for decompressed data alignment */
 | 
			
		||||
            s->cluster_data = qemu_try_blockalign(bs->file->bs,
 | 
			
		||||
                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size + 512);
 | 
			
		||||
            if (!s->cluster_data) {
 | 
			
		||||
                return -ENOMEM;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!s->cluster_cache) {
 | 
			
		||||
            s->cluster_cache = g_malloc(s->cluster_size);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
 | 
			
		||||
        ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data,
 | 
			
		||||
                        nb_csectors);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1360,16 +1360,6 @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->cluster_cache = g_malloc(s->cluster_size);
 | 
			
		||||
    /* one more sector for decompressed data alignment */
 | 
			
		||||
    s->cluster_data = qemu_try_blockalign(bs->file->bs, QCOW_MAX_CRYPT_CLUSTERS
 | 
			
		||||
                                                    * s->cluster_size + 512);
 | 
			
		||||
    if (s->cluster_data == NULL) {
 | 
			
		||||
        error_setg(errp, "Could not allocate temporary cluster buffer");
 | 
			
		||||
        ret = -ENOMEM;
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->cluster_cache_offset = -1;
 | 
			
		||||
    s->flags = flags;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1507,8 +1497,6 @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
 | 
			
		|||
    if (s->refcount_block_cache) {
 | 
			
		||||
        qcow2_cache_destroy(bs, s->refcount_block_cache);
 | 
			
		||||
    }
 | 
			
		||||
    g_free(s->cluster_cache);
 | 
			
		||||
    qemu_vfree(s->cluster_data);
 | 
			
		||||
    qcrypto_block_free(s->crypto);
 | 
			
		||||
    qapi_free_QCryptoBlockOpenOptions(s->crypto_opts);
 | 
			
		||||
    return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -1820,15 +1808,13 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
 | 
			
		|||
                assert(s->crypto);
 | 
			
		||||
                assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
 | 
			
		||||
                assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
 | 
			
		||||
                Error *err = NULL;
 | 
			
		||||
                if (qcrypto_block_decrypt(s->crypto,
 | 
			
		||||
                                          (s->crypt_physical_offset ?
 | 
			
		||||
                                           cluster_offset + offset_in_cluster :
 | 
			
		||||
                                           offset) >> BDRV_SECTOR_BITS,
 | 
			
		||||
                                          cluster_data,
 | 
			
		||||
                                          cur_bytes,
 | 
			
		||||
                                          &err) < 0) {
 | 
			
		||||
                    error_free(err);
 | 
			
		||||
                                          NULL) < 0) {
 | 
			
		||||
                    ret = -EIO;
 | 
			
		||||
                    goto fail;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -1942,7 +1928,6 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
 | 
			
		|||
        qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes);
 | 
			
		||||
 | 
			
		||||
        if (bs->encrypted) {
 | 
			
		||||
            Error *err = NULL;
 | 
			
		||||
            assert(s->crypto);
 | 
			
		||||
            if (!cluster_data) {
 | 
			
		||||
                cluster_data = qemu_try_blockalign(bs->file->bs,
 | 
			
		||||
| 
						 | 
				
			
			@ -1963,8 +1948,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
 | 
			
		|||
                                       cluster_offset + offset_in_cluster :
 | 
			
		||||
                                       offset) >> BDRV_SECTOR_BITS,
 | 
			
		||||
                                      cluster_data,
 | 
			
		||||
                                      cur_bytes, &err) < 0) {
 | 
			
		||||
                error_free(err);
 | 
			
		||||
                                      cur_bytes, NULL) < 0) {
 | 
			
		||||
                ret = -EIO;
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								dump.c
								
								
								
								
							
							
						
						
									
										4
									
								
								dump.c
								
								
								
								
							| 
						 | 
				
			
			@ -1695,10 +1695,8 @@ static void dump_process(DumpState *s, Error **errp)
 | 
			
		|||
 | 
			
		||||
static void *dump_thread(void *data)
 | 
			
		||||
{
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
    DumpState *s = (DumpState *)data;
 | 
			
		||||
    dump_process(s, &err);
 | 
			
		||||
    error_free(err);
 | 
			
		||||
    dump_process(s, NULL);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -615,7 +615,7 @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
 | 
			
		|||
        result = blk_enable_write_cache(n->conf.blk);
 | 
			
		||||
        break;
 | 
			
		||||
    case NVME_NUMBER_OF_QUEUES:
 | 
			
		||||
        result = cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16));
 | 
			
		||||
        result = cpu_to_le32((n->num_queues - 2) | ((n->num_queues - 2) << 16));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return NVME_INVALID_FIELD | NVME_DNR;
 | 
			
		||||
| 
						 | 
				
			
			@ -636,7 +636,7 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
 | 
			
		|||
        break;
 | 
			
		||||
    case NVME_NUMBER_OF_QUEUES:
 | 
			
		||||
        req->cqe.result =
 | 
			
		||||
            cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16));
 | 
			
		||||
            cpu_to_le32((n->num_queues - 2) | ((n->num_queues - 2) << 16));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return NVME_INVALID_FIELD | NVME_DNR;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ typedef enum {
 | 
			
		|||
 * - The bkt.avg rate does not apply until the bucket is full,
 | 
			
		||||
 *   allowing the user to do bursts until then. The I/O limit during
 | 
			
		||||
 *   bursts is bkt.max. To enforce this limit we keep an additional
 | 
			
		||||
 *   bucket in bkt.burst_length that leaks at a rate of bkt.max units
 | 
			
		||||
 *   bucket in bkt.burst_level that leaks at a rate of bkt.max units
 | 
			
		||||
 *   per second.
 | 
			
		||||
 *
 | 
			
		||||
 * - Because of all of the above, the user can perform I/O at a
 | 
			
		||||
| 
						 | 
				
			
			@ -77,11 +77,11 @@ typedef enum {
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct LeakyBucket {
 | 
			
		||||
    double  avg;              /* average goal in units per second */
 | 
			
		||||
    double  max;              /* leaky bucket max burst in units */
 | 
			
		||||
    uint64_t avg;             /* average goal in units per second */
 | 
			
		||||
    uint64_t max;             /* leaky bucket max burst in units */
 | 
			
		||||
    double  level;            /* bucket level in units */
 | 
			
		||||
    double  burst_level;      /* bucket level in units (for computing bursts) */
 | 
			
		||||
    unsigned burst_length;    /* max length of the burst period, in seconds */
 | 
			
		||||
    uint64_t burst_length;    /* max length of the burst period, in seconds */
 | 
			
		||||
} LeakyBucket;
 | 
			
		||||
 | 
			
		||||
/* The following structure is used to configure a ThrottleState
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1066,10 +1066,11 @@ in a configuration file provided via '-readconfig' or directly on the
 | 
			
		|||
command line.
 | 
			
		||||
 | 
			
		||||
If the initiator-name is not specified qemu will use a default name
 | 
			
		||||
of 'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
 | 
			
		||||
of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
 | 
			
		||||
virtual machine. If the UUID is not specified qemu will use
 | 
			
		||||
'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
 | 
			
		||||
virtual machine.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@example
 | 
			
		||||
Setting a specific initiator name to use when logging in to the target
 | 
			
		||||
-iscsi initiator-name=iqn.qemu.test:my-initiator
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -13,12 +13,14 @@
 | 
			
		|||
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
sys.path.append(os.path.join(os.path.dirname(__file__),
 | 
			
		||||
                             '..', '..', 'scripts'))
 | 
			
		||||
import argparse
 | 
			
		||||
import subprocess
 | 
			
		||||
import json
 | 
			
		||||
import hashlib
 | 
			
		||||
import atexit
 | 
			
		||||
import uuid
 | 
			
		||||
import argparse
 | 
			
		||||
import tempfile
 | 
			
		||||
import re
 | 
			
		||||
import signal
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,12 +18,14 @@
 | 
			
		|||
#
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import argparse
 | 
			
		||||
import fnmatch
 | 
			
		||||
import os
 | 
			
		||||
import os.path
 | 
			
		||||
import platform
 | 
			
		||||
import sys
 | 
			
		||||
sys.path.append(os.path.join(os.path.dirname(__file__),
 | 
			
		||||
                             '..', '..', '..', 'scripts'))
 | 
			
		||||
import argparse
 | 
			
		||||
import fnmatch
 | 
			
		||||
import platform
 | 
			
		||||
 | 
			
		||||
from guestperf.hardware import Hardware
 | 
			
		||||
from guestperf.engine import Engine
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -284,13 +284,14 @@ static void test_enabled(void)
 | 
			
		|||
    for (i = 0; i < BUCKETS_COUNT; i++) {
 | 
			
		||||
        throttle_config_init(&cfg);
 | 
			
		||||
        set_cfg_value(false, i, 150);
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
        g_assert(throttle_enabled(&cfg));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < BUCKETS_COUNT; i++) {
 | 
			
		||||
        throttle_config_init(&cfg);
 | 
			
		||||
        set_cfg_value(false, i, -150);
 | 
			
		||||
        g_assert(!throttle_enabled(&cfg));
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -377,6 +378,82 @@ static void test_is_valid(void)
 | 
			
		|||
    test_is_valid_for_value(1, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_ranges(void)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < BUCKETS_COUNT; i++) {
 | 
			
		||||
        LeakyBucket *b = &cfg.buckets[i];
 | 
			
		||||
        throttle_config_init(&cfg);
 | 
			
		||||
 | 
			
		||||
        /* avg = 0 means throttling is disabled, but the config is valid */
 | 
			
		||||
        b->avg = 0;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
        g_assert(!throttle_enabled(&cfg));
 | 
			
		||||
 | 
			
		||||
        /* These are valid configurations (values <= THROTTLE_VALUE_MAX) */
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = THROTTLE_VALUE_MAX;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = THROTTLE_VALUE_MAX;
 | 
			
		||||
        b->max = THROTTLE_VALUE_MAX;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        /* Values over THROTTLE_VALUE_MAX are not allowed */
 | 
			
		||||
        b->avg = THROTTLE_VALUE_MAX + 1;
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = THROTTLE_VALUE_MAX;
 | 
			
		||||
        b->max = THROTTLE_VALUE_MAX + 1;
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        /* burst_length must be between 1 and THROTTLE_VALUE_MAX */
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = 1;
 | 
			
		||||
        b->burst_length = 0;
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = 1;
 | 
			
		||||
        b->burst_length = 1;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = 1;
 | 
			
		||||
        b->burst_length = THROTTLE_VALUE_MAX;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = 1;
 | 
			
		||||
        b->burst_length = THROTTLE_VALUE_MAX + 1;
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        /* burst_length * max cannot exceed THROTTLE_VALUE_MAX */
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = 2;
 | 
			
		||||
        b->burst_length = THROTTLE_VALUE_MAX / 2;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = 3;
 | 
			
		||||
        b->burst_length = THROTTLE_VALUE_MAX / 2;
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = THROTTLE_VALUE_MAX;
 | 
			
		||||
        b->burst_length = 1;
 | 
			
		||||
        g_assert(throttle_is_valid(&cfg, NULL));
 | 
			
		||||
 | 
			
		||||
        b->avg = 1;
 | 
			
		||||
        b->max = THROTTLE_VALUE_MAX;
 | 
			
		||||
        b->burst_length = 2;
 | 
			
		||||
        g_assert(!throttle_is_valid(&cfg, NULL));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_max_is_missing_limit(void)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
| 
						 | 
				
			
			@ -668,6 +745,7 @@ int main(int argc, char **argv)
 | 
			
		|||
    g_test_add_func("/throttle/config/enabled",     test_enabled);
 | 
			
		||||
    g_test_add_func("/throttle/config/conflicting", test_conflicting_config);
 | 
			
		||||
    g_test_add_func("/throttle/config/is_valid",    test_is_valid);
 | 
			
		||||
    g_test_add_func("/throttle/config/ranges",      test_ranges);
 | 
			
		||||
    g_test_add_func("/throttle/config/max",         test_max_is_missing_limit);
 | 
			
		||||
    g_test_add_func("/throttle/config/iops_size",
 | 
			
		||||
                    test_iops_size_is_missing_limit);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -530,6 +530,7 @@ void *qemu_alloc_stack(size_t *sz)
 | 
			
		|||
    ptr = mmap(NULL, *sz, PROT_READ | PROT_WRITE,
 | 
			
		||||
               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 | 
			
		||||
    if (ptr == MAP_FAILED) {
 | 
			
		||||
        perror("failed to allocate memory for stack");
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -544,6 +545,7 @@ void *qemu_alloc_stack(size_t *sz)
 | 
			
		|||
    guardpage = ptr;
 | 
			
		||||
#endif
 | 
			
		||||
    if (mprotect(guardpage, pagesz, PROT_NONE) != 0) {
 | 
			
		||||
        perror("failed to set up stack guard page");
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,23 +95,36 @@ static int64_t throttle_do_compute_wait(double limit, double extra)
 | 
			
		|||
int64_t throttle_compute_wait(LeakyBucket *bkt)
 | 
			
		||||
{
 | 
			
		||||
    double extra; /* the number of extra units blocking the io */
 | 
			
		||||
    double bucket_size;   /* I/O before throttling to bkt->avg */
 | 
			
		||||
    double burst_bucket_size; /* Before throttling to bkt->max */
 | 
			
		||||
 | 
			
		||||
    if (!bkt->avg) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If the bucket is full then we have to wait */
 | 
			
		||||
    extra = bkt->level - bkt->max * bkt->burst_length;
 | 
			
		||||
    if (!bkt->max) {
 | 
			
		||||
        /* If bkt->max is 0 we still want to allow short bursts of I/O
 | 
			
		||||
         * from the guest, otherwise every other request will be throttled
 | 
			
		||||
         * and performance will suffer considerably. */
 | 
			
		||||
        bucket_size = (double) bkt->avg / 10;
 | 
			
		||||
        burst_bucket_size = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* If we have a burst limit then we have to wait until all I/O
 | 
			
		||||
         * at burst rate has finished before throttling to bkt->avg */
 | 
			
		||||
        bucket_size = bkt->max * bkt->burst_length;
 | 
			
		||||
        burst_bucket_size = (double) bkt->max / 10;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If the main bucket is full then we have to wait */
 | 
			
		||||
    extra = bkt->level - bucket_size;
 | 
			
		||||
    if (extra > 0) {
 | 
			
		||||
        return throttle_do_compute_wait(bkt->avg, extra);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If the bucket is not full yet we have to make sure that we
 | 
			
		||||
     * fulfill the goal of bkt->max units per second. */
 | 
			
		||||
    /* If the main bucket is not full yet we still have to check the
 | 
			
		||||
     * burst bucket in order to enforce the burst limit */
 | 
			
		||||
    if (bkt->burst_length > 1) {
 | 
			
		||||
        /* We use 1/10 of the max value to smooth the throttling.
 | 
			
		||||
         * See throttle_fix_bucket() for more details. */
 | 
			
		||||
        extra = bkt->burst_level - bkt->max / 10;
 | 
			
		||||
        extra = bkt->burst_level - burst_bucket_size;
 | 
			
		||||
        if (extra > 0) {
 | 
			
		||||
            return throttle_do_compute_wait(bkt->max, extra);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -324,32 +337,35 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < BUCKETS_COUNT; i++) {
 | 
			
		||||
        if (cfg->buckets[i].avg < 0 ||
 | 
			
		||||
            cfg->buckets[i].max < 0 ||
 | 
			
		||||
            cfg->buckets[i].avg > THROTTLE_VALUE_MAX ||
 | 
			
		||||
            cfg->buckets[i].max > THROTTLE_VALUE_MAX) {
 | 
			
		||||
        LeakyBucket *bkt = &cfg->buckets[i];
 | 
			
		||||
        if (bkt->avg > THROTTLE_VALUE_MAX || bkt->max > THROTTLE_VALUE_MAX) {
 | 
			
		||||
            error_setg(errp, "bps/iops/max values must be within [0, %lld]",
 | 
			
		||||
                       THROTTLE_VALUE_MAX);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!cfg->buckets[i].burst_length) {
 | 
			
		||||
        if (!bkt->burst_length) {
 | 
			
		||||
            error_setg(errp, "the burst length cannot be 0");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (cfg->buckets[i].burst_length > 1 && !cfg->buckets[i].max) {
 | 
			
		||||
        if (bkt->burst_length > 1 && !bkt->max) {
 | 
			
		||||
            error_setg(errp, "burst length set without burst rate");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (cfg->buckets[i].max && !cfg->buckets[i].avg) {
 | 
			
		||||
        if (bkt->max && bkt->burst_length > THROTTLE_VALUE_MAX / bkt->max) {
 | 
			
		||||
            error_setg(errp, "burst length too high for this burst rate");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (bkt->max && !bkt->avg) {
 | 
			
		||||
            error_setg(errp, "bps_max/iops_max require corresponding"
 | 
			
		||||
                       " bps/iops values");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (cfg->buckets[i].max && cfg->buckets[i].max < cfg->buckets[i].avg) {
 | 
			
		||||
        if (bkt->max && bkt->max < bkt->avg) {
 | 
			
		||||
            error_setg(errp, "bps_max/iops_max cannot be lower than bps/iops");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -358,36 +374,6 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* fix bucket parameters */
 | 
			
		||||
static void throttle_fix_bucket(LeakyBucket *bkt)
 | 
			
		||||
{
 | 
			
		||||
    double min;
 | 
			
		||||
 | 
			
		||||
    /* zero bucket level */
 | 
			
		||||
    bkt->level = bkt->burst_level = 0;
 | 
			
		||||
 | 
			
		||||
    /* The following is done to cope with the Linux CFQ block scheduler
 | 
			
		||||
     * which regroup reads and writes by block of 100ms in the guest.
 | 
			
		||||
     * When they are two process one making reads and one making writes cfq
 | 
			
		||||
     * make a pattern looking like the following:
 | 
			
		||||
     * WWWWWWWWWWWRRRRRRRRRRRRRRWWWWWWWWWWWWWwRRRRRRRRRRRRRRRRR
 | 
			
		||||
     * Having a max burst value of 100ms of the average will help smooth the
 | 
			
		||||
     * throttling
 | 
			
		||||
     */
 | 
			
		||||
    min = bkt->avg / 10;
 | 
			
		||||
    if (bkt->avg && !bkt->max) {
 | 
			
		||||
        bkt->max = min;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* undo internal bucket parameter changes (see throttle_fix_bucket()) */
 | 
			
		||||
static void throttle_unfix_bucket(LeakyBucket *bkt)
 | 
			
		||||
{
 | 
			
		||||
    if (bkt->max < bkt->avg) {
 | 
			
		||||
        bkt->max = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Used to configure the throttle
 | 
			
		||||
 *
 | 
			
		||||
 * @ts: the throttle state we are working on
 | 
			
		||||
| 
						 | 
				
			
			@ -402,8 +388,10 @@ void throttle_config(ThrottleState *ts,
 | 
			
		|||
 | 
			
		||||
    ts->cfg = *cfg;
 | 
			
		||||
 | 
			
		||||
    /* Zero bucket level */
 | 
			
		||||
    for (i = 0; i < BUCKETS_COUNT; i++) {
 | 
			
		||||
        throttle_fix_bucket(&ts->cfg.buckets[i]);
 | 
			
		||||
        ts->cfg.buckets[i].level = 0;
 | 
			
		||||
        ts->cfg.buckets[i].burst_level = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ts->previous_leak = qemu_clock_get_ns(clock_type);
 | 
			
		||||
| 
						 | 
				
			
			@ -416,13 +404,7 @@ void throttle_config(ThrottleState *ts,
 | 
			
		|||
 */
 | 
			
		||||
void throttle_get_config(ThrottleState *ts, ThrottleConfig *cfg)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    *cfg = ts->cfg;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < BUCKETS_COUNT; i++) {
 | 
			
		||||
        throttle_unfix_bucket(&cfg->buckets[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue