/[gli]/trunk/src/GLIStorageDevice.py
Gentoo

Diff of /trunk/src/GLIStorageDevice.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 638 Revision 639
1import commands, string, os, parted 1import commands, string, os, parted
2from GLIException import * 2from GLIException import *
3import GLIUtility 3import GLIUtility
4 4
5MEGABYTE = 1024 * 1024 5MEGABYTE = 1024 * 1024
6
7# these are here so that we can change them easily in future
8# the values were chosen to represent perfect floating point representations
9FREE_MINOR_FRAC_PRI = 1.0/32.0
10FREE_MINOR_FRAC_LOG = 1.0/8.0
6 11
7archinfo = { 'sparc': { 'fixedparts': [ { 'minor': 3, 'type': "wholedisk" } ], 'disklabel': 'sun', 'extended': False }, 12archinfo = { 'sparc': { 'fixedparts': [ { 'minor': 3, 'type': "wholedisk" } ], 'disklabel': 'sun', 'extended': False },
8 'hppa': { 'fixedparts': [ { 'minor': 1, 'type': "boot" } ], 'disklabel': 'msdos', 'extended': False }, 13 'hppa': { 'fixedparts': [ { 'minor': 1, 'type': "boot" } ], 'disklabel': 'msdos', 'extended': False },
9 'x86': { 'fixedparts': [], 'disklabel': 'msdos', 'extended': True }, 14 'x86': { 'fixedparts': [], 'disklabel': 'msdos', 'extended': True },
10 'amd64': { 'fixedparts': [], 'disklabel': 'msdos', 'extended': True }, 15 'amd64': { 'fixedparts': [], 'disklabel': 'msdos', 'extended': True },
79 last_part = parted_part.num 84 last_part = parted_part.num
80 self._partitions[int(parted_part.num)] = Partition(self, parted_part.num, part_mb, parted_part.geom.start, parted_part.geom.end, fs_type, format=False, existing=True) 85 self._partitions[int(parted_part.num)] = Partition(self, parted_part.num, part_mb, parted_part.geom.start, parted_part.geom.end, fs_type, format=False, existing=True)
81 elif parted_part.type_name == "free": 86 elif parted_part.type_name == "free":
82 parent_part = self.get_partition_at(parted_part.geom.start, ignore_extended=0) 87 parent_part = self.get_partition_at(parted_part.geom.start, ignore_extended=0)
83 if parent_part: 88 if parent_part:
84 self._partitions[last_log_part+0.9] = Partition(self, last_log_part+0.9, part_mb, parted_part.geom.start, parted_part.geom.end, "free", format=False, existing=False) 89 self._partitions[last_log_part+FREE_MINOR_FRAC_LOG] = Partition(self, last_log_part+FREE_MINOR_FRAC_LOG, part_mb, parted_part.geom.start, parted_part.geom.end, "free", format=False, existing=False)
85 last_log_part += 1 90 last_log_part += 1
86 else: 91 else:
87 self._partitions[last_part+0.1] = Partition(self, last_part+0.1, part_mb, parted_part.geom.start, parted_part.geom.end, "free", format=False, existing=False) 92 self._partitions[last_part+FREE_MINOR_FRAC_PRI] = Partition(self, last_part+FREE_MINOR_FRAC_PRI, part_mb, parted_part.geom.start, parted_part.geom.end, "free", format=False, existing=False)
88 last_part += 1 93 last_part += 1
89 parted_part = self._parted_disk.next_partition(parted_part) 94 parted_part = self._parted_disk.next_partition(parted_part)
90 95
91 ## 96 ##
92 # Imports partition info from the install profile partition structure (currently does nothing) 97 # Imports partition info from the install profile partition structure
93 # @param ips Parameter structure returned from install_profile.get_partition_tables() 98 # @param ips Parameter structure returned from install_profile.get_partition_tables()
94 def set_partitions_from_install_profile_structure(self, ips): 99 def set_partitions_from_install_profile_structure(self, ips):
95 for part in ips: 100 for part in ips:
96 tmppart = ips[part] 101 tmppart = ips[part]
97 existing = False 102 existing = False
116 for part in parts: 121 for part in parts:
117 if archinfo[self._arch]['extended'] and part > 4: break 122 if archinfo[self._arch]['extended'] and part > 4: break
118 tmppart = self._partitions[part] 123 tmppart = self._partitions[part]
119 if tmppart.get_type() == "extended": 124 if tmppart.get_type() == "extended":
120 for part_log in parts: 125 for part_log in parts:
121 if part_log < 4.9: continue 126 if part_log < (4 + FREE_MINOR_FRAC_LOG): continue
122 tmppart_log = self._partitions[part_log] 127 tmppart_log = self._partitions[part_log]
123 if tmppart_log.get_type() == "free": 128 if tmppart_log.get_type() == "free":
124 if last_log_minor < last_log_free: 129 if last_log_minor < last_log_free:
125 self._partitions[last_log_free].set_mb(self._partitions[last_log_free].get_mb()+tmppart_log.get_mb()) 130 self._partitions[last_log_free].set_mb(self._partitions[last_log_free].get_mb()+tmppart_log.get_mb())
126 del self._partitions[part_log] 131 del self._partitions[part_log]
127 else: 132 else:
128 if not last_log_free: 133 if not last_log_free:
129 last_log_free = last_log_minor + 0.9 134 last_log_free = last_log_minor + FREE_MINOR_FRAC_LOG
130 else: 135 else:
131 last_log_free = part_log 136 last_log_free = part_log
132 tmppart_log.set_minor(last_log_free) 137 tmppart_log.set_minor(last_log_free)
133 self._partitions[last_log_free] = tmppart_log 138 self._partitions[last_log_free] = tmppart_log
134 if part_log != last_log_free: del self._partitions[part_log] 139 if part_log != last_log_free: del self._partitions[part_log]
144 if last_minor < last_free: 149 if last_minor < last_free:
145 self._partitions[last_free].set_mb(self._partitions[last_free].get_mb()+tmppart.get_mb()) 150 self._partitions[last_free].set_mb(self._partitions[last_free].get_mb()+tmppart.get_mb())
146 del self._partitions[part] 151 del self._partitions[part]
147 else: 152 else:
148 if not last_free: 153 if not last_free:
149 last_free = last_minor + 0.1 154 last_free = last_minor + FREE_MINOR_FRAC_PRI
150 else: 155 else:
151 last_free = part 156 last_free = part
152 tmppart.set_minor(last_free) 157 tmppart.set_minor(last_free)
153 self._partitions[last_free] = tmppart 158 self._partitions[last_free] = tmppart
154 if part != last_free: del self._partitions[part] 159 if part != last_free: del self._partitions[part]
193 if i == new_minor: stopscooting = 1 198 if i == new_minor: stopscooting = 1
194 if mb != self._partitions[free_minor].get_mb(): 199 if mb != self._partitions[free_minor].get_mb():
195 old_free_mb = self._partitions[free_minor].get_mb() 200 old_free_mb = self._partitions[free_minor].get_mb()
196 del self._partitions[free_minor] 201 del self._partitions[free_minor]
197 if archinfo[self._arch]['extended'] and new_minor >= 5: 202 if archinfo[self._arch]['extended'] and new_minor >= 5:
198 free_minor = new_minor + 0.9 203 free_minor = new_minor + FREE_MINOR_FRAC_LOG
199 else: 204 else:
200 free_minor = new_minor + 0.1 205 free_minor = new_minor + FREE_MINOR_FRAC_PRI
201 self._partitions[free_minor] = Partition(self, free_minor, old_free_mb-mb, 0, 0, "free") 206 self._partitions[free_minor] = Partition(self, free_minor, old_free_mb-mb, 0, 0, "free")
202# print "add_partition(): new part doesn't use all freespace. new free part is: minor=" + str(free_minor)
203 else: 207 else:
204 del self._partitions[free_minor] 208 del self._partitions[free_minor]
205 self._partitions[new_minor] = Partition(self, new_minor, mb, start, end, type, mountpoint=mountpoint, mountopts=mountopts,mkfsopts=mkfsopts) 209 self._partitions[new_minor] = Partition(self, new_minor, mb, start, end, type, mountpoint=mountpoint, mountopts=mountopts,mkfsopts=mkfsopts)
206 if type == "extended": 210 if type == "extended":
207 self._partitions[4.9] = Partition(self, 4.9, mb, 0, 0, "free") 211 self._partitions[4 + FREE_MINOR_FRAC_LOG] = Partition(self, (4 + FREE_MINOR_FRAC_LOG), mb, 0, 0, "free")
208 self.tidy_partitions() 212 self.tidy_partitions()
209 213
210 ## 214 ##
211 # Removes partition from partition info 215 # Removes partition from partition info
212 # @param minor Minor of partition to remove 216 # @param minor Minor of partition to remove
213 def remove_partition(self, minor): 217 def remove_partition(self, minor):
214 tmppart = self._partitions[int(minor)] 218 tmppart = self._partitions[int(minor)]
215 free_minor = 0 219 free_minor = 0
216 if tmppart.is_logical(): 220 if tmppart.is_logical():
217 free_minor = minor-0.1 221 free_minor = int(minor-1)+FREE_MINOR_FRAC_LOG
218 else: 222 else:
219 free_minor = minor-0.9 223 free_minor = int(minor-1)+FREE_MINOR_FRAC_PRI
224 if free_minor in self._partitions:
225 self._partitions[free_minor].set_mb(self._partitions[free_minor].get_mb() + tmppart.get_mb())
226 else:
220 self._partitions[free_minor] = Partition(self, free_minor, tmppart.get_mb(), 0, 0, "free", format=False, existing=False) 227 self._partitions[free_minor] = Partition(self, free_minor, tmppart.get_mb(), 0, 0, "free", format=False, existing=False)
221 del self._partitions[int(minor)] 228 del self._partitions[int(minor)]
222 self.tidy_partitions() 229 self.tidy_partitions()
223
224 ##
225 # Returns free space (no longer used)
226 # @param start Start sector for search
227 def get_free_space(self, start):
228 GAP_SIZE = 100
229 parts = self._partitions.keys()
230 parts.sort()
231 lastend_pri = 0
232 lastend_log = 0
233 free_start = -1
234 free_end = -1
235 if start > self._total_sectors: return (-1, -1)
236 for part in parts:
237 if part > 4: break
238 tmppart = self._partitions[part]
239 if (tmppart.get_start() > (lastend_pri + GAP_SIZE)) and (lastend_pri >= start):
240 free_start = lastend_pri
241 free_end = tmppart.get_start() - 1
242 break
243 if tmppart.is_extended() and start < tmppart.get_end():
244 lastend_log = tmppart.get_start()
245 for part_log in parts:
246 if part_log < 5: continue
247 tmppart_log = self._partitions[part_log]
248 if (tmppart_log.get_start() > (lastend_log + GAP_SIZE)) and (lastend_log >= start):
249 free_start = lastend_log
250 free_end = tmppart_log.get_start() - 1
251 break
252 lastend_log = tmppart_log.get_end() + 1
253 if free_start == -1 and lastend_log < tmppart.get_end():
254 free_start = lastend_log
255 free_end = tmppart.get_end()
256 break
257 lastend_pri = tmppart.get_end() + 1
258 if free_start == -1 and lastend_pri < self._total_sectors:
259 free_start = lastend_pri
260 free_end = self._total_sectors
261 return (free_start, free_end)
262
263 ##
264 # Gets partition containing a certain sector (no longer used)
265 # @param sector Sector to look at
266 # @param ignore_extended=1 Ignore extended partitions
267 def get_partition_at(self, sector, ignore_extended=1):
268 parts = self._partitions.keys()
269 parts.sort()
270 for part in parts:
271 tmppart = self._partitions[part]
272 if ignore_extended and tmppart.is_extended(): continue
273 if (sector >= tmppart.get_start()) and (sector <= tmppart.get_end()):
274 return part
275 return 0
276
277 ##
278 # Returns free minor (no longer used)
279 # @param start Parameter description
280 # @param end Parameter description
281 def get_free_minor_at(self, start, end):
282 parts = self._partitions.keys()
283 parts.sort()
284 minor = 1
285 lastpart = 0
286 for part in parts:
287 if part > 4: break
288 tmppart = self._partitions[part]
289 if end < tmppart.get_start():
290 minor = part
291 if (minor - 1) > lastpart: minor = lastpart + 1
292 break
293 if tmppart.is_extended() and start < tmppart.get_end():
294 minor = 5
295 lastpart = 4
296 for part_log in parts:
297 if part_log < 5: continue
298 tmppart_log = self._partitions[part_log]
299 if end < tmppart_log.get_start():
300 minor = part_log
301 if (minor - 1) > lastpart: minor = lastpart + 1
302 break
303 minor = part_log + 1
304 lastpart = part_log
305 break
306 minor = part + 1
307 lastpart = part
308 return minor
309 230
310 ## 231 ##
311 # Returns an ordered list (disk order) of partition minors 232 # Returns an ordered list (disk order) of partition minors
312 def get_ordered_partition_list(self): 233 def get_ordered_partition_list(self):
313 parts = self._partitions.keys() 234 parts = self._partitions.keys()
314 parts.sort() 235 parts.sort()
315 partlist = [] 236 partlist = []
316 tmppart = None 237 tmppart = None
317 for part in parts: 238 for part in parts:
318 if archinfo[self._arch]['extended'] and part > 4.1: break 239 if archinfo[self._arch]['extended'] and part > (4 + FREE_MINOR_FRAC_PRI): break
319 tmppart = self._partitions[part] 240 tmppart = self._partitions[part]
320 partlist.append(part) 241 partlist.append(part)
321 if tmppart.is_extended(): 242 if tmppart.is_extended():
322 for part_log in parts: 243 for part_log in parts:
323 if part_log < 4.9: continue 244 if part_log < (4 + FREE_MINOR_FRAC_LOG): continue
324 partlist.append(part_log) 245 partlist.append(part_log)
325 return partlist 246 return partlist
326 247
327 ## 248 ##
328 # Returns partition info in a format suitable for passing to install_profile.set_partition_tables() 249 # Returns partition info in a format suitable for passing to install_profile.set_partition_tables()
394 315
395 ## 316 ##
396 # Prints disk geometry to STDOUT (no longer used) 317 # Prints disk geometry to STDOUT (no longer used)
397 def print_geometry(self): 318 def print_geometry(self):
398 print self._total_bytes, self._geometry 319 print self._total_bytes, self._geometry
399
400 ##
401 # Utility function for running a command and returning it's output as a list
402 # @param cmd Command to run
403 def _run(self, cmd):
404 "Runs a command and returns the output"
405
406 # Run command
407 output_string = commands.getoutput(cmd)
408
409 # What we will return
410 output_list = []
411
412 # As long as there is a new line in the output_string
413 while output_string.find("\n") != -1:
414
415 # Find the \n in the string
416 index = output_string.find("\n") + 1
417
418 # Add the line to the output and remove it from
419 # the output_string
420 output_list.append(output_string[:index])
421 output_string = output_string[index:]
422
423 # return output
424 return output_list
425 320
426## 321##
427# This class represents a partition within a GLIStorageDevice object 322# This class represents a partition within a GLIStorageDevice object
428class Partition: 323class Partition:
429 "Class representing a single partition within a Device object" 324 "Class representing a single partition within a Device object"
513 408
514 ## 409 ##
515 # Returns whether or not the partition is logical 410 # Returns whether or not the partition is logical
516 def is_logical(self): 411 def is_logical(self):
517 if self._type == "free": 412 if self._type == "free":
518 if int(self._minor) + 0.9 == self._minor: 413 if int(self._minor) + FREE_MINOR_FRAC_LOG == self._minor:
519 return True 414 return True
520 else: 415 else:
521 return False 416 return False
522 elif archinfo[self._device._arch]['extended'] and self._minor > 4: 417 elif archinfo[self._device._arch]['extended'] and self._minor > 4:
523 return True 418 return True
685 # Returns maximum MB for resize 580 # Returns maximum MB for resize
686 def get_max_mb_for_resize(self): 581 def get_max_mb_for_resize(self):
687 if self._resizeable: 582 if self._resizeable:
688 free_minor = 0 583 free_minor = 0
689 if self.is_logical(): 584 if self.is_logical():
690 free_minor = self._minor + 0.9 585 free_minor = self._minor + FREE_MINOR_FRAC_LOG
691 else: 586 else:
692 free_minor = self._minor + 0.1 587 free_minor = self._minor + FREE_MINOR_FRAC_PRI
693 if free_minor in self._device._partitions: 588 if free_minor in self._device._partitions:
694 return self._mb + self._device._partitions[free_minor]._mb 589 return self._mb + self._device._partitions[free_minor]._mb
695 else: 590 else:
696 return self._mb 591 return self._mb
697 else: 592 else:
701 # Resizes the partition 596 # Resizes the partition
702 # @param mb New size in MB 597 # @param mb New size in MB
703 def resize(self, mb): 598 def resize(self, mb):
704 free_minor = self._minor 599 free_minor = self._minor
705 if self.is_logical(): 600 if self.is_logical():
706 free_minor += 0.9 601 free_minor += FREE_MINOR_FRAC_LOG
707 else: 602 else:
708 free_minor += 0.1 603 free_minor += FREE_MINOR_FRAC_PRI
709 if mb < self._mb: 604 if mb < self._mb:
710 # Shrinking 605 # Shrinking
711 if not free_minor in self._device._partitions: 606 if not free_minor in self._device._partitions:
712 self._device._partitions[free_minor] = Partition(self._device, free_minor, 0, 0, 0, "free", format=False, existing=False) 607 self._device._partitions[free_minor] = Partition(self._device, free_minor, 0, 0, 0, "free", format=False, existing=False)
713 self._device._partitions[free_minor]._mb += self._mb - mb 608 self._device._partitions[free_minor]._mb += self._mb - mb

Legend:
Removed from v.638  
changed lines
  Added in v.639

  ViewVC Help
Powered by ViewVC 1.1.20