Safe Haskell | Safe-Infered |
---|
KVM daemon
The KVM daemon is responsible for determining whether a given KVM instance was shutdown by an administrator or a user. For more information read the design document on the KVM daemon.
The KVM daemon design is split in 2 parts, namely, monitors for Qmp sockets and directory/file watching.
The monitors are spawned in lightweight Haskell threads and are reponsible for handling the communication between the KVM daemon and the KVM instance using the Qmp protocol. During the communcation, the monitor parses the Qmp messages and if powerdown or shutdown is received, then the shutdown file is written in the KVM control directory. Otherwise, when the communication terminates, that same file is removed. The communication terminates when the KVM instance stops or crashes.
The directory and file watching uses inotify to track down events on the KVM control directory and its parents. There is a directory crawler that will try to add a watch to the KVM control directory if available or its parents, thus replacing watches until the KVM control directory becomes available. When this happens, a monitor for the Qmp socket is spawned. Given that the KVM daemon might stop or crash, the directory watching also simulates events for the Qmp sockets that already exist in the KVM control directory when the KVM daemon starts.
- type Lock = MVar ()
- type Monitors = MVar (Set FilePath)
- isPrefixPath :: FilePath -> FilePath -> Bool
- monitorGreeting :: String
- monitorDir :: String
- monitorExtension :: String
- isMonitorPath :: FilePath -> Bool
- shutdownExtension :: String
- shutdownPath :: String -> String
- touchFile :: FilePath -> IO ()
- parseQmp :: Bool -> Bool -> Bool -> String -> (Bool, Bool, Bool)
- receiveQmp :: Handle -> IO Bool
- detectMonitor :: FilePath -> Handle -> IO ()
- runMonitor :: FilePath -> IO ()
- ensureMonitor :: Monitors -> FilePath -> IO ()
- handleGenericEvent :: Lock -> String -> String -> Event -> IO ()
- handleTargetEvent :: Lock -> Monitors -> String -> Event -> IO ()
- handleDir :: Lock -> Monitors -> String -> String -> Event -> IO ()
- recapDir :: Lock -> Monitors -> FilePath -> IO ()
- watchDir :: Lock -> FilePath -> INotify -> IO ()
- rewatchDir :: Lock -> FilePath -> INotify -> IO ()
- startWith :: FilePath -> IO ()
- start :: IO ()
Documentation
Utils
isPrefixPath :: FilePath -> FilePath -> BoolSource
isPrefixPath x y
determines whether x
is a FilePath
prefix
of FilePath
y
.
monitorGreeting :: StringSource
monitorDir :: StringSource
KVM control directory containing the Qmp sockets.
monitorExtension :: StringSource
isMonitorPath :: FilePath -> BoolSource
shutdownExtension :: StringSource
shutdownPath :: String -> StringSource
Monitors for Qmp sockets
parseQmp :: Bool -> Bool -> Bool -> String -> (Bool, Bool, Bool)Source
parseQmp isPowerdown isShutdown isStop str
parses the packet
str
and returns whether a powerdown, shutdown, or stop event is
contained in that packet, defaulting to the values isPowerdown
,
isShutdown
, and isStop
, otherwise.
receiveQmp :: Handle -> IO BoolSource
receiveQmp handle
listens for Qmp events on handle
and, when
handle
is closed, it returns True
if a user shutdown event was
received, and False
otherwise.
detectMonitor :: FilePath -> Handle -> IO ()Source
detectMonitor monitorFile handle
listens for Qmp events on
handle
for Qmp socket monitorFile
and, when communcation
terminates, it either creates the shutdown file, if a user shutdown
was detected, or it deletes that same file, if an administrator
shutdown was detected.
runMonitor :: FilePath -> IO ()Source
runMonitor monitorFile
creates a monitor for the Qmp socket
monitorFile
and calls detectMonitor
.
ensureMonitor :: Monitors -> FilePath -> IO ()Source
ensureMonitor monitors monitorFile
ensures that there is
exactly one monitor running for the Qmp socket monitorFile
, given
the existing set of monitors monitors
.
Directory and file watching
handleGenericEvent :: Lock -> String -> String -> Event -> IO ()Source
Handles an inotify event outside the target directory.
Tracks events on the parent directory of the KVM control directory until one of its parents becomes available.
handleTargetEvent :: Lock -> Monitors -> String -> Event -> IO ()Source
Handles an inotify event in the target directory.
Upon a create or open event inside the KVM control directory, it ensures that there is a monitor running for the new Qmp socket.
handleDir :: Lock -> Monitors -> String -> String -> Event -> IO ()Source
Dispatches inotify events depending on the directory they occur in.
recapDir :: Lock -> Monitors -> FilePath -> IO ()Source
Simulates file creation events for the Qmp sockets that already
exist in dir
.
watchDir :: Lock -> FilePath -> INotify -> IO ()Source
Crawls tarDir
, or its parents until tarDir
becomes available,
always listening for inotify events.
Used for crawling the KVM control directory and its parents, as well as simulating file creation events.
rewatchDir :: Lock -> FilePath -> INotify -> IO ()Source