Reorganize and fix monitor resume after migration
If migration failed in migrate_fd_put_buffer, the monitor may have been resumed not only in the error path of that function but also once again in migrate_fd_put_ready which is called unconditionally by migrate_fd_connect. Fix this by establishing a cleaner policy: the monitor shall be resumed when the migration file is closed, either via callback (migrate_fd_close) or in migrate_fd_cleanup if no file is open (i.e. no callback invoked). Reported-By: Michael Tokarev <mjt@tls.msk.ru> Tested-By: Michael Tokarev <mjt@tls.msk.ru> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									2da8bb92fb
								
							
						
					
					
						commit
						84ec65520b
					
				
							
								
								
									
										17
									
								
								migration.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								migration.c
									
									
									
									
									
								
							@ -292,17 +292,16 @@ int migrate_fd_cleanup(FdMigrationState *s)
 | 
				
			|||||||
            ret = -1;
 | 
					            ret = -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        s->file = NULL;
 | 
					        s->file = NULL;
 | 
				
			||||||
    }
 | 
					    } else {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (s->fd != -1)
 | 
					 | 
				
			||||||
        close(s->fd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Don't resume monitor until we've flushed all of the buffers */
 | 
					 | 
				
			||||||
        if (s->mon) {
 | 
					        if (s->mon) {
 | 
				
			||||||
            monitor_resume(s->mon);
 | 
					            monitor_resume(s->mon);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->fd != -1) {
 | 
				
			||||||
 | 
					        close(s->fd);
 | 
				
			||||||
        s->fd = -1;
 | 
					        s->fd = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -330,9 +329,6 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
 | 
				
			|||||||
    if (ret == -EAGAIN) {
 | 
					    if (ret == -EAGAIN) {
 | 
				
			||||||
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
 | 
					        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
 | 
				
			||||||
    } else if (ret < 0) {
 | 
					    } else if (ret < 0) {
 | 
				
			||||||
        if (s->mon) {
 | 
					 | 
				
			||||||
            monitor_resume(s->mon);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        s->state = MIG_STATE_ERROR;
 | 
					        s->state = MIG_STATE_ERROR;
 | 
				
			||||||
        notifier_list_notify(&migration_state_notifiers, NULL);
 | 
					        notifier_list_notify(&migration_state_notifiers, NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -458,6 +454,9 @@ int migrate_fd_close(void *opaque)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    FdMigrationState *s = opaque;
 | 
					    FdMigrationState *s = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->mon) {
 | 
				
			||||||
 | 
					        monitor_resume(s->mon);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
 | 
					    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
 | 
				
			||||||
    return s->close(s);
 | 
					    return s->close(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user