add code to support "/var/" and "/var/tmp/logs" as parent&child directory;

some bug fix in rc.statelite

    fix one bug when recovering the files in litefile.save
    update the example for parselitefile subroutine

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@8080 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
mxi1 2010-11-06 07:36:48 +00:00
parent 4f3986a605
commit 7ccb6dc32e
2 changed files with 160 additions and 123 deletions

View File

@ -219,26 +219,36 @@ sub process_request {
return;
}
# validate the options for all litefile entries
# if there is any scenario not supported, the command exits
foreach my $entry (keys %hashNew) {
my @tmp = split (/\s+/, $entry);
my $f = $tmp[1];
if ($hashNew{$entry}) {
if ( $tmp[0] =~ m/ro/ or $tmp[0] =~ m/con/) {
$callback->({error=>[qq{the parent directory should not be with "ro" or "con" as its option}], errorcode=>[1]});
if ( $tmp[0] =~ m/ro$/ or $tmp[0] =~ m/con$/) {
$callback->({error=>[qq{the directory "$f" should not be with "ro" or "con" as its option}], errorcode=>[1]});
return;
}
foreach my $child ( @{$hashNew{$entry}} ) {
my @tmpc = split (/\s+/, $child);
my $f = $tmp[1];
my $fc = $tmpc[1];
if ( ($tmp[0] =~ m/link/) and ( $tmpc[0] !~ m/link/) ) {
$callback->({error=>[qq{Based on the option of $f, $fc can only use "link"-headed options}], errorcode=> [ 1]});
return;
if ($tmp[0] =~ m/link/) {
if ($tmpc[0] eq "link,ro") {
$callback->({error=>[qq{Based on the option of $f, $fc should not use "link,ro" as its option}], errorcode=> [1]});
return;
}
if ($tmpc[0] !~ m/link/) {
$callback->({error=>[qq{Based on the option of $f, $fc can only use "link"-based options}], errorcode=> [1]});
return;
}
} else {
if ($tmpc[0] =~ m/link/) {
$callback->({error=>[qq{Based on the option of $f, $fc should not use "link"-based options}], errorcode=>[1]});
return;
}
}
if ( ($tmp[0] !~ m/link/) and ($tmpc[0] =~ m/link/) ) {
$callback->({error=>[qq{$fc shouldnot use "link"-headed options }], errorcode=> [ 1]});
return;
}
if ( ($tmp[0] eq qq{persistent}) and ($tmpc[0] ne qq{persistent}) ) {
if ( ($tmp[0] =~ m{persistent}) and ($tmpc[0] !~ m{persistent}) ) {
# TODO: if the parent is "persistent", the child can be ro/persistent/rw/con
$callback->({error=>["$fc should have persistent option like $f "], errorcode=> [ 1]});
return;
}
@ -287,10 +297,12 @@ sub process_request {
}
}
# there's one parent directory, whose option is different from the old one
unless ($entry[1] eq $oldentry[0]) {
recoverFiles($rootimg_dir, \@oldentry, $callback);
# if its children items exist, we need to copy the backup files from .statebackup to the rootfs,
if ($hashSaved{$line}) {
$verbose && $callback->({info=>["$f has sub items in the litefile table."]});
$verbose && $callback->({info=>["$f has child file/directory in the litefile table."]});
my $childrenRef = $hashSaved{$line};
foreach my $child (@{$childrenRef}) {
# recover them from .statebackup to $rootimg_dir
@ -305,6 +317,13 @@ sub process_request {
xCAT::Utils->runcmd("rm -rf $destf", 0, 1);
}
# maybe the dir of $destf doesn't exist, so we will create one
my $dirDestf = dirname $destf;
unless ( -d $dirDestf ) {
$verbose && $callback->({info=>["mkdir -p $dirDestf"]});
xCAT::Utils->runcmd("mkdir -p $dirDestf", 0, 1);
}
if ( -e $srcf ) {
$verbose && $callback->({info=>["recovering from $srcf to $destf"]});
xCAT::Utils->runcmd("cp -r -a $srcf $destf", 0, 1);
@ -316,7 +335,7 @@ sub process_request {
# recover the children
if ($hashSaved{$line}) {
$verbose && $callback->({info=>["$f has sub items in the litefile table."]});
$verbose && $callback->({info=>["$f has child file/directory in the litefile table."]});
my $childrenRef = $hashSaved{$line};
foreach my $child (@{$childrenRef}) {
my @tmpc = split (/\s+/, $child);
@ -412,26 +431,28 @@ In order to handle such a scenario, one hash is generated to show the hirarachy
For example, one array with entry names is used as the input:
my @entries = (
"imagename bind,persistent /var/",
"imagename bind /var/tmp/",
"imagename tmpfs,rw /root/",
"imagename tmpfs,rw /root/.bashrc",
"imagename tmpfs,rw /root/test/",
"imagename bind /etc/resolv.conf",
"imagename bind /var/run/"
"imagename persistent /var/",
"imagename tempfs /var/tmp/",
"imagename link /root/",
"imagename link /root/.bashrc",
"imagename link /root/test/",
"imagename link /root/second/third",
"imagename tempfs /etc/resolv.conf",
"imagename tempfs /var/run/"
);
Then, one hash will generated as:
%hashentries = {
'bind,persistent /var/' => [
'bind /var/tmp/',
'bind /var/run/'
],
'bind /etc/resolv.conf' => undef,
'tmpfs,rw /root/' => [
'tmpfs,rw /root/.bashrc',
'tmpfs,rw /root/test/'
]
};
'persistent /var/' => [
'tempfs /var/tmp/',
'tempfs /var/run/'
],
'tempfs /etc/resolv.conf' => undef,
'link /root/' => [
'link /root/.bashrc',
'link /root/test/',
'link /root/second/third"
]
};
Arguments:
one array with entrynames,
@ -451,24 +472,27 @@ sub parseLiteFiles {
foreach (@entries) {
my $entry = $_;
my @str = split /\s+/, $entry;
shift @str;
shift @str; # remove the imgname in @entries
$entry = join "\t", @str;
my $file = $str[1];
chop $file if ($file =~ m{/$});
unless (exists $dhref->{"$entry"}) {
my $parent = dirname($file);
# to see whether $parent exists in @entries or not
unless ($parent =~ m/\/$/) {
$parent .= "/";
my $parent = dirname $file;
my @res;
my $found = 0;
while($parent ne "/") {
# to see whether $parent exists in @entries or not
$parent .= "/" unless ($parent =~ m/\/$/);
@res = grep {$_ =~ m/\Q$parent\E$/} @entries;
$found = scalar @res;
last if ($found eq 1);
$parent = dirname $parent;
}
#my $found = grep $_ =~ m/\Q$parent\E$/, @entries;
my @res = grep {$_ =~ m/\Q$parent\E$/} @entries;
my $found = scalar @res;
if($found eq 1) { # $parent is found in @entries
# handle $res[0];
my @tmpresentry=split /\s+/, $res[0];
shift @tmpresentry;
shift @tmpresentry; # remove the imgname in @tmpresentry
$res[0] = join "\t", @tmpresentry;
chop $parent;
my @keys = keys %{$dhref};
@ -497,7 +521,7 @@ sub recoverFiles {
#$callback->({info => ["! updating $f ..."]});
if ($oldentry->[0] eq "tmpfs,rw" or $oldentry->[0] eq "ro" ) {
if ($oldentry->[0] =~ m{^link}) {
my $target = $rootimg_dir . $f;
if (-l $target) { #not one directory
my $location = readlink $target;
@ -546,9 +570,9 @@ sub liteItem {
my @entry = split (/\s+/, $item);
my $f = $entry[1];
my $f = $entry[1]; # file name
my $rif = $rootimg_dir . $f;
my $rif = $rootimg_dir . $f; # the file's location in rootimg_dir
my $d = dirname($f);
if ($entry[0] =~ m/link/) {
@ -636,7 +660,7 @@ sub liteItem {
} else {
# since its parent directory has been linked to .default and .statelite/tmpfs/,
# what we only to do is to check it exists in .default directory
# what we need to do is only to check whether it exists in .default directory
if($f =~ m{/$}) { # one directory
unless ( -d "$rootimg_dir/.default$f" ) {
if (-e "$rootimg_dir/.default$f") {
@ -648,6 +672,7 @@ sub liteItem {
}else { # only one file
my $fdir = dirname($f);
unless ( -d "$rootimg_dir/.default$fdir") {
$verbose && $callback->({info=>["mkdir -p $rootimg_dir/.default$fdir"]});
xCAT::Utils->runcmd("mkdir -p $rootimg_dir/.default$fdir", 0, 1);
}
unless( -e "$rootimg_dir/.default$f") {

View File

@ -179,7 +179,6 @@ ResolveLinks () {
done
num=${#ELIST[@]}
# put all the child entry to the end of the ELIST array
for ((i=0;i<$num;i++)); do
set -- ${ELIST[$i]}
type=$1
@ -187,21 +186,34 @@ ResolveLinks () {
parent="`dirname $path`/"
efound=0
for ((j=0;j<$num;j++)); do
set -- ${ELIST[$j]}
jtype=$1
jpath=$2
if [ "$parent" = "$jpath" ]; then
efound=1
fi
while [ "$parent" != "//" ]; do
for ((j=0;j<$num;j++)); do
set -- ${ELIST[$j]}
jtype=$1
jpath=$2
if [ "$parent" = "$jpath" ]; then
efound=1
break 2
fi
done
parent="`dirname $parent`/"
done
if [ "$efound" = "1" ]; then
# put it into CLIST
CLIST[$[ ${#CLIST[@]} ]]=${ELIST[$i]}
else
# put it into PLIST
PLIST[$[ ${#PLIST[@]} ]]=${ELIST[$i]}
pfound=0
pnum=${#PLIST[@]}
for ((k=0;k<$pnum;k++)); do
if [ "${PLIST[$k]}" = "${path}" ]; then
pfound=1
fi
done
if [ "$pfound" = "0" ]; then
# put it into PLIST
PLIST[$[ ${#PLIST[@]} ]]=${ELIST[$i]}
fi
fi
done
@ -227,7 +239,7 @@ ProcessType () {
#TYPE=$3 # type of file
#isChild=$4 # child = 1, parent = 0
PPATH=`dirname ${2}`
PPATH=`/usr/bin/dirname ${2}`
# every type has to have a base dir in tmpfs
if [ ! -d ${TMPFS}${PPATH} ] && [ ! -L ${TMPFS}${PPATH} ]; then
@ -238,24 +250,27 @@ ProcessType () {
case "${3}" in
link) # the previous name is tmpfs,rw
if [ -d ${TMPFS}${2} ]; then
cp -r -a ${1}* ${TMPFS}${2}
/bin/cp -r -a ${1}* ${TMPFS}${2}
echo "cp -r -a ${1}* ${TMPFS}${2}" >>$LOG
else
cp -r -a ${1} ${TMPFS}${2}
/bin/cp -r -a ${1} ${TMPFS}${2}
echo "cp -r -a ${1} ${TMPFS}${2}" >>$LOG
fi
# the link will already be in place on the image, so nothing else to do!
# the link has already be in place on the image, so nothing else to do!
;;
link,ro)
# need to make sure directory exists:
# need to make sure its parent directory exists:
if [ ! -d ${TMPFS}${PPATH} ]; then
mkdir -p ${TMPFS}${PPATH} >>$LOG 2>&1
/bin/mkdir -p ${TMPFS}${PPATH} >>$LOG 2>&1
fi
TARGET=`echo ${TMPFS}${2} | sed -e 's/\/$//'`
LINK=`echo ${1} | sed -e "s/^\/sysroot//"`
echo "ln -sf ${LINK} ${TARGET}" >>$LOG 2>&1
ln -sf ${LINK} ${TARGET} >>$LOG 2>&1
if [ "${4}" = "0" ]; then
TARGET=`echo ${TMPFS}${2} | /bin/sed -e 's/\/$//'`
LINK=`echo ${1} | /bin/sed -e "s/^\/sysroot//"`
echo "ln -sf ${LINK} ${TARGET}" >>$LOG 2>&1
/bin/ln -sf ${LINK} ${TARGET} >>$LOG 2>&1
fi
;;
link,persistent)
# everything from root image points to tmpfs
@ -264,151 +279,148 @@ ProcessType () {
# make tree in persistent and tmpfs
# need to check whether the option of its parent direcotry is persistent or not
TMPDIR=`dirname ${2}`
if [ ! -e ${PERSISTENT}${TMPDIR} ]; then
mkdir -p ${PERSISTENT}${TMPDIR} >>$LOG 2>&1
echo "mkdir -p ${PERSISTENT}${TMPDIR}" >>$LOG 2>&1
PATH=${2}
MOUNT=${1}
# if target is a directory, then remove it first,
# otherwise, the link will be created under this dir instead of replacing it.
# whack of trailing / for persistent directories:
PATH=`echo ${PATH} | /bin/sed -e 's/\/$//'`
TARGET=${TMPFS}${PATH}
if [ -d ${TARGET} ]; then
echo "rm -Rf ${TARGET}" >>$LOG 2>&1
/bin/rm -Rf ${TARGET} 2>&1 >>$LOG
fi
if [ ! -d ${PERSISTENT}${PPATH} ]; then
/bin/mkdir -p ${PERSISTENT}${PPATH} 2>&1 >>$LOG
echo "mkdir -p ${PERSISTENT}${PPATH}" >>$LOG
fi
# if the file/directory doesn't exist, copy it over to persistent
if [ ! -e ${PERSISTENT}${PATH} ]; then
echo "cp -r -a ${MOUNT} ${PERSISTENT}${PATH}" >>$LOG 2>&1
/bin/cp -r -a ${MOUNT} ${PERSISTENT}${PATH}
fi
if [ "$isChild" = "1" ]; then
num=${#PLIST[@]}
echo "${PPATH}: "
for ((i=0;i<$num; i++)); do
set -- ${PLIST[$i]}
itype=$1
ipath=$2
if [ "$PPATH" = "$ipath" ]; then
if [[ ! "$itype" =~ "persistent*" ]]; then
if [ ! -e ${PERSISTENT}${2} ]; then
echo "cp -r -a ${1} ${PERSISTENT}${2}" >>$LOG 2>&1
cp -r -a ${1} ${PERSISTENT}${2} 2>&1 >>$LOG
fi
echo "${itype}"
if [ "$itype" = "link,persistent" ]; then
# mount it to ${TARGET}
echo "mount --bind ${PERSISTENT}${2} ${TARGET}" >>$LOG 2>&1
mount --bind ${PERSISTENT}${2} ${TARGET}
echo "mount --bind ${PERSISTENT}${PATH} ${TARGET}" >>$LOG 2>&1
/bin/mount --bind ${PERSISTENT}${PATH} ${TARGET}
fi
fi
done
else
if [[ ! -d ${PERSISTENT}${PPATH} && ! -d `readlink -m ${PERSISTENT}${PPERS}` ]]; then
# unless the entry is one directory or one link to the directory
rm -rf ${PERSISTENT}${PPERS} >>$LOG 2>&1
mkdir -p ${PERSISTENT}${PPERS} >>$LOG 2>&1
echo "mkdir -p ${PERSISTENT}${PPERS}" >>$LOG 2>&1
fi
# if the file doesn't exist, then copy it over to persistent
if [ ! -e ${PERSISTENT}${2} ]; then
# if its not there, then take it from something else
echo "cp -r -a ${1} ${PERSISTENT}${2}" >>$LOG 2>&1
cp -r -a ${1} ${PERSISTENT}${2} 2>&1 >>$LOG 2>&1
fi
# if target is a directory, then remove it first,
# otherwise, the link will be created under this dir instead of replacing it.
# whack of trailing / for persistent directories:
TARGET=`echo ${TMPFS}${2} | sed -e 's/\/$//'`
if [ -d ${TARGET} ]; then
echo "rm -Rf ${TARGET}" >>$LOG 2>&1
rm -Rf ${TARGET} 2>&1 >>$LOG
fi
# finally make the tmpfs link point to the persistent file
# you have to get rid of the /sysroot in the beginning
# so that when the chroot happens the link is valid.
LINK=`echo ${PERSISTENT}${2} | sed -e 's/^\/sysroot//'`
LINK=`echo ${PERSISTENT}${PATH} | /bin/sed -e 's/^\/sysroot//'`
echo "ln -sf ${LINK} ${TARGET}" >>$LOG
ln -sf ${LINK} ${TARGET} >>$LOG 2>&1
/bin/ln -sf ${LINK} ${TARGET} >>$LOG 2>&1
fi
;;
link,con)
echo "cat ${1} >>${TMPFS}${2}" >>$LOG 2>&1
cat ${1} >>${TMPFS}${2} 2>&1
/bin/cat ${1} >>${TMPFS}${2} 2>&1
;;
con)
# there's one more option to indicate the con is at the end
if [ "${5}" = "1" ]; then
# mount the file with "--bind" option
echo "mount --bind ${TMPFS}${2} /sysroot${2}" >>$LOG
mount --bind ${TMPFS}${2} /sysroot${2} >> $LOG 2>&1
/bin/mount --bind ${TMPFS}${2} /sysroot${2} >> $LOG 2>&1
else
echo "cat ${1} >>${TMPFS}${2}" >>$LOG 2>&1
cat ${1} >>${TMPFS}${2} 2>&1
/bin/cat ${1} >>${TMPFS}${2} 2>&1
fi
;;
tempfs) # the default option, same as "tempfs" and "NULL"
ORIG=`echo ${2} | sed -e 's/\/$//'`
ORIG=`echo ${2} | /bin/sed -e 's/\/$//'`
TARGET=`echo ${1}`
if [ -d ${TMPFS}${2} ]; then
cp -r -a ${1}* ${TMPFS}${2}
/bin/cp -r -a ${1}* ${TMPFS}${2}
echo "cp -r -a ${1}* ${TMPFS}${2}" >>$LOG
else
cp -r -a ${1} ${TMPFS}${2}
/bin/cp -r -a ${1} ${TMPFS}${2}
echo "cp -r -a ${1} ${TMPFS}${2}" >>$LOG
fi
if [ "$isChild" = "0" ]; then
echo "mount --bind ${TMPFS}${2} /sysroot${ORIG}" >>$LOG
mount --bind ${TMPFS}${2} /sysroot${ORIG}>>$LOG 2>&1
/bin/mount --bind ${TMPFS}${2} /sysroot${ORIG}>>$LOG 2>&1
fi
;;
rw) # the default option, same as "tempfs" and "NULL"
ORIG=`echo ${2} | sed -e 's/\/$//'`
ORIG=`echo ${2} | /bin/sed -e 's/\/$//'`
TARGET=`echo ${1}`
if [ -d ${TMPFS}${2} ]; then
cp -r -a ${1}* ${TMPFS}${2}
/bin/cp -r -a ${1}* ${TMPFS}${2}
echo "cp -r -a ${1}* ${TMPFS}${2}" >>$LOG
else
cp -r -a ${1} ${TMPFS}${2}
/bin/cp -r -a ${1} ${TMPFS}${2}
echo "cp -r -a ${1} ${TMPFS}${2}" >>$LOG
fi
if [ "$isChild" = "0" ]; then
echo "mount --bind ${TMPFS}${2} /sysroot${ORIG}" >>$LOG
mount --bind ${TMPFS}${2} /sysroot${ORIG}>>$LOG 2>&1
/bin/mount --bind ${TMPFS}${2} /sysroot${ORIG}>>$LOG 2>&1
fi
;;
persistent)
if [ ! -d ${PERSISTENT}${PPATH} ]; then
mkdir -p ${PERSISTENT}${PPATH}
/bin/mkdir -p ${PERSISTENT}${PPATH}
echo "mkdir -p ${PERSISTENT}${PPATH}" >>$LOG
fi
# if the file doesn't exist, then copy it over to persistent
if [ ! -e ${PERSISTENT}${2} ]; then
echo "cp -r -a ${1} ${PERSISTENT}${2}" >>$LOG
cp -r -a ${1} ${PERSISTENT}${2} 2>&1 >>$LOG
/bin/cp -r -a ${1} ${PERSISTENT}${2} 2>&1 >>$LOG
fi
ORIG=`echo ${2} | sed -e 's/\/$//'`
ORIG=`echo ${2} | /bin/sed -e 's/\/$//'`
TARGET=`echo ${PERSISTENT}${2}`
echo "mount --bind ${TARGET} /sysroot/${ORIG}" >>$LOG
mount --bind ${TARGET} /sysroot/${ORIG}>>$LOG 2>&1
/bin/mount --bind ${TARGET} /sysroot/${ORIG}>>$LOG 2>&1
;;
ro)
# need to make sure directory exists:
if [ ! -d ${TMPFS}${PPATH} ]; then
mkdir -p ${TMPFS}${PPATH} >>$LOG 2>&1
/bin/mkdir -p ${TMPFS}${PPATH} >>$LOG 2>&1
fi
# before mount, need to check whether it exists or not
STRPATH="${TMPFS}${2}"
STRLEN=${#STRPATH}
CHAREND=`echo ${STRPATH} | cut -c${STRLEN}`
CHAREND=`echo ${STRPATH} | /bin/cut -c${STRLEN}`
if [ "${CHAREND}" = "/" ]; then # it is one directory
if [ ! -d ${STRPATH} ]; then
rm -rf ${STRPATH}
mkdir ${STRPATH}
/bin/rm -rf ${STRPATH}
/bin/mkdir ${STRPATH}
fi
else
if [ ! -f ${STRPATH} ]; then
rm -rf ${STRPATH}
touch ${STRPATH}
/bin/rm -rf ${STRPATH}
/bin/touch ${STRPATH}
fi
fi
echo "mout --bind -o ro ${1} ${MNTDIR}${2}" >>$LOG 2>&1
mount --bind -o ro ${1} ${MNTDIR}${2} >>$LOG 2>&1
/bin/mount --bind -o ro ${1} ${MNTDIR}${2} >>$LOG 2>&1
;;
*)
;;
@ -424,15 +436,15 @@ FindFile () {
type=$2
isChild=$3
FOUND=0
for DIR in `cat ${SYNCTREE}` ;do
for DIR in `/bin/cat ${SYNCTREE}` ;do
DIR=${DIR/:/}
if [ -e ${TREEMOUNT}/${DIR}${path} ]; then
FOUND=1 # we found it!
if [ -d ${TREEMOUNT}/${DIR}${path} ] && [ "0" -eq `ls -A ${TREEMOUNT}/${DIR}${path} |wc -l` ]; then
if [ -d ${TREEMOUNT}/${DIR}${path} ] && [ "0" -eq `/bin/ls -A ${TREEMOUNT}/${DIR}${path} |/usr/bin/wc -l` ]; then
FOUND=0
else
ProcessType ${TREEMOUNT}/${DIR}${path} ${path} ${type} ${isChild}
if [[ "${2}" -eq "link,con" ]] || [[ "${2}" -eq "con" ]]; then
if [ "${2}" = "link,con" ] || [ "${2}" = "con" ]; then
continue
else
break
@ -473,7 +485,7 @@ MountTrees
ResolveLinks
# make sure mtab points to the right place:
ln -sf /proc/mounts ${TMPFS}/etc/mtab
/bin/ln -sf /proc/mounts ${TMPFS}/etc/mtab
# catch all hack for debugging:
#cp -r -a ${DEFAULT}/* /.snapshot/tmpfs/