From: Kai Kang <[email protected]> When perform useradd during populate sysroot, it locks files passwd.lock and group.lock at same time. And then it meets a dead lock issue randomly.
Use flock to reslove it by using an universal lock file for all the user and group related operations. [YOCTO #9022] Signed-off-by: Kai Kang <[email protected]> --- meta/classes/useradd.bbclass | 6 +- meta/classes/useradd_base.bbclass | 186 ++++++++------------------------------ 2 files changed, 40 insertions(+), 152 deletions(-) diff --git a/meta/classes/useradd.bbclass b/meta/classes/useradd.bbclass index c960656..0a6f2be 100644 --- a/meta/classes/useradd.bbclass +++ b/meta/classes/useradd.bbclass @@ -57,7 +57,7 @@ if test "x`echo $GROUPADD_PARAM | tr -d '[:space:]'`" != "x"; then opts=`echo "$GROUPADD_PARAM" | cut -d ';' -f 1` remaining=`echo "$GROUPADD_PARAM" | cut -d ';' -f 2-` while test "x$opts" != "x"; do - perform_groupadd "$SYSROOT" "$OPT $opts" 10 + perform_groupadd "$SYSROOT" "$OPT $opts" if test "x$opts" = "x$remaining"; then break fi @@ -73,7 +73,7 @@ if test "x`echo $USERADD_PARAM | tr -d '[:space:]'`" != "x"; then opts=`echo "$USERADD_PARAM" | cut -d ';' -f 1` remaining=`echo "$USERADD_PARAM" | cut -d ';' -f 2-` while test "x$opts" != "x"; do - perform_useradd "$SYSROOT" "$OPT $opts" 10 + perform_useradd "$SYSROOT" "$OPT $opts" if test "x$opts" = "x$remaining"; then break fi @@ -89,7 +89,7 @@ if test "x`echo $GROUPMEMS_PARAM | tr -d '[:space:]'`" != "x"; then opts=`echo "$GROUPMEMS_PARAM" | cut -d ';' -f 1` remaining=`echo "$GROUPMEMS_PARAM" | cut -d ';' -f 2-` while test "x$opts" != "x"; do - perform_groupmems "$SYSROOT" "$OPT $opts" 10 + perform_groupmems "$SYSROOT" "$OPT $opts" if test "x$opts" = "x$remaining"; then break fi diff --git a/meta/classes/useradd_base.bbclass b/meta/classes/useradd_base.bbclass index ab3cd35..7c1cc13 100644 --- a/meta/classes/useradd_base.bbclass +++ b/meta/classes/useradd_base.bbclass @@ -4,7 +4,7 @@ # The following functions basically have similar logic. # *) Perform necessary checks before invoking the actual command -# *) Invoke the actual command, make retries if necessary +# *) Invoke the actual command with flock # *) Error out if an error occurs. # Note that before invoking these functions, make sure the global variable @@ -12,65 +12,32 @@ perform_groupadd () { local rootdir="$1" - local opts="$2" - local retries="$3" - bbnote "${PN}: Performing groupadd with [$opts] and $retries times of retry" + local opts=`echo $2 | sed s/\'/\"/g` + bbnote "${PN}: Performing groupadd with [$opts]" + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO groupadd $opts\' || true local groupname=`echo "$opts" | awk '{ print $NF }'` - local group_exists="`grep "^$groupname:" $rootdir/etc/group || true`" + local group_exists=`grep "^$groupname:" $rootdir/etc/group` if test "x$group_exists" = "x"; then - local count=0 - while true; do - eval $PSEUDO groupadd $opts || true - group_exists="`grep "^$groupname:" $rootdir/etc/group || true`" - if test "x$group_exists" = "x"; then - bbwarn "${PN}: groupadd command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - bbfatal "${PN}: Tried running groupadd command $retries times without success, giving up" - fi - sleep $count - done - else - bbnote "${PN}: group $groupname already exists, not re-creating it" + bbfatal "${PN}: groupadd command did not succeed." fi } perform_useradd () { local rootdir="$1" - local opts="$2" - local retries="$3" - bbnote "${PN}: Performing useradd with [$opts] and $retries times of retry" + local opts=`echo $2 | sed s/\'/\"/g` + bbnote "${PN}: Performing useradd with [$opts]" + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO useradd $opts\' || true local username=`echo "$opts" | awk '{ print $NF }'` - local user_exists="`grep "^$username:" $rootdir/etc/passwd || true`" + local user_exists=`grep "^$username:" $rootdir/etc/passwd` if test "x$user_exists" = "x"; then - local count=0 - while true; do - eval $PSEUDO useradd $opts || true - user_exists="`grep "^$username:" $rootdir/etc/passwd || true`" - if test "x$user_exists" = "x"; then - bbwarn "${PN}: useradd command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - bbfatal "${PN}: Tried running useradd command $retries times without success, giving up" - fi - sleep $count - done - else - bbnote "${PN}: user $username already exists, not re-creating it" + bbfatal "${PN}: useradd command did not succeed." fi } perform_groupmems () { local rootdir="$1" local opts="$2" - local retries="$3" - bbnote "${PN}: Performing groupmems with [$opts] and $retries times of retry" + bbnote "${PN}: Performing groupmems with [$opts]" local groupname=`echo "$opts" | awk '{ for (i = 1; i < NF; i++) if ($i == "-g" || $i == "--group") print $(i+1) }'` local username=`echo "$opts" | awk '{ for (i = 1; i < NF; i++) if ($i == "-a" || $i == "--add") print $(i+1) }'` bbnote "${PN}: Running groupmems command with group $groupname and user $username" @@ -82,30 +49,13 @@ perform_groupmems () { gshadow="no" touch $rootdir${sysconfdir}/gshadow fi - local mem_exists="`grep "^$groupname:[^:]*:[^:]*:\([^,]*,\)*$username\(,[^,]*\)*" $rootdir/etc/group || true`" + + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO groupmems $opts\' || true + local mem_exists=`grep "^$groupname:[^:]*:[^:]*:\([^,]*,\)*$username\(,[^,]*\)*" $rootdir/etc/group` if test "x$mem_exists" = "x"; then - local count=0 - while true; do - eval $PSEUDO groupmems $opts || true - mem_exists="`grep "^$groupname:[^:]*:[^:]*:\([^,]*,\)*$username\(,[^,]*\)*" $rootdir/etc/group || true`" - if test "x$mem_exists" = "x"; then - bbwarn "${PN}: groupmems command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - if test "x$gshadow" = "xno"; then - rm -f $rootdir${sysconfdir}/gshadow - rm -f $rootdir${sysconfdir}/gshadow- - fi - bbfatal "${PN}: Tried running groupmems command $retries times without success, giving up" - fi - sleep $count - done - else - bbnote "${PN}: group $groupname already contains $username, not re-adding it" + bbfatal "${PN}: groupmems command did not succeed." fi + if test "x$gshadow" = "xno"; then rm -f $rootdir${sysconfdir}/gshadow rm -f $rootdir${sysconfdir}/gshadow- @@ -115,56 +65,24 @@ perform_groupmems () { perform_groupdel () { local rootdir="$1" local opts="$2" - local retries="$3" - bbnote "${PN}: Performing groupdel with [$opts] and $retries times of retry" + bbnote "${PN}: Performing groupdel with [$opts]" + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO groupdel $opts\' || true local groupname=`echo "$opts" | awk '{ print $NF }'` - local group_exists="`grep "^$groupname:" $rootdir/etc/group || true`" + local group_exists=`grep "^$groupname:" $rootdir/etc/group` if test "x$group_exists" != "x"; then - local count=0 - while true; do - eval $PSEUDO groupdel $opts || true - group_exists="`grep "^$groupname:" $rootdir/etc/group || true`" - if test "x$group_exists" != "x"; then - bbwarn "${PN}: groupdel command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - bbfatal "${PN}: Tried running groupdel command $retries times without success, giving up" - fi - sleep $count - done - else - bbnote "${PN}: group $groupname doesn't exist, not removing it" + bbfatal "${PN}: groupdel command did not succeed." fi } perform_userdel () { local rootdir="$1" local opts="$2" - local retries="$3" - bbnote "${PN}: Performing userdel with [$opts] and $retries times of retry" + bbnote "${PN}: Performing userdel with [$opts]" + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO userdel $opts\' || true local username=`echo "$opts" | awk '{ print $NF }'` - local user_exists="`grep "^$username:" $rootdir/etc/passwd || true`" + local user_exists=`grep "^$username:" $rootdir/etc/passwd` if test "x$user_exists" != "x"; then - local count=0 - while true; do - eval $PSEUDO userdel $opts || true - user_exists="`grep "^$username:" $rootdir/etc/passwd || true`" - if test "x$user_exists" != "x"; then - bbwarn "${PN}: userdel command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - bbfatal "${PN}: Tried running userdel command $retries times without success, giving up" - fi - sleep $count - done - else - bbnote "${PN}: user $username doesn't exist, not removing it" + bbfatal "${PN}: userdel command did not succeed." fi } @@ -172,59 +90,29 @@ perform_groupmod () { # Other than the return value of groupmod, there's no simple way to judge whether the command # succeeds, so we disable -e option temporarily set +e + local rootdir="$1" local opts="$2" - local retries="$3" - bbnote "${PN}: Performing groupmod with [$opts] and $retries times of retry" - local groupname=`echo "$opts" | awk '{ print $NF }'` - local group_exists="`grep "^$groupname:" $rootdir/etc/group || true`" - if test "x$group_exists" != "x"; then - local count=0 - while true; do - eval $PSEUDO groupmod $opts - if test $? != 0; then - bbwarn "${PN}: groupmod command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - bbfatal "${PN}: Tried running groupmod command $retries times without success, giving up" - fi - sleep $count - done - else - bbwarn "${PN}: group $groupname doesn't exist, unable to modify it" + bbnote "${PN}: Performing groupmod with [$opts]" + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO groupmod $opts\' + if test $? != 0; then + bbwarn "${PN}: groupmod command did not succeed." fi + set -e } perform_usermod () { # Same reason with groupmod, temporarily disable -e option set +e + local rootdir="$1" local opts="$2" - local retries="$3" - bbnote "${PN}: Performing usermod with [$opts] and $retries times of retry" - local username=`echo "$opts" | awk '{ print $NF }'` - local user_exists="`grep "^$username:" $rootdir/etc/passwd || true`" - if test "x$user_exists" != "x"; then - local count=0 - while true; do - eval $PSEUDO usermod $opts - if test $? != 0; then - bbwarn "${PN}: usermod command did not succeed. Retrying..." - else - break - fi - count=`expr $count + 1` - if test $count = $retries; then - bbfatal "${PN}: Tried running usermod command $retries times without success, giving up" - fi - sleep $count - done - else - bbwarn "${PN}: user $username doesn't exist, unable to modify it" + bbnote "${PN}: Performing usermod with [$opts]" + eval flock -x -w 100 $rootdir${sysconfdir} -c \'$PSEUDO usermod $opts\' + if test $? != 0; then + bbfatal "${PN}: usermod command did not succeed." fi + set -e } -- 2.6.1 -- _______________________________________________ Openembedded-core mailing list [email protected] http://lists.openembedded.org/mailman/listinfo/openembedded-core
