OLD | NEW |
1 """ | 1 """ |
2 APIs to write tests and control files that handle partition creation, deletion | 2 APIs to write tests and control files that handle partition creation, deletion |
3 and formatting. | 3 and formatting. |
4 | 4 |
5 @copyright: Google 2006-2008 | 5 @copyright: Google 2006-2008 |
6 @author: Martin Bligh (mbligh@google.com) | 6 @author: Martin Bligh (mbligh@google.com) |
7 """ | 7 """ |
8 | 8 |
9 import os, re, string, sys, fcntl, logging | 9 import os, re, string, sys, fcntl, logging |
10 from autotest_lib.client.bin import os_dep, utils | 10 from autotest_lib.client.bin import os_dep, utils |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 169 |
170 if filter_func and not filter_func(partname): | 170 if filter_func and not filter_func(partname): |
171 logging.debug('Skipping %s - Filter func.' % partname) | 171 logging.debug('Skipping %s - Filter func.' % partname) |
172 continue | 172 continue |
173 | 173 |
174 partitions.append(partition(job, device)) | 174 partitions.append(partition(job, device)) |
175 | 175 |
176 return partitions | 176 return partitions |
177 | 177 |
178 | 178 |
| 179 def get_mount_info(partition_list): |
| 180 """ |
| 181 Picks up mount point information about the machine mounts. By default, we |
| 182 try to associate mount points with UUIDs, because in newer distros the |
| 183 partitions are uniquely identified using them. |
| 184 """ |
| 185 mount_info = set() |
| 186 for p in partition_list: |
| 187 try: |
| 188 uuid = utils.system_output('blkid -s UUID -o value %s' % p.device) |
| 189 except error.CmdError: |
| 190 # fall back to using the partition |
| 191 uuid = p.device |
| 192 mount_info.add((uuid, p.get_mountpoint())) |
| 193 |
| 194 return mount_info |
| 195 |
| 196 |
179 def filter_partition_list(partitions, devnames): | 197 def filter_partition_list(partitions, devnames): |
180 """ | 198 """ |
181 Pick and choose which partition to keep. | 199 Pick and choose which partition to keep. |
182 | 200 |
183 filter_partition_list accepts a list of partition objects and a list | 201 filter_partition_list accepts a list of partition objects and a list |
184 of strings. If a partition has the device name of the strings it | 202 of strings. If a partition has the device name of the strings it |
185 is returned in a list. | 203 is returned in a list. |
186 | 204 |
187 @param partitions: A list of L{partition} objects | 205 @param partitions: A list of L{partition} objects |
188 @param devnames: A list of devnames of the form '/dev/hdc3' that | 206 @param devnames: A list of devnames of the form '/dev/hdc3' that |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 if not partname[-1].isdigit(): | 322 if not partname[-1].isdigit(): |
305 # Disk name does not end in number, AFAIK | 323 # Disk name does not end in number, AFAIK |
306 # so use it as a reference to a disk | 324 # so use it as a reference to a disk |
307 if device.strip("/dev/") == partname: | 325 if device.strip("/dev/") == partname: |
308 return True | 326 return True |
309 | 327 |
310 return False | 328 return False |
311 | 329 |
312 | 330 |
313 def run_test_on_partitions(job, test, partitions, mountpoint_func, | 331 def run_test_on_partitions(job, test, partitions, mountpoint_func, |
314 tag, fs_opt, **dargs): | 332 tag, fs_opt, do_fsck=True, **dargs): |
315 """ | 333 """ |
316 Run a test that requires multiple partitions. Filesystems will be | 334 Run a test that requires multiple partitions. Filesystems will be |
317 made on the partitions and mounted, then the test will run, then the | 335 made on the partitions and mounted, then the test will run, then the |
318 filesystems will be unmounted and fsck'd. | 336 filesystems will be unmounted and optionally fsck'd. |
319 | 337 |
320 @param job: A job instance to run the test | 338 @param job: A job instance to run the test |
321 @param test: A string containing the name of the test | 339 @param test: A string containing the name of the test |
322 @param partitions: A list of partition objects, these are passed to the | 340 @param partitions: A list of partition objects, these are passed to the |
323 test as partitions= | 341 test as partitions= |
324 @param mountpoint_func: A callable that returns a mountpoint given a | 342 @param mountpoint_func: A callable that returns a mountpoint given a |
325 partition instance | 343 partition instance |
326 @param tag: A string tag to make this test unique (Required for control | 344 @param tag: A string tag to make this test unique (Required for control |
327 files that make multiple calls to this routine with the same value | 345 files that make multiple calls to this routine with the same value |
328 of 'test'.) | 346 of 'test'.) |
329 @param fs_opt: An FsOptions instance that describes what filesystem to make | 347 @param fs_opt: An FsOptions instance that describes what filesystem to make |
| 348 @param do_fsck: include fsck in post-test partition cleanup. |
330 @param dargs: Dictionary of arguments to be passed to job.run_test() and | 349 @param dargs: Dictionary of arguments to be passed to job.run_test() and |
331 eventually the test | 350 eventually the test |
332 """ | 351 """ |
333 # setup the filesystem parameters for all the partitions | 352 # setup the filesystem parameters for all the partitions |
334 for p in partitions: | 353 for p in partitions: |
335 p.set_fs_options(fs_opt) | 354 p.set_fs_options(fs_opt) |
336 | 355 |
337 # make and mount all the partitions in parallel | 356 # make and mount all the partitions in parallel |
338 parallel(partitions, 'setup_before_test', mountpoint_func=mountpoint_func) | 357 parallel(partitions, 'setup_before_test', mountpoint_func=mountpoint_func) |
339 | 358 |
340 mountpoint = mountpoint_func(partitions[0]) | 359 mountpoint = mountpoint_func(partitions[0]) |
341 | 360 |
342 # run the test against all the partitions | 361 # run the test against all the partitions |
343 job.run_test(test, tag=tag, partitions=partitions, dir=mountpoint, **dargs) | 362 job.run_test(test, tag=tag, partitions=partitions, dir=mountpoint, **dargs) |
344 | 363 |
345 # fsck and then remake all the filesystems in parallel | 364 parallel(partitions, 'unmount') # unmount all partitions in parallel |
346 parallel(partitions, 'cleanup_after_test') | 365 if do_fsck: |
| 366 parallel(partitions, 'fsck') # fsck all partitions in parallel |
| 367 # else fsck is done by caller |
347 | 368 |
348 | 369 |
349 class partition(object): | 370 class partition(object): |
350 """ | 371 """ |
351 Class for handling partitions and filesystems | 372 Class for handling partitions and filesystems |
352 """ | 373 """ |
353 | 374 |
354 def __init__(self, job, device, loop_size=0, mountpoint=None): | 375 def __init__(self, job, device, loop_size=0, mountpoint=None): |
355 """ | 376 """ |
356 @param job: A L{client.bin.job} instance. | 377 @param job: A L{client.bin.job} instance. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 mountpoint = mountpoint_func(self) | 444 mountpoint = mountpoint_func(self) |
424 if not mountpoint: | 445 if not mountpoint: |
425 raise ValueError('Don\'t know where to put this partition') | 446 raise ValueError('Don\'t know where to put this partition') |
426 self.unmount(ignore_status=True, record=False) | 447 self.unmount(ignore_status=True, record=False) |
427 self.mkfs() | 448 self.mkfs() |
428 if not os.path.isdir(mountpoint): | 449 if not os.path.isdir(mountpoint): |
429 os.makedirs(mountpoint) | 450 os.makedirs(mountpoint) |
430 self.mount(mountpoint) | 451 self.mount(mountpoint) |
431 | 452 |
432 | 453 |
433 def cleanup_after_test(self): | |
434 """ | |
435 Cleans up a partition after running a filesystem test. The | |
436 filesystem is unmounted, and then checked for errors. | |
437 """ | |
438 self.unmount() | |
439 self.fsck() | |
440 | |
441 | |
442 def run_test_on_partition(self, test, mountpoint_func, **dargs): | 454 def run_test_on_partition(self, test, mountpoint_func, **dargs): |
443 """ | 455 """ |
444 Executes a test fs-style (umount,mkfs,mount,test) | 456 Executes a test fs-style (umount,mkfs,mount,test) |
445 | 457 |
446 Here we unmarshal the args to set up tags before running the test. | 458 Here we unmarshal the args to set up tags before running the test. |
447 Tests are also run by first umounting, mkfsing and then mounting | 459 Tests are also run by first umounting, mkfsing and then mounting |
448 before executing the test. | 460 before executing the test. |
449 | 461 |
450 @param test: name of test to run | 462 @param test: name of test to run |
451 @param mountpoint_func: function to return mount point string | 463 @param mountpoint_func: function to return mount point string |
(...skipping 11 matching lines...) Expand all Loading... |
463 if suffix: | 475 if suffix: |
464 tag = '%s.%s' % (tag, suffix) | 476 tag = '%s.%s' % (tag, suffix) |
465 | 477 |
466 dargs['tag'] = test + '.' + tag | 478 dargs['tag'] = test + '.' + tag |
467 | 479 |
468 def _make_partition_and_run_test(test_tag, dir=None, **dargs): | 480 def _make_partition_and_run_test(test_tag, dir=None, **dargs): |
469 self.setup_before_test(mountpoint_func) | 481 self.setup_before_test(mountpoint_func) |
470 try: | 482 try: |
471 self.job.run_test(test, tag=test_tag, dir=mountpoint, **dargs) | 483 self.job.run_test(test, tag=test_tag, dir=mountpoint, **dargs) |
472 finally: | 484 finally: |
473 self.cleanup_after_test() | 485 self.unmount() |
| 486 self.fsck() |
| 487 |
474 | 488 |
475 mountpoint = mountpoint_func(self) | 489 mountpoint = mountpoint_func(self) |
476 | 490 |
477 # The tag is the tag for the group (get stripped off by run_group) | 491 # The tag is the tag for the group (get stripped off by run_group) |
478 # The test_tag is the tag for the test itself | 492 # The test_tag is the tag for the test itself |
479 self.job.run_group(_make_partition_and_run_test, | 493 self.job.run_group(_make_partition_and_run_test, |
480 test_tag=tag, dir=mountpoint, **dargs) | 494 test_tag=tag, dir=mountpoint, **dargs) |
481 | 495 |
482 | 496 |
483 def get_mountpoint(self, open_func=open, filename=None): | 497 def get_mountpoint(self, open_func=open, filename=None): |
484 """ | 498 """ |
485 Find the mount point of this partition object. | 499 Find the mount point of this partition object. |
486 | 500 |
487 @param open_func: the function to use for opening the file containing | 501 @param open_func: the function to use for opening the file containing |
488 the mounted partitions information | 502 the mounted partitions information |
489 @param filename: where to look for the mounted partitions information | 503 @param filename: where to look for the mounted partitions information |
490 (default None which means it will search /proc/mounts and/or | 504 (default None which means it will search /proc/mounts and/or |
491 /etc/mtab) | 505 /etc/mtab) |
492 | 506 |
493 @returns a string with the mount point of the partition or None if not | 507 @returns a string with the mount point of the partition or None if not |
494 mounted | 508 mounted |
495 """ | 509 """ |
496 if filename: | 510 if filename: |
497 for line in open_func(filename).readlines(): | 511 for line in open_func(filename).readlines(): |
498 parts = line.split() | 512 parts = line.split() |
499 if parts[0] == self.device: | 513 if parts[0] == self.device or parts[1] == self.mountpoint: |
500 return parts[1] # The mountpoint where it's mounted | 514 return parts[1] # The mountpoint where it's mounted |
501 return None | 515 return None |
502 | 516 |
503 # no specific file given, look in /proc/mounts | 517 # no specific file given, look in /proc/mounts |
504 res = self.get_mountpoint(open_func=open_func, filename='/proc/mounts') | 518 res = self.get_mountpoint(open_func=open_func, filename='/proc/mounts') |
505 if not res: | 519 if not res: |
506 # sometimes the root partition is reported as /dev/root in | 520 # sometimes the root partition is reported as /dev/root in |
507 # /proc/mounts in this case, try /etc/mtab | 521 # /proc/mounts in this case, try /etc/mtab |
508 res = self.get_mountpoint(open_func=open_func, filename='/etc/mtab') | 522 res = self.get_mountpoint(open_func=open_func, filename='/etc/mtab') |
509 | 523 |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 os.remove(self.img) | 991 os.remove(self.img) |
978 except: | 992 except: |
979 e_msg = 'Error removing image file %s' % self.img | 993 e_msg = 'Error removing image file %s' % self.img |
980 raise error.AutotestError(e_msg) | 994 raise error.AutotestError(e_msg) |
981 | 995 |
982 # import a site partition module to allow it to override functions | 996 # import a site partition module to allow it to override functions |
983 try: | 997 try: |
984 from autotest_lib.client.bin.site_partition import * | 998 from autotest_lib.client.bin.site_partition import * |
985 except ImportError: | 999 except ImportError: |
986 pass | 1000 pass |
OLD | NEW |