home *** CD-ROM | disk | FTP | other *** search
- /**
- * File:
- * OSRFsck.ycp
- *
- * Module:
- * YaST OS Repair. Automatic error detection & repair tool for Linux.
- *
- * Summary:
- * YaST OS Repair. Automatic error detection & repair tool for Linux.
- *
- * Author:
- * Johannes Buchhold <jbuch@suse.de>
- *
- * $Id: OSRFsck.ycp 31106 2006-05-23 08:01:21Z jsuchome $
- */
- {
- module "OSRFsck";
-
- import "FileSystems";
- import "FileUtils";
- import "Storage";
- import "Partitions";
- import "Mode";
- import "Popup";
- import "Stage";
-
- import "OSRExecute";
- import "OSRLogFile";
- import "OSRModuleLoading";
- import "OSRPopup";
- import "OSRCommon";
-
- textdomain "repair";
-
- /**
- * The last return value from a check_... call
- */
- integer last_check_return = 0;
-
- /**
- * Options for a repair call. Not Supported at the moment.
- */
- string fsck_options = "";
-
- /**
- * The not loaded filesystem an lvm/raid modules.
- */
- global list<string> not_installed_modules = [];
-
- /**
- * The loaded modules.
- */
- global list<string> fs_kernel_modules = [];
-
- /**
- * A list of all possible filesystem id's for fsck...
- */
- global list fsck_fsid = [];
-
- /**
- * A list of all possible types for a fsck ...
- */
- global list<symbol> fsck_type = [`sw_raid, `lvm, `logical, `primary];
-
- /**
- * The partition name witch is currently in work ( checked - repaired)
- */
- string check_partition = "";
-
- // prototypes of check/repair functions
- define boolean is_ext2fs();
- define boolean is_reiserfs();
- define boolean is_xfs();
- define boolean is_jfs();
- define boolean is_fat();
- define boolean is_ntfs();
-
- define boolean repair_ext2fs();
- define boolean repair_reiserfs();
- define boolean repair_xfs();
- define boolean repair_jfs();
-
- define boolean check_ext2fs();
- define boolean check_reiserfs();
- define boolean check_xfs();
- define boolean check_jfs();
-
- /**
- * The find/check/repair define for all supported filesystems.
- */
- map fsck_map = $[
- `ext2 : $[
- "find" : is_ext2fs,
- "repair" : repair_ext2fs,
- "check" : check_ext2fs
- ],
- `ext3 : $[
- "find" : is_ext2fs,
- "repair" : repair_ext2fs,
- "check" : check_ext2fs
- ],
- `reiser: $[
- "find" : is_reiserfs,
- "repair" : repair_reiserfs,
- "check" : check_reiserfs
- ],
- `xfs : $[
- "find" : is_xfs,
- "repair" : repair_xfs,
- "check" : check_xfs
- ],
- `jfs : $[
- "find" : is_jfs,
- "repair" : repair_jfs,
- "check" : check_jfs
- ],
- // "Do not touch non-linux partitions" (#25002)
- // -> no check/repair functions for other filesystems
- `fat16 : $[
- "find" : is_fat
- ],
- `fat32 : $[
- "find" : is_fat
- ],
- `ntfs : $[
- "find" : is_ntfs
- ]
- ];
-
-
- string file_name = "";
-
- global define void Reset()``{
- file_name = "";
- last_check_return = 0;
- fsck_options = "";
- not_installed_modules = [];
- fs_kernel_modules = [];
- check_partition = "";
- }
-
- /**
- * Constructor.
- * Fill the list fsck_fsid with the date from module Partition.
- */
- global define void OSRFsck()``{
-
- fsck_fsid = union (Partitions::fsid_wintypes, Partitions::fsid_dostypes );
- fsck_fsid = union (fsck_fsid, Partitions::fsid_ntfstypes );
- fsck_fsid = union (fsck_fsid,
- [ Partitions::fsid_native, Partitions::fsid_lvm, Partitions::fsid_raid ]);
- }
-
-
- /**
- * Load all needed fileystem and lvm/raid modules.
- */
- global define boolean LoadAllFsModules()``{
-
- if( Mode::test () ) return true;
-
- not_installed_modules = [];
- fs_kernel_modules = [];
-
- list all_supportet_fs = maplist (symbol fs, map details,
- (map<symbol,map<any,any> >)FileSystems::GetAllFileSystems(false, false ), ``(fs) );
-
- foreach (symbol fs, (list<symbol>) all_supportet_fs , ``{
- fs_kernel_modules = (list<string>) union (
- fs_kernel_modules, FileSystems::GetNeededModules (fs));
- });
- fs_kernel_modules = (list<string>) union (
- fs_kernel_modules , [ "xor", "raid0", "raid1", "raid5"]);
-
- // iterate all listed kernel modules
- foreach(string fs_module, fs_kernel_modules, ``{
- if (! OSRModuleLoading::Load( fs_module, "","","",false, true))
- not_installed_modules = add (not_installed_modules, fs_module);
- });
-
- return size( not_installed_modules ) == 0;
- }
-
-
-
-
- /**
- * Return a list witch contains all partitions names that can be
- * used for a fsck.
- */
- global define list<map> PossiblePartitions()``{
-
- list<map> partitions = [];
-
- foreach(string dev, map target, Storage::GetTargetMap(), {
- foreach(map p, target["partitions"]:[], {
-
- if (p["delete"]:false == false &&
- (contains (fsck_fsid, p["fsid"]:0) || p["fstype"]:"" == "LV") &&
- contains (fsck_type, p["type"]:`unknown))
- {
- partitions = add(partitions, p );
- }
- });
- });
-
- y2milestone("all partitions %1", partitions);
- return partitions;
- }
-
-
- define boolean is_unknown()``{
- y2warning ("unkonwn file system");
- return false;
- }
-
- /**
- * Checks if the specified check_partition is of filesystem-type ext2fs.
- * @return boolean True if the check_partition is ext2fs.
- */
- define boolean is_ext2fs() ``{
-
- boolean isext2fs = OSRExecute::Command (
- .local.bash, "/sbin/dumpe2fs -h " + check_partition);
-
- if (isext2fs )
- y2milestone("partition %1 is ext2fs", check_partition);
- else
- y2milestone("partition %1 is NOT ext2fs", check_partition);
-
- return isext2fs;
- };
-
- /**
- * Checks if the specified partition is of filesystem-type reiserfs.
- * @return boolean True if the partition is reiserfs.
- */
- define boolean is_reiserfs() ``{
-
- boolean isreiserfs = OSRExecute::Command (
- .local.bash, "/sbin/debugreiserfs " + check_partition);
-
- if ( isreiserfs )
- {
- y2milestone("partition %1 is reiserfs", check_partition);
- }
- else
- {
- y2milestone("partition %1 is NOT reiserfs", check_partition);
- }
- return isreiserfs;
- };
-
-
- /**
- * Checks if the specified partition is of filesystem-type xfs.
- * @return boolean True if the partition is xfs.
- */
- define boolean is_xfs()``{
-
- boolean isxfs = OSRExecute::CommandOutput (
- .local.bash, "/usr/sbin/xfs_admin -l -u " + check_partition);
- // failed
- //xfs_admin: unexpected XFS SB magic number 0xdd0a05a6
- //bad sb magic # 0xdd0a05a6 in AG 0
- //failed to read label in AG 0
- //bad sb magic # 0xdd0a05a6 in AG 0
- //failed to read UUID from AG 0
-
- // success
- //label = ""
- //uuid = ad743076-12b8-452b-86c0-2e62918479ae
- if (issubstring (OSRExecute::stdout, "label") &&
- issubstring (OSRExecute::stdout, "uuid" ))
- {
- y2milestone("partition %1 is xfs", check_partition);
- isxfs = true;
- }
- else
- {
- y2milestone("partition %1 is NOT xfs", check_partition);
- isxfs = false;
- }
- return isxfs;
- };
-
- /**
- * Checks if the specified partition is of filesystem-type jfs.
- * @return boolean True if the partition is jfs.
- */
- define boolean is_jfs()``{
-
- if (!FileUtils::Exists ("/sbin/jfs_logdump"))
- {
- y2milestone ("/sbin/jfs_logdump not available, exiting check...");
- return false;
- }
-
- string command = sformat ("if /usr/bin/test -f %1; then /bin/rm %1; fi",
- OSRLogFile::GetTmpDir() +"/jfslog.dmp" );
-
- // delete the old progress_file, if it exists
- if (WFM::Execute(.local.bash, command) != 0)
- {
- y2error("The file %1 could not be deleted.",
- OSRLogFile::GetTmpDir() +"/jfslog.dmp" );
- }
-
- command = sformat("cd %1; /sbin/jfs_logdump %2",
- OSRLogFile::GetTmpDir(), check_partition );
- boolean isjfs = OSRExecute::CommandOutput (.local.bash, command );
-
- // check_jfs is 0 !! -> read jfslog.dmp
- string jfslog = (string) WFM::Read (.local.string,
- OSRLogFile::GetTmpDir()+"/jfslog.dmp" );
-
- y2milestone("jfslog.dmp %1", jfslog);
-
- if (jfslog == nil || issubstring( jfslog, "?????????????????" ))
- {
- isjfs = false;
- }
- return isjfs;
- };
-
-
- /**
- * Checks if the specified partition is of filesystem-type fat/vfat.
- * @return boolean True if the partition is fat/vfat.
- */
- define boolean is_fat()``{
-
- string command = sformat("/bin/guessfstype %1", check_partition );
- boolean isfat = OSRExecute::CommandOutput (.local.bash, command );
-
- if ( issubstring( OSRExecute::stdout, "fat" ))
- {
- isfat = true;
- }
- else
- {
- isfat = false;
- }
- return isfat;
- };
-
- /**
- * Checks if the specified partition is of filesystem-type ntfs
- * @return boolean True if the partition is ntfs
- */
- define boolean is_ntfs() ``{
-
- string command = sformat("/bin/guessfstype %1", check_partition );
- boolean isntfs = false;
- OSRExecute::CommandOutput (.local.bash, command );
-
- if (issubstring (OSRExecute::stdout, "ntfs" ))
- isntfs = true;
- return isntfs;
- };
-
- /**
- * Checks the specified partition for consistency with "/sbin/e2fsck".
- * @return boolean
- * The exit code returned by e2fsck is the sum of the following conditions:
- * 0 - No errors,
- * 1 - File system errors corrected,
- * 2 - File system errors corrected, system should be rebooted if file system was mounted,
- * 4 - File system errors left uncorrected,
- * 8 - Operational error,
- * 16 - Usage or syntax error,
- * 128 - Shared library error.
- */
- define boolean check_ext2fs() ``{
-
- string command = sformat("/sbin/fsck.ext2 -n -f %1", check_partition );
- boolean checkext2fs = OSRExecute::Command (.local.bash,command);
- last_check_return = OSRExecute::result;
-
- if (checkext2fs)
- {
- y2milestone("partition %1 is o.k., /sbin/e2fsck reports no errors",
- check_partition);
- }
- else
- {
- y2error("/sbin/e2fsck reports an error: %1, command line: %2",
- checkext2fs, command);
- }
- return checkext2fs;
- };
-
- /**
- * Checks the specified partition for consistency with "/sbin/reiserfsck".
- */
- define boolean check_reiserfs() ``{
-
- string command = sformat("/bin/echo Yes | /sbin/reiserfsck --check %1",
- check_partition);
-
- // don't use OSRExecute .. because OSRExecute use .target.bash_output and
- // this break the whole Yast2 -> output is to much !! e.g. 14 MB
- last_check_return = (integer) WFM::Execute(.local.bash, command);
- boolean checkreiserfs = last_check_return == 0 ;
-
- if (checkreiserfs )
- {
- y2milestone("partition %1 is o.k., /sbin/reiserfsck reports no errors",
- check_partition);
- }
- else
- {
- y2error("/sbin/reiserfsck reports an error: %1, command line: %2",
- checkreiserfs, command);
- }
- return checkreiserfs;
- };
-
- /**
- * Checks the specified partition for consistency with "/sbin/xfs_db -c check".
- */
- define boolean check_xfs()``{
-
- string command = sformat("/usr/sbin/xfs_db -c check %1", check_partition);
- boolean checkxfs = OSRExecute::Command(.local.bash, command);
- last_check_return = OSRExecute::result;
-
- if (checkxfs)
- {
- y2milestone("partition %1 is o.k., xfs_check reports no errors",
- check_partition);
- }
- else
- {
- y2milestone("xfs_check reports an error for partition %1",
- check_partition );
- }
- return checkxfs;
- };
-
- /**
- * Checks the specified partition for consistency with "/sbin/fsck.jfs -n ".
- */
- define boolean check_jfs()``{
-
- if (!FileUtils::Exists ("/sbin/fsck.jfs"))
- {
- y2milestone ("/sbin/fsck.jfs not available, exiting check...");
- return false;
- }
-
- string command = sformat("/sbin/fsck.jfs -n %1", check_partition);
- boolean checkjfs = OSRExecute::Command(.local.bash, command);
- last_check_return = OSRExecute::result;
-
- if (checkjfs)
- {
- y2milestone ("partition %1 is o.k., jfs_check reports no errors",
- check_partition);
- }
- else
- {
- y2milestone("jfs_check reports an error for partition %1",
- check_partition );
- }
- return checkjfs;
- };
-
- /**
- * checks for filesystem type
- * (Repair module should not touch non-linux partitions - bug #25002)
- */
- global define boolean IsNonLinuxFileSystem (symbol fs) ``{
-
- return contains ([`ntfs, `fat16, `fat32], fs);
-
- }
-
- /**
- * Test the filesystem of one partition.
- * @param the partition map
- */
- global define boolean Check(map part ) ``{
- if(Mode::test () ) return true;
-
- symbol used_fs = part["detected_fs"]:`unknown;
- check_partition = part["device"]:"";
-
- y2milestone("Check the file system of the partition %1", check_partition );
- // find fs
-
- boolean () find_fs = fsck_map [used_fs, "find"]:is_unknown;
- if (!find_fs ())
- {
- // ignore LVM partitions
- if (part["fsid"]:0 == Partitions::fsid_lvm)
- {
- y2milestone("LVM group: no checks");
- return true;
- }
-
- y2error("used_fs is not ok or unknown. Searching for new filesystem");
-
- used_fs = `unknown;
- symbol new_used_fs = `unknown;
-
- foreach (symbol fs, map fs_map, (map<symbol,map<string,any> >)fsck_map, ``{
- if ( fs != used_fs ) {
- find_fs = fs_map["find"]:OSRCommon::False;
- if (find_fs ())
- {
- new_used_fs = fs;
- }
- }
- });
- if ( new_used_fs != `unknown )
- used_fs = new_used_fs;
- else
- {
- y2error("no file systen found for %1", check_partition );
- }
- }
- else
- {
- y2milestone("used_fs is ok. Executing file system check !!");
- }
- if ( used_fs != `unknown && used_fs != nil )
- {
- // ----------- start check now
- if (IsNonLinuxFileSystem (used_fs))
- {
- y2milestone("non-linux filesystem: no checks");
- return true;
- }
- boolean () f_check = fsck_map[used_fs, "check"]:OSRCommon::False;
- if (f_check ())
- {
- y2milestone("file system check successful executed");
- return true;
- }
- }
- else
- {
- y2milestone("no file system found");
- return nil;
- }
- y2error("file system check was not successful");
- return false;
- }
-
-
-
- /**
- * The main repair dialog.
- * @param t_check_partition the partition e.g.: /dev/hda1
- * @param used_fs the filesystem symbol
- * @return `ok,`error,`cancel
- */
- global define symbol Repair(string t_check_partition, symbol used_fs ) ``{
-
- // not used at the moment.
- fsck_options = "";
-
- file_name = OSRLogFile::GetTmpDir()+ "/" + "fsck_repair";
-
- // makes global use possible ( from another define as Check);
- check_partition = t_check_partition;
-
- // error message, %1 is filesystem type, %2 partition
- string error_message = sformat(_("
- The %1 file system of the partition %2 is corrupted.
- To repair the file system, press Repair.
-
- Press Skip if you do not want this repair.
- "), FileSystems::GetName( used_fs, "unkonwn"), check_partition );
-
- // error message
- string help_text = _("
- <p>An inconsistent file system occurs when
- a partition is not correctly unmounted.
- This could happen during a system crash.</p>
- ") +
-
- // error message
- _("<p>There is a repair method for each file
- system. For example, if the file system
- of the damaged partition is ext2 or
- ext3, use fsck.ext2 (e2fsck) with the
- corresponding options to repair the
- file system. The following lines list
- the repair tools of the different Linux
- file systems.</p>
- ") +
-
- _("<p><pre>
- ext2 and ext2: fsck.ext2 or e2fsck
- reiserfs: reiserfsck
- jfs: fsck.jfs
- xfs: xfs_repair
- msdos (fat): fsck.msdos</pre></p>");
-
- // do not write about "closing YaST" when Mode::init?
- if (!Stage::initial ())
- help_text = help_text +
- _("<p>If you know what kind of file system
- you have and how to use the corresponding
- tool, close this program and repair the
- damaged file system on your own. Otherwise,
- close this help dialog and press
- Repair for automatic repair.</p>
- ");
-
- while( true )
- {
- if (! OSRPopup::Repair(_("Error Detected"), error_message, help_text) ) return `cancel;
-
- UI::OpenDialog(`VBox(`VSpacing(1),
- `Label(_("Repairing file system...")),
- `VSpacing(1)));
-
- // if file exist
- if( WFM::Execute(.local.bash, "/usr/bin/test -f " + file_name ) == 0 )
- {
- WFM::Execute(.local.bash, sformat ("/bin/rm %1", file_name) );
- }
-
- boolean ret = true;
- if( !Mode::test () )
- {
- boolean () f_rep = fsck_map [used_fs, "repair"]:OSRCommon::False;
- ret = f_rep ();
- }
- UI::CloseDialog();
-
- string headline = "";
-
- if ( ret )
- {
- //%1 is file system, %2 is partition
- headline = sformat(_("
- Successfully Repaired %1 on %2"),
- FileSystems::GetName(used_fs, "unkonwn"), check_partition );
- }
- else
- {
- //%1 is file system, %2 is partition
- headline = sformat(_("
- Failed Repair of %1 on %2"),
- FileSystems::GetName(used_fs, "unkonwn"), check_partition );
- }
-
- // if file exist
- if( WFM::Execute(.local.bash, "/usr/bin/test -f " + file_name ) == 0 )
- {
- Popup::ShowFile( headline, file_name);
- }
-
- if ( ret ) return `ok;
- }
- }
-
- /**
- * Repair ext2/ext3 filesystem.
- * The exit code returned by e2fsck is the sum of the following conditions:
- * 0 - No errors,
- * 1 - File system errors corrected,
- * 2 - File system errors corrected, system should be rebooted if file system was mounted,
- * 4 - File system errors left uncorrected,
- * 8 - Operational error,
- * 16 - Usage or syntax error,
- * 128 - Shared library error.
- */
- define boolean repair_ext2fs()``{
-
- if (last_check_return == 4 )
- {
- y2milestone("repair ext2/ext3 filesystem on partition %1",
- check_partition);
-
- string command = sformat("/sbin/fsck.ext2 -p -f %1 %2",
- fsck_options, check_partition );
- boolean repairext2fs = OSRExecute::CommandProgress (
- .local.bash,command ,file_name);
-
- // TODO what is if fsck.ext2 requires y y y y for del indo XX ...
- if (OSRExecute::result == 0 ||
- OSRExecute::result == 1 ||
- OSRExecute::result == 2 )
- {
- return true;
- }
- }
- y2milestone("ext2 filesystem not successful repaired.");
- return false;
- }
-
- /**
- * Repair reiserfs filesystem.
- */
- define boolean repair_reiserfs()``{
-
- string command = "";
- integer repairreiserfs = 0;
-
- if ( last_check_return == 1 )
- {
- command = sformat("/bin/echo Yes | /sbin/reiserfsck --fix-fixable %1",
- check_partition);
- repairreiserfs = (integer) WFM::Execute (.local.bash, command);
- }
- else if ( last_check_return == 2 )
- {
- // popup headline, reiserfs is file system
- if (Popup::AnyQuestion (_("Fatal Corruptions on reiserfs"),
- // popup text (yes/no)
- _("
- Checking the file system (reiserfs) reports
- fatal corruptions. Only a rebuild of the reiserfs
- file system tree (reiserfsck --rebuild-tree)
- could solve the problem.
-
- To rebuild your reiserfs tree,
- press Repair. Otherwise press
- Skip and repair the file system manually.
- "),
- OSRPopup::repair_label, OSRPopup::skip_label,`focus_yes))
- {
- command =
- sformat("/bin/echo Yes | /sbin/reiserfsck --rebuild-tree %1",
- check_partition);
- repairreiserfs = (integer) WFM::Execute (.local.bash,command);
- }
- else
- {
- return false;
- }
- }
- if (repairreiserfs == 0 ||
- repairreiserfs == 1 ||
- repairreiserfs == 2 )
- {
- return true;
- }
- return false;
- }
-
- /**
- * Repair xfs filesystem.
- */
- define boolean repair_xfs()``{
-
- string command = sformat("/sbin/xfs_repair %1", check_partition);
- return OSRExecute::CommandProgress (.local.bash,command, file_name);
- }
-
- /**
- * Repair jfs filesystem.
- */
- define boolean repair_jfs()``{
-
- if (!FileUtils::Exists ("/sbin/fsck.jfs"))
- {
- y2milestone ("/sbin/fsck.jfs not available, exiting repair...");
- return false;
- }
- string command = sformat("/sbin/fsck.jfs -p %1", check_partition);
- boolean repairjfs = OSRExecute::CommandProgress (
- .local.bash, command, file_name);
-
- if (OSRExecute::result == 0 ||
- OSRExecute::result == 1 ||
- OSRExecute::result == 2 )
- {
- return true;
- }
- y2milestone("jfs filesystem repair was not successful");
- return false;
- }
-
- }//EOF
-