packages feed

hen 0.1.0.1 → 0.1.1

raw patch · 8 files changed

+163/−43 lines, 8 filesdep +tastydep +tasty-quickcheckdep −test-frameworkdep −test-framework-quickcheck2dep ~QuickCheckdep ~exceptionsPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: tasty, tasty-quickcheck

Dependencies removed: test-framework, test-framework-quickcheck2

Dependency ranges changed: QuickCheck, exceptions

API changes (from Hackage documentation)

+ System.Xen: domainDestroy :: MonadXen m => DomId -> m Bool
+ System.Xen: domainPause :: MonadXen m => DomId -> m Bool
+ System.Xen: domainShutdown :: MonadXen m => DomId -> DomainShutdownReason -> m Bool
+ System.Xen: domainUnpause :: MonadXen m => DomId -> m Bool
+ System.Xen.High: domainDestroy :: MonadXen m => DomId -> m Bool
+ System.Xen.High: domainPause :: MonadXen m => DomId -> m Bool
+ System.Xen.High: domainShutdown :: MonadXen m => DomId -> DomainShutdownReason -> m Bool
+ System.Xen.High: domainUnpause :: MonadXen m => DomId -> m Bool
+ System.Xen.Low: xc_domain_destroy :: XcHandle -> DomId -> IO CInt
+ System.Xen.Low: xc_domain_pause :: XcHandle -> DomId -> IO CInt
+ System.Xen.Low: xc_domain_shutdown :: XcHandle -> DomId -> CInt -> IO CInt
+ System.Xen.Low: xc_domain_unpause :: XcHandle -> DomId -> IO CInt
+ System.Xen.Mid: domainDestroy :: MonadIO m => DomId -> XcHandle -> m Bool
+ System.Xen.Mid: domainPause :: MonadIO m => DomId -> XcHandle -> m Bool
+ System.Xen.Mid: domainShutdown :: MonadIO m => DomId -> DomainShutdownReason -> XcHandle -> m Bool
+ System.Xen.Mid: domainUnpause :: MonadIO m => DomId -> XcHandle -> m Bool
- System.Xen: DomainInfo :: {-# UNPACK #-} !DomId -> {-# UNPACK #-} !Word32 -> BitSet DomainFlag -> Maybe DomainShutdownReason -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !UUID -> {-# UNPACK #-} !Word32 -> DomainInfo
+ System.Xen: DomainInfo :: {-# UNPACK #-} !DomId -> {-# UNPACK #-} !Word32 -> !(BitSet DomainFlag) -> !(Maybe DomainShutdownReason) -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !UUID -> {-# UNPACK #-} !Word32 -> DomainInfo
- System.Xen: domainInfoFlags :: DomainInfo -> BitSet DomainFlag
+ System.Xen: domainInfoFlags :: DomainInfo -> !(BitSet DomainFlag)
- System.Xen: domainInfoShutdownReason :: DomainInfo -> Maybe DomainShutdownReason
+ System.Xen: domainInfoShutdownReason :: DomainInfo -> !(Maybe DomainShutdownReason)
- System.Xen.Mid: domainGetInfo :: MonadIO m => XcHandle -> m [DomainInfo]
+ System.Xen.Mid: domainGetInfo :: (MonadIO m, Alternative t, Traversable t) => XcHandle -> m (t DomainInfo)
- System.Xen.Types: DomainInfo :: {-# UNPACK #-} !DomId -> {-# UNPACK #-} !Word32 -> BitSet DomainFlag -> Maybe DomainShutdownReason -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !UUID -> {-# UNPACK #-} !Word32 -> DomainInfo
+ System.Xen.Types: DomainInfo :: {-# UNPACK #-} !DomId -> {-# UNPACK #-} !Word32 -> !(BitSet DomainFlag) -> !(Maybe DomainShutdownReason) -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !Word32 -> {-# UNPACK #-} !UUID -> {-# UNPACK #-} !Word32 -> DomainInfo
- System.Xen.Types: domainInfoFlags :: DomainInfo -> BitSet DomainFlag
+ System.Xen.Types: domainInfoFlags :: DomainInfo -> !(BitSet DomainFlag)
- System.Xen.Types: domainInfoShutdownReason :: DomainInfo -> Maybe DomainShutdownReason
+ System.Xen.Types: domainInfoShutdownReason :: DomainInfo -> !(Maybe DomainShutdownReason)

Files

hen.cabal view
@@ -1,5 +1,5 @@ Name:               hen-Version:            0.1.0.1+Version:            0.1.1 Synopsis:           Haskell bindings to Xen hypervisor interface Description:        Haskell bindings to Xen hypervisor interface License:            MIT@@ -24,7 +24,7 @@     Build-depends:      base                      == 4.6.* || == 4.5.*                       , transformers              == 0.3.*                       , mtl                       == 2.1.* || == 2.0.*-                      , exceptions                == 0.1.*+                      , exceptions                == 0.3.*                       , uuid                      == 1.2.*                       , bitset                    == 1.4.* @@ -35,7 +35,7 @@                         System.Xen.Errors                         System.Xen.Mid                         System.Xen.Low-    Extra-libraries:    xenctrl+--    Extra-libraries:    xenctrl  Test-suite hen-tests     Main-is:          Tests.hs@@ -46,14 +46,14 @@     Build-depends:      base                      == 4.6.* || == 4.5.*                       , transformers              == 0.3.*                       , mtl                       == 2.1.* || == 2.0.*-                      , exceptions                == 0.1.*+                      , exceptions                == 0.3.*                       , uuid                      == 1.2.*                       , bitset                    == 1.4.*                       , hen -                      , test-framework             == 0.8.*-                      , test-framework-quickcheck2 == 0.3.*-                      , QuickCheck                 == 2.5.*+                      , tasty                      == 0.3.*+                      , tasty-quickcheck           == 0.3.*+                      , QuickCheck                 == 2.6.*  Source-repository head     Type:     git
src/System/Xen.hs view
@@ -31,14 +31,23 @@     , DomainShutdownReason(..)     , DomainInfo(..)     -- * High-level API+    -- ** Monad stuff     , XenT     , Xen-    , domainGetInfo     , runXenT+    -- ** Domain+    , domainGetInfo+    -- *** Domain pause+    , domainPause+    , domainUnpause+    -- *** Domain powerstate+    , domainShutdown+    , domainDestroy     ) where  import System.Xen.Errors (XcHandleOpenError(..), InvalidDomainShutdownReason(..),                           DomainGetInfoError(..))-import System.Xen.High (XenT, Xen, domainGetInfo, runXenT)+import System.Xen.High (XenT, Xen, domainGetInfo, domainPause, domainUnpause, domainShutdown,+                        domainDestroy, runXenT) import System.Xen.Types (DomId(..), DomainFlag(..), DomainShutdownReason(..),                          DomainInfo(..))
src/System/Xen/High.hs view
@@ -1,14 +1,23 @@ -- | High-level interface to @XenCtrl@. Contains `Xen` monad and provides a safe way -- to run any `Xen` computation. module System.Xen.High-    ( XenT+    (+    -- * Monad stuff+      XenT     , Xen-    , domainGetInfo     , runXenT+    -- * Domain+    , domainGetInfo+    -- ** Domain pause+    , domainPause+    , domainUnpause+    -- ** Domain powerstate+    , domainShutdown+    , domainDestroy     ) where  import System.Xen.High.Internal (XenT, Xen, MonadXen(withXenHandle), runXenT)-import System.Xen.Types (DomainInfo)+import System.Xen.Types (DomainInfo, DomId, DomainShutdownReason) import qualified System.Xen.Mid as Mid  -- | Returns a lift of domains, this function can fail with@@ -16,3 +25,22 @@ -- 'System.Xen.Errors.DomainGetInfoError'. domainGetInfo :: MonadXen m => m [DomainInfo] domainGetInfo = withXenHandle Mid.domainGetInfo++-- | Pause domain. A paused domain still exists in memory+-- however it does not receive any timeslices from the hypervisor.+domainPause :: MonadXen m => DomId -> m Bool+domainPause = withXenHandle . Mid.domainPause++-- | Unpause a domain. The domain should have been previously paused.+domainUnpause :: MonadXen m => DomId -> m Bool+domainUnpause = withXenHandle . Mid.domainUnpause++-- | Shutdown domain. This is intended for use in fully-virtualized domains where+-- this operation is analogous to the sched_op operations in a paravirtualized domain.+domainShutdown :: MonadXen m => DomId -> DomainShutdownReason -> m Bool+domainShutdown domid reason = withXenHandle $ Mid.domainShutdown domid reason++-- | Destroy a domain.  Destroying a domain removes the domain completely from memory.+-- This function should be called after 'domainShutdown' to free up the domain resources.+domainDestroy :: MonadXen m => DomId -> m Bool+domainDestroy = withXenHandle . Mid.domainDestroy
src/System/Xen/High/Internal.hs view
@@ -22,16 +22,16 @@ import Control.Monad.State (MonadState(..)) import Control.Monad.Writer (MonadWriter(..)) -import Control.Monad.Trans.Identity (IdentityT(..)) import Control.Monad.Trans (MonadIO, MonadTrans(lift))-import qualified Control.Monad.Trans.Cont as Cont-import qualified Control.Monad.Trans.Error as Error-import qualified Control.Monad.Trans.State.Lazy as LazyState-import qualified Control.Monad.Trans.State.Strict as StrictState-import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter-import qualified Control.Monad.Trans.Writer.Strict as StrictWriter-import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS-import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import Control.Monad.Trans.Identity (IdentityT(..))+import qualified Control.Monad.Cont as Cont+import qualified Control.Monad.Error as Error+import qualified Control.Monad.State.Lazy as LazyState+import qualified Control.Monad.State.Strict as StrictState+import qualified Control.Monad.Writer.Lazy as LazyWriter+import qualified Control.Monad.Writer.Strict as StrictWriter+import qualified Control.Monad.RWS.Lazy as LazyRWS+import qualified Control.Monad.RWS.Strict as StrictRWS  import System.Xen.Types (XcHandle) import qualified System.Xen.Mid as Mid@@ -76,9 +76,12 @@ -- * The @transformers@-style monad transfomer ------------------------------------------------------------------------------ +-- | A Xen transformer. This transformers keeps connection to the Xen+-- hypervisor interface. newtype XenT m a = XenT { unXenT :: ReaderT XcHandle m a }     deriving (Functor, Applicative, Monad, MonadTrans, MonadIO, MonadCatch) +-- | Most simple 'XenT' implementation. type Xen = XenT IO  instance (Functor m, MonadIO m, MonadCatch m) => MonadXen (XenT m) where
src/System/Xen/Low.hsc view
@@ -4,9 +4,18 @@ -- a ffi call to corresponding c function.  module System.Xen.Low-    ( xc_interface_open+    (+    -- * Interface+      xc_interface_open     , xc_interface_close+    -- * Domain     , xc_domain_getinfo+    -- ** Domain pause+    , xc_domain_pause+    , xc_domain_unpause+    -- ** Domain powerstate+    , xc_domain_shutdown+    , xc_domain_destroy     ) where  #include <xenctrl.h>@@ -45,10 +54,40 @@ -- one exists. It is, therefore, important in this case to make sure the -- domain requested was the one returned. foreign import ccall unsafe "xenctrl.h xc_domain_getinfo"-    xc_domain_getinfo :: XcHandle  -- ^ Handle to the open hypervisor interface-                      -> DomId -- ^ First domain to enumerate from.-                      -> CUInt -- ^ The number of requested domains+    xc_domain_getinfo :: XcHandle        -- ^ Handle to the open hypervisor interface+                      -> DomId           -- ^ First domain to enumerate from.+                      -> CUInt           -- ^ The number of requested domains                       -> Ptr DomainInfo  -- ^ Pointer to the structure that will                                          -- contain the information for                                          -- enumerated domains-                      -> IO CInt  -- ^ Number of domains enumerated, -1 on error+                      -> IO CInt         -- ^ Number of domains enumerated, -1 on error++-- | This function pauses a domain. A paused domain still exists in memory+-- however it does not receive any timeslices from the hypervisor.+foreign import ccall unsafe "xenctrl.h xc_domain_pause"+    xc_domain_pause :: XcHandle -- ^ Handle to the open hypervisor interface+                    -> DomId    -- ^ Domain to pause+                    -> IO CInt  -- ^ 0 if success, -1 if error++-- | This function unpauses a domain. The domain should have been previously paused.+foreign import ccall unsafe "xenctrl.h xc_domain_unpause"+    xc_domain_unpause :: XcHandle -- ^ Handle to the open hypervisor interface+                      -> DomId    -- ^ Domain to unpause+                      -> IO CInt  -- ^ 0 if success, -1 if error++-- | This function will shutdown a domain. This is intended for use in+-- fully-virtualized domains where this operation is analogous to the+-- sched_op operations in a paravirtualized domain.+foreign import ccall unsafe "xenctrl.h xc_domain_shutdown"+    xc_domain_shutdown :: XcHandle -- ^ Handle to the open hypervisor interface+                       -> DomId    -- ^ Domain to shutdown+                       -> CInt     -- ^ Shutdown reason+                       -> IO CInt  -- ^ 0 if success, -1 if error++-- | This function will destroy a domain. Destroying a domain removes the domain+-- completely from memory. This function should be called after sending the+-- domain a SHUTDOWN control message to free up the domain resources.+foreign import ccall unsafe "xenctrl.h xc_domain_destroy"+    xc_domain_destroy :: XcHandle -- ^ Handle to the open hypervisor interface+                      -> DomId    -- ^ Domain to destroy+                      -> IO CInt  -- ^ 0 if success, -1 if error
src/System/Xen/Mid.hsc view
@@ -5,33 +5,47 @@ -- error codes and @errno@.  module System.Xen.Mid-    ( interfaceOpen+    (+    -- * Interface+      interfaceOpen     , interfaceClose+    -- * Domain     , domainGetInfo+    -- ** Domain pause+    , domainPause+    , domainUnpause+    -- ** Domain powerstate+    , domainShutdown+    , domainDestroy     ) where  #include <xenctrl.h> -import Control.Monad (void, when, forM)+import Prelude hiding (sequence)++import Control.Applicative (Alternative(..), pure)+import Control.Monad (void, when)+import Data.Traversable (Traversable(sequenceA)) import Foreign.Marshal.Alloc (allocaBytes)-import Foreign.Storable (peekElemOff, sizeOf)+import Foreign.Storable (peekElemOff, peek, poke, sizeOf)+import Foreign.Ptr (castPtr)  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)+import System.Xen.Types (XcHandle(..), DomId(..), DomainShutdownReason, DomainInfo)+import qualified System.Xen.Low as Low  -- | Open the connection to the hypervisor interface, can fail with -- 'System.Xen.Errors.XcHandleOpenError'. interfaceOpen :: MonadIO m => m XcHandle interfaceOpen = liftIO $ do #if XEN_SYSCTL_INTERFACE_VERSION == 8-    i@(XcHandle ptr) <- xc_interface_open 0 0 0+    i@(XcHandle ptr) <- Low.xc_interface_open 0 0 0     when (ptr `elem` [-1, 0]) $ getErrno >>= throwM . XcHandleOpenError #elif XEN_SYSCTL_INTERFACE_VERSION == 6-    i@(XcHandle h) <- xc_interface_open+    i@(XcHandle h) <- Low.xc_interface_open     when (h == -1) $ getErrno >>= throwM . XcHandleOpenError #endif     return i@@ -39,18 +53,46 @@ -- | Close an open hypervisor interface, ignores all possible errors but all the -- same can fail with segfault or sutin. interfaceClose :: (MonadIO m, Functor m) => XcHandle -> m ()-interfaceClose = void . liftIO . xc_interface_close+interfaceClose = void . liftIO . Low.xc_interface_close  -- | Returns a list of currently runing domains, 1024 maximum, can fail with -- 'System.Xen.Errors.InvalidDomainShutdownReason' and -- 'System.Xen.Errors.DomainGetInfoError'.-domainGetInfo :: MonadIO m => XcHandle -> m [DomainInfo]+domainGetInfo :: (MonadIO m, Alternative t, Traversable t) => XcHandle -> m (t DomainInfo) domainGetInfo handle = liftIO $ allocaBytes size $ \ptr -> do-     wrote <- fmap fromIntegral $ xc_domain_getinfo handle (dom0) count ptr+     wrote <- fmap fromIntegral $ Low.xc_domain_getinfo handle (dom0) count ptr      when (wrote == -1) $ getErrno >>= throwM . DomainGetInfoError-     forM [0 .. wrote - 1] $ peekElemOff ptr+     sequenceA $ generateA wrote $ peekElemOff ptr   where     dom0 = DomId 0     count :: Num a => a     count = 1024     size = count * sizeOf (undefined :: DomainInfo)+    generateA c = go empty c c+      where+        go t 0 _ _ = t+        go t n l a = n `seq` go (pure (a (l - n)) <|> t) l (n - 1) a++-- | Pause domain. A paused domain still exists in memory+-- however it does not receive any timeslices from the hypervisor.+domainPause :: MonadIO m => DomId -> XcHandle -> m Bool+domainPause domid handle = liftIO $ fmap (== 0) $ Low.xc_domain_pause handle domid++-- | Unpause a domain. The domain should have been previously paused.+domainUnpause :: MonadIO m => DomId -> XcHandle -> m Bool+domainUnpause domid handle = liftIO $ fmap (== 0) $ Low.xc_domain_unpause handle domid++-- | Shutdown domain. This is intended for use in fully-virtualized domains where+-- this operation is analogous to the sched_op operations in a paravirtualized domain.+domainShutdown :: MonadIO m => DomId -> DomainShutdownReason -> XcHandle -> m Bool+domainShutdown domid reason handle = liftIO $ fmap (== 0) $ allocaBytes size $ \ptr -> do+    poke ptr reason+    intReason <- peek $ castPtr ptr+    Low.xc_domain_shutdown handle domid intReason+  where+    size = sizeOf (undefined :: DomainShutdownReason)++-- | Destroy a domain.  Destroying a domain removes the domain completely from memory.+-- This function should be called after 'domainShutdown' to free up the domain resources.+domainDestroy :: MonadIO m => DomId -> XcHandle -> m Bool+domainDestroy domid handle = liftIO $ fmap (== 0) $ Low.xc_domain_destroy handle domid
src/System/Xen/Types.hsc view
@@ -22,7 +22,6 @@ import Control.Applicative ((<$>)) import Data.Bits (testBit, bit, (.|.)) import Data.Maybe (catMaybes)-import Data.Foldable (foldl) import Data.Word (Word32, Word64) import Foreign.C (CInt(..), CUInt(..)) #if XEN_SYSCTL_INTERFACE_VERSION == 8@@ -77,8 +76,8 @@ data DomainInfo = DomainInfo     { domainInfoId                  :: {-# UNPACK #-} !DomId     , domainInfoSsidRef             :: {-# UNPACK #-} !Word32-    , domainInfoFlags               :: BitSet DomainFlag-    , domainInfoShutdownReason      :: Maybe DomainShutdownReason+    , domainInfoFlags               :: !(BitSet DomainFlag)+    , domainInfoShutdownReason      :: !(Maybe DomainShutdownReason)     , domainInfoNumberOfPages       :: {-# UNPACK #-} !Word32 #if XEN_SYSCTL_INTERFACE_VERSION == 8     , domainInfoNumberOfSharedPages :: {-# UNPACK #-} !Word32@@ -154,7 +153,7 @@         #{poke xc_dominfo_t, domid} ptr domainInfoId         #{poke xc_dominfo_t, ssidref} ptr domainInfoSsidRef         let off = sizeOf domainInfoId + sizeOf domainInfoSsidRef-        let flags :: CUInt = foldl (\a b -> a .|. bit (fromEnum b)) 0 domainInfoFlags+        let flags :: CUInt = BitSet.foldl' (\a b -> a .|. bit (fromEnum b)) 0 domainInfoFlags         pokeByteOff ptr off flags         case domainInfoShutdownReason of             Nothing -> return ()
tests/Tests.hs view
@@ -1,10 +1,10 @@ module Main where -import Test.Framework (defaultMain)+import Test.Tasty (defaultMain, testGroup)  import qualified System.Xen.Types.Tests  main :: IO ()-main = defaultMain+main = defaultMain $ testGroup "Tests"     [ System.Xen.Types.Tests.tests     ]