diff --git a/README.md b/README.md
index 69b64cf..e0f11d5 100644
--- a/README.md
+++ b/README.md
@@ -38,11 +38,15 @@ If `firestarter` is invoked without any arguments, it will attempt to start a se
 
 * `list`, `ls`: List all configuration files and, if they are fsdefaults files, resolve them. Useful for debugging.
 
+* `logout`: Kill Firestarter, if it's running.
+
+* `restart`: Stop a running service and start it back up again. Does not fail on dead services.
+
 * `start`: Start a configuration file, redirecting output to the proper logs and dropping its PID in `/run` for existing Firestarter instances to use.
 
 * `status`, `st`, `stat`: Prints information about the running Firestarter session, including PID, display, and the state of all services.
 
-* `stop`: Kill Firestarter, if it's running.
+* `stop`: Stop a running service
 
 ## Logging
 
diff --git a/firestarter b/firestarter
index 2e0f471..f2af349 100755
--- a/firestarter
+++ b/firestarter
@@ -23,6 +23,8 @@ declare -i _optverbose
 declare -a _args
 declare -i _hasdbus
 declare _return
+# Junk FD used for read waiting
+exec 1023<> <(:)
 
 # Helper functions
 log() {
@@ -107,6 +109,37 @@ gettarget() {
 	done < "$1"
 	return 2
 }
+fskill() {
+	# Kill any number of PIDs, validating inputs n stuff
+	for pid in $@; do
+		# Sanity checks
+		[ -z "$pid" ] && continue
+		[ "$pid" -gt 0 ] 2> /dev/null || warn "Invalid PID: $pid" 2
+		[ -d "/proc/$pid" ] || warn "Process is already dead: $pid" 2
+		kill "$pid"
+		(
+		exec 1023<> <(:)
+		for (( i=0; i<10; i++ )); do
+			kill -0 "$pid" 2> /dev/null || return 0
+			read -t 1 -u 1023 || :
+		done
+		warn "Force stopping unresponsive process: $pid"
+		kill -9 "$pid"
+		)
+	done
+}
+fsstop() {
+	# Stop a running service by name
+	for service in $@; do
+		pidfile="$_optrundir"/"$service".pid
+		[ -f "$pidfile" ] || warn "Service is not already running: $service"
+		pid="$(< $pidfile)"
+		[ "$pid" -gt 0 ] 2> /dev/null || error "PID is invalid for service: $service (PID $pid)" 51
+		[ -d "/proc/$pid" ] || warn "Service is already dead: $service"
+		[ -d "/proc/$pid" ] && fskill "$pid"
+		return 0
+	done
+}
 fsexec() {
 	# Execute an fsdefaults file
 	[ -z "$1" ] && return 1
@@ -448,7 +481,7 @@ step_logout() {
 		fi
 	else
 		# Otherwise just brute it out
-		kill $(jobs -p)
+		fskill $(jobs -p)
 	fi
 	return 0
 }
@@ -468,8 +501,11 @@ provided
 
   init			Start all services and wait
   list			List all valid services
-  start			Start the provided service, fork, and exit
+  logout		Log out of an existing Firestarter session
+  restart		Stop and restart the provided services
+  start			Start the provided services, fork, and exit
   status		Show status information
+  stop			Stop the provided services
 
 Environment Variables:
 
@@ -496,6 +532,12 @@ firestart() {
 		ls|list)
 			fslist
 			;;
+		restart)
+			for file in "${_args[@]:1}"; do
+				fsstop "$file"
+				fsexec "$_optconfigdir"/"$file"
+			done
+			;;
 		start)
 			for file in "${_args[@]:1}"; do
 				fsexec "$_optconfigdir"/"$file"
@@ -505,6 +547,11 @@ firestart() {
 			fsstatus
 			;;
 		stop)
+			for file in "${_args[@]:1}"; do
+				fsstop "$file"
+			done
+			;;
+		logout)
 			if [ -n "$FIRESTARTER" ] && [ -d "/proc/$FIRESTARTER" ] && [ "$FIRESTARTER" -gt 0 ] 2> /dev/null; then
 				log "Killing PID $FIRESTARTER"
 				kill $FIRESTARTER