diff --git a/src/mirror.c b/src/mirror.c index 4f1523d..2b35a31 100644 --- a/src/mirror.c +++ b/src/mirror.c @@ -347,13 +347,14 @@ void mirror_run( struct server *serve ) NULLCHECK( serve ); NULLCHECK( serve->mirror ); - int pass; + struct mirror* m = serve->mirror; + uint64_t written; info("Starting mirror" ); - for (pass=0; pass < mirror_maximum_passes-1; pass++) { + for (m->pass=0; m->pass < mirror_maximum_passes-1; m->pass++) { - debug("mirror start pass=%d", pass); + debug("mirror start pass=%d", m->pass); if ( !mirror_pass( serve, 0, &written ) ){ debug("Failed mirror pass state is %d", mirror_get_state( serve->mirror ) ); debug("pass failed, giving up"); diff --git a/src/mirror.h b/src/mirror.h index 9767d55..741151a 100644 --- a/src/mirror.h +++ b/src/mirror.h @@ -69,7 +69,7 @@ struct mirror { const char * filename; off64_t max_bytes_per_second; enum mirror_finish_action action_at_finish; - + char *mapped; struct bitset_mapping *dirty_map; @@ -79,6 +79,9 @@ struct mirror { * and checking the remote size, whether successful or not. */ struct mbox * commit_signal; + + /* The current mirror pass. We put this here so status can query it */ + int pass; }; @@ -106,3 +109,4 @@ struct mirror_super * mirror_super_create( ); void * mirror_super_runner( void * serve_uncast ); #endif + diff --git a/src/status.c b/src/status.c index dba9629..2bdbad6 100644 --- a/src/status.c +++ b/src/status.c @@ -11,6 +11,11 @@ struct status * status_create( struct server * serve ) status->pid = getpid(); status->has_control = serve->success; status->is_mirroring = NULL != serve->mirror; + + if ( status->is_mirroring ) { + status->migration_pass = serve->mirror->pass; + } + return status; } @@ -26,6 +31,11 @@ int status_write( struct status * status, int fd ) PRINT_INT( pid ); PRINT_BOOL( is_mirroring ); PRINT_BOOL( has_control ); + + if ( status->is_mirroring ) { + PRINT_INT( migration_pass ); + } + dprintf(fd, "\n"); return 1; } @@ -36,3 +46,4 @@ void status_destroy( struct status * status ) NULLCHECK( status ); free( status ); } + diff --git a/src/status.h b/src/status.h index 6293e43..024a516 100644 --- a/src/status.h +++ b/src/status.h @@ -32,8 +32,17 @@ * or "serve" mode. It will become true when a server in "serve" * mode starts a migration, and will become false again when the * migration terminates, successfully or not. - * If the server is currently in "listen" mode, this will never b + * 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. + * + * migration_pass: + * When migrating, we perform a number of passes over the file. This indicates + * the current pass. + * + * */ @@ -46,6 +55,7 @@ struct status { pid_t pid; int has_control; int is_mirroring; + int migration_pass; }; /** Create a status object for the given server. */ @@ -60,3 +70,4 @@ void status_destroy( struct status * ); #endif + diff --git a/tests/unit/check_status.c b/tests/unit/check_status.c index 518c630..6c27419 100644 --- a/tests/unit/check_status.c +++ b/tests/unit/check_status.c @@ -10,6 +10,7 @@ START_TEST( test_status_create ) struct server server; struct status *status = NULL; + server.mirror = NULL; status = status_create( &server ); fail_if( NULL == status, "Status wasn't allocated" ); @@ -22,6 +23,7 @@ START_TEST( test_gets_has_control ) struct server server; struct status * status; + server.mirror = NULL; server.success = 1; status = status_create( &server ); @@ -48,6 +50,25 @@ START_TEST( test_gets_is_mirroring ) } END_TEST +START_TEST( test_gets_migration_pass ) +{ + struct server server; + struct status * status; + + server.mirror = NULL; + status = status_create( &server ); + fail_if( status->migration_pass != 0, "migration_pass was set" ); + status_destroy( status ); + + server.mirror = (struct mirror *)xmalloc( sizeof( struct mirror ) ); + server.mirror->pass = 1; + status = status_create( &server ); + fail_unless( status->migration_pass == 1, "migration_pass wasn't set" ); + status_destroy( status ); + free( server.mirror ); +} +END_TEST + START_TEST( test_gets_pid ) { @@ -137,6 +158,36 @@ START_TEST( test_renders_pid ) } END_TEST +START_TEST( test_renders_migration_pass ) +{ + struct status status; + int fds[2]; + pipe(fds); + char buf[1024] = {0}; + char *found; + + status.is_mirroring = 0; + status.migration_pass = 1; + status_write( &status, fds[1] ); + + fail_unless( read_until_newline( fds[0], buf, 1024 ) > 0, + "Couldn't read the result" ); + found = strstr( buf, "migration_pass" ); + fail_if( NULL != found, "migration pass output when not migrating" ); + + status.is_mirroring = 1; + status_write( &status, fds[1] ); + + fail_unless( read_until_newline( fds[0], buf, 1024 ) > 0, + "Couldn't read the result" ); + found = strstr( buf, "migration_pass=1" ); + fail_if( NULL == found, "migration pass not output when not migrating" ); + + +} +END_TEST + + Suite *status_suite(void) { @@ -148,10 +199,12 @@ Suite *status_suite(void) tcase_add_test(tc_create, test_gets_has_control); tcase_add_test(tc_create, test_gets_is_mirroring); tcase_add_test(tc_create, test_gets_pid); + tcase_add_test(tc_create, test_gets_migration_pass); tcase_add_test(tc_render, test_renders_has_control); tcase_add_test(tc_render, test_renders_is_mirroring); tcase_add_test(tc_render, test_renders_pid); + tcase_add_test(tc_render, test_renders_migration_pass); suite_add_tcase(s, tc_create); suite_add_tcase(s, tc_render); @@ -171,4 +224,3 @@ int main(void) return (number_failed == 0) ? 0 : 1; } -