1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 """Utility functions for storage.
31
32 """
33
34 import logging
35
36 from ganeti import constants
37
38
44
45
47 """Checks if a particular disk template is enabled.
48
49 """
50 return disk_template in enabled_disk_templates
51
52
58
59
65
66
68 """Check whether or not any lvm-based disk templates are enabled."""
69 return len(constants.DTS_LVM & set(enabled_disk_templates)) != 0
70
71
72 -def LvmGetsEnabled(enabled_disk_templates, new_enabled_disk_templates):
73 """Checks whether lvm was not enabled before, but will be enabled after
74 the operation.
75
76 """
77 if IsLvmEnabled(enabled_disk_templates):
78 return False
79 return len(constants.DTS_LVM & set(new_enabled_disk_templates)) != 0
80
81
83 """Retrieves the identifier of the default storage entity for the given
84 storage type.
85
86 @type cfg: C{objects.ConfigData}
87 @param cfg: the configuration data
88 @type disk_template: string
89 @param disk_template: a disk template, for example 'drbd'
90 @rtype: string
91 @return: identifier for a storage unit, for example the vg_name for lvm
92 storage
93
94 """
95 storage_type = constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]
96 cluster = cfg.GetClusterInfo()
97 if disk_template in constants.DTS_LVM:
98 return (storage_type, cfg.GetVGName())
99 elif disk_template == constants.DT_FILE:
100 return (storage_type, cluster.file_storage_dir)
101 elif disk_template == constants.DT_SHARED_FILE:
102 return (storage_type, cluster.shared_file_storage_dir)
103 elif disk_template == constants.DT_GLUSTER:
104 return (storage_type, cluster.gluster_storage_dir)
105 else:
106 return (storage_type, None)
107
108
113
114
116 """Get the cluster's storage units for the given disk templates.
117
118 If any lvm-based disk template is requested, spindle information
119 is added to the request.
120
121 @type cfg: L{config.ConfigWriter}
122 @param cfg: Cluster configuration
123 @type disk_templates: list of string
124 @param disk_templates: list of disk templates for which the storage
125 units will be computed
126 @rtype: list of tuples (string, string)
127 @return: list of storage units, each storage unit being a tuple of
128 (storage_type, storage_key); storage_type is in
129 C{constants.STORAGE_TYPES} and the storage_key a string to
130 identify an entity of that storage type, for example a volume group
131 name for LVM storage or a file for file storage.
132
133 """
134 storage_units = []
135 for disk_template in disk_templates:
136 if DiskTemplateSupportsSpaceReporting(disk_template):
137 storage_units.append(
138 _GetDefaultStorageUnitForDiskTemplate(cfg, disk_template))
139 return storage_units
140
141
143 """Looks up the storage space info for a given disk template.
144
145 @type storage_space_info: list of dicts
146 @param storage_space_info: result of C{GetNodeInfo}
147 @type disk_template: string
148 @param disk_template: disk template to get storage space info
149 @rtype: tuple
150 @return: returns the element of storage_space_info that matches the given
151 disk template
152
153 """
154 storage_type = constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[disk_template]
155 return LookupSpaceInfoByStorageType(storage_space_info, storage_type)
156
157
159 """Looks up the storage space info for a given storage type.
160
161 Note that this lookup can be ambiguous if storage space reporting for several
162 units of the same storage type was requested. This function is only supposed
163 to be used for legacy code in situations where it actually is unambiguous.
164
165 @type storage_space_info: list of dicts
166 @param storage_space_info: result of C{GetNodeInfo}
167 @type storage_type: string
168 @param storage_type: a storage type, which is included in the storage_units
169 list
170 @rtype: tuple
171 @return: returns the element of storage_space_info that matches the given
172 storage type
173
174 """
175 result = None
176 for unit_info in storage_space_info:
177 if unit_info["type"] == storage_type:
178 if result is None:
179 result = unit_info
180 else:
181
182 logging.warning("Storage space information requested for"
183 " ambiguous storage type '%s'.", storage_type)
184 return result
185
186
188 """Generate disk labels for a number of disks
189
190 Note that disk labels are generated in the range [start..num_disks[
191 (e.g., as in range(start, num_disks))
192
193 @type prefix: string
194 @param prefix: disk label prefix (e.g., "/dev/sd")
195
196 @type num_disks: int
197 @param num_disks: number of disks (i.e., disk labels)
198
199 @type start: int
200 @param start: optional start index
201
202 @rtype: generator
203 @return: generator for the disk labels
204
205 """
206 def _GetDiskSuffix(i):
207 n = ord('z') - ord('a') + 1
208 if i < n:
209 return chr(ord('a') + i)
210 else:
211 mod = int(i % n)
212 pref = _GetDiskSuffix((i - mod) / (n + 1))
213 suf = _GetDiskSuffix(mod)
214 return pref + suf
215
216 for i in range(start, num_disks):
217 yield prefix + _GetDiskSuffix(i)
218
219
221 """Return the device minor number from a raw device number.
222
223 This is a replacement for os.minor working around the issue that
224 Python's os.minor still has the old definition. See Ganeti issue
225 1058 for more details.
226 """
227 return (dev & 0xff) | ((dev >> 12) & ~0xff)
228