ACC SHELL

Path : /usr/share/YaST2/clients/
File Upload :
Current File : //usr/share/YaST2/clients/umount_finish.ycp

/**
 * File:
 *  umount_finish.ycp
 *
 * Module:
 *  Step of base installation finish
 *
 * Authors:
 *  Jiri Srain <jsrain@suse.cz>
 *
 * $Id: umount_finish.ycp 54888 2009-01-22 11:47:19Z locilka $
 *
 */

{

textdomain "installation";

import "Installation";
import "Storage";
import "Hotplug";
import "Vendor";
import "String";
import "Internet";

any ret = nil;
string func = "";
map param = $[];

/* Check arguments */
if(size(WFM::Args()) > 0 && is(WFM::Args(0), string)) {
    func = (string)WFM::Args(0);
    if(size(WFM::Args()) > 1 && is(WFM::Args(1), map))
	param = (map)WFM::Args(1);
}

y2milestone ("starting umount_finish");
y2debug("func=%1", func);
y2debug("param=%1", param);

if (func == "Info")
{
    return (any)$[
	"steps" : 1,
	// progress step title
	"title" : _("Unmounting all mounted devices..."),
	"when" : [ `installation, `live_installation, `update, `autoinst ],
    ];
}
else if (func == "Write")
{
    // Release all sources, they might be still mounted
    Pkg::SourceReleaseAll();

    // save all sources and finish target
    // bnc #398315
    Pkg::SourceSaveAll();
    Pkg::TargetFinish();

    // loop over all filesystems
    map<string,list> mountPoints = (map<string,list>)Storage::GetMountPoints();
    y2milestone ("Known mount points: %1", mountPoints);
    y2milestone ("/proc/mounts:\n%1", WFM::Read (.local.string, "/proc/mounts"));
    y2milestone ("/proc/partitions:\n%1", WFM::Read (.local.string, "/proc/partitions"));

    list<string> umountList = [];

    // go through mountPoints collecting paths in umountList
    // *** umountList is lexically ordered !

    foreach (string mountpoint, list mountval, mountPoints, {
	if (mountpoint != "swap") {
	    umountList = add (umountList, mountpoint);
	}
    });

    // remove [Installation::destdir]/etc/mtab which was faked for %post
    // scripts in inst_rpmcopy
    SCR::Execute(.target.remove, "/etc/mtab");

    // Stop SCR on target
    WFM::SCRClose (Installation::scr_handle);

    // first, umount everthing mounted *in* the target.
    // /proc/bus/usb
    // /proc

    list <string> umount_these = ["/proc", "/sys", "/dev"];
    if (Hotplug::haveUSB) {
	umount_these = (list <string>) union (["/proc/bus/usb"], umount_these);
    }

    foreach (string umount_dir, umount_these, {
	string umount_this = sformat ("%1%2", Installation::destdir, umount_dir);
	y2milestone ("Umounting: %1", umount_this);
	boolean umount_result = (boolean) WFM::Execute (.local.umount, umount_this);

	if (umount_result != true) {
	    // bnc #395034
	    // Don't remount them read-only!
	    if (contains (["/proc", "/sys", "/dev", "/proc/bus/usb"], umount_dir)) {
		y2warning ("Umount failed, trying lazy umount...");
		string cmd = sformat ("sync; umount -l -f '%1';", String::Quote (umount_this));
		y2milestone ("Cmd: '%1' Ret: %2", cmd, WFM::Execute (.local.bash_output, cmd));
	    } else {
		y2warning ("Umount failed, trying to remount read only...");
		string cmd = sformat ("sync; mount -o remount,ro '%1'; umount -l -f '%1';", String::Quote (umount_this));
		y2milestone ("Cmd: '%1' Ret: %2", cmd, WFM::Execute (.local.bash_output, cmd));
	    }
	}
    });

    map<string,map> targetMap = Storage::GetTargetMap();

    // first umount all file based crypto fs since they potentially
    // could mess up umounting of normale filesystems if the crypt
    // file is not on the root fs
    y2milestone( "umount list %1", umountList );
    foreach (map e,  targetMap["/dev/loop","partitions"]:[], {
	if (size(e["mount"]:"")>0) {
	    Storage::Umount (e["device"]:"");
            umountList = filter (string m, umountList, ``(m!=e["mount"]:""));
            y2milestone ("loop umount %1 new list %2", e["mount"]:"", umountList);
        }
    });

    // *** umountList is lexically ordered !
    // now umount in reverse order (guarantees "/" as last umount)

    integer umountLength = size (umountList);

    while (umountLength > 0)
    {
        umountLength = umountLength - 1;
        string tmp = Installation::destdir + (string) (umountList[umountLength]:"");
        y2milestone ("umount target: %1", tmp);

        boolean umount_status = (boolean) WFM::Execute (.local.umount, tmp);

	// bnc #395034
	// Don't remount them read-only!
	if (umount_status != true) {
	    if (contains (["/proc", "/sys", "/dev", "/proc/bus/usb"], tmp)) {
		y2warning ("Umount failed, trying lazy umount...");
		string cmd = sformat ("sync; umount -l -f '%1';", String::Quote (tmp));
		y2milestone ("Cmd: '%1' Ret: %2", cmd, WFM::Execute (.local.bash_output, cmd));
	    } else {
		y2warning ("Umount failed, trying to remount read only...");
		string cmd = sformat ("mount -o remount,ro '%1'; umount -l -f '%1';", String::Quote (tmp));
		y2milestone ("Cmd: '%1' Ret: %2", cmd, WFM::Execute (.local.bash_output, cmd));
	    }
	}
    }

    // bugzilla #326478
    y2milestone ("Currently mounted partitions: %1", WFM::Execute (.local.bash_output, "mount"));

    string cmd = sformat ("fuser -v '%1' 2>&1", String::Quote (Installation::destdir));
    map cmd_run = (map) WFM::Execute (.local.bash_output, cmd);

    // must call .local.bash_output !
    integer max_loop_dev = Storage::NumLoopDevices();

    // disable loop device of crypto fs
    boolean unload_crypto = false;

    while (max_loop_dev > 0)
    {
        unload_crypto   = true;
        string exec_str = sformat( "/sbin/losetup -d /dev/loop%1", max_loop_dev-1 );
        y2milestone( "loopdev: %1", exec_str);
        WFM::Execute(.local.bash, exec_str);
        max_loop_dev = max_loop_dev -1;
    }

    if( size(filter(string k, map v, targetMap, ``(v["type"]:`CT_UNKNOWN==`CT_LVM))) >0 )
    {
        y2milestone( "shutting down LVM" );
        WFM::Execute(.local.bash, "/sbin/vgchange -a n" );
    }

}
else
{
    y2error ("unknown function: %1", func);
    ret = nil;
}

y2debug("ret=%1", ret);
y2milestone("umount_finish finished");
return ret;


} /* EOF */

ACC SHELL 2018