#!/usr/bin/ksh93 # # Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. # . /lib/svc/share/smf_include.sh PATH=/usr/bin:/usr/sbin:$PATH logadm_conf=/etc/logadm.conf logadm_conf_new= logadm_d=${logadm_conf%conf}d # # Everything between these lines in /etc/logadm.conf is placed there by this # script. # dnm_beg="# DO NOT MODIFY logadm-upgrade-begin DO NOT MODIFY" dnm_end="# DO NOT MODIFY logadm-upgrade-end DO NOT MODIFY" # # This is a temporary service to allow addition (only) to /etc/logadm.conf # It is temporary in the sense that logadm(1M) should have its configuration # migrated to SMF in the future. # # # Display error message and exits with error code # msg_exit() { exit_code=$1 msg=$2 if [[ -n $logadm_conf_new ]]; then rm -f "$logadm_conf_new" fi print -u2 -- "$msg" exit $exit_code } # # Generate a new logadm.conf on stdout. Uses several global variables: # # old_logadm_cont Contains the full content of /etc/logadm.conf. # rm_line Associative array. Each key is a log name, as is used # in the first token in each line of /etc/logadm.conf. # add_files Array of files that should be present in # /etc/logadm.conf. # function generate_logadm_content { typeset line logname # Be sure that if print or sed fails, the failure can be detected. set -o pipefail # Remove old content print -- "$old_logadm_cont" | sed -e "/^${dnm_beg}$/,/^${dnm_end}$/ d" | while read line; do # Preserve comments if [[ $line == "#"* ]]; then print -- "$line" continue fi # # Remove duplicate lines as identified by comparing the logname # field. This will only be relevant for the first run of # this version of this script. # logname=${line%%[ \t]*} [[ -n ${rm_line[$logname]} ]] && continue # Preserve this line print -- "$line" done if (( $? != 0 )); then msg_exit $SMF_EXIT_ERR_FATAL \ "Failed to strip old entries from $logadm_conf" fi # Generate new content typeset file print "$dnm_beg" for file in "${add_files[@]}"; do print "# DO NOT MODIFY Added by logadm-upgrade for $file" sed '/^#/ d' "$file" || msg_exit $SMF_EXIT_ERR_FATAL \ "Failed to add content of $file" done print "$dnm_end" } # # Testing for writable root rather that using is_self_assembly_boot so that # changes that don't require an alternate root install will be noticed. This # also makes it feasible for packages to use restart_fmri on files delivered to # /etc/logadm.d to allow logadm.conf updates without a reboot. # if [[ ! -w / ]]; then exit $SMF_EXIT_OK fi # # If there is no /etc/logadm.conf create it and make sure it has the # right ownership and permissions. # if [[ ! -f "$logadm_conf" ]]; then touch "$logadm_conf" chmod 644 "$logadm_conf" chown root:sys "$logadm_conf" fi typeset -A rm_line typeset -a add_files for f in "$logadm_d"/*; do # # If it is not a file, we skip it. # if [[ ! -f $f ]]; then continue fi # # Files must be owned by root, group sys and have permissions 444. If a # file with different permissions is found, it's a configuration error # that needs to be fixed. Put the service in maintenance to draw # attention to the problem. # perm=$(ls -l "$f" | nawk '{printf("%s %s:%s", $1, $3, $4)}') if [[ $? != 0 ]]; then msg_exit $SMF_EXIT_ERR_FATAL "Failed to get permissions of $f" fi if [[ "$perm" != "-r--r--r-- root:sys" ]]; then print -u2 "Unexpected permission/ownership for $f" print -u2 " expected -r--r--r-- root:sys but got $perm" exit $SMF_EXIT_ERR_FATAL fi # This file will be added to /etc/logadm.conf. add_files+=("$f") # # The first generation of logadm-upgrade did not tag content that came # from /etc/logadm.d/ in /etc/logadm.conf, making updates or removals # rather challenging. The best we can do is look at the current entries # in the /etc/logadm.d/ files to recognize conflicts in # /etc/logadm.conf. The existing entry in /etc/logadm.conf will be # removed. # exec <$f while read logname args; do # skip comments [[ $logname == "#"* ]] && continue # skip blank lines and those containing only white space [[ $logname == *(\s) ]] && continue rm_line[$logname]=1 done done # # Load the existing logadm.conf into memory so that we can compare the old and # new configuration without having to write a new file. # old_logadm_cont=$(cat "$logadm_conf") || msg_exit $SMF_EXIT_ERR_FATAL "Failed to read existing config file" # # Generate the new logadm.conf and write it out, if necessary. # new_logadm_cont=$(generate_logadm_content) || msg_exit $SMF_EXIT_ERR_FATAL "Failed to create temporary config content" if [[ "$old_logadm_cont" == "$new_logadm_cont" ]]; then # No updates required exit $SMF_EXIT_OK fi logadm_conf_new=$(mktemp "$logadm_conf.XXXXXX") || msg_exit $SMF_EXIT_ERR_FATAL "Failed to create temporary config file" print -- "$new_logadm_cont" >$logadm_conf_new || msg_exit $SMF_EXIT_ERR_FATAL "Failed to write new config file" chown root:sys "$logadm_conf_new" || msg_exit $SMF_EXIT_ERR_FATAL "Failed to set owner:group on new config file" chmod 644 "$logadm_conf_new" || msg_exit $SMF_EXIT_ERR_FATAL "Failed to set permissions on new config file" mv "$logadm_conf_new" "$logadm_conf" || msg_exit $SMF_EXIT_ERR_FATAL "Failed to install new config file" exit $SMF_EXIT_OK