ACC SHELL
/**
* File:
* StorageDevices.ycp
*
* Module:
* StorageDevices
*
* Depends:
* StorageControllers
*
* Summary:
* This module does all storage device related stuff:
* - hard disk drives
* - removable drives (ZIP)
* - floppy devices
*
* $Id: StorageDevices.ycp 61905 2010-04-29 09:05:37Z aschnell $
*
* Author:
* Klaus Kaempf <kkaempf@suse.de> (initial)
*/
{
module "StorageDevices";
import "Mode";
import "Stage";
import "HwStatus";
textdomain "storage";
boolean disks_valid = false;
/**
* @return map of $["device": $[..target..], ...] for each ZIP drive
*
*/
map<string,map> zip_drives = nil;
/**
* @return list of maps: all kinds of removable media, esp. ZIP drives
*/
list<map> floppy_drives = nil;
/**
* @return true if floppy drive present
*/
boolean floppy_present = nil;
/**
* @return Device name of floppy, empty string if no floppy present
*/
string floppy_device = nil;
//---------------------------------------------------------------
/**
* list of cd-rom drives
*/
list<map> cd_drives = nil;
// storage for localProbe, see Probe()
integer targetMapSize = 0;
//---------------------------------------------------------------
list<map> AddNormalLinknames( list<map> cddrives )
``{
map linknum = $[ "cdrom" : 0,
"cdrecorder" : 0,
"dvd" : 0,
"dvdrecorder" : 0,
"dvdram" : 0 ];
cddrives = maplist( map e, cddrives,
``{
// first, determine the drive type and make a linkname guess
string cddevice = e["dev_name"]:"";
string linkname = "cdrom";
if( e["dvdram"]:false )
{
linkname = "dvdram";
}
else if( e["dvdr"]:false )
{
linkname = "dvdrecorder";
}
else if( e["cdr"]:false || e["cdrw"]:false )
{
linkname = "cdrecorder";
}
else if( e["dvd"]:false )
{
linkname = "dvd";
}
// now check the number (for /dev/cdrom, /dev/cdrom2, ...)
integer number = linknum[linkname]:0;
linknum[linkname] = number + 1;
string devname = "/dev/" + linkname;
if( number > 0)
devname = sformat( "%1%2", devname, number+1 );
e["linkname"] = devname;
return( e );
});
y2milestone( "AddNormalLinknames linknum %1", linknum );
return( cddrives );
}
list<map> AddAlternateLinks( list<map> cddrives )
``{
list<string> llist = [];
foreach( map cd, cddrives,
``{
llist = (list<string>)union( llist, cd["udev_links"]:[] );
});
y2milestone( "AddAlternateLinks llist %1", llist );
if( !contains( llist, "cdrom" ) && size(cddrives)>0 )
{
cddrives[0,"udev_links"] = add( cddrives[0,"udev_links"]:[], "cdrom" );
y2milestone( "AddAlternateLinks cdrom %1", cddrives[0]:$[] );
}
integer i = 0;
if( !contains( llist, "dvd" ))
{
while( i<size(cddrives) && !cddrives[i,"dvd"]:false )
{
i = i + 1;
}
if( i<size(cddrives) )
{
cddrives[i,"udev_links"] = add( cddrives[i,"udev_links"]:[], "dvd" );
y2milestone( "AddAlternateLinks dvd %1", cddrives[i]:$[] );
}
}
if( !contains( llist, "cdrecorder" ))
{
i = 0;
while( i<size(cddrives) && !cddrives[i,"cdrw"]:false )
{
i = i + 1;
}
if( i<size(cddrives) )
{
cddrives[i,"udev_links"] = add( cddrives[i,"udev_links"]:[], "cdrecorder" );
y2milestone( "AddAlternateLinks cdrecorder %1", cddrives[i]:$[] );
}
}
y2milestone( "AddAlternateLinks ret %1", cddrives );
return( cd_drives );
}
/**
* ProbeCDROMs()
*
* Initialize cd_drives
*
*/
boolean ProbeCDROMs()
``{
if( cd_drives==nil )
{
cd_drives = [];
if (Stage::initial() || Stage::cont())
{
y2milestone( "before SCR::Read (.probe.cdrom)" );
cd_drives = (list<map>) SCR::Read (.probe.cdrom);
y2milestone( "after SCR::Read (.probe.cdrom)" );
// write out data for hardware status check
foreach (map drive, cd_drives,
``{
HwStatus::Set (drive["unique_key"]:"", `yes);
});
}
else
{
y2milestone( "before SCR::Read (.probe.cdrom)" );
foreach(map e, (list<map>) SCR::Read (.probe.cdrom),
``{
map conf = (map) SCR::Read(.probe.status, e["unique_key"]:"");
y2milestone( "ProbeCDROMs conf:%1", conf );
y2milestone( "ProbeCDROMs cd:%1", e );
if( conf["available"]:`no != `no )
{
cd_drives = add( cd_drives, e );
}
});
if ((cd_drives == nil) || (size (cd_drives) == 0))
{
cd_drives = [ $["dev_name":"/dev/cdrom"] ];
}
}
string boot_device = (string) SCR::Read (.etc.install_inf.Cdrom);
if (boot_device == nil) boot_device = "";
if( boot_device != "" )
{
y2milestone( "ProbeCDROMs cddrives:%1", cd_drives );
y2milestone( "ProbeCDROMs boot_device:%1", boot_device );
if( search( boot_device, "/dev/" ) != 0 )
boot_device = "/dev/" + boot_device;
list tmp = filter( map e, cd_drives, ``(e["dev_name"]:""==boot_device));
if( size(tmp)>0 )
{
cd_drives = filter( map e, cd_drives, ``(e["dev_name"]:""!=boot_device));
cd_drives = (list<map>)merge( tmp, cd_drives );
}
y2milestone( "ProbeCDROMs cddrives:%1", cd_drives );
}
y2milestone( "ProbeCDROMs cddrives:%1", cd_drives );
cd_drives = AddNormalLinknames( cd_drives );
cd_drives = maplist( map drive, cd_drives,
``{
drive["udev_links"] = [ substring(drive["linkname"]:"",5) ];
return( drive );
});
cd_drives = AddAlternateLinks( cd_drives );
}
y2milestone ("ProbeCDROMs (%1)", cd_drives);
return( size(cd_drives)>0 );
}
global list<map> cddrives()
{
if( cd_drives==nil )
ProbeCDROMs();
return( cd_drives );
}
global define map GetCdromEntry( string device )
``{
map ret = $[];
y2milestone( "GetCdromEntry device %1", device );
ret = find(map e, cd_drives, ``(e["dev_orig"]:(e["dev_name"]:"")==device));
if( ret == nil )
{
ret = $[];
}
y2milestone( "GetCdromEntry ret %1", ret );
return( ret );
}
/*
* FloppyReady ()
* @return floppy media status
* determines if a media is present.
* @see: FloppyPresent
* @see: FloppyDevice
*/
global define boolean FloppyReady()
``{
if( floppy_present==nil )
{
floppy_present = false;
floppy_drives = [];
if( Stage::initial() )
{
y2milestone( "before .probe.floppy" );
floppy_drives = (list<map>) SCR::Read(.probe.floppy);
y2milestone( "after .probe.floppy" );
// write out data for hardware status check
foreach (map drive, floppy_drives,
``{
HwStatus::Set (drive["unique_key"]:"", `yes);
});
}
else
{
y2milestone( "before .probe.floppy.manual" );
floppy_drives = (list<map>) SCR::Read(.probe.floppy.manual);
y2milestone( "after .probe.floppy.manual" );
}
floppy_device = floppy_drives[0,"dev_name"]:"";
if( (floppy_device != "") || Mode::test ())
{
floppy_present = true;
}
}
y2milestone( "FloppyDrives %1", floppy_drives );
return( size(floppy_drives[0]:$[])>0 &&
!haskey(floppy_drives[0]:$[],"notready") );
}
// loop over floppy drives to find IDE ZIPs
// return map of $[ "device" : $[target], ...]
define map<string,map> findZIPs ()
``{
map<string,map> zips = $[];
FloppyReady();
foreach (map disk, floppy_drives,
``{
if (disk["zip"]:false)
{
map target = $[];
string dname = "";
string ddevice = disk["dev_name"]:"?";
string dinfo = disk["vendor"]:"";
target["vendor"] = dinfo;
if (dinfo != "") dname = dname + dinfo + "-";
dinfo = disk["device"]:"";
target["model"] = dinfo;
if (dinfo != "") dname = dname + dinfo;
target["name"] = dname;
target["partitions"] = [];
zips[ddevice] = target;
}
});
y2milestone( "zips %1", zips );
return zips;
}
global define map<string,map> ZipDrives()
{
if( zip_drives==nil )
{
zip_drives = findZIPs();
}
return( zip_drives );
}
/*
* Fake probing for storage devices in test or demo mode -
* read ready-made target maps from file.
*
* @return map TargetMap
*/
map<string, map> fakeProbe()
{
string fake_map_file = ( Mode::test () ? "demo_target_map.ycp" : "test_target_map.ycp" );
y2milestone( "%1 mode - using fake target map from %2",
Mode::test () ? "Demo" : "Test", fake_map_file );
map<string, map> target_map = (map<string, map>) SCR::Read( .target.yast2, fake_map_file );
y2debug( "Fake target map: %1", target_map );
return target_map;
}
global boolean FloppyPresent()
{
if( floppy_present==nil )
FloppyReady();
return( floppy_present );
}
global string FloppyDevice()
{
if( floppy_device==nil )
FloppyReady();
return( floppy_device );
}
global list<map> FloppyDrives()
{
if( floppy_drives==nil )
FloppyReady();
return( floppy_drives );
}
/*
* Probe for storage devices attached to storage controllers
* Should be called after StorageControllers::Initialize
* @return map TargetMap
*/
map<string, map> localProbe()
{
map<string, map> targets = $[];
if( Mode::test () )
{
return fakeProbe();
}
FloppyReady();
// do the probing. disks are sorted the way found in /sys/block.
list<map> all_disks = (list<map>) SCR::Read(.probe.disk_raid);
y2milestone("localProbe: disks probed all_disks:%1", all_disks);
if( size(all_disks)==0 )
{
// somehow, we couldn't find any harddisks for installation.
// This is a fatal error, we can't do anything about it
return targets;
}
// loop over all_disks, constructing targets map
zip_drives = $[];
foreach (map disk, filter(map e, all_disks, ``(!isempty(e["dev_name"]:""))), {
y2milestone( "localProbe: disk %1", disk );
map<string, any> target = $[];
boolean no_disk = false;
boolean notready = disk["notready"]:false &&
disk["device"]:"" != "DASD";
boolean is_zip = (notready || disk["zip"]:false);
if( search( disk["dev_name"]:"", "/dev/dm-" )==0 &&
size( disk["bios_id"]:"")==0 &&
disk["resource","disk_log_geo",0,"cylinders"]:0==0 )
no_disk = true;
if( disk["hotpluggable"]:false )
target["hotpluggable"] = true;
if( disk["softraiddisk"]:false )
target["softraiddisk"] = true;
map<string, any> res_fc = disk["resource", "fc", 0]:$[];
if (res_fc != $[])
target["fc"] = res_fc;
y2milestone( "localProbe: is_zip:%1 notready:%2 softraid:%3 no_disk:%4",
is_zip, notready, disk["softraiddisk"]:false, no_disk );
if( no_disk )
continue;
// write out data for hardware status check
HwStatus::Set (disk["unique_key"]:"", `yes);
target["unique"] = disk["unique_key"]:"";
target["bus"] = disk["bus"]:"?";
// needed also later as key
string ddevice = disk["dev_name"]:"";
target["device"] = ddevice;
if( size(disk["bios_id"]:"")>0 )
target["bios_id"] = disk["bios_id"]:"";
y2milestone("localProbe: disk: %1", ddevice );
// ------------------------------------------------------
// construct full target name
if( size(disk["vendor"]:"")>0 )
target["vendor"] = disk["vendor"]:"";
if( size(disk["device"]:"")>0 )
target["model"] = disk["device"]:"";
if( size(disk["driver"]:"")>0 )
target["driver"] = disk["driver"]:"";
if( size(disk["driver_module"]:"")>0 )
target["driver_module"] = disk["driver_module"]:"";
if( size(disk["parent_unique_key"]:"")>0 )
{
map tmp = (map) SCR::Read(.probe.uniqueid, disk["parent_unique_key"]:"" );
y2milestone( "localProbe: parent %1", tmp );
map m1 = find( map e, tmp["drivers"]:[], ``(e["active"]:false));
y2milestone( "localProbe: m1 %1", m1 );
if( m1 != nil && size(m1["modules"]:[])>0 )
target["modules"] = (list) merge( target["modules"]:[],
maplist( list l, m1["modules"]:[],
``{return(l[0]:"");}));
map m2 = find( map e, disk["drivers"]:[], ``(e["active"]:false));
y2milestone( "localProbe: m2 %1", m2 );
if( m2 != nil && size(m2["modules"]:[])>0 )
target["modules"] = (list) merge( target["modules"]:[],
maplist( list l, m2["modules"]:[],
``{return(l[0]:"");}));
y2milestone( "localProbe: modules %1", target["modules"]:[] );
}
// ----------------------------------------------------------
// Partitions
target["partitions"] = [];
// add constructed target map to list of all targets
if( (!notready||search(ddevice,"/dev/dasd")==0) && (size(target)>0) )
{
if (is_zip)
{
zip_drives[ddevice] = target;
}
else
{
targets[ddevice] = target;
if( notready && search(ddevice,"/dev/dasd")==0 )
{
targets[ddevice,"dasdfmt"] = true;
}
}
}
y2milestone( "localProbe: disk %1 tg: %2", ddevice,
targets[ddevice]:$[] );
}); // foreach (disk)
zip_drives = (map<string,map>)union( zip_drives, findZIPs() );
foreach(string k, any e, zip_drives,
``{
floppy_drives = filter(map f, floppy_drives, ``(f["dev_name"]:""!=k));
});
y2milestone( "localProbe: FloppyDrives %1", FloppyDrives() );
y2milestone( "localProbe: ZipDrives %1", ZipDrives() );
return targets;
}
/*
* Probe ()
* probe for target devices, return map
* used like proposal-api
*
* @param boolean force_reset
*/
global map<string, map> Probe(boolean force_reset)
{
map<string, map> target = $[];
y2milestone( "Probe force_reset:%1 disks_valid:%2", force_reset, disks_valid );
if( force_reset )
targetMapSize = 0;
if( targetMapSize==0 && disks_valid )
{
target = (map<string, map>) localProbe();
targetMapSize = size(target);
ProbeCDROMs();
}
return target;
}
/*
* Initialize
*/
global define void FullProbe()
``{
FloppyReady(); // probe floppy
ProbeCDROMs(); // probe CDs
}
global define void InitDone()
``{
disks_valid = true;
y2milestone( "called disks_valid %1", disks_valid );
}
/*
* Constructor
*/
global define void StorageDevices()
``{
if( !Stage::initial() && !Mode::config() )
{
disks_valid = true;
}
}
}
ACC SHELL 2018