######################################################################## # Description : Gnu Makefile to control the services in the specified # runlevel. It will run the required services, and log # the output of the services to the file # /var/log/initd.$runlevel.start (for service startup) and # /var/log/initd.$runlevel.stop (for service shutdown). # # This controlling program is designed to be invoked by # the "/etc/rc.d/rc" script. # # Author : jameshunt@uk.ibm.com # Modified by : Silvan Calarco # # Notes : # # - Run as, # # make [-n] -j -f runlevel.mk \ # RUNLEVEL={0|1|2|3|4|5|6} \ # JOB={start|stop|restart|status} # # - $(JOB) is not validated - that is left to the service program. # - $(RUNLEVEL) is not validated - that is left to the calling program # (usually /etc/rc.d/rc). # - It wouldn't take too much effort to auto-generate this Makefile. # ######################################################################## # passed as a parameter export RUNLEVEL := $(shell echo $$RUNLEVEL) PREV_RUNLEVEL := $(shell echo $$PREVLEVEL) PREV_RUNLEVEL_DIR = /etc/rc.d/rc$(PREV_RUNLEVEL).d SERVICE= /sbin/service # passed as a parameter (start, stop, status, etc) JOB = JB = `case $(JOB) in "start") echo S;; "stop") echo K;; esac` # set to a value to enable debug output DEBUG = # with TEST=1 only print service startup order TEST = ######################################################################## # START CONFIGURATION # system commands used by this facility CAT = /bin/cat RM = /bin/rm ECHO = /bin/echo DATE = /bin/date LS = /bin/ls XARGS = /usr/bin/xargs # Directory containing scripts/programs to run. INITD_DIR := /etc/init.d # Directory into which a lock file is created when a service starts. # (Note that the lock file is created by the service). SUBSYS_FILE_DIR := /var/lock/subsys # Rcl init database/dependecies file dir RCL_DIR := /var/init # Used to create temporary files, before collating them all into # $(FINAL_OUTPUT_FILE). TMP_DIR := /tmp ifneq ($(DEBUG),) DEBUG_FILE = /dev/stdout else DEBUG_FILE = /dev/null endif TMPFILE_PREFIX := .runlevel TMP_FILE = $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).$@ # Variable used for splash progress bar PROGRESS_TOT := 0 PROGRESS_BASE := 0 PROGRESS_FILEDIR := /dev/shm/progcounter # File that contains all output of programs/scripts run. FINAL_OUTPUT_FILE := /var/log/initd.$(RUNLEVEL).$(JOB) # # List of all runlevel services to be started/stopped # include $(RCL_DIR)/$(RUNLEVEL).$(JOB).rcl START_RUNLEVEL = $(ALL_RUNLEVEL) STARTAFTER_RUNLEVEL = LOCAL = openldap messagebus haldaemon ifeq ($(JOB)$(RUNLEVEL),start5) START_RUNLEVEL = random sysinit syslog-ng sysklogd msysklogd network iptables wicd acpid apmd # LOCAL: list of services that have to be started before KDM LOCAL = openldap messagebus haldaemon alsa bluetooth consolekit mambawelcome STARTAFTER_RUNLEVEL = $(filter-out $(LOCAL) $(START_RUNLEVEL), $(ALL_RUNLEVEL)) endif ifeq ($(JOB)$(RUNLEVEL),start4) START_RUNLEVEL = random sysinit syslog-ng sysklogd msysklogd network iptables wicd acpid apmd # LOCAL: list of services that have to be started before KDM LOCAL = openldap messagebus haldaemon alsa bluetooth consolekit STARTAFTER_RUNLEVEL = $(filter-out $(LOCAL) $(START_RUNLEVEL), $(ALL_RUNLEVEL)) endif ifeq ($(JOB)$(RUNLEVEL),start3) START_RUNLEVEL = random sysinit syslog-ng sysklogd msysklogd network iptables wicd acpid apmd # LOCAL: list of services that have to be started before agetty LOCAL = openldap messagebus haldaemon STARTAFTER_RUNLEVEL = $(filter-out $(LOCAL) $(START_RUNLEVEL), $(ALL_RUNLEVEL)) endif ifeq ($(JOB)$(RUNLEVEL),start2) # runlevel 2: don't wait for network before agetty START_RUNLEVEL = random sysinit syslog-ng sysklogd msysklogd acpid apmd # LOCAL: list of services that have to be started before agetty LOCAL = openldap STARTAFTER_RUNLEVEL = $(filter-out $(LOCAL) $(START_RUNLEVEL), $(ALL_RUNLEVEL)) endif # END CONFIGURATION ######################################################################## # Check command-line parameters ifndef RUNLEVEL $(error must specify RUNLEVEL, so I know what to run) endif ifndef JOB $(error must specify JOB, so I know what to do) endif default: prep $(START_RUNLEVEL) local $(STARTAFTER_RUNLEVEL) create_final_output_file prep: @mkdir -p $(PROGRESS_FILEDIR) || rm -f $(PROGRESS_FILEDIR)/* @rm -f $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).* ifeq ($(DEBUG),2) @$(ECHO) "RUNLEVEL=$(RUNLEVEL)" >> $(DEBUG_FILE) @$(ECHO) "JOB=$(JOB)" >> $(DEBUG_FILE) @$(ECHO) "FINAL_OUTPUT_FILE=$(FINAL_OUTPUT_FILE)" >> $(DEBUG_FILE) @$(ECHO) "TMP_FILE=$(TMP_FILE)" >> $(DEBUG_FILE) @$(ECHO) "ALL_RUNLEVEL=|$(ALL_RUNLEVEL)|" >> $(DEBUG_FILE) @$(ECHO) "START_RUNLEVEL=|$(START_RUNLEVEL)|" >> $(DEBUG_FILE) @$(ECHO) "STARTAFTER_RUNLEVEL=|$(STARTAFTER_RUNLEVEL)|" >> $(DEBUG_FILE) @$(ECHO) "LOCAL=|$(LOCAL)|" >> $(DEBUG_FILE) @$(ECHO) "($(JB)$(RUNLEVEL),S5)" >> $(DEBUG_FILE) @$(ECHO) >> $(DEBUG_FILE) endif ############################################################## # Rule that executes all services jobs # $(ALL_RUNLEVEL): @if [ "$(TEST)" = "1" ]; then echo $@; sleep 1; fi @if [ ! -e $(PREV_RUNLEVEL_DIR)/$(JB)??$@ ]; then \ $(ECHO) "Begin \"$(JOB) $@\" at `$(DATE)`" | tee -a $(TMP_FILE) >$(DEBUG_FILE); \ RUNLEVEL=$(RUNLEVEL) $(INITD_DIR)/$@ $(JOB) 2>&1 | tee -a $(TMP_FILE) >$(DEBUG_FILE); \ $(ECHO) "End \"$(JOB) $@\" at `$(DATE)`" | tee -a $(TMP_FILE) >$(DEBUG_FILE); \ else \ $(ECHO) "Already running \"$(JOB) $@\" at `$(DATE)`" | tee -a $(TMP_FILE) >$(DEBUG_FILE); \ fi; \ if [ -d $(PROGRESS_FILEDIR) ]; then \ >$(PROGRESS_FILEDIR)/$@ \ i=`ls $(PROGRESS_FILEDIR) | wc -w`; \ . /etc/init.d/functions; \ progress=`expr $(PROGRESS_BASE) + $$i \* \( 100 - $(PROGRESS_BASE) \) / $(PROGRESS_TOT)`; \ fi; ############################################################## # List of services that have dependencies. # # (Note: It is not necessary to list services that have no # dependencies). # Include the relevant dependencies. If you intend to use this facility, # you must provide 2 makefiles / runlevel, one for starting the services # in the runlevel, and one for stopping the services in the runlevel. # # WARNING: If make attempts to include a file that does not exist, it will # exit. This could cause your system to boot in an unfamiliar way. include $(RCL_DIR)/deps.$(JOB).mk # Lastly, merge all the service output files into a single file. # Note that the order of the service output in the merged file is not # chronological. create_final_output_file: $(START_RUNLEVEL) $(STARTAFTER_RUNLEVEL) @$(LS) -Srt $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).* 2>/dev/null | $(XARGS) $(CAT) > $(FINAL_OUTPUT_FILE) 2>/dev/null @$(RM) -f $(TMP_DIR)/$(TMPFILE_PREFIX).$(JOB).* 2>/dev/null # EOF