void do_info_migrate(Monitor *mon) { MigrationState *s = current_migration; if (s) { monitor_printf(mon, "Migration status: "); switch (s->get_status(s)) { case MIG_STATE_ACTIVE: monitor_printf(mon, "active\n"); monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10); monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10); monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10); break; case MIG_STATE_COMPLETED: monitor_printf(mon, "completed\n"); break; case MIG_STATE_ERROR: monitor_printf(mon, "failed\n"); break; case MIG_STATE_CANCELLED: monitor_printf(mon, "cancelled\n"); break; } } }
void do_info_migrate(Monitor *mon, QObject **ret_data) { QDict *qdict; MigrationState *s = current_migration; if (s) { switch (s->get_status(s)) { case MIG_STATE_ACTIVE: qdict = qdict_new(); qdict_put(qdict, "status", qstring_from_str("active")); migrate_put_status(qdict, "ram", ram_bytes_transferred(), ram_bytes_remaining(), ram_bytes_total()); if (blk_mig_active()) { migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(), blk_mig_bytes_remaining(), blk_mig_bytes_total()); } *ret_data = QOBJECT(qdict); break; case MIG_STATE_COMPLETED: *ret_data = qobject_from_jsonf("{ 'status': 'completed' }"); break; case MIG_STATE_ERROR: *ret_data = qobject_from_jsonf("{ 'status': 'failed' }"); break; case MIG_STATE_CANCELLED: *ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }"); break; } } }
MigrationInfo *qmp_query_migrate(Error **errp) { MigrationInfo *info = g_malloc0(sizeof(*info)); MigrationState *s = migrate_get_current(); switch (s->state) { case MIG_STATE_SETUP: /* no migration has happened ever */ break; case MIG_STATE_ACTIVE: info->has_status = true; info->status = g_strdup("active"); info->has_ram = true; info->ram = g_malloc0(sizeof(*info->ram)); info->ram->transferred = ram_bytes_transferred(); info->ram->remaining = ram_bytes_remaining(); info->ram->total = ram_bytes_total(); if (blk_mig_active()) { info->has_disk = true; info->disk = g_malloc0(sizeof(*info->disk)); info->disk->transferred = blk_mig_bytes_transferred(); info->disk->remaining = blk_mig_bytes_remaining(); info->disk->total = blk_mig_bytes_total(); } break; case MIG_STATE_COMPLETED: info->has_status = true; info->status = g_strdup("completed"); break; case MIG_STATE_ERROR: info->has_status = true; info->status = g_strdup("failed"); break; case MIG_STATE_CANCELLED: info->has_status = true; info->status = g_strdup("cancelled"); break; } return info; }
MigrationInfo *qmp_query_migrate(Error **errp) { MigrationInfo *info = g_malloc0(sizeof(*info)); MigrationState *s = migrate_get_current(); switch (s->state) { case MIG_STATE_SETUP: /* no migration has happened ever */ break; case MIG_STATE_ACTIVE: info->has_status = true; info->status = g_strdup("active"); info->has_total_time = true; info->total_time = qemu_get_clock_ms(rt_clock) - s->total_time; info->has_expected_downtime = true; info->expected_downtime = s->expected_downtime; info->has_ram = true; info->ram = g_malloc0(sizeof(*info->ram)); info->ram->transferred = ram_bytes_transferred(); info->ram->remaining = ram_bytes_remaining(); info->ram->total = ram_bytes_total(); info->ram->duplicate = dup_mig_pages_transferred(); info->ram->normal = norm_mig_pages_transferred(); info->ram->normal_bytes = norm_mig_bytes_transferred(); info->ram->dirty_pages_rate = s->dirty_pages_rate; if (blk_mig_active()) { info->has_disk = true; info->disk = g_malloc0(sizeof(*info->disk)); info->disk->transferred = blk_mig_bytes_transferred(); info->disk->remaining = blk_mig_bytes_remaining(); info->disk->total = blk_mig_bytes_total(); } get_xbzrle_cache_stats(info); break; case MIG_STATE_COMPLETED: get_xbzrle_cache_stats(info); info->has_status = true; info->status = g_strdup("completed"); info->total_time = s->total_time; info->has_downtime = true; info->downtime = s->downtime; info->has_ram = true; info->ram = g_malloc0(sizeof(*info->ram)); info->ram->transferred = ram_bytes_transferred(); info->ram->remaining = 0; info->ram->total = ram_bytes_total(); info->ram->duplicate = dup_mig_pages_transferred(); info->ram->normal = norm_mig_pages_transferred(); info->ram->normal_bytes = norm_mig_bytes_transferred(); break; case MIG_STATE_ERROR: info->has_status = true; info->status = g_strdup("failed"); break; case MIG_STATE_CANCELLED: info->has_status = true; info->status = g_strdup("cancelled"); break; } return info; }
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { // printf("migrate thread %lu\n",(unsigned long int)pthread_self()); MigrationState *s = NULL; const char *p; int detach = qdict_get_int(qdict, "detach"); const char *uri = qdict_get_str(qdict, "uri"); if (current_migration && current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) { monitor_printf(mon, "migration already in progress\n"); return -1; } /* Pacer modification: computing estimate migration speed */ int has_mig_time = qdict_haskey(qdict, "mig_time"); int mig_time=500; if(has_mig_time) mig_time=qdict_get_int(qdict,"mig_time"); printf("migration requried time %d\n",mig_time); int metricopt=(int)qdict_get_int(qdict,"throughputrequired"); int metricvalue=0; if(metricopt==1) { int has_throughput = qdict_haskey(qdict,"required"); if(has_throughput) metricvalue=qdict_get_int(qdict,"required"); if(metricvalue!=0) printf("throughput required %d\n",metricvalue); }else{ int has_latency = qdict_haskey(qdict,"required"); if(has_latency) metricvalue=qdict_get_int(qdict,"required"); if(metricvalue!=0) printf("latency required %d\n",metricvalue); } if(metricvalue==0){ printf("no requirement\n"); metricopt=2; } uint64_t memsize=ram_bytes_remaining(); uint64_t disksize=bdrv_get_totallength(); uint64_t speed; printf("ram size %"PRId64"\n",ram_bytes_remaining()); printf("disk size %"PRId64"\n",bdrv_get_totallength()); if(mig_time!=0){ speed=(disksize+memsize)/mig_time; max_throttle=speed; printf("migration speed0 %"PRId64"\n",speed); } //end if (strstart(uri, "tcp:", &p)) { s = tcp_start_outgoing_migration(mon, p, max_throttle, detach, (int)qdict_get_int(qdict, "blk"), (int)qdict_get_int(qdict, "inc"), (int)qdict_get_int(qdict, "sparse"), mig_time, metricopt, metricvalue, (int)qdict_get_int(qdict,"compression"), (int)qdict_get_int(qdict,"scheduling"), (int)qdict_get_int(qdict,"dscheduling"), (int)qdict_get_int(qdict,"throttling")); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { s = exec_start_outgoing_migration(mon, p, max_throttle, detach, (int)qdict_get_int(qdict, "blk"), (int)qdict_get_int(qdict, "inc"), (int)qdict_get_int(qdict, "sparse"), mig_time, metricopt, metricvalue, (int)qdict_get_int(qdict,"compression"), (int)qdict_get_int(qdict, "scheduling"), (int)qdict_get_int(qdict,"dscheduling"), (int)qdict_get_int(qdict,"throttling")); } else if (strstart(uri, "unix:", &p)) { s = unix_start_outgoing_migration(mon, p, max_throttle, detach, (int)qdict_get_int(qdict, "blk"), (int)qdict_get_int(qdict, "inc"), (int)qdict_get_int(qdict, "sparse"), mig_time, metricopt, metricvalue, (int)qdict_get_int(qdict,"compression"), (int)qdict_get_int(qdict, "scheduling"), (int)qdict_get_int(qdict, "dscheduling"), (int)qdict_get_int(qdict, "throttling")); } else if (strstart(uri, "fd:", &p)) { s = fd_start_outgoing_migration(mon, p, max_throttle, detach, (int)qdict_get_int(qdict, "blk"), (int)qdict_get_int(qdict, "inc"), (int)qdict_get_int(qdict, "sparse"), mig_time, metricopt, metricvalue, (int)qdict_get_int(qdict,"compression"), (int)qdict_get_int(qdict, "scheduling"), (int)qdict_get_int(qdict, "dscheduling"), (int)qdict_get_int(qdict, "throttling")); #endif } else { monitor_printf(mon, "unknown migration protocol: %s\n", uri); return -1; } if (s == NULL) { monitor_printf(mon, "migration failed\n"); return -1; } if (current_migration) { current_migration->release(current_migration); } current_migration = s; return 0; }
static void migration_rate_tick(void *opaque) { FdMigrationState *s = opaque; int interval=30000; int64_t total_transfer = my_blk_mig_bytes_transferred(); int64_t current_transfer = total_transfer - s->last_transferred; int64_t real_speed = current_transfer*1000/s->last_interval; //Bytes per second int64_t pasttime=(qemu_get_clock(rt_clock)-s->starttime)/1000L; printf("time %"PRId64" real_speed %"PRId64" ",pasttime,real_speed); int64_t memsize=ram_bytes_remaining(); int64_t remaindisksize=get_remaining_dirty(); int64_t speed = 0L; int64_t maxspeed=80L*1024L*1024L; int64_t restdisk=(bdrv_get_totallength()-total_transfer); //old version for dirtyrate which is the average rate comparing to time zero /*int64_t dirtyamount=(disksize-restdisk); int64_t dirtyrate=dirtyamount/pasttime; int64_t newdirtyrate=dirtyrate; */ //old drity - transferred + generated = new dirty int64_t newgenerate = remaindisksize + current_transfer - s->last_dirty; int64_t dirtyrate=newgenerate*1000/s->last_interval; int64_t newdirtyrate=dirtyrate; int64_t resttime=(uint64_t)(s->mig_state.mig_time)-pasttime; int64_t real_speed_MB = real_speed >> 20L; int64_t last_speed_MB = s->last_speed >> 20L; int64_t speed_MB = 0L; if(s->mig_state.mig_time <= pasttime) { //already over the time speed=maxspeed; }else { /*pess*/ // speed=(disksize+memsize+dirtyrate*resttime)/(resttime); /*opt*/ // speed=(disksize+memsize)/resttime; /*pess-80*/ if((bdrv_get_totallength()<=total_transfer)||(s->precopy==0)) { s->precopy=0; // speed=maxspeed; interval=5000; /* if(dirtyrate>s->last_dirtyrate) newdirtyrate=dirtyrate+(dirtyrate-s->last_dirtyrate)*disksize/(real_speed*s->last_interval/1000L); else{ int64_t temprate=(s->last_dirtyrate-dirtyrate)*disksize/(real_speed*s->last_interval/1000L); if(temprate>dirtyrate) newdirtyrate=0; else newdirtyrate=dirtyrate-temprate; } */ speed=(remaindisksize+memsize+newdirtyrate*resttime)/resttime; } else { // newdirtyrate=dirtyrate; /* if(dirtyrate>s->last_dirtyrate) newdirtyrate=dirtyrate+(dirtyrate-s->last_dirtyrate)*restdisk/(real_speed*s->last_interval/1000L); else{ int64_t temprate=(s->last_dirtyrate-dirtyrate)*restdisk/(real_speed*s->last_interval/1000L); if(temprate>dirtyrate) newdirtyrate=0; else newdirtyrate=dirtyrate-temprate; } */ speed=(remaindisksize+memsize+newdirtyrate*resttime)/resttime; if(restdisk<speed*30L) { uint64_t interval_64=restdisk*1000/speed; interval=interval_64; printf("approaching pre-copy ending: interval %"PRId64"\n",interval_64); } } speed_MB = speed >> 20L; if((real_speed_MB<last_speed_MB)&&(speed_MB>=real_speed_MB)){ printf("extend speed from %"PRId64" ",speed); speed=speed*s->last_speed/real_speed; printf(" to %"PRId64" ",speed); } if(speed>maxspeed) speed =maxspeed; } speed_MB = speed >> 20L; printf("new generate %"PRId64" dirtyrate %"PRId64" new dirty rate %"PRId64" remaining disk %"PRId64" ram %"PRId64" \n",newgenerate,dirtyrate,newdirtyrate,remaindisksize,memsize); printf("real_speed_%"PRId64" last_speed_%"PRId64" speed_%"PRId64"\n",real_speed,s->last_speed,speed); printf("real_speed_MB %"PRId64" last_speed_MB %"PRId64" speed_MB %"PRId64"\n",real_speed_MB,last_speed_MB,speed_MB); if((s->mig_state.metricopt==1)||(s->mig_state.metricopt==2)){ int64_t total_throughput = get_throughput(); int64_t current_throughput=(total_throughput-s->last_throughput)*1000/s->last_interval; //Bytes per second s->last_throughput = total_throughput; int64_t current_throughput_MB = current_throughput >> 20L; printf("current_throughput_MB %"PRId64"\n",current_throughput_MB); if(s->mig_state.metricopt==1){ if(current_throughput_MB>=s->mig_state.metricvalue) { printf("case 1 "); printf("max speed %"PRId64" s->last_speed+step %"PRId64"\n",speed,s->last_speed+speed_step); speed=maxvalue(speed,s->last_speed+speed_step); } else { printf("case 2 "); printf("max speed %"PRId64" s->last_speed-step %"PRId64"\n",speed,s->last_speed-speed_step); speed=maxvalue(speed,s->last_speed-speed_step); } } }
MigrationInfo *qmp_query_migrate(Error **errp) { MigrationInfo *info = g_malloc0(sizeof(*info)); MigrationState *s = migrate_get_current(); switch (s->state) { case MIGRATION_STATUS_NONE: /* no migration has happened ever */ break; case MIGRATION_STATUS_SETUP: info->has_status = true; info->has_total_time = false; break; case MIGRATION_STATUS_ACTIVE: case MIGRATION_STATUS_CANCELLING: info->has_status = true; info->has_total_time = true; info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - s->total_time; info->has_expected_downtime = true; info->expected_downtime = s->expected_downtime; info->has_setup_time = true; info->setup_time = s->setup_time; info->has_ram = true; info->ram = g_malloc0(sizeof(*info->ram)); info->ram->transferred = ram_bytes_transferred(); info->ram->remaining = ram_bytes_remaining(); info->ram->total = ram_bytes_total(); info->ram->duplicate = dup_mig_pages_transferred(); info->ram->skipped = skipped_mig_pages_transferred(); info->ram->normal = norm_mig_pages_transferred(); info->ram->normal_bytes = norm_mig_bytes_transferred(); info->ram->dirty_pages_rate = s->dirty_pages_rate; info->ram->mbps = s->mbps; info->ram->dirty_sync_count = s->dirty_sync_count; if (blk_mig_active()) { info->has_disk = true; info->disk = g_malloc0(sizeof(*info->disk)); info->disk->transferred = blk_mig_bytes_transferred(); info->disk->remaining = blk_mig_bytes_remaining(); info->disk->total = blk_mig_bytes_total(); } get_xbzrle_cache_stats(info); break; case MIGRATION_STATUS_COMPLETED: get_xbzrle_cache_stats(info); info->has_status = true; info->has_total_time = true; info->total_time = s->total_time; info->has_downtime = true; info->downtime = s->downtime; info->has_setup_time = true; info->setup_time = s->setup_time; info->has_ram = true; info->ram = g_malloc0(sizeof(*info->ram)); info->ram->transferred = ram_bytes_transferred(); info->ram->remaining = 0; info->ram->total = ram_bytes_total(); info->ram->duplicate = dup_mig_pages_transferred(); info->ram->skipped = skipped_mig_pages_transferred(); info->ram->normal = norm_mig_pages_transferred(); info->ram->normal_bytes = norm_mig_bytes_transferred(); info->ram->mbps = s->mbps; info->ram->dirty_sync_count = s->dirty_sync_count; break; case MIGRATION_STATUS_FAILED: info->has_status = true; break; case MIGRATION_STATUS_CANCELLED: info->has_status = true; break; } info->status = s->state; return info; }