throttle.c (c416eecea5f3aea863ab8fda5a36a24157b8f704) | throttle.c (bc33c047d1ec0b35c9cd8be62bcefae2da28654f) |
---|---|
1/* 2 * QEMU block throttling filter driver infrastructure 3 * 4 * Copyright (c) 2017 Manos Pitsidianakis 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 or --- 22 unchanged lines hidden (view full) --- 31 .name = QEMU_OPT_THROTTLE_GROUP_NAME, 32 .type = QEMU_OPT_STRING, 33 .help = "Name of the throttle group", 34 }, 35 { /* end of list */ } 36 }, 37}; 38 | 1/* 2 * QEMU block throttling filter driver infrastructure 3 * 4 * Copyright (c) 2017 Manos Pitsidianakis 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 or --- 22 unchanged lines hidden (view full) --- 31 .name = QEMU_OPT_THROTTLE_GROUP_NAME, 32 .type = QEMU_OPT_STRING, 33 .help = "Name of the throttle group", 34 }, 35 { /* end of list */ } 36 }, 37}; 38 |
39static int throttle_configure_tgm(BlockDriverState *bs, 40 ThrottleGroupMember *tgm, 41 QDict *options, Error **errp) | 39/* 40 * If this function succeeds then the throttle group name is stored in 41 * @group and must be freed by the caller. 42 * If there's an error then @group remains unmodified. 43 */ 44static int throttle_parse_options(QDict *options, char **group, Error **errp) |
42{ 43 int ret; 44 const char *group_name; 45 Error *local_err = NULL; 46 QemuOpts *opts = qemu_opts_create(&throttle_opts, NULL, 0, &error_abort); 47 48 qemu_opts_absorb_qdict(opts, options, &local_err); 49 if (local_err) { --- 8 unchanged lines hidden (view full) --- 58 ret = -EINVAL; 59 goto fin; 60 } else if (!throttle_group_exists(group_name)) { 61 error_setg(errp, "Throttle group '%s' does not exist", group_name); 62 ret = -EINVAL; 63 goto fin; 64 } 65 | 45{ 46 int ret; 47 const char *group_name; 48 Error *local_err = NULL; 49 QemuOpts *opts = qemu_opts_create(&throttle_opts, NULL, 0, &error_abort); 50 51 qemu_opts_absorb_qdict(opts, options, &local_err); 52 if (local_err) { --- 8 unchanged lines hidden (view full) --- 61 ret = -EINVAL; 62 goto fin; 63 } else if (!throttle_group_exists(group_name)) { 64 error_setg(errp, "Throttle group '%s' does not exist", group_name); 65 ret = -EINVAL; 66 goto fin; 67 } 68 |
66 /* Register membership to group with name group_name */ 67 throttle_group_register_tgm(tgm, group_name, bdrv_get_aio_context(bs)); | 69 *group = g_strdup(group_name); |
68 ret = 0; 69fin: 70 qemu_opts_del(opts); 71 return ret; 72} 73 74static int throttle_open(BlockDriverState *bs, QDict *options, 75 int flags, Error **errp) 76{ 77 ThrottleGroupMember *tgm = bs->opaque; | 70 ret = 0; 71fin: 72 qemu_opts_del(opts); 73 return ret; 74} 75 76static int throttle_open(BlockDriverState *bs, QDict *options, 77 int flags, Error **errp) 78{ 79 ThrottleGroupMember *tgm = bs->opaque; |
80 char *group; 81 int ret; |
|
78 79 bs->file = bdrv_open_child(NULL, options, "file", bs, 80 &child_file, false, errp); 81 if (!bs->file) { 82 return -EINVAL; 83 } 84 bs->supported_write_flags = bs->file->bs->supported_write_flags | 85 BDRV_REQ_WRITE_UNCHANGED; 86 bs->supported_zero_flags = bs->file->bs->supported_zero_flags | 87 BDRV_REQ_WRITE_UNCHANGED; 88 | 82 83 bs->file = bdrv_open_child(NULL, options, "file", bs, 84 &child_file, false, errp); 85 if (!bs->file) { 86 return -EINVAL; 87 } 88 bs->supported_write_flags = bs->file->bs->supported_write_flags | 89 BDRV_REQ_WRITE_UNCHANGED; 90 bs->supported_zero_flags = bs->file->bs->supported_zero_flags | 91 BDRV_REQ_WRITE_UNCHANGED; 92 |
89 return throttle_configure_tgm(bs, tgm, options, errp); | 93 ret = throttle_parse_options(options, &group, errp); 94 if (ret == 0) { 95 /* Register membership to group with name group_name */ 96 throttle_group_register_tgm(tgm, group, bdrv_get_aio_context(bs)); 97 g_free(group); 98 } 99 100 return ret; |
90} 91 92static void throttle_close(BlockDriverState *bs) 93{ 94 ThrottleGroupMember *tgm = bs->opaque; 95 throttle_group_unregister_tgm(tgm); 96} 97 --- 59 unchanged lines hidden (view full) --- 157{ 158 ThrottleGroupMember *tgm = bs->opaque; 159 throttle_group_attach_aio_context(tgm, new_context); 160} 161 162static int throttle_reopen_prepare(BDRVReopenState *reopen_state, 163 BlockReopenQueue *queue, Error **errp) 164{ | 101} 102 103static void throttle_close(BlockDriverState *bs) 104{ 105 ThrottleGroupMember *tgm = bs->opaque; 106 throttle_group_unregister_tgm(tgm); 107} 108 --- 59 unchanged lines hidden (view full) --- 168{ 169 ThrottleGroupMember *tgm = bs->opaque; 170 throttle_group_attach_aio_context(tgm, new_context); 171} 172 173static int throttle_reopen_prepare(BDRVReopenState *reopen_state, 174 BlockReopenQueue *queue, Error **errp) 175{ |
165 ThrottleGroupMember *tgm; | 176 int ret; 177 char *group = NULL; |
166 167 assert(reopen_state != NULL); 168 assert(reopen_state->bs != NULL); 169 | 178 179 assert(reopen_state != NULL); 180 assert(reopen_state->bs != NULL); 181 |
170 reopen_state->opaque = g_new0(ThrottleGroupMember, 1); 171 tgm = reopen_state->opaque; 172 173 return throttle_configure_tgm(reopen_state->bs, tgm, reopen_state->options, 174 errp); | 182 ret = throttle_parse_options(reopen_state->options, &group, errp); 183 reopen_state->opaque = group; 184 return ret; |
175} 176 177static void throttle_reopen_commit(BDRVReopenState *reopen_state) 178{ | 185} 186 187static void throttle_reopen_commit(BDRVReopenState *reopen_state) 188{ |
179 ThrottleGroupMember *old_tgm = reopen_state->bs->opaque; 180 ThrottleGroupMember *new_tgm = reopen_state->opaque; | 189 BlockDriverState *bs = reopen_state->bs; 190 ThrottleGroupMember *tgm = bs->opaque; 191 char *group = reopen_state->opaque; |
181 | 192 |
182 throttle_group_unregister_tgm(old_tgm); 183 g_free(old_tgm); 184 reopen_state->bs->opaque = new_tgm; | 193 assert(group); 194 195 if (strcmp(group, throttle_group_get_name(tgm))) { 196 throttle_group_unregister_tgm(tgm); 197 throttle_group_register_tgm(tgm, group, bdrv_get_aio_context(bs)); 198 } 199 g_free(reopen_state->opaque); |
185 reopen_state->opaque = NULL; 186} 187 188static void throttle_reopen_abort(BDRVReopenState *reopen_state) 189{ | 200 reopen_state->opaque = NULL; 201} 202 203static void throttle_reopen_abort(BDRVReopenState *reopen_state) 204{ |
190 ThrottleGroupMember *tgm = reopen_state->opaque; 191 192 throttle_group_unregister_tgm(tgm); 193 g_free(tgm); | 205 g_free(reopen_state->opaque); |
194 reopen_state->opaque = NULL; 195} 196 197static bool throttle_recurse_is_first_non_filter(BlockDriverState *bs, 198 BlockDriverState *candidate) 199{ 200 return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate); 201} --- 56 unchanged lines hidden --- | 206 reopen_state->opaque = NULL; 207} 208 209static bool throttle_recurse_is_first_non_filter(BlockDriverState *bs, 210 BlockDriverState *candidate) 211{ 212 return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate); 213} --- 56 unchanged lines hidden --- |