141 |
def __init__(self): |
def __init__(self): |
142 |
self.deviceArguments = {} |
self.deviceArguments = {} |
143 |
self.formattable = 0 |
self.formattable = 0 |
144 |
|
self.checkable = 0 |
145 |
self.checked = 0 |
self.checked = 0 |
146 |
self.name = "" |
self.name = "" |
147 |
self.linuxnativefs = 0 |
self.linuxnativefs = 0 |
271 |
if self.isFormattable(): |
if self.isFormattable(): |
272 |
raise RuntimeError, "formatDevice method not defined" |
raise RuntimeError, "formatDevice method not defined" |
273 |
|
|
274 |
|
def checkDevice(self, entry, progress, chroot='/'): |
275 |
|
if self.isCheckable(): |
276 |
|
raise RuntimeError, "checkDevice method not defined" |
277 |
|
|
278 |
def migrateFileSystem(self, device, message, chroot='/'): |
def migrateFileSystem(self, device, message, chroot='/'): |
279 |
if self.isMigratable(): |
if self.isMigratable(): |
280 |
raise RuntimeError, "migrateFileSystem method not defined" |
raise RuntimeError, "migrateFileSystem method not defined" |
285 |
def isFormattable(self): |
def isFormattable(self): |
286 |
return self.formattable |
return self.formattable |
287 |
|
|
288 |
|
def isCheckable(self): |
289 |
|
return self.checkable |
290 |
|
|
291 |
def isLinuxNativeFS(self): |
def isLinuxNativeFS(self): |
292 |
return self.linuxnativefs |
return self.linuxnativefs |
293 |
|
|
515 |
FileSystemType.__init__(self) |
FileSystemType.__init__(self) |
516 |
self.partedFileSystemType = None |
self.partedFileSystemType = None |
517 |
self.formattable = 1 |
self.formattable = 1 |
518 |
|
self.checkable = 1 |
519 |
self.checked = 1 |
self.checked = 1 |
520 |
self.linuxnativefs = 1 |
self.linuxnativefs = 1 |
521 |
self.maxSizeMB = 8 * 1024 * 1024 |
self.maxSizeMB = 8 * 1024 * 1024 |
545 |
entry.mountpoint) |
entry.mountpoint) |
546 |
if rc: |
if rc: |
547 |
raise SystemError |
raise SystemError |
548 |
|
|
549 |
|
def checkDevice(self, entry, progress, chroot='/'): |
550 |
|
devicePath = entry.device.setupDevice(chroot) |
551 |
|
args = [ "/usr/sbin/e2fsck", "-p", "-f", "-C0", devicePath] |
552 |
|
|
553 |
|
rc = fsckFilesystem(args, "/dev/tty5", |
554 |
|
progress, entry.mountpoint) |
555 |
|
if rc: |
556 |
|
raise SystemError |
557 |
|
|
558 |
# this is only for ext3 filesystems, but migration is a method |
# this is only for ext3 filesystems, but migration is a method |
559 |
# of the ext2 fstype, so it needs to be here. FIXME should be moved |
# of the ext2 fstype, so it needs to be here. FIXME should be moved |
1394 |
log("formatting %s as %s" %(entry.mountpoint, entry.fsystem.name)) |
log("formatting %s as %s" %(entry.mountpoint, entry.fsystem.name)) |
1395 |
entry.fsystem.formatDevice(entry, self.progressWindow, chroot) |
entry.fsystem.formatDevice(entry, self.progressWindow, chroot) |
1396 |
|
|
1397 |
|
def checkEntry(self, entry, chroot): |
1398 |
|
log("checking %s type %s" %(entry.mountpoint, entry.fsystem.name)) |
1399 |
|
entry.fsystem.checkDevice(entry, self.progressWindow, chroot) |
1400 |
|
|
1401 |
def badblocksEntry(self, entry, chroot): |
def badblocksEntry(self, entry, chroot): |
1402 |
entry.fsystem.badblocksDevice(entry, self.progressWindow, chroot) |
entry.fsystem.badblocksDevice(entry, self.progressWindow, chroot) |
1403 |
|
|
1507 |
def haveMigratedFilesystems(self): |
def haveMigratedFilesystems(self): |
1508 |
return self.migratedfs |
return self.migratedfs |
1509 |
|
|
1510 |
|
def checkFilesystems (self, chroot='/'): |
1511 |
|
for entry in self.entries: |
1512 |
|
if entry.fsystem.isCheckable(): |
1513 |
|
self.checkEntry(entry, chroot) |
1514 |
|
|
1515 |
def migrateFilesystems (self, chroot='/'): |
def migrateFilesystems (self, chroot='/'): |
1516 |
if self.migratedfs: |
if self.migratedfs: |
1517 |
return |
return |
1958 |
if self.spares > 0: |
if self.spares > 0: |
1959 |
args.append("--spare-devices=%s" %(self.spares,),) |
args.append("--spare-devices=%s" %(self.spares,),) |
1960 |
|
|
1961 |
if self.numDisks == 1: |
if self.numDisks == 1 and self.level == 1: |
1962 |
args.append("--raid-devices=2") |
args.append("--raid-devices=2") |
1963 |
else: |
else: |
1964 |
args.append("--raid-devices=%s" %(self.numDisks,),) |
args.append("--raid-devices=%s" %(self.numDisks,),) |
1965 |
|
|
1966 |
args.extend(map(devify, self.members)) |
args.extend(map(devify, self.members)) |
1967 |
|
|
1968 |
if self.numDisks == 1: |
if self.numDisks == 1 and self.level == 1: |
1969 |
args.append("missing") |
args.append("missing") |
1970 |
|
|
1971 |
log("going to run: %s" %(args,)) |
log("going to run: %s" %(args,)) |
2578 |
return 0 |
return 0 |
2579 |
|
|
2580 |
return 1 |
return 1 |
2581 |
|
|
2582 |
|
def fsckFilesystem(argList, messageFile, windowCreator, mntpoint): |
2583 |
|
if windowCreator: |
2584 |
|
w = windowCreator(_("Checking"), |
2585 |
|
_("Checking %s file system...") % (mntpoint,), 100) |
2586 |
|
else: |
2587 |
|
w = None |
2588 |
|
|
2589 |
|
fd = os.open(messageFile, os.O_RDWR | os.O_CREAT | os.O_APPEND) |
2590 |
|
p = os.pipe() |
2591 |
|
childpid = os.fork() |
2592 |
|
if not childpid: |
2593 |
|
os.close(p[0]) |
2594 |
|
os.dup2(p[1], 1) |
2595 |
|
os.dup2(fd, 2) |
2596 |
|
os.close(p[1]) |
2597 |
|
os.close(fd) |
2598 |
|
os.execv(argList[0], argList) |
2599 |
|
log("failed to exec %s", argList) |
2600 |
|
os._exit(1) |
2601 |
|
|
2602 |
|
os.close(p[1]) |
2603 |
|
|
2604 |
|
# ignoring SIGCHLD would be cleaner then ignoring EINTR, but |
2605 |
|
# we can't use signal() in this thread? |
2606 |
|
|
2607 |
|
s = 'a' |
2608 |
|
num = '' |
2609 |
|
sync = 0 |
2610 |
|
while s: |
2611 |
|
try: |
2612 |
|
s = os.read(p[0], 1) |
2613 |
|
os.write(fd, s) |
2614 |
|
|
2615 |
|
if s != ' ': |
2616 |
|
try: |
2617 |
|
num = num + s |
2618 |
|
except: |
2619 |
|
pass |
2620 |
|
else: |
2621 |
|
if num and num[:1] != '(' and num[-1] == '%': |
2622 |
|
try: |
2623 |
|
val = int(num[:string.find(num, ".")]) |
2624 |
|
except (IndexError, TypeError): |
2625 |
|
pass |
2626 |
|
else: |
2627 |
|
w and w.set(val) |
2628 |
|
num = '' |
2629 |
|
except OSError, args: |
2630 |
|
(errno, str) = args |
2631 |
|
if (errno != 4): |
2632 |
|
raise IOError, args |
2633 |
|
|
2634 |
|
try: |
2635 |
|
(pid, status) = os.waitpid(childpid, 0) |
2636 |
|
except OSError, (num, msg): |
2637 |
|
log("exception from waitpid while checking: %s %s" %(num, msg)) |
2638 |
|
status = None |
2639 |
|
os.close(fd) |
2640 |
|
|
2641 |
|
w and w.pop() |
2642 |
|
|
2643 |
|
# *shrug* no clue why this would happen, but hope that things are fine |
2644 |
|
if status is None: |
2645 |
|
return 0 |
2646 |
|
|
2647 |
|
if os.WIFEXITED(status) and ((os.WEXITSTATUS(status) == 0) or (os.WEXITSTATUS(status) == 1)): |
2648 |
|
return 0 |
2649 |
|
|
2650 |
|
return 1 |
2651 |
|
|
2652 |
if __name__ == "__main__": |
if __name__ == "__main__": |
2653 |
log.open("foo") |
log.open("foo") |