diff --git a/src/status.c b/src/status.c index 8e206a2..17a78cc 100644 --- a/src/status.c +++ b/src/status.c @@ -33,6 +33,8 @@ struct status * status_create( struct server * serve ) status->migration_duration /= 1000; status->migration_speed = serve->mirror->all_dirty / ( status->migration_duration + 1 ); status->migration_speed_limit = serve->mirror->max_bytes_per_second; + + status->migration_seconds_left = server_mirror_eta( serve ); } server_unlock_start_mirror( serve ); @@ -64,6 +66,7 @@ int status_write( struct status * status, int fd ) PRINT_UINT64( pass_clean_bytes ); PRINT_UINT64( migration_speed ); PRINT_UINT64( migration_duration ); + PRINT_UINT64( migration_seconds_left ); if ( status->migration_speed_limit < UINT64_MAX ) { PRINT_UINT64( migration_speed_limit ); }; diff --git a/src/status.h b/src/status.h index 795632b..925ec99 100644 --- a/src/status.h +++ b/src/status.h @@ -46,6 +46,7 @@ * If the server is currently in "listen" mode, this will never be * true. * + * * If is_migrating is true, then a number of other attributes may appear, * relating to the progress of the migration. * @@ -69,6 +70,10 @@ * to send to the destination. Once all the bytes are clean, the migration is * done. * + * migration_seconds_left: + * Our current best estimate of how many seconds are left before the migration + * migration is finished. + * */ @@ -91,6 +96,7 @@ struct status { uint64_t migration_duration; uint64_t migration_speed; uint64_t migration_speed_limit; + uint64_t migration_seconds_left; }; /** Create a status object for the given server. */ diff --git a/tests/unit/check_status.c b/tests/unit/check_status.c index dba1e6c..3e4586b 100644 --- a/tests/unit/check_status.c +++ b/tests/unit/check_status.c @@ -2,6 +2,7 @@ #include "serve.h" #include "ioutil.h" #include "util.h" +#include "bitset.h" #include @@ -11,6 +12,10 @@ struct server* mock_server(void) out->l_start_mirror = flexthread_mutex_create(); out->nbd_client = xmalloc( sizeof( struct client_tbl_entry ) * 4 ); out->max_nbd_clients = 4; + out->size = 65536; + + out->allocation_map = bitset_alloc( 65536, 4096 ); + return out; } @@ -18,7 +23,7 @@ struct server* mock_mirroring_server(void) { struct server *out = mock_server(); out->mirror = xmalloc( sizeof( struct mirror ) ); - + out->mirror_super = xmalloc( sizeof( struct mirror_super ) ); return out; } @@ -28,7 +33,13 @@ void destroy_mock_server( struct server* serve ) free( serve->mirror ); } + if ( NULL != serve->mirror_super ) { + free( serve->mirror_super ); + } + flexthread_mutex_destroy( serve->l_start_mirror ); + + bitset_free( serve->allocation_map ); free( serve->nbd_client ); free( serve ); } @@ -166,6 +177,7 @@ START_TEST( test_gets_migration_statistics ) server->mirror->this_pass_dirty = 4096; server->mirror->all_dirty = 16384; server->mirror->max_bytes_per_second = 32768; + server->mirror->offset = 0; /* we have a bit of a time dependency here */ server->mirror->migration_started = monotonic_time_ms(); @@ -189,6 +201,8 @@ START_TEST( test_gets_migration_statistics ) fail_unless( 32768 == status->migration_speed_limit, "migration_speed_limit not read" ); + // ( size / current_bps ) + 1 happens to be 3 for this test + fail_unless( 3 == status->migration_seconds_left, "migration_seconds_left not gathered" ); status_destroy( status ); destroy_mock_server( server ); @@ -335,6 +349,7 @@ START_TEST( test_renders_migration_statistics ) status.migration_duration = 8; status.migration_speed = 40000000; status.migration_speed_limit = 40000001; + status.migration_seconds_left = 1; status_write( &status, fds[1] ); fail_if_rendered( fds[0], "pass_dirty_bytes" ); @@ -351,6 +366,9 @@ START_TEST( test_renders_migration_statistics ) status_write( &status, fds[1] ); fail_if_rendered( fds[0], "migration_speed_limit" ); + status_write( &status, fds[1] ); + fail_if_rendered( fds[0], "migration_seconds_left" ); + status.is_mirroring = 1; status_write( &status, fds[1] ); @@ -368,6 +386,9 @@ START_TEST( test_renders_migration_statistics ) status_write( &status, fds[1] ); fail_unless_rendered( fds[0], "migration_speed_limit=40000001" ); + status_write( &status, fds[1] ); + fail_unless_rendered( fds[0], "migration_seconds_left=1" ); + status.migration_speed_limit = UINT64_MAX; status_write( &status, fds[1] );