aboutsummaryrefslogtreecommitdiff
path: root/migration/ram.c
AgeCommit message (Collapse)AuthorFilesLines
2023-07-26migration: Implement dirty-limit convergence algoHyman Huang(黄勇)1-0/+36
Implement dirty-limit convergence algo for live migration, which is kind of like auto-converge algo but using dirty-limit instead of cpu throttle to make migration convergent. Enable dirty page limit if dirty_rate_high_cnt greater than 2 when dirty-limit capability enabled, Disable dirty-limit if migration be canceled. Note that "set_vcpu_dirty_limit", "cancel_vcpu_dirty_limit" commands are not allowed during dirty-limit live migration. Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-ID: <168733225273.5845.15871826788879741674-7@git.sr.ht> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-07-26migration: Put the detection logic before auto-converge checkingHyman Huang(黄勇)1-10/+11
This commit is prepared for the implementation of dirty-limit convergence algo. The detection logic of throttling condition can apply to both auto-converge and dirty-limit algo, putting it's position before the checking logic for auto-converge feature. Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-ID: <168733225273.5845.15871826788879741674-6@git.sr.ht> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-07-26migration: Refactor auto-converge capability logicHyman Huang(黄勇)1-1/+5
Check if block migration is running before throttling guest down in auto-converge way. Note that this modification is kind of like code clean, because block migration does not depend on auto-converge capability, so the order of checks can be adjusted. Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com> Acked-by: Peter Xu <peterx@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-Id: <168618975839.6361.17407633874747688653-5@git.sr.ht> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-07-12migration/ram: Expose ramblock_is_ignored() as migrate_ram_is_ignored()David Hildenbrand1-7/+7
virtio-mem wants to know whether it should not mess with the RAMBlock content (e.g., discard RAM, preallocate memory) on incoming migration. So let's expose that function as migrate_ram_is_ignored() in migration/misc.h Message-ID: <20230706075612.67404-4-david@redhat.com> Acked-by: Peter Xu <peterx@redhat.com> Tested-by: Mario Casquero <mcasquer@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com>
2023-06-13exec/memory: Introduce RAM_NAMED_FILE flagSteve Sistare1-1/+2
migrate_ignore_shared() is an optimization that avoids copying memory that is visible and can be mapped on the target. However, a memory-backend-ram or a memory-backend-memfd block with the RAM_SHARED flag set is not migrated when migrate_ignore_shared() is true. This is wrong, because the block has no named backing store, and its contents will be lost. To fix, ignore shared memory iff it is a named file. Define a new flag RAM_NAMED_FILE to distinguish this case. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> Reviewed-by: Peter Xu <peterx@redhat.com> Message-Id: <1686151116-253260-1-git-send-email-steven.sistare@oracle.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2023-05-23migration/xbzrle: Use i386 host/cpuinfo.hRichard Henderson1-31/+3
Perform the function selection once, and only if CONFIG_AVX512_OPT is enabled. Centralize the selection to xbzrle.c, instead of spreading the init across 3 files. Remove xbzrle-bench.c. The benefit of being able to benchmark the different implementations is less important than not peeking into the internals of the implementation. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2023-05-18Merge tag 'migration-20230518-pull-request' of ↵Richard Henderson1-1/+1
https://gitlab.com/juan.quintela/qemu into staging Migration Pull request Hi Based on latest reviewed parts of migration: - Disable colo (vladimir) - Migration atomic counters (juan) Please apply. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmRmXJUACgkQ9IfvGFhy # 1yNRAxAAjDYJELL34Qovt/WE9qKhYJEvIUGTl1IMWJ22YMFnqIFKRdka57dWoU3P # 7EK1BHmokEEtzGT7Fe1ecERXsOwQIJDIkDTJ5g8Oc8Jt1iqY1AC8h5T+LghijCar # mbZ6qWHaSjsg2lmek/xc9quymzFGGK36PSyB5WkaLRviKQn4RIkEDpUaWny7nDbA # Q8zJJpBqNFqKfC5/DN0ePa3QQscXQJhey3nxqFd8hYp8RFNIV5UJVW5Lf6ombtK7 # atgdWC4ckkfO2z3OsghKeo/UiMFWpPktgBVVMhDLmk+P/E6czc2gfzD6SCvrPKTj # XowI8hro22HVmq9bEY8PtbjMOfpxrAxer+tM2KR/0O9l3UzUacFsi7KGqCJ1/trQ # 1tSDjlgyczb8GOgLwwxj8XE+jPHPfVrzCNfDqrBKBNxz6nnZSdZUwhV5mG8FdVtm # oVVV96BIrNXLl/lIxYIFD/Zyvl8/lrSWQdLkEHTzihYQeXaQfyvPVbV/dOLT4sii # YUuGCuEhF+DW/qz43G1krwq5/bfxsiZoQzrMV/Odtf0wYQKkabA3KNBIda/vxBCR # dsLQ7QtmOwKmCzjqw4LUov9vDNYOYr98o7ZqwJ3qeKL4QgFwtEZUFO3VW6UR8fnF # arVXiTn9wVlkTpu4sT5hLm9400iadhX4Fppji7Ce0tUpLbWbghA= # =3x32 # -----END PGP SIGNATURE----- # gpg: Signature made Thu 18 May 2023 10:12:53 AM PDT # gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [undefined] # gpg: aka "Juan Quintela <quintela@trasno.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * tag 'migration-20230518-pull-request' of https://gitlab.com/juan.quintela/qemu: migration: Fix duplicated included in meson.build migration/multifd: Compute transferred bytes correctly migration: We don't need the field rate_limit_used anymore migration: Use migration_transferred_bytes() to calculate rate_limit migration: Add a trace for migration_transferred_bytes migration: Move migration_total_bytes() to migration-stats.c migration: Move rate_limit_max and rate_limit_used to migration_stats qemu-file: Account for rate_limit usage on qemu_fflush() migration: Don't use INT64_MAX for unlimited rate migration: process_incoming_migration_co(): move colo part to colo migration: split migration_incoming_co configure: add --disable-colo-proxy option Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2023-05-18migration: Move rate_limit_max and rate_limit_used to migration_statsJuan Quintela1-1/+1
These way we can make them atomic and use this functions from any place. I also moved all functions that use rate_limit to migration-stats. Functions got renamed, they are not qemu_file anymore. qemu_file_rate_limit -> migration_rate_exceeded qemu_file_set_rate_limit -> migration_rate_set qemu_file_get_rate_limit -> migration_rate_get qemu_file_reset_rate_limit -> migration_rate_reset qemu_file_acct_rate_limit -> migration_rate_account. Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com> Signed-off-by: Juan Quintela <quintela@redhat.com> Message-Id: <20230515195709.63843-6-quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-18migration: Add last stage indicator to global dirty logGavin Shan1-10/+10
The global dirty log synchronization is used when KVM and dirty ring are enabled. There is a particularity for ARM64 where the backup bitmap is used to track dirty pages in non-running-vcpu situations. It means the dirty ring works with the combination of ring buffer and backup bitmap. The dirty bits in the backup bitmap needs to collected in the last stage of live migration. In order to identify the last stage of live migration and pass it down, an extra parameter is added to the relevant functions and callbacks. This last stage indicator isn't used until the dirty ring is enabled in the subsequent patches. No functional change intended. Signed-off-by: Gavin Shan <gshan@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Tested-by: Zhenyu Zhang <zhenyzha@redhat.com> Message-Id: <20230509022122.20888-2-gshan@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-10ram: Let colo_flush_ram_cache take the bitmap_mutexLukas Straub1-0/+2
This is not required, colo_flush_ram_cache does not run concurrently with the multifd threads since the cache is only flushed after everything has been received. But it makes me more comfortable. This will be used in the next commits to add colo support to multifd. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-Id: <35cb23ba854151d38a31e3a5c8a1020e4283cb4a.1683572883.git.lukasstraub2@web.de> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-10ram: Add public helper to set colo bitmapLukas Straub1-3/+14
The overhead of the mutex in non-multifd mode is negligible, because in that case its just the single thread taking the mutex. This will be used in the next commits to add colo support to multifd. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-Id: <22d83cb428f37929563155531bfb69fd8953cc61.1683572883.git.lukasstraub2@web.de> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08migration: Initialize and cleanup decompression in migration.cLukas Straub1-5/+0
This fixes compress with colo. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram compress: Assert that the file buffer matches the resultLukas Straub1-0/+2
Before this series, "nothing to send" was handled by the file buffer being empty. Now it is tracked via param->result. Assert that the file buffer state matches the result. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Move core decompression code into its own fileLukas Straub1-204/+0
No functional changes intended. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Move core compression code into its own fileLukas Straub1-261/+1
No functional changes intended. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Remove last ram.c dependency from the core compress codeLukas Straub1-10/+17
Make compression interfaces take send_queued_data() as an argument. Remove save_page_use_compression() from flush_compressed_data(). This removes the last ram.c dependency from the core compress code. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Call update_compress_thread_counts from compress_send_queued_dataLukas Straub1-12/+6
This makes the core compress code more independend from ram.c. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Do not call save_page_header() from compress threadsLukas Straub1-9/+35
save_page_header() accesses several global variables, so calling it from multiple threads is pretty ugly. Instead, call save_page_header() before writing out the compressed data from the compress buffer to the migration stream. This also makes the core compress code more independend from ram.c. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Reset result after sending queued dataLukas Straub1-10/+22
And take the param->mutex lock for the whole section to ensure thread-safety. Now, it is explicitly clear if there is no queued data to send. Before, this was handled by param->file stream being empty and thus qemu_put_qemu_file() not sending anything. This will be used in the next commits to move save_page_header() out of compress code. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Dont change param->block in the compress threadLukas Straub1-2/+4
Instead introduce a extra parameter to trigger the compress thread. Now, when the compress thread is done, we know what RAMBlock and offset it did compress. This will be used in the next commits to move save_page_header() out of compress code. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-08ram.c: Let the compress threads return a CompressResult enumLukas Straub1-12/+22
This will be used in the next commits to move save_page_header() out of compress code. Signed-off-by: Lukas Straub <lukasstraub2@web.de> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
2023-05-05migration: Make RAM_SAVE_FLAG_HOOK a normal case entryJuan Quintela1-7/+5
Fixes this commit, clearly a bad merge after a rebase or similar, it should have been its own case since that point. commit 5b0e9dd46fbda5152566a4a26fd96bc0d0452bf7 Author: Peter Lieven <pl@kamp.de> Date: Tue Jun 24 11:32:36 2014 +0200 migration: catch unknown flag combinations in ram_load Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20230504114443.23891-2-quintela@redhat.com>
2023-05-05migration: Rename xbzrle_enabled xbzrle_startedJuan Quintela1-7/+7
Otherwise it is confusing with the function xbzrle_enabled(). Suggested-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com> Message-Id: <20230504115323.24407-1-quintela@redhat.com>
2023-05-03migration/rdma: Unfold last user of acct_update_position()Juan Quintela1-9/+0
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Lukas Straub <lukasstraub2@web.de>
2023-05-03migration/rdma: Split the zero page case from acct_update_positionJuan Quintela1-8/+4
Now that we have atomic counters, we can do it on the place that we need it, no need to do it inside ram.c. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Lukas Straub <lukasstraub2@web.de>
2023-05-03migration: Rename ram_counters to mig_statsJuan Quintela1-24/+24
migration_stats is just too long, and it is going to have more than ram counters in the near future. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Lukas Straub <lukasstraub2@web.de>
2023-05-03migration: Move ram_stats to its own file migration-stats.[ch]Juan Quintela1-2/+1
There is already include/qemu/stats.h, so stats.h was a bad idea. We want this file to not depend on anything else, we will move all the migration counters/stats to this struct. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Lukas Straub <lukasstraub2@web.de>
2023-04-27migration: Make dirty_bytes_last_sync atomicJuan Quintela1-1/+1
As we set its value, it needs to be operated with atomics. We rename it from remaining to better reflect its meaning. Statistics always return the real reamaining bytes. This was used to store how much pages where dirty on the previous generation, so we can calculate the expected downtime as: dirty_bytes_last_sync / current_bandwith. If we use the actual remaining bytes, we would see a very small value at the end of the iteration. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> --- I am open to use ram_bytes_remaining() in its only use and be more "optimistic" about the downtime. Don't use __nocheck() functions. Use stat64_get() now that it exists.
2023-04-27migration: Make dirty_pages_rate atomicJuan Quintela1-2/+3
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Xu <peterx@redhat.com> --- Don't use __nocheck() variants Use stat64_get()
2023-04-27multifd: Only flush once each full round of memoryJuan Quintela1-1/+27
We need to add a new flag to mean to flush at that point. Notice that we still flush at the end of setup and at the end of complete stages. Signed-off-by: Juan Quintela <quintela@redhat.com> Acked-by: Peter Xu <peterx@redhat.com> --- Add missing qemu_fflush(), now it passes all tests always. In the previous version, the check that changes the default value to false got lost in some rebase. Get it back.
2023-04-27multifd: Protect multifd_send_sync_main() callsJuan Quintela1-5/+11
We only need to do that on the ram_save_iterate() call on sending and on destination when we get a RAM_SAVE_FLAG_EOS. In setup() and complete() we need to synch in both new and old cases, so don't add a check there. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Acked-by: Peter Xu <peterx@redhat.com> --- Remove the wrappers that we take out on patch 5.
2023-04-24migration: Create migrate_cpu_throttle_tailslow() functionJuan Quintela1-2/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de>
2023-04-24migration: Create migrate_cpu_throttle_increment() functionJuan Quintela1-1/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de>
2023-04-24migration: Create migrate_cpu_throttle_initial() to option.cJuan Quintela1-1/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de>
2023-04-24migration: Create migrate_max_cpu_throttle()Juan Quintela1-1/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de>
2023-04-24migration: Create migrate_throttle_trigger_threshold()Juan Quintela1-2/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de>
2023-04-24migration: Move migrate_use_xbzrle() to options.cJuan Quintela1-5/+5
Once that we are there, we rename the function to migrate_xbzrle() to be consistent with all other capabilities. We change the type to return bool also for consistency. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2023-04-24migration: Move migrate_use_multifd() to options.cJuan Quintela1-1/+1
Once that we are there, we rename the function to migrate_multifd() to be consistent with all other capabilities. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2023-04-24migration: Move migrate_use_events() to options.cJuan Quintela1-1/+1
Once that we are there, we rename the function to migrate_events() to be consistent with all other capabilities. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2023-04-24migration: Move migrate_use_compression() to options.cJuan Quintela1-8/+8
Once that we are there, we rename the function to migrate_compress() to be consistent with all other capabilities. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
2023-04-24migration: Create options.cJuan Quintela1-0/+1
We move there all capabilities helpers from migration.c. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> --- Following David advise: - looked through the history, capabilities are newer than 2012, so we can remove that bit of the header. - This part is posterior to Anthony. Original Author is Orit. Once there, I put myself. Peter Xu also did quite a bit of work here. Anyone else wants/needs to be there? I didn't search too hard because nobody asked before to be added. What do you think?
2023-04-24migration: Rename normal to normal_pagesJuan Quintela1-5/+5
Rest of counters that refer to pages has a _pages suffix. And historically, this showed the number of full pages transferred. The name "normal" refered to the fact that they were sent without any optimization (compression, xbzrle, zero_page, ...). Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Rename duplicate to zero_pagesJuan Quintela1-5/+5
Rest of counters that refer to pages has a _pages suffix. And historically, this showed the number of pages composed of the same character, here comes the name "duplicated". But since years ago, it refers to the number of zero_pages. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Make postcopy_requests atomicJuan Quintela1-1/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Make dirty_sync_count atomicJuan Quintela1-6/+7
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Make downtime_bytes atomicJuan Quintela1-1/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Make precopy_bytes atomicJuan Quintela1-1/+1
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Make dirty_sync_missed_zero_copy atomicJuan Quintela1-5/+0
Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
2023-04-24migration: Merge ram_counters and ram_atomic_countersJuan Quintela1-23/+16
Using MgrationStats as type for ram_counters mean that we didn't have to re-declare each value in another struct. The need of atomic counters have make us to create MigrationAtomicStats for this atomic counters. Create RAMStats type which is a merge of MigrationStats and MigrationAtomicStats removing unused members. Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> --- Fix typos found by David Edmondson
2023-04-24migration: remove extra whitespace character for code style李皆俊1-1/+1
Fix code style. Signed-off-by: 李皆俊 <a_lijiejun@163.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>