copy_vm: re-structure code to allow more checks before fork

This commit is contained in:
Dietmar Maurer 2013-05-02 07:10:46 +02:00
parent c6d0c8a702
commit 829967a93b

View File

@ -1901,13 +1901,11 @@ __PACKAGE__->register_method({
# exclusive lock if VM is running - else shared lock is enough;
my $shared_lock = $running ? 0 : 1;
# fixme: do early checks - re-check after lock
# fixme: impl. target node parameter (mv VM config if all storages are shared)
my $copyfn = sub {
# all tests after lock
# do all tests after lock
# we also try to do all tests before we fork the worker
my $conf = PVE::QemuServer::load_config($vmid);
PVE::QemuServer::check_lock($conf);
@ -1930,15 +1928,6 @@ __PACKAGE__->register_method({
die "unable to create VM $newid: config file already exists\n"
if -f $conffile;
# create empty/temp config - this fails if VM already exists on other node
PVE::Tools::file_set_contents($conffile, "# qmcopy temporary file\nlock: copy\n");
my $realcmd = sub {
my $upid = shift;
my $newvollist = [];
eval {
my $newconf = { lock => 'copy' };
my $drives = {};
my $vollist = [];
@ -1959,6 +1948,7 @@ __PACKAGE__->register_method({
if (PVE::QemuServer::drive_is_cdrom($drive)) {
$newconf->{$opt} = $value; # simply copy configuration
} else {
$drive->{full} = 1 if $param->{full} || !PVE::Storage::volume_is_base($storecfg, $drive->{file});
$drives->{$opt} = $drive;
push @$vollist, $drive->{file};
}
@ -1980,16 +1970,24 @@ __PACKAGE__->register_method({
$newconf->{description} = $param->{description};
}
PVE::Storage::activate_volumes($storecfg, $vollist);
# create empty/temp config - this fails if VM already exists on other node
PVE::Tools::file_set_contents($conffile, "# qmcopy temporary file\nlock: copy\n");
my $realcmd = sub {
my $upid = shift;
my $newvollist = [];
eval {
local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub { die "interrupted by signal\n"; };
PVE::Storage::activate_volumes($storecfg, $vollist);
foreach my $opt (keys %$drives) {
my $drive = $drives->{$opt};
my $newvolid;
if (!$param->{full} && PVE::Storage::volume_is_base($storecfg, $drive->{file})) {
if (!$drive->{full}) {
print "clone drive $opt ($drive->{file})\n";
$newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newid);
push @$newvollist, $newvolid;
@ -2021,8 +2019,6 @@ __PACKAGE__->register_method({
PVE::QemuServer::update_config_nolock($newid, $newconf, 1);
}
};
die $@ if $@;
delete $newconf->{lock};
PVE::QemuServer::update_config_nolock($newid, $newconf, 1);