home *** CD-ROM | disk | FTP | other *** search
- /**
- * 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;
- }
- }
-