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.Exception.Lifted (throwIO)
import Control.Monad.Base (MonadBase(liftBase))
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 :: MonadBase IO m => m XcHandle
interfaceOpen = liftBase $ do
i@(XcHandle ptr) <- xc_interface_open 0 0 0
when (ptr `elem` [1, 0]) $ getErrno >>= throwIO . XcHandleOpenError
return i
interfaceClose :: MonadBase IO m => XcHandle -> m ()
interfaceClose = void . liftBase . xc_interface_close
domainGetInfo :: MonadBase IO m => XcHandle -> m [DomainInfo]
domainGetInfo handle = liftBase $ allocaBytes size $ \ptr -> do
wrote <- fmap fromIntegral $ xc_domain_getinfo handle (dom0) count ptr
when (wrote == 1) $ getErrno >>= throwIO . DomainGetInfoError
forM [0 .. wrote 1] $ peekElemOff ptr
where
dom0 = DomId 0
count :: Num a => a
count = 1024
size = count * sizeOf (undefined :: DomainInfo)