Revision 47e0abee

b/lib/backend.py
66 66
from ganeti import vcluster
67 67
from ganeti import ht
68 68
from ganeti.block.base import BlockDev
69
from ganeti.block.drbd_info import DRBD8Info
69
from ganeti.block.drbd import DRBD8
70 70
from ganeti import hooksmaster
71 71

  
72 72

  
......
833 833

  
834 834
  if constants.NV_DRBDVERSION in what and vm_capable:
835 835
    try:
836
      drbd_version = DRBD8Info.CreateFromFile().GetVersionString()
836
      drbd_version = DRBD8.GetProcInfo().GetVersionString()
837 837
    except errors.BlockDeviceError, err:
838 838
      logging.warning("Can't get DRBD version", exc_info=True)
839 839
      drbd_version = str(err)
......
841 841

  
842 842
  if constants.NV_DRBDLIST in what and vm_capable:
843 843
    try:
844
      used_minors = drbd.DRBD8Dev.GetUsedDevs()
844
      used_minors = drbd.DRBD8.GetUsedDevs()
845 845
    except errors.BlockDeviceError, err:
846 846
      logging.warning("Can't get used minors list", exc_info=True)
847 847
      used_minors = str(err)
......
850 850
  if constants.NV_DRBDHELPER in what and vm_capable:
851 851
    status = True
852 852
    try:
853
      payload = drbd.DRBD8Dev.GetUsermodeHelper()
853
      payload = drbd.DRBD8.GetUsermodeHelper()
854 854
    except errors.BlockDeviceError, err:
855 855
      logging.error("Can't get DRBD usermode helper: %s", str(err))
856 856
      status = False
......
3692 3692

  
3693 3693
  """
3694 3694
  try:
3695
    return drbd.DRBD8Dev.GetUsermodeHelper()
3695
    return drbd.DRBD8.GetUsermodeHelper()
3696 3696
  except errors.BlockDeviceError, err:
3697 3697
    _Fail(str(err))
3698 3698

  
b/lib/block/base.py
149 149
    The force parameter signifies that if the device has any kind of
150 150
    --force thing, it should be used, we know what we are doing.
151 151

  
152
    @type force: boolean
153

  
152 154
    """
153 155
    raise NotImplementedError
154 156

  
......
185 187

  
186 188
    In case this is not a mirroring device, this is no-op.
187 189

  
190
    @type pause: boolean
188 191
    @param pause: Whether to pause or resume
189 192

  
190 193
    """
b/lib/block/drbd.py
32 32
from ganeti import objects
33 33
from ganeti.block import base
34 34
from ganeti.block.drbd_info import DRBD8Info
35
from ganeti.block.drbd_info import DRBD83ShowInfo
36
from ganeti.block.drbd_info import DRBD84ShowInfo
35
from ganeti.block import drbd_info
37 36
from ganeti.block import drbd_cmdgen
38 37

  
39 38

  
......
42 41
_DEVICE_READ_SIZE = 128 * 1024
43 42

  
44 43

  
44
class DRBD8(object):
45
  """Various methods to deals with the DRBD system as a whole.
46

  
47
  This class provides a set of methods to deal with the DRBD installation on
48
  the node or with uninitialized devices as opposed to a DRBD device.
49

  
50
  """
51
  _USERMODE_HELPER_FILE = "/sys/module/drbd/parameters/usermode_helper"
52

  
53
  _MAX_MINORS = 255
54

  
55
  @staticmethod
56
  def GetUsermodeHelper(filename=_USERMODE_HELPER_FILE):
57
    """Returns DRBD usermode_helper currently set.
58

  
59
    @type filename: string
60
    @param filename: the filename to read the usermode helper from
61
    @rtype: string
62
    @return: the currently configured DRBD usermode helper
63

  
64
    """
65
    try:
66
      helper = utils.ReadFile(filename).splitlines()[0]
67
    except EnvironmentError, err:
68
      if err.errno == errno.ENOENT:
69
        base.ThrowError("The file %s cannot be opened, check if the module"
70
                        " is loaded (%s)", filename, str(err))
71
      else:
72
        base.ThrowError("Can't read DRBD helper file %s: %s",
73
                        filename, str(err))
74
    if not helper:
75
      base.ThrowError("Can't read any data from %s", filename)
76
    return helper
77

  
78
  @staticmethod
79
  def GetProcInfo():
80
    """Reads and parses information from /proc/drbd.
81

  
82
    @rtype: DRBD8Info
83
    @return: a L{DRBD8Info} instance containing the current /proc/drbd info
84

  
85
    """
86
    return DRBD8Info.CreateFromFile()
87

  
88
  @staticmethod
89
  def GetUsedDevs():
90
    """Compute the list of used DRBD minors.
91

  
92
    @rtype: list of ints
93

  
94
    """
95
    info = DRBD8.GetProcInfo()
96
    return filter(lambda m: not info.GetMinorStatus(m).is_unconfigured,
97
                  info.GetMinors())
98

  
99
  @staticmethod
100
  def FindUnusedMinor():
101
    """Find an unused DRBD device.
102

  
103
    This is specific to 8.x as the minors are allocated dynamically,
104
    so non-existing numbers up to a max minor count are actually free.
105

  
106
    @rtype: int
107

  
108
    """
109
    highest = None
110
    info = DRBD8.GetProcInfo()
111
    for minor in info.GetMinors():
112
      status = info.GetMinorStatus(minor)
113
      if not status.is_in_use:
114
        return minor
115
      highest = max(highest, minor)
116

  
117
    if highest is None: # there are no minors in use at all
118
      return 0
119
    if highest >= DRBD8._MAX_MINORS:
120
      logging.error("Error: no free drbd minors!")
121
      raise errors.BlockDeviceError("Can't find a free DRBD minor")
122

  
123
    return highest + 1
124

  
125
  @staticmethod
126
  def GetCmdGenerator(info):
127
    """Creates a suitable L{BaseDRBDCmdGenerator} based on the given info.
128

  
129
    @type info: DRBD8Info
130
    @rtype: BaseDRBDCmdGenerator
131

  
132
    """
133
    version = info.GetVersion()
134
    if version["k_minor"] <= 3:
135
      return drbd_cmdgen.DRBD83CmdGenerator(version)
136
    else:
137
      return drbd_cmdgen.DRBD84CmdGenerator(version)
138

  
139
  @staticmethod
140
  def ShutdownAll(minor):
141
    """Deactivate the device.
142

  
143
    This will, of course, fail if the device is in use.
144

  
145
    @type minor: int
146
    @param minor: the minor to shut down
147

  
148
    """
149
    info = DRBD8.GetProcInfo()
150
    cmd_gen = DRBD8.GetCmdGenerator(info)
151

  
152
    cmd = cmd_gen.GenDownCmd(minor)
153
    result = utils.RunCmd(cmd)
154
    if result.failed:
155
      base.ThrowError("drbd%d: can't shutdown drbd device: %s",
156
                      minor, result.output)
157

  
158

  
45 159
class DRBD8Dev(base.BlockDev):
46 160
  """DRBD v8.x block device.
47 161

  
......
57 171
  """
58 172
  _DRBD_MAJOR = 147
59 173

  
60
  _USERMODE_HELPER_FILE = "/sys/module/drbd/parameters/usermode_helper"
61

  
62
  _MAX_MINORS = 255
63

  
64 174
  # timeout constants
65 175
  _NET_RECONFIG_TIMEOUT = 60
66 176

  
......
81 191
    super(DRBD8Dev, self).__init__(unique_id, children, size, params)
82 192
    self.major = self._DRBD_MAJOR
83 193

  
84
    drbd_info = DRBD8Info.CreateFromFile()
85
    version = drbd_info.GetVersion()
194
    info = DRBD8.GetProcInfo()
195
    version = info.GetVersion()
86 196
    if version["k_major"] != 8:
87 197
      base.ThrowError("Mismatch in DRBD kernel version and requested ganeti"
88 198
                      " usage: kernel is %s.%s, ganeti wants 8.x",
89 199
                      version["k_major"], version["k_minor"])
90 200

  
91 201
    if version["k_minor"] <= 3:
92
      self._show_info_cls = DRBD83ShowInfo
202
      self._show_info_cls = drbd_info.DRBD83ShowInfo
93 203
    else:
94
      self._show_info_cls = DRBD84ShowInfo
204
      self._show_info_cls = drbd_info.DRBD84ShowInfo
95 205

  
96
    self._cmd_gen = self._GetCmdGenerator(drbd_info)
206
    self._cmd_gen = DRBD8.GetCmdGenerator(info)
97 207

  
98 208
    if (self._lhost is not None and self._lhost == self._rhost and
99 209
            self._lport == self._rport):
......
101 211
                       (unique_id,))
102 212
    self.Attach()
103 213

  
104
  @classmethod
105
  def _GetCmdGenerator(cls, drbd_info):
106
    version = drbd_info.GetVersion()
107
    if version["k_minor"] <= 3:
108
      return drbd_cmdgen.DRBD83CmdGenerator(version)
109
    else:
110
      return drbd_cmdgen.DRBD84CmdGenerator(version)
111

  
112
  @staticmethod
113
  def GetUsermodeHelper(filename=_USERMODE_HELPER_FILE):
114
    """Returns DRBD usermode_helper currently set.
115

  
116
    """
117
    try:
118
      helper = utils.ReadFile(filename).splitlines()[0]
119
    except EnvironmentError, err:
120
      if err.errno == errno.ENOENT:
121
        base.ThrowError("The file %s cannot be opened, check if the module"
122
                        " is loaded (%s)", filename, str(err))
123
      else:
124
        base.ThrowError("Can't read DRBD helper file %s: %s",
125
                        filename, str(err))
126
    if not helper:
127
      base.ThrowError("Can't read any data from %s", filename)
128
    return helper
129

  
130 214
  @staticmethod
131 215
  def _DevPath(minor):
132 216
    """Return the path to a drbd device for a given minor.
133 217

  
134
    """
135
    return "/dev/drbd%d" % minor
136

  
137
  @classmethod
138
  def GetUsedDevs(cls):
139
    """Compute the list of used DRBD devices.
218
    @type minor: int
219
    @rtype: string
140 220

  
141 221
    """
142
    drbd_info = DRBD8Info.CreateFromFile()
143
    return filter(lambda m: not drbd_info.GetMinorStatus(m).is_unconfigured,
144
                  drbd_info.GetMinors())
222
    return "/dev/drbd%d" % minor
145 223

  
146 224
  def _SetFromMinor(self, minor):
147 225
    """Set our parameters based on the given minor.
148 226

  
149 227
    This sets our minor variable and our dev_path.
150 228

  
229
    @type minor: int
230

  
151 231
    """
152 232
    if minor is None:
153 233
      self.minor = self.dev_path = None
......
164 244
    This currently only checks the size, which must be around
165 245
    128MiB.
166 246

  
247
    @type meta_device: string
248
    @param meta_device: the path to the device to check
249

  
167 250
    """
168 251
    result = utils.RunCmd(["blockdev", "--getsize", meta_device])
169 252
    if result.failed:
......
187 270
      base.ThrowError("Meta device too big (%.2fMiB)",
188 271
                      (num_bytes / 1024 / 1024))
189 272

  
190
  @classmethod
191
  def _InitMeta(cls, minor, dev_path):
192
    """Initialize a meta device.
193

  
194
    This will not work if the given minor is in use.
195

  
196
    """
197
    # Zero the metadata first, in order to make sure drbdmeta doesn't
198
    # try to auto-detect existing filesystems or similar (see
199
    # http://code.google.com/p/ganeti/issues/detail?id=182); we only
200
    # care about the first 128MB of data in the device, even though it
201
    # can be bigger
202
    result = utils.RunCmd([constants.DD_CMD,
203
                           "if=/dev/zero", "of=%s" % dev_path,
204
                           "bs=1048576", "count=128", "oflag=direct"])
205
    if result.failed:
206
      base.ThrowError("Can't wipe the meta device: %s", result.output)
207

  
208
    drbd_info = DRBD8Info.CreateFromFile()
209
    cmd_gen = cls._GetCmdGenerator(drbd_info)
210
    cmd = cmd_gen.GenInitMetaCmd(minor, dev_path)
211

  
212
    result = utils.RunCmd(cmd)
213
    if result.failed:
214
      base.ThrowError("Can't initialize meta device: %s", result.output)
215

  
216
  def _FindUnusedMinor(self):
217
    """Find an unused DRBD device.
218

  
219
    This is specific to 8.x as the minors are allocated dynamically,
220
    so non-existing numbers up to a max minor count are actually free.
221

  
222
    """
223

  
224
    highest = None
225
    drbd_info = DRBD8Info.CreateFromFile()
226
    for minor in drbd_info.GetMinors():
227
      status = drbd_info.GetMinorStatus(minor)
228
      if not status.is_in_use:
229
        return minor
230
      highest = max(highest, minor)
231

  
232
    if highest is None: # there are no minors in use at all
233
      return 0
234
    if highest >= self._MAX_MINORS:
235
      logging.error("Error: no free drbd minors!")
236
      raise errors.BlockDeviceError("Can't find a free DRBD minor")
237

  
238
    return highest + 1
239

  
240 273
  def _GetShowData(self, minor):
241
    """Return the `drbdsetup show` data for a minor.
274
    """Return the `drbdsetup show` data.
275

  
276
    @type minor: int
277
    @param minor: the minor to collect show output for
278
    @rtype: string
242 279

  
243 280
    """
244 281
    result = utils.RunCmd(self._cmd_gen.GenShowCmd(minor))
......
249 286
    return result.stdout
250 287

  
251 288
  def _GetShowInfo(self, minor):
289
    """Return parsed information from `drbdsetup show`.
290

  
291
    @type minor: int
292
    @param minor: the minor to return information for
293
    @rtype: dict as described in L{drbd_info.BaseShowInfo.GetDevInfo}
294

  
295
    """
252 296
    return self._show_info_cls.GetDevInfo(self._GetShowData(minor))
253 297

  
254 298
  def _MatchesLocal(self, info):
255 299
    """Test if our local config matches with an existing device.
256 300

  
257
    The parameter should be as returned from `_GetDevInfo()`. This
301
    The parameter should be as returned from `_GetShowInfo()`. This
258 302
    method tests if our local backing device is the same as the one in
259 303
    the info parameter, in effect testing if we look like the given
260 304
    device.
261 305

  
306
    @type info: dict as described in L{drbd_info.BaseShowInfo.GetDevInfo}
307
    @rtype: boolean
308

  
262 309
    """
263 310
    if self._children:
264 311
      backend, meta = self._children
......
283 330
  def _MatchesNet(self, info):
284 331
    """Test if our network config matches with an existing device.
285 332

  
286
    The parameter should be as returned from `_GetDevInfo()`. This
333
    The parameter should be as returned from `_GetShowInfo()`. This
287 334
    method tests if our network configuration is the same as the one
288 335
    in the info parameter, in effect testing if we look like the given
289 336
    device.
290 337

  
338
    @type info: dict as described in L{drbd_info.BaseShowInfo.GetDevInfo}
339
    @rtype: boolean
340

  
291 341
    """
292 342
    if (((self._lhost is None and not ("local_addr" in info)) and
293 343
         (self._rhost is None and not ("remote_addr" in info)))):
......
308 358
  def _AssembleLocal(self, minor, backend, meta, size):
309 359
    """Configure the local part of a DRBD device.
310 360

  
361
    @type minor: int
362
    @param minor: the minor to assemble locally
363
    @type backend: string
364
    @param backend: path to the data device to use
365
    @type meta: string
366
    @param meta: path to the meta device to use
367
    @type size: int
368
    @param size: size in MiB
369

  
311 370
    """
312 371
    cmds = self._cmd_gen.GenLocalInitCmds(minor, backend, meta,
313 372
                                          size, self.params)
......
322 381
                   dual_pri=False, hmac=None, secret=None):
323 382
    """Configure the network part of the device.
324 383

  
384
    @type minor: int
385
    @param minor: the minor to assemble the network for
386
    @type net_info: (string, int, string, int)
387
    @param net_info: tuple containing the local address, local port, remote
388
      address and remote port
389
    @type protocol: string
390
    @param protocol: either "ipv4" or "ipv6"
391
    @type dual_pri: boolean
392
    @param dual_pri: whether two primaries should be allowed or not
393
    @type hmac: string
394
    @param hmac: the HMAC algorithm to use
395
    @type secret: string
396
    @param secret: the shared secret to use
397

  
325 398
    """
326 399
    lhost, lport, rhost, rport = net_info
327 400
    if None in net_info:
......
384 457
  def AddChildren(self, devices):
385 458
    """Add a disk to the DRBD device.
386 459

  
460
    @type devices: list of L{BlockDev}
461
    @param devices: a list of exactly two L{BlockDev} objects; the first
462
      denotes the data device, the second the meta device for this DRBD device
463

  
387 464
    """
388 465
    if self.minor is None:
389 466
      base.ThrowError("drbd%d: can't attach to dbrd8 during AddChildren",
......
400 477
    backend.Open()
401 478
    meta.Open()
402 479
    self._CheckMetaSize(meta.dev_path)
403
    self._InitMeta(self._FindUnusedMinor(), meta.dev_path)
480
    self._InitMeta(DRBD8.FindUnusedMinor(), meta.dev_path)
404 481

  
405 482
    self._AssembleLocal(self.minor, backend.dev_path, meta.dev_path, self.size)
406 483
    self._children = devices
......
408 485
  def RemoveChildren(self, devices):
409 486
    """Detach the drbd device from local storage.
410 487

  
488
    @type devices: list of L{BlockDev}
489
    @param devices: a list of exactly two L{BlockDev} objects; the first
490
      denotes the data device, the second the meta device for this DRBD device
491

  
411 492
    """
412 493
    if self.minor is None:
413 494
      base.ThrowError("drbd%d: can't attach to drbd8 during RemoveChildren",
......
459 540
  def SetSyncParams(self, params):
460 541
    """Set the synchronization parameters of the DRBD syncer.
461 542

  
462
    @type params: dict
463
    @param params: LD level disk parameters related to the synchronization
464
    @rtype: list
465
    @return: a list of error messages, emitted both by the current node and by
466
    children. An empty list means no errors
543
    See L{BlockDev.SetSyncParams} for parameter description.
467 544

  
468 545
    """
469 546
    if self.minor is None:
......
478 555
  def PauseResumeSync(self, pause):
479 556
    """Pauses or resumes the sync of a DRBD device.
480 557

  
481
    @param pause: Wether to pause or resume
482
    @return: the success of the operation
558
    See L{BlockDev.PauseResumeSync} for parameter description.
483 559

  
484 560
    """
485 561
    if self.minor is None:
......
500 576
    return not result.failed and children_result
501 577

  
502 578
  def GetProcStatus(self):
503
    """Return device data from /proc.
579
    """Return the current status data from /proc/drbd for this device.
580

  
581
    @rtype: DRBD8Status
504 582

  
505 583
    """
506 584
    if self.minor is None:
507 585
      base.ThrowError("drbd%d: GetStats() called while not attached",
508 586
                      self._aminor)
509
    drbd_info = DRBD8Info.CreateFromFile()
510
    if not drbd_info.HasMinorStatus(self.minor):
587
    info = DRBD8.GetProcInfo()
588
    if not info.HasMinorStatus(self.minor):
511 589
      base.ThrowError("drbd%d: can't find myself in /proc", self.minor)
512
    return drbd_info.GetMinorStatus(self.minor)
590
    return info.GetMinorStatus(self.minor)
513 591

  
514 592
  def GetSyncStatus(self):
515 593
    """Returns the sync status of the device.
516 594

  
517

  
518 595
    If sync_percent is None, it means all is ok
519 596
    If estimated_time is None, it means we can't estimate
520 597
    the time needed, otherwise it's the time left in seconds.
521 598

  
522

  
523 599
    We set the is_degraded parameter to True on two conditions:
524 600
    network not connected or local disk missing.
525 601

  
......
553 629
  def Open(self, force=False):
554 630
    """Make the local state primary.
555 631

  
556
    If the 'force' parameter is given, the '-o' option is passed to
557
    drbdsetup. Since this is a potentially dangerous operation, the
558
    force flag should be only given after creation, when it actually
559
    is mandatory.
632
    If the 'force' parameter is given, DRBD is instructed to switch the device
633
    into primary mode. Since this is a potentially dangerous operation, the
634
    force flag should be only given after creation, when it actually is
635
    mandatory.
560 636

  
561 637
    """
562 638
    if self.minor is None and not self.Attach():
......
653 729
    specified multi-master flag. The device needs to be 'Standalone'
654 730
    but have valid network configuration data.
655 731

  
656
    Args:
657
      - multimaster: init the network in dual-primary mode
732
    @type multimaster: boolean
733
    @param multimaster: init the network in dual-primary mode
658 734

  
659 735
    """
660 736
    if self.minor is None:
......
685 761
    /proc).
686 762

  
687 763
    """
688
    used_devs = self.GetUsedDevs()
764
    used_devs = DRBD8.GetUsedDevs()
689 765
    if self._aminor in used_devs:
690 766
      minor = self._aminor
691 767
    else:
......
818 894
    I/Os will continue to be served from the remote device. If we
819 895
    don't have a remote device, this operation will fail.
820 896

  
897
    @type minor: int
898
    @param minor: the device to detach from the local device
899

  
821 900
    """
822 901
    cmd = self._cmd_gen.GenDetachCmd(minor)
823 902
    result = utils.RunCmd(cmd)
......
830 909

  
831 910
    This fails if we don't have a local device.
832 911

  
912
    @type minor: boolean
913
    @param minor: the device to disconnect from the remote peer
914

  
833 915
    """
834 916
    family = self._GetNetFamily(minor, self._lhost, self._rhost)
835 917
    cmd = self._cmd_gen.GenDisconnectCmd(minor, family,
......
840 922
      base.ThrowError("drbd%d: can't shutdown network: %s",
841 923
                      minor, result.output)
842 924

  
843
  @classmethod
844
  def _ShutdownAll(cls, minor):
845
    """Deactivate the device.
846

  
847
    This will, of course, fail if the device is in use.
848

  
849
    """
850
    # FIXME: _ShutdownAll, despite being private, is used in nodemaint.py.
851
    # That's why we can't make it an instance method, which in turn requires
852
    # us to duplicate code here (from __init__). This should be properly fixed.
853
    drbd_info = DRBD8Info.CreateFromFile()
854
    cmd_gen = cls._GetCmdGenerator(drbd_info)
855

  
856
    cmd = cmd_gen.GenDownCmd(minor)
857
    result = utils.RunCmd(cmd)
858
    if result.failed:
859
      base.ThrowError("drbd%d: can't shutdown drbd device: %s",
860
                      minor, result.output)
861

  
862 925
  def Shutdown(self):
863 926
    """Shutdown the DRBD device.
864 927

  
......
869 932
    minor = self.minor
870 933
    self.minor = None
871 934
    self.dev_path = None
872
    self._ShutdownAll(minor)
935
    DRBD8.ShutdownAll(minor)
873 936

  
874 937
  def Remove(self):
875 938
    """Stub remove for DRBD devices.
......
885 948
    """
886 949
    raise errors.ProgrammerError("Can't rename a drbd device")
887 950

  
951
  def Grow(self, amount, dryrun, backingstore):
952
    """Resize the DRBD device and its backing storage.
953

  
954
    See L{BlockDev.Grow} for parameter description.
955

  
956
    """
957
    if self.minor is None:
958
      base.ThrowError("drbd%d: Grow called while not attached", self._aminor)
959
    if len(self._children) != 2 or None in self._children:
960
      base.ThrowError("drbd%d: cannot grow diskless device", self.minor)
961
    self._children[0].Grow(amount, dryrun, backingstore)
962
    if dryrun or backingstore:
963
      # DRBD does not support dry-run mode and is not backing storage,
964
      # so we'll return here
965
      return
966
    cmd = self._cmd_gen.GenResizeCmd(self.minor, self.size + amount)
967
    result = utils.RunCmd(cmd)
968
    if result.failed:
969
      base.ThrowError("drbd%d: resize failed: %s", self.minor, result.output)
970

  
971
  @classmethod
972
  def _InitMeta(cls, minor, dev_path):
973
    """Initialize a meta device.
974

  
975
    This will not work if the given minor is in use.
976

  
977
    @type minor: int
978
    @param minor: the DRBD minor whose (future) meta device should be
979
      initialized
980
    @type dev_path: string
981
    @param dev_path: path to the meta device to initialize
982

  
983
    """
984
    # Zero the metadata first, in order to make sure drbdmeta doesn't
985
    # try to auto-detect existing filesystems or similar (see
986
    # http://code.google.com/p/ganeti/issues/detail?id=182); we only
987
    # care about the first 128MB of data in the device, even though it
988
    # can be bigger
989
    result = utils.RunCmd([constants.DD_CMD,
990
                           "if=/dev/zero", "of=%s" % dev_path,
991
                           "bs=1048576", "count=128", "oflag=direct"])
992
    if result.failed:
993
      base.ThrowError("Can't wipe the meta device: %s", result.output)
994

  
995
    info = DRBD8.GetProcInfo()
996
    cmd_gen = DRBD8.GetCmdGenerator(info)
997
    cmd = cmd_gen.GenInitMetaCmd(minor, dev_path)
998

  
999
    result = utils.RunCmd(cmd)
1000
    if result.failed:
1001
      base.ThrowError("Can't initialize meta device: %s", result.output)
1002

  
888 1003
  @classmethod
889 1004
  def Create(cls, unique_id, children, size, params, excl_stor):
890 1005
    """Create a new DRBD8 device.
......
901 1016
    # check that the minor is unused
902 1017
    aminor = unique_id[4]
903 1018

  
904
    drbd_info = DRBD8Info.CreateFromFile()
905
    if drbd_info.HasMinorStatus(aminor):
906
      status = drbd_info.GetMinorStatus(aminor)
1019
    info = DRBD8.GetProcInfo()
1020
    if info.HasMinorStatus(aminor):
1021
      status = info.GetMinorStatus(aminor)
907 1022
      in_use = status.is_in_use
908 1023
    else:
909 1024
      in_use = False
......
919 1034
    cls._InitMeta(aminor, meta.dev_path)
920 1035
    return cls(unique_id, children, size, params)
921 1036

  
922
  def Grow(self, amount, dryrun, backingstore):
923
    """Resize the DRBD device and its backing storage.
924

  
925
    """
926
    if self.minor is None:
927
      base.ThrowError("drbd%d: Grow called while not attached", self._aminor)
928
    if len(self._children) != 2 or None in self._children:
929
      base.ThrowError("drbd%d: cannot grow diskless device", self.minor)
930
    self._children[0].Grow(amount, dryrun, backingstore)
931
    if dryrun or backingstore:
932
      # DRBD does not support dry-run mode and is not backing storage,
933
      # so we'll return here
934
      return
935
    cmd = self._cmd_gen.GenResizeCmd(self.minor, self.size + amount)
936
    result = utils.RunCmd(cmd)
937
    if result.failed:
938
      base.ThrowError("drbd%d: resize failed: %s", self.minor, result.output)
939

  
940 1037

  
941 1038
def _CanReadDevice(path):
942 1039
  """Check if we can read from the given device.
943 1040

  
944 1041
  This tries to read the first 128k of the device.
945 1042

  
1043
  @type path: string
1044

  
946 1045
  """
947 1046
  try:
948 1047
    utils.ReadFile(path, size=_DEVICE_READ_SIZE)
b/lib/bootstrap.py
470 470

  
471 471
  if drbd_helper is not None:
472 472
    try:
473
      curr_helper = drbd.DRBD8Dev.GetUsermodeHelper()
473
      curr_helper = drbd.DRBD8.GetUsermodeHelper()
474 474
    except errors.BlockDeviceError, err:
475 475
      raise errors.OpPrereqError("Error while checking drbd helper"
476 476
                                 " (specify --no-drbd-storage if you are not"
b/lib/watcher/nodemaint.py
80 80
    """Get list of used DRBD minors.
81 81

  
82 82
    """
83
    return drbd.DRBD8Dev.GetUsedDevs()
83
    return drbd.DRBD8.GetUsedDevs()
84 84

  
85 85
  @classmethod
86 86
  def DoMaintenance(cls, role):
......
121 121
      logging.info("Following DRBD minors should not be active,"
122 122
                   " shutting them down: %s", utils.CommaJoin(drbd_running))
123 123
      for minor in drbd_running:
124
        # pylint: disable=W0212
125
        # using the private method as is, pending enhancements to the DRBD
126
        # interface
127
        drbd.DRBD8Dev._ShutdownAll(minor)
124
        drbd.DRBD8.ShutdownAll(minor)
128 125

  
129 126
  def Exec(self):
130 127
    """Check node status versus cluster desired state.
b/test/py/ganeti.block.drbd_unittest.py
295 295
  def testHelper(self):
296 296
    """Test reading usermode_helper in /sys."""
297 297
    sys_drbd_helper = testutils.TestDataFilename("sys_drbd_usermode_helper.txt")
298
    drbd_helper = drbd.DRBD8Dev.GetUsermodeHelper(filename=sys_drbd_helper)
298
    drbd_helper = drbd.DRBD8.GetUsermodeHelper(filename=sys_drbd_helper)
299 299
    self.failUnlessEqual(drbd_helper, "/bin/true")
300 300

  
301 301
  def testHelperIOErrors(self):
......
303 303
    temp_file = self._CreateTempFile()
304 304
    os.unlink(temp_file)
305 305
    self.failUnlessRaises(errors.BlockDeviceError,
306
                          drbd.DRBD8Dev.GetUsermodeHelper, filename=temp_file)
306
                          drbd.DRBD8.GetUsermodeHelper, filename=temp_file)
307 307

  
308 308
  def testMinorNotFound(self):
309 309
    """Test not-found-minor in /proc"""
......
401 401

  
402 402
    self.test_unique_id = ("hosta.com", 123, "host2.com", 123, 0, "secret")
403 403

  
404
  @testutils.patch_object(drbd_info.DRBD8Info, "CreateFromFile")
404
  @testutils.patch_object(drbd.DRBD8, "GetProcInfo")
405 405
  def testConstructionWith80Data(self, mock_create_from_file):
406 406
    mock_create_from_file.return_value = self.proc80_info
407 407

  
......
409 409
    self.assertEqual(inst._show_info_cls, drbd_info.DRBD83ShowInfo)
410 410
    self.assertTrue(isinstance(inst._cmd_gen, drbd_cmdgen.DRBD83CmdGenerator))
411 411

  
412
  @testutils.patch_object(drbd_info.DRBD8Info, "CreateFromFile")
412
  @testutils.patch_object(drbd.DRBD8, "GetProcInfo")
413 413
  def testConstructionWith83Data(self, mock_create_from_file):
414 414
    mock_create_from_file.return_value = self.proc83_info
415 415

  
......
417 417
    self.assertEqual(inst._show_info_cls, drbd_info.DRBD83ShowInfo)
418 418
    self.assertTrue(isinstance(inst._cmd_gen, drbd_cmdgen.DRBD83CmdGenerator))
419 419

  
420
  @testutils.patch_object(drbd_info.DRBD8Info, "CreateFromFile")
420
  @testutils.patch_object(drbd.DRBD8, "GetProcInfo")
421 421
  def testConstructionWith84Data(self, mock_create_from_file):
422 422
    mock_create_from_file.return_value = self.proc84_info
423 423

  

Also available in: Unified diff