Merge lp:~gnuoy/charm-helpers/1496746 into lp:charm-helpers

Proposed by Liam Young on 2015-09-17
Status: Merged
Merged at revision: 450
Proposed branch: lp:~gnuoy/charm-helpers/1496746
Merge into: lp:charm-helpers
Diff against target: 158 lines (+79/-7)
4 files modified
charmhelpers/core/hugepage.py (+8/-1)
charmhelpers/core/strutils.py (+30/-0)
tests/core/test_hugepage.py (+26/-6)
tests/core/test_strutils.py (+15/-0)
To merge this branch: bzr merge lp:~gnuoy/charm-helpers/1496746
Reviewer Review Type Date Requested Status
James Page 2015-09-17 Approve on 2015-09-17
Review via email: mp+271443@code.launchpad.net
To post a comment you must log in.
Liam Young (gnuoy) wrote :

Looking at https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt the pagesize option that is used to mount the hugepages should be set in bytes not human readable equivalent and that makes working out shmmax much easier too.

lp:~gnuoy/charm-helpers/1496746 updated on 2015-09-17
451. By Liam Young on 2015-09-17

Add function to convert human readable representation of quantity of bytes (eg 1G) to int

James Page (james-page) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/core/hugepage.py'
2--- charmhelpers/core/hugepage.py 2015-08-19 09:40:54 +0000
3+++ charmhelpers/core/hugepage.py 2015-09-17 11:04:29 +0000
4@@ -25,11 +25,13 @@
5 fstab_mount,
6 mkdir,
7 )
8+from charmhelpers.core.strutils import bytes_from_string
9+from subprocess import check_output
10
11
12 def hugepage_support(user, group='hugetlb', nr_hugepages=256,
13 max_map_count=65536, mnt_point='/run/hugepages/kvm',
14- pagesize='2MB', mount=True):
15+ pagesize='2MB', mount=True, set_shmmax=False):
16 """Enable hugepages on system.
17
18 Args:
19@@ -49,6 +51,11 @@
20 'vm.max_map_count': max_map_count,
21 'vm.hugetlb_shm_group': gid,
22 }
23+ if set_shmmax:
24+ shmmax_current = int(check_output(['sysctl', '-n', 'kernel.shmmax']))
25+ shmmax_minsize = bytes_from_string(pagesize) * nr_hugepages
26+ if shmmax_minsize > shmmax_current:
27+ sysctl_settings['kernel.shmmax'] = shmmax_minsize
28 sysctl.create(yaml.dump(sysctl_settings), '/etc/sysctl.d/10-hugepage.conf')
29 mkdir(mnt_point, owner='root', group='root', perms=0o755, force=False)
30 lfstab = fstab.Fstab()
31
32=== modified file 'charmhelpers/core/strutils.py'
33--- charmhelpers/core/strutils.py 2015-04-13 19:18:40 +0000
34+++ charmhelpers/core/strutils.py 2015-09-17 11:04:29 +0000
35@@ -18,6 +18,7 @@
36 # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
37
38 import six
39+import re
40
41
42 def bool_from_string(value):
43@@ -40,3 +41,32 @@
44
45 msg = "Unable to interpret string value '%s' as boolean" % (value)
46 raise ValueError(msg)
47+
48+
49+def bytes_from_string(value):
50+ """Interpret human readable string value as bytes.
51+
52+ Returns int
53+ """
54+ BYTE_POWER = {
55+ 'K': 1,
56+ 'KB': 1,
57+ 'M': 2,
58+ 'MB': 2,
59+ 'G': 3,
60+ 'GB': 3,
61+ 'T': 4,
62+ 'TB': 4,
63+ 'P': 5,
64+ 'PB': 5,
65+ }
66+ if isinstance(value, six.string_types):
67+ value = six.text_type(value)
68+ else:
69+ msg = "Unable to interpret non-string value '%s' as boolean" % (value)
70+ raise ValueError(msg)
71+ matches = re.match("([0-9]+)([a-zA-Z]+)", value)
72+ if not matches:
73+ msg = "Unable to interpret string value '%s' as bytes" % (value)
74+ raise ValueError(msg)
75+ return int(matches.group(1)) * (1024 ** BYTE_POWER[matches.group(2)])
76
77=== modified file 'tests/core/test_hugepage.py'
78--- tests/core/test_hugepage.py 2015-08-17 11:37:03 +0000
79+++ tests/core/test_hugepage.py 2015-09-17 11:04:29 +0000
80@@ -1,6 +1,7 @@
81 from testtools import TestCase
82 from mock import patch
83 from charmhelpers.core import hugepage
84+import yaml
85
86 TO_PATCH = [
87 'fstab',
88@@ -9,6 +10,7 @@
89 'sysctl',
90 'fstab_mount',
91 'mkdir',
92+ 'check_output',
93 ]
94
95
96@@ -68,15 +70,33 @@
97 self.fstab.Fstab().Entry.return_value = 'new fstab entry'
98 hugepage.hugepage_support(
99 'nova', group='neutron', nr_hugepages=512, max_map_count=70000,
100- mnt_point='/hugepages', pagesize='1GB', mount=False)
101- sysctl_expect = ("{vm.hugetlb_shm_group: '1010', "
102- "vm.max_map_count: 70000, vm.nr_hugepages: 512}\n")
103- self.sysctl.create.assert_called_with(sysctl_expect,
104- '/etc/sysctl.d/10-hugepage.conf')
105+ mnt_point='/hugepages', pagesize='1G', mount=False)
106+ sysctl_expect = {
107+ 'vm.hugetlb_shm_group': '1010',
108+ 'vm.max_map_count': 70000,
109+ 'vm.nr_hugepages': 512,
110+ }
111+ sysctl_setting_arg = self.sysctl.create.call_args_list[0][0][0]
112+ self.assertEqual(yaml.load(sysctl_setting_arg), sysctl_expect)
113 self.mkdir.assert_called_with('/hugepages', owner='root',
114 group='root', perms=0o755, force=False)
115 self.fstab.Fstab().remove_entry.assert_called_with('old fstab entry')
116 self.fstab.Fstab().Entry.assert_called_with(
117 'nodev', '/hugepages', 'hugetlbfs',
118- 'mode=1770,gid=1010,pagesize=1GB', 0, 0)
119+ 'mode=1770,gid=1010,pagesize=1G', 0, 0)
120 self.fstab.Fstab().add_entry.assert_called_with('new fstab entry')
121+
122+ def test_hugepage_support_set_shmmax(self):
123+ self.add_group.return_value = Group()
124+ self.fstab.Fstab().get_entry_by_attr.return_value = None
125+ self.fstab.Fstab().Entry.return_value = 'new fstab entry'
126+ self.check_output.return_value = 2000
127+ hugepage.hugepage_support('nova', mount=False, set_shmmax=True)
128+ sysctl_expect = {
129+ 'kernel.shmmax': 536870912,
130+ 'vm.hugetlb_shm_group': '1010',
131+ 'vm.max_map_count': 65536,
132+ 'vm.nr_hugepages': 256
133+ }
134+ sysctl_setting_arg = self.sysctl.create.call_args_list[0][0][0]
135+ self.assertEqual(yaml.load(sysctl_setting_arg), sysctl_expect)
136
137=== modified file 'tests/core/test_strutils.py'
138--- tests/core/test_strutils.py 2015-04-13 19:18:40 +0000
139+++ tests/core/test_strutils.py 2015-09-17 11:04:29 +0000
140@@ -32,3 +32,18 @@
141
142 self.assertRaises(ValueError, strutils.bool_from_string, None)
143 self.assertRaises(ValueError, strutils.bool_from_string, 'foo')
144+
145+ def test_bytes_from_string(self):
146+ self.assertEqual(strutils.bytes_from_string('3K'), 3072)
147+ self.assertEqual(strutils.bytes_from_string('3KB'), 3072)
148+ self.assertEqual(strutils.bytes_from_string('3M'), 3145728)
149+ self.assertEqual(strutils.bytes_from_string('3MB'), 3145728)
150+ self.assertEqual(strutils.bytes_from_string('3G'), 3221225472)
151+ self.assertEqual(strutils.bytes_from_string('3GB'), 3221225472)
152+ self.assertEqual(strutils.bytes_from_string('3T'), 3298534883328)
153+ self.assertEqual(strutils.bytes_from_string('3TB'), 3298534883328)
154+ self.assertEqual(strutils.bytes_from_string('3P'), 3377699720527872)
155+ self.assertEqual(strutils.bytes_from_string('3PB'), 3377699720527872)
156+
157+ self.assertRaises(ValueError, strutils.bytes_from_string, None)
158+ self.assertRaises(ValueError, strutils.bytes_from_string, 'foo')

Subscribers

People subscribed via source and target branches