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 >
Text File  |  2006-11-29  |  20KB  |  811 lines

  1. /**
  2.  * File:
  3.  *    StorageDevices.ycp
  4.  *
  5.  * Module:
  6.  *    StorageDevices
  7.  *
  8.  * Depends:
  9.  *    StorageControllers
  10.  *
  11.  * Summary:
  12.  *    This module does all storage device related stuff:
  13.  *    - hard disk drives
  14.  *    - removable drives (ZIP)
  15.  *    - floppy devices
  16.  *
  17.  * $Id: StorageDevices.ycp 33312 2006-10-10 10:50:56Z fehr $
  18.  *
  19.  * Author:
  20.  *    Klaus Kaempf <kkaempf@suse.de> (initial)
  21.  */
  22. {
  23.     module "StorageDevices";
  24.  
  25.     import "Mode";
  26.     import "Stage";
  27.     import "String";
  28.     import "HwStatus";
  29.     import "Partitions";
  30.     import "Installation";
  31.     import "Kernel";
  32.     import "AsciiFile";
  33.  
  34.     import "Arch";
  35.     import "Report";
  36.  
  37.     textdomain "storage";
  38.  
  39.  
  40.  
  41.     boolean disks_valid = false;
  42.     boolean raid_shown = false;
  43.  
  44.     /**
  45.      * @return map of $["device": $[..target..], ...] for each ZIP drive
  46.      *
  47.      */
  48.     global map<string,any> ZipDrives = $[];
  49.  
  50.  
  51.     /**
  52.      * @return list of maps: all kinds of removable media, esp. ZIP drives
  53.      * @see: FloppyDevice
  54.      * @see: FloppyReady
  55.      */
  56.     global list<map> FloppyDrives = [];
  57.  
  58.  
  59.     /**
  60.      * @return true if floppy drive present
  61.      * @see: FloppyDevice
  62.      * @see: FloppyReady
  63.      */
  64.     global boolean FloppyPresent = false;
  65.  
  66.  
  67.     /**
  68.      * @return Device name of floppy, empty string if no floppy present
  69.      * @see: FloppyPresent
  70.      * @see: FloppyReady
  71.      */
  72.     global string FloppyDevice = "";    // set in constructor
  73.  
  74.  
  75.     //---------------------------------------------------------------
  76.  
  77.     /**
  78.      * list of cd-rom drives
  79.      */
  80.     global list<map> cddrives = [];
  81.  
  82.     global list<string> TypeNames = [ "cdrom", "dvd", "cdrecorder", "dvdrecorder",
  83.                       "dvdram" ];
  84.  
  85.     // storage for localProbe, see Probe()
  86.     map targetMap = $[];
  87.  
  88.     //---------------------------------------------------------------
  89.  
  90.  
  91. //---------------------------------------------------------------
  92. // CD Recorders and CD-ROM links
  93. list idecdrws = [];        // list of IDE CD-RW drivers for ide-scsi
  94. list scsicds = [];        // list of SCSI CDs
  95.  
  96. global define integer TypeNameIndex( string cdtype )
  97.     ``{
  98.     integer idx = 0;
  99.     integer n = 0;
  100.     foreach( string t, StorageDevices::TypeNames,
  101.     ``{
  102.     if( substring( cdtype, 0, size(t)) == t )
  103.         {
  104.         idx = n;
  105.         }
  106.     n = n + 1;
  107.     });
  108.     return( idx );
  109.     }
  110.  
  111.  
  112.  
  113.  
  114.   /**
  115.    *
  116.       #include "storage/routines.ycp";
  117.    */
  118. global define string GetDeviceName( string disk, any partition )
  119.     ``{
  120.       string ret = disk;
  121.  
  122.       if( is( partition, integer ) )
  123.       {
  124.         if( search( disk, "/dev/cciss/" )==0 ||
  125.             search( disk, "/dev/ida/" )==0 ||
  126.             search( disk, "/dev/ataraid/" )==0 ||
  127.           search( disk, "/dev/etherd/" )==0 ||
  128.             search( disk, "/dev/rd/" )==0 )
  129.             {
  130.             ret = ret + "p";
  131.             }
  132.         ret = ret + sformat( "%1", partition );
  133.       }
  134.       else if( size( (string)partition )>0 )
  135.           {
  136.         ret = ret + "/" + (string)partition;
  137.       }
  138.       return( ret );
  139.   };
  140.  
  141. global define list<map> AddNormalLinknames( list<map> cddrives )
  142.     ``{
  143.     map linknum = $[ "cdrom"       : 0,
  144.                      "cdrecorder"  : 0,
  145.              "dvd"         : 0,
  146.              "dvdrecorder" : 0,
  147.              "dvdram"      : 0 ];
  148.  
  149.     cddrives = maplist( map e, cddrives,
  150.     ``{
  151.     // first, determine the drive type and make a linkname guess
  152.     string cddevice = e["dev_name"]:"";
  153.  
  154.     string linkname = "cdrom";
  155.     if( e["dvdram"]:false )
  156.         {
  157.         linkname = "dvdram";
  158.         }
  159.     else if( e["dvdr"]:false )
  160.         {
  161.         linkname = "dvdrecorder";
  162.         }
  163.     else if( e["cdr"]:false || e["cdrw"]:false )
  164.         {
  165.         linkname = "cdrecorder";
  166.         }
  167.     else if( e["dvd"]:false )
  168.         {
  169.         linkname = "dvd";
  170.         }
  171.  
  172.     // now check the number (for /dev/cdrom, /dev/cdrom2, ...)
  173.     integer number = linknum[linkname]:0;
  174.     linknum[linkname] = number + 1;
  175.  
  176.     string devname = "/dev/" + linkname;
  177.  
  178.     if( number > 0)
  179.         devname = sformat( "%1%2", devname, number+1 );
  180.  
  181.     e["linkname"] = devname;
  182.     return( e );
  183.     });
  184.     y2milestone( "AddNormalLinknames linknum %1", linknum );
  185.     return( cddrives );
  186.     }
  187.  
  188. global define list<map> AddAlternateLinks( list<map> cddrives )
  189.     ``{
  190.     list<string> llist = [];
  191.     foreach( map cd, cddrives,
  192.     ``{
  193.     llist = (list<string>)union( llist, cd["udev_links"]:[] );
  194.     });
  195.     y2milestone( "AddAlternateLinks llist %1", llist );
  196.  
  197.     if( !contains( llist, "cdrom" ) && size(cddrives)>0 )
  198.     {
  199.     cddrives[0,"udev_links"] = add( cddrives[0,"udev_links"]:[], "cdrom" );
  200.     y2milestone( "AddAlternateLinks cdrom %1", cddrives[0]:$[] );
  201.     }
  202.     integer i = 0;
  203.     if( !contains( llist, "dvd" ))
  204.     {
  205.     while( i<size(cddrives) && !cddrives[i,"dvd"]:false )
  206.         {
  207.         i = i + 1;
  208.         }
  209.     if( i<size(cddrives) )
  210.         {
  211.         cddrives[i,"udev_links"] = add( cddrives[i,"udev_links"]:[], "dvd" );
  212.         y2milestone( "AddAlternateLinks dvd %1", cddrives[i]:$[] );
  213.         }
  214.     }
  215.     if( !contains( llist, "cdrecorder" ))
  216.     {
  217.     i = 0;
  218.     while( i<size(cddrives) && !cddrives[i,"cdrw"]:false )
  219.         {
  220.         i = i + 1;
  221.         }
  222.     if( i<size(cddrives) )
  223.         {
  224.         cddrives[i,"udev_links"] = add( cddrives[i,"udev_links"]:[], "cdrecorder" );
  225.         y2milestone( "AddAlternateLinks cdrecorder %1", cddrives[i]:$[] );
  226.         }
  227.     }
  228.     y2milestone( "AddAlternateLinks ret %1", cddrives );
  229.     return( cddrives );
  230.     }
  231.  
  232. /**
  233.   * ProbeCDROMs()
  234.   *
  235.   * Initialize cddrives
  236.   *
  237.   */
  238. global define boolean ProbeCDROMs()
  239.     ``{
  240.     if (size (cddrives) == 0)
  241.     {
  242.     if (Stage::initial () || Stage::cont ())
  243.         {
  244.         cddrives = (list<map>) SCR::Read (.probe.cdrom);
  245.         // write out data for hardware status check
  246.         foreach (map drive, cddrives,
  247.         ``{
  248.         HwStatus::Set (drive["unique_key"]:"", `yes);
  249.         });
  250.         }
  251.     else
  252.         {
  253.         cddrives = [];
  254.         foreach(map e, (list<map>) SCR::Read (.probe.cdrom),
  255.         ``{
  256.         map conf = (map) SCR::Read(.probe.status, e["unique_key"]:"");
  257.         y2milestone( "ProbeCDROMs conf:%1", conf );
  258.         y2milestone( "ProbeCDROMs cd:%1", e );
  259.         if( conf["available"]:`no != `no )
  260.             {
  261.             cddrives = add( cddrives, e );
  262.             }
  263.         });
  264.  
  265.         if ((cddrives == nil) || (size (cddrives) == 0))
  266.         {
  267.         cddrives = [ $["dev_name":"/dev/cdrom"] ];
  268.         }
  269.         }
  270.  
  271.     // sort out idecdrws and scsicds
  272.     foreach (map e, cddrives,
  273.         ``{
  274.         if( (e["cdr"]:false || e["cdrw"]:false || e["dvdr"]:false ) &&
  275.         e["bus"]:"" == "IDE" )
  276.         {
  277.         y2milestone ("IDE CD-RW %1", idecdrws );
  278.         }
  279.         if( e["bus"]:"" == "SCSI" )
  280.         {
  281.         scsicds = add (scsicds, e["dev_name"]:"");
  282.         }
  283.         });
  284.  
  285.     string boot_device = (string) SCR::Read (.etc.install_inf.Cdrom);
  286.     if (boot_device == nil) boot_device = "";
  287.  
  288.     if( boot_device != "" )
  289.         {
  290.         y2milestone( "ProbeCDROMs cddrives:%1", cddrives );
  291.         y2milestone( "ProbeCDROMs boot_device:%1", boot_device );
  292.  
  293.         if( search( boot_device, "/dev/" ) != 0 )
  294.         boot_device = "/dev/" + boot_device;
  295.         list tmp = filter( map e, cddrives, ``(e["dev_name"]:""==boot_device));
  296.         if( size(tmp)>0 )
  297.         {
  298.         cddrives = filter( map e, cddrives, ``(e["dev_name"]:""!=boot_device));
  299.         cddrives = (list<map>)merge( tmp, cddrives );
  300.         }
  301.  
  302.         y2milestone( "ProbeCDROMs cddrives:%1", cddrives );
  303.         }
  304.  
  305.     y2milestone( "ProbeCDROMs cddrives:%1", cddrives );
  306.     cddrives = AddNormalLinknames( cddrives );
  307.     cddrives = maplist( map drive, cddrives,
  308.         ``{
  309.         drive["udev_links"] = [ substring(drive["linkname"]:"",5) ];
  310.         return( drive );
  311.         });
  312.     cddrives = AddAlternateLinks( cddrives );
  313.     }
  314.     y2milestone ("ProbeCDROMs (%1)", cddrives);
  315.     return (size (cddrives) > 0);
  316.     }
  317.  
  318. global define map GetCdromEntry( string device )
  319.     ``{
  320.     map ret = $[];
  321.     y2milestone( "GetCdromEntry device %1", device );
  322.     ret = find(map e, cddrives, ``(e["dev_orig"]:(e["dev_name"]:"") == device));
  323.     if( ret == nil )
  324.     {
  325.     ret = $[];
  326.     }
  327.     y2milestone( "GetCdromEntry ret %1", ret );
  328.     return( ret );
  329.     }
  330.  
  331. /*
  332.  * FloppyReady ()
  333.  * @return floppy media status
  334.  * determines if a media is present.
  335.  * @see: FloppyPresent
  336.  * @see: FloppyDevice
  337.  */
  338.  
  339. global define boolean FloppyReady ()
  340.     ``{
  341.     if( Stage::initial () )
  342.     {
  343.     y2milestone( "before .probe.floppy" );
  344.     FloppyDrives = (list<map>) SCR::Read(.probe.floppy);
  345.     y2milestone( "after .probe.floppy" );
  346.  
  347.     if( !FloppyPresent )    // only once !
  348.         {
  349.         // write out data for hardware status check
  350.         foreach (map drive, FloppyDrives,
  351.         ``{
  352.         HwStatus::Set (drive["unique_key"]:"", `yes);
  353.         });
  354.         }
  355.     }
  356.     else
  357.     {
  358.     FloppyDrives = (list<map>) SCR::Read(.probe.floppy.manual);
  359.     }
  360.  
  361.     map floppy_data = FloppyDrives[0]:$[];
  362.     FloppyDevice = floppy_data["dev_name"]:"";
  363.     if( (FloppyDevice != "") || Mode::test ())
  364.     {
  365.     FloppyPresent = true;
  366.     }
  367.     y2milestone( "FloppyDrives %1", FloppyDrives );
  368.     return( size(floppy_data)>0 && !haskey(floppy_data,"notready") );
  369.     }
  370.  
  371.  
  372. // loop over floppy drives to find IDE ZIPs
  373. // return map of $[ "device" : $[target], ...]
  374.  
  375. define map findZIPs ()
  376.     ``{
  377.     map zips = $[];
  378.     foreach (map disk, FloppyDrives,
  379.     ``{
  380.     if (disk["zip"]:false)
  381.         {
  382.         map target = $[];
  383.         string dname = "";
  384.  
  385.         string ddevice = disk["dev_name"]:"?";
  386.         string dinfo = disk["vendor"]:"";
  387.  
  388.         target["vendor"] = dinfo;
  389.         if (dinfo != "") dname = dname + dinfo + "-";
  390.  
  391.         dinfo = disk["device"]:"";
  392.         target["model"] = dinfo;
  393.  
  394.         if (dinfo != "") dname = dname + dinfo;
  395.         target["name"] = dname;
  396.         target["partitions"] = [];
  397.  
  398.         zips[ddevice] = target;
  399.         }
  400.     });
  401.     y2milestone( "zips %1", zips );
  402.     return zips;
  403.     }
  404.  
  405.  
  406. /*
  407.  * Fake probing for storage devices in test or demo mode -
  408.  * read ready-made target maps from file.
  409.  *
  410.  * @return    map    TargetMap
  411.  */
  412.  
  413. global define map fakeProbe ()
  414.     ``{
  415.     string fake_map_file = ( Mode::test () ? "demo_target_map.ycp" : "test_target_map.ycp" );
  416.  
  417.     y2milestone( "%1 mode - using fake target map from %2",
  418.                  Mode::test () ? "Demo" : "Test", fake_map_file );
  419.  
  420.     map target_map = (map) SCR::Read( .target.yast2, fake_map_file );
  421.  
  422.     y2debug( "Fake target map: %1", target_map );
  423.  
  424.     return target_map;
  425.     } // fakeProbe()
  426.  
  427.  
  428. /*
  429.  * Probe for storage devices attached to storage controllers
  430.  * Should be called after StorageControllers::Initialize
  431.  * @return    map    TargetMap
  432.  */
  433.  
  434. define map localProbe()
  435.     ``{
  436.     map targets = $[];
  437.     if( Mode::test () )
  438.     {
  439.     return fakeProbe();
  440.     }
  441.     // do the probing
  442.     list<map> all_disks = (list<map>) SCR::Read(.probe.disk);
  443.  
  444.     y2milestone( "localProbe: disks probed");
  445.     y2milestone( "localProbe: all_disks %1", all_disks );
  446.  
  447.     if( size(all_disks)==0 )
  448.     {
  449.     // somehow, we couldn't find any harddisks for installation.
  450.     // This is a fatal error, we can't do anything about it
  451.     return targets;
  452.     }
  453.  
  454.     // loop over all_disks, constructing targets map
  455.  
  456.     integer ide_count = 0;
  457.     integer scsi_count = 0;
  458.     integer raid_count = 0;
  459.     integer other_count = 0;
  460.     string fake_raid = "";
  461.     map target = $[];
  462.  
  463.     foreach (map disk, filter(map e,all_disks,``(size(e["dev_name"]:"")>0)),
  464.     ``{
  465.     target = $[];
  466.     y2milestone( "localProbe: disk %1", disk );
  467.  
  468.     boolean notready = disk["notready"]:false &&
  469.                        disk["device"]:"" != "DASD";
  470.     boolean is_zip = (notready || disk["zip"]:false);
  471.  
  472.     if( disk["softraiddisk"]:false )
  473.         {
  474.         target["softraiddisk"] = true;
  475.         if( size(fake_raid)>0 )
  476.         {
  477.         fake_raid = fake_raid + " ";
  478.         }
  479.         fake_raid = fake_raid + disk["dev_name"]:"";
  480.         y2milestone( "localProbe: fake_raid %1", fake_raid );
  481.         }
  482.  
  483.     y2milestone( "localProbe: is_zip %1 notready:%2 softraid %3",
  484.                  is_zip, notready, disk["softraiddisk"]:false );
  485.  
  486.     string bus = disk["bus"]:"?";
  487.     string dname = "";
  488.     integer i = 0;
  489.  
  490.     // write out data for hardware status check
  491.     HwStatus::Set (disk["unique_key"]:"", `yes);
  492.  
  493.     target["unique"] = disk["unique_key"]:"";
  494.  
  495.     // ------------------------------------------------------
  496.     // check bus, count disks per bus
  497.  
  498.     if (bus == "IDE")
  499.         {
  500.         ide_count = ide_count + 1;
  501.         i = ide_count;
  502.         }
  503.     else if (bus == "SCSI")
  504.         {
  505.         scsi_count = scsi_count + 1;
  506.         i = scsi_count;
  507.         }
  508.     else if (bus == "RAID")
  509.         {
  510.         raid_count = raid_count + 1;
  511.         i = raid_count;
  512.         }
  513.     else
  514.         {
  515.         other_count = other_count + 1;
  516.         i = other_count;
  517.         }
  518.  
  519.     target["bus"] = bus;
  520.  
  521.     // ------------------------------------------------------
  522.     // construct disk name for user
  523.  
  524.     dname = ""+i+". ";
  525.     if( bus != "None" )
  526.         {
  527.         dname = dname + bus;
  528.         }
  529.     else
  530.         {
  531.         dname = dname + "Disk";
  532.         }
  533.     dname = dname + ", ";
  534.     target["dname"] = dname;
  535.  
  536.     // needed also later as key
  537.     string ddevice = disk["dev_name"]:"";
  538.     target["device"] = ddevice;
  539.  
  540.     if( size(disk["bios_id"]:"")>0 )
  541.         {
  542.         target["bios_id"] = disk["bios_id"]:"";
  543.         }
  544.  
  545.     y2milestone("localProbe: disk: %1", ddevice );
  546.  
  547.     // call fdisk agent to get size information
  548.  
  549.     // ------------------------------------------------------
  550.     // construct full target name
  551.  
  552.     if( size(disk["vendor"]:"")>0 )
  553.         target["vendor"] = disk["vendor"]:"";
  554.  
  555.     if( size(disk["device"]:"")>0 )
  556.         target["model"] = disk["device"]:"";
  557.     if( size(disk["driver"]:"")>0 )
  558.         target["driver"] = disk["driver"]:"";
  559.     if( size(disk["driver_module"]:"")>0 )
  560.         target["driver_module"] = disk["driver_module"]:"";
  561.     if( size(disk["parent_unique_key"]:"")>0 )
  562.         {
  563.         map tmp = (map) SCR::Read(.probe.uniqueid, disk["parent_unique_key"]:"" );
  564.         y2milestone( "localProbe: parent %1", tmp );
  565.         map m1 = find( map e, tmp["drivers"]:[], ``(e["active"]:false));
  566.         y2milestone( "localProbe: m1 %1", m1 );
  567.         if( m1 != nil && size(m1["modules"]:[])>0 )
  568.         target["modules"] = (list) merge( target["modules"]:[],
  569.                               maplist( list l, m1["modules"]:[], 
  570.                                    ``{return(l[0]:"");}));
  571.         map m2 = find( map e, disk["drivers"]:[], ``(e["active"]:false));
  572.         y2milestone( "localProbe: m2 %1", m2 );
  573.         if( m2 != nil && size(m2["modules"]:[])>0 )
  574.         target["modules"] = (list) merge( target["modules"]:[],
  575.                               maplist( list l, m2["modules"]:[], 
  576.                                    ``{return(l[0]:"");}));
  577.         y2milestone( "localProbe: modules %1", target["modules"]:[] );
  578.         }
  579.  
  580.     // ----------------------------------------------------------
  581.     // Partitions
  582.  
  583.     target["partitions"] = [];
  584.  
  585.     // add constructed target map to list of all targets
  586.  
  587.     if( (!notready||search(ddevice,"/dev/dasd")==0) && (size(target)>0) )
  588.         {
  589.         if (is_zip)
  590.         ZipDrives[ddevice] = target;
  591.         else
  592.         {
  593.         targets[ddevice] = target;
  594.         if( notready && search(ddevice,"/dev/dasd")==0 )
  595.             {
  596.             targets[ddevice,"dasdfmt"] = true;
  597.             }
  598.         }
  599.         }
  600.     y2milestone( "localProbe: disk %1 tg: %2", ddevice,
  601.                  targets[ddevice]:$[] );
  602.     }); // foreach (disk)
  603.  
  604.     SCR::UnmountAgent(.disk);
  605.  
  606.     ZipDrives = (map<string,any>)union (ZipDrives, findZIPs ());
  607.  
  608.     foreach(string k, any e, ZipDrives,
  609.     ``{
  610.     FloppyDrives = filter(map f, FloppyDrives, ``(f["dev_name"]:""!=k));
  611.     });
  612.     y2milestone( "localProbe: FloppyDrives %1", FloppyDrives );
  613.     y2milestone( "localProbe: ZipDrives %1", ZipDrives );
  614.  
  615.     return targets;
  616.     }
  617.  
  618. /*
  619.  * Probe ()
  620.  * probe for target devices, return map
  621.  * used like proposal-api
  622.  *
  623.  * @param boolean force_reset
  624.  */
  625.  
  626. global define map Probe(boolean force_reset)
  627.     ``{
  628.     y2milestone( "Probe force_reset:%1 disks_valid:%2", force_reset, disks_valid );
  629.     if( force_reset )
  630.     targetMap = $[];
  631.  
  632.     if( targetMap==$[] && disks_valid )
  633.     {
  634.     targetMap = localProbe();
  635.     ProbeCDROMs();
  636.     }
  637.     return targetMap;
  638.     }
  639.  
  640.  
  641. /*
  642.  * symlink_cdrom
  643.  *
  644.  * make proper symlink for cd-rom/dvd/cdrecorder drive
  645.  *
  646.  * @param    map    cdinfo    result of .probe.cdrom
  647.  */
  648.  
  649. // count the links for "pseudo" devices
  650.  
  651. define void symlink_cdrom( map cdinfo )
  652.     ``{
  653.     y2milestone( "device %1 link %2", cdinfo["dev_name"]:"",
  654.                  cdinfo["linkname"]:"" );
  655.     if( size(cdinfo["linkname"]:"")>0 && size(cdinfo["dev_name"]:"")>0 )
  656.     {
  657.     string link = cdinfo["linkname"]:"";
  658.     string device = cdinfo["dev_name"]:"";
  659.  
  660.     if( Installation::scr_destdir != "/" )
  661.         {
  662.         link = Installation::scr_destdir + link;
  663.         }
  664.     y2milestone( "pathname %1 links to %2", link, device );
  665.     SCR::Execute (.target.symlink, substring(device,5), link);
  666.     }
  667.     return;
  668.     }
  669.  
  670. define string UdevBusEntry( string bus )
  671.     ``{
  672.     return( sformat( "BUS=\"%1\",", bus ));
  673.     }
  674.  
  675. define string UdevPlaceEntry( string place )
  676.     ``{
  677.     return( sformat( "ID=\"%1\",", place ));
  678.     }
  679.  
  680. global define string UdevSylinkEntry( list<string> links )
  681.     ``{
  682.     return( sformat( "SYMLINK+=\"%1\"", mergestring( links, " ") ));
  683.     }
  684.  
  685. global define string UdevCdromPath()
  686.     ``{
  687.     string pathname = "/etc/udev/rules.d/65-cdrom.rules";
  688.     if( Installation::scr_destdir != "/" )
  689.     {
  690.     pathname = Installation::scr_destdir + pathname;
  691.     }
  692.     return( pathname );
  693.     }
  694.  
  695. global define map<integer,map> GetSysfsCdrom()
  696.     ``{
  697.     map<integer,map> file = $[];
  698.     AsciiFile::SetComment( file, "^[ \t]*#" );
  699.     AsciiFile::SetDelimiter( file, " " );
  700.     AsciiFile::ReadFile( file, UdevCdromPath() );
  701.     return( file );
  702.     }
  703.  
  704. global define string UdevPathEntry( map drive )
  705.     {
  706.     string ret = "";
  707.     list<string> l = drive["dev_names"]:[];
  708.     y2milestone( "UdevPathEntry l:%1", l );
  709.     l = filter( string n, l, ``(search(n,"by-path")!=nil));
  710.     y2milestone( "UdevPathEntry l:%1", l );
  711.     ret = l[0]:"";
  712.     if( size(ret)>0 )
  713.     {
  714.     ret = substring( ret, search(ret,"by-path")+8 );
  715.     ret = "ENV{ID_PATH}==\""+ret+"\"";
  716.     }
  717.     y2milestone( "UdevPathEntry ret:%1", ret );
  718.     return( ret );
  719.     }
  720.  
  721. global define string MakeUdevRulesLine( map drive )
  722.     ``{
  723.     y2milestone( "MakeUdevRulesLine %1", drive );
  724.     string line = "";
  725.     string bpath = UdevPathEntry(drive);
  726.     y2milestone( "MakeUdevRulesLine path:%1", bpath );
  727.     if( size(bpath)>0 )
  728.     {
  729.     line = sformat( "SUBSYSTEM==\"block\", %1, SYSFS{removable}==\"1\", %2",
  730.             bpath, UdevSylinkEntry(drive["udev_links"]:[]) );
  731.     }
  732.     else
  733.     {
  734.     y2error( "No udev path id found for %1", drive );
  735.     }
  736.     y2milestone( "MakeUdevRulesLine ret %1", line );
  737.     return( line );
  738.     }
  739.  
  740. global define list<integer> FindUdevRulesLine( map sysfs, map entry )
  741.     ``{
  742.     list<integer> a = AsciiFile::FindLineField( sysfs, 1, UdevPathEntry(entry)+"," );
  743.     y2milestone( "FindUdevRulesLine entry %1", entry );
  744.     y2milestone( "FindUdevRulesLine %1", a );
  745.     return( a );
  746.     }
  747.  
  748. /*
  749.  * Symlink (/mnt)/dev/cdromX to all real cdrom devices (/dev/sr0, etc.)
  750.  * create type dependant links (i.e. /dev/dvd for a DVD drive
  751.  * but make sure that at least /dev/cdrom exists.
  752.  */
  753.  
  754. global define void MakeCDLinks ()
  755.     ``{
  756.     if( ProbeCDROMs() )
  757.     {
  758.     map udev_file = GetSysfsCdrom();
  759.     if( AsciiFile::NumLines( udev_file )==0 )
  760.         {
  761.         AsciiFile::AppendLine( udev_file, [ "# cdrom links generated by YaST2" ] );
  762.         AsciiFile::AppendLine( udev_file, [ "# " ] );
  763.  
  764.         foreach( map drive, cddrives,
  765.         ``{
  766.         string line = MakeUdevRulesLine(drive);
  767.         if( size(line)>0 )
  768.             AsciiFile::AppendLine( udev_file, [ line ]); 
  769.         });
  770.         y2milestone( "MakeCDLinks %1", cddrives );
  771.         string dir = substring( UdevCdromPath(), 0, findlastof( UdevCdromPath(), "/" ) );
  772.         y2milestone( "MakeCDLinks dir %1", dir );
  773.         if( SCR::Read( .target.size, dir )<=0 )
  774.         SCR::Execute( .target.mkdir, dir );
  775.         AsciiFile::RewriteFile( udev_file, UdevCdromPath() );
  776.         }
  777.     }
  778.     return;
  779.     }
  780.  
  781. /*
  782.  * Initialize
  783.  */
  784.  
  785. global define void FullProbe ()
  786.     ``{
  787.     FloppyReady();        // probe floppy
  788.     ProbeCDROMs();        // probe CDs
  789.     }
  790.  
  791. global define void InitDone()
  792.     ``{
  793.     disks_valid = true;
  794.     y2milestone( "called disks_valid %1", disks_valid );
  795.     }
  796.  
  797. /*
  798.  * Constructor
  799.  */
  800.  
  801. global define void StorageDevices ()
  802.     ``{
  803.     if( !Stage::initial () && !Mode::config () )
  804.     {
  805.     FullProbe ();
  806.     disks_valid = true;
  807.     }
  808.     return;
  809.     }
  810. }
  811.