mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-30 01:26:38 +00:00
Merge pull request #2036 from immarvin/ongenimage
add lock in rh/genimage to avoid multiple genimage processes on same rootimg directory;add guard code before umount/remove mount points under rootimg directory
This commit is contained in:
commit
062ed1385a
@ -32,6 +32,7 @@ else {
|
||||
use IPC::Open3;
|
||||
use IO::Select;
|
||||
use xCAT::GlobalDef;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
eval {
|
||||
require xCAT::RemoteShellExp;
|
||||
};
|
||||
@ -2394,19 +2395,21 @@ sub acquire_lock {
|
||||
use Fcntl ":flock";
|
||||
my $tlock;
|
||||
$tlock->{path} = "/var/lock/xcat/" . $lock_name;
|
||||
open($tlock->{fd}, ">", $tlock->{path}) or return undef;
|
||||
sysopen($tlock->{fd}, $tlock->{path}, POSIX::O_CREAT | POSIX::O_WRONLY) or return undef;
|
||||
unless ($tlock->{fd}) { return undef; }
|
||||
|
||||
if ($nonblock_mode) {
|
||||
flock($tlock->{fd}, LOCK_EX | LOCK_NB) or return undef;
|
||||
} else {
|
||||
flock($tlock->{fd}, LOCK_EX) or return undef;
|
||||
}
|
||||
print { $tlock->{fd} } $$;
|
||||
|
||||
truncate $tlock->{fd},0;
|
||||
syswrite $tlock->{fd} ,$$;
|
||||
$tlock->{fd}->autoflush(1);
|
||||
return $tlock;
|
||||
}
|
||||
|
||||
|
||||
#---------------------
|
||||
|
||||
=head3 release_lock
|
||||
@ -4781,4 +4784,45 @@ sub get_nmapversion {
|
||||
return $nmap_version;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 acquire_lock_imageop
|
||||
acquire lock for the image related operations on specific rootimg dir
|
||||
the image related operation includes genimage,packimage,rmimage...
|
||||
Arguments:
|
||||
$rootimg_dir: the full path of osimage rootimage dir
|
||||
lock mode: 0-block, 1-non-block
|
||||
Returns:
|
||||
a list with format (<error code>, <error messgae> or <lock handler>)
|
||||
|
||||
the <error code>: 0 on success, 1 on fail
|
||||
the <error message>: available on fail
|
||||
the <lock handler>: available on success
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub acquire_lock_imageop {
|
||||
my $self=shift;
|
||||
my $rootimg_dir=shift;
|
||||
my $NON_BLOCK=shift;
|
||||
|
||||
$NON_BLOCK=1 unless(defined $NON_BLOCK);
|
||||
my $mylockfile=Cwd::realpath($rootimg_dir);
|
||||
my $mymd5=md5_hex($mylockfile);
|
||||
$mylockfile=~s/\//./g;
|
||||
$mylockfile=$mylockfile.".".$mymd5;
|
||||
|
||||
my $lock = xCAT::Utils->acquire_lock("$mylockfile", $NON_BLOCK);
|
||||
unless ($lock){
|
||||
my $pidfd;
|
||||
open($pidfd,"<","/var/run/lock/xcat/$mylockfile");
|
||||
my $pid=<$pidfd>;
|
||||
close($pidfd);
|
||||
return (1, "failed to acquire lock, seems there is another genimage/packimage/rmimage process $pid running on root image dir \"$rootimg_dir\"");
|
||||
}
|
||||
return (0,$lock);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -37,6 +37,8 @@ use File::Path;
|
||||
use xCAT::Utils;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::SvrUtils;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
@ -97,7 +99,8 @@ sub process_request {
|
||||
my $provmethod;
|
||||
my $help;
|
||||
my $version;
|
||||
|
||||
my $lock;
|
||||
|
||||
GetOptions(
|
||||
"profile|p=s" => \$profile,
|
||||
"arch|a=s" => \$arch,
|
||||
@ -199,6 +202,14 @@ sub process_request {
|
||||
}
|
||||
$rootimg_dir = "$destdir/rootimg";
|
||||
|
||||
|
||||
my $retcode;
|
||||
($retcode,$lock)=xCAT::Utils->acquire_lock_imageop($rootimg_dir);
|
||||
if($retcode){
|
||||
$callback->({ error => ["$lock"], errorcode => [1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $distname = $osver;
|
||||
until (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) {
|
||||
chop($distname);
|
||||
|
@ -10,9 +10,11 @@ BEGIN
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
use Getopt::Long;
|
||||
use File::Path;
|
||||
use Cwd qw(realpath);
|
||||
use xCAT::Utils;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::DBobjUtils;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
@ -41,7 +43,8 @@ sub process_request {
|
||||
my $xcatdef;
|
||||
my $imagename;
|
||||
my $imagedir;
|
||||
|
||||
my $lock;
|
||||
|
||||
if (!xCAT::Utils->isLinux()) {
|
||||
$callback->({ error => ["The rmimage command is only supported on Linux."], errorcode => [1] });
|
||||
return;
|
||||
@ -175,8 +178,17 @@ sub process_request {
|
||||
$callback->({ error => ["Image directory $imagedir does not exist"], errorcode => [1] });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# Doing this extra check now because we now have a method and arch from either the node or the image name.
|
||||
my $retcode;
|
||||
($retcode,$lock)=xCAT::Utils->acquire_lock_imageop("$imagedir/rootimg");
|
||||
if($retcode){
|
||||
$callback->({ error => ["$lock"], errorcode => [1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
# Doing this extra check now because we now have a method and arch from either the node or the image namee
|
||||
if (($method eq "sysclone") && ($arch ne "s390x")) {
|
||||
|
||||
# Only supporting removing sysclone images for s390x at this time.
|
||||
@ -184,17 +196,28 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
|
||||
my @filestoremove = ("$imagedir/rootimg.gz", "$imagedir/kernel", "$imagedir/initrd-stateless.gz", "$imagedir/initrd-statelite.gz");
|
||||
my @filestoremove = ("$imagedir/kernel", "$imagedir/initrd-stateless.gz", "$imagedir/initrd-statelite.gz");
|
||||
my @rootimgtars=glob "$imagedir/rootimg.{tar,cpio}.{xz,gz}";
|
||||
push @filestoremove,@rootimgtars;
|
||||
#unmount all the mount points under rootimg directory
|
||||
#to avoid removing the directory/files on management node by mistake
|
||||
$realimagedir=realpath("$imagedir/rootimg");
|
||||
my @mntptlist;
|
||||
my $FILEHD=undef;
|
||||
open($FILEHD,"<","/proc/mounts");
|
||||
while(<$FILEHD>){
|
||||
my @arr=split / /;
|
||||
push @mntptlist,$arr[1] if(substr($arr[1],0,length($realimagedir)) eq $realimagedir);
|
||||
}
|
||||
close($FILEHD);
|
||||
foreach my $mntpt (@mntptlist){
|
||||
system("umount -l $mntpt >/dev/null 2>&1")
|
||||
}
|
||||
|
||||
#some rpms like atftp mount the rootimg/proc to /proc, we need to make sure rootimg/proc is free of junk
|
||||
`umount -l $imagedir/rootimg/proc 2>&1 1>/dev/null`;
|
||||
|
||||
# also umount the rootimg/sys
|
||||
`umount -l $imagedir/rootimg/sys 2>&1 1>/dev/null`;
|
||||
|
||||
# umount the rootimg/dev
|
||||
my $devmount = `cat /proc/mounts |grep "$imagedir/rootimg/dev"`;
|
||||
if ($devmount) {
|
||||
my $devmount = system("findmnt $imagedir/rootimg/dev/ >/dev/null 2>&1");
|
||||
if (!$devmount) {
|
||||
xCAT::Utils->runcmd("umount -l $imagedir/rootimg/dev");
|
||||
if ($?) {
|
||||
$callback->({ error => ["$imagedir/rootimg/dev mount on /dev, and can't umount. remove $imagename will lead to unpredictable result, please umount manualy before try again"], errorcode => [1] });
|
||||
|
@ -19,6 +19,8 @@ use File::Temp qw/mkdtemp/;
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../imgutils";
|
||||
use imgutils;
|
||||
use xCAT::Utils;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
|
||||
#use strict;
|
||||
Getopt::Long::Configure("bundling");
|
||||
@ -66,6 +68,8 @@ my $tempfile;
|
||||
my $prompt;
|
||||
my $ignorekernelchk;
|
||||
my $noupdate;
|
||||
my $lock;
|
||||
|
||||
|
||||
|
||||
sub xdie {
|
||||
@ -112,17 +116,30 @@ sub mount_chroot {
|
||||
|
||||
sub umount_chroot {
|
||||
my $rootimage_dir = shift;
|
||||
if ($rootimage_dir eq "") {
|
||||
|
||||
$rootimage_dir=realpath($rootimage_dir);
|
||||
if ($rootimage_dir eq "/") {
|
||||
print "\n\n\n\nWARNING: /proc and /sys may still be mounted in the rootimgdir\n\n\n\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#unmount all the mount points under rootimg directory
|
||||
#to avoid removing the direcoty/files on managemment node by mistake
|
||||
my @mntptlist;
|
||||
my $FILEHD=undef;
|
||||
open($FILEHD,"<","/proc/mounts");
|
||||
while(<$FILEHD>){
|
||||
my @arr=split / /;
|
||||
push @mntptlist,$arr[1] if(substr($arr[1],0,length($rootimage_dir)) eq $rootimage_dir);
|
||||
}
|
||||
close($FILEHD);
|
||||
foreach my $mntpt (@mntptlist){
|
||||
system("umount -l $mntpt >/dev/null 2>&1")
|
||||
}
|
||||
|
||||
if (majversion($osver) > 6) {
|
||||
system("umount -l $rootimage_dir/proc");
|
||||
system("umount -l $rootimage_dir/sys");
|
||||
|
||||
#system("umount -l $rootimage_dir/dev");
|
||||
system("rm -rf $rootimage_dir/dev/*");
|
||||
#only remove the /dev in rootimg directory if it is not a mount point
|
||||
system("findmnt $rootimage_dir/dev/ >/dev/null 2>&1 || rm -rf $rootimage_dir/dev/*");
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,6 +211,7 @@ $srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_o
|
||||
$destdir = "$installroot/netboot/$osver/$arch/$profile" unless ($destdir);
|
||||
$updates{'rootimgdir'} = $destdir if ($tempfile);
|
||||
|
||||
|
||||
$rootimg_dir = "$destdir/rootimg";
|
||||
|
||||
$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels";
|
||||
@ -348,6 +366,14 @@ unless ($onlyinitrd) {
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $retcode;
|
||||
($retcode,$lock)=xCAT::Utils->acquire_lock_imageop($rootimg_dir);
|
||||
if($retcode){
|
||||
print "$lock";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
mount_chroot($rootimg_dir);
|
||||
|
||||
my %pkg_hash = imgutils::get_package_names($pkglist);
|
||||
|
Loading…
x
Reference in New Issue
Block a user