Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / Block / Drbd / Types.hs @ 9de303af

History | View | Annotate | Download (12.3 kB)

1
{-| DRBD Data Types
2

    
3
This module holds the definition of the data types describing the status of
4
DRBD.
5

    
6
-}
7
{-
8

    
9
Copyright (C) 2012 Google Inc.
10

    
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 2 of the License, or
14
(at your option) any later version.
15

    
16
This program is distributed in the hope that it will be useful, but
17
WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
General Public License for more details.
20

    
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software
23
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
02110-1301, USA.
25

    
26
-}
27
module Ganeti.Block.Drbd.Types
28
  ( DRBDStatus(..)
29
  , VersionInfo(..)
30
  , DeviceInfo(..)
31
  , ConnState(..)
32
  , LocalRemote(..)
33
  , Role(..)
34
  , DiskState(..)
35
  , PerfIndicators(..)
36
  , SyncStatus(..)
37
  , SizeUnit(..)
38
  , Time(..)
39
  , TimeUnit(..)
40
  , AdditionalInfo(..)
41
  ) where
42

    
43
import Text.JSON
44
import Text.Printf
45

    
46
import Ganeti.JSON
47

    
48
--TODO: consider turning deviceInfos into an IntMap
49
-- | Data type contaning all the data about the status of DRBD.
50
data DRBDStatus =
51
  DRBDStatus
52
  { versionInfo :: VersionInfo  -- ^ Version information about DRBD
53
  , deviceInfos :: [DeviceInfo] -- ^ Per-minor information
54
  } deriving (Eq, Show)
55

    
56
-- | The DRBDStatus instance of JSON.
57
instance JSON DRBDStatus where
58
  showJSON d = makeObj
59
    [ ("versionInfo", showJSON $ versionInfo d)
60
    , ("deviceInfos", showJSONs $ deviceInfos d)
61
    ]
62

    
63
  readJSON = error "JSON read instance not implemented for type DRBDStatus"
64

    
65
-- | Data type describing the DRBD version.
66
data VersionInfo =
67
  VersionInfo
68
  { version    :: Maybe String -- ^ DRBD driver version
69
  , api        :: Maybe String -- ^ The api version
70
  , proto      :: Maybe String -- ^ The protocol version
71
  , srcversion :: Maybe String -- ^ The version of the source files
72
  , gitHash    :: Maybe String -- ^ Git hash of the source files
73
  , buildBy    :: Maybe String -- ^ Who built the binary (and,
74
                               -- optionally, when)
75
  } deriving (Eq, Show)
76

    
77
-- | The VersionInfo instance of JSON.
78
instance JSON VersionInfo where
79
  showJSON (VersionInfo versionF apiF protoF srcversionF gitHashF buildByF) =
80
    optFieldsToObj
81
      [ optionalJSField "version" versionF
82
      , optionalJSField "api" apiF
83
      , optionalJSField "proto" protoF
84
      , optionalJSField "srcversion" srcversionF
85
      , optionalJSField "gitHash" gitHashF
86
      , optionalJSField "buildBy" buildByF
87
      ]
88

    
89
  readJSON = error "JSON read instance not implemented for type VersionInfo"
90

    
91
-- | Data type describing a device.
92
data DeviceInfo =
93
  UnconfiguredDevice Int -- ^ An DRBD minor marked as unconfigured
94
  | -- | A configured DRBD minor
95
    DeviceInfo
96
      { minorNumber :: Int -- ^ The minor index of the device
97
      , connectionState :: ConnState -- ^ State of the connection
98
      , resourceRoles :: LocalRemote Role -- ^ Roles of the resources
99
      , diskStates :: LocalRemote DiskState -- ^ Status of the disks
100
      , replicationProtocol :: Char -- ^ The replication protocol being used
101
      , ioFlags :: String -- ^ The input/output flags
102
      , perfIndicators
103
          :: PerfIndicators -- ^ Performance indicators
104
      , syncStatus :: Maybe SyncStatus -- ^ The status of the syncronization of
105
                                       -- the disk (only if it is happening)
106
      , resync :: Maybe AdditionalInfo -- ^ Additional info by DRBD 8.0
107
      , actLog :: Maybe AdditionalInfo -- ^ Additional info by DRBD 8.0
108
      } deriving (Eq, Show)
109

    
110
-- | The DeviceInfo instance of JSON.
111
instance JSON DeviceInfo where
112
  showJSON (UnconfiguredDevice num) = makeObj
113
    [ ("minor", showJSON num)
114
    , ("connectionState", showJSON Unconfigured)
115
    ]
116
  showJSON (DeviceInfo minorNumberF connectionStateF (LocalRemote
117
    localRole remoteRole) (LocalRemote localState remoteState)
118
    replicProtocolF ioFlagsF perfIndicatorsF syncStatusF _ _) =
119
    optFieldsToObj
120
    [ Just ("minor", showJSON minorNumberF)
121
    , Just ("connectionState", showJSON connectionStateF)
122
    , Just ("localRole", showJSON localRole)
123
    , Just ("remoteRole", showJSON remoteRole)
124
    , Just ("localState", showJSON localState)
125
    , Just ("remoteState", showJSON remoteState)
126
    , Just ("replicationProtocol", showJSON replicProtocolF)
127
    , Just ("ioFlags", showJSON ioFlagsF)
128
    , Just ("perfIndicators", showJSON perfIndicatorsF)
129
    , optionalJSField "syncStatus" syncStatusF
130
    ]
131

    
132
  readJSON = error "JSON read instance not implemented for type DeviceInfo"
133

    
134
-- | Data type describing the state of the connection.
135
data ConnState
136
  = StandAlone     -- ^  No network configuration available
137
  | Disconnecting  -- ^ Temporary state during disconnection
138
  | Unconnected    -- ^ Prior to a connection attempt
139
  | Timeout        -- ^ Following a timeout in the communication
140
  | BrokenPipe     -- ^ After the connection to the peer was lost
141
  | NetworkFailure -- ^ After the connection to the parner was lost
142
  | ProtocolError  -- ^ After the connection to the parner was lost
143
  | TearDown       -- ^ The peer is closing the connection
144
  | WFConnection   -- ^ Waiting for the peer to become visible
145
  | WFReportParams -- ^ Waiting for first packet from peer
146
  | Connected      -- ^ Connected, data mirroring active
147
  | StartingSyncS  -- ^ Source of a full sync started by admin
148
  | StartingSyncT  -- ^ Target of a full sync started by admin
149
  | WFBitMapS      -- ^ Source of a just starting partial sync
150
  | WFBitMapT      -- ^ Target of a just starting partial sync
151
  | WFSyncUUID     -- ^ Synchronization is about to begin
152
  | SyncSource     -- ^ Source of a running synchronization
153
  | SyncTarget     -- ^ Target of a running synchronization
154
  | PausedSyncS    -- ^ Source of a paused synchronization
155
  | PausedSyncT    -- ^ Target of a paused synchronization
156
  | VerifyS        -- ^ Source of an running verification
157
  | VerifyT        -- ^ Target of an running verification
158
  | Unconfigured   -- ^ The device is not configured
159
    deriving (Show, Eq)
160

    
161
-- | The ConnState instance of JSON.
162
instance JSON ConnState where
163
  showJSON = showJSON . show
164

    
165
  readJSON = error "JSON read instance not implemented for type ConnState"
166

    
167
-- | Algebraic data type describing something that has a local and a remote
168
-- value.
169
data LocalRemote a =
170
  LocalRemote
171
  { local  :: a -- ^ The local value
172
  , remote :: a -- ^ The remote value
173
  } deriving (Eq, Show)
174

    
175
-- | Data type describing.
176
data Role = Primary   -- ^ The device role is primary
177
          | Secondary -- ^ The device role is secondary
178
          | Unknown   -- ^ The device role is unknown
179
            deriving (Eq, Show)
180

    
181
-- | The Role instance of JSON.
182
instance JSON Role where
183
  showJSON = showJSON . show
184

    
185
  readJSON = error "JSON read instance not implemented for type Role"
186

    
187
-- | Data type describing disk states.
188
data DiskState
189
  = Diskless     -- ^ No local block device assigned to the DRBD driver
190
  | Attaching    -- ^ Reading meta data
191
  | Failed       -- ^ I/O failure
192
  | Negotiating  -- ^ "Attach" on an already-connected device
193
  | Inconsistent -- ^ The data is inconsistent between nodes.
194
  | Outdated     -- ^ Data consistent but outdated
195
  | DUnknown     -- ^ No network connection available
196
  | Consistent   -- ^ Consistent data, but without network connection
197
  | UpToDate     -- ^ Consistent, up-to-date. This is the normal state
198
    deriving (Eq, Show)
199

    
200
-- | The DiskState instance of JSON.
201
instance JSON DiskState where
202
  showJSON = showJSON . show
203

    
204
  readJSON = error "JSON read instance not implemented for type DiskState"
205

    
206
-- | Data type containing data about performance indicators.
207
data PerfIndicators = PerfIndicators
208
  { networkSend :: Int -- ^ KiB of data sent on the network
209
  , networkReceive :: Int -- ^ KiB of data received from the network
210
  , diskWrite :: Int -- ^ KiB of data written on local disk
211
  , diskRead :: Int -- ^ KiB of data read from local disk
212
  , activityLog :: Int -- ^ Number of updates of the activity log
213
  , bitMap :: Int -- ^ Number of updates to the bitmap area of the metadata
214
  , localCount :: Int -- ^ Number of open requests to te local I/O subsystem
215
  , pending :: Int -- ^ Num of requests sent to the partner but not yet answered
216
  , unacknowledged :: Int -- ^ Num of requests received by the partner but still
217
                        -- to be answered
218
  , applicationPending :: Int -- ^ Num of block I/O requests forwarded
219
                              -- to DRBD but that have not yet been
220
                              -- answered
221
  , epochs :: Maybe Int -- ^ Number of epoch objects
222
  , writeOrder :: Maybe Char -- ^ Currently used write ordering method
223
  , outOfSync :: Maybe Int -- ^ KiB of storage currently out of sync
224
  } deriving (Eq, Show)
225

    
226
-- | The PerfIndicators instance of JSON.
227
instance JSON PerfIndicators where
228
  showJSON p = optFieldsToObj
229
    [ Just ("networkSend", showJSON $ networkSend p)
230
    , Just ("networkReceive", showJSON $ networkReceive p)
231
    , Just ("diskWrite", showJSON $ diskWrite p)
232
    , Just ("diskRead", showJSON $ diskRead p)
233
    , Just ("activityLog", showJSON $ activityLog p)
234
    , Just ("bitMap", showJSON $ bitMap p)
235
    , Just ("localCount", showJSON $ localCount p)
236
    , Just ("pending", showJSON $ pending p)
237
    , Just ("unacknowledged", showJSON $ unacknowledged p)
238
    , Just ("applicationPending", showJSON $ applicationPending p)
239
    , optionalJSField "epochs" $ epochs p
240
    , optionalJSField "writeOrder" $ writeOrder p
241
    , optionalJSField "outOfSync" $ outOfSync p
242
    ]
243

    
244
  readJSON = error "JSON read instance not implemented for type PerfIndicators"
245

    
246
-- | Data type containing data about the synchronization status of a device.
247
data SyncStatus =
248
  SyncStatus
249
  { percentage      :: Double    -- ^ Percentage of syncronized data
250
  , partialSyncSize :: Int       -- ^ Numerator of the fraction of synced data
251
  , totalSyncSize   :: Int       -- ^ Denominator of the fraction of
252
                                 -- synced data
253
  , syncUnit        :: SizeUnit  -- ^ Measurement unit of the previous
254
                                 -- fraction
255
  , timeToFinish    :: Time      -- ^ Expected time before finishing
256
                                 -- the syncronization
257
  , speed           :: Int       -- ^ Speed of the syncronization
258
  , want            :: Maybe Int -- ^ Want of the syncronization
259
  , speedSizeUnit   :: SizeUnit  -- ^ Size unit of the speed
260
  , speedTimeUnit   :: TimeUnit  -- ^ Time unit of the speed
261
  } deriving (Eq, Show)
262

    
263
-- | The SyncStatus instance of JSON.
264
instance JSON SyncStatus where
265
  showJSON s = optFieldsToObj
266
    [ Just ("percentage", showJSON $ percentage s)
267
    , Just ("progress", showJSON $ show (partialSyncSize s) ++ "/" ++
268
        show (totalSyncSize s))
269
    , Just ("progressUnit", showJSON $ syncUnit s)
270
    , Just ("timeToFinish", showJSON $ timeToFinish s)
271
    , Just ("speed", showJSON $ speed s)
272
    , optionalJSField "want" $ want s
273
    , Just ("speedUnit", showJSON $ show (speedSizeUnit s) ++ "/" ++
274
        show (speedTimeUnit s))
275
    ]
276

    
277
  readJSON = error "JSON read instance not implemented for type SyncStatus"
278

    
279
-- | Data type describing a size unit for memory.
280
data SizeUnit = KiloByte | MegaByte deriving (Eq, Show)
281

    
282
-- | The SizeUnit instance of JSON.
283
instance JSON SizeUnit where
284
  showJSON = showJSON . show
285

    
286
  readJSON = error "JSON read instance not implemented for type SizeUnit"
287

    
288
-- | Data type describing a time (hh:mm:ss).
289
data Time = Time
290
  { hour :: Int
291
  , min  :: Int
292
  , sec  :: Int
293
  } deriving (Eq, Show)
294

    
295
-- | The Time instance of JSON.
296
instance JSON Time where
297
  showJSON (Time h m s) = showJSON (printf "%02d:%02d:%02d" h m s :: String)
298

    
299
  readJSON = error "JSON read instance not implemented for type Time"
300

    
301
-- | Data type describing a time unit.
302
data TimeUnit = Second deriving (Eq, Show)
303

    
304
-- | The TimeUnit instance of JSON.
305
instance JSON TimeUnit where
306
  showJSON Second = showJSON "Second"
307

    
308
  readJSON = error "JSON read instance not implemented for type TimeUnit"
309

    
310
-- | Additional device-specific cache-like information produced by
311
-- drbd <= 8.0.
312
--
313
-- Internal debug information exported by old DRBD versions.
314
-- Undocumented both in DRBD and here.
315
data AdditionalInfo = AdditionalInfo
316
  { partialUsed :: Int
317
  , totalUsed   :: Int
318
  , hits        :: Int
319
  , misses      :: Int
320
  , starving    :: Int
321
  , dirty       :: Int
322
  , changed     :: Int
323
  } deriving (Eq, Show)