home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
StorageDevices.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
20KB
|
811 lines
/**
* 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 33312 2006-10-10 10:50:56Z fehr $
*
* Author:
* Klaus Kaempf <kkaempf@suse.de> (initial)
*/
{
module "StorageDevices";
import "Mode";
import "Stage";
import "String";
import "HwStatus";
import "Partitions";
import "Installation";
import "Kernel";
import "AsciiFile";
import "Arch";
import "Report";
textdomain "storage";
boolean disks_valid = false;
boolean raid_shown = false;
/**
* @return map of $["device": $[..target..], ...] for each ZIP drive
*
*/
global map<string,any> ZipDrives = $[];
/**
* @return list of maps: all kinds of removable media, esp. ZIP drives
* @see: FloppyDevice
* @see: FloppyReady
*/
global list<map> FloppyDrives = [];
/**
* @return true if floppy drive present
* @see: FloppyDevice
* @see: FloppyReady
*/
global boolean FloppyPresent = false;
/**
* @return Device name of floppy, empty string if no floppy present
* @see: FloppyPresent
* @see: FloppyReady
*/
global string FloppyDevice = ""; // set in constructor
//---------------------------------------------------------------
/**
* list of cd-rom drives
*/
global list<map> cddrives = [];
global list<string> TypeNames = [ "cdrom", "dvd", "cdrecorder", "dvdrecorder",
"dvdram" ];
// storage for localProbe, see Probe()
map targetMap = $[];
//---------------------------------------------------------------
//---------------------------------------------------------------
// CD Recorders and CD-ROM links
list idecdrws = []; // list of IDE CD-RW drivers for ide-scsi
list scsicds = []; // list of SCSI CDs
global define integer TypeNameIndex( string cdtype )
``{
integer idx = 0;
integer n = 0;
foreach( string t, StorageDevices::TypeNames,
``{
if( substring( cdtype, 0, size(t)) == t )
{
idx = n;
}
n = n + 1;
});
return( idx );
}
/**
*
#include "storage/routines.ycp";
*/
global define string GetDeviceName( string disk, any partition )
``{
string ret = disk;
if( is( partition, integer ) )
{
if( search( disk, "/dev/cciss/" )==0 ||
search( disk, "/dev/ida/" )==0 ||
search( disk, "/dev/ataraid/" )==0 ||
search( disk, "/dev/etherd/" )==0 ||
search( disk, "/dev/rd/" )==0 )
{
ret = ret + "p";
}
ret = ret + sformat( "%1", partition );
}
else if( size( (string)partition )>0 )
{
ret = ret + "/" + (string)partition;
}
return( ret );
};
global define 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 );
}
global define 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( cddrives );
}
/**
* ProbeCDROMs()
*
* Initialize cddrives
*
*/
global define boolean ProbeCDROMs()
``{
if (size (cddrives) == 0)
{
if (Stage::initial () || Stage::cont ())
{
cddrives = (list<map>) SCR::Read (.probe.cdrom);
// write out data for hardware status check
foreach (map drive, cddrives,
``{
HwStatus::Set (drive["unique_key"]:"", `yes);
});
}
else
{
cddrives = [];
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 )
{
cddrives = add( cddrives, e );
}
});
if ((cddrives == nil) || (size (cddrives) == 0))
{
cddrives = [ $["dev_name":"/dev/cdrom"] ];
}
}
// sort out idecdrws and scsicds
foreach (map e, cddrives,
``{
if( (e["cdr"]:false || e["cdrw"]:false || e["dvdr"]:false ) &&
e["bus"]:"" == "IDE" )
{
y2milestone ("IDE CD-RW %1", idecdrws );
}
if( e["bus"]:"" == "SCSI" )
{
scsicds = add (scsicds, e["dev_name"]:"");
}
});
string boot_device = (string) SCR::Read (.etc.install_inf.Cdrom);
if (boot_device == nil) boot_device = "";
if( boot_device != "" )
{
y2milestone( "ProbeCDROMs cddrives:%1", cddrives );
y2milestone( "ProbeCDROMs boot_device:%1", boot_device );
if( search( boot_device, "/dev/" ) != 0 )
boot_device = "/dev/" + boot_device;
list tmp = filter( map e, cddrives, ``(e["dev_name"]:""==boot_device));
if( size(tmp)>0 )
{
cddrives = filter( map e, cddrives, ``(e["dev_name"]:""!=boot_device));
cddrives = (list<map>)merge( tmp, cddrives );
}
y2milestone( "ProbeCDROMs cddrives:%1", cddrives );
}
y2milestone( "ProbeCDROMs cddrives:%1", cddrives );
cddrives = AddNormalLinknames( cddrives );
cddrives = maplist( map drive, cddrives,
``{
drive["udev_links"] = [ substring(drive["linkname"]:"",5) ];
return( drive );
});
cddrives = AddAlternateLinks( cddrives );
}
y2milestone ("ProbeCDROMs (%1)", cddrives);
return (size (cddrives) > 0);
}
global define map GetCdromEntry( string device )
``{
map ret = $[];
y2milestone( "GetCdromEntry device %1", device );
ret = find(map e, cddrives, ``(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( Stage::initial () )
{
y2milestone( "before .probe.floppy" );
FloppyDrives = (list<map>) SCR::Read(.probe.floppy);
y2milestone( "after .probe.floppy" );
if( !FloppyPresent ) // only once !
{
// write out data for hardware status check
foreach (map drive, FloppyDrives,
``{
HwStatus::Set (drive["unique_key"]:"", `yes);
});
}
}
else
{
FloppyDrives = (list<map>) SCR::Read(.probe.floppy.manual);
}
map floppy_data = FloppyDrives[0]:$[];
FloppyDevice = floppy_data["dev_name"]:"";
if( (FloppyDevice != "") || Mode::test ())
{
FloppyPresent = true;
}
y2milestone( "FloppyDrives %1", FloppyDrives );
return( size(floppy_data)>0 && !haskey(floppy_data,"notready") );
}
// loop over floppy drives to find IDE ZIPs
// return map of $[ "device" : $[target], ...]
define map findZIPs ()
``{
map zips = $[];
foreach (map disk, FloppyDrives,
``{
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;
}
/*
* Fake probing for storage devices in test or demo mode -
* read ready-made target maps from file.
*
* @return map TargetMap
*/
global define 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 target_map = (map) SCR::Read( .target.yast2, fake_map_file );
y2debug( "Fake target map: %1", target_map );
return target_map;
} // fakeProbe()
/*
* Probe for storage devices attached to storage controllers
* Should be called after StorageControllers::Initialize
* @return map TargetMap
*/
define map localProbe()
``{
map targets = $[];
if( Mode::test () )
{
return fakeProbe();
}
// do the probing
list<map> all_disks = (list<map>) SCR::Read(.probe.disk);
y2milestone( "localProbe: disks probed");
y2milestone( "localProbe: 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
integer ide_count = 0;
integer scsi_count = 0;
integer raid_count = 0;
integer other_count = 0;
string fake_raid = "";
map target = $[];
foreach (map disk, filter(map e,all_disks,``(size(e["dev_name"]:"")>0)),
``{
target = $[];
y2milestone( "localProbe: disk %1", disk );
boolean notready = disk["notready"]:false &&
disk["device"]:"" != "DASD";
boolean is_zip = (notready || disk["zip"]:false);
if( disk["softraiddisk"]:false )
{
target["softraiddisk"] = true;
if( size(fake_raid)>0 )
{
fake_raid = fake_raid + " ";
}
fake_raid = fake_raid + disk["dev_name"]:"";
y2milestone( "localProbe: fake_raid %1", fake_raid );
}
y2milestone( "localProbe: is_zip %1 notready:%2 softraid %3",
is_zip, notready, disk["softraiddisk"]:false );
string bus = disk["bus"]:"?";
string dname = "";
integer i = 0;
// write out data for hardware status check
HwStatus::Set (disk["unique_key"]:"", `yes);
target["unique"] = disk["unique_key"]:"";
// ------------------------------------------------------
// check bus, count disks per bus
if (bus == "IDE")
{
ide_count = ide_count + 1;
i = ide_count;
}
else if (bus == "SCSI")
{
scsi_count = scsi_count + 1;
i = scsi_count;
}
else if (bus == "RAID")
{
raid_count = raid_count + 1;
i = raid_count;
}
else
{
other_count = other_count + 1;
i = other_count;
}
target["bus"] = bus;
// ------------------------------------------------------
// construct disk name for user
dname = ""+i+". ";
if( bus != "None" )
{
dname = dname + bus;
}
else
{
dname = dname + "Disk";
}
dname = dname + ", ";
target["dname"] = dname;
// 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 );
// call fdisk agent to get size information
// ------------------------------------------------------
// 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)
ZipDrives[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)
SCR::UnmountAgent(.disk);
ZipDrives = (map<string,any>)union (ZipDrives, findZIPs ());
foreach(string k, any e, ZipDrives,
``{
FloppyDrives = filter(map f, FloppyDrives, ``(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 define map Probe(boolean force_reset)
``{
y2milestone( "Probe force_reset:%1 disks_valid:%2", force_reset, disks_valid );
if( force_reset )
targetMap = $[];
if( targetMap==$[] && disks_valid )
{
targetMap = localProbe();
ProbeCDROMs();
}
return targetMap;
}
/*
* symlink_cdrom
*
* make proper symlink for cd-rom/dvd/cdrecorder drive
*
* @param map cdinfo result of .probe.cdrom
*/
// count the links for "pseudo" devices
define void symlink_cdrom( map cdinfo )
``{
y2milestone( "device %1 link %2", cdinfo["dev_name"]:"",
cdinfo["linkname"]:"" );
if( size(cdinfo["linkname"]:"")>0 && size(cdinfo["dev_name"]:"")>0 )
{
string link = cdinfo["linkname"]:"";
string device = cdinfo["dev_name"]:"";
if( Installation::scr_destdir != "/" )
{
link = Installation::scr_destdir + link;
}
y2milestone( "pathname %1 links to %2", link, device );
SCR::Execute (.target.symlink, substring(device,5), link);
}
return;
}
define string UdevBusEntry( string bus )
``{
return( sformat( "BUS=\"%1\",", bus ));
}
define string UdevPlaceEntry( string place )
``{
return( sformat( "ID=\"%1\",", place ));
}
global define string UdevSylinkEntry( list<string> links )
``{
return( sformat( "SYMLINK+=\"%1\"", mergestring( links, " ") ));
}
global define string UdevCdromPath()
``{
string pathname = "/etc/udev/rules.d/65-cdrom.rules";
if( Installation::scr_destdir != "/" )
{
pathname = Installation::scr_destdir + pathname;
}
return( pathname );
}
global define map<integer,map> GetSysfsCdrom()
``{
map<integer,map> file = $[];
AsciiFile::SetComment( file, "^[ \t]*#" );
AsciiFile::SetDelimiter( file, " " );
AsciiFile::ReadFile( file, UdevCdromPath() );
return( file );
}
global define string UdevPathEntry( map drive )
{
string ret = "";
list<string> l = drive["dev_names"]:[];
y2milestone( "UdevPathEntry l:%1", l );
l = filter( string n, l, ``(search(n,"by-path")!=nil));
y2milestone( "UdevPathEntry l:%1", l );
ret = l[0]:"";
if( size(ret)>0 )
{
ret = substring( ret, search(ret,"by-path")+8 );
ret = "ENV{ID_PATH}==\""+ret+"\"";
}
y2milestone( "UdevPathEntry ret:%1", ret );
return( ret );
}
global define string MakeUdevRulesLine( map drive )
``{
y2milestone( "MakeUdevRulesLine %1", drive );
string line = "";
string bpath = UdevPathEntry(drive);
y2milestone( "MakeUdevRulesLine path:%1", bpath );
if( size(bpath)>0 )
{
line = sformat( "SUBSYSTEM==\"block\", %1, SYSFS{removable}==\"1\", %2",
bpath, UdevSylinkEntry(drive["udev_links"]:[]) );
}
else
{
y2error( "No udev path id found for %1", drive );
}
y2milestone( "MakeUdevRulesLine ret %1", line );
return( line );
}
global define list<integer> FindUdevRulesLine( map sysfs, map entry )
``{
list<integer> a = AsciiFile::FindLineField( sysfs, 1, UdevPathEntry(entry)+"," );
y2milestone( "FindUdevRulesLine entry %1", entry );
y2milestone( "FindUdevRulesLine %1", a );
return( a );
}
/*
* Symlink (/mnt)/dev/cdromX to all real cdrom devices (/dev/sr0, etc.)
* create type dependant links (i.e. /dev/dvd for a DVD drive
* but make sure that at least /dev/cdrom exists.
*/
global define void MakeCDLinks ()
``{
if( ProbeCDROMs() )
{
map udev_file = GetSysfsCdrom();
if( AsciiFile::NumLines( udev_file )==0 )
{
AsciiFile::AppendLine( udev_file, [ "# cdrom links generated by YaST2" ] );
AsciiFile::AppendLine( udev_file, [ "# " ] );
foreach( map drive, cddrives,
``{
string line = MakeUdevRulesLine(drive);
if( size(line)>0 )
AsciiFile::AppendLine( udev_file, [ line ]);
});
y2milestone( "MakeCDLinks %1", cddrives );
string dir = substring( UdevCdromPath(), 0, findlastof( UdevCdromPath(), "/" ) );
y2milestone( "MakeCDLinks dir %1", dir );
if( SCR::Read( .target.size, dir )<=0 )
SCR::Execute( .target.mkdir, dir );
AsciiFile::RewriteFile( udev_file, UdevCdromPath() );
}
}
return;
}
/*
* 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 () )
{
FullProbe ();
disks_valid = true;
}
return;
}
}