From fb3ad956dce7a426329f4b3ff9354fd4e8949d75 Mon Sep 17 00:00:00 2001 From: Uri Lublin <uril@redhat.com> Date: Mon, 30 Mar 2009 23:15:52 +0300 Subject: [PATCH 11/12] block: set high watermark and get a notification when reached Added a monitor command block_set_watermark. Keeping watermark in bs structure. The user gets one notification per request. For additional notification the user must set a new watermark. In this patch only qcow2 format actually check the watermark and send notifications. Signed-off-by: Uri Lublin <uril@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Bugzilla: 489964 RH-Upstream-status: pending Acked-by: Eduardo Habkost <ehabkost@redhat.com> Acked-by: john cooper <john.cooper@redhat.com> --- qemu/block-qcow2.c | 9 +++++++++ qemu/block.c | 7 +++++++ qemu/block.h | 2 ++ qemu/block_int.h | 3 +++ qemu/monitor.c | 21 +++++++++++++++++++++ 5 files changed, 42 insertions(+), 0 deletions(-) diff --git a/qemu/block-qcow2.c b/qemu/block-qcow2.c index 8ef4f1b..41750ed 100644 --- a/qemu/block-qcow2.c +++ b/qemu/block-qcow2.c @@ -2378,6 +2378,15 @@ retry: if (s->highest_alloc < s->free_cluster_index) { s->highest_alloc = s->free_cluster_index; + if (bs->high_watermark) { + uint64_t ha = (s->highest_alloc << s->cluster_bits); + if (ha >= bs->high_watermark) { + term_printf("high watermark reached for %s alloc=%" PRIu64 + " mark=%" PRIu64 "\n", + bs->device_name, ha, bs->high_watermark); + bs->high_watermark = 0; + } + } } return (s->free_cluster_index - nb_clusters) << s->cluster_bits; diff --git a/qemu/block.c b/qemu/block.c index 106270c..c847088 100644 --- a/qemu/block.c +++ b/qemu/block.c @@ -1116,6 +1116,13 @@ void bdrv_flush_all(void) bdrv_flush(bs); } + +void bdrv_set_high_watermark(BlockDriverState *bs, uint64_t offset) +{ + bs->high_watermark = offset; +} + + /* * Returns true iff the specified sector is present in the disk image. Drivers * not implementing the functionality are assumed to not support backing files, diff --git a/qemu/block.h b/qemu/block.h index d74f388..c3798bd 100644 --- a/qemu/block.h +++ b/qemu/block.h @@ -104,6 +104,8 @@ int qemu_key_check(BlockDriverState *bs, const char *name); void bdrv_flush(BlockDriverState *bs); void bdrv_flush_all(void); +void bdrv_set_high_watermark(BlockDriverState *bs, uint64_t offset); + int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); diff --git a/qemu/block_int.h b/qemu/block_int.h index a4629ef..9541b2e 100644 --- a/qemu/block_int.h +++ b/qemu/block_int.h @@ -123,6 +123,9 @@ struct BlockDriverState { void *sync_aiocb; + /* high watermark -- notify if it was reached */ + uint64_t high_watermark; + /* I/O stats (display with "info blockstats"). */ uint64_t rd_bytes; uint64_t wr_bytes; diff --git a/qemu/monitor.c b/qemu/monitor.c index 7022744..d8296ab 100644 --- a/qemu/monitor.c +++ b/qemu/monitor.c @@ -595,6 +595,24 @@ static void do_gdbserver(const char *port) } #endif +void do_block_set_watermark(char *device, int megs) +{ + uint64_t offset = ((uint64_t)megs) << 20; + BlockDriverState *bs; + + bs = bdrv_find(device); + if (!bs) { + term_printf("device not found\n"); + return; + } + + if (megs < 0) + term_printf("ileggal offset\n"); + else + bdrv_set_high_watermark(bs, offset); +} + + static void term_printc(int c) { term_printf("'"); @@ -1623,6 +1641,9 @@ static term_cmd_t term_cmds[] = { #endif { "notify", "ss", do_notify_async_events, "vnc|rtc|migration|reboot|shutdown|vmstop on|off", "enable / disable printing of notifications for the specified event" }, + { "block_set_watermark", "Bi", do_block_set_watermark, + "block-device offset(in MB)", + "set watermark, get notification when reached"}, { NULL, NULL, }, }; -- 1.6.1