Revision 3840729d

b/lib/bdev.py
1737 1737
    return bnf
1738 1738

  
1739 1739
  @classmethod
1740
  def _GetDevInfo(cls, minor):
1741
    """Get details about a given DRBD minor.
1742

  
1743
    This return, if available, the local backing device (as a path)
1744
    and the local and remote (ip, port) information.
1740
  def _GetShowData(cls, minor):
1741
    """Return the `drbdsetup show` data for a minor.
1745 1742

  
1746 1743
    """
1747
    data = {}
1748 1744
    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "show"])
1749 1745
    if result.failed:
1750 1746
      logger.Error("Can't display the drbd config: %s" % result.fail_reason)
1751
      return data
1752
    out = result.stdout
1747
      return None
1748
    return result.stdout
1749

  
1750
  @classmethod
1751
  def _GetDevInfo(cls, out):
1752
    """Parse details about a given DRBD minor.
1753

  
1754
    This return, if available, the local backing device (as a path)
1755
    and the local and remote (ip, port) information from a string
1756
    containing the output of the `drbdsetup show` command as returned
1757
    by _GetShowData.
1758

  
1759
    """
1760
    data = {}
1753 1761
    if not out:
1754 1762
      return data
1755 1763

  
......
1881 1889
    timeout = time.time() + 10
1882 1890
    ok = False
1883 1891
    while time.time() < timeout:
1884
      info = cls._GetDevInfo(minor)
1892
      info = cls._GetDevInfo(cls._GetShowData(minor))
1885 1893
      if not "local_addr" in info or not "remote_addr" in info:
1886 1894
        time.sleep(1)
1887 1895
        continue
......
1904 1912
      raise errors.BlockDeviceError("Can't attach to dbrd8 during AddChildren")
1905 1913
    if len(devices) != 2:
1906 1914
      raise errors.BlockDeviceError("Need two devices for AddChildren")
1907
    info = self._GetDevInfo(self.minor)
1915
    info = self._GetDevInfo(self._GetShowData(self.minor))
1908 1916
    if "local_dev" in info:
1909 1917
      raise errors.BlockDeviceError("DRBD8 already attached to a local disk")
1910 1918
    backend, meta = devices
......
1930 1938
      raise errors.BlockDeviceError("Can't attach to drbd8 during"
1931 1939
                                    " RemoveChildren")
1932 1940
    # early return if we don't actually have backing storage
1933
    info = self._GetDevInfo(self.minor)
1941
    info = self._GetDevInfo(self._GetShowData(self.minor))
1934 1942
    if "local_dev" not in info:
1935 1943
      return
1936 1944
    if len(self._children) != 2:
......
2083 2091

  
2084 2092
    """
2085 2093
    for minor in self._GetUsedDevs():
2086
      info = self._GetDevInfo(minor)
2094
      info = self._GetDevInfo(self._GetShowData(minor))
2087 2095
      match_l = self._MatchesLocal(info)
2088 2096
      match_r = self._MatchesNet(info)
2089 2097
      if match_l and match_r:
......
2093 2101
                                  (self._lhost, self._lport,
2094 2102
                                   self._rhost, self._rport),
2095 2103
                                  "C")
2096
        if res_r and self._MatchesNet(self._GetDevInfo(minor)):
2097
          break
2104
        if res_r:
2105
          if self._MatchesNet(self._GetDevInfo(self._GetShowData(minor))):
2106
            break
2098 2107
      # the weakest case: we find something that is only net attached
2099 2108
      # even though we were passed some children at init time
2100 2109
      if match_r and "local_dev" not in info:
......
2114 2123
        # None)
2115 2124
        if (self._AssembleNet(minor, (self._lhost, self._lport,
2116 2125
                                      self._rhost, self._rport), "C") and
2117
            self._MatchesNet(self._GetDevInfo(minor))):
2126
            self._MatchesNet(self._GetDevInfo(self._GetShowData(minor)))):
2118 2127
          break
2119 2128

  
2120 2129
    else:
b/test/Makefile.am
1 1
TESTS = \
2 2
  ganeti.config_unittest.py \
3 3
  ganeti.hooks_unittest.py \
4
  ganeti.utils_unittest.py
4
  ganeti.utils_unittest.py \
5
  ganeti.bdev_unittest.py
6

  
5 7
TESTS_ENVIRONMENT = PYTHONPATH=.:$(top_builddir)
6 8

  
7 9
check-am: do-pre-check
b/test/data/bdev-both.txt
1
disk {
2
	size            	0s _is_default; # bytes
3
	on-io-error     	detach;
4
	fencing         	dont-care _is_default;
5
}
6
net {
7
	timeout         	60 _is_default; # 1/10 seconds
8
	max-epoch-size  	16384;
9
	max-buffers     	16384;
10
	unplug-watermark	128 _is_default;
11
	connect-int     	10 _is_default; # seconds
12
	ping-int        	10 _is_default; # seconds
13
	sndbuf-size     	8388608; # bytes
14
	ko-count        	0 _is_default;
15
	after-sb-0pri   	disconnect _is_default;
16
	after-sb-1pri   	disconnect _is_default;
17
	after-sb-2pri   	disconnect _is_default;
18
	rr-conflict     	disconnect _is_default;
19
	ping-timeout    	5 _is_default; # 1/10 seconds
20
}
21
syncer {
22
	rate            	30720k; # bytes/second
23
	after           	-1 _is_default;
24
	al-extents      	257;
25
}
26
protocol A;
27
_this_host {
28
	device			"/dev/drbd63";
29
	disk			"/dev/xenvg/test.data";
30
	meta-disk		"/dev/xenvg/test.meta" [ 0 ];
31
	address			192.168.1.1:11000;
32
}
33
_remote_host {
34
	address			192.168.1.2:11000;
35
}
b/test/data/bdev-disk.txt
1
disk {
2
	size            	0s _is_default; # bytes
3
	on-io-error     	detach;
4
	fencing         	dont-care _is_default;
5
}
6
syncer {
7
	rate            	250k _is_default; # bytes/second
8
	after           	-1 _is_default;
9
	al-extents      	257;
10
}
11
_this_host {
12
	device			"/dev/drbd58";
13
	disk			"/dev/xenvg/test.data";
14
	meta-disk		"/dev/xenvg/test.meta" [ 0 ];
15
}
b/test/data/bdev-net.txt
1
net {
2
	timeout         	60 _is_default; # 1/10 seconds
3
	max-epoch-size  	2048 _is_default;
4
	max-buffers     	2048 _is_default;
5
	unplug-watermark	128 _is_default;
6
	connect-int     	10 _is_default; # seconds
7
	ping-int        	10 _is_default; # seconds
8
	sndbuf-size     	131070 _is_default; # bytes
9
	ko-count        	0 _is_default;
10
	after-sb-0pri   	disconnect _is_default;
11
	after-sb-1pri   	disconnect _is_default;
12
	after-sb-2pri   	disconnect _is_default;
13
	rr-conflict     	disconnect _is_default;
14
	ping-timeout    	5 _is_default; # 1/10 seconds
15
}
16
syncer {
17
	rate            	250k _is_default; # bytes/second
18
	after           	-1 _is_default;
19
	al-extents      	127 _is_default;
20
}
21
protocol C;
22
_this_host {
23
	device			"/dev/drbd59";
24
	address			192.168.1.1:11002;
25
}
26
_remote_host {
27
	address			192.168.1.2:11002;
28
}
b/test/ganeti.bdev_unittest.py
1
#!/usr/bin/python
2
#
3

  
4
# Copyright (C) 2006, 2007 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

  
21

  
22
"""Script for unittesting the bdev module"""
23

  
24

  
25
import unittest
26

  
27
from ganeti import bdev
28

  
29

  
30
class TestDRBD8Runner(unittest.TestCase):
31
  """Testing case for DRBD8"""
32

  
33
  @staticmethod
34
  def _has_disk(data, dname, mname):
35
    """Check local disk corectness"""
36
    retval = (
37
      "local_dev" in data and
38
      data["local_dev"] == dname and
39
      "meta_dev" in data and
40
      data["meta_dev"] == mname and
41
      "meta_index" in data and
42
      data["meta_index"] == 0
43
      )
44
    return retval
45

  
46
  @staticmethod
47
  def _has_net(data, local, remote):
48
    """Check network connection parameters"""
49
    retval = (
50
      "local_addr" in data and
51
      data["local_addr"] == local and
52
      "remote_addr" in data and
53
      data["remote_addr"] == remote
54
      )
55
    return retval
56

  
57
  def testParserCreation(self):
58
    """Test drbdsetup show parser creation"""
59
    bdev.DRBD8._GetShowParser()
60

  
61
  def testParserBoth(self):
62
    """Test drbdsetup show parser for disk and network"""
63
    data = open("data/bdev-both.txt").read()
64
    result = bdev.DRBD8._GetDevInfo(data)
65
    self.failUnless(self._has_disk(result, "/dev/xenvg/test.data",
66
                                   "/dev/xenvg/test.meta"),
67
                    "Wrong local disk info")
68
    self.failUnless(self._has_net(result, ("192.168.1.1", 11000),
69
                                  ("192.168.1.2", 11000)),
70
                    "Wrong network info")
71

  
72
  def testParserNet(self):
73
    """Test drbdsetup show parser for disk and network"""
74
    data = open("data/bdev-net.txt").read()
75
    result = bdev.DRBD8._GetDevInfo(data)
76
    self.failUnless(("local_dev" not in result and
77
                     "meta_dev" not in result and
78
                     "meta_index" not in result),
79
                    "Should not find local disk info")
80
    self.failUnless(self._has_net(result, ("192.168.1.1", 11002),
81
                                  ("192.168.1.2", 11002)),
82
                    "Wrong network info")
83

  
84
  def testParserDisk(self):
85
    """Test drbdsetup show parser for disk and network"""
86
    data = open("data/bdev-disk.txt").read()
87
    result = bdev.DRBD8._GetDevInfo(data)
88
    self.failUnless(self._has_disk(result, "/dev/xenvg/test.data",
89
                                   "/dev/xenvg/test.meta"),
90
                    "Wrong local disk info")
91
    self.failUnless(("local_addr" not in result and
92
                     "remote_addr" not in result),
93
                    "Should not find network info")
94

  
95
if __name__ == '__main__':
96
  unittest.main()

Also available in: Unified diff