mirror of https://github.com/nocturn9x/nimd.git
Added sync() system call for testing purposes. Added SIGSTP signal handler. Removed CtrlCException. Added dummy SIGCHLD handler for future process reaping. NimD now creates some symlinks at startup so Linux ports of BSD software don't crash. Moved exists procedure to misc module. UnmountAllDisks now unmounts the source instead of the target. Other minor fixes and typos
This commit is contained in:
parent
6ef157baa0
commit
bd7d4e1974
|
@ -0,0 +1,3 @@
|
||||||
|
.git
|
||||||
|
nimd
|
||||||
|
src/main
|
|
@ -6,6 +6,7 @@ WORKDIR /code
|
||||||
# Removes any already existing binary so that when compilation fails the container stops
|
# Removes any already existing binary so that when compilation fails the container stops
|
||||||
RUN rm -f /code/nimd
|
RUN rm -f /code/nimd
|
||||||
RUN rm -f /code/main
|
RUN rm -f /code/main
|
||||||
|
RUN nimble install syscall -y
|
||||||
RUN nim -d:release --opt:size --passL:"-static" --gc:orc -d:useMalloc c -o:nimd src/main
|
RUN nim -d:release --opt:size --passL:"-static" --gc:orc -d:useMalloc c -o:nimd src/main
|
||||||
RUN cp /code/nimd /sbin/nimd
|
RUN cp /code/nimd /sbin/nimd
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,12 @@ proc mainLoop*(logger: Logger, mountDisks: bool = true, fstab: string = "/etc/fs
|
||||||
logger.fatal(&"A fatal error has occurred while preparing filesystem, booting cannot continue. Error -> {getCurrentExceptionMsg()}")
|
logger.fatal(&"A fatal error has occurred while preparing filesystem, booting cannot continue. Error -> {getCurrentExceptionMsg()}")
|
||||||
nimDExit(logger, 131)
|
nimDExit(logger, 131)
|
||||||
logger.info("Disks mounted")
|
logger.info("Disks mounted")
|
||||||
|
logger.debug("Calling sync() just in case")
|
||||||
|
doSync(logger)
|
||||||
logger.info("Setting hostname")
|
logger.info("Setting hostname")
|
||||||
logger.debug(&"Hostname was set to '{setHostname(logger)}'")
|
logger.debug(&"Hostname was set to '{setHostname(logger)}'")
|
||||||
|
logger.info("Creating symlinks")
|
||||||
|
createSymlinks(logger)
|
||||||
logger.info("Processing boot runlevel")
|
logger.info("Processing boot runlevel")
|
||||||
# TODO
|
# TODO
|
||||||
logger.info("Processing default runlevel")
|
logger.info("Processing default runlevel")
|
||||||
|
@ -46,9 +50,6 @@ proc mainLoop*(logger: Logger, mountDisks: bool = true, fstab: string = "/etc/fs
|
||||||
try:
|
try:
|
||||||
# TODO
|
# TODO
|
||||||
sleepSeconds(5)
|
sleepSeconds(5)
|
||||||
except CtrlCException:
|
|
||||||
logger.warning("Main process received SIGINT: exiting") # TODO: Ignore this once we stop testing on our local machines lol
|
|
||||||
nimDExit(logger, 130, emerg=false) # 130 - Interrupted by SIGINT
|
|
||||||
except:
|
except:
|
||||||
logger.critical(&"A critical error has occurred while running, restarting the mainloop! Error -> {getCurrentExceptionMsg()}")
|
logger.critical(&"A critical error has occurred while running, restarting the mainloop! Error -> {getCurrentExceptionMsg()}")
|
||||||
# We *absolutely* cannot die
|
# We *absolutely* cannot die
|
||||||
|
|
|
@ -37,11 +37,14 @@ proc main(logger: Logger) =
|
||||||
logger.fatal(&"NimD must run as root, but current user id is {uid}")
|
logger.fatal(&"NimD must run as root, but current user id is {uid}")
|
||||||
quit(EPERM) # EPERM - Operation not permitted
|
quit(EPERM) # EPERM - Operation not permitted
|
||||||
logger.debug("Setting up dummy signal handlers")
|
logger.debug("Setting up dummy signal handlers")
|
||||||
onSignal(SIGABRT, SIGALRM, SIGHUP, SIGILL, SIGKILL, SIGQUIT, SIGSTOP, SIGSEGV,
|
onSignal(SIGABRT, SIGALRM, SIGHUP, SIGILL, SIGKILL, SIGQUIT, SIGSTOP, SIGSEGV, SIGTSTP,
|
||||||
SIGTRAP, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, 6, SIGFPE, SIGBUS, SIGURG, SIGINT): # 6 is SIGIOT
|
SIGTRAP, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, 6, SIGFPE, SIGBUS, SIGURG, SIGINT): # 6 is SIGIOT
|
||||||
# Can't capture local variables because this implicitly generates
|
# Can't capture local variables because this implicitly generates
|
||||||
# a noconv procedure
|
# a noconv procedure
|
||||||
getDefaultLogger().warning(&"Ignoring signal {sig} ({strsignal(sig)})") # Nim injects the variable "sig" into the scope. Gotta love those macros
|
getDefaultLogger().warning(&"Ignoring signal {sig} ({strsignal(sig)})") # Nim injects the variable "sig" into the scope. Gotta love those macros
|
||||||
|
logger.debug("Setting up SIGCHLD signal handler")
|
||||||
|
onSignal(SIGCHLD):
|
||||||
|
reapProcess(getDefaultLogger())
|
||||||
logger.debug("Starting uninterruptible mainloop")
|
logger.debug("Starting uninterruptible mainloop")
|
||||||
mainLoop(logger)
|
mainLoop(logger)
|
||||||
|
|
||||||
|
|
|
@ -115,16 +115,6 @@ proc umount*(target: string): int = int(umount(cstring(target)))
|
||||||
proc umount2*(target: string, flags: int): int = int(umount2(cstring(target), cint(flags)))
|
proc umount2*(target: string, flags: int): int = int(umount2(cstring(target), cint(flags)))
|
||||||
|
|
||||||
|
|
||||||
proc exists(p: string): bool =
|
|
||||||
# Checks if a path exists. Thanks
|
|
||||||
# araq :)
|
|
||||||
try:
|
|
||||||
discard getFileInfo(p)
|
|
||||||
result = true
|
|
||||||
except OSError:
|
|
||||||
result = false
|
|
||||||
|
|
||||||
|
|
||||||
proc checkDisksIsMounted(search: tuple[source, target, filesystemtype: string, mountflags: uint64, data: string, dump, pass: uint8], expand: bool = false): bool =
|
proc checkDisksIsMounted(search: tuple[source, target, filesystemtype: string, mountflags: uint64, data: string, dump, pass: uint8], expand: bool = false): bool =
|
||||||
## Returns true if a disk is already mounted. If expand is true,
|
## Returns true if a disk is already mounted. If expand is true,
|
||||||
## symlinks are expanded and checked instead of doing a simple
|
## symlinks are expanded and checked instead of doing a simple
|
||||||
|
@ -211,9 +201,9 @@ proc unmountAllDisks*(logger: Logger, code: int) =
|
||||||
logger.debug(&"Skipping unmounting filesystem {entry.source} ({entry.filesystemtype}) from {entry.target}: not mounted")
|
logger.debug(&"Skipping unmounting filesystem {entry.source} ({entry.filesystemtype}) from {entry.target}: not mounted")
|
||||||
continue
|
continue
|
||||||
logger.debug(&"Unmounting filesystem {entry.source} ({entry.filesystemtype}) from {entry.target}")
|
logger.debug(&"Unmounting filesystem {entry.source} ({entry.filesystemtype}) from {entry.target}")
|
||||||
logger.trace(&"Calling umount2('{entry.target}', MNT_DETACH)")
|
logger.trace(&"Calling umount2('{entry.source}', MNT_DETACH)")
|
||||||
retcode = umount2(entry.target, 2) # 2 = MNT_DETACH - Since we're shutting down, we need the disks to be *gone*!
|
retcode = umount2(entry.source, 2) # 2 = MNT_DETACH - Since we're shutting down, we need the disks to be *gone*!
|
||||||
logger.trace(&"umount2('{entry.target}', MNT_DETACH) returned {retcode}")
|
logger.trace(&"umount2('{entry.source}', MNT_DETACH) returned {retcode}")
|
||||||
if retcode == -1:
|
if retcode == -1:
|
||||||
logger.error(&"Unmounting disk {entry.source} from {entry.target} has failed with error {posix.errno}: {posix.strerror(posix.errno)}")
|
logger.error(&"Unmounting disk {entry.source} from {entry.target} has failed with error {posix.errno}: {posix.strerror(posix.errno)}")
|
||||||
# Resets the error code
|
# Resets the error code
|
||||||
|
|
|
@ -17,16 +17,45 @@
|
||||||
import os
|
import os
|
||||||
import strformat
|
import strformat
|
||||||
import strutils
|
import strutils
|
||||||
|
import syscall
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
type CtrlCException* = object of CatchableError
|
# Note: This will work reliably only with absolute paths. Use with care
|
||||||
|
const symlinks: array[7, tuple[dest, source: string]] = [
|
||||||
|
(dest: "/dev/fd", source: "/proc/self/fd"),
|
||||||
|
(dest: "/dev/fd/0", source: "/proc/self/fd/0"),
|
||||||
|
(dest: "/dev/fd/1", source: "/proc/self/fd/1"),
|
||||||
|
(dest: "/dev/fd/2", source: "/proc/self/fd/2"),
|
||||||
|
(dest: "/dev/std/in", source: "/proc/self/fd/0"),
|
||||||
|
(dest: "/dev/std/out", source: "/proc/self/fd/1"),
|
||||||
|
(dest: "/dev/std/err", source: "/proc/self/fd/2"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var shutdownHandlers: seq[proc (logger: Logger, code: int)] = @[]
|
var shutdownHandlers: seq[proc (logger: Logger, code: int)] = @[]
|
||||||
|
|
||||||
|
|
||||||
|
proc doSync*(logger: Logger) =
|
||||||
|
logger.debug(&"Calling sync() syscall has returned {syscall(SYNC)}")
|
||||||
|
|
||||||
|
|
||||||
|
proc reapProcess*(logger: Logger) =
|
||||||
|
logger.debug("Handling SIGCHLD")
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
|
||||||
|
proc exists*(p: string): bool =
|
||||||
|
# Checks if a path exists. Thanks
|
||||||
|
# araq :)
|
||||||
|
try:
|
||||||
|
discard getFileInfo(p)
|
||||||
|
result = true
|
||||||
|
except OSError:
|
||||||
|
result = false
|
||||||
|
|
||||||
|
|
||||||
proc addShutdownHandler*(handler: proc (logger: Logger, code: int), logger: Logger) =
|
proc addShutdownHandler*(handler: proc (logger: Logger, code: int), logger: Logger) =
|
||||||
shutdownHandlers.add(handler)
|
shutdownHandlers.add(handler)
|
||||||
|
|
||||||
|
@ -83,7 +112,31 @@ proc setHostname*(logger: Logger): string =
|
||||||
return hostname
|
return hostname
|
||||||
|
|
||||||
|
|
||||||
|
proc createSymlinks*(logger: Logger) =
|
||||||
|
## Creates a set of symlinks needed
|
||||||
|
## by stuff like Linux ports of BSD
|
||||||
|
## software
|
||||||
|
for sym in symlinks:
|
||||||
|
try:
|
||||||
|
if not exists(sym.source):
|
||||||
|
logger.warning(&"Skipping creation of symbolic link from {sym.dest} to {sym.source}: destination does not exist")
|
||||||
|
continue
|
||||||
|
elif exists(sym.dest):
|
||||||
|
if symlinkExists(sym.dest) and sameFile(expandSymlink(sym.dest), sym.source):
|
||||||
|
logger.debug(&"Skipping creation of symbolic link from {sym.dest} to {sym.source}: link already exists")
|
||||||
|
elif symlinkExists(sym.dest) and not sameFile(expandSymlink(sym.dest), sym.source):
|
||||||
|
logger.warning(&"Attempted to create symbolic link from {sym.dest} to {sym.source}, but link already exists and points to {expandSymlink(sym.dest)}")
|
||||||
|
continue
|
||||||
|
logger.debug(&"Creating symbolic link from {sym.source} to {sym.dest}")
|
||||||
|
createSymlink(sym.dest, sym.source)
|
||||||
|
except:
|
||||||
|
logger.error(&"Failed to create symbolic link from {sym.dest} to {sym.source}: {getCurrentExceptionMsg()}")
|
||||||
|
|
||||||
|
|
||||||
|
proc createDirectories*(logger: Logger) =
|
||||||
|
## Creates
|
||||||
|
|
||||||
proc sleepSeconds*(amount: SomeInteger) = sleep(amount * 1000)
|
proc sleepSeconds*(amount: SomeInteger) = sleep(amount * 1000)
|
||||||
|
|
||||||
|
|
||||||
proc strsignal*(sig: cint): cstring {.header:"string.h", importc.}
|
proc strsignal*(sig: cint): cstring {.header: "string.h", importc.}
|
||||||
|
|
Loading…
Reference in New Issue