Exemple #1
0
  def Snapshot(self, snap_name=None, snap_size=None):
    """Create a snapshot copy of an lvm block device.

    @returns: tuple (vg, lv)

    """
    if not snap_name:
      snap_name = self._lv_name + ".snap"

    if not snap_size:
      # FIXME: choose a saner value for the snapshot size
      # let's stay on the safe side and ask for the full size, for now
      snap_size = self.size

    # remove existing snapshot if found
    snap = LogicalVolume((self._vg_name, snap_name), None, snap_size,
                         self.params, self.dyn_params)
    base.IgnoreError(snap.Remove)

    vg_info = self.GetVGInfo([self._vg_name], False)
    if not vg_info:
      base.ThrowError("Can't compute VG info for vg %s", self._vg_name)
    free_size, _, _ = vg_info[0]
    if free_size < snap_size:
      base.ThrowError("Not enough free space: required %s,"
                      " available %s", snap_size, free_size)

    _CheckResult(utils.RunCmd(["lvcreate", "-L%dm" % snap_size, "-s",
                               "-n%s" % snap_name, self.dev_path]))

    return (self._vg_name, snap_name)
Exemple #2
0
        def _WaitForDisconnect():
            if self.GetProcStatus().is_standalone:
                return

            # retry the disconnect, it seems possible that due to a well-time
            # disconnect on the peer, my disconnect command might be ignored and
            # forgotten
            dstatus.ever_disconnected = \
              base.IgnoreError(self._ShutdownNet, self.minor) or \
              dstatus.ever_disconnected

            raise utils.RetryAgain()
Exemple #3
0
    def DisconnectNet(self):
        """Removes network configuration.

    This method shutdowns the network side of the device.

    The method will wait up to a hardcoded timeout for the device to
    go into standalone after the 'disconnect' command before
    re-configuring it, as sometimes it takes a while for the
    disconnect to actually propagate and thus we might issue a 'net'
    command while the device is still connected. If the device will
    still be attached to the network and we time out, we raise an
    exception.

    """
        if self.minor is None:
            base.ThrowError("drbd%d: disk not attached in re-attach net",
                            self._aminor)

        if None in (self._lhost, self._lport, self._rhost, self._rport):
            base.ThrowError(
                "drbd%d: DRBD disk missing network info in"
                " DisconnectNet()", self.minor)

        class _DisconnectStatus(object):
            def __init__(self, ever_disconnected):
                self.ever_disconnected = ever_disconnected

        dstatus = _DisconnectStatus(
            base.IgnoreError(self._ShutdownNet, self.minor))

        def _WaitForDisconnect():
            if self.GetProcStatus().is_standalone:
                return

            # retry the disconnect, it seems possible that due to a well-time
            # disconnect on the peer, my disconnect command might be ignored and
            # forgotten
            dstatus.ever_disconnected = \
              base.IgnoreError(self._ShutdownNet, self.minor) or \
              dstatus.ever_disconnected

            raise utils.RetryAgain()

        # Keep start time
        start_time = time.time()

        try:
            # Start delay at 100 milliseconds and grow up to 2 seconds
            utils.Retry(_WaitForDisconnect, (0.1, 1.5, 2.0),
                        self._NET_RECONFIG_TIMEOUT)
        except utils.RetryTimeout:
            if dstatus.ever_disconnected:
                msg = ("drbd%d: device did not react to the"
                       " 'disconnect' command in a timely manner")
            else:
                msg = "drbd%d: can't shutdown network, even after multiple retries"

            base.ThrowError(msg, self.minor)

        reconfig_time = time.time() - start_time
        if reconfig_time > (self._NET_RECONFIG_TIMEOUT * 0.25):
            logging.info("drbd%d: DisconnectNet: detach took %.3f seconds",
                         self.minor, reconfig_time)