Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pve-manager
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
pve-manager
Commits
f7b706cb
Commit
f7b706cb
authored
Dec 02, 2011
by
Dietmar Maurer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use new AbstractMigrate.pm
parent
25ac9b68
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
396 deletions
+175
-396
OpenVZ.pm
PVE/API2/OpenVZ.pm
+13
-1
OpenVZMigrate.pm
PVE/OpenVZMigrate.pm
+159
-373
VNCConsole.js
www/manager/VNCConsole.js
+3
-22
No files found.
PVE/API2/OpenVZ.pm
View file @
f7b706cb
...
...
@@ -320,6 +320,16 @@ __PACKAGE__->register_method({
my
$cmd
=
['
vzctl
',
'
--skiplock
',
'
--quiet
',
'
set
',
$vmid
,
'
--applyconfig_map
',
'
name
',
'
--save
'];
run_command
(
$cmd
);
# reload config
my
$conf
=
PVE::OpenVZ::
load_config
(
$vmid
);
# and initialize quota
my
$disk_quota
=
$conf
->
{
disk_quota
}
->
{
value
};
if
(
!
defined
(
$disk_quota
)
||
(
$disk_quota
!=
0
))
{
my
$cmd
=
['
vzctl
',
'
--skiplock
',
'
quotainit
',
$vmid
];
run_command
(
$cmd
);
}
};
return
$rpcenv
->
fork_worker
(
$param
->
{
restore
}
?
'
vzrestore
'
:
'
vzcreate
',
...
...
@@ -1037,7 +1047,9 @@ __PACKAGE__->register_method({
my
$realcmd
=
sub
{
my
$upid
=
shift
;
PVE::OpenVZMigrate::
migrate
(
$target
,
$targetip
,
$vmid
,
$param
->
{
online
});
PVE::
OpenVZMigrate
->
migrate
(
$target
,
$targetip
,
$vmid
,
$param
);
return
;
};
...
...
PVE/OpenVZMigrate.pm
View file @
f7b706cb
...
...
@@ -2,334 +2,125 @@ package PVE::OpenVZMigrate;
use
strict
;
use
warnings
;
use
P
OSIX
qw(strftime)
;
use
P
VE::
AbstractMigrate
;
use
File::
Basename
;
use
File::
Copy
;
use
IO::
File
;
use
IPC::
Open2
;
use
PVE::
Tools
;
use
PVE::
INotify
;
use
PVE::
Cluster
;
use
PVE::
Storage
;
use
PVE::
OpenVZ
;
my
$delayed_interrupt
=
0
;
use
base
qw(PVE::AbstractMigrate)
;
# blowfish is a fast block cipher, much faster then 3des
my
@ssh_opts
=
('
-c
',
'
blowfish
',
'
-o
',
'
BatchMode=yes
');
my
@ssh_cmd
=
('
/usr/bin/ssh
',
@ssh_opts
);
my
@scp_cmd
=
('
/usr/bin/scp
',
@ssh_opts
);
my
@rsync_opts
=
('
-aH
',
'
--delete
',
'
--numeric-ids
');
my
@rsync_cmd
=
('
/usr/bin/rsync
',
@rsync_opts
);
# fixme: lock VM on target node
sub
msg2text
{
my
(
$level
,
$msg
)
=
@_
;
chomp
$msg
;
return
''
if
!
$msg
;
my
$res
=
'';
my
$tstr
=
strftime
("
%b %d %H:%M:%S
",
localtime
);
foreach
my
$line
(
split
(
/\n/
,
$msg
))
{
if
(
$level
eq
'
err
')
{
$res
.=
"
$tstr
ERROR:
$line
\n
";
}
else
{
$res
.=
"
$tstr
$line
\n
";
}
}
return
$res
;
}
sub
logmsg
{
my
(
$level
,
$msg
)
=
@_
;
chomp
$msg
;
return
if
!
$msg
;
print
msg2text
(
$level
,
$msg
);
}
sub
run_command
{
my
(
$cmd
,
%
param
)
=
@_
;
my
$logfunc
=
sub
{
my
$line
=
shift
;
logmsg
('
info
',
$line
);
};
logmsg
('
info
',
"
#
"
.
PVE::Tools::
cmd2string
(
$cmd
));
PVE::Tools::
run_command
(
$cmd
,
%
param
,
outfunc
=>
$logfunc
,
errfunc
=>
$logfunc
);
}
sub
run_command_quiet_full
{
my
(
$cmd
,
$logerr
,
%
param
)
=
@_
;
my
$log
=
'';
my
$logfunc
=
sub
{
my
$line
=
shift
;
$log
.=
msg2text
('
info
',
$line
);;
};
eval
{
PVE::Tools::
run_command
(
$cmd
,
%
param
,
outfunc
=>
$logfunc
,
errfunc
=>
$logfunc
);
};
if
(
my
$err
=
$@
)
{
logmsg
('
info
',
"
#
"
.
PVE::Tools::
cmd2string
(
$cmd
));
print
$log
;
if
(
$logerr
)
{
logmsg
('
err
',
$err
);
}
else
{
die
$err
;
}
}
}
sub
run_command_quiet
{
my
(
$cmd
,
%
param
)
=
@_
;
return
run_command_quiet_full
(
$cmd
,
0
,
%
param
);
}
sub
run_command_logerr
{
my
(
$cmd
,
%
param
)
=
@_
;
return
run_command_quiet_full
(
$cmd
,
1
,
%
param
);
}
sub
eval_int
{
my
(
$func
)
=
@_
;
eval
{
local
$SIG
{
INT
}
=
$SIG
{
TERM
}
=
$SIG
{
QUIT
}
=
$SIG
{
HUP
}
=
sub
{
$delayed_interrupt
=
0
;
die
"
interrupted by signal
\n
";
};
local
$SIG
{
PIPE
}
=
sub
{
$delayed_interrupt
=
0
;
die
"
interrupted by signal
\n
";
};
my
$di
=
$delayed_interrupt
;
$delayed_interrupt
=
0
;
die
"
interrupted by signal
\n
"
if
$di
;
&
$func
();
};
}
sub
migrate
{
my
(
$node
,
$nodeip
,
$vmid
,
$online
)
=
@_
;
my
$starttime
=
time
();
my
$rem_ssh
=
local
$ENV
{
RSYNC_RSH
}
=
join
('
',
@ssh_cmd
);
local
$SIG
{
INT
}
=
$SIG
{
TERM
}
=
$SIG
{
QUIT
}
=
$SIG
{
HUP
}
=
$SIG
{
PIPE
}
=
sub
{
logmsg
('
err
',
"
received interrupt - delayed
");
$delayed_interrupt
=
1
;
};
local
$ENV
{
RSYNC_RSH
}
=
join
('
',
@ssh_cmd
);
my
$session
=
{
vmid
=>
$vmid
,
node
=>
$node
,
nodeip
=>
$nodeip
,
storecfg
=>
PVE::Storage::
config
(),
vzconf
=>
PVE::OpenVZ::
read_global_vz_config
(),
rem_ssh
=>
[
@ssh_cmd
,
"
root
\
@
$nodeip
"],
};
sub
lock_vm
{
my
(
$self
,
$vmid
,
$code
,
@param
)
=
@_
;
my
$errors
;
# lock container during migration
eval
{
PVE::OpenVZ::
lock_container
(
$vmid
,
sub
{
eval_int
(
sub
{
prepare
(
$session
,
$vmid
,
$online
);
});
die
$@
if
$@
;
my
$rhash
=
{};
eval_int
(
sub
{
phase1
(
$session
,
$vmid
,
$session
->
{
vmconf
},
$rhash
,
$session
->
{
running
});
});
my
$err
=
$@
;
if
(
$err
)
{
logmsg
('
err
',
$err
);
eval
{
phase1_cleanup
(
$session
,
$vmid
,
$session
->
{
vmconf
},
$rhash
,
$session
->
{
running
});
};
if
(
my
$tmperr
=
$@
)
{
logmsg
('
err
',
$tmperr
);
}
eval
{
final_cleanup
(
$session
,
$vmid
,
$session
->
{
vmconf
});
};
if
(
my
$tmperr
=
$@
)
{
logmsg
('
err
',
$tmperr
);
}
die
$err
;
}
# vm is now owned by other node
# Note: there is no VM config file on the local node anymore
if
(
$session
->
{
running
})
{
$rhash
=
{};
eval_int
(
sub
{
phase2
(
$session
,
$vmid
,
$session
->
{
vmconf
},
$rhash
);
});
my
$phase2err
=
$@
;
if
(
$phase2err
)
{
$errors
=
1
;
logmsg
('
err
',
"
online migrate failure -
$phase2err
");
}
eval
{
phase2_cleanup
(
$session
,
$vmid
,
$session
->
{
vmconf
},
$rhash
,
$phase2err
);
};
if
(
my
$err
=
$@
)
{
logmsg
('
err
',
$err
);
$errors
=
1
;
}
# always stop local VM - no interrupts possible
eval
{
phase2_stop_vm
(
$session
,
$vmid
,
$session
->
{
vmconf
})
};
if
(
my
$err
=
$@
)
{
logmsg
('
err
',
"
stopping vm failed -
$err
");
$errors
=
1
;
}
}
# phase3 (finalize)
$rhash
=
{};
eval_int
(
sub
{
phase3
(
$session
,
$vmid
,
$session
->
{
vmconf
},
$rhash
);
});
my
$phase3err
=
$@
;
if
(
$phase3err
)
{
logmsg
('
err
',
$phase3err
);
$errors
=
1
;
}
eval
{
phase3_cleanup
(
$session
,
$vmid
,
$session
->
{
vmconf
},
$rhash
,
$phase3err
);
};
if
(
my
$err
=
$@
)
{
logmsg
('
err
',
$err
);
$errors
=
1
;
}
eval
{
final_cleanup
(
$session
,
$vmid
,
$session
->
{
vmconf
});
};
if
(
my
$tmperr
=
$@
)
{
logmsg
('
err
',
$tmperr
);
}
})};
my
$err
=
$@
;
my
$delay
=
time
()
-
$starttime
;
my
$mins
=
int
(
$delay
/
60
);
my
$secs
=
$delay
-
$mins
*
60
;
my
$hours
=
int
(
$mins
/
60
);
$mins
=
$mins
-
$hours
*
60
;
my
$duration
=
sprintf
"
%02d:%02d:%02d
",
$hours
,
$mins
,
$secs
;
if
(
$err
)
{
logmsg
('
err
',
"
migration aborted (duration
$duration
):
$err
");
die
"
migration aborted
\n
";
}
if
(
$errors
)
{
logmsg
('
err
',
"
migration finished with problems (duration
$duration
)
");
die
"
migration problems
\n
"
}
logmsg
('
info
',
"
migration finished successfuly (duration
$duration
)
");
return
PVE::OpenVZ::
lock_container
(
$vmid
,
$code
,
@param
);
}
sub
prepare
{
my
(
$session
,
$vmid
,
$online
)
=
@_
;
my
(
$self
,
$vmid
)
=
@_
;
my
$online
=
$self
->
{
opts
}
->
{
online
};
$self
->
{
storecfg
}
=
PVE::Storage::
config
();
$self
->
{
vzconf
}
=
PVE::OpenVZ::
read_global_vz_config
(),
# test is VM exist
my
$conf
=
$se
ssion
->
{
vmconf
}
=
PVE::OpenVZ::
load_config
(
$vmid
);
my
$conf
=
$se
lf
->
{
vmconf
}
=
PVE::OpenVZ::
load_config
(
$vmid
);
my
$path
=
PVE::OpenVZ::
get_privatedir
(
$conf
,
$vmid
);
my
(
$vtype
,
$volid
)
=
PVE::Storage::
path_to_volume_id
(
$se
ssion
->
{
storecfg
},
$path
);
my
(
$vtype
,
$volid
)
=
PVE::Storage::
path_to_volume_id
(
$se
lf
->
{
storecfg
},
$path
);
my
(
$storage
,
$volname
)
=
PVE::Storage::
parse_volume_id
(
$volid
,
1
)
if
$volid
;
die
"
can't determine assigned storage
\n
"
if
!
$storage
;
# check if storage is available on both nodes
my
$scfg
=
PVE::Storage::
storage_check_node
(
$se
ssion
->
{
storecfg
},
$storage
);
PVE::Storage::
storage_check_node
(
$se
ssion
->
{
storecfg
},
$storage
,
$session
->
{
node
});
my
$scfg
=
PVE::Storage::
storage_check_node
(
$se
lf
->
{
storecfg
},
$storage
);
PVE::Storage::
storage_check_node
(
$se
lf
->
{
storecfg
},
$storage
,
$self
->
{
node
});
# we simply use the backup dir to store temporary dump files
# Note: this is on shared storage if the storage is 'shared'
$se
ssion
->
{
dumpdir
}
=
PVE::Storage::
get_backup_dir
(
$session
->
{
storecfg
},
$storage
);
$se
lf
->
{
dumpdir
}
=
PVE::Storage::
get_backup_dir
(
$self
->
{
storecfg
},
$storage
);
PVE::Storage::
activate_volumes
(
$se
ssion
->
{
storecfg
},
[
$volid
]);
PVE::Storage::
activate_volumes
(
$se
lf
->
{
storecfg
},
[
$volid
]);
$se
ssion
->
{
storage
}
=
$storage
;
$se
ssion
->
{
privatedir
}
=
$path
;
$se
lf
->
{
storage
}
=
$storage
;
$se
lf
->
{
privatedir
}
=
$path
;
$se
ssion
->
{
rootdir
}
=
PVE::OpenVZ::
get_rootdir
(
$conf
,
$vmid
);
$se
lf
->
{
rootdir
}
=
PVE::OpenVZ::
get_rootdir
(
$conf
,
$vmid
);
$se
ssion
->
{
shared
}
=
$scfg
->
{
shared
};
$se
lf
->
{
shared
}
=
$scfg
->
{
shared
};
$session
->
{
running
}
=
0
;
my
$running
=
0
;
if
(
PVE::OpenVZ::
check_running
(
$vmid
))
{
die
"
cant migrate running container without --online
\n
"
if
!
$online
;
$
session
->
{
running
}
=
1
;
$
running
=
1
;
}
# fixme: test if VM uses local resources
# test ssh connection
my
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
/bin/true
'
];
eval
{
run_comman
d_quiet
(
$cmd
);
};
my
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
/bin/true
'
];
eval
{
$self
->
cm
d_quiet
(
$cmd
);
};
die
"
Can't connect to destination address using public key
\n
"
if
$@
;
if
(
$
session
->
{
running
}
)
{
if
(
$
running
)
{
# test if OpenVZ is running
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
/etc/init.d/vz status
'
];
eval
{
run_comman
d_quiet
(
$cmd
);
};
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
/etc/init.d/vz status
'
];
eval
{
$self
->
cm
d_quiet
(
$cmd
);
};
die
"
OpenVZ is not running on the target machine
\n
"
if
$@
;
# test if CPT modules are loaded for online migration
die
"
vzcpt module is not loaded
\n
"
if
!
-
f
'
/proc/cpt
';
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
test -f /proc/rst
'
];
eval
{
run_comman
d_quiet
(
$cmd
);
};
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
test -f /proc/rst
'
];
eval
{
$self
->
cm
d_quiet
(
$cmd
);
};
die
"
vzrst module is not loaded on the target machine
\n
"
if
$@
;
}
# fixme: do we want to test if IPs exists on target node?
return
$running
;
}
sub
phase1
{
my
(
$se
ssion
,
$vmid
,
$conf
,
$rhash
,
$running
)
=
@_
;
my
(
$se
lf
,
$vmid
)
=
@_
;
logmsg
('
info
',
"
starting migration of CT
$session
->{vmid} to node '
$session
->{node}' (
$session
->{nodeip})
");
$self
->
log
('
info
',
"
starting migration of CT
$self
->{vmid} to node '
$self
->{node}' (
$self
->{nodeip})
");
if
(
$running
)
{
logmsg
('
info
',
"
container is running - using online migration
");
my
$conf
=
$self
->
{
vmconf
};
if
(
$self
->
{
running
})
{
$self
->
log
('
info
',
"
container is running - using online migration
");
}
my
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
mkdir
',
'
-p
',
$session
->
{
rootdir
}
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to make container root directory
");
my
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
mkdir
',
'
-p
',
$self
->
{
rootdir
}
];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to make container root directory
");
my
$privatedir
=
$se
ssion
->
{
privatedir
};
my
$privatedir
=
$se
lf
->
{
privatedir
};
if
(
!
$se
ssion
->
{
shared
})
{
if
(
!
$se
lf
->
{
shared
})
{
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
mkdir
',
'
-p
',
$privatedir
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to make container private directory
");
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
mkdir
',
'
-p
',
$privatedir
];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to make container private directory
");
$
rhash
->
{
undo_private
}
=
$privatedir
;
$
self
->
{
undo_private
}
=
$privatedir
;
logms
g
('
info
',
"
starting rsync phase 1
");
$self
->
lo
g
('
info
',
"
starting rsync phase 1
");
my
$basedir
=
dirname
(
$privatedir
);
$cmd
=
[
@
rsync_cmd
,
'
--sparse
',
$privatedir
,
"
root
\
@
$session
->{nodeip}:
$basedir
"
];
run_comman
d
(
$cmd
,
errmsg
=>
"
Failed to sync container private area
");
$cmd
=
[
@
{
$self
->
{
rsync_cmd
}},
'
--sparse
',
$privatedir
,
"
root
\
@
$self
->{nodeip}:
$basedir
"
];
$self
->
cm
d
(
$cmd
,
errmsg
=>
"
Failed to sync container private area
");
}
else
{
logmsg
('
info
',
"
container data is on shared storage '
$session
->{storage}'
");
$self
->
log
('
info
',
"
container data is on shared storage '
$self
->{storage}'
");
}
my
$conffile
=
PVE::OpenVZ::
config_file
(
$vmid
);
my
$newconffile
=
PVE::OpenVZ::
config_file
(
$vmid
,
$se
ssion
->
{
node
});
my
$newconffile
=
PVE::OpenVZ::
config_file
(
$vmid
,
$se
lf
->
{
node
});
my
$srccfgdir
=
dirname
(
$conffile
);
my
$newcfgdir
=
dirname
(
$newconffile
);
...
...
@@ -341,208 +132,203 @@ sub phase1 {
copy
(
$srcfn
,
$dstfn
)
||
die
"
copy '
$srcfn
' to '
$dstfn
' failed - $!
\n
";
}
if
(
$
running
)
{
if
(
$
self
->
{
running
}
)
{
# fixme: save state and quota
logms
g
('
info
',
"
start live migration - suspending container
");
$self
->
lo
g
('
info
',
"
start live migration - suspending container
");
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
chkpnt
',
$vmid
,
'
--suspend
'
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to suspend container
");
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to suspend container
");
$
rhash
->
{
undo_suspend
}
=
1
;
$
self
->
{
undo_suspend
}
=
1
;
logms
g
('
info
',
"
dump container state
");
$se
ssion
->
{
dumpfile
}
=
"
$session
->{dumpdir}/dump.
$vmid
";
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
chkpnt
',
$vmid
,
'
--dump
',
'
--dumpfile
',
$se
ssion
->
{
dumpfile
}
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to dump container state
");
$self
->
lo
g
('
info
',
"
dump container state
");
$se
lf
->
{
dumpfile
}
=
"
$self
->{dumpdir}/dump.
$vmid
";
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
chkpnt
',
$vmid
,
'
--dump
',
'
--dumpfile
',
$se
lf
->
{
dumpfile
}
];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to dump container state
");
if
(
!
$se
ssion
->
{
shared
})
{
logms
g
('
info
',
"
copy dump file to target node
");
$se
ssion
->
{
undo_copy_dump
}
=
1
;
$cmd
=
[
@scp_cmd
,
$session
->
{
dumpfile
},
"
root
\
@
$session
->{nodeip}:
$session
->{dumpfile}
"];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to copy dump file
");
if
(
!
$se
lf
->
{
shared
})
{
$self
->
lo
g
('
info
',
"
copy dump file to target node
");
$se
lf
->
{
undo_copy_dump
}
=
1
;
$cmd
=
[
@
{
$self
->
{
scp_cmd
}},
$self
->
{
dumpfile
},
"
root
\
@
$self
->{nodeip}:
$self
->{dumpfile}
"];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to copy dump file
");
logms
g
('
info
',
"
starting rsync (2nd pass)
");
$self
->
lo
g
('
info
',
"
starting rsync (2nd pass)
");
my
$basedir
=
dirname
(
$privatedir
);
$cmd
=
[
@
rsync_cmd
,
$privatedir
,
"
root
\
@
$session
->{nodeip}:
$basedir
"
];
run_comman
d
(
$cmd
,
errmsg
=>
"
Failed to sync container private area
");
$cmd
=
[
@
{
$self
->
{
rsync_cmd
}},
$privatedir
,
"
root
\
@
$self
->{nodeip}:
$basedir
"
];
$self
->
cm
d
(
$cmd
,
errmsg
=>
"
Failed to sync container private area
");
}
}
else
{
if
(
PVE::OpenVZ::
check_mounted
(
$conf
,
$vmid
))
{
logms
g
('
info
',
"
unmounting container
");
$self
->
lo
g
('
info
',
"
unmounting container
");
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
umount
',
$vmid
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to umount container
");
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to umount container
");
}
}
my
$disk_quota
=
$conf
->
{
disk_quota
}
->
{
value
};
if
(
!
defined
(
$disk_quota
)
||
(
$disk_quota
!=
0
))
{
$disk_quota
=
$session
->
{
disk_quota
}
=
1
;
logmsg
('
info
',
"
dump 2nd level quota
");
$session
->
{
quotadumpfile
}
=
"
$session
->{dumpdir}/quotadump.
$vmid
";
$cmd
=
"
vzdqdump
$vmid
-U -G -T >
"
.
PVE::Tools::
shellquote
(
$session
->
{
quotadumpfile
});
run_command_quiet
(
$cmd
,
errmsg
=>
"
Failed to dump 2nd level quota
");
if
(
!
$session
->
{
shared
})
{
logmsg
('
info
',
"
copy 2nd level quota to target node
");
$session
->
{
undo_copy_quota_dump
}
=
1
;
$cmd
=
[
@scp_cmd
,
$session
->
{
quotadumpfile
},
"
root
\
@
$session
->{nodeip}:
$session
->{quotadumpfile}
"];
run_command_quiet
(
$cmd
,
errmsg
=>
"
Failed to copy 2nd level quota dump
");
$disk_quota
=
$self
->
{
disk_quota
}
=
1
;
$self
->
log
('
info
',
"
dump 2nd level quota
");
$self
->
{
quotadumpfile
}
=
"
$self
->{dumpdir}/quotadump.
$vmid
";
$cmd
=
"
vzdqdump
$vmid
-U -G -T >
"
.
PVE::Tools::
shellquote
(
$self
->
{
quotadumpfile
});
$self
->
cmd_quiet
(
$cmd
,
errmsg
=>
"
Failed to dump 2nd level quota
");
if
(
!
$self
->
{
shared
})
{
$self
->
log
('
info
',
"
copy 2nd level quota to target node
");
$self
->
{
undo_copy_quota_dump
}
=
1
;
$cmd
=
[
@
{
$self
->
{
scp_cmd
}},
$self
->
{
quotadumpfile
},
"
root
\
@
$self
->{nodeip}:
$self
->{quotadumpfile}
"];
$self
->
cmd_quiet
(
$cmd
,
errmsg
=>
"
Failed to copy 2nd level quota dump
");
}
}
# everythin copied - make sure container is stoped
# fixme_ do we need to start on the other node first?
if
(
$
running
)
{
delete
$
rhash
->
{
undo_suspend
};
if
(
$
self
->
{
running
}
)
{
delete
$
self
->
{
undo_suspend
};
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
chkpnt
',
$vmid
,
'
--kill
'
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to kill container
");
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to kill container
");
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
umount
',
$vmid
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to umount container
");
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to umount container
");
}
# move config
die
"
Failed to move config to node '
$se
ssion
->{node}' - rename failed: $!
\n
"
die
"
Failed to move config to node '
$se
lf
->{node}' - rename failed: $!
\n
"
if
!
rename
(
$conffile
,
$newconffile
);
}
# only called if there are errors in phase1
sub
phase1_cleanup
{
my
(
$se
ssion
,
$vmid
,
$conf
,
$rhash
,
$running
)
=
@_
;
my
(
$se
lf
,
$vmid
,
$err
)
=
@_
;
logms
g
('
info
',
"
aborting phase 1 - cleanup resources
");
$self
->
lo
g
('
info
',
"
aborting phase 1 - cleanup resources
");
if
(
$rhash
->
{
undo_suspend
})
{
my
$conf
=
$self
->
{
vmconf
};
if
(
$self
->
{
undo_suspend
})
{
my
$cmd
=
[
'
vzctl
',
'
--skiplock
',
'
chkpnt
',
$vmid
,
'
--resume
'
];
run_comman
d_logerr
(
$cmd
,
errmsg
=>
"
Failed to resume container
");
$self
->
cm
d_logerr
(
$cmd
,
errmsg
=>
"
Failed to resume container
");
}
if
(
$
rhash
->
{
undo_private
})
{
logms
g
('
info
',
"
removing copied files on target node
");
my
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
rm
',
'
-rf
',
$rhash
->
{
undo_private
}
];
run_comman
d_logerr
(
$cmd
,
errmsg
=>
"
Failed to remove copied files
");
if
(
$
self
->
{
undo_private
})
{
$self
->
lo
g
('
info
',
"
removing copied files on target node
");
my
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
rm
',
'
-rf
',
$self
->
{
undo_private
}
];
$self
->
cm
d_logerr
(
$cmd
,
errmsg
=>
"
Failed to remove copied files
");
}
# fixme: that seem to be very dangerous and not needed
#my $cmd = [ @{$se
ssion->{rem_ssh}}, 'rm', '-rf', $session
->{rootdir} ];
#eval {
run_comman
d_quiet($cmd); };
#my $cmd = [ @{$se
lf->{rem_ssh}}, 'rm', '-rf', $self
->{rootdir} ];
#eval {
$self->cm
d_quiet($cmd); };
my
$newconffile
=
PVE::OpenVZ::
config_file
(
$vmid
,
$se
ssion
->
{
node
});
my
$newconffile
=
PVE::OpenVZ::
config_file
(
$vmid
,
$se
lf
->
{
node
});
my
$newcfgdir
=
dirname
(
$newconffile
);
foreach
my
$s
(
PVE::OpenVZ::
SCRIPT_EXT
)
{
my
$scriptfn
=
"
${vmid}
.
$s
";
my
$dstfn
=
"
$newcfgdir
/
$scriptfn
";
if
(
-
f
$dstfn
)
{
logms
g
('
err
',
"
unlink '
$dstfn
' failed - $!
")
if
!
unlink
$dstfn
;
$self
->
lo
g
('
err
',
"
unlink '
$dstfn
' failed - $!
")
if
!
unlink
$dstfn
;
}
}
}
sub
init_target_vm
{
my
(
$session
,
$vmid
,
$conf
)
=
@_
;
my
(
$self
,
$vmid
)
=
@_
;
my
$conf
=
$self
->
{
vmconf
};
logmsg
('
info
',
"
initialize container on remote node '
$session
->{node}'
");
$self
->
log
('
info
',
"
initialize container on remote node '
$self
->{node}'
");
my
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
vzctl
',
'
--quiet
',
'
set
',
$vmid
,
my
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
vzctl
',
'
--quiet
',
'
set
',
$vmid
,
'
--applyconfig_map
',
'
name
',
'
--save
'
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to apply config on target node
");
if
(
$se
ssion
->
{
disk_quota
})
{
logms
g
('
info
',
"
initializing remote quota
");
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
vzctl
',
'
quotainit
',
$vmid
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to initialize quota
");
logms
g
('
info
',
"
turn on remote quota
");
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
vzctl
',
'
quotaon
',
$vmid
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to turn on quota
");
logms
g
('
info
',
"
load 2nd level quota
");
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
"
(vzdqload
$vmid
-U -G -T <
"
.
PVE::Tools::
shellquote
(
$se
ssion
->
{
quotadumpfile
})
.
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to apply config on target node
");
if
(
$se
lf
->
{
disk_quota
})
{
$self
->
lo
g
('
info
',
"
initializing remote quota
");
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
vzctl
',
'
quotainit
',
$vmid
];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to initialize quota
");
$self
->
lo
g
('
info
',
"
turn on remote quota
");
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
vzctl
',
'
quotaon
',
$vmid
];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to turn on quota
");
$self
->
lo
g
('
info
',
"
load 2nd level quota
");
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
"
(vzdqload
$vmid
-U -G -T <
"
.
PVE::Tools::
shellquote
(
$se
lf
->
{
quotadumpfile
})
.
"
&& vzquota reload2
$vmid
)
"];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to load 2nd level quota
");
if
(
!
$se
ssion
->
{
running
})
{
logms
g
('
info
',
"
turn off remote quota
");
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
vzquota
',
'
off
',
$vmid
];
run_comman
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to turn off quota
");
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to load 2nd level quota
");
if
(
!
$se
lf
->
{
running
})
{
$self
->
lo
g
('
info
',
"
turn off remote quota
");
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
vzquota
',
'
off
',
$vmid
];
$self
->
cm
d_quiet
(
$cmd
,
errmsg
=>
"
Failed to turn off quota
");
}
}
}
# only called when VM is running
sub
phase2
{
my
(
$session
,
$vmid
,
$conf
,
$rhash
)
=
@_
;
$session
->
{
target_initialized
}
=
1
;
init_target_vm
(
$session
,
$vmid
,
$conf
);
my
(
$self
,
$vmid
)
=
@_
;
logmsg
('
info
',
"
starting container on remote node '
$session
->{node}'
")
;
my
$conf
=
$self
->
{
vmconf
}
;
logmsg
('
info
',
"
restore container state
");
$session
->
{
dumpfile
}
=
"
$session
->{dumpdir}/dump.
$vmid
";
my
$cmd
=
[
@
{
$session
->
{
rem_ssh
}},
'
vzctl
',
'
restore
',
$vmid
,
'
--undump
',
'
--dumpfile
',
$session
->
{
dumpfile
},
'
--skip_arpdetect
'
];
run_command_quiet
(
$cmd
,
errmsg
=>
"
Failed to restore container
");
$cmd
=
[
@
{
$session
->
{
rem_ssh
}},
'
vzctl
',
'
restore
',
$vmid
,
'
--resume
'
];
run_command_quiet
(
$cmd
,
errmsg
=>
"
Failed to resume container
");
}
$self
->
{
target_initialized
}
=
1
;
init_target_vm
(
$self
,
$vmid
);
sub
phase2_cleanup
{
my
(
$session
,
$vmid
,
$conf
,
$rhash
,
$err
)
=
@_
;
$self
->
log
('
info
',
"
starting container on remote node '
$self
->{node}'
");
};
sub
phase2_stop_vm
{
my
(
$session
,
$vmid
,
$conf
,
$rhash
);
$self
->
log
('
info
',
"
restore container state
");
$self
->
{
dumpfile
}
=
"
$self
->{dumpdir}/dump.
$vmid
";
my
$cmd
=
[
@
{
$self
->
{
rem_ssh
}},
'
vzctl
',
'
restore
',
$vmid
,
'
--undump
',
'
--dumpfile
',
$self
->
{
dumpfile
},
'
--skip_arpdetect
'
];
$self
->
cmd_quiet
(
$cmd
,
errmsg
=>
"
Failed to restore container
");
$cmd
=
[
@
{
$self
->
{
rem_ssh
}},
'
vzctl
',
'
restore
',
$vmid
,
'
--resume
'
];
$self
->
cmd_quiet
(
$cmd
,
errmsg
=>
"
Failed to resume container
");
}
# finalize
sub
phase3
{
my
(
$se
ssion
,
$vmid
,
$conf
,
$rhash
)
=
@_
;
my
(
$se
lf
,
$vmid
)
=
@_
;
if
(
!
$se
ssion
->
{
target_initialized
})
{
init_target_vm
(
$se
ssion
,
$vmid
,
$conf
);
if
(
!
$se
lf
->
{
target_initialized
})
{
init_target_vm
(
$se
lf
,
$vmid
);
}
}
# phase3 cleanup
sub
phase3_cleanup
{
my
(
$session
,
$vmid
,
$conf
,
$rhash
,
$err
)
=
@_
;
my
(
$self
,
$vmid
,
$err
)
=
@_
;
my
$conf
=
$self
->
{
vmconf
};
if
(
!
$se
ssion
->
{
shared
})
{
if
(
!
$se
lf
->
{
shared
})
{
# destroy local container data
logms
g
('
info
',
"
removing container files on local node
");
my
$cmd
=
[
'
rm
',
'
-rf
',
$se
ssion
->
{
privatedir
}
];
run_comman
d_logerr
(
$cmd
);
$self
->
lo
g
('
info
',
"
removing container files on local node
");
my
$cmd
=
[
'
rm
',
'
-rf
',
$se
lf
->
{
privatedir
}
];
$self
->
cm
d_logerr
(
$cmd
);
}
if
(
$se
ssion
->
{
disk_quota
})
{
if
(
$se
lf
->
{
disk_quota
})
{
my
$cmd
=
[
'
vzquota
',
'
drop
',
$vmid
];
run_comman
d_logerr
(
$cmd
,
errmsg
=>
"
Failed to drop local quota
");
$self
->
cm
d_logerr
(
$cmd
,
errmsg
=>
"
Failed to drop local quota
");
}
}
# final cleanup - always called
sub
final_cleanup
{
my
(
$se
ssion
,
$vmid
,
$conf
)
=
@_
;
my
(
$se
lf
,
$vmid
)
=
@_
;
logms
g
('
info
',
"
start final cleanup
");
$self
->
lo
g
('
info
',
"
start final cleanup
");
unlink
(
$session
->
{
quotadumpfile
})
if
$session
->
{
quotadumpfile
};
my
$conf
=
$self
->
{
vmconf
};
unlink
(
$se
ssion
->
{
dumpfile
})
if
$session
->
{
dumpfile
};
unlink
(
$se
lf
->
{
quotadumpfile
})
if
$self
->
{
quota
dumpfile
};
if
(
$session
->
{
undo_copy_dump
}
&&
$session
->
{
dumpfile
})
{
my
$cmd
=
[
@
{
$session
->
{
rem_ssh
}},
'
rm
',
'
-f
',
$session
->
{
dumpfile
}
];
run_command_logerr
(
$cmd
,
errmsg
=>
"
Failed to remove dump file
");
}
unlink
(
$self
->
{
dumpfile
})
if
$self
->
{
dumpfile
};
if
(
$se
ssion
->
{
undo_copy_quota_dump
}
&&
$session
->
{
quota
dumpfile
})
{
my
$cmd
=
[
@
{
$se
ssion
->
{
rem_ssh
}},
'
rm
',
'
-f
',
$session
->
{
quota
dumpfile
}
];
run_command_logerr
(
$cmd
,
errmsg
=>
"
Failed to remove 2nd level quota
dump file
");
if
(
$se
lf
->
{
undo_copy_dump
}
&&
$self
->
{
dumpfile
})
{
my
$cmd
=
[
@
{
$se
lf
->
{
rem_ssh
}},
'
rm
',
'
-f
',
$self
->
{
dumpfile
}
];
$self
->
cmd_logerr
(
$cmd
,
errmsg
=>
"
Failed to remove
dump file
");
}
if
(
$self
->
{
undo_copy_quota_dump
}
&&
$self
->
{
quotadumpfile
})
{
my
$cmd
=
[
@
{
$self
->
{
rem_ssh
}},
'
rm
',
'
-f
',
$self
->
{
quotadumpfile
}
];
$self
->
cmd_logerr
(
$cmd
,
errmsg
=>
"
Failed to remove 2nd level quota dump file
");
}
}
1
;
www/manager/VNCConsole.js
View file @
f7b706cb
...
...
@@ -292,17 +292,7 @@ Ext.define('PVE.KVMConsole', {
vm_command
(
"
resume
"
);
}
},
{
text
:
gettext
(
'
Migrate
'
),
handler
:
function
()
{
var
win
=
Ext
.
create
(
'
PVE.window.Migrate
'
,
{
vmtype
:
'
qemu
'
,
nodename
:
me
.
nodename
,
vmid
:
me
.
vmid
});
win
.
show
();
}
},
// Note: no migrate here, because we can't display migrate log
{
text
:
gettext
(
'
Console
'
),
handler
:
function
()
{
...
...
@@ -397,17 +387,8 @@ Ext.define('PVE.OpenVZConsole', {
});
}
},
{
text
:
gettext
(
'
Migrate
'
),
handler
:
function
()
{
var
win
=
Ext
.
create
(
'
PVE.window.Migrate
'
,
{
vmtype
:
'
openvz
'
,
nodename
:
me
.
nodename
,
vmid
:
me
.
vmid
});
win
.
show
();
}
},
// Note: no migrate here, because we can't display migrate log
// and openvz migrate does not work if console is open
{
text
:
gettext
(
'
Console
'
),
handler
:
function
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment