home *** CD-ROM | disk | FTP | other *** search
Text File | 2006-11-29 | 58.9 KB | 2,291 lines |
- /**
- * File:
- * OSRFstab.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>
- *
- * Use:
- * OSRFstab::LinuxPartitions ("/dev/hda1", "/dev/hda2", .. ]);
- * OSRFstab::MountablePartitions( ..);
- * OSRFstab::ValidRootPartitions( ..);
- *
- * OSRFstab::ReadFstab("/");
- * OSRFstab::CheckRootEntry ("/dev/hda1",
- * ["/dev/hda2"], ["/dev/hda3", "/dev/hda4" ]);
- * OSRFstab::Repair();
- *
- * OSRFstab::Check(["/dev/hda2"], ["/dev/hda3", "/dev/hda4" ]);
- * OSRFstab::Repair();
- *
- *
- * $Id: OSRFstab.ycp 32906 2006-09-15 09:57:06Z jsuchome $
- */
- {
- module "OSRFstab";
-
- import "FileSystems";
- import "Storage";
- import "StorageDevices";
- import "Hotplug";
- import "Partitions";
- import "Mode";
- import "Installation";
- import "AsciiFile";
- import "Initrd";
- import "Report";
-
- import "OSRFsck";
- import "OSRLogFile";
- import "OSRSystem";
- import "OSRExecute";
- import "OSRPopup";
-
- import "Label";
- import "Popup";
- import "SuSERelease";
-
-
- textdomain "repair";
-
- string remove_label = _("Remove");
- string ignore_label = _("Ignore");
- string replace_label = _("Replace");
- string create_label = _("Create");
-
- string device_label = _("Device");
- string mount_label = _("Mount Point");
- string create_mp_label = _("Create Mount Point");
- string state_label = _("State");
- // fstab is file name
- string fstab_line_label = _("fstab Line");
-
- // button label
- string b_ignore_label = _("&Ignore");
- // button label
- string b_create_label = _("&Create");
- // button label
- string b_remove_label = _("&Remove");
- // button label
- string b_change_mp_label = _("Change &Mount Point");
- // button label
- string b_replace_label = _("R&eplace");
-
- global list<string> system_mount_points =
- [ "/dev", "/lib", "/bin", "/etc", "/sbin" ];
-
- /**
- * The path
- */
- global string fstabpath = "/etc/fstab";
-
- /**
- * The default fstab entries (as maps) -> set in constructor
- */
- map <string,map> fstab_defaults = $[];
-
- /**
- * All digits
- */
- string digits = "0123456789";
-
- /**
- * Line position to sense
- */
- map pos2field = $[ 0: "spec",
- 1: "mount",
- 2: "vfstype",
- 3: "mntops",
- 4: "freq",
- 5: "passno" ];
-
-
- /**
- * Partitions which are swapable
- */
- list<string> swapable_partition_list = [];
-
- /**
- * All checked partitions (OSRFsck)
- */
- list<string> checked_partitions = [];
-
- /**
- @example of map describing /etc/fstab:
-
- $[
- "comment" : "^[ \t]*#.*",
- "delim" : " \t",
- "l" : $[
- 1 : $[
- "fields" : ["/dev/hda2", "/", "reiserfs", "defaults", "1", "1"],
- "line" :"/dev/hda2\t/\treiserfs\tdefaults 1 1"
- ],
- 2 : $[
- "fields" : [
- "/dev/hda3", "/local", "reiserfs", "defaults", "1", "2"],
- "line" : "/dev/hda3\t/local\treiserfs\tdefaults 1 2"
- ],
- 3 : $[
- "fields" : [ "/dev/hda1", "swap", "swap", "pri=42", "0", "0"],
- "line" : "/dev/hda1\tswap\tswap\tpri=42 0 0"
- ],
- 4 : $[
- "fields" : [
- "devpts", "/dev/pts", "devpts", "mode=0620,gid=5","0", "0"],
- "line" : "devpts\t/dev/pts\tdevpts\tmode=0620,gid=5 0 0"
- ],
- ...
- 14 : $[
- "fields" : [
- "nfs.suse.cz:/home", "/home", "nfs", "defaults", "0", "0"],
- "line" : "nfs.suse.cz:/home\t/home\tnfs\tdefaults 0 0"
- ],
- 15 : $[
- "comment":true,
- "line":"#blah"
- ]
- ],
- "widths" : [20, 20, 10, 21, 1, 1]
- ]
- */
- map fstab = $[];
-
- /**
- * The root mount points e.g.: "/", "/mnt"
- */
- string root_mountpoint = "";
-
- /**
- * All checked valid lines
- * e.g.: [1,2,3];
- */
- list<integer> valid_lines = [];
-
- /**
- * Not valid lines, e.g.:
- * $[4: ["dev", false, true, true ,true ,true ,true ]],//spec error in line 4
- */
- map not_valid_lines = $[];
-
- /**
- * Devices without fstab entry
- * e.g.: ["/dev/hdb7"]
- */
- list<string> missing_devs = [];
-
- /**
- * Constructor: initialize data structures with default values
- */
- global define void OSRFstab () {
-
- foreach (string type, [
- "pts", "proc", "usb", "swap", "cdrom", "floppy",
- "root", "zip", "dev", "nfs", "sys" ],
- {
- fstab_defaults [type] = FileSystems::GetFstabDefaultMap (type);
- });
- }
-
- define void ResetSettings() {
- missing_devs = [];
- valid_lines = [];
- not_valid_lines = $[];
- }
-
- global define void Reset() {
- ResetSettings();
- root_mountpoint = "";
- fstab = $[];
- swapable_partition_list = [];
- checked_partitions = [];
- }
-
- /**
- * @param key values of which key should be returned
- * @param exists restrict the returned set only to the types with
- * nonempty values of key 'exists'
- */
- define list<string> fstab_default_exist (string exists, string key)
- {
- map <string,map> existing = filter (
- string type, map desc, fstab_defaults, ``(desc[exists]:"" != ""));
- return (list<string>) maplist (string type, map d, existing, ``(d[key]:""));
- }
-
-
- /**
- * e.g.: transform a fstab list to a fstab map.
- * list: ["/dev/hda6", "/", "reiserfs", "defaults", "1", "1"]
- * map : $[ "spec":"/dev/hda6", "file":"/" ... ]
- */
- define map fstabline2map (list<string> line)``{
-
- map ret = $[];
- integer pos = 0;
- foreach (string e, line, ``{
- ret [pos2field[pos]:""] = e;
- pos = pos +1;
- });
- return ret;
- }
-
- /**
- * Find the list of all valid linux-partitions in the target-map.
- * @return list The list of names of valid linux-partitions.
- */
- global define list<string> LinuxPartitions(list checked_partitions) ``{
-
- if (Mode::test ()) return ["/dev/hda1", "/dev/hda2"];
-
- if (size (checked_partitions) == 0) return [];
- y2warning ("checked_partitions: %1", checked_partitions);
-
- // e.g.: ["/dev/hda1", "/dev/hdb2"]
- list<string> linux_partition_list = [];
-
- foreach (string device , map description, Storage::GetTargetMap(), {
-
- foreach (map partition, description["partitions"]:[], ``{
-
- y2internal ("partition: %1", partition);
- if ((partition["fsid"]:0 == Partitions::fsid_native ||
- partition["type"]:`primary == `lvm ||
- partition["type"]:`primary == `sw_raid))
- {
- // if the fsck functions have been executed
- if (size (checked_partitions) != 0)
- {
- if (contains (checked_partitions,partition["device"]:""))
- {
- linux_partition_list = add (linux_partition_list,
- partition["device"]:"");
- }
- }
- else
- {
- linux_partition_list = add (linux_partition_list,
- partition["device"]:"");
- }
- }
- });
- });
- if (size ( linux_partition_list) == 0)
- y2error("no linux partition found");
- return linux_partition_list;
- };
-
-
- /**
- * Returns a list of names of all mountable partitions out of
- * the specified list.
- * @param list linux_partition_list A list of valid linux-partitions out of
- * which the mountable partitions are to be returned.
- * @param m_point the test mountpoint
- * @return list List of partition names successfully mounted to m_point.
- */
- global define list<string> MountablePartitions(
- list<string> linux_partition_list, string m_point) ``{
-
- if (Mode::test () || size (linux_partition_list) == 0)
- return linux_partition_list;
-
- // e.g.: ["/dev/hda1"]
- list<string> mount_possible_list = [];
-
- integer i = 0;
- foreach (string partition_item, linux_partition_list, ``{
-
- if ((boolean) WFM::Execute (.local.mount,
- [ partition_item, m_point, OSRExecute::OutputFile() ]))
- {
- mount_possible_list = add (mount_possible_list, partition_item);
- if (!(boolean) WFM::Execute(.local.umount, m_point))
- {
- y2error("umounting partition %1 not possible",partition_item);
- }
- }
- else
- {
- y2error("mounting partition %1 is not possible", partition_item);
- }
- i = i + 1;
- });
- return mount_possible_list;
- };
-
-
- /**
- * Returns a list of names of all mountable partitions that contain
- * a file /etc/fstab out of the specified list.
- * @param list linux_partition_list A list of valid linux-partitions
- * out of which the mountable partitions are to be returned.
- * @return list The list of partition-names that were successfully mounted
- * to /mnt and contain a filesystem table.
- */
- global define list<map> ValidRootPartitions (
- list<string> mount_possible_list, string mount_p)
- {
-
- if (Mode::test ())
- return maplist (string p, mount_possible_list, ``($["device": p]));
-
- if (size (mount_possible_list) == 0) return [];
-
- // e.g.: [ "device" : "/dev/hda1", "label" : "SUSE Linux"]
- list<map> valid_root_partitions = [];
- list<string> fstab_found_partitions = [];
- list<string> smpoints_found_partitions = [];
-
- // mapping of device to the product label ($[ "/dev/hda1" : "SUSE Linux"])
- map device2label = $[];
-
- foreach (string partition_item, mount_possible_list, ``{
-
- if (! (boolean) WFM::Execute(.local.mount,
- [ partition_item, mount_p , OSRExecute::OutputFile() ]))
- {
- y2error("Partition: %1; not possible to mount to /mnt",
- partition_item);
- }
- else
- {
- device2label[partition_item] =
- SuSERelease::ReleaseInformation (mount_p);
- // Check fstab exist
- // use the .local.size agent instead of the .etc.fstab agent
- // because it finds the fstab of currently mounted root partition
- if (WFM::Read (.local.size, mount_p + fstabpath) > 0)
- {
- y2milestone("Partition %1: fstab found", partition_item);
- fstab_found_partitions = add (fstab_found_partitions,
- partition_item);
- }
- else
- {
- y2milestone("Partition: %1; no fstab found", partition_item);
- }
- // Check system mount points
- boolean not_fount = false;
- foreach (string mp, system_mount_points, ``{
- if (mp != "/")
- {
- string cmd = sformat ("/usr/bin/test -d %1%2", mount_p,mp);
- y2debug ("command: %1", cmd);
- if (!OSRExecute::Command (.local.bash, cmd))
- {
- not_fount = true;
- }
- }
- });
- if (! not_fount)
- {
- y2milestone("system mount points found");
- smpoints_found_partitions = add (smpoints_found_partitions,
- partition_item);
- }
- else
- y2warning("system mount points not found. Partition %1 could not be a root partition", partition_item);
- }
- // umount the partition
- WFM::Execute(.local.umount, mount_p);
- });
-
- valid_root_partitions = maplist (string part, smpoints_found_partitions, {
- return $[ "device" : part, "label" : device2label[part]:"?" ];
- });
-
- y2milestone("ValidRootPartitions return %1", valid_root_partitions);
- return valid_root_partitions;
- };
-
- /**
- * Read the fstab file.
- */
- global define boolean ReadFstab(string mount_p , boolean strict)``{
-
- root_mountpoint = mount_p;
- fstab = Partitions::GetFstab( mount_p + fstabpath);
-
- if (fstab == nil || size (fstab) == 0 || fstab["l"]:$[] == $[])
- {
- y2error("No fstab found !!");
- if (strict) return false;
-
- // yes/no popup headline, fstab is file name
- if (Popup::YesNoHeadline(_("Cannot Read fstab"),
- // yes/no popup text
- _("
- No existing fstab file found.
- Create a new one?
- ")))
- {
- OSRExecute::Command (.local.bash,
- sformat ("/bin/mv %1%2 %1%2.YaSTsave",root_mountpoint,fstabpath));
- OSRExecute::Command (.local.bash,
- sformat ("/bin/touch %1%2", root_mountpoint, fstabpath));
- fstab = Partitions::GetFstab (mount_p + fstabpath);
- return true;
- }
- return false;
- }
- else
- {
- y2milestone ("fstab :%1 ", fstab);
- return true;
- }
- }
-
- /**
- * Removes blanks from a string.
- */
- define string remove_blanks (string c) ``{
- return ( mergestring (splitstring (c ," "), ""));
- }
-
- /**
- * Cat the uuid from a string.
- */
- define string uuid_string(list<string> line) ``{
-
- if (substring (line[0]:"", 0, 4) == "UUID") {
- return substring (line[0]:"", 5);
- }
- return "";
- }
-
- /**
- * Cat the label from a string.
- */
- define string label_string(list<string> line)``{
-
- if (substring (line[0]:"", 0,5) =="LABEL") {
- return substring (line[0]:"",6);
- }
- return "";
- }
-
- /**
- * Check the spec (first) entry in a fstab line.
- */
- define boolean check_fs_spec( list<string> line, map part)``{
-
- string uuidstring = uuid_string (line);
- string labelstring = label_string (line);
-
- return (contains (checked_partitions, line[0]:"") ||
- uuidstring == part["uuid"]:"!" ||
- labelstring == part["label"]:"!"
- );
- }
-
- /**
- * Check the file (second) entry in a fstab line.
- */
- define boolean check_fs_file(list<string> line)``{
-
- if (line[1]:"" == nil || line[1]:"" == "")
- return false;
-
- string dir = line[1]:"";
- if (dir == "" || dir == nil)
- return false;
-
- return (OSRExecute::Command (.local.bash,
- sformat ("/usr/bin/test -d %1%2", root_mountpoint, dir)));
- }
-
- /**
- * Check the filesystem type (third) entry in a fstab line.
- */
- define boolean check_fs_vfstype(list<string> line, map part) ``{
-
- if (line[2]:"" == nil || line[2]:"" == "") return false;
-
- line[2] = remove_blanks (line[2]:"");
-
- if (!(FileSystems::GetMountString (part["detected_fs"]:`unknown, "!")
- == line[2]:""
- || line[2]:"" == "auto" || line[2]:"" == "subfs"))
- {
- return false;
- }
- return true;
- }
-
- /**
- * Check the mount options (fourth) entry in a fstab line.
- */
- define boolean check_fs_mntops(list<string> line) {
-
- if (line[3]:"" == nil || line[3]:"" == "") return false;
-
- map checked = FileSystems::CheckFstabOptions (remove_blanks(line[3]:""));
- if (!checked["all_known"]:true)
- {
- y2error ("unknown mount options: %1",checked["unknown_options"]:"");
- }
- return checked["all_known"]:true;
- }
-
- /**
- * Check the freq (fifth) entry in a fstab line.
- */
- define boolean check_fs_freq(list<string> line, list<string> defaults)``{
- if (line[4]:"" == nil || line[4]:"" == "") return false;
-
- return (( size (filterchars (remove_blanks (line[4]:"0"), digits)) > 0) &&
- ( contains (defaults, remove_blanks (line[4]:"0"))));
- }
-
- /**
- * Check the passno (sixth) entry in a fstab line.
- */
- define boolean check_fs_passno(list<string> line, list<string> defaults)``{
-
- if (line[5]:"" == nil || line[5]:"" == "")
- return false;
-
- if (size (filterchars (remove_blanks (line[5]:"0"), digits))
- == size (remove_blanks (line[5]:"0")))
- {
- if (size (defaults) != 0)
- {
- return contains (defaults, remove_blanks (line[5]:"!"));
- }
- else
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the partition map for a device.
- * cdrom, floppy and zip devices are support too.
- */
- define map devname2part(string dev_name)``{
-
- if (substring (dev_name, 0,1) != "/") return $[];
-
- map ret = StorageDevices::GetCdromEntry( dev_name);
- if (ret == $[] || ret == nil) {
-
- ret = find(map e, StorageDevices::cddrives, ``(e["linkname"]:"" == dev_name));
-
- // check link
- if (ret == nil) {
- OSRExecute::CommandOutput(.local.bash, sformat ("/bin/ls -l %1", dev_name));
- list<string> std_dev_list = filter (string s, splitstring (OSRExecute::stdout, " "), ``( s != " "));
- string link = std_dev_list[size (std_dev_list)-1]:"";
- list linkl = splitstring (link , "\n");
- link = linkl[0]:"";
- y2milestone("link is %1", link);
- if (! issubstring (link , "/dev"))
- {
- link = "/dev/" + link ;
- }
- y2milestone("new link %1", link);
- ret = StorageDevices::GetCdromEntry( link);
- if (ret == $[] || ret == nil)
- {
- //y2milestone(" StorageDevices :: %1 " ,StorageDevices::cddrives);
- ret = find(map e, StorageDevices::cddrives, ``(e["linkname"]:"" == link));
- }
- y2milestone(" ret in check link %1", ret);
- }
- }
-
- if (ret == $[] || ret == nil) {
- ret = find(map e, StorageDevices::FloppyDrives, ``(e["dev_orig"]:(e["dev_name"]:"") == dev_name));
- if (ret != $[] && ret != nil) ret["found"] = "floppy";
- }
- else {
- ret["found"] = "cdrom";
- }
-
- if (ret == $[] || ret == nil)
- {
- list lret = maplist (string n, map m,
- filter (string k, map e, (map<string,map>)StorageDevices::ZipDrives,
- ``(e["dev_orig"]:(e["dev_name"]:"") == dev_name)), ``(m));
- ret = lret[0]:$[];
- if (ret != $[] && ret != nil) ret["found"] = "zip";
- }
-
- if (ret == $[] || ret == nil)
- {
- ret = Storage::GetPartition( Storage::GetTargetMap(), dev_name );
- if (ret != $[] && ret != nil) {
- if (ret["device"]:"" == dev_name)
- {
- ret["dev_name"] = dev_name;
- if (ret["fsid"]:0 == Partitions::fsid_swap) {
- ret["found"] = "swap";
- }
- else {
- ret["found"] ="dev";
- }
- if (ret["mount"]:"" == "/")
- {
- ret["found"] = "root";
- }
- }
- else {
- // Storage return default !!
- ret = $[];
- }
- }
- }
- return ret;
- };
-
- /**
- * Check if an entry for a device exist in the fstab.
- */
- define boolean check_dev_entry(string p)``{
-
- map part = devname2part(p);
- map lines = filter (integer lnr, map line, fstab["l"]:$[], ``(
-
- (line["fields",0]:"!" == p) ||
- (line["fields",0]:"!" == part["linkname"]:"" &&
- part["found"]:"" == "cdrom") ||
- (line["fields",0]:"!" == "UUID=" + part["uuid"]:"") ||
- (line["fields",0]:"!" == "LABEL=" + part["label"]:""))
- );
- if (size (lines) > 0)
- {
- y2milestone("found entry for %1 in the fstab", p);
- return true;
- }
- else
- {
- y2warning ("no entry for %1 found in the fstab",p);
- if (part["used_by"]:"" != "")
- {
- y2warning ("it is a device used by other entity (e.g. LVM, EVMS, MD): ignoring");
- return true;
- }
- missing_devs = add (missing_devs, p);
- missing_devs = toset (missing_devs);
- return false;
- }
- }
-
-
- /**
- * Return the partition map for a special uuid.
- */
- define map uuid2part(string uuidstring) {
- map ret = $[];
- foreach (string dn, checked_partitions, {
- if (ret == $[]) {
- map part = devname2part(dn);
- if (part ["uuid"]:"" == uuidstring)
- {
- ret = devname2part(dn);
- ret["wise"] = "uuid" ;
- }
- }
- });
- return ret;
- }
-
- /**
- * Return the partition map for a special label.
- */
- define map label2part(string labelstring) {
- map ret = $[];
- foreach (string dn, checked_partitions, {
- if (ret == $[]) {
- map part = devname2part(dn);
- if (part ["label"]:"!" == labelstring) {
- ret = devname2part( dn);
- ret["wise"] = "label";
- }
- }
- });
- return ret;
- }
-
- /**
- * Return the partition map for a fstab line.
- */
- define map line2part(list<string> line) ``{
-
- if (contains (fstab_default_exist ("spec", "spec"), line[0]:""))
- return $[];
-
- map ret = devname2part(line[0]:"");
- if (ret == nil || ret == $[])
- {
- string uuidstring = uuid_string(line);
- if (uuidstring != "")
- ret = uuid2part (uuidstring);
- if (ret == nil || ret == $[])
- {
- string labelstring = label_string(line);
- if (labelstring != "")
- ret = label2part( labelstring);
- }
- }
- else
- {
- ret["wise"] = "dev";
- }
- y2milestone("line2part return: %1", ret);
- return ret;
- }
-
-
- /**
- * Check one fstab line and return false if
- * the line contains errors.
- */
- define boolean check_fstab_line( integer lnr)``{
-
- map linemap = AsciiFile::GetLine(fstab, lnr);
- list<string> line = linemap["fields"]:[];
-
- // empty line ?
- if (size (filter (string pos, line, ``( pos != "" && pos != " "))) == 0 ||
- line == [])
- {
- y2milestone(" add empty line to valid_lines ");
- valid_lines = add (valid_lines , lnr);
- return true;
- }
-
- map part = line2part(line);
-
- string type = "invalid";
- boolean fs_spec = false;
- boolean fs_file = false;
- boolean fs_vfstype = false;
- boolean fs_mntops = false;
- boolean fs_freq = false;
- boolean fs_passno = false;
-
- if (part == nil || part == $[] || size (part)<=0)
- {
- if (line[0]:"" == fstab_defaults["usb","spec"]:"!")
- {
- if (Hotplug::haveUSB)
- {
- type = "usb";
- fs_spec = true;
- fs_file = (line[1]:"" == fstab_defaults[type,"mount"]:"!");
- fs_vfstype = (line[2]:"" == fstab_defaults[type,"vfstype"]:"!");
- fs_mntops = check_fs_mntops (line);
- }
- else
- {
- y2error("usb line in fstab but no usb found");
- type = "usb";
- fs_spec = false;
- fs_file = true;
- fs_vfstype = true;
- fs_mntops = true;
- }
- }
- else if (issubstring (line[0]:"", ":/"))
- {
- // nfs
- type = "nfs";
- fs_spec = true; // no check
- fs_file = check_fs_file (line);
- fs_vfstype = true; // no check
- fs_mntops = true; // no check
- }
- else if (line[0]:"" == fstab_defaults["pts","spec"]:"!")
- {
- type = "pts";
- fs_spec = true;
- fs_file = check_fs_file (line);
- fs_vfstype = ( line[2]:"" == fstab_defaults[type,"vfstype"]:"!");
- fs_mntops = ( line[3]:"" != nil && line[3]:"" != "");
- }
- else if (line[0]:"" == fstab_defaults["proc","spec"]:"!")
- {
- type = "proc";
- fs_spec = true;
- fs_file = ( line[1]:"" == fstab_defaults[type,"mount"]:"!");
- fs_vfstype = ( line[2]:"" == fstab_defaults[type,"vfstype"]:"!");
- fs_mntops = ( line[3]:"" != nil && line[3]:"" != "");
- }
- else if (line[0]:"" == fstab_defaults["sys","spec"]:"!")
- {
- type = "sys";
- fs_spec = true;
- fs_file = ( line[1]:"" == fstab_defaults[type,"mount"]:"!");
- fs_vfstype = ( line[2]:"" == fstab_defaults[type,"vfstype"]:"!");
- fs_mntops = ( line[3]:"" != nil && line[3]:"" != "");
- }
- fs_freq = check_fs_freq (
- line, [ tostring (fstab_defaults [type, "freq"]:0) ]);
- fs_passno = check_fs_passno (
- line, [ tostring (fstab_defaults [type, "passno"]:0) ]);
- }
- else
- {
- list<string> special_freq = [];
- list<string> special_passno = [];
-
- // cdrom floppy zip
- if (part["found"]:"" == "floppy" ||
- part["found"]:"" == "zip" ||
- part["found"]:"" == "cdrom")
- {
- type = part["found"]:"";
- fs_spec = true;
- fs_file = check_fs_file(line);
- fs_vfstype = check_fs_vfstype(line, part);
- fs_mntops = check_fs_mntops( line);
- }
- else if (contains (checked_partitions, part["dev_name"]:"") &&
- part["found"]:"" == "dev")
- {
- // check root first with CheckRootEntry!!
- if (line[1]:"" == "/")
- return true;
- type = "dev";
- fs_spec = true;
- fs_file = check_fs_file(line);
- fs_vfstype = check_fs_vfstype(line, part);
- fs_mntops = check_fs_mntops( line);
-
- special_passno = [ "2" ];
- special_freq = [ "1" ];
- // add mount point to target_map for later use (OSRBoot)
- part["mount"] = line[1]:"";
- Storage::ChangeVolumeProperties(part);
- }
- else if (contains (swapable_partition_list, part["dev_name"]:"") &&
- part["found"]:"" == "swap")
- {
- type = "swap";
- fs_file = true;
- fs_spec = (line[1]:"" == "swap");
- fs_vfstype = ( line[2]:"" == "swap");
- // TODO the default could be checked by
- // FileSystems::GetFstabDefaultMntops ("swap")
- fs_mntops = check_fs_mntops (line);
- }
- else if (part["found"]:"" == "root")
- {
- fs_spec = true;
- fs_file = true;
- fs_vfstype = true;
- fs_mntops = true;
- fs_freq = true;
- fs_passno = true;
- }
- else
- {
- y2error("not valid fstab entry found");
- }
-
- // not check for root
- if (type != "" &&
- contains (["dev", "swap","floppy", "zip", "cdrom"], type))
- {
- fs_freq = check_fs_freq (line,
- add (special_freq, tostring (fstab_defaults [type, "freq"]:0)));
- fs_passno = check_fs_passno (line,
- add (special_passno,tostring(fstab_defaults[type,"passno"]:0)));
- }
- }
- if (! fs_spec)
- {
- y2error("%1 spec not valid", line[0]:"");
- }
- if (! fs_file)
- {
- y2error("%1 file not valid", line[0]:"");
- }
- if (! fs_vfstype)
- {
- y2error("%1 fstype not valid",line[0]:"");
- }
- if (! fs_mntops)
- {
- y2error("%1 mntops not valid",line[0]:"");
- }
- if (! fs_freq)
- {
- y2error("%1 freq not valid",line[0]:"");
- }
- if (! fs_passno)
- {
- y2error("%1 passno not valid",line[0]:"");
- }
-
- if (fs_spec && fs_file && fs_vfstype && fs_mntops && fs_freq && fs_passno)
- {
- valid_lines = add (valid_lines , lnr);
- y2milestone("fstab line nr %1 entry is valid", lnr);
- }
- else
- {
- y2error("fstab line nr %1 is not valid", lnr);
- not_valid_lines [lnr] =
- [type, fs_spec, fs_file, fs_vfstype, fs_mntops, fs_freq, fs_passno];
- }
- return (fs_spec && fs_file && fs_vfstype && fs_mntops && fs_freq &&
- fs_passno);
- }
-
- /**
- * All device that should be checked.
- */
- define list<string> devices2check()``{
- list<string> dev2check = (list<string>)
- union (
- union (checked_partitions, swapable_partition_list),
- [
- fstab_defaults ["usb", "spec"]:"",
- fstab_defaults ["proc", "spec"]:"",
- fstab_defaults ["pts", "spec"]:""
- ]
- );
- dev2check = (list<string>) union (dev2check,
- maplist (map d, StorageDevices::cddrives,
- ``(d["dev_orig"]:(d["dev_name"]:""))));
-
- dev2check = (list<string>) union (dev2check,
- maplist (map d, StorageDevices::FloppyDrives,
- ``(d["dev_orig"]:(d["dev_name"]:""))));
-
- dev2check = (list<string>) union (dev2check,
- maplist (string k, map d, (map<string,map>) StorageDevices::ZipDrives,
- ``(d["dev_orig"]:(d["dev_name"]:""))));
-
- return dev2check;
- }
-
- /**
- * Check if all entries in the fstab are valid and
- * if all found devices have an entry in the fstab.
- */
- global define boolean Check(list<string> tswapable_partition_list,
- list<string> tchecked_partitions) ``{
-
- ResetSettings();
- swapable_partition_list = tswapable_partition_list;
- checked_partitions = tchecked_partitions;
-
- // check all lines in existing fstab file
- foreach (integer lnr, map line, fstab["l"]:$[], ``{
- y2milestone("----check fstab line %1 ", lnr);
- if (! contains (valid_lines, lnr))
- check_fstab_line(lnr);
- });
- // check all mountable partitions + swap + usb+ proc +...
- foreach (string p, devices2check(), ``{
- y2milestone("-----check partition and usb,proc,pts %1", p);
- check_dev_entry(p);
- });
-
- return ((size (missing_devs) == 0) && (size (not_valid_lines) == 0));
- }
-
- /**
- * Build items for table in missing devices dialog.
- */
- define list<term> missing_devs_items( map new_entries)``{
- list<term> item_list = [];
- foreach (string k, map<string,any> e, (map<string,map<string,any> >)new_entries, ``{
- item_list = add (item_list, `item(`id(k), k, e["mount"]:""));
- });
- return item_list;
- }
-
- define string find_next_media_file(string type)``{
- integer num = 0;
- string mp = "/media/" + type;
- while (true) {
- if (AsciiFile::FindLineField(fstab, 1,mp) == [])
- return mp;
- else {
- num = num + 1;
- mp = sformat ("%1%2",mp,num);
- }
- }
- }
-
- define list<string> used_mount_points(map fstab)``{
-
- list<string> ret = [];
- foreach (integer lnr, map ldata, fstab["l"]:$[], ``{
- ret = add (ret , ldata["fields", 1 ]:"");
- });
- return ret;
- }
-
- /**
- * Build fstab entries for all existing devices that are not listed
- * in the fstab.
- */
- define map suggest_missing_entries()``{
-
- if (Mode::test ()) return $[ "/dev/hda1" : $[ "mount" : "/hh" ]];
-
- integer other_nr = 1; // count other mounts -> global for wirte_fstab
- map new_entries = $[];
-
- missing_devs = sort (string d1, string d2, missing_devs , ``( d1 < d2));
-
- foreach (string dev, missing_devs, {
-
- map part = devname2part(dev);
- if (part != nil && part != $[] &&
- contains (["dev", "swap", "root"], part["found"]:"" ))
- {
- part["device"] = dev;
- integer nr = 1;
- map fstabentry = Storage::onepartition2fstab(part,nr);
- list<string> used_mountpoints = used_mount_points(fstab);
- string start = "/data";
- integer count = 2;
-
- // fstabentry could be empty map for some partitions (e.g.
- // with LVM group) -> suggest_missing_entries could report error 4
- while (contains (used_mountpoints , fstabentry["mount"]:""))
- {
- // find new mount point
- fstabentry["mount"] = sformat ("%1%2", start, count);
- count = count + 1;
- y2milestone("new mount point %1 ", fstabentry["mount"]:"");
- }
- if (size (fstabentry)>0)
- {
- new_entries[dev] = fstabentry;
- }
- }
- else if (contains (fstab_default_exist ("spec", "spec"), dev))
- {
- string type = "";
- foreach (string key, map descr, fstab_defaults, {
- if (descr["spec"]:"" == dev)
- type = key;
- });
- new_entries[dev] = fstabline2map ((list<string>)
- FileSystems::GetFstabDefaultList (type));
- }
- else if (contains (["zip", "floppy"], part["found"]:""))
- {
- map fstline = fstabline2map ((list<string>)
- FileSystems::GetFstabDefaultList (part["found"]:""));
- fstline["spec"] = part["dev_orig"]:(part["dev_name"]:"");
- fstline["mount"] = find_next_media_file (part["found"]:"");
- new_entries[dev] = fstline;
- }
- else if ("cdrom" == part["found"]:"")
- {
- map ret = Storage::MakeCdromFstabEntry (part);
- // new_entries[dev] = ret; // workaround for bug #185575
- }
- else {
- y2error("creating an entry for %1 is not possible (3)", dev);
- }
- });
- if (size (new_entries) == 0) {
- y2error("creating fstab entries is not possible (4)");
- }
- else {
- y2milestone("Suggested new fstab entries %1", new_entries);
- }
- return new_entries;
- }
-
- /**
- * @param cmp:
- * fstab line nr : mount point
- * cmp : $[ 1 : "/hhh",
- * 2 : "/mnt/uuu" ];
- *
- * @return create failed for mount points $[ 1 : "/hhh" ];
- */
- global define map check_and_create_mount_points(map cmp) ``{
-
- map failed = $[];
- foreach (integer lnr, string missing_dir, (map<integer,string>) cmp, ``{
- if (substring (missing_dir , 0,1) == "/")
- {
- list<string> subdirs = filter (string sdir, splitstring (missing_dir, "/"), ``( sdir != ""));
- string mkdir = root_mountpoint + "/";
- foreach (string sdir, subdirs, ``{
- mkdir = mkdir + "/"+ sdir;
- if (! OSRExecute::Command(.local.bash, sformat ("/usr/bin/test -d %1", mkdir)))
- OSRExecute::Command(.local.bash, sformat ("/bin/mkdir %1", mkdir));
- });
- if (! OSRExecute::Command(.local.bash, sformat ("/usr/bin/test -d %1", root_mountpoint + missing_dir)))
- {
- failed[lnr] = missing_dir;
- }
- }
- });
-
- if (size (failed) == 0)
- {
- // popup message
- Report::Message(_("
- All missing mount points were
- created successfully.
- "));
- }
- else if (size (failed) > 1)
- {
- // error popup
- Report::Error (sformat (_("
- Could not create the
- following mount points:
- %1
- "), mergestring ((list<string>)
- maplist (integer lnr, string dir, (map<integer,string>) failed,``(dir)), "\n")));
- }
- else if (size (failed) == 1)
- {
- Report::Error(sformat (_("
- Could not create the
- mount point:
- %1
- "), mergestring ((list<string>)
- maplist (integer lnr, string dir,(map<integer,string>) failed, ``(dir)), "\n")));
- }
- return failed;
- }
-
- /**
- * Dialog for existing devices that are not listed in the fstab.
- */
- define symbol SuggestMissingEntriesDialog()``{
-
- map new_entries = suggest_missing_entries();
-
- if (size (new_entries) == 0) return `error;
-
- string help_text = _("
- <P>No valid fstab entry was found
- for the devices listed in the table.
- </P>
- <P>
- Select the devices for which
- to create a new fstab entry
- and enter a mount point.
- </P>
- <P>After creating mount points for all
- devices, press Repair
- to continue.
- </P>
- ");
- help_text = help_text +
-
-
- OSRPopup::build_label_description (device_label, _("The name of the device for which no valid fstab
- entry was found.
- ")) +
-
- OSRPopup::build_label_description (mount_label, _("The mount point for the found device. This
- mount point is created in the file system. If you leave the mount point field empty, no fstab entry will be created.
- ")) +
-
- OSRPopup::build_label_description (create_mp_label, _("Add a mount point for a device."));
-
- OSRPopup::OpenSuggestDialog(_("Add fstab Entries"),
- _("
- Select the devices for which to
- create a new fstab entry and enter a mount point.
- "),
- help_text,
- `VBox(`Left(`Label(_("Devices without Valid fstab Entry"))),
- `Table(`id(`table), `header(device_label, mount_label), missing_devs_items(new_entries)),
- `Right(`PushButton(`id(`mountpoint), create_mp_label))) ,70 );
-
-
- symbol ret = `ok;
- repeat
- {
- ret = (symbol) UI::UserInput();
-
- if (ret == `mountpoint)
- {
- string current = (string)UI::QueryWidget(`id(`table),`CurrentItem);
- if (current != nil && current != "")
- {
- string text = OSRPopup::ChangeFieldDialog (
- new_entries[current,"mount"]:"",
- // TextEntry label, %1 is device label
- sformat (_("
- Mount Point for %1
- "), new_entries[current,"spec"]:""));
-
- if (text != nil)
- {
- new_entries[current,"mount"] = text;
- UI::ChangeWidget(`id(`table),
- `Items, missing_devs_items (new_entries));
- }
- }
- }
-
- if (ret == `ok)
- {
- integer changed_size = size (
- filter (string k,map e, (map<string,map<string,any> >)new_entries, ``(
- e["spec"]:"" != "" && e["mount"]:"" != ""))
- );
- if (changed_size == 0)
- {
- Report::Warning(_("
- First create mount points
- for the listed devices.
- "));
- ret = `notok;
- continue;
- }
- else if (changed_size < size (new_entries))
- {
- // yes/no popup headline
- if (!Popup::YesNoHeadline (_("Empty Mount Point"),
- // yes/no popup text
- _("
- Valid mount points are required to
- create fstab entries for devices.
- You did not enter a mount point
- for all devices. If you continue
- now, fstab entries are only created
- for devices with mount points.
- Really continue?
- ")))
- {
- ret = `notok;
- continue;
- }
- }
- // create mount point (cmp)
- map cmp = $[];
- integer fack_lnr = 0;
- foreach (string k, map e, (map<string,map<string,any> >)new_entries, ``{
- if (e["spec"]:"" != "" && e["mount"]:"" != ""){
- list<string> fstlist = [ k , e["mount"]:"",
- e["vfstype"]:"", e["mntops"]:"",
- sformat ("%1",e["freq"]:nil),
- sformat ("%1",e["passno"]:nil) ];
-
- cmp[fack_lnr] = e["mount"]:"";
- fack_lnr = fack_lnr + 1;
- AsciiFile::AppendLine( fstab, fstlist);
- }
- });
-
- map failed = check_and_create_mount_points(cmp);
- if (size (failed) > 0) ret = `error;
- }
- } until( ret == `ok || ret == `cancel || ret == `error);
-
- UI::CloseDialog();
- return ret;
- }
-
-
-
- /**
- *
- */
- define map suggest_create_mp()``{
-
- // found fstab line without valid mount point, e.g. (not_valid_lines):
- // $[4: ["dev", false, true, true ,true ,true ,true ]], //spec error
- list<integer> cmpl = maplist (integer kk, list vv,
- filter (integer k, list v, (map<integer,list>) not_valid_lines,
- {
- return
- v[1]:true == true &&
- v[2]:true == false &&
- substring (fstab [4, "fields", 1]:"", 0, 1) == "/" &&
- (fstab_defaults[v[0]:"","mount"]:"" == "" || v[0]:"" == "pts");
- }),
- ``(kk)
- );
-
- if (Mode::test ()) cmpl = [1,2];
- return AsciiFile::GetLines (fstab, cmpl);
- }
-
-
- /**
- *
- */
- define list<term> create_mp_items(map cmp)``{
- list<term> ret = [];
- foreach (integer lnr, map v, (map<integer,map<string,any> >)cmp, ``{
- ret = add (ret,
- `item (`id(lnr), create_label, v["fields",1]:"", v["fields",0]:""));
- });
- return ret;
- }
-
- /**
- *
- */
- define symbol SuggestCreateMp()``{
- map missing_create_mp = suggest_create_mp();
-
- if (size (missing_create_mp) == 0) return `ok;
-
- // help text
- string help_text = _("
- <P>The /etc/fstab file does not contain
- valid mount points for the listed devices.
- </P>") +
- //%1 is Ignore label and %2 is Create label
- OSRPopup::build_label_description (state_label, sformat (_("
- The status of a listed line can be switched between
- %1 and %2. Mount points for a partition are only created
- if the the status is %2.
- "), ignore_label, create_label)) +
-
-
- OSRPopup::build_label_description (mount_label, _("
- This field contains the present entry
- of the mount point in fstab.
- Change this field to a valid mount point.
- If you do not want to create the mount point,
- select the corresponding line in the table and change
- the status to ignore.
- ")) +
- // %1 is Ignore label
- OSRPopup::build_label_description (b_ignore_label, sformat (_("Change the status of the line to %1.
- "),ignore_label)) +
-
- // %1 is Create label
- OSRPopup::build_label_description (b_create_label, sformat (_("Change the status of the line to %1.
- "), create_label));
-
- OSRPopup::OpenSuggestDialog( _("Create Mount Points"),
- _("
- Some mount points for fstab entries are missing in
- the file system. Change the status of the
- lines for which to create a mount point.
- "),
- help_text,
- `VBox(`Left(`Label(_("Missing or Invalid Mount Points"))),
- `Table(`id(`table), `header( state_label, mount_label, device_label ),
- create_mp_items(missing_create_mp)),
- `HBox(`PushButton(`id(`ignore), b_ignore_label),
- `PushButton(`id(`create), b_create_label),
- `Right(`PushButton(`id(`change), b_change_mp_label))),
- `VSpacing(1)
- ), 50);
-
- UI::SetFocus(`id(`table));
- symbol ret = `ok;
- map cmp = $[];
- repeat
- {
- ret = (symbol) UI::UserInput();
- integer current_item = (integer)
- UI::QueryWidget(`id(`table), `CurrentItem);
-
- if (ret == `ignore)
- {
- UI::ChangeWidget (`id(`table), `Item(current_item,0), ignore_label);
- }
- else if (ret == `create)
- {
- UI::ChangeWidget (`id(`table), `Item(current_item,0), create_label);
- }
- else if (ret == `change)
- {
- integer current = (integer)
- UI::QueryWidget(`id(`table), `CurrentItem);
- if (current != nil)
- {
- string text = OSRPopup::ChangeFieldDialog (
- // TextEntry label, %1 is device
- missing_create_mp [current,"fields",1]:"", sformat (_("
- Mount Point for %1
- "), missing_create_mp[current,"fields",0]:""));
-
-
- if (text != nil)
- {
- missing_create_mp[current,"fields",1] = text;
- UI::ChangeWidget (`id(`table), `Items,
- create_mp_items (missing_create_mp));
- }
- }
- }
- else if (ret == `ok)
- {
- cmp = $[];
- foreach (integer e, map lines, (map<integer,map>) missing_create_mp,
- {
- term it = (term) UI::QueryWidget(`id(`table), `Item(e));
- if (it[1]:"" == create_label)
- {
- cmp[e] = lines["fields", 1]:"";
- }
- });
- }
- } until( ret == `ok || ret == `cancel);
-
- UI::CloseDialog();
-
- if (ret == `ok)
- {
- map failed = check_and_create_mount_points( cmp);
-
- if (size (failed) == 0)
- {
- foreach (integer lnr, string dir, (map<integer,string>) cmp,``{
- fstab["l",lnr,"fields",1] = dir;
- // rebuild the hole entry
- not_valid_lines[lnr,3] = false;
- not_valid_lines[lnr,4] = false;
- not_valid_lines[lnr,5] = false;
- not_valid_lines[lnr,6] = false;
- });
- }
- else if (size (failed) > 1)
- {
- // suggest to remove the line
- foreach (integer lnr, string dir, (map<integer,string>) failed, ``{
- not_valid_lines = filter (integer llnr, list<any> v, (map<integer,list<any> >)not_valid_lines,
- ``( llnr != lnr));
- });
- ret = `error;
- }
- else if (size (failed) == 1)
- {
- // suggest to remove the line
- foreach (integer lnr, string dir, (map<integer,string>) failed, ``{
- not_valid_lines = filter (integer llnr, list<any> v, (map<integer,list<any> >)not_valid_lines,
- ``( llnr != lnr));
- });
- ret = `error;
- }
- }
- return ret;
- }
-
- /**
- * Find all fstab entries (line nr) with not existing devices.
- */
- define list<integer> suggest_remove_spec()``{
- // spec not valid (false) -> remove
- list<integer> rm = (list<integer>) maplist (integer n, list m,
- filter (integer k, list<any>v, (map<integer,list<any> >)not_valid_lines, ``( v[1]:true == false)),
- ``(n));
- return rm;
- }
-
- /**
- * Build a item list for all fstab entries with not existing devices.
- */
- define list<term> remove_spec_items(list<integer> rm_entries, string ignore_label)
- {
-
- list<term> ret = [];
- foreach (integer lnr, rm_entries, {
- map line = AsciiFile::GetLine (fstab, lnr);
- ret = add (ret, `item (`id(lnr), ignore_label, line["line"]:""));
- });
- return ret;
- }
-
- /**
- * Dialog for all fstab entries with not existing devices.
- */
- define symbol SuggestRemoveSpecDialog()``{
- list<integer> rm_entries = suggest_remove_spec();
-
- if (size (rm_entries) == 0) return `ok;
-
- string help_text = OSRPopup::build_label_description (state_label,
- // help text in fstab dialog, %1 is Ignore label, %2 is Remove label
- sformat (_("
- The status of a listed line can be switched between
- %1 and %2. fstab entries are only removed if the the status of the
- corresponding line is %2.
- "), ignore_label, remove_label)) +
-
- // %1 is Ignore label
- OSRPopup::build_label_description (b_ignore_label, sformat (_("Change the status of the line to %1.
- "), ignore_label)) +
-
- // %1 is Remove label
- OSRPopup::build_label_description (b_remove_label, sformat (_("Change the status of the line to %1.
- "), remove_label));
-
- OSRPopup::OpenSuggestDialog(
- // dialog caption, fstab is filename
- _("Remove fstab Entries"),
- // dialog text
- _("Could not find existing devices for the following fstab lines.
- To remove the lines from fstab, select them in the table and
- change the status.
- "),
- help_text,
- `VBox(
- // label (table will follow)
- `Left(`Label(_("Invalid or Obsolete Lines in fstab"))),
- `Table(`id(`table),
- `header(state_label, fstab_line_label),
- remove_spec_items(rm_entries, ignore_label)),
- `Left(`HBox(
- `PushButton(`id(`ignore), b_ignore_label),
- `PushButton(`id(`remove), b_remove_label)))
- ), 50);
-
- UI::SetFocus(`id(`table));
-
- symbol ret = `ok;
- repeat
- {
- ret = (symbol) UI::UserInput();
- integer current_item =
- (integer) UI::QueryWidget(`id(`table), `CurrentItem);
-
- if (ret == `ignore)
- {
- UI::ChangeWidget(`id(`table), `Item(current_item, 0), ignore_label);
- }
- else if (ret == `remove)
- {
- UI::ChangeWidget(`id(`table), `Item(current_item, 0), remove_label);
- }
- else if (ret == `ok)
- {
- list<integer> rm_list = [];
- foreach (integer e, rm_entries, {
- term it = (term) UI::QueryWidget(`id(`table), `Item(e));
- if (it[1]:"" == remove_label)
- {
- rm_list = add (rm_list, e);
- }
- });
- y2milestone("lines to remove %1", rm_list);
- AsciiFile::RemoveLines(fstab, rm_list);
- }
- } until( ret == `ok || ret == `cancel);
-
- UI::CloseDialog();
- return ret;
- };
-
- /**
- * Find all fstab lines with at least one invalid position
- */
- define map suggest_modify()``{
-
- y2milestone("starting modify suggestion");
- /*
- map modify_entries = filter (integer k, list<any> v, (map<integer,list<any> >)not_valid_lines,
- ``( v[1]:false == true));
- */
- map modify_entries = filter (integer k, list v,
- (map<integer,list>) not_valid_lines,``( v[1]:false == true));
-
- if (size (modify_entries) == 0) return $[];
-
- map nlines = $[];
- foreach (integer lnr, list opts, (map<integer,list>) modify_entries,
- {
- map linemap = AsciiFile::GetLine (fstab, lnr);
- list<string> line = linemap ["fields"]:[];
- list<string> nline = [line[0]:""];
- map part = line2part(line);
- string type = opts[0]:"";
- list default_line = FileSystems::GetFstabDefaultList (type);
- if (opts[2]:true == false)
- {
- if (fstab_defaults [type,"mount"]:"" != "" && type != "pts")
- {
- nline = add (nline, fstab_defaults[type,"mount"]:"");
- }
- else
- {
- AsciiFile::RemoveLines(fstab, [ lnr ]);
- return;
- }
- }
- else
- {
- nline = add (nline , line[1]:"");
- }
- // invalid vfstype
- if (opts[3]:true == false)
- {
- if (type == "dev" )
- {
- string detected_fs = FileSystems::GetMountString (
- part["detected_fs"]:part["used_fs"]:`unknown, "");
- if (detected_fs != "")
- {
- nline = add (nline, detected_fs);
- }
- else
- {
- y2error("could not repair the defect fstab line %1", line);
- return;
- }
- }
- else
- {
- // proc, usb, pts
- string fs = fstab_defaults[type,"vfstype"]:"";
- if (fs != "")
- nline = add (nline, fs);
- else
- {
- y2error("invalid type");
- return;
- }
- }
- }
- else
- {
- nline = add (nline, line[2]:"");
- }
- integer i = 4;
- while (i <= 6)
- {
- // invalid ops
- if (opts[i]:true == false)
- {
- string str = default_line[i-1]:"";
- if (str != "")
- nline = add (nline, str);
- else
- {
- y2error("not valid %2 for line %1 found", line,
- pos2field[i-1]:"");
- }
- //set following pos to false
- integer ii = i+1;
- while (ii <=6)
- {
- opts[ii] = false;
- ii = ii+1;
- }
- }
- else
- {
- nline = add (nline, line[i-1]:"");
- }
- i = i +1;
- }
- nline = filter (string pos, nline, ``( pos != nil && pos != ""));
- if (size (nline) == 6 && nline != line)
- {
- nlines[lnr] = nline;
- }
- else if (nline != line)
- {
- y2error("the size of the suggested fstab entry is to less");
- }
- });
- return nlines;
- }
-
- /**
- * Build a item list.
- */
- define list<term> modify_items (map nlines, string ignore_label, boolean existing)
- {
-
- list<term> ret = [];
- foreach (integer lnr, list<string> nline,(map<integer,list<string> >)nlines,
- {
- if (existing)
- {
- map linemap = AsciiFile::GetLine(fstab,lnr);
- nline = linemap["fields"]:[];
- }
- ret = add (ret,`item(`id(lnr), ignore_label, mergestring(nline, ", ")));
- });
- return ret;
- };
-
- /**
- * Dialog for all fstab entries that have at least one invalid entry.
- */
- define symbol SuggestModifyDialog()``{
-
- map nlines = suggest_modify();
-
- if (size (nlines) == 0)
- return `ok;
-
- //label of table, fstab is filename
- string existing_label = _("Existing fstab Lines");
- //label of table, fstab is filename
- string suggested_label = _("Suggested fstab Lines");
-
- // help text, %1 is table label for Suggested. %2 is Replace button label
- string help_text = sformat (_("
- One or more existing fstab entries seem to
- be invalid. Compare the suggested entry
- with the existing one.
- To replace an existing line with a suggested
- line, select the corresponding line
- in the %1 table and
- press %2.
- "), suggested_label, b_replace_label) +
-
- //%1 is Ignore label, %2 is replace label
- OSRPopup::build_label_description (state_label, sformat (_("
- The status of a listed line can be switched between
- %1 and %2. Lines are only replaced if the status is %2.
- "), ignore_label, replace_label)) +
-
- //%1 is Ignore label
- OSRPopup::build_label_description (b_ignore_label, sformat (_("Change the status of the line to %1.
- "), ignore_label)) +
-
- //%1 is Replace label
- OSRPopup::build_label_description (b_replace_label, sformat (_("Change the status of the line to %1.
- "), replace_label));
-
- // dialog headline
- OSRPopup::OpenSuggestDialog (_("Change Existing fstab Entries"),
- // dialog description
- _("
- One or more existing fstab entries seem invalid.
- Compare the suggested entry with the existing one."),
- help_text,
- `VBox (
- `Left(`Label(existing_label)),
- `Table (`id(`table_e), `opt(`disabled),
- `header (state_label, fstab_line_label),
- modify_items (nlines, ignore_label, true)
- ),
- `VSpacing(1),
- `Left(`Label(suggested_label)),
- `Table(`id(`table_s), `opt(`notify),
- `header (state_label, fstab_line_label),
- modify_items(nlines,ignore_label, false)
- ),
- `Left (`HBox(
- `PushButton(`id(`ignore), b_ignore_label),
- `PushButton(`id(`replace),b_replace_label)
- ))
- ),
- 80
- );
- UI::SetFocus(`id(`table_s));
-
- symbol ret = `ok;
- repeat
- {
- ret = (symbol) UI::UserInput();
- integer current_item =
- (integer) UI::QueryWidget(`id(`table_s), `CurrentItem);
- UI::ChangeWidget (`id(`table_e), `CurrentItem, current_item);
-
- if (ret == `ignore)
- {
- UI::ChangeWidget(`id(`table_s), `Item(current_item,0),ignore_label);
- UI::ChangeWidget(`id(`table_e), `Item(current_item,0),ignore_label);
- }
- else if (ret == `replace)
- {
- UI::ChangeWidget(`id(`table_s),`Item(current_item,0),replace_label);
- UI::ChangeWidget(`id(`table_e),`Item(current_item,0),replace_label);
- }
- else if (ret == `ok)
- {
- integer changed_count = size (
- filter (integer e, any ld, (map<integer,any>) nlines, {
- term it = (term)UI::QueryWidget(`id(`table_s),`Item(e));
- return (it[1]:"" == replace_label);
- })
- );
- if (changed_count == 0)
- {
- Report::Warning(_("
- Set the status of at least one
- table entry to replace.
- "));
- ret = `notok;
- continue;
- }
- else if (changed_count < size (nlines))
- {
- // yes/no popup headline
- if (! Popup::YesNoHeadline (_("Not All Replaced"),
- // yes/no popup text
- _("
- Only the fstab lines marked for replacement
- are replaced. Really replace only the
- selected lines?
- ")))
- {
- ret = `notok;
- continue;
- }
- }
- list<integer> rp_list = [];
- foreach (integer e, any ld, (map<integer,any>) nlines, {
- term it = (term) UI::QueryWidget (`id(`table_s),`Item (e));
- if (it[1]:"" == replace_label)
- {
- rp_list = add (rp_list, e);
- }
- });
-
- y2milestone("lines to remove %1", rp_list);
- AsciiFile::RemoveLines(fstab, rp_list);
-
- // save and reread before append fstab !!
- // Remove don't resort list positions!!
- AsciiFile::RewriteFile (fstab, root_mountpoint + fstabpath);
- ReadFstab (root_mountpoint, true);
-
- foreach (integer rp, rp_list, ``{
- AsciiFile::AppendLine(fstab, nlines[rp]:[]);
- });
- }
- } until( ret == `ok || ret == `cancel);
-
- UI::CloseDialog();
- return ret;
- }
-
- define symbol ret_worst_symbol(list<symbol> retl)``{
-
- map symbol_weight = $[
- `ok : 1,
- `cancel : 2,
- `error : 3,
- `abort : 2
- ];
-
- symbol ret = `ok;
- foreach (symbol r, retl, ``{
- if (symbol_weight[ret]:0 < symbol_weight[r]:-1)
- ret = r;
- });
- return ret;
- }
-
- /**
- * Repair the fstab. Call sub dialogs.
- */
- global define symbol Repair () ``{
-
- list<symbol> ret = [];
-
- if (Mode::test ())
- {
- return `ok;
- }
-
- if (size (missing_devs) > 0) {
- y2milestone ("-------------- missing devices: %1", missing_devs);
- ret = add (ret, SuggestMissingEntriesDialog());
- }
-
- if (size (not_valid_lines) > 0) {
- y2milestone ("-------------- not valid lines: %1", not_valid_lines);
- ret = add (ret, SuggestCreateMp());
- ret = add (ret, SuggestRemoveSpecDialog());
- ret = add (ret, SuggestModifyDialog());
- }
-
- y2milestone("ret repair list %1", ret);
-
- if ((size (filter (symbol r, ret, ``( r == `ok))) > 0))
- {
- AsciiFile::RewriteFile (fstab, root_mountpoint + fstabpath);
- ResetSettings ();
- ReadFstab (root_mountpoint, true);
- }
- else
- {
- y2milestone("new fstab was not written");
- return `cancel;
- }
- return ret_worst_symbol(ret);
- }
-
- /**
- *
- */
- global define boolean CheckRootEntry (string dev_name,
- list<string> tswapable_partition_list,
- list<string> tchecked_partitions)``{
-
- ResetSettings();
- y2milestone("check root fstab entry");
- swapable_partition_list = tswapable_partition_list;
- checked_partitions = tchecked_partitions;
- boolean ret = false;
- map root_part = devname2part (dev_name);
- list root_l_no = AsciiFile::FindLineField (fstab, 0, dev_name);
-
- root_l_no = union (root_l_no,
- AsciiFile::FindLineField (fstab, 0, "UUID=" + root_part["uuid"]:""));
-
- root_l_no = union (root_l_no,
- AsciiFile::FindLineField (fstab, 0, "LABEL=" + root_part["label"]:""));
-
- // root_lines example:
- // $[ 1 : $["fields":["/dev/hda3", "/", "reiserfs", "defaults", "1", "2"],
- // "line":"/dev/hda3\t/\treiserfs\tdefaults 1 2" ]
- // ]
- map<integer,map> root_lines = $[];
-
- foreach (integer n, (list<integer>) root_l_no, {
- root_lines[n] = AsciiFile::GetLine(fstab, n);
- });
-
- root_lines =
- filter (integer n, map l, root_lines, ``(l["fields",1]:"" == "/"));
-
- if (size (root_lines) != 1)
- {
- y2error(" several or non root entries in fstab found");
- y2error(" root lines %1", root_lines);
- missing_devs = add (missing_devs, dev_name);
- ret = false;
- }
- else
- {
- list keys = maplist (integer k, map v, root_lines,``(k));
- integer root_line_key = keys[0]:1;
- list<string> root_line = root_lines [root_line_key, "fields"]:[];
- string type = "root";
-
- boolean fs_vfstype = check_fs_vfstype (root_line, root_part);
- boolean fs_mntops = check_fs_mntops (root_line);
- boolean fs_freq = check_fs_freq (root_line,
- [ tostring (fstab_defaults [type, "freq"]:0) ]);
- boolean fs_passno = check_fs_passno (root_line,
- [ tostring (fstab_defaults [type, "passno"]:0) ]);
-
- if (! fs_vfstype)
- {
- y2error("root fstype not valid");
- }
- if (! fs_mntops)
- {
- y2error("root mntops not valid");
- }
- if (! fs_freq)
- {
- y2error("root freq not valid");
- }
- if (! fs_passno)
- {
- y2error("root passno not valid");
- }
-
- if (fs_vfstype && fs_mntops && fs_freq && fs_passno)
- {
- valid_lines = add (valid_lines, root_line_key);
- y2milestone("root fstab line entry is valid");
- }
- else
- {
- y2error("root fstab line is not valid");
- not_valid_lines [root_line_key] =
- [ type, true, true, fs_vfstype, fs_mntops, fs_freq, fs_passno];
- }
- ret = (fs_vfstype && fs_mntops && fs_freq && fs_passno);
- }
-
- //for OSRBoot
- root_part["mount"] = "/";
- Storage::ChangeVolumeProperties(root_part);
-
- //inst_prepdisk for OSRBoot!
- foreach (string modname, (list<string>)FileSystems::GetNeededModules (
- root_part["detected_fs"]:(root_part["used_fs"]:`ext2)), ``{
- Initrd::AddModule (modname, "");
- });
-
- return ret;
- }
-
-
- /**
- *
- */
- global define string BootDev() ``{
-
- map lines = fstab["l"]:$[];
- list line = maplist (integer llineno, map llinedata,
- filter (integer lineno, map<string,any> linedata, (map<integer,map<string,any> >) lines , ``(
- linedata["fields", 1]:"" == "/boot")),
- ``(llinedata)
- );
- string ret = "";
- if (size (line) == 1)
- {
- map part = line2part(line[0,"fields"]:[]);
- ret = part["dev_name"]:part["device"]:"";
- }
- else
- {
- y2milestone("no /boot device in fstab");
- }
- if (ret == nil)
- ret = "";
- return ret;
- }
-
-
- /**
- * ask user to select the root partition
- */
- global define string SelectRoot (list<map> valid_root_partition_list) {
-
- if (size (valid_root_partition_list) == 1)
- return valid_root_partition_list[0,"device"]:"";
-
- return OSRPopup::RadioButtonGroupText (
- // popup headline
- _("Select a Root Partition"),
- // popup text (radio buttons wil follow
- _("There are several valid root partitions in your system.
- Select one item in the list.
- "),
- (list<list>) maplist (map entry, valid_root_partition_list, ``(
- [
- entry["device"]:"",
- entry["label"]:""
- ]
- )),
- "",
- "",
- true
- );
- }
-
- /**
- *
- */
- global define boolean ReadedSuccessfully() ``{
- return ( fstab != nil && fstab != $[]);
- }
-
- /**
- *
- */
- global define list<map> UmountAll (list<map> umount_list) ``{
-
- integer counter_error = 0;
- list<map> just_umounted = [];
- list<map> mnt_list = [];
-
- mnt_list = filter (map s, umount_list, ``(
- substring (s["file"]:s["mountpoint"]:"", 0, size (root_mountpoint))
- == root_mountpoint)
- );
-
- mnt_list = sort (map x, map y, mnt_list, ``(
- size (splitstring (x["file"]:x["mountpoint"]:"", "/")) >
- size (splitstring (y["file"]:y["mountpoint"]:"" ,"/")))
- );
-
- y2milestone("partitions which should be umounted %1", mnt_list);
-
- // umount all partitions from "/mnt" or deeper, as long as there are no
- // more mounted partitions with mountpoint "/mnt..."
- foreach (map current, mnt_list, ``{
-
- if (OSRExecute::Command (.local.bash,
- "/bin/umount "+ current["file"]:current["mountpoint"]:""))
- {
- just_umounted = add (just_umounted, $[
- "partition" : current["spec"]:current["partition"]:"",
- "mountpoint" : current["file"]:current["mountpoint"]:"" ]
- );
- }
- else
- {
- y2error(" %1 could not be umounted",
- current["file"]:current["mountpoint"]:"");
- counter_error = counter_error +1;
- }
- });
-
- if (counter_error == 0)
- {
- y2debug("All partitions were successfully umounted from /mnt...");
- }
- return just_umounted;
- }
-
- /**
- *
- */
- global define list<map> UmountAllFrom( string root)``{
-
- if (root != "" && root != nil)
- root_mountpoint = root;
-
- list<map> just_umounted = [];
- list<map> mounted_partitions = Partitions::CurMounted();
-
- // filter swap partitions
- mounted_partitions = filter (map p, mounted_partitions, ``(
- p["file"]:"" != "swap" && findfirstof (p["spec"]:"", "/") == 0));
-
- // filter the list of partitions that are mounted to "/mnt" or deeper
- if (root_mountpoint != "/")
- {
- just_umounted = UmountAll( mounted_partitions);
- }
-
- return just_umounted;
- }
-
-
- /**
- *
- */
- global define list<map> RootDev(string root)``{
-
- if (root != "" && root != nil)
- root_mountpoint = root;
-
- list<map> mounted = [];
-
- if (! ReadedSuccessfully())
- {
- list<string> checked_partitions = filter (string s,
- maplist (map p, OSRFsck::PossiblePartitions(), ``(p["device"]:"")),
- ``(s !=""));
- list<string> linux_partition_list =
- LinuxPartitions(checked_partitions);
- list<string> mount_possible_list =
- MountablePartitions (linux_partition_list, root_mountpoint);
- list<map> valid_root_partitions =
- ValidRootPartitions (mount_possible_list, root_mountpoint);
-
- if (size (valid_root_partitions) == 0)
- {
- // error popup: no root partition found
- Report::Error(_("
- No valid root partition found.
- Go back and select all scan
- options. Afterwards, restart
- scanning.
- "));
- return nil;
- }
- string root_partition = SelectRoot (valid_root_partitions);
- y2milestone("selected root_partition %1" ,root_partition);
-
- boolean mount = OSRExecute::Command (.local.bash,
- sformat ("/bin/mount %1 %2", root_partition, root_mountpoint));
-
- mounted = add (mounted, $[
- "partition" : root_partition,
- "mountpoint" : root_mountpoint,
- "status" : mount ]
- );
- if (mount)
- {
- OSRSystem::ChangeRoot("/");
- ReadFstab(root_mountpoint, true);
- }
- else
- {
- y2error("can not mount root partition");
- }
- }
-
- y2milestone("RootDev in Fstab %1" ,mounted);
- return mounted;
- }
-
-
- /**
- * Mount all partitions specified in the fstab.
- * If no fstab was readed try to find root partition
- * and read fstab. Afterwards mount all partitions.
- */
- global define list<map> MountAll(string root)``{
-
- list<map> mounted = [];
-
- if (root != "" && root != nil)
- root_mountpoint = root;
-
- if (OSRFsck::LoadAllFsModules())
- {
- y2milestone("kernel fs modules successful loaded");
- }
- else
- {
- y2error("loaded kernel modules returned an error");
- }
- // if fstab is not readed.
- // Fstab functions are not called.
- // user skiped execution of osr_module_partition,
- // but need a root partition -> find root and
- // read fstab.
- list<map> t_mounted = RootDev(root_mountpoint);
-
- if (t_mounted != nil && t_mounted != [])
- mounted = (list<map>) union (mounted, t_mounted);
-
- if (! ReadedSuccessfully())
- {
- Report::Error(_("
- Cannot read the file /etc/fstab.
- Initialization of the target system
- is not possible. Go back
- and select all scan options.
- "));
- return nil;
- }
-
- //sort fstab lines /mnt/hh/kk > /mnt/hh
- list<map> lines = (list<map>) maplist (integer lnr, map linedata,
- fstab["l"]:$[], ``(linedata));
-
- foreach (map linedata, lines, ``{
-
- list<string> line = linedata["fields"]:[];
- map part = line2part (line);
- // not mounted
- if ((part["found"]:"" == "dev") &&
- (!contains (["/dev/cdrecorder", "/dev/cdrom", "/dev/dvd",
- "/media/cdrecorder", "/media/cdrom", "/media/dvd" ],
- line[1]:"")) &&
- (Storage::DeviceMounted(line[1]:"") == "")
- && ( line[1]:"" != "/"))
- {
- string mp = root_mountpoint + line[1]:"";
- mounted = add (mounted , $[
- "partition" : line[0]:"",
- "mountpoint" : mp,
- "status" : OSRExecute::Command (.local.bash,
- sformat ("/bin/mount %1 %2", line[0]:"", mp))
- ]
- );
- }
- });
-
- OSRSystem::ChangeRoot(root_mountpoint);
- y2milestone(" Mount all return %1", mounted);
- return mounted;
- }
-
-
- }//EOF
-