Block patches

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJUEwy3AAoJEH8JsnLIjy/WqkUQALPsR68w2bB6aiN6zUaJt1X3
 VaksCQGgtZdN6itDvn6v6ktayFXXfjRE+U0hK7joXUiokq17YZmKqf+1V4LPJRSW
 Tv21gIAHuIyf+8LL/xGS3W9+EEXAaKbp1t6AT/VDWv/mQ4KY5xrvhn2E/+7r0wKr
 EBOHrKd4tQualV12MtrZsrWZy3oMQvkimcVIfnjFZ2gJg5dmUBXQ35Kdj9+AxDiX
 1hDizBRbozvzSBCnS9PUcJ1OfCxoCRewbHn43LeCYWyB8m3ttpdPpuMaUoSNGrVY
 Tw7aYvYjMArr/ChrF8eH2vKJSeHabSPbYqgNsGqpS2n5KYJbzoyv8iQQCSHjtKZe
 vagoIRomF/BtOWT8mvUSHGw2vmQm6JZJdHJsXNeyDJ/P8ZSSm0vsZMjqh6vwS7sB
 +AURb5BaFWNnThwm80tJl23uJLjohNsdrmuLvAiHX0e03dyyQFDBS1zqb9BTbOsP
 SdBPFZy1hA0deYnJlyeLj94iyIosdsMihLkDJrIdNzn6qMF9QCdFs+rgOepwsfml
 ZNG1h2V+Wo3LS1SkKpK0mhiTBFLCit8Cq03+n95zBTcPCBMGgoJVC2VZef8XXKDn
 v6vuSYikCkEIDEWhsUrIZmDWKv/83AwSW+i+ir3IOVgxOJ51Z/mr5PAQQ+3/Gaat
 G5gSIDmW4rGgYDk/coDf
 =3He1
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block patches

# gpg: Signature made Fri 12 Sep 2014 16:09:43 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (22 commits)
  qcow2: Add falloc and full preallocation option
  raw-posix: Add falloc and full preallocation option
  qapi: introduce PreallocMode and new PreallocModes full and falloc.
  block: don't convert file size to sector size
  block: round up file size to nearest sector
  iotests: Send the correct fd in socket_scm_helper
  blockdev: Refuse to drive_del something added with blockdev-add
  block: extend BLOCK_IO_ERROR with reason string
  dataplane: fix virtio_blk_data_plane_create() op blocker error path
  qemu-iotests: Run 025 for Archipelago block driver
  block/archipelago: Implement bdrv_truncate()
  block: Make the block accounting functions operate on BlockAcctStats
  block: rename BlockAcctType members to start with BLOCK_ instead of BDRV_
  block: Extract the block accounting code
  block: Extract the BlockAcctStats structure
  IDE: MMIO IDE device control should be little endian
  thread-pool: Drop unnecessary includes
  xen: Drop redundant bdrv_close() from pci_piix3_xen_ide_unplug()
  xen_disk: Plug memory leak on error path
  qemu-io: Clean up openfile() after commit 2e40134
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-09-15 17:35:21 +01:00
commit f2bcdc8de0
53 changed files with 709 additions and 284 deletions

60
block.c
View File

@ -3363,9 +3363,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
bdrv_set_dirty(bs, sector_num, nb_sectors); bdrv_set_dirty(bs, sector_num, nb_sectors);
if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { block_acct_highest_sector(&bs->stats, sector_num, nb_sectors);
bs->wr_highest_sector = sector_num + nb_sectors - 1;
}
if (bs->growable && ret >= 0) { if (bs->growable && ret >= 0) {
bs->total_sectors = MAX(bs->total_sectors, sector_num + nb_sectors); bs->total_sectors = MAX(bs->total_sectors, sector_num + nb_sectors);
} }
@ -3639,6 +3638,19 @@ BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int e
} }
} }
static void send_qmp_error_event(BlockDriverState *bs,
BlockErrorAction action,
bool is_read, int error)
{
BlockErrorAction ac;
ac = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
qapi_event_send_block_io_error(bdrv_get_device_name(bs), ac, action,
bdrv_iostatus_is_enabled(bs),
error == ENOSPC, strerror(error),
&error_abort);
}
/* This is done by device models because, while the block layer knows /* This is done by device models because, while the block layer knows
* about the error, it does not know whether an operation comes from * about the error, it does not know whether an operation comes from
* the device or the block layer (from a job, for example). * the device or the block layer (from a job, for example).
@ -3664,16 +3676,10 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
* also ensures that the STOP/RESUME pair of events is emitted. * also ensures that the STOP/RESUME pair of events is emitted.
*/ */
qemu_system_vmstop_request_prepare(); qemu_system_vmstop_request_prepare();
qapi_event_send_block_io_error(bdrv_get_device_name(bs), send_qmp_error_event(bs, action, is_read, error);
is_read ? IO_OPERATION_TYPE_READ :
IO_OPERATION_TYPE_WRITE,
action, &error_abort);
qemu_system_vmstop_request(RUN_STATE_IO_ERROR); qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
} else { } else {
qapi_event_send_block_io_error(bdrv_get_device_name(bs), send_qmp_error_event(bs, action, is_read, error);
is_read ? IO_OPERATION_TYPE_READ :
IO_OPERATION_TYPE_WRITE,
action, &error_abort);
} }
} }
@ -5566,27 +5572,6 @@ void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
} }
} }
void
bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
enum BlockAcctType type)
{
assert(type < BDRV_MAX_IOTYPE);
cookie->bytes = bytes;
cookie->start_time_ns = get_clock();
cookie->type = type;
}
void
bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
{
assert(cookie->type < BDRV_MAX_IOTYPE);
bs->nr_bytes[cookie->type] += cookie->bytes;
bs->nr_ops[cookie->type]++;
bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
}
void bdrv_img_create(const char *filename, const char *fmt, void bdrv_img_create(const char *filename, const char *fmt,
const char *base_filename, const char *base_fmt, const char *base_filename, const char *base_fmt,
char *options, uint64_t img_size, int flags, char *options, uint64_t img_size, int flags,
@ -6103,3 +6088,14 @@ void bdrv_refresh_filename(BlockDriverState *bs)
QDECREF(json); QDECREF(json);
} }
} }
/* This accessor function purpose is to allow the device models to access the
* BlockAcctStats structure embedded inside a BlockDriverState without being
* aware of the BlockDriverState structure layout.
* It will go away when the BlockAcctStats structure will be moved inside
* the device models.
*/
BlockAcctStats *bdrv_get_stats(BlockDriverState *bs)
{
return &bs->stats;
}

View File

@ -18,6 +18,7 @@ block-obj-$(CONFIG_RBD) += rbd.o
block-obj-$(CONFIG_GLUSTERFS) += gluster.o block-obj-$(CONFIG_GLUSTERFS) += gluster.o
block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
block-obj-$(CONFIG_LIBSSH2) += ssh.o block-obj-$(CONFIG_LIBSSH2) += ssh.o
block-obj-y += accounting.o
common-obj-y += stream.o common-obj-y += stream.o
common-obj-y += commit.o common-obj-y += commit.o

54
block/accounting.c Normal file
View File

@ -0,0 +1,54 @@
/*
* QEMU System Emulator block accounting
*
* Copyright (c) 2011 Christoph Hellwig
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "block/accounting.h"
#include "block/block_int.h"
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type)
{
assert(type < BLOCK_MAX_IOTYPE);
cookie->bytes = bytes;
cookie->start_time_ns = get_clock();
cookie->type = type;
}
void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
{
assert(cookie->type < BLOCK_MAX_IOTYPE);
stats->nr_bytes[cookie->type] += cookie->bytes;
stats->nr_ops[cookie->type]++;
stats->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
}
void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
unsigned int nb_sectors)
{
if (stats->wr_highest_sector < sector_num + nb_sectors - 1) {
stats->wr_highest_sector = sector_num + nb_sectors - 1;
}
}

View File

@ -63,8 +63,6 @@
#include <xseg/xseg.h> #include <xseg/xseg.h>
#include <xseg/protocol.h> #include <xseg/protocol.h>
#define ARCHIP_FD_READ 0
#define ARCHIP_FD_WRITE 1
#define MAX_REQUEST_SIZE 524288 #define MAX_REQUEST_SIZE 524288
#define ARCHIPELAGO_OPT_VOLUME "volume" #define ARCHIPELAGO_OPT_VOLUME "volume"
@ -84,6 +82,7 @@ typedef enum {
ARCHIP_OP_WRITE, ARCHIP_OP_WRITE,
ARCHIP_OP_FLUSH, ARCHIP_OP_FLUSH,
ARCHIP_OP_VOLINFO, ARCHIP_OP_VOLINFO,
ARCHIP_OP_TRUNCATE,
} ARCHIPCmd; } ARCHIPCmd;
typedef struct ArchipelagoAIOCB { typedef struct ArchipelagoAIOCB {
@ -248,6 +247,7 @@ static void xseg_request_handler(void *state)
} }
break; break;
case ARCHIP_OP_VOLINFO: case ARCHIP_OP_VOLINFO:
case ARCHIP_OP_TRUNCATE:
s->is_signaled = true; s->is_signaled = true;
qemu_cond_signal(&s->archip_cond); qemu_cond_signal(&s->archip_cond);
break; break;
@ -708,7 +708,8 @@ static int qemu_archipelago_create(const char *filename,
parse_filename_opts(filename, errp, &volname, &segment_name, &mport, parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
&vport); &vport);
total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0); total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
if (segment_name == NULL) { if (segment_name == NULL) {
segment_name = g_strdup("archipelago"); segment_name = g_strdup("archipelago");
@ -995,6 +996,64 @@ static int64_t qemu_archipelago_getlength(BlockDriverState *bs)
return ret; return ret;
} }
static int qemu_archipelago_truncate(BlockDriverState *bs, int64_t offset)
{
int ret, targetlen;
struct xseg_request *req;
BDRVArchipelagoState *s = bs->opaque;
AIORequestData *reqdata = g_new(AIORequestData, 1);
const char *volname = s->volname;
targetlen = strlen(volname);
req = xseg_get_request(s->xseg, s->srcport, s->mportno, X_ALLOC);
if (!req) {
archipelagolog("Cannot get XSEG request\n");
return err_exit2;
}
ret = xseg_prep_request(s->xseg, req, targetlen, 0);
if (ret < 0) {
archipelagolog("Cannot prepare XSEG request\n");
goto err_exit;
}
char *target = xseg_get_target(s->xseg, req);
if (!target) {
archipelagolog("Cannot get XSEG target\n");
goto err_exit;
}
memcpy(target, volname, targetlen);
req->offset = offset;
req->op = X_TRUNCATE;
reqdata->op = ARCHIP_OP_TRUNCATE;
reqdata->volname = volname;
xseg_set_req_data(s->xseg, req, reqdata);
xport p = xseg_submit(s->xseg, req, s->srcport, X_ALLOC);
if (p == NoPort) {
archipelagolog("Cannot submit XSEG request\n");
goto err_exit;
}
xseg_signal(s->xseg, p);
qemu_mutex_lock(&s->archip_mutex);
while (!s->is_signaled) {
qemu_cond_wait(&s->archip_cond, &s->archip_mutex);
}
s->is_signaled = false;
qemu_mutex_unlock(&s->archip_mutex);
xseg_put_request(s->xseg, req, s->srcport);
g_free(reqdata);
return 0;
err_exit:
xseg_put_request(s->xseg, req, s->srcport);
err_exit2:
g_free(reqdata);
return -EIO;
}
static QemuOptsList qemu_archipelago_create_opts = { static QemuOptsList qemu_archipelago_create_opts = {
.name = "archipelago-create-opts", .name = "archipelago-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qemu_archipelago_create_opts.head), .head = QTAILQ_HEAD_INITIALIZER(qemu_archipelago_create_opts.head),
@ -1024,6 +1083,7 @@ static BlockDriver bdrv_archipelago = {
.bdrv_close = qemu_archipelago_close, .bdrv_close = qemu_archipelago_close,
.bdrv_create = qemu_archipelago_create, .bdrv_create = qemu_archipelago_create,
.bdrv_getlength = qemu_archipelago_getlength, .bdrv_getlength = qemu_archipelago_getlength,
.bdrv_truncate = qemu_archipelago_truncate,
.bdrv_aio_readv = qemu_archipelago_aio_readv, .bdrv_aio_readv = qemu_archipelago_aio_readv,
.bdrv_aio_writev = qemu_archipelago_aio_writev, .bdrv_aio_writev = qemu_archipelago_aio_writev,
.bdrv_aio_flush = qemu_archipelago_aio_flush, .bdrv_aio_flush = qemu_archipelago_aio_flush,

View File

@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts *opts, Error **errp)
BlockDriverState *cow_bs = NULL; BlockDriverState *cow_bs = NULL;
/* Read out options */ /* Read out options */
image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
ret = bdrv_create_file(filename, opts, &local_err); ret = bdrv_create_file(filename, opts, &local_err);

View File

@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
goto out; goto out;
} }
total_size = total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; BDRV_SECTOR_SIZE);
tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
if (!tmp || !strcmp(tmp, "off")) { if (!tmp || !strcmp(tmp, "off")) {
@ -516,9 +516,8 @@ static int qemu_gluster_create(const char *filename,
if (!fd) { if (!fd) {
ret = -errno; ret = -errno;
} else { } else {
if (!glfs_ftruncate(fd, total_size * BDRV_SECTOR_SIZE)) { if (!glfs_ftruncate(fd, total_size)) {
if (prealloc && qemu_gluster_zerofill(fd, 0, if (prealloc && qemu_gluster_zerofill(fd, 0, total_size)) {
total_size * BDRV_SECTOR_SIZE)) {
ret = -errno; ret = -errno;
} }
} else { } else {

View File

@ -1531,8 +1531,8 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
bs = bdrv_new("", &error_abort); bs = bdrv_new("", &error_abort);
/* Read out options */ /* Read out options */
total_size = total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; BDRV_SECTOR_SIZE);
bs->opaque = g_new0(struct IscsiLun, 1); bs->opaque = g_new0(struct IscsiLun, 1);
iscsilun = bs->opaque; iscsilun = bs->opaque;

View File

@ -418,7 +418,8 @@ static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
client->aio_context = qemu_get_aio_context(); client->aio_context = qemu_get_aio_context();
/* Read out options */ /* Read out options */
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
ret = nfs_client_open(client, url, O_CREAT, errp); ret = nfs_client_open(client, url, O_CREAT, errp);
if (ret < 0) { if (ret < 0) {

View File

@ -333,15 +333,16 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
} }
s->stats = g_malloc0(sizeof(*s->stats)); s->stats = g_malloc0(sizeof(*s->stats));
s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ]; s->stats->rd_bytes = bs->stats.nr_bytes[BLOCK_ACCT_READ];
s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE]; s->stats->wr_bytes = bs->stats.nr_bytes[BLOCK_ACCT_WRITE];
s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ]; s->stats->rd_operations = bs->stats.nr_ops[BLOCK_ACCT_READ];
s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE]; s->stats->wr_operations = bs->stats.nr_ops[BLOCK_ACCT_WRITE];
s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE; s->stats->wr_highest_offset =
s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH]; bs->stats.wr_highest_sector * BDRV_SECTOR_SIZE;
s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE]; s->stats->flush_operations = bs->stats.nr_ops[BLOCK_ACCT_FLUSH];
s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ]; s->stats->wr_total_time_ns = bs->stats.total_time_ns[BLOCK_ACCT_WRITE];
s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH]; s->stats->rd_total_time_ns = bs->stats.total_time_ns[BLOCK_ACCT_READ];
s->stats->flush_total_time_ns = bs->stats.total_time_ns[BLOCK_ACCT_FLUSH];
if (bs->file) { if (bs->file) {
s->has_parent = true; s->has_parent = true;

View File

@ -725,7 +725,8 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
BlockDriverState *qcow_bs; BlockDriverState *qcow_bs;
/* Read out options */ /* Read out options */
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
flags |= BLOCK_FLAG_ENCRYPT; flags |= BLOCK_FLAG_ENCRYPT;
@ -753,7 +754,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
header.magic = cpu_to_be32(QCOW_MAGIC); header.magic = cpu_to_be32(QCOW_MAGIC);
header.version = cpu_to_be32(QCOW_VERSION); header.version = cpu_to_be32(QCOW_VERSION);
header.size = cpu_to_be64(total_size * 512); header.size = cpu_to_be64(total_size);
header_size = sizeof(header); header_size = sizeof(header);
backing_filename_len = 0; backing_filename_len = 0;
if (backing_file) { if (backing_file) {
@ -775,7 +776,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
} }
header_size = (header_size + 7) & ~7; header_size = (header_size + 7) & ~7;
shift = header.cluster_bits + header.l2_bits; shift = header.cluster_bits + header.l2_bits;
l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift; l1_size = (total_size + (1LL << shift) - 1) >> shift;
header.l1_table_offset = cpu_to_be64(header_size); header.l1_table_offset = cpu_to_be64(header_size);
if (flags & BLOCK_FLAG_ENCRYPT) { if (flags & BLOCK_FLAG_ENCRYPT) {

View File

@ -30,6 +30,7 @@
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qapi/qmp/qerror.h" #include "qapi/qmp/qerror.h"
#include "qapi/qmp/qbool.h" #include "qapi/qmp/qbool.h"
#include "qapi/util.h"
#include "trace.h" #include "trace.h"
#include "qemu/option_int.h" #include "qemu/option_int.h"
@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs)
static int qcow2_create2(const char *filename, int64_t total_size, static int qcow2_create2(const char *filename, int64_t total_size,
const char *backing_file, const char *backing_format, const char *backing_file, const char *backing_format,
int flags, size_t cluster_size, int prealloc, int flags, size_t cluster_size, PreallocMode prealloc,
QemuOpts *opts, int version, QemuOpts *opts, int version,
Error **errp) Error **errp)
{ {
@ -1771,6 +1772,56 @@ static int qcow2_create2(const char *filename, int64_t total_size,
Error *local_err = NULL; Error *local_err = NULL;
int ret; int ret;
if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
int64_t meta_size = 0;
uint64_t nreftablee, nrefblocke, nl1e, nl2e;
int64_t aligned_total_size = align_offset(total_size, cluster_size);
/* header: 1 cluster */
meta_size += cluster_size;
/* total size of L2 tables */
nl2e = aligned_total_size / cluster_size;
nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
meta_size += nl2e * sizeof(uint64_t);
/* total size of L1 tables */
nl1e = nl2e * sizeof(uint64_t) / cluster_size;
nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t));
meta_size += nl1e * sizeof(uint64_t);
/* total size of refcount blocks
*
* note: every host cluster is reference-counted, including metadata
* (even refcount blocks are recursively included).
* Let:
* a = total_size (this is the guest disk size)
* m = meta size not including refcount blocks and refcount tables
* c = cluster size
* y1 = number of refcount blocks entries
* y2 = meta size including everything
* then,
* y1 = (y2 + a)/c
* y2 = y1 * sizeof(u16) + y1 * sizeof(u16) * sizeof(u64) / c + m
* we can get y1:
* y1 = (a + m) / (c - sizeof(u16) - sizeof(u16) * sizeof(u64) / c)
*/
nrefblocke = (aligned_total_size + meta_size + cluster_size) /
(cluster_size - sizeof(uint16_t) -
1.0 * sizeof(uint16_t) * sizeof(uint64_t) / cluster_size);
nrefblocke = align_offset(nrefblocke, cluster_size / sizeof(uint16_t));
meta_size += nrefblocke * sizeof(uint16_t);
/* total size of refcount tables */
nreftablee = nrefblocke * sizeof(uint16_t) / cluster_size;
nreftablee = align_offset(nreftablee, cluster_size / sizeof(uint64_t));
meta_size += nreftablee * sizeof(uint64_t);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
aligned_total_size + meta_size);
qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc]);
}
ret = bdrv_create_file(filename, opts, &local_err); ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
@ -1859,7 +1910,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
} }
/* Okay, now that we have a valid image, let's give it the right size */ /* Okay, now that we have a valid image, let's give it the right size */
ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE); ret = bdrv_truncate(bs, total_size);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not resize image"); error_setg_errno(errp, -ret, "Could not resize image");
goto out; goto out;
@ -1876,7 +1927,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
} }
/* And if we're supposed to preallocate metadata, do that now */ /* And if we're supposed to preallocate metadata, do that now */
if (prealloc) { if (prealloc != PREALLOC_MODE_OFF) {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);
ret = preallocate(bs); ret = preallocate(bs);
@ -1912,16 +1963,17 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
char *backing_file = NULL; char *backing_file = NULL;
char *backing_fmt = NULL; char *backing_fmt = NULL;
char *buf = NULL; char *buf = NULL;
uint64_t sectors = 0; uint64_t size = 0;
int flags = 0; int flags = 0;
size_t cluster_size = DEFAULT_CLUSTER_SIZE; size_t cluster_size = DEFAULT_CLUSTER_SIZE;
int prealloc = 0; PreallocMode prealloc;
int version = 3; int version = 3;
Error *local_err = NULL; Error *local_err = NULL;
int ret; int ret;
/* Read out options */ /* Read out options */
sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
@ -1930,12 +1982,11 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
DEFAULT_CLUSTER_SIZE); DEFAULT_CLUSTER_SIZE);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
if (!buf || !strcmp(buf, "off")) { prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
prealloc = 0; PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
} else if (!strcmp(buf, "metadata")) { &local_err);
prealloc = 1; if (local_err) {
} else { error_propagate(errp, local_err);
error_setg(errp, "Invalid preallocation mode: '%s'", buf);
ret = -EINVAL; ret = -EINVAL;
goto finish; goto finish;
} }
@ -1957,7 +2008,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
flags |= BLOCK_FLAG_LAZY_REFCOUNTS; flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
} }
if (backing_file && prealloc) { if (backing_file && prealloc != PREALLOC_MODE_OFF) {
error_setg(errp, "Backing file and preallocation cannot be used at " error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time"); "the same time");
ret = -EINVAL; ret = -EINVAL;
@ -1971,7 +2022,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
goto finish; goto finish;
} }
ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags, ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
cluster_size, prealloc, opts, version, &local_err); cluster_size, prealloc, opts, version, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
@ -2517,7 +2568,8 @@ static QemuOptsList qcow2_create_opts = {
{ {
.name = BLOCK_OPT_PREALLOC, .name = BLOCK_OPT_PREALLOC,
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
.help = "Preallocation mode (allowed values: off, metadata)" .help = "Preallocation mode (allowed values: off, metadata, "
"falloc, full)"
}, },
{ {
.name = BLOCK_OPT_LAZY_REFCOUNTS, .name = BLOCK_OPT_LAZY_REFCOUNTS,

View File

@ -648,7 +648,8 @@ static int bdrv_qed_create(const char *filename, QemuOpts *opts, Error **errp)
char *backing_fmt = NULL; char *backing_fmt = NULL;
int ret; int ret;
image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); image_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
cluster_size = qemu_opt_get_size_del(opts, cluster_size = qemu_opt_get_size_del(opts,

View File

@ -30,6 +30,7 @@
#include "block/thread-pool.h" #include "block/thread-pool.h"
#include "qemu/iov.h" #include "qemu/iov.h"
#include "raw-aio.h" #include "raw-aio.h"
#include "qapi/util.h"
#if defined(__APPLE__) && (__MACH__) #if defined(__APPLE__) && (__MACH__)
#include <paths.h> #include <paths.h>
@ -1365,44 +1366,92 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
int result = 0; int result = 0;
int64_t total_size = 0; int64_t total_size = 0;
bool nocow = false; bool nocow = false;
PreallocMode prealloc;
char *buf = NULL;
Error *local_err = NULL;
strstart(filename, "file:", &filename); strstart(filename, "file:", &filename);
/* Read out options */ /* Read out options */
total_size = total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; BDRV_SECTOR_SIZE);
nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
&local_err);
g_free(buf);
if (local_err) {
error_propagate(errp, local_err);
result = -EINVAL;
goto out;
}
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644); 0644);
if (fd < 0) { if (fd < 0) {
result = -errno; result = -errno;
error_setg_errno(errp, -result, "Could not create file"); error_setg_errno(errp, -result, "Could not create file");
} else { goto out;
if (nocow) {
#ifdef __linux__
/* Set NOCOW flag to solve performance issue on fs like btrfs.
* This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
* will be ignored since any failure of this operation should not
* block the left work.
*/
int attr;
if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
attr |= FS_NOCOW_FL;
ioctl(fd, FS_IOC_SETFLAGS, &attr);
}
#endif
}
if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
result = -errno;
error_setg_errno(errp, -result, "Could not resize file");
}
if (qemu_close(fd) != 0) {
result = -errno;
error_setg_errno(errp, -result, "Could not close the new file");
}
} }
if (nocow) {
#ifdef __linux__
/* Set NOCOW flag to solve performance issue on fs like btrfs.
* This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
* will be ignored since any failure of this operation should not
* block the left work.
*/
int attr;
if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
attr |= FS_NOCOW_FL;
ioctl(fd, FS_IOC_SETFLAGS, &attr);
}
#endif
}
if (ftruncate(fd, total_size) != 0) {
result = -errno;
error_setg_errno(errp, -result, "Could not resize file");
goto out_close;
}
if (prealloc == PREALLOC_MODE_FALLOC) {
/* posix_fallocate() doesn't set errno. */
result = -posix_fallocate(fd, 0, total_size);
if (result != 0) {
error_setg_errno(errp, -result,
"Could not preallocate data for the new file");
}
} else if (prealloc == PREALLOC_MODE_FULL) {
buf = g_malloc0(65536);
int64_t num = 0, left = total_size;
while (left > 0) {
num = MIN(left, 65536);
result = write(fd, buf, num);
if (result < 0) {
result = -errno;
error_setg_errno(errp, -result,
"Could not write to the new file");
break;
}
left -= num;
}
fsync(fd);
g_free(buf);
} else if (prealloc != PREALLOC_MODE_OFF) {
result = -EINVAL;
error_setg(errp, "Unsupported preallocation mode: %s",
PreallocMode_lookup[prealloc]);
}
out_close:
if (qemu_close(fd) != 0 && result == 0) {
result = -errno;
error_setg_errno(errp, -result, "Could not close the new file");
}
out:
return result; return result;
} }
@ -1585,6 +1634,11 @@ static QemuOptsList raw_create_opts = {
.type = QEMU_OPT_BOOL, .type = QEMU_OPT_BOOL,
.help = "Turn off copy-on-write (valid only on btrfs)" .help = "Turn off copy-on-write (valid only on btrfs)"
}, },
{
.name = BLOCK_OPT_PREALLOC,
.type = QEMU_OPT_STRING,
.help = "Preallocation mode (allowed values: off, falloc, full)"
},
{ /* end of list */ } { /* end of list */ }
} }
}; };
@ -1966,8 +2020,8 @@ static int hdev_create(const char *filename, QemuOpts *opts,
(void)has_prefix; (void)has_prefix;
/* Read out options */ /* Read out options */
total_size = total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; BDRV_SECTOR_SIZE);
fd = qemu_open(filename, O_WRONLY | O_BINARY); fd = qemu_open(filename, O_WRONLY | O_BINARY);
if (fd < 0) { if (fd < 0) {
@ -1983,7 +2037,7 @@ static int hdev_create(const char *filename, QemuOpts *opts,
error_setg(errp, error_setg(errp,
"The given file is neither a block nor a character device"); "The given file is neither a block nor a character device");
ret = -ENODEV; ret = -ENODEV;
} else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE) { } else if (lseek(fd, 0, SEEK_END) < total_size) {
error_setg(errp, "Device is too small"); error_setg(errp, "Device is too small");
ret = -ENOSPC; ret = -ENOSPC;
} }

View File

@ -511,8 +511,8 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
strstart(filename, "file:", &filename); strstart(filename, "file:", &filename);
/* Read out options */ /* Read out options */
total_size = total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; BDRV_SECTOR_SIZE);
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644); 0644);
@ -521,7 +521,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
return -EIO; return -EIO;
} }
set_sparse(fd); set_sparse(fd);
ftruncate(fd, total_size * 512); ftruncate(fd, total_size);
qemu_close(fd); qemu_close(fd);
return 0; return 0;
} }

View File

@ -314,7 +314,8 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
} }
/* Read out options */ /* Read out options */
bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); bytes = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0); objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
if (objsize) { if (objsize) {
if ((objsize - 1) & objsize) { /* not a power of 2? */ if ((objsize - 1) & objsize) { /* not a power of 2? */

View File

@ -1702,7 +1702,8 @@ static int sd_create(const char *filename, QemuOpts *opts,
goto out; goto out;
} }
s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); s->inode.vdi_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
if (!buf || !strcmp(buf, "off")) { if (!buf || !strcmp(buf, "off")) {

View File

@ -700,7 +700,8 @@ static int ssh_create(const char *filename, QemuOpts *opts, Error **errp)
ssh_state_init(&s); ssh_state_init(&s);
/* Get desired file size. */ /* Get desired file size. */
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
DPRINTF("total_size=%" PRIi64, total_size); DPRINTF("total_size=%" PRIi64, total_size);
uri_options = qdict_new(); uri_options = qdict_new();

View File

@ -700,7 +700,8 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
logout("\n"); logout("\n");
/* Read out options. */ /* Read out options. */
bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); bytes = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
#if defined(CONFIG_VDI_BLOCK_SIZE) #if defined(CONFIG_VDI_BLOCK_SIZE)
/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */ /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
block_size = qemu_opt_get_size_del(opts, block_size = qemu_opt_get_size_del(opts,

View File

@ -1766,7 +1766,8 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
VHDXImageType image_type; VHDXImageType image_type;
Error *local_err = NULL; Error *local_err = NULL;
image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); image_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0); log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0);
block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0); block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0);
type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT); type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);

View File

@ -1807,7 +1807,8 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
goto exit; goto exit;
} }
/* Read out options */ /* Read out options */
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE); adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) { if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {

View File

@ -489,7 +489,7 @@ static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
BDRVVPCState *s = (BDRVVPCState *)bs->opaque; BDRVVPCState *s = (BDRVVPCState *)bs->opaque;
VHDFooter *footer = (VHDFooter *) s->footer_buf; VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) != VHD_FIXED) { if (be32_to_cpu(footer->type) != VHD_FIXED) {
bdi->cluster_size = s->block_size; bdi->cluster_size = s->block_size;
} }
@ -506,7 +506,7 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
int64_t sectors, sectors_per_block; int64_t sectors, sectors_per_block;
VHDFooter *footer = (VHDFooter *) s->footer_buf; VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) == VHD_FIXED) { if (be32_to_cpu(footer->type) == VHD_FIXED) {
return bdrv_read(bs->file, sector_num, buf, nb_sectors); return bdrv_read(bs->file, sector_num, buf, nb_sectors);
} }
while (nb_sectors > 0) { while (nb_sectors > 0) {
@ -555,7 +555,7 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
int ret; int ret;
VHDFooter *footer = (VHDFooter *) s->footer_buf; VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) == VHD_FIXED) { if (be32_to_cpu(footer->type) == VHD_FIXED) {
return bdrv_write(bs->file, sector_num, buf, nb_sectors); return bdrv_write(bs->file, sector_num, buf, nb_sectors);
} }
while (nb_sectors > 0) { while (nb_sectors > 0) {
@ -757,7 +757,8 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
/* Read out options */ /* Read out options */
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
BDRV_SECTOR_SIZE);
disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT); disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
if (disk_type_param) { if (disk_type_param) {
if (!strcmp(disk_type_param, "dynamic")) { if (!strcmp(disk_type_param, "dynamic")) {
@ -857,7 +858,7 @@ static int vpc_has_zero_init(BlockDriverState *bs)
BDRVVPCState *s = bs->opaque; BDRVVPCState *s = bs->opaque;
VHDFooter *footer = (VHDFooter *) s->footer_buf; VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) == VHD_FIXED) { if (be32_to_cpu(footer->type) == VHD_FIXED) {
return bdrv_has_zero_init(bs->file); return bdrv_has_zero_init(bs->file);
} else { } else {
return 1; return 1;

View File

@ -1739,6 +1739,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{ {
const char *id = qdict_get_str(qdict, "id"); const char *id = qdict_get_str(qdict, "id");
BlockDriverState *bs; BlockDriverState *bs;
DriveInfo *dinfo;
AioContext *aio_context; AioContext *aio_context;
Error *local_err = NULL; Error *local_err = NULL;
@ -1748,6 +1749,13 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
return -1; return -1;
} }
dinfo = drive_get_by_blockdev(bs);
if (dinfo && !dinfo->enable_auto_del) {
error_report("Deleting device added with blockdev-add"
" is not supported");
return -1;
}
aio_context = bdrv_get_aio_context(bs); aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context); aio_context_acquire(aio_context);
@ -1775,7 +1783,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT, bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
BLOCKDEV_ON_ERROR_REPORT); BLOCKDEV_ON_ERROR_REPORT);
} else { } else {
drive_del(drive_get_by_blockdev(bs)); drive_del(dinfo);
} }
aio_context_release(aio_context); aio_context_release(aio_context);

View File

@ -277,5 +277,5 @@ uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg)
void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
QEMUSGList *sg, enum BlockAcctType type) QEMUSGList *sg, enum BlockAcctType type)
{ {
bdrv_acct_start(bs, cookie, sg->size, type); block_acct_start(bdrv_get_stats(bs), cookie, sg->size, type);
} }

View File

@ -164,8 +164,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
* block jobs that can conflict. * block jobs that can conflict.
*/ */
if (bdrv_op_is_blocked(blk->conf.bs, BLOCK_OP_TYPE_DATAPLANE, &local_err)) { if (bdrv_op_is_blocked(blk->conf.bs, BLOCK_OP_TYPE_DATAPLANE, &local_err)) {
error_report("cannot start dataplane thread: %s", error_setg(errp, "cannot start dataplane thread: %s",
error_get_pretty(local_err)); error_get_pretty(local_err));
error_free(local_err); error_free(local_err);
return; return;
} }

View File

@ -197,7 +197,7 @@ static void nvme_rw_cb(void *opaque, int ret)
NvmeCtrl *n = sq->ctrl; NvmeCtrl *n = sq->ctrl;
NvmeCQueue *cq = n->cq[sq->cqid]; NvmeCQueue *cq = n->cq[sq->cqid];
bdrv_acct_done(n->conf.bs, &req->acct); block_acct_done(bdrv_get_stats(n->conf.bs), &req->acct);
if (!ret) { if (!ret) {
req->status = NVME_SUCCESS; req->status = NVME_SUCCESS;
} else { } else {
@ -232,7 +232,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
assert((nlb << data_shift) == req->qsg.size); assert((nlb << data_shift) == req->qsg.size);
dma_acct_start(n->conf.bs, &req->acct, &req->qsg, is_write ? dma_acct_start(n->conf.bs, &req->acct, &req->qsg, is_write ?
BDRV_ACCT_WRITE : BDRV_ACCT_READ); BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
req->aiocb = is_write ? req->aiocb = is_write ?
dma_bdrv_write(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req) : dma_bdrv_write(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req) :
dma_bdrv_read(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req); dma_bdrv_read(n->conf.bs, &req->qsg, aio_slba, nvme_rw_cb, req);

View File

@ -74,7 +74,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
s->rq = req; s->rq = req;
} else if (action == BLOCK_ERROR_ACTION_REPORT) { } else if (action == BLOCK_ERROR_ACTION_REPORT) {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
bdrv_acct_done(s->bs, &req->acct); block_acct_done(bdrv_get_stats(s->bs), &req->acct);
virtio_blk_free_request(req); virtio_blk_free_request(req);
} }
@ -96,7 +96,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
} }
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
bdrv_acct_done(req->dev->bs, &req->acct); block_acct_done(bdrv_get_stats(req->dev->bs), &req->acct);
virtio_blk_free_request(req); virtio_blk_free_request(req);
} }
@ -111,7 +111,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
} }
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
bdrv_acct_done(req->dev->bs, &req->acct); block_acct_done(bdrv_get_stats(req->dev->bs), &req->acct);
virtio_blk_free_request(req); virtio_blk_free_request(req);
} }
@ -279,7 +279,8 @@ void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
{ {
bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH); block_acct_start(bdrv_get_stats(req->dev->bs), &req->acct, 0,
BLOCK_ACCT_FLUSH);
/* /*
* Make sure all outstanding writes are posted to the backing device. * Make sure all outstanding writes are posted to the backing device.
@ -322,7 +323,8 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
return; return;
} }
bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE); block_acct_start(bdrv_get_stats(req->dev->bs), &req->acct, req->qiov.size,
BLOCK_ACCT_WRITE);
if (mrb->num_writes == 32) { if (mrb->num_writes == 32) {
virtio_submit_multiwrite(req->dev->bs, mrb); virtio_submit_multiwrite(req->dev->bs, mrb);
@ -353,7 +355,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
return; return;
} }
bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(req->dev->bs), &req->acct, req->qiov.size,
BLOCK_ACCT_READ);
bdrv_aio_readv(req->dev->bs, sector, &req->qiov, bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
req->qiov.size / BDRV_SECTOR_SIZE, req->qiov.size / BDRV_SECTOR_SIZE,
virtio_blk_rw_complete, req); virtio_blk_rw_complete, req);

View File

@ -493,7 +493,7 @@ static void qemu_aio_complete(void *opaque, int ret)
break; break;
} }
case BLKIF_OP_READ: case BLKIF_OP_READ:
bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct); block_acct_done(bdrv_get_stats(ioreq->blkdev->bs), &ioreq->acct);
break; break;
case BLKIF_OP_DISCARD: case BLKIF_OP_DISCARD:
default: default:
@ -518,7 +518,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
switch (ioreq->req.operation) { switch (ioreq->req.operation) {
case BLKIF_OP_READ: case BLKIF_OP_READ:
bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(blkdev->bs), &ioreq->acct,
ioreq->v.size, BLOCK_ACCT_READ);
ioreq->aio_inflight++; ioreq->aio_inflight++;
bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE, bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
&ioreq->v, ioreq->v.size / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE,
@ -530,7 +531,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
break; break;
} }
bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE); block_acct_start(bdrv_get_stats(blkdev->bs), &ioreq->acct,
ioreq->v.size, BLOCK_ACCT_WRITE);
ioreq->aio_inflight++; ioreq->aio_inflight++;
bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE, bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
&ioreq->v, ioreq->v.size / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE,
@ -852,28 +854,25 @@ static int blk_connect(struct XenDevice *xendev)
blkdev->dinfo = drive_get(IF_XEN, 0, index); blkdev->dinfo = drive_get(IF_XEN, 0, index);
if (!blkdev->dinfo) { if (!blkdev->dinfo) {
Error *local_err = NULL; Error *local_err = NULL;
BlockDriver *drv;
/* setup via xenbus -> create new block driver instance */ /* setup via xenbus -> create new block driver instance */
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
blkdev->bs = bdrv_new(blkdev->dev, &local_err); blkdev->bs = bdrv_new(blkdev->dev, NULL);
if (local_err) {
blkdev->bs = NULL;
}
if (blkdev->bs) {
BlockDriver *drv = bdrv_find_whitelisted_format(blkdev->fileproto,
readonly);
if (bdrv_open(&blkdev->bs, blkdev->filename, NULL, NULL, qflags,
drv, &local_err) != 0)
{
xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
error_get_pretty(local_err));
error_free(local_err);
bdrv_unref(blkdev->bs);
blkdev->bs = NULL;
}
}
if (!blkdev->bs) { if (!blkdev->bs) {
return -1; return -1;
} }
drv = bdrv_find_whitelisted_format(blkdev->fileproto, readonly);
if (bdrv_open(&blkdev->bs, blkdev->filename, NULL, NULL, qflags,
drv, &local_err) != 0) {
xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
error_get_pretty(local_err));
error_free(local_err);
bdrv_unref(blkdev->bs);
blkdev->bs = NULL;
return -1;
}
} else { } else {
/* setup via qemu cmdline -> already setup for us */ /* setup via qemu cmdline -> already setup for us */
xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");

View File

@ -809,7 +809,8 @@ static void ncq_cb(void *opaque, int ret)
DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n", DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
ncq_tfs->tag); ncq_tfs->tag);
bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct); block_acct_done(bdrv_get_stats(ncq_tfs->drive->port.ifs[0].bs),
&ncq_tfs->acct);
qemu_sglist_destroy(&ncq_tfs->sglist); qemu_sglist_destroy(&ncq_tfs->sglist);
ncq_tfs->used = 0; ncq_tfs->used = 0;
} }
@ -860,7 +861,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
ncq_tfs->tag, ncq_tfs->lba); ncq_tfs->tag, ncq_tfs->lba);
dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct, dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
&ncq_tfs->sglist, BDRV_ACCT_READ); &ncq_tfs->sglist, BLOCK_ACCT_READ);
ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs, ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
&ncq_tfs->sglist, ncq_tfs->lba, &ncq_tfs->sglist, ncq_tfs->lba,
ncq_cb, ncq_tfs); ncq_cb, ncq_tfs);
@ -873,7 +874,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
ncq_tfs->tag, ncq_tfs->lba); ncq_tfs->tag, ncq_tfs->lba);
dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct, dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
&ncq_tfs->sglist, BDRV_ACCT_WRITE); &ncq_tfs->sglist, BLOCK_ACCT_WRITE);
ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs, ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
&ncq_tfs->sglist, ncq_tfs->lba, &ncq_tfs->sglist, ncq_tfs->lba,
ncq_cb, ncq_tfs); ncq_cb, ncq_tfs);

View File

@ -110,14 +110,16 @@ static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)
switch(sector_size) { switch(sector_size) {
case 2048: case 2048:
bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct,
4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4); ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4);
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
break; break;
case 2352: case 2352:
bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct,
4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4); ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4);
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
if (ret < 0) if (ret < 0)
return ret; return ret;
cd_data_to_raw(buf, lba); cd_data_to_raw(buf, lba);
@ -253,7 +255,8 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
s->io_buffer_index = 0; s->io_buffer_index = 0;
if (s->atapi_dma) { if (s->atapi_dma) {
bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct, size,
BLOCK_ACCT_READ);
s->status = READY_STAT | SEEK_STAT | DRQ_STAT; s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
ide_start_dma(s, ide_atapi_cmd_read_dma_cb); ide_start_dma(s, ide_atapi_cmd_read_dma_cb);
} else { } else {
@ -354,7 +357,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
return; return;
eot: eot:
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
ide_set_inactive(s, false); ide_set_inactive(s, false);
} }
@ -369,7 +372,8 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
s->io_buffer_size = 0; s->io_buffer_size = 0;
s->cd_sector_size = sector_size; s->cd_sector_size = sector_size;
bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct, s->packet_transfer_size,
BLOCK_ACCT_READ);
/* XXX: check if BUSY_STAT should be set */ /* XXX: check if BUSY_STAT should be set */
s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;

View File

@ -568,7 +568,7 @@ static void ide_sector_read_cb(void *opaque, int ret)
s->pio_aiocb = NULL; s->pio_aiocb = NULL;
s->status &= ~BUSY_STAT; s->status &= ~BUSY_STAT;
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
if (ret != 0) { if (ret != 0) {
if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO | if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
IDE_RETRY_READ)) { IDE_RETRY_READ)) {
@ -624,7 +624,8 @@ void ide_sector_read(IDEState *s)
s->iov.iov_len = n * BDRV_SECTOR_SIZE; s->iov.iov_len = n * BDRV_SECTOR_SIZE;
qemu_iovec_init_external(&s->qiov, &s->iov, 1); qemu_iovec_init_external(&s->qiov, &s->iov, 1);
bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct,
n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
s->pio_aiocb = bdrv_aio_readv(s->bs, sector_num, &s->qiov, n, s->pio_aiocb = bdrv_aio_readv(s->bs, sector_num, &s->qiov, n,
ide_sector_read_cb, s); ide_sector_read_cb, s);
} }
@ -756,7 +757,7 @@ void ide_dma_cb(void *opaque, int ret)
eot: eot:
if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
} }
ide_set_inactive(s, stay_active); ide_set_inactive(s, stay_active);
} }
@ -770,12 +771,12 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
switch (dma_cmd) { switch (dma_cmd) {
case IDE_DMA_READ: case IDE_DMA_READ:
bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE, block_acct_start(bdrv_get_stats(s->bs), &s->acct,
BDRV_ACCT_READ); s->nsector * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
break; break;
case IDE_DMA_WRITE: case IDE_DMA_WRITE:
bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE, block_acct_start(bdrv_get_stats(s->bs), &s->acct,
BDRV_ACCT_WRITE); s->nsector * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
break; break;
default: default:
break; break;
@ -802,7 +803,7 @@ static void ide_sector_write_cb(void *opaque, int ret)
IDEState *s = opaque; IDEState *s = opaque;
int n; int n;
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
s->pio_aiocb = NULL; s->pio_aiocb = NULL;
s->status &= ~BUSY_STAT; s->status &= ~BUSY_STAT;
@ -869,7 +870,8 @@ void ide_sector_write(IDEState *s)
s->iov.iov_len = n * BDRV_SECTOR_SIZE; s->iov.iov_len = n * BDRV_SECTOR_SIZE;
qemu_iovec_init_external(&s->qiov, &s->iov, 1); qemu_iovec_init_external(&s->qiov, &s->iov, 1);
bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct,
n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
s->pio_aiocb = bdrv_aio_writev(s->bs, sector_num, &s->qiov, n, s->pio_aiocb = bdrv_aio_writev(s->bs, sector_num, &s->qiov, n,
ide_sector_write_cb, s); ide_sector_write_cb, s);
} }
@ -888,7 +890,7 @@ static void ide_flush_cb(void *opaque, int ret)
} }
if (s->bs) { if (s->bs) {
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
} }
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_cmd_done(s); ide_cmd_done(s);
@ -903,7 +905,7 @@ void ide_flush_cache(IDEState *s)
} }
s->status |= BUSY_STAT; s->status |= BUSY_STAT;
bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH); block_acct_start(bdrv_get_stats(s->bs), &s->acct, 0, BLOCK_ACCT_FLUSH);
s->pio_aiocb = bdrv_aio_flush(s->bs, ide_flush_cb, s); s->pio_aiocb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
} }

View File

@ -171,7 +171,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
done: done:
MACIO_DPRINTF("done DMA\n"); MACIO_DPRINTF("done DMA\n");
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
io->dma_end(opaque); io->dma_end(opaque);
} }
@ -352,7 +352,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
done: done:
if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
} }
io->dma_end(io); io->dma_end(io);
} }
@ -370,8 +370,8 @@ static void pmac_ide_transfer(DBDMA_io *io)
/* Handle non-block ATAPI DMA transfers */ /* Handle non-block ATAPI DMA transfers */
if (s->lba == -1) { if (s->lba == -1) {
s->io_buffer_size = MIN(io->len, s->packet_transfer_size); s->io_buffer_size = MIN(io->len, s->packet_transfer_size);
bdrv_acct_start(s->bs, &s->acct, s->io_buffer_size, block_acct_start(bdrv_get_stats(s->bs), &s->acct, s->io_buffer_size,
BDRV_ACCT_READ); BLOCK_ACCT_READ);
MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n", MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n",
s->io_buffer_size); s->io_buffer_size);
@ -382,22 +382,25 @@ static void pmac_ide_transfer(DBDMA_io *io)
m->dma_active = false; m->dma_active = false;
MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n"); MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n");
bdrv_acct_done(s->bs, &s->acct); block_acct_done(bdrv_get_stats(s->bs), &s->acct);
io->dma_end(io); io->dma_end(io);
return; return;
} }
bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct, io->len,
BLOCK_ACCT_READ);
pmac_ide_atapi_transfer_cb(io, 0); pmac_ide_atapi_transfer_cb(io, 0);
return; return;
} }
switch (s->dma_cmd) { switch (s->dma_cmd) {
case IDE_DMA_READ: case IDE_DMA_READ:
bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->bs), &s->acct, io->len,
BLOCK_ACCT_READ);
break; break;
case IDE_DMA_WRITE: case IDE_DMA_WRITE:
bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); block_acct_start(bdrv_get_stats(s->bs), &s->acct, io->len,
BLOCK_ACCT_WRITE);
break; break;
default: default:
break; break;

View File

@ -82,7 +82,7 @@ static void mmio_ide_write(void *opaque, hwaddr addr,
static const MemoryRegionOps mmio_ide_ops = { static const MemoryRegionOps mmio_ide_ops = {
.read = mmio_ide_read, .read = mmio_ide_read,
.write = mmio_ide_write, .write = mmio_ide_write,
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_LITTLE_ENDIAN,
}; };
static uint64_t mmio_ide_status_read(void *opaque, hwaddr addr, static uint64_t mmio_ide_status_read(void *opaque, hwaddr addr,
@ -102,7 +102,7 @@ static void mmio_ide_cmd_write(void *opaque, hwaddr addr,
static const MemoryRegionOps mmio_ide_cs_ops = { static const MemoryRegionOps mmio_ide_cs_ops = {
.read = mmio_ide_status_read, .read = mmio_ide_status_read,
.write = mmio_ide_cmd_write, .write = mmio_ide_cmd_write,
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_LITTLE_ENDIAN,
}; };
static const VMStateDescription vmstate_ide_mmio = { static const VMStateDescription vmstate_ide_mmio = {

View File

@ -182,7 +182,6 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
if (ds) { if (ds) {
bdrv_detach_dev(di->bdrv, ds); bdrv_detach_dev(di->bdrv, ds);
} }
bdrv_close(di->bdrv);
pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
drive_del(di); drive_del(di);
} }

View File

@ -183,7 +183,7 @@ static void scsi_aio_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL); assert(r->req.aiocb != NULL);
r->req.aiocb = NULL; r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct); block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
if (r->req.io_canceled) { if (r->req.io_canceled) {
goto done; goto done;
} }
@ -237,7 +237,8 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
} }
if (scsi_is_cmd_fua(&r->req.cmd)) { if (scsi_is_cmd_fua(&r->req.cmd)) {
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct, 0,
BLOCK_ACCT_FLUSH);
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r); r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
return; return;
} }
@ -257,7 +258,7 @@ static void scsi_dma_complete_noio(void *opaque, int ret)
if (r->req.aiocb != NULL) { if (r->req.aiocb != NULL) {
r->req.aiocb = NULL; r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct); block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
} }
if (r->req.io_canceled) { if (r->req.io_canceled) {
goto done; goto done;
@ -300,7 +301,7 @@ static void scsi_read_complete(void * opaque, int ret)
assert(r->req.aiocb != NULL); assert(r->req.aiocb != NULL);
r->req.aiocb = NULL; r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct); block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
if (r->req.io_canceled) { if (r->req.io_canceled) {
goto done; goto done;
} }
@ -333,7 +334,7 @@ static void scsi_do_read(void *opaque, int ret)
if (r->req.aiocb != NULL) { if (r->req.aiocb != NULL) {
r->req.aiocb = NULL; r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct); block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
} }
if (r->req.io_canceled) { if (r->req.io_canceled) {
goto done; goto done;
@ -349,13 +350,14 @@ static void scsi_do_read(void *opaque, int ret)
scsi_req_ref(&r->req); scsi_req_ref(&r->req);
if (r->req.sg) { if (r->req.sg) {
dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_READ); dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BLOCK_ACCT_READ);
r->req.resid -= r->req.sg->size; r->req.resid -= r->req.sg->size;
r->req.aiocb = dma_bdrv_read(s->qdev.conf.bs, r->req.sg, r->sector, r->req.aiocb = dma_bdrv_read(s->qdev.conf.bs, r->req.sg, r->sector,
scsi_dma_complete, r); scsi_dma_complete, r);
} else { } else {
n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,
n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n, r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
scsi_read_complete, r); scsi_read_complete, r);
} }
@ -399,7 +401,8 @@ static void scsi_read_data(SCSIRequest *req)
first = !r->started; first = !r->started;
r->started = true; r->started = true;
if (first && scsi_is_cmd_fua(&r->req.cmd)) { if (first && scsi_is_cmd_fua(&r->req.cmd)) {
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct, 0,
BLOCK_ACCT_FLUSH);
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_do_read, r); r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_do_read, r);
} else { } else {
scsi_do_read(r, 0); scsi_do_read(r, 0);
@ -453,7 +456,7 @@ static void scsi_write_complete(void * opaque, int ret)
if (r->req.aiocb != NULL) { if (r->req.aiocb != NULL) {
r->req.aiocb = NULL; r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct); block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
} }
if (r->req.io_canceled) { if (r->req.io_canceled) {
goto done; goto done;
@ -522,13 +525,14 @@ static void scsi_write_data(SCSIRequest *req)
} }
if (r->req.sg) { if (r->req.sg) {
dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_WRITE); dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BLOCK_ACCT_WRITE);
r->req.resid -= r->req.sg->size; r->req.resid -= r->req.sg->size;
r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector, r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector,
scsi_dma_complete, r); scsi_dma_complete, r);
} else { } else {
n = r->qiov.size / 512; n = r->qiov.size / 512;
bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,
n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n, r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
scsi_write_complete, r); scsi_write_complete, r);
} }
@ -1496,7 +1500,8 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
if (!bdrv_enable_write_cache(s->qdev.conf.bs)) { if (!bdrv_enable_write_cache(s->qdev.conf.bs)) {
/* The request is used as the AIO opaque value, so add a ref. */ /* The request is used as the AIO opaque value, so add a ref. */
scsi_req_ref(&r->req); scsi_req_ref(&r->req);
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct, 0,
BLOCK_ACCT_FLUSH);
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r); r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
return; return;
} }
@ -1647,7 +1652,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL); assert(r->req.aiocb != NULL);
r->req.aiocb = NULL; r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct); block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
if (r->req.io_canceled) { if (r->req.io_canceled) {
goto done; goto done;
} }
@ -1662,7 +1667,8 @@ static void scsi_write_same_complete(void *opaque, int ret)
data->sector += data->iov.iov_len / 512; data->sector += data->iov.iov_len / 512;
data->iov.iov_len = MIN(data->nb_sectors * 512, data->iov.iov_len); data->iov.iov_len = MIN(data->nb_sectors * 512, data->iov.iov_len);
if (data->iov.iov_len) { if (data->iov.iov_len) {
bdrv_acct_start(s->qdev.conf.bs, &r->acct, data->iov.iov_len, BDRV_ACCT_WRITE); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,
data->iov.iov_len, BLOCK_ACCT_WRITE);
r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector, r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,
&data->qiov, data->iov.iov_len / 512, &data->qiov, data->iov.iov_len / 512,
scsi_write_same_complete, data); scsi_write_same_complete, data);
@ -1708,8 +1714,9 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
/* The request is used as the AIO opaque value, so add a ref. */ /* The request is used as the AIO opaque value, so add a ref. */
scsi_req_ref(&r->req); scsi_req_ref(&r->req);
bdrv_acct_start(s->qdev.conf.bs, &r->acct, nb_sectors * s->qdev.blocksize, block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,
BDRV_ACCT_WRITE); nb_sectors * s->qdev.blocksize,
BLOCK_ACCT_WRITE);
r->req.aiocb = bdrv_aio_write_zeroes(s->qdev.conf.bs, r->req.aiocb = bdrv_aio_write_zeroes(s->qdev.conf.bs,
r->req.cmd.lba * (s->qdev.blocksize / 512), r->req.cmd.lba * (s->qdev.blocksize / 512),
nb_sectors * (s->qdev.blocksize / 512), nb_sectors * (s->qdev.blocksize / 512),
@ -1730,7 +1737,8 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
} }
scsi_req_ref(&r->req); scsi_req_ref(&r->req);
bdrv_acct_start(s->qdev.conf.bs, &r->acct, data->iov.iov_len, BDRV_ACCT_WRITE); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct,
data->iov.iov_len, BLOCK_ACCT_WRITE);
r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector, r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, data->sector,
&data->qiov, data->iov.iov_len / 512, &data->qiov, data->iov.iov_len / 512,
scsi_write_same_complete, data); scsi_write_same_complete, data);
@ -1994,7 +2002,8 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE:
/* The request is used as the AIO opaque value, so add a ref. */ /* The request is used as the AIO opaque value, so add a ref. */
scsi_req_ref(&r->req); scsi_req_ref(&r->req);
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH); block_acct_start(bdrv_get_stats(s->qdev.conf.bs), &r->acct, 0,
BLOCK_ACCT_FLUSH);
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r); r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
return 0; return 0;
case SEEK_10: case SEEK_10:

View File

@ -0,0 +1,57 @@
/*
* QEMU System Emulator block accounting
*
* Copyright (c) 2011 Christoph Hellwig
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef BLOCK_ACCOUNTING_H
#define BLOCK_ACCOUNTING_H
#include <stdint.h>
#include "qemu/typedefs.h"
enum BlockAcctType {
BLOCK_ACCT_READ,
BLOCK_ACCT_WRITE,
BLOCK_ACCT_FLUSH,
BLOCK_MAX_IOTYPE,
};
typedef struct BlockAcctStats {
uint64_t nr_bytes[BLOCK_MAX_IOTYPE];
uint64_t nr_ops[BLOCK_MAX_IOTYPE];
uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
uint64_t wr_highest_sector;
} BlockAcctStats;
typedef struct BlockAcctCookie {
int64_t bytes;
int64_t start_time_ns;
enum BlockAcctType type;
} BlockAcctCookie;
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type);
void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
unsigned int nb_sectors);
#endif

View File

@ -5,6 +5,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "block/coroutine.h" #include "block/coroutine.h"
#include "block/accounting.h"
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi-types.h" #include "qapi-types.h"
@ -485,23 +486,6 @@ void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason); void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
bool bdrv_op_blocker_is_empty(BlockDriverState *bs); bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
enum BlockAcctType {
BDRV_ACCT_READ,
BDRV_ACCT_WRITE,
BDRV_ACCT_FLUSH,
BDRV_MAX_IOTYPE,
};
typedef struct BlockAcctCookie {
int64_t bytes;
int64_t start_time_ns;
enum BlockAcctType type;
} BlockAcctCookie;
void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type);
void bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie);
typedef enum { typedef enum {
BLKDBG_L1_UPDATE, BLKDBG_L1_UPDATE,
@ -591,4 +575,6 @@ void bdrv_io_plug(BlockDriverState *bs);
void bdrv_io_unplug(BlockDriverState *bs); void bdrv_io_unplug(BlockDriverState *bs);
void bdrv_flush_io_queue(BlockDriverState *bs); void bdrv_flush_io_queue(BlockDriverState *bs);
BlockAcctStats *bdrv_get_stats(BlockDriverState *bs);
#endif #endif

View File

@ -24,6 +24,7 @@
#ifndef BLOCK_INT_H #ifndef BLOCK_INT_H
#define BLOCK_INT_H #define BLOCK_INT_H
#include "block/accounting.h"
#include "block/block.h" #include "block/block.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/queue.h" #include "qemu/queue.h"
@ -359,10 +360,7 @@ struct BlockDriverState {
bool io_limits_enabled; bool io_limits_enabled;
/* I/O stats (display with "info blockstats"). */ /* I/O stats (display with "info blockstats"). */
uint64_t nr_bytes[BDRV_MAX_IOTYPE]; BlockAcctStats stats;
uint64_t nr_ops[BDRV_MAX_IOTYPE];
uint64_t total_time_ns[BDRV_MAX_IOTYPE];
uint64_t wr_highest_sector;
/* I/O Limits */ /* I/O Limits */
BlockLimits bl; BlockLimits bl;

View File

@ -18,11 +18,7 @@
#ifndef QEMU_THREAD_POOL_H #ifndef QEMU_THREAD_POOL_H
#define QEMU_THREAD_POOL_H 1 #define QEMU_THREAD_POOL_H 1
#include "qemu-common.h" #include "block/block.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
#include "block/coroutine.h"
#include "block/block_int.h"
typedef int ThreadPoolFunc(void *opaque); typedef int ThreadPoolFunc(void *opaque);

View File

@ -18,6 +18,7 @@
#include "hw/block/block.h" #include "hw/block/block.h"
#include "sysemu/iothread.h" #include "sysemu/iothread.h"
#include "block/block.h" #include "block/block.h"
#include "block/accounting.h"
#define TYPE_VIRTIO_BLK "virtio-blk-device" #define TYPE_VIRTIO_BLK "virtio-blk-device"
#define VIRTIO_BLK(obj) \ #define VIRTIO_BLK(obj) \

View File

@ -15,6 +15,7 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "hw/hw.h" #include "hw/hw.h"
#include "block/block.h" #include "block/block.h"
#include "block/accounting.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
typedef struct ScatterGatherEntry ScatterGatherEntry; typedef struct ScatterGatherEntry ScatterGatherEntry;

View File

@ -336,6 +336,7 @@
# #
# @io-status: #optional @BlockDeviceIoStatus. Only present if the device # @io-status: #optional @BlockDeviceIoStatus. Only present if the device
# supports it and the VM is configured to stop on errors # supports it and the VM is configured to stop on errors
# (supported device models: virtio-blk, ide, scsi-disk)
# #
# @inserted: #optional @BlockDeviceInfo describing the device if media is # @inserted: #optional @BlockDeviceInfo describing the device if media is
# present # present
@ -1587,6 +1588,15 @@
# #
# @action: action that has been taken # @action: action that has been taken
# #
# @nospace: #optional true if I/O error was caused due to a no-space
# condition. This key is only present if query-block's
# io-status is present, please see query-block documentation
# for more information (since: 2.2)
#
# @reason: human readable string describing the error cause.
# (This field is a debugging aid for humans, it should not
# be parsed by applications) (since: 2.2)
#
# Note: If action is "stop", a STOP event will eventually follow the # Note: If action is "stop", a STOP event will eventually follow the
# BLOCK_IO_ERROR event # BLOCK_IO_ERROR event
# #
@ -1594,7 +1604,8 @@
## ##
{ 'event': 'BLOCK_IO_ERROR', { 'event': 'BLOCK_IO_ERROR',
'data': { 'device': 'str', 'operation': 'IoOperationType', 'data': { 'device': 'str', 'operation': 'IoOperationType',
'action': 'BlockErrorAction' } } 'action': 'BlockErrorAction', '*nospace': 'bool',
'reason': 'str' } }
## ##
# @BLOCK_JOB_COMPLETED # @BLOCK_JOB_COMPLETED
@ -1697,3 +1708,20 @@
'len' : 'int', 'len' : 'int',
'offset': 'int', 'offset': 'int',
'speed' : 'int' } } 'speed' : 'int' } }
# @PreallocMode
#
# Preallocation mode of QEMU image file
#
# @off: no preallocation
# @metadata: preallocate only for metadata
# @falloc: like @full preallocation but allocate disk space by
# posix_fallocate() rather than writing zeros.
# @full: preallocate all data by writing zeros to device to ensure disk
# space is really available. @full preallocation also sets up
# metadata correctly.
#
# Since 2.2
##
{ 'enum': 'PreallocMode',
'data': [ 'off', 'metadata', 'falloc', 'full' ] }

View File

@ -527,6 +527,15 @@ Linux or NTFS on Windows), then only the written sectors will reserve
space. Use @code{qemu-img info} to know the real size used by the space. Use @code{qemu-img info} to know the real size used by the
image or @code{ls -ls} on Unix/Linux. image or @code{ls -ls} on Unix/Linux.
Supported options:
@table @code
@item preallocation
Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
@code{falloc} mode preallocates space for image by calling posix_fallocate().
@code{full} mode preallocates space for image by writing zeros to underlying
storage.
@end table
@item qcow2 @item qcow2
QEMU image format, the most versatile format. Use it to have smaller QEMU image format, the most versatile format. Use it to have smaller
images (useful if your filesystem does not supports holes, for example images (useful if your filesystem does not supports holes, for example
@ -575,9 +584,11 @@ sizes can improve the image file size whereas larger cluster sizes generally
provide better performance. provide better performance.
@item preallocation @item preallocation
Preallocation mode (allowed values: off, metadata). An image with preallocated Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
metadata is initially larger but can improve performance when the image needs @code{full}). An image with preallocated metadata is initially larger but can
to grow. improve performance when the image needs to grow. @code{falloc} and @code{full}
preallocations are like the same options of @code{raw} format, but sets up
metadata also.
@item lazy_refcounts @item lazy_refcounts
If this option is set to @code{on}, reference count updates are postponed with If this option is set to @code{on}, reference count updates are postponed with

View File

@ -419,6 +419,15 @@ Linux or NTFS on Windows), then only the written sectors will reserve
space. Use @code{qemu-img info} to know the real size used by the space. Use @code{qemu-img info} to know the real size used by the
image or @code{ls -ls} on Unix/Linux. image or @code{ls -ls} on Unix/Linux.
Supported options:
@table @code
@item preallocation
Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
@code{falloc} mode preallocates space for image by calling posix_fallocate().
@code{full} mode preallocates space for image by writing zeros to underlying
storage.
@end table
@item qcow2 @item qcow2
QEMU image format, the most versatile format. Use it to have smaller QEMU image format, the most versatile format. Use it to have smaller
images (useful if your filesystem does not supports holes, for example images (useful if your filesystem does not supports holes, for example
@ -467,9 +476,11 @@ sizes can improve the image file size whereas larger cluster sizes generally
provide better performance. provide better performance.
@item preallocation @item preallocation
Preallocation mode (allowed values: off, metadata). An image with preallocated Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
metadata is initially larger but can improve performance when the image needs @code{full}). An image with preallocated metadata is initially larger but can
to grow. improve performance when the image needs to grow. @code{falloc} and @code{full}
preallocations are like the same options of @code{raw} format, but sets up
metadata also.
@item lazy_refcounts @item lazy_refcounts
If this option is set to @code{on}, reference count updates are postponed with If this option is set to @code{on}, reference count updates are postponed with

View File

@ -58,30 +58,20 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
return 1; return 1;
} }
if (growable) { qemuio_bs = bdrv_new("hda", &error_abort);
if (bdrv_open(&qemuio_bs, name, NULL, opts, flags | BDRV_O_PROTOCOL,
NULL, &local_err))
{
fprintf(stderr, "%s: can't open%s%s: %s\n", progname,
name ? " device " : "", name ?: "",
error_get_pretty(local_err));
error_free(local_err);
return 1;
}
} else {
qemuio_bs = bdrv_new("hda", &error_abort);
if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, NULL, &local_err) if (growable) {
< 0) flags |= BDRV_O_PROTOCOL;
{ }
fprintf(stderr, "%s: can't open%s%s: %s\n", progname,
name ? " device " : "", name ?: "", if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, NULL, &local_err) < 0) {
error_get_pretty(local_err)); fprintf(stderr, "%s: can't open%s%s: %s\n", progname,
error_free(local_err); name ? " device " : "", name ?: "",
bdrv_unref(qemuio_bs); error_get_pretty(local_err));
qemuio_bs = NULL; error_free(local_err);
return 1; bdrv_unref(qemuio_bs);
} qemuio_bs = NULL;
return 1;
} }
return 0; return 0;

View File

@ -40,7 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
. ./common.pattern . ./common.pattern
_supported_fmt raw qcow2 qed _supported_fmt raw qcow2 qed
_supported_proto file sheepdog rbd nfs _supported_proto file sheepdog rbd nfs archipelago
_supported_os Linux _supported_os Linux
echo "=== Creating image" echo "=== Creating image"

View File

@ -179,7 +179,7 @@ qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off
qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
qemu-img: TEST_DIR/t.qcow2: Invalid preallocation mode: '1234' qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' lazy_refcounts=off Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation='1234' lazy_refcounts=off
== Check encryption option == == Check encryption option ==

View File

@ -64,7 +64,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -76,7 +76,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -88,7 +88,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -100,7 +100,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -112,7 +112,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -124,7 +124,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -136,7 +136,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -148,7 +148,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -175,7 +175,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
Testing: create -o help Testing: create -o help
@ -253,7 +253,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -265,7 +265,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -277,7 +277,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -289,7 +289,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -301,7 +301,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -313,7 +313,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -325,7 +325,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -337,7 +337,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -364,7 +364,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
Testing: convert -o help Testing: convert -o help
@ -431,7 +431,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -443,7 +443,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -455,7 +455,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -467,7 +467,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -479,7 +479,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -491,7 +491,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -503,7 +503,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -515,7 +515,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
nocow Turn off copy-on-write (valid only on btrfs) nocow Turn off copy-on-write (valid only on btrfs)
@ -544,7 +544,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image backing_fmt Image format of the base image
encryption Encrypt the image encryption Encrypt the image
cluster_size qcow2 cluster size cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata) preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates lazy_refcounts Postpone refcount updates
Testing: convert -o help Testing: convert -o help

57
tests/qemu-iotests/104 Executable file
View File

@ -0,0 +1,57 @@
#!/bin/bash
#
# Test image creation with aligned and unaligned sizes
#
# Copyright (C) 2014 Fujitsu.
#
# 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 of the License, or
# (at your option) any later version.
#
# 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 <http://www.gnu.org/licenses/>.
#
# creator
owner=hutao@cn.fujitsu.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
tmp=/tmp/$$
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt generic
_supported_proto generic
_supported_os Linux
echo "=== Check qemu-img info output ==="
echo
image_sizes="1024 1234"
for s in $image_sizes; do
_make_test_img $s | _filter_img_create
_img_info | _filter_img_info
done
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,12 @@
QA output created by 104
=== Check qemu-img info output ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 1.0K (1024 bytes)
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1234
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 1.5K (1536 bytes)
***done

View File

@ -192,5 +192,26 @@ _filter_img_create()
-e "s/archipelago:a/TEST_DIR\//g" -e "s/archipelago:a/TEST_DIR\//g"
} }
_filter_img_info()
{
sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
-e "s#$TEST_DIR#TEST_DIR#g" \
-e "s#$IMGFMT#IMGFMT#g" \
-e "/encrypted: yes/d" \
-e "/cluster_size: [0-9]\\+/d" \
-e "/table_size: [0-9]\\+/d" \
-e "/compat: '[^']*'/d" \
-e "/compat6: \\(on\\|off\\)/d" \
-e "/static: \\(on\\|off\\)/d" \
-e "/zeroed_grain: \\(on\\|off\\)/d" \
-e "/subformat: '[^']*'/d" \
-e "/adapter_type: '[^']*'/d" \
-e "/lazy_refcounts: \\(on\\|off\\)/d" \
-e "/block_size: [0-9]\\+/d" \
-e "/block_state_zero: \\(on\\|off\\)/d" \
-e "/log_size: [0-9]\\+/d" \
-e "s/archipelago:a/TEST_DIR\//g"
}
# make sure this script returns success # make sure this script returns success
/bin/true /bin/true

View File

@ -104,3 +104,4 @@
100 rw auto quick 100 rw auto quick
101 rw auto quick 101 rw auto quick
103 rw auto quick 103 rw auto quick
104 rw auto

View File

@ -52,7 +52,7 @@ static int send_fd(int fd, int fd_to_send)
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); memcpy(CMSG_DATA(cmsg), &fd_to_send, sizeof(int));
do { do {
ret = sendmsg(fd, &msg, 0); ret = sendmsg(fd, &msg, 0);

View File

@ -20,7 +20,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "block/coroutine.h" #include "block/coroutine.h"
#include "trace.h" #include "trace.h"
#include "block/block_int.h"
#include "block/thread-pool.h" #include "block/thread-pool.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"