-static struct timeval tsub(struct timeval t1, struct timeval t2)
+static struct timespec tsub(struct timespec t1, struct timespec t2)
{
- t1.tv_usec -= t2.tv_usec;
- if (t1.tv_usec < 0) {
- t1.tv_usec += 1000000;
+ t1.tv_nsec -= t2.tv_nsec;
+ if (t1.tv_nsec < 0) {
+ t1.tv_nsec += NANOSECONDS_PER_SECOND;
t1.tv_sec--;
}
t1.tv_sec -= t2.tv_sec;
return t1;
}
-static double tdiv(double value, struct timeval tv)
+static double tdiv(double value, struct timespec tv)
{
- return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
+ double seconds = tv.tv_sec + (tv.tv_nsec / 1e9);
+ return value / seconds;
}
#define HOURS(sec) ((sec) / (60 * 60))
VERBOSE_FIXED_TIME = 0x2,
};
-static void timestr(struct timeval *tv, char *ts, size_t size, int format)
+static void timestr(struct timespec *tv, char *ts, size_t size, int format)
{
- double usec = (double)tv->tv_usec / 1000000.0;
+ double frac_sec = tv->tv_nsec / 1e9;
if (format & TERSE_FIXED_TIME) {
if (!HOURS(tv->tv_sec)) {
- snprintf(ts, size, "%u:%02u.%02u",
- (unsigned int) MINUTES(tv->tv_sec),
- (unsigned int) SECONDS(tv->tv_sec),
- (unsigned int) (usec * 100));
+ snprintf(ts, size, "%u:%05.2f",
+ (unsigned int) MINUTES(tv->tv_sec),
+ SECONDS(tv->tv_sec) + frac_sec);
return;
}
format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
}
if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
- snprintf(ts, size, "%u:%02u:%02u.%02u",
+ snprintf(ts, size, "%u:%02u:%05.2f",
(unsigned int) HOURS(tv->tv_sec),
(unsigned int) MINUTES(tv->tv_sec),
- (unsigned int) SECONDS(tv->tv_sec),
- (unsigned int) (usec * 100));
+ SECONDS(tv->tv_sec) + frac_sec);
} else {
- snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
+ snprintf(ts, size, "%05.2f sec", frac_sec);
}
}
}
}
-static void print_report(const char *op, struct timeval *t, int64_t offset,
+static void print_report(const char *op, struct timespec *t, int64_t offset,
int64_t count, int64_t total, int cnt, bool Cflag)
{
char s1[64], s2[64], ts[64];
{
int ret;
- if (bytes >> 9 > BDRV_REQUEST_MAX_SECTORS) {
+ if (bytes > BDRV_REQUEST_MAX_BYTES) {
return -ERANGE;
}
static int read_f(BlockBackend *blk, int argc, char **argv)
{
- struct timeval t1, t2;
+ struct timespec t1, t2;
bool Cflag = false, qflag = false, vflag = false;
bool Pflag = false, sflag = false, lflag = false, bflag = false;
int c, cnt, ret;
buf = qemu_io_alloc(blk, count, 0xab);
- gettimeofday(&t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t1);
if (bflag) {
ret = do_load_vmstate(blk, buf, offset, count, &total);
} else {
ret = do_pread(blk, buf, offset, count, &total);
}
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
printf("read failed: %s\n", strerror(-ret));
static int readv_f(BlockBackend *blk, int argc, char **argv)
{
- struct timeval t1, t2;
+ struct timespec t1, t2;
bool Cflag = false, qflag = false, vflag = false;
int c, cnt, ret;
char *buf;
return -EINVAL;
}
- gettimeofday(&t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t1);
ret = do_aio_readv(blk, &qiov, offset, &total);
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
printf("readv failed: %s\n", strerror(-ret));
" -b, -- write to the VM state rather than the virtual disk\n"
" -c, -- write compressed data with blk_write_compressed\n"
" -f, -- use Force Unit Access semantics\n"
+" -n, -- with -z, don't allow slow fallback\n"
" -p, -- ignored for backwards compatibility\n"
" -P, -- use different pattern to fill file\n"
" -C, -- report statistics in a machine parsable format\n"
.perm = BLK_PERM_WRITE,
.argmin = 2,
.argmax = -1,
- .args = "[-bcCfquz] [-P pattern] off len",
+ .args = "[-bcCfnquz] [-P pattern] off len",
.oneline = "writes a number of bytes at a specified offset",
.help = write_help,
};
static int write_f(BlockBackend *blk, int argc, char **argv)
{
- struct timeval t1, t2;
+ struct timespec t1, t2;
bool Cflag = false, qflag = false, bflag = false;
bool Pflag = false, zflag = false, cflag = false;
int flags = 0;
int64_t total = 0;
int pattern = 0xcd;
- while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
+ while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
switch (c) {
case 'b':
bflag = true;
case 'f':
flags |= BDRV_REQ_FUA;
break;
+ case 'n':
+ flags |= BDRV_REQ_NO_FALLBACK;
+ break;
case 'p':
/* Ignored for backwards compatibility */
break;
return -EINVAL;
}
+ if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
+ printf("-n requires -z to be specified\n");
+ return -EINVAL;
+ }
+
if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
printf("-u requires -z to be specified\n");
return -EINVAL;
buf = qemu_io_alloc(blk, count, pattern);
}
- gettimeofday(&t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t1);
if (bflag) {
ret = do_save_vmstate(blk, buf, offset, count, &total);
} else if (zflag) {
} else {
ret = do_pwrite(blk, buf, offset, count, flags, &total);
}
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
printf("write failed: %s\n", strerror(-ret));
static int writev_f(BlockBackend *blk, int argc, char **argv)
{
- struct timeval t1, t2;
+ struct timespec t1, t2;
bool Cflag = false, qflag = false;
int flags = 0;
int c, cnt, ret;
return -EINVAL;
}
- gettimeofday(&t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t1);
ret = do_aio_writev(blk, &qiov, offset, flags, &total);
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
printf("writev failed: %s\n", strerror(-ret));
bool zflag;
BlockAcctCookie acct;
int pattern;
- struct timeval t1;
+ struct timespec t1;
};
static void aio_write_done(void *opaque, int ret)
{
struct aio_ctx *ctx = opaque;
- struct timeval t2;
+ struct timespec t2;
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
static void aio_read_done(void *opaque, int ret)
{
struct aio_ctx *ctx = opaque;
- struct timeval t2;
+ struct timespec t2;
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
printf("readv failed: %s\n", strerror(-ret));
return -EINVAL;
}
- gettimeofday(&ctx->t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
BLOCK_ACCT_READ);
blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx);
return -EINVAL;
}
- gettimeofday(&ctx->t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
BLOCK_ACCT_WRITE);
BlockDriverState *bs = blk_bs(blk);
BlockDriverInfo bdi;
ImageInfoSpecific *spec_info;
+ Error *local_err = NULL;
char s1[64], s2[64];
int ret;
printf("cluster size: %s\n", s1);
printf("vm state offset: %s\n", s2);
- spec_info = bdrv_get_specific_info(bs);
+ spec_info = bdrv_get_specific_info(bs, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ return -EIO;
+ }
if (spec_info) {
printf("Format specific information:\n");
- bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
+ bdrv_image_info_specific_dump(spec_info);
qapi_free_ImageInfoSpecific(spec_info);
}
static int discard_f(BlockBackend *blk, int argc, char **argv)
{
- struct timeval t1, t2;
+ struct timespec t1, t2;
bool Cflag = false, qflag = false;
int c, ret;
int64_t offset, bytes;
if (bytes < 0) {
print_cvtnum_err(bytes, argv[optind]);
return bytes;
- } else if (bytes >> BDRV_SECTOR_BITS > BDRV_REQUEST_MAX_SECTORS) {
+ } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
printf("length cannot exceed %"PRIu64", given %s\n",
- (uint64_t)BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS,
- argv[optind]);
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return -EINVAL;
}
- gettimeofday(&t1, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t1);
ret = blk_pdiscard(blk, offset, bytes);
- gettimeofday(&t2, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
printf("discard failed: %s\n", strerror(-ret));
}
bdrv_subtree_drained_begin(bs);
- brq = bdrv_reopen_queue(NULL, bs, opts);
- bdrv_reopen_multiple(bdrv_get_aio_context(bs), brq, &local_err);
+ brq = bdrv_reopen_queue(NULL, bs, opts, true);
+ bdrv_reopen_multiple(brq, &local_err);
bdrv_subtree_drained_end(bs);
if (local_err) {