#!/bin/bash # # Service Library Usage Check # # Copyright 2016 Steadfast Networks, LLC # # This script checks to see if any services should be restarted after a library update # Provide a list of package names or library sonames you want to check on the command line OLDIFS=$IFS LIBS="$@ " SERVICES= if [[ `uname -m` == 'x86_64' ]] ; then LIBDIR='/usr/lib64' else LIBDIR='/usr/lib' fi rpm --version >/dev/null 2>&1 if [[ $? -ne 0 ]] ; then echo "Error: Need RPM to continue. Maybe this isn't CentOS?"; exit 1; fi for LIB in $LIBS; do echo $LIB | grep '\.' >/dev/null if [[ $? -ne 0 ]] ; then RPMLIBS=`rpm -ql $LIB | grep "\.so\.\?" | tr '\n' ' '` COUNT=(${RPMLIBS}) COUNT=${#COUNT[@]} echo "+ Using $LIB as RPM name, found $COUNT libraries" LIBS="`echo $LIBS | sed 's/'$LIB'\( \|$\)//'` $RPMLIBS" fi done OSVER=`rpm -q centos-release --queryformat="%{VERSION}"` for LIB in $LIBS; do if [[ `basename $LIB` == $LIB ]] ; then LIB=$LIBDIR/$LIB fi if [[ $OSVER -eq 5 ]] ; then MSTRING=n${LIB}'\s.path\sinode' elif [[ $OSVER -eq 6 ]] ; then MSTRING="fDEL n${LIB}" else MSTRING="n${LIB};" fi LIBFN=`basename $LIB` MATCH=`lsof -F fpn / | grep '^\(f\|p\|n\)' | tr '\n' ' ' | sed 's/ p/\np/g' | grep "${MSTRING}" | sed 's/^p\([0-9]\+\) f.*$/\1/'i` MATCHES="$MATCHES $MATCH" if [[ $MATCH != "" ]] ; then echo "+ Found $LIBFN PID matches: "$MATCH else echo "- Nothing was found running on an old $LIBFN" fi done EXES="" # Deduplicate the PID list MATCHES=`echo $MATCHES | tr ' ' '\n' | sort -n | uniq` for PID in $MATCHES; do EXE=`readlink /proc/$PID/exe | sed 's/;.*$//' | sed 's/ (deleted)//'` # If this is a script, try to figure out what script was run and match the package for that instead if [[ $EXE =~ /python || $EXE =~ /php || $EXE =~ /perl || $EXE =~ /sh || $EXE =~ /bash || $EXE =~ /ruby ]] ; then SCRIPT=`sed 's/\x00/\n/g' /proc/$PID/cmdline | tail -n +2 | grep '\(libexec\|bin\)'` if [[ $SCRIPT != "" ]] ; then EXE=$SCRIPT fi fi EXES="$EXES $EXE" done # Deduplicate the EXE list EXES=`echo $EXES | tr ' ' '\n' | sort | uniq` for EXE in $EXES; do PACKAGE=`rpm -qf $EXE 2>/dev/null` if [[ $PACKAGE == "" ]] ; then NOPKG="$NOPKG $EXE" else if [[ $OSVER -ge 7 ]] ; then SVCS=`rpm -qf $EXE -l 2>/dev/null | grep '\.service$'` else SVCS=`rpm -qf $EXE -l 2>/dev/null | grep '/init.d/'` fi if [[ $SVCS == "" ]] ; then NOSVC="$NOSVC $EXE" fi for SVC in $SVCS; do SERVICES="$SERVICES `basename $SVC | sed 's/.service$//'`" done fi done if [[ $SERVICES != "" ]] ; then echo echo "You probably need to do the following:" echo for RESTART in `echo $SERVICES | sed 's/ /\n/g' | sort -u`; do service $RESTART status >/dev/null 2>&1 if [[ $? -eq 0 ]] ; then SVCFOUND=1 if [[ $OSVER -ge 7 ]] ; then echo " systemctl restart $RESTART" else echo " service $RESTART restart" fi fi done if [[ $SVCFOUND -ne 1 ]] ; then echo " * Some startup scripts matched, but none are running, so nothing seems relevant." fi fi if [[ $NOSVC != "" || $NOPKG != "" ]] ; then echo echo "You're on your own with these:" echo for EXE in `echo $NOPKG | sed 's/ /\n/g' | grep -v '(deleted)' | sort -u`; do echo "* The program $EXE does not appear to come from an installed package." done for EXE in `echo $NOSVC | sed 's/ /\n/g' | sort -u`; do echo "* The program $EXE does not appear to have any relevant services." done fi if [[ $SERVICES == "" && $NOSVC == "" && $NOPKG == "" ]] ; then echo echo "Good news! Nothing seems to need to be restarted." fi echo