mirror of https://github.com/nocturn9x/nimd.git
Added VERY experimental (untested) networking code
This commit is contained in:
parent
fea5e625e2
commit
2f107f7f28
|
@ -11,3 +11,26 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import os
|
||||
import net
|
||||
import strformat
|
||||
import shutdown
|
||||
|
||||
|
||||
import ../util/logging
|
||||
import ../util/misc
|
||||
|
||||
|
||||
proc initControlSocket*(logger: Logger, path: string = "/var/run/nimd.sock"): Socket =
|
||||
## Initializes NimD's control socket (an unbuffered
|
||||
## TCP Unix Domain Socket) binding it to the given
|
||||
## path (defaults to /var/run/nimd.sock)
|
||||
try:
|
||||
logger.info(&"Initializing control socket at '{path}'")
|
||||
if exists(path):
|
||||
removeFile(path)
|
||||
result = newSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP, buffered=false)
|
||||
bindUnix(result, path)
|
||||
except OSError:
|
||||
logger.error(&"Error when binding unix socket at '{path}': {getCurrentExceptionMsg()}")
|
||||
nimDExit(logger, code=int(osLastError()))
|
|
@ -13,10 +13,13 @@
|
|||
# limitations under the License.
|
||||
import strformat
|
||||
import os
|
||||
import net
|
||||
|
||||
|
||||
import ../util/[logging, misc]
|
||||
import services
|
||||
import control
|
||||
import shutdown
|
||||
|
||||
|
||||
|
||||
|
@ -27,10 +30,43 @@ proc mainLoop*(logger: Logger) =
|
|||
logger.debug(&"Unblocking signals")
|
||||
unblockSignals(logger)
|
||||
logger.info("System initialization complete, going idle")
|
||||
logger.switchToFile()
|
||||
var opType: string
|
||||
try:
|
||||
logger.trace("Calling initControlSocket()")
|
||||
var serverSocket = initControlSocket(logger)
|
||||
serverSocket.listen(5)
|
||||
var clientSocket = newSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
|
||||
# logger.switchToFile()
|
||||
while true:
|
||||
sleepSeconds(30)
|
||||
serverSocket.accept(clientSocket)
|
||||
if clientSocket.recv(opType, size=1) == 0:
|
||||
logger.debug(&"Client has disconnected, waiting for new connection")
|
||||
continue
|
||||
logger.debug(&"Received operation type '{opType}' via control socket")
|
||||
# The operation type is a single byte:
|
||||
# - 'p' -> poweroff
|
||||
# - 'r' -> reboot
|
||||
# - 'h' -> halt
|
||||
# - 's' -> Services-related operations (start, stop, get status, etc.)
|
||||
case opType:
|
||||
of "":
|
||||
logger.debug(&"Empty read from control socket: did the client disconnect?")
|
||||
continue
|
||||
of "p":
|
||||
logger.info("Received shutdown request")
|
||||
shutdown(logger)
|
||||
of "r":
|
||||
logger.info("Received reboot request")
|
||||
reboot(logger)
|
||||
of "h":
|
||||
logger.info("Received halt request")
|
||||
halt(logger)
|
||||
of "s":
|
||||
discard # TODO
|
||||
else:
|
||||
logger.warning(&"Received unknown operation type '{opType}' via control socket, ignoring it")
|
||||
discard
|
||||
clientSocket.close()
|
||||
except:
|
||||
logger.critical(&"A critical error has occurred while running, restarting the mainloop in 30 seconds! Error -> {getCurrentExceptionMsg()}")
|
||||
sleepSeconds(30)
|
||||
|
|
|
@ -327,8 +327,9 @@ proc startService(logger: Logger, service: Service) =
|
|||
elif pid == 0:
|
||||
logger.trace(&"New child has been spawned")
|
||||
supervisorWorker(logger, service, process)
|
||||
# If the service is unsupervised we just spawn the logger worker
|
||||
loggerWorker(logger, service, process)
|
||||
# If the service is unsupervised we just spawn the logger worker (assuming it doesn't use poParentStreams)
|
||||
if not service.useParentStreams:
|
||||
loggerWorker(logger, service, process)
|
||||
except:
|
||||
logger.error(&"Error while starting service '{service.name}': {getCurrentExceptionMsg()}")
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ import glob
|
|||
import strutils
|
||||
import strformat
|
||||
import times
|
||||
import tables
|
||||
import syscall
|
||||
|
||||
|
||||
import ../util/logging
|
||||
|
@ -29,6 +31,9 @@ type ShutdownHandler* = ref object
|
|||
body*: proc (logger: Logger, code: int)
|
||||
|
||||
|
||||
const reboot_codes = {"poweroff": 0x4321fedc'i64, "restart": 0x01234567'i64, "halt": 0xcdef0123}.toTable()
|
||||
|
||||
|
||||
proc newShutdownHandler*(body: proc (logger: Logger, code: int)): ShutdownHandler =
|
||||
result = ShutdownHandler(body: body)
|
||||
|
||||
|
@ -80,6 +85,7 @@ proc nimDExit*(logger: Logger, code: int, emerg: bool = true) =
|
|||
## NimD's exit point. This function tries to shut down
|
||||
## as cleanly as possible. When emerg equals true, it will
|
||||
## try to spawn a root shell and exit
|
||||
logger.switchToConsole()
|
||||
if emerg:
|
||||
# We're in emergency mode: do not crash the kernel, spawn a shell and exit
|
||||
logger.fatal("NimD has entered emergency mode and cannot continue. You will be now (hopefully) dropped in a root shell: you're on your own. May the force be with you")
|
||||
|
@ -89,7 +95,7 @@ proc nimDExit*(logger: Logger, code: int, emerg: bool = true) =
|
|||
quit(-1)
|
||||
logger.warning("The system is shutting down")
|
||||
logger.info("Processing shutdown runlevel")
|
||||
startServices(logger, Shutdown)
|
||||
startServices(logger, RunLevel.Shutdown)
|
||||
logger.info("Running shutdown handlers")
|
||||
try:
|
||||
for handler in shutdownHandlers:
|
||||
|
@ -108,4 +114,30 @@ proc nimDExit*(logger: Logger, code: int, emerg: bool = true) =
|
|||
logger.info("Terminating child processes with SIGKILL")
|
||||
discard posix.kill(-1, SIGKILL)
|
||||
logger.warning("Shutdown procedure complete, sending final termination signal")
|
||||
quit(code)
|
||||
|
||||
|
||||
proc reboot*(logger: Logger) =
|
||||
## Reboots the system
|
||||
logger.debug("Switching logs to console")
|
||||
logger.switchToConsole()
|
||||
logger.info("The system is rebooting")
|
||||
nimDExit(logger, 0, emerg=false)
|
||||
discard syscall(REBOOT, 0xfee1dead, 537993216, reboot_codes["reboot"])
|
||||
|
||||
|
||||
proc shutdown*(logger: Logger) =
|
||||
## Shuts the system off
|
||||
logger.debug("Switching logs to console")
|
||||
logger.switchToConsole()
|
||||
logger.info("The system is powering off")
|
||||
nimDExit(logger, 0, emerg=false)
|
||||
discard syscall(REBOOT, 0xfee1dead, 537993216, reboot_codes["poweroff"])
|
||||
|
||||
|
||||
proc halt*(logger: Logger) =
|
||||
## Halts the system
|
||||
logger.debug("Switching logs to console")
|
||||
logger.switchToConsole()
|
||||
logger.info("The system is halting")
|
||||
nimDExit(logger, 0, emerg=false)
|
||||
discard syscall(REBOOT, 0xfee1dead, 537993216, reboot_codes["halt"])
|
||||
|
|
Loading…
Reference in New Issue