diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 2d906f7f2bf..5e57c620c13 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -325,6 +325,8 @@ Trunk (Unreleased) HADOOP-11052. hadoop_verify_secure_prereq's results aren't checked in bin/hdfs (aw) + HADOOP-11055. non-daemon pid files are missing (aw) + OPTIMIZATIONS HADOOP-7761. Improve the performance of raw comparisons. (todd) diff --git a/hadoop-common-project/hadoop-common/src/main/bin/hadoop-functions.sh b/hadoop-common-project/hadoop-common/src/main/bin/hadoop-functions.sh index 1677cc06bfa..db7dd5e2a9b 100644 --- a/hadoop-common-project/hadoop-common/src/main/bin/hadoop-functions.sh +++ b/hadoop-common-project/hadoop-common/src/main/bin/hadoop-functions.sh @@ -645,7 +645,7 @@ function hadoop_verify_secure_prereq # ${EUID} comes from the shell itself! if [[ "${EUID}" -ne 0 ]] && [[ -z "${HADOOP_SECURE_COMMAND}" ]]; then - hadoop_error "ERROR: You must be a privileged in order to run a secure serice." + hadoop_error "ERROR: You must be a privileged user in order to run a secure service." exit 1 else return 0 @@ -704,7 +704,8 @@ function hadoop_verify_logdir rm "${HADOOP_LOG_DIR}/$$" >/dev/null 2>&1 } -function hadoop_status_daemon() { +function hadoop_status_daemon() +{ # # LSB 4.1.0 compatible status command (1) # @@ -760,11 +761,19 @@ function hadoop_start_daemon # so complex! so wow! much java! local command=$1 local class=$2 - shift 2 + local pidfile=$3 + shift 3 hadoop_debug "Final CLASSPATH: ${CLASSPATH}" hadoop_debug "Final HADOOP_OPTS: ${HADOOP_OPTS}" + # this is for the non-daemon pid creation + #shellcheck disable=SC2086 + echo $$ > "${pidfile}" 2>/dev/null + if [[ $? -gt 0 ]]; then + hadoop_error "ERROR: Cannot write ${command} pid ${pidfile}." + fi + export CLASSPATH #shellcheck disable=SC2086 exec "${JAVA}" "-Dproc_${command}" ${HADOOP_OPTS} "${class}" "$@" @@ -779,27 +788,42 @@ function hadoop_start_daemon_wrapper local pidfile=$3 local outfile=$4 shift 4 - + + local counter + hadoop_rotate_log "${outfile}" hadoop_start_daemon "${daemonname}" \ - "$class" "$@" >> "${outfile}" 2>&1 < /dev/null & + "$class" \ + "${pidfile}" \ + "$@" >> "${outfile}" 2>&1 < /dev/null & + + # we need to avoid a race condition here + # so let's wait for the fork to finish + # before overriding with the daemonized pid + (( counter=0 )) + while [[ ! -f ${pidfile} && ${counter} -le 5 ]]; do + sleep 1 + (( counter++ )) + done + + # this is for daemon pid creation #shellcheck disable=SC2086 echo $! > "${pidfile}" 2>/dev/null if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot write pid ${pidfile}." + hadoop_error "ERROR: Cannot write ${daemonname} pid ${pidfile}." fi # shellcheck disable=SC2086 renice "${HADOOP_NICENESS}" $! >/dev/null 2>&1 if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot set priority of process $!" + hadoop_error "ERROR: Cannot set priority of ${daemoname} process $!" fi # shellcheck disable=SC2086 - disown $! 2>&1 + disown %+ >/dev/null 2>&1 if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot disconnect process $!" + hadoop_error "ERROR: Cannot disconnect ${daemoname} process $!" fi sleep 1 @@ -829,7 +853,8 @@ function hadoop_start_secure_daemon # where to send stderr. same thing, except &2 = stderr local daemonerrfile=$5 - shift 5 + local privpidfile=$6 + shift 6 hadoop_rotate_log "${daemonoutfile}" hadoop_rotate_log "${daemonerrfile}" @@ -849,17 +874,23 @@ function hadoop_start_secure_daemon hadoop_debug "Final CLASSPATH: ${CLASSPATH}" hadoop_debug "Final HADOOP_OPTS: ${HADOOP_OPTS}" + + #shellcheck disable=SC2086 + echo $$ > "${privpidfile}" 2>/dev/null + if [[ $? -gt 0 ]]; then + hadoop_error "ERROR: Cannot write ${daemoname} pid ${privpidfile}." + fi exec "${jsvc}" \ - "-Dproc_${daemonname}" \ - -outfile "${daemonoutfile}" \ - -errfile "${daemonerrfile}" \ - -pidfile "${daemonpidfile}" \ - -nodetach \ - -user "${HADOOP_SECURE_USER}" \ - -cp "${CLASSPATH}" \ - ${HADOOP_OPTS} \ - "${class}" "$@" + "-Dproc_${daemonname}" \ + -outfile "${daemonoutfile}" \ + -errfile "${daemonerrfile}" \ + -pidfile "${daemonpidfile}" \ + -nodetach \ + -user "${HADOOP_SECURE_USER}" \ + -cp "${CLASSPATH}" \ + ${HADOOP_OPTS} \ + "${class}" "$@" } function hadoop_start_secure_daemon_wrapper @@ -886,39 +917,52 @@ function hadoop_start_secure_daemon_wrapper local daemonerrfile=$7 shift 7 + + local counter hadoop_rotate_log "${jsvcoutfile}" hadoop_start_secure_daemon \ - "${daemonname}" \ - "${class}" \ - "${daemonpidfile}" \ - "${daemonoutfile}" \ - "${daemonerrfile}" "$@" >> "${jsvcoutfile}" 2>&1 < /dev/null & - - # This wrapper should only have one child. Unlike Shawty Lo. + "${daemonname}" \ + "${class}" \ + "${daemonpidfile}" \ + "${daemonoutfile}" \ + "${daemonerrfile}" \ + "${jsvcpidfile}" "$@" >> "${jsvcoutfile}" 2>&1 < /dev/null & + + # we need to avoid a race condition here + # so let's wait for the fork to finish + # before overriding with the daemonized pid + (( counter=0 )) + while [[ ! -f ${pidfile} && ${counter} -le 5 ]]; do + sleep 1 + (( counter++ )) + done + + # this is for the daemon pid creation #shellcheck disable=SC2086 echo $! > "${jsvcpidfile}" 2>/dev/null if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot write pid ${pidfile}." + hadoop_error "ERROR: Cannot write ${daemonname} pid ${pidfile}." fi + sleep 1 #shellcheck disable=SC2086 renice "${HADOOP_NICENESS}" $! >/dev/null 2>&1 if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot set priority of process $!" + hadoop_error "ERROR: Cannot set priority of ${daemonname} process $!" fi if [[ -f "${daemonpidfile}" ]]; then #shellcheck disable=SC2046 - renice "${HADOOP_NICENESS}" $(cat "${daemonpidfile}") >/dev/null 2>&1 + renice "${HADOOP_NICENESS}" $(cat "${daemonpidfile}" 2>/dev/null) >/dev/null 2>&1 if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot set priority of process $(cat "${daemonpidfile}")" + hadoop_error "ERROR: Cannot set priority of ${daemonname} process $(cat "${daemonpidfile}" 2>/dev/null)" fi fi - #shellcheck disable=SC2086 - disown $! 2>&1 + #shellcheck disable=SC2046 + disown %+ >/dev/null 2>&1 if [[ $? -gt 0 ]]; then - hadoop_error "ERROR: Cannot disconnect process $!" + hadoop_error "ERROR: Cannot disconnect ${daemonname} process $!" fi # capture the ulimit output su "${HADOOP_SECURE_USER}" -c 'bash -c "ulimit -a"' >> "${jsvcoutfile}" 2>&1 @@ -994,7 +1038,7 @@ function hadoop_daemon_handler hadoop_verify_logdir hadoop_status_daemon "${daemon_pidfile}" if [[ $? == 0 ]]; then - hadoop_error "${daemonname} running as process $(cat "${daemon_pidfile}"). Stop it first." + hadoop_error "${daemonname} is running as process $(cat "${daemon_pidfile}"). Stop it first." exit 1 else # stale pid file, so just remove it and continue on @@ -1003,7 +1047,7 @@ function hadoop_daemon_handler ##COMPAT - differenticate between --daemon start and nothing # "nothing" shouldn't detach if [[ "$daemonmode" = "default" ]]; then - hadoop_start_daemon "${daemonname}" "${class}" "$@" + hadoop_start_daemon "${daemonname}" "${class}" "${daemon_pidfile}" "$@" else hadoop_start_daemon_wrapper "${daemonname}" \ "${class}" "${daemon_pidfile}" "${daemon_outfile}" "$@" @@ -1042,7 +1086,7 @@ function hadoop_secure_daemon_handler hadoop_verify_logdir hadoop_status_daemon "${daemon_pidfile}" if [[ $? == 0 ]]; then - hadoop_error "${daemonname} running as process $(cat "${daemon_pidfile}"). Stop it first." + hadoop_error "${daemonname} is running as process $(cat "${daemon_pidfile}"). Stop it first." exit 1 else # stale pid file, so just remove it and continue on @@ -1054,7 +1098,7 @@ function hadoop_secure_daemon_handler if [[ "${daemonmode}" = "default" ]]; then hadoop_start_secure_daemon "${daemonname}" "${classname}" \ "${daemon_pidfile}" "${daemon_outfile}" \ - "${priv_errfile}" "$@" + "${priv_errfile}" "${priv_pidfile}" "$@" else hadoop_start_secure_daemon_wrapper "${daemonname}" "${classname}" \ "${daemon_pidfile}" "${daemon_outfile}" \