Changeset 43688 in vbox for trunk/src/VBox/Installer/linux
- Timestamp:
- Oct 18, 2012 7:39:16 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 81506
- Location:
- trunk/src/VBox/Installer/linux
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Installer/linux/VBoxHeadlessXOrg.sh
r43634 r43688 1 1 #!/bin/sh 2 2 # 3 # VirtualBox X Server auto-start s cript.3 # VirtualBox X Server auto-start service. 4 4 # 5 5 # Copyright (C) 2012 Oracle Corporation … … 17 17 18 18 ## Start one or several X servers in the background for use with headless 19 # rendering. We only support X.Org Server at the moment. Starting the X 20 # servers is managed by dropping one or more files xorg.conf.<n> into the 21 # directory ${HEADLESS_X_ORG_CONFIGURATION_DIRECTORY} - the default value 22 # below can be overridden in the configuration file. We will attempt to start 23 # an X server process for each configuration file using display number <n>. 24 # For usage and options see the usage() function below this comment block. 19 # rendering. For details, options and configuration see the usage() function 20 # further down. 25 21 # 26 22 # I have tried to follow the best practices I could find for writing a Linux 27 # daemon process(and doing it in shell script) which should work well with23 # service (and doing it in shell script) which should work well with 28 24 # traditional and modern service systems using minimal init or service files. 29 25 # In our case this boils down to: 30 26 # * Start with a single command line, stop using one of ${EXIT_SIGNALS} below. 31 27 # * Stopping with a signal can be done safely using the pid stored in the 32 # pid-file and our (presumably unique) command name. For this reason we only33 # support running one instance of the service though.34 # * S upport starting in the foreground for systems with proper service control.35 # * Support backgrounding with a pid-file for other systems.28 # pid-file and our (presumably unique) command name. For this reason we 29 # only support running one instance of the service though. 30 # * Start in the foreground. Systems without proper service control can take 31 # care of the backgrounding in the init script. 36 32 # * Clean up all sub-processes (X servers) ourselves when we are stopped 37 33 # cleanly and don't provide any other way to clean them up automatically (in … … 42 38 # using a service-specific user account and just terminate all processes 43 39 # run by that user to clean up.) 44 # * For this reason, our pid-file only contains the pid of the master process. 45 # * To simplify system service and start-up message handling, we write 46 # Debian-conform progress information to standard output (what processes we 47 # are starting, information if we do something slow) and errors to standard 48 # error. This should allow us to write pretty generic init/startup scripts 49 # for different distributions which produce more-or-less correct output for 50 # the system they run on. 51 52 ## Print usage information for the service script. 53 usage() { 54 cat << EOF 55 Usage: 56 57 $(basename "${SCRIPT_NAME}") [<options>] 58 59 Do any system-wide set-up required to properly run the copy of VirtualBox 60 residing in the current directory. If no options are specified, everything 61 except --no-udev-and --log-file is assumed. 62 63 Options: 64 65 -d|--daemonize) Detach fron the terminal and continue running in the 66 background. 67 68 -l|--log-folder) Create log files in this folder. 69 70 -p|--pidfile <name> Specify the name of the file to save the pids of child 71 processes in. Pass in an empty string to disable 72 pid-file creation. 73 74 -q|--quiet) Do not produce unnecessary console output. We still 75 show a banner if the command line arguments are 76 invalid. 77 78 --quick) Intended for internal use. Skip certain checks and 79 actions at start-up and print the command line 80 arguments to standard output. 81 82 --help|--usage Print this text. 83 EOF 84 } 85 86 ## Configuration file name. 40 41 ## Default configuration file name. 87 42 # Don't use vbox.cfg as that is currently automatically created and deleted. 88 43 # Don't use /etc/default/virtualbox as that is Debian policy only and not very … … 90 45 ## @todo Should we be using /etc/virtualbox instead of /etc/vbox? 91 46 CONFIGURATION_FILE=/etc/vbox/vbox.conf 92 93 47 ## The name of this script. 94 48 SCRIPT_NAME="$0" … … 99 53 ## The descriptive service name. 100 54 SERVICE_LONG_NAME="VBoxHeadless X Server service" 101 ## Timeout in seconds when shutting down the service.102 SERVICE_SHUTDOWN_TIMEOUT=5103 55 ## Signals and conditions which may be used to terminate the service. 104 56 EXIT_SIGNALS="EXIT HUP INT QUIT ABRT TERM" 105 106 # Default settings values, override in the configuration file. 107 ## The directory where the configuration files for the X servers are dropped. 108 HEADLESS_X_ORG_CONFIGURATION_DIRECTORY=/etc/vbox/headlessxorg.conf.d 109 ## The path to the pidfile for the service. 110 HEADLESS_X_ORG_PID_FILE="/var/run/${SERVICE_NAME}.pid" 111 ## The default log folder 57 ## The default X server configuration directory. 58 DEFAULT_CONFIGURATION_FOLDER="/etc/vbox/headlessxorg.conf.d" 59 60 ## Print usage information for the service script. 61 ## @todo Perhaps we should support some of the configuration file options from 62 # the command line. Opinions welcome. 63 ## @todo Possibly extract this information for the user manual. 64 usage() { 65 cat << EOF 66 Usage: 67 68 $(basename "${SCRIPT_NAME}") [<options>] 69 70 Start one or several X servers in the background for use with headless 71 rendering. We only support X.Org Server at the moment. Starting the X servers 72 is managed by dropping one or more files xorg.conf.<n> into a configuration 73 directory (by default ${DEFAULT_CONFIGURATION_FOLDER} - this can be overridden 74 in the configuration file (see below). We will attempt to start an X server 75 process for each configuration file using display number <n>. 76 77 Options: 78 79 -c|--conf-file) Specify an alternative locations for the configuration 80 file. The default location is \"${CONFIGURATION_FILE}\". 81 82 --help|--usage Print this text. 83 84 The optional configuration file should contain a series of lines of the form 85 "KEY=value". It will be read in as a command shell sub-script. Here is the 86 current list of possible key settings with a short explanation. 87 88 HEADLESS_X_ORG_CONFIGURATION_FOLDER 89 The folder where the configuration files for the X servers are to be found. 90 91 HEADLESS_X_ORG_LOG_FOLDER 92 The default log folder. 93 94 HEADLESS_X_ORG_LOG_FILE 95 The default log file. 96 97 HEADLESS_X_ORG_SERVER_COMMAND 98 The default X server start-up command, containing the variables "${screen}" 99 for the screen number, "${conf_file}" for the configuration file path and 100 ${log_file} for the log file. The variables must be quoted for expansion 101 at evaluation time, e.g. 102 HEADLESS_X_ORG_SERVER_COMMAND="Xorg :\${screen} [...] > \"\${log_file}\" 103 104 HEADLESS_X_ORG_SERVER_LOG_FILE_TEMPLATE 105 The default X server log file name, containing the variable "${screen}" for 106 the screen number. The variable must be quoted for expansion at evaluation 107 time, e.g. 108 HEADLESS_X_ORG_SERVER_LOG_FILE_TEMPLATE="Xorg.\${screen}.log" 109 EOF 110 } 111 112 # Default configuration. 113 HEADLESS_X_ORG_CONFIGURATION_FOLDER="${DEFAULT_CONFIGURATION_FOLDER}" 112 114 HEADLESS_X_ORG_LOG_FOLDER="/var/log/${SERVICE_NAME}" 115 HEADLESS_X_ORG_LOG_FILE="${SERVICE_NAME}.log" 116 HEADLESS_X_ORG_SERVER_COMMAND="Xorg :\${screen} -config \"\${conf_file}\" -logverbose 0 -logfile /dev/null -verbose 7 > \"\${log_file}\" 2>&1" 117 HEADLESS_X_ORG_SERVER_LOG_FILE_TEMPLATE="Xorg.\${screen}.log" 113 118 114 119 ## The function definition at the start of every non-trivial shell script! 115 120 abort() { 116 stop 2>/dev/null117 121 ## $@, ... Error text to output to standard error in printf format. 118 122 printf "$@" >&2 … … 122 126 ## Milder version of abort, when we can't continue because of a valid condition. 123 127 abandon() { 124 stop 2>/dev/null125 128 ## $@, ... Text to output to standard error in printf format. 126 129 printf "$@" >&2 … … 128 131 } 129 132 133 abort_usage() { 134 usage >&2 135 abort "$@" 136 } 137 138 # Print a banner message 130 139 banner() { 131 140 cat << EOF … … 135 144 136 145 EOF 137 [ -n "${QUICK}" ] && 138 printf "Internal command line: ${SCRIPT_COMMAND_LINE}\n\n" 139 } 140 141 abort_usage() { 142 usage >&2 143 abort "$@" 144 } 145 146 # Change to the directory where the script is located. 147 MY_DIR="$(dirname "${SCRIPT_NAME}")" 148 MY_DIR=`cd "${MY_DIR}" && pwd` 149 [ -d "${MY_DIR}" ] || 150 abort "Failed to change to directory ${MY_DIR}.\n" 151 152 # Get installation configuration 153 [ -r /etc/vbox/vbox.cfg ] || abort "/etc/vbox/vbox.cfg not found.\n" 154 . /etc/vbox/vbox.cfg 155 156 [ -r scripts/generated.sh ] || 157 abort "${LOG_FILE}" "Failed to find installation information in ${MY_DIR}.\n" 158 . scripts/generated.sh 159 160 [ -r /etc/vbox/vbox.conf ] && . /etc/vbox/vbox.conf 146 } 147 148 # Get the directory where the script is located. 149 VBOX_FOLDER="$(dirname "${SCRIPT_NAME}")" 150 VBOX_FOLDER=$(cd "${VBOX_FOLDER}" && pwd) 151 [ -d "${VBOX_FOLDER}" ] || 152 abort "Failed to change to directory ${VBOX_FOLDER}.\n" 153 # And change to the root directory so we don't hold any other open. 154 cd / 155 156 [ -r "${VBOX_FOLDER}/scripts/generated.sh" ] || 157 abort "${LOG_FILE}" "Failed to find installation information in ${VBOX_FOLDER}.\n" 158 . "${VBOX_FOLDER}/scripts/generated.sh" 161 159 162 160 # Parse our arguments. 163 161 while [ "$#" -gt 0 ]; do 164 162 case $1 in 165 -d|--daemonize) 166 DAEMONIZE=true 167 ;; 168 -l|--log-folder) 163 -c|--conf-file) 169 164 [ "$#" -gt 1 ] || 170 171 172 173 174 HEADLESS_X_ORG_LOG_FOLDER="$2"165 { 166 banner 167 abort "%s requires at least one argument.\n" "$1" 168 } 169 CONFIGURATION_FILE="$2" 175 170 shift 176 171 ;; 177 -p|--pidfile)178 [ "$#" -gt 1 ] ||179 {180 banner181 abort "%s requires at least one argument.\n" "$1"182 }183 HEADLESS_X_ORG_PID_FILE="$2"184 shift185 ;;186 -q|--quiet)187 QUIET=true188 ;;189 --quick)190 QUICK=true191 ;;192 172 --help|--usage) 173 banner 193 174 usage 194 175 exit 0 195 176 ;; 196 177 *) 197 { 198 banner 199 abort_usage "Unknown argument $1.\n" 200 } 178 banner 179 abort_usage "Unknown argument $1.\n" 201 180 ;; 202 181 esac … … 204 183 done 205 184 206 [ -z "${QUIET}" ] && banner 207 208 if [ -z "${QUICK}" ]; then 209 [ -f "${HEADLESS_X_ORG_PID_FILE}" ] && 210 ps -p "$(cat "${HEADLESS_X_ORG_PID_FILE}")" -o comm | 211 grep -q "${SERVICE_NAME}" && 212 abort "The service appears to be already running.\n" 213 214 PIDFILE_DIRECTORY="$(dirname "${HEADLESS_X_ORG_PID_FILE}")" 215 { ! [ -d "${PIDFILE_DIRECTORY}" ] || ! [ -w "${PIDFILE_DIRECTORY}" ]; } && 216 abort "Can't write to pid-file directory \"${PIDFILE_DIRECTORY}\".\n" 217 218 # If something fails here we will catch it when we create the directory. 219 [ -e "${HEADLESS_X_ORG_LOG_FOLDER}" ] && 220 [ -d "${HEADLESS_X_ORG_LOG_FOLDER}" ] && 221 rm -rf "${HEADLESS_X_ORG_LOG_FOLDER}.old" 2> /dev/null && 222 mv "${HEADLESS_X_ORG_LOG_FOLDER}" "${HEADLESS_X_ORG_LOG_FOLDER}.old" 2> /dev/null 223 mkdir -p "${HEADLESS_X_ORG_LOG_FOLDER}" 2>/dev/null || 224 abort "Failed to create log folder \"${HEADLESS_X_ORG_LOG_FOLDER}\".\n" 225 fi # -z "${QUICK}" 226 227 # Double background from shell script, disconnecting all standard streams, to 228 # daemonise. This may fail if someone has connected something to another file 229 # descriptor. This is intended (see e.g. fghack in the daemontools package). 230 if [ -n "${DAEMONIZE}" ]; then 231 ("${SCRIPT_NAME}" --quick -p "${HEADLESS_X_ORG_PID_FILE}" < /dev/null > "${HEADLESS_X_ORG_LOG_FOLDER}/${SERVICE_NAME}.log" 2>&1 &) & 232 ## @todo wait for the servers to start accepting connections before exiting. 233 exit 0 234 fi 185 [ -r "${CONFIGURATION_FILE}" ] && . "${CONFIGURATION_FILE}" 186 187 # If something fails here we will catch it when we create the directory. 188 [ -e "${HEADLESS_X_ORG_LOG_FOLDER}" ] && 189 [ -d "${HEADLESS_X_ORG_LOG_FOLDER}" ] && 190 rm -rf "${HEADLESS_X_ORG_LOG_FOLDER}.old" 2> /dev/null && 191 mv "${HEADLESS_X_ORG_LOG_FOLDER}" "${HEADLESS_X_ORG_LOG_FOLDER}.old" 2> /dev/null 192 mkdir -p "${HEADLESS_X_ORG_LOG_FOLDER}" 2>/dev/null || 193 { 194 banner 195 abort "Failed to create log folder \"${HEADLESS_X_ORG_LOG_FOLDER}\".\n" 196 } 197 exec > "${HEADLESS_X_ORG_LOG_FOLDER}/${HEADLESS_X_ORG_LOG_FILE}" 2>&1 198 199 banner 235 200 236 201 X_SERVER_PIDS="" 237 trap "kill \${X_SERVER_PIDS} 2>/dev/null ; exit 0" ${EXIT_SIGNALS}202 trap "kill \${X_SERVER_PIDS} 2>/dev/null" ${EXIT_SIGNALS} 238 203 space="" # Hack to put spaces between the pids but not before or after. 239 for file in "${HEADLESS_X_ORG_CONFIGURATION_DIRECTORY}"/xorg.conf.*; do 240 filename="$(basename "${file}")" 241 expr "${filename}" : "xorg.conf.[0-9]*" > /dev/null || 242 { stop; abort "Badly formed file name \"${file}\".\n"; } 243 screen="${filename##*.}" 244 Xorg ":${screen}" -config "${file}" -logverbose 0 -logfile /dev/null -verbose 7 > "${HEADLESS_X_ORG_LOG_FOLDER}/Xorg.${screen}.log" 2>&1 & 204 for conf_file in "${HEADLESS_X_ORG_CONFIGURATION_FOLDER}"/*; do 205 [ x"${conf_file}" = x"${HEADLESS_X_ORG_CONFIGURATION_FOLDER}/*" ] && 206 ! [ -e "${conf_file}" ] && 207 abort "No configuration files found.\n" 208 filename="$(basename "${conf_file}")" 209 screen="$(expr "${filename}" : "xorg\.conf\.\(.*\)")" 210 [ 0 -le "${screen}" ] 2>/dev/null || 211 abort "Badly formed file name \"${conf_file}\".\n" 212 log_file="${HEADLESS_X_ORG_LOG_FOLDER}/$(eval echo "${HEADLESS_X_ORG_SERVER_LOG_FILE_TEMPLATE}")" 213 eval "${HEADLESS_X_ORG_SERVER_COMMAND}" "&" 245 214 X_SERVER_PIDS="${X_SERVER_PIDS}${space}$!" 246 215 space=" " 247 216 done 248 [ -n "${HEADLESS_X_ORG_PID_FILE}" ] &&249 echo "$$" > "${HEADLESS_X_ORG_PID_FILE}"250 217 wait -
trunk/src/VBox/Installer/linux/testcase/Makefile.kmk
r41477 r43688 39 39 $(QUIET)$(CHMOD) a+rx,u+w $@ 40 40 41 INSTALLS += tstHeadlessXOrg 42 TESTING += tstHeadlessXOrg 43 tstHeadlessXOrg_INST = $(INST_TESTCASE) 44 tstHeadlessXOrg_MODE = a+rx,u+w 45 tstHeadlessXOrg_SOURCES = tstHeadlessXOrg.sh 46 41 47 include $(FILE_KBUILD_SUB_FOOTER)
Note:
See TracChangeset
for help on using the changeset viewer.