module System.Xen.Mid
( interfaceOpen
, interfaceClose
, domainGetInfo
) where
import Control.Monad (void, when, forM)
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Storable (peekElemOff, sizeOf)
import Control.Monad.Catch (throwM)
import Control.Monad.Trans (MonadIO(liftIO))
import System.Xen.Errors (DomainGetInfoError(..), XcHandleOpenError(..), getErrno)
import System.Xen.Low (xc_interface_open, xc_interface_close, xc_domain_getinfo)
import System.Xen.Types (XcHandle(..), DomId(..), DomainInfo)
interfaceOpen :: MonadIO m => m XcHandle
interfaceOpen = liftIO $ do
i@(XcHandle ptr) <- xc_interface_open 0 0 0
when (ptr `elem` [1, 0]) $ getErrno >>= throwM . XcHandleOpenError
return i
interfaceClose :: (MonadIO m, Functor m) => XcHandle -> m ()
interfaceClose = void . liftIO . xc_interface_close
domainGetInfo :: MonadIO m => XcHandle -> m [DomainInfo]
domainGetInfo handle = liftIO $ allocaBytes size $ \ptr -> do
wrote <- fmap fromIntegral $ xc_domain_getinfo handle (dom0) count ptr
when (wrote == 1) $ getErrno >>= throwM . DomainGetInfoError
forM [0 .. wrote 1] $ peekElemOff ptr
where
dom0 = DomId 0
count :: Num a => a
count = 1024
size = count * sizeOf (undefined :: DomainInfo)