qmp: add block-dirty-bitmap-clear
Add bdrv_clear_dirty_bitmap and a matching QMP command, qmp_block_dirty_bitmap_clear that enables a user to reset the bitmap attached to a drive. This allows us to reset a bitmap in the event of a full drive backup. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-id: 1429314609-29776-12-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									d58d845397
								
							
						
					
					
						commit
						e74e6b78e6
					
				
							
								
								
									
										8
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								block.c
									
									
									
									
									
								
							| @ -63,6 +63,7 @@ | ||||
| struct BdrvDirtyBitmap { | ||||
|     HBitmap *bitmap; | ||||
|     BdrvDirtyBitmap *successor; | ||||
|     int64_t size; | ||||
|     char *name; | ||||
|     bool disabled; | ||||
|     QLIST_ENTRY(BdrvDirtyBitmap) list; | ||||
| @ -5557,6 +5558,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, | ||||
|     } | ||||
|     bitmap = g_new0(BdrvDirtyBitmap, 1); | ||||
|     bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity)); | ||||
|     bitmap->size = bitmap_size; | ||||
|     bitmap->name = g_strdup(name); | ||||
|     bitmap->disabled = false; | ||||
|     QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list); | ||||
| @ -5759,6 +5761,12 @@ void bdrv_reset_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, | ||||
|     hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors); | ||||
| } | ||||
| 
 | ||||
| void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap) | ||||
| { | ||||
|     assert(bdrv_dirty_bitmap_enabled(bitmap)); | ||||
|     hbitmap_reset(bitmap->bitmap, 0, bitmap->size); | ||||
| } | ||||
| 
 | ||||
| static void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, | ||||
|                            int nr_sectors) | ||||
| { | ||||
|  | ||||
							
								
								
									
										34
									
								
								blockdev.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								blockdev.c
									
									
									
									
									
								
							| @ -2079,6 +2079,40 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, | ||||
|     aio_context_release(aio_context); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Completely clear a bitmap, for the purposes of synchronizing a bitmap | ||||
|  * immediately after a full backup operation. | ||||
|  */ | ||||
| void qmp_block_dirty_bitmap_clear(const char *node, const char *name, | ||||
|                                   Error **errp) | ||||
| { | ||||
|     AioContext *aio_context; | ||||
|     BdrvDirtyBitmap *bitmap; | ||||
|     BlockDriverState *bs; | ||||
| 
 | ||||
|     bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp); | ||||
|     if (!bitmap || !bs) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (bdrv_dirty_bitmap_frozen(bitmap)) { | ||||
|         error_setg(errp, | ||||
|                    "Bitmap '%s' is currently frozen and cannot be modified", | ||||
|                    name); | ||||
|         goto out; | ||||
|     } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { | ||||
|         error_setg(errp, | ||||
|                    "Bitmap '%s' is currently disabled and cannot be cleared", | ||||
|                    name); | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     bdrv_clear_dirty_bitmap(bitmap); | ||||
| 
 | ||||
|  out: | ||||
|     aio_context_release(aio_context); | ||||
| } | ||||
| 
 | ||||
| int hmp_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) | ||||
| { | ||||
|     const char *id = qdict_get_str(qdict, "id"); | ||||
|  | ||||
| @ -479,6 +479,7 @@ void bdrv_set_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, | ||||
|                            int64_t cur_sector, int nr_sectors); | ||||
| void bdrv_reset_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, | ||||
|                              int64_t cur_sector, int nr_sectors); | ||||
| void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||||
| void bdrv_dirty_iter_init(BlockDriverState *bs, | ||||
|                           BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi); | ||||
| void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset); | ||||
|  | ||||
| @ -1021,6 +1021,20 @@ | ||||
| { 'command': 'block-dirty-bitmap-remove', | ||||
|   'data': 'BlockDirtyBitmap' } | ||||
| 
 | ||||
| ## | ||||
| # @block-dirty-bitmap-clear | ||||
| # | ||||
| # Clear (reset) a dirty bitmap on the device | ||||
| # | ||||
| # Returns: nothing on success | ||||
| #          If @node is not a valid block device, DeviceNotFound | ||||
| #          If @name is not found, GenericError with an explanation | ||||
| # | ||||
| # Since 2.4 | ||||
| ## | ||||
| { 'command': 'block-dirty-bitmap-clear', | ||||
|   'data': 'BlockDirtyBitmap' } | ||||
| 
 | ||||
| ## | ||||
| # @block_set_io_throttle: | ||||
| # | ||||
|  | ||||
| @ -1361,6 +1361,35 @@ Example: | ||||
|                                                       "name": "bitmap0" } } | ||||
| <- { "return": {} } | ||||
| 
 | ||||
| EQMP | ||||
| 
 | ||||
|     { | ||||
|         .name       = "block-dirty-bitmap-clear", | ||||
|         .args_type  = "node:B,name:s", | ||||
|         .mhandler.cmd_new = qmp_marshal_input_block_dirty_bitmap_clear, | ||||
|     }, | ||||
| 
 | ||||
| SQMP | ||||
| 
 | ||||
| block-dirty-bitmap-clear | ||||
| ------------------------ | ||||
| Since 2.4 | ||||
| 
 | ||||
| Reset the dirty bitmap associated with a node so that an incremental backup | ||||
| from this point in time forward will only backup clusters modified after this | ||||
| clear operation. | ||||
| 
 | ||||
| Arguments: | ||||
| 
 | ||||
| - "node": device/node on which to remove dirty bitmap (json-string) | ||||
| - "name": name of the dirty bitmap to remove (json-string) | ||||
| 
 | ||||
| Example: | ||||
| 
 | ||||
| -> { "execute": "block-dirty-bitmap-clear", "arguments": { "node": "drive0", | ||||
|                                                            "name": "bitmap0" } } | ||||
| <- { "return": {} } | ||||
| 
 | ||||
| EQMP | ||||
| 
 | ||||
|     { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 John Snow
						John Snow