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 / Storage.ycp < prev    next >
Text File  |  2006-11-29  |  175KB  |  5,933 lines

  1. /**
  2.  * Module:         Storage.ycp
  3.  *
  4.  * Authors:        Johannes Buchhold (jbuch@suse.de)
  5.  *
  6.  * Purpose:         These module contains all settings/information which
  7.  * are needed to partitioning the harddisk. Futhermore it contains a interface
  8.  * to * access and modify the partitioning settings.
  9.  *
  10.  * Todo: Translate
  11.  * Diese Modul enthΣlt alle Informationen die fⁿr die Partitionierung der
  12.  * Festplatten erforderlich sind. Diese Informationen bestehen aus der
  13.  * Beschreibung, der vor der Partitionierung vorhandenen Platteneinstellungen,
  14.  * und der Art und Weise wie diese verΣndert werden soll.
  15.  * Alle n÷tigen Zugriffsfunktionen auf diese Datenstruktur sind ebenfalls in
  16.  * diesem Modul enthalten. Der Zugriff auf die Speicherung der
  17.  * Partitionseinstellungen lΣuft also nur ⁿber dieses Modul.
  18.  * Der Zugriff und die Rⁿckgabe von Teilen der Partitionsdatenstruktur
  19.  * wurde versucht "intelligent" zu gestallten und ist im einzelen bei den
  20.  * entspechenden Funktionen nΣher erklΣrt.
  21.  *
  22.  * $Id: Storage.ycp 33934 2006-10-31 12:30:46Z fehr $
  23.  */
  24. {
  25.  
  26.   module "Storage";
  27.   textdomain "storage";
  28.  
  29.   import "Arch";
  30.   import "AsciiFile";
  31.   import "Encoding";
  32.   import "Directory";
  33.   import "FileSystems";
  34.   import "Installation";
  35.   import "Label";
  36.   import "Mode";
  37.   import "Partitions";
  38.   import "Popup";
  39.   import "Misc";
  40.   import "HTML";
  41.   import "StorageDevices";
  42.   import "StorageClients";
  43.   import "ProductFeatures";
  44.   import "Stage";
  45.   import "String";
  46.   import "Hotplug";
  47.  
  48.   import "LibStorage";
  49.   import "LibStorage::StorageInterface";
  50.   import "LibStorage::VolumeInfo";
  51.   import "LibStorage::PartitionInfo";
  52.   import "LibStorage::LvmLvInfo";
  53.   import "LibStorage::EvmsInfo";
  54.   import "LibStorage::MdInfo";
  55.   import "LibStorage::LoopInfo";
  56.   import "LibStorage::DmInfo";
  57.   import "LibStorage::DmPartInfo";
  58.   import "LibStorage::DmraidInfo";
  59.   import "LibStorage::ContainerInfo";
  60.   import "LibStorage::DiskInfo";
  61.   import "LibStorage::LvmVgInfo";
  62.   import "LibStorage::EvmsCoInfo";
  63.   import "LibStorage::PartitionAddInfo";
  64.   import "LibStorage::DmPartCoInfo";
  65.   import "LibStorage::DmraidCoInfo";
  66.  
  67. map<string,any> conv_ctype =
  68.     $[ "def_sym" : `CT_UNKNOWN,
  69.        "def_int" : LibStorage::CUNKNOWN(),
  70.        "m" : $[ LibStorage::DISK() : `CT_DISK,
  71.                 LibStorage::MD() : `CT_MD,
  72.                 LibStorage::LOOP() : `CT_LOOP,
  73.                 LibStorage::LVM() : `CT_LVM,
  74.                 LibStorage::EVMS() : `CT_EVMS,
  75.                 LibStorage::DMRAID() : `CT_DMRAID,
  76.                 LibStorage::DM() : `CT_DM
  77.           ]
  78.      ];
  79.  
  80. map<string,any> conv_usedby =
  81.     $[ "def_sym" : `UB_NONE,
  82.        "def_int" : LibStorage::UB_NONE(),
  83.        "m" : $[ LibStorage::UB_LVM() : `UB_LVM,
  84.                 LibStorage::UB_MD() : `UB_MD,
  85.                 LibStorage::UB_EVMS() : `UB_EVMS,
  86.                 LibStorage::UB_DMRAID() : `UB_DMRAID,
  87.                 LibStorage::UB_DM() : `UB_DM
  88.           ]
  89.      ];
  90.  
  91. map<string,any> conv_ptype =
  92.     $[ "def_sym" : `primary,
  93.        "def_int" : LibStorage::PRIMARY(),
  94.        "m" : $[ LibStorage::LOGICAL() : `logical,
  95.                 LibStorage::EXTENDED() : `extended
  96.           ]
  97.      ];
  98.  
  99. map<string,any> conv_mountby =
  100.     $[ "def_sym" : `device,
  101.        "def_int" : LibStorage::MOUNTBY_DEVICE(),
  102.        "m" : $[ LibStorage::MOUNTBY_UUID() : `uuid,
  103.                 LibStorage::MOUNTBY_LABEL() : `label,
  104.         LibStorage::MOUNTBY_ID() : `id,
  105.         LibStorage::MOUNTBY_PATH() : `path
  106.           ]
  107.      ];
  108.  
  109. map<string,any> conv_encryption =
  110.     $[ "def_sym" : `none,
  111.        "def_int" : LibStorage::ENC_NONE(),
  112.        "m" : $[ LibStorage::ENC_TWOFISH() : `twofish,
  113.                 LibStorage::ENC_TWOFISH_OLD() : `twofish_old,
  114.                 LibStorage::ENC_TWOFISH256_OLD() : `twofish_256_old,
  115.                 LibStorage::ENC_UNKNOWN() : `unknown,
  116.           ]
  117.      ];
  118.  
  119. map<string,any> conv_mdtype =
  120.     $[ "def_sym" : `raid_unknown,
  121.        "def_int" : LibStorage::RAID_UNK(),
  122.        "m" : $[ LibStorage::RAID0() : `raid0,
  123.                 LibStorage::RAID1() : `raid1,
  124.                 LibStorage::RAID5() : `raid5,
  125.                 LibStorage::RAID6() : `raid6,
  126.                 LibStorage::RAID10() : `raid10,
  127.                 LibStorage::MULTIPATH() : `multipath
  128.           ]
  129.      ];
  130.  
  131. map<string,integer> conv_mdstring =
  132.     $[ "raid0" : LibStorage::RAID0(),
  133.        "raid1" : LibStorage::RAID1(),
  134.        "raid5" : LibStorage::RAID5(),
  135.        "raid6" : LibStorage::RAID6(),
  136.        "raid10" : LibStorage::RAID10(),
  137.        "multipath" : LibStorage::MULTIPATH() ];
  138.  
  139. map<string,any> conv_mdparity =
  140.     $[ "def_sym" : `par_none,
  141.        "def_int" : LibStorage::PAR_NONE(),
  142.        "m" : $[ LibStorage::LEFT_ASYMMETRIC() : `left_asymmetric,
  143.                 LibStorage::LEFT_SYMMETRIC() : `left_symmetric,
  144.                 LibStorage::RIGHT_ASYMMETRIC() : `right_asymmetric,
  145.                 LibStorage::RIGHT_SYMMETRIC() : `right_symmetric
  146.           ]
  147.      ];
  148.  
  149. map<string,integer> conv_parstring =
  150.     $[ "left_asymmetric" : LibStorage::LEFT_ASYMMETRIC(),
  151.        "left_symmetric" : LibStorage::LEFT_SYMMETRIC(),
  152.        "right_asymmetric" : LibStorage::RIGHT_ASYMMETRIC(),
  153.        "right_symmetric" : LibStorage::RIGHT_SYMMETRIC() ];
  154.  
  155. global boolean DoCheckEvmsNonEvms = true;
  156. global boolean DoCheckEvmsLvm = true;
  157. map DiskMapVersion = $[];
  158. map DiskMap = $[];
  159. map ClassifiedSettings = $[];
  160. map type_order = $[ `CT_DISK : 0, `CT_MD : 1, `CT_DMRAID : 2,
  161.                     `CT_LOOP : 3, `CT_DM : 4, `CT_LVM : 5, 
  162.             `CT_EVMS : 6 ];
  163. list<string> hw_packages = [];
  164. list<string> no_propose_disks = nil;
  165. boolean proposal_evms = false;
  166. boolean proposal_lvm = false;
  167. boolean proposal_home = false;
  168. map cfg_xml = $[];
  169.  
  170.  
  171.  /*
  172.   include "storage/routines.ycp";
  173.  */
  174.   /**
  175.    * Get Device Name
  176.    * @param disk Disk
  177.    * @param any partition
  178.    * @return string device name
  179.    */
  180. global define string GetDeviceName( string disk, any partition )
  181.     {
  182.       string ret = disk;
  183.  
  184.       if( is( partition, integer ) )
  185.       {
  186.         if( search( disk, "/dev/cciss/" )==0 ||
  187.             search( disk, "/dev/ida/" )==0 ||
  188.             search( disk, "/dev/ataraid/" )==0 ||
  189.             search( disk, "/dev/etherd/" )==0 ||
  190.             search( disk, "/dev/rd/" )==0 )
  191.             {
  192.             ret = ret + "p";
  193.             }
  194.       else if( search( disk, "/dev/mapper/" )==0 )
  195.             {
  196.             ret = ret + "_part";
  197.             }
  198.         ret = ret + sformat( "%1", partition );
  199.       }
  200.       else if( size( (string)partition )>0 )
  201.           {
  202.         ret = ret + "/" + (string)partition;
  203.       }
  204.       return( ret );
  205.   };
  206.  
  207. global string EvmsDevDisk( string dev )
  208.     {
  209.     string ret = "/dev/" + substring( dev, 10 );
  210.     integer pos = search( ret, "!" );
  211.     y2milestone( "EvmsDevDisk pos:%1", pos );
  212.     if( pos!=nil )
  213.     ret = String::Replace( ret, "!", "/" );
  214.     pos = search( ret, "|" );
  215.     y2milestone( "EvmsDevDisk pos:%1", pos );
  216.     if( pos!=nil )
  217.     ret = String::Replace( ret, "|", "/" );
  218.     return( ret );
  219.     }
  220.  
  221.  
  222.     /* Storage = TargetMap
  223.     /* Storage = $[ "targets"             : $[],
  224.             "lvm_view_all_mnt"        : true,
  225.             "whole_disk"            : false,
  226.             "must_reread_partitions"       : false,
  227.             "win_device"           : false,
  228.             "raidtab_created"       : false,
  229.             "use_lvm"           : false,
  230.             "testsuite"           : false,
  231.             "do_resize"            : "",
  232.             "part_proposal_mode"        : "",
  233.             "part_proposal_first"       : true,
  234.             "focus"                   : key
  235.             ]
  236.     */
  237.  
  238.     global boolean ZeroNewPartitions = false;
  239.  
  240.     map  StorageMap    = $[];
  241.     map<integer,map>  StorageMaps    = $[];
  242.  
  243.     /* stringkeys for access  to the Storage map */
  244.     string lvm_view_all_mnt_key      = "lvm_view_all_mnt";
  245.     string targets_key             = "targets";
  246.     string targets_backup_key         = "targets_backup";
  247.     string targets_backup_l_key     = "targets_l_backup";
  248.     string targets_backup_m_key     = "targets_m_backup";
  249.     string part_mode_key         = "part_mode";
  250.     string part_disk_key          = "part_disk";
  251.     string whole_disk_key         = "whole_disk";
  252.     string raidtab_created_key         = "raidtab_created";
  253.     string testsuite_key               = "testsuite";
  254.     string do_resize_key         = "do_resize";
  255.     string win_device_key         = "win_device";
  256.     string custom_display_key         = "custom_display";
  257.     string part_proposal_mode_key    = "part_proposal_mode";
  258.     string part_proposal_first_key    = "part_proposal_first";
  259.     string part_proposal_active_key    = "part_proposal_active";
  260.     string use_lvm_key            = "use_lvm";
  261.  
  262.     string storage_map_key        = "storage_map";
  263.     string storage_type_key         = "storage_type";
  264.     string storage_doc_key        = "storage_doc";
  265.     symbol record_key            = `record;
  266.     symbol custom_key            = `custom;
  267.     boolean probe_done                 = false;
  268.     symbol  exit_key                   = `next;
  269.     string  last_used                  = "";
  270.     any sint                            = nil;
  271.     list<map> conts                     = [];
  272.  
  273. define any createInterface()
  274.     {
  275.     any ret = LibStorage::createStorageInterface(false, Mode::test(), true);
  276.     if( ZeroNewPartitions )
  277.     LibStorage::StorageInterface::setZeroNewPartitions(ret,true);
  278.  
  279.     return( ret );
  280.     }
  281.  
  282. list<map> getContainers();
  283.  
  284. global define void InitLibstorage()
  285.     {
  286.     if( sint==nil )
  287.     {
  288.     y2milestone( "InitLibstorage" );
  289.     sint = createInterface();
  290.     if( Stage::initial() )
  291.         {
  292.         LibStorage::StorageInterface::setDetectMountedVolumes(sint,false);
  293.         LibStorage::StorageInterface::setRootPrefix( sint,
  294.                              Installation::destdir );
  295.         }
  296.     conts = getContainers();
  297.     y2milestone( "InitLibstorage conts:%1", conts );
  298.     FileSystems::InitSlib( sint );
  299.     }
  300.     }
  301.  
  302. /**
  303. *
  304. */
  305. global define map GetDiskPartition( string device )
  306.     ``{
  307.     map ret = $[];
  308.     integer dlen = 0;
  309.     boolean as_string = false;
  310.     list<string> ls = filter( string s, splitstring( device, "/" ), 
  311.                               ``(size(s)>0));
  312.     y2debug( "GetDiskPartition size:%1 ls:%2", size(ls), ls );
  313.  
  314.     if( search( device, "/dev/hd" )==0 ||
  315.     search( device, "/dev/sd" )==0 ||
  316.     search( device, "/dev/ed" )==0 ||
  317.     search( device, "/dev/iseries/vd" )==0 )
  318.     {
  319.     dlen = findfirstof( device, "0123456789" );
  320.     if( dlen == nil )
  321.         {
  322.         dlen = size(device);
  323.         }
  324.     }
  325.     else if( search( device, "/dev/md" )==0 && size(ls)==2 )
  326.     {
  327.     dlen = 7;
  328.     }
  329.     else if( search( device, "/dev/loop" )==0 )
  330.     {
  331.     dlen = 9;
  332.     }
  333.     else if( search( device, "/dev/i2o/hd" )==0 )
  334.     {
  335.     dlen = 12;
  336.     }
  337.     else if( search( device, "/dev/rd/" )==0 ||
  338.          search( device, "/dev/cciss/" )==0 ||
  339.          search( device, "/dev/ataraid/" )==0 ||
  340.          search( device, "/dev/etherd/" )==0 ||
  341.          search( device, "/dev/ida/" )==0 )
  342.     {
  343.     integer pos = findlastof( device, "p" );
  344.     dlen = size(device);
  345.     if( pos!=nil )
  346.         {
  347.         dlen = pos;
  348.         }
  349.     }
  350.     else if( search( device, "/dev/dasd" )==0 )
  351.     {
  352.     dlen = size(device);
  353.     if( findfirstof( device, "0123456789" )!=nil )
  354.         {
  355.         dlen = dlen-1;
  356.         }
  357.     }
  358.     else if( search( device, "/dev/mapper/" )==0 )
  359.     {
  360.     string regex = "_part[0-9]+$";
  361.     list l = regexppos( device, regex );
  362.     if( size(l)>0 )
  363.         dlen = l[0]:0;
  364.     else
  365.         dlen = size(device);
  366.     }
  367.     else
  368.     {
  369.     as_string = true;
  370.     if( size(ls)>=3 )
  371.         {
  372.         integer pos = findlastof( device, "/" );
  373.         if( pos!=nil )
  374.         {
  375.         dlen = pos;
  376.         }
  377.         }
  378.     else
  379.         {
  380.         dlen = size(device);
  381.         integer nonzero = findlastnotof( device, "0123456789" );
  382.         if( nonzero!=nil && nonzero < dlen-1 )
  383.         {
  384.         dlen = nonzero+1;
  385.         as_string = false;
  386.         }
  387.         }
  388.     }
  389.     ret = add( ret, "disk", substring( device, 0, dlen ) );
  390.     device = substring( device, dlen );
  391.     if( search( device, "_part" )==0 )
  392.     device = substring( device, 5 );
  393.     if( size(device)>0 && findfirstof( device, "/p" )==0 )
  394.     {
  395.     device = substring( device, 1 );
  396.     }
  397.     ret["nr"] = -1;
  398.     if( as_string )
  399.     {
  400.     ret["nr"] = device;
  401.     }
  402.     else
  403.     {
  404.     if( size(device)>0 )
  405.         {
  406.         ret["nr"] = tointeger(device);
  407.         }
  408.     }
  409.     if( size(ret["disk"]:"")>0 && ret["nr"]:(any)1 == -1 )
  410.     {
  411.     ret["nr"] = "";
  412.     }
  413.     y2debug( "GetDiskPartition device:%1 ret:%2", device, ret );
  414.     return( ret );
  415.     };
  416.  
  417. void UpdateChangeTime()
  418.     {
  419.     integer change_time = time();
  420.     StorageMap["targets_time"] = change_time;
  421.     }
  422.  
  423. /* return partition <device> of map <tg> */
  424. global define map<string,any> GetPartition( map<string,map> tg, string device )
  425.     ``{
  426.     map<string,any> ret = $[];
  427.     map tmp = GetDiskPartition( device );
  428.     y2milestone( "GetPartition tmp:%1", tmp );
  429.     string disk = tmp["disk"]:"";
  430.     if( search(device, "/dev/evms")==0 && !haskey( tg, disk ) )
  431.     {
  432.     disk = "/dev/evms";
  433.     }
  434.     y2debug( "GetPartition device=%1", device );
  435.     list< map<string,any> > part = (list< map<string,any> >)
  436.     filter( map<string, any> pi, tg[disk,"partitions"]:[],
  437.             ``(pi["device"]:""==device ));
  438.     ret = part[0]:$[];
  439.     y2debug( "GetPartition ret=%1", ret );
  440.     return( ret );
  441.     }
  442.  
  443. /* return disk <device> belongs to in map <tg> */
  444. global define map<string,any> GetDisk( map<string,map> tg, string device )
  445.     ``{
  446.     map<string,any> ret = $[];
  447.     map tmp = GetDiskPartition( device );
  448.     string disk = tmp["disk"]:"";
  449.     if( search(device, "/dev/evms")==0 && !haskey( tg, disk ) )
  450.     {
  451.     disk = "/dev/evms";
  452.     }
  453.     y2debug( "GetDisk disk=%1", disk );
  454.     return( (map<string,any>)tg[disk]:$[] );
  455.     }
  456.  
  457.  
  458. /* set <part>, return changed map <tg> */
  459. global define map<string,map> SetPartition( map<string,map> tg, map part )
  460.     ``{
  461.     y2milestone( "SetPartition part=%1", part );
  462.     map tmp = GetDiskPartition( part["device"]:"" );
  463.     y2milestone( "SetPartition tmp=%1", tmp );
  464.     string disk = tmp["disk"]:"";
  465.     if( search(part["device"]:"", "/dev/evms")==0 && !haskey( tg, disk ) )
  466.     {
  467.     disk = "/dev/evms";
  468.     }
  469.     list r_part = filter(map p, tg[disk,"partitions"]:[],
  470.               ``(p["device"]:"" != part["device"]:""));
  471.     r_part = add( r_part, part );
  472.     tg[disk,"partitions"] = r_part;
  473.     return( tg );
  474.     }
  475.  
  476. /**
  477.  * Find next free loop device.
  478.  * @return string loop_dev ( e.g.: /dev/loop1 )
  479.  */
  480. global define string GetLoopDev( integer start )
  481.     ``{
  482.     if( Mode::test () )
  483.     return "/dev/loop2";
  484.  
  485.     integer max_loop_dev= 15;
  486.     integer loop_dev_nb = start;
  487.     boolean found_free  = false;
  488.     string  loop_dev    = "";
  489.  
  490.     while( !found_free && loop_dev_nb <= max_loop_dev )
  491.     {
  492.     loop_dev = sformat("/dev/loop%1", loop_dev_nb );
  493.     loop_dev_nb = loop_dev_nb + 1;
  494.  
  495.     // Test loop dev
  496.     if( SCR::Execute(.target.bash , "/sbin/losetup 2>/dev/null " + loop_dev ) != 0 )
  497.         found_free = true;
  498.     }
  499.  
  500.     if( !found_free )
  501.     {
  502.     loop_dev = "";
  503.     // internal error popup
  504.     Popup::Error( _("Too many loop devices (cryptofs ...)") );
  505.     y2error( "Too many loop devices");
  506.     }
  507.  
  508.     y2milestone("ret \"%1\"",loop_dev);
  509.  
  510.     return( loop_dev );
  511.     };
  512.  
  513.  
  514. /**
  515.  * Get List of swap partitions
  516.  * @return list List of swap partitions
  517.  */
  518. global define list SwappingPartitions()``{
  519.     list ret = [];
  520.     SCR::UnmountAgent (.proc.swaps);
  521.     list<map> swaps = filter(map e, (list<map>) SCR::Read( .proc.swaps ),
  522.                          ``(e["type"]:""=="partition"));
  523.     ret = maplist(map e, swaps, ``(Partitions::TranslateMapperName(e["file"]:"")) );
  524.     y2milestone( "SwappingPartitions %1", ret );
  525.     return( ret );
  526.     }
  527.  
  528. global define list GetDestroyedLvmVgs( map<string,map> target )
  529.     ``{
  530.     list vgs = [];
  531.     foreach(string diskdev, map disk, target,
  532.     ``{
  533.     foreach( map p, disk["partitions"]:[],
  534.         ``{
  535.         if( p["used_by_type"]:`UB_NONE==`UB_LVM && p["format"]:false )
  536.         {
  537.         vgs = union( vgs, [ p["used_by"]:"" ] );
  538.         }
  539.         });
  540.     });
  541.     vgs = sort( vgs );
  542.     y2milestone( "GetDestroyedLvmVgs %1", vgs );
  543.     return( vgs );
  544.     }
  545.  
  546. global define map<string,map> DeleteDestroyedLvmVgs( map<string,map> target )
  547.     ``{
  548.     list<string> vgs = maplist( string s, (list<string>)GetDestroyedLvmVgs( target ),
  549.                 ``("/dev/"+s));
  550.     y2milestone( "DeleteDestroyedLvmVgs %1", vgs );
  551.     foreach( string dev, vgs,
  552.     ``{
  553.     if( haskey( target, dev ))
  554.         target[dev,"delete"] = true;
  555.     target[dev,"partitions"] = maplist( map p, target[dev,"partitions"]:[],
  556.                         ``{
  557.                         if( haskey( p, "mount" ))
  558.                         p = remove( p, "mount" );
  559.                         return( p );
  560.                         });
  561.     y2milestone( "DeleteDestroyedLvmVgs %1: %2", dev, target[dev]:$[] );
  562.     });
  563.     return( target );
  564.     }
  565.  
  566. global define map GetFreeSpace( string device, integer testsize,
  567.                                 symbol used_fs, boolean verbose )
  568.     ``{
  569.     if( Mode::test() )
  570.     {
  571.     integer wf =  tointeger(tofloat(testsize) * 0.6);
  572.     integer wu =  tointeger(tofloat(testsize) * 0.4);
  573.     integer ls =  tointeger(tofloat(testsize) * 0.5);
  574.     return( $[ "free"  : wf, "used"    : wu,
  575.            "linux_size"  : ls, "new_size": (wu + wf - ls) ] );
  576.     }
  577.  
  578.     integer used = 0;
  579.     integer resize_free = 0;
  580.     integer df_free = 0;
  581.     boolean win_disk = false;
  582.  
  583.     boolean r = false;
  584.     r = LibStorage::StorageInterface::getFreeInfo( sint, device, resize_free,
  585.                                                    df_free, used, win_disk,
  586.                            used_fs==`ntfs );
  587.  
  588.     resize_free = resize_free * 1024;    // Byte
  589.     df_free = df_free * 1024;    // Byte
  590.     used = used * 1024;    // Byte
  591.  
  592.     if( used_fs == `ntfs && !r && verbose )
  593.     {
  594.     string cmd = sformat("ntfsresize -f -i %1", device );
  595.     y2milestone( "GetFreeSpace Executing cmd:%1", cmd );
  596.     map bcall = (map) SCR::Execute( .target.bash_output, cmd,
  597.                     $[ "LC_MESSAGES" :"POSIX"] );
  598.     y2milestone( "GetFreeSpace Executing ret:%1", bcall );
  599.     string tmp = _("Resize Not Possible:") + "\n\n";
  600.     tmp = tmp + bcall["stdout"]:"" + bcall["stderr"]:"";
  601.     Popup::Error( tmp );
  602.     return( $[] );
  603.     }
  604.  
  605.     integer linux_size = 0;
  606.     integer min_linux_size = 0;
  607.     integer add_free = df_free - resize_free;
  608.  
  609.     y2milestone( "GetFreeSpace resize_free %1 add_free %2", 
  610.                  resize_free, add_free );
  611.  
  612.     if( resize_free < 300*1024*1024 || !r )
  613.     {
  614.     linux_size = 0;
  615.     min_linux_size = 0;
  616.     }
  617.     else if( resize_free < 600*1024*1024 )
  618.     {
  619.     linux_size = resize_free;
  620.     if( add_free < 75*1024*1024 )
  621.         {
  622.         linux_size = linux_size - 75*1024*1024 + add_free;
  623.         }
  624.     min_linux_size = linux_size;
  625.     }
  626.     else if ( resize_free < 1024*1024*1024 )
  627.     {
  628.     linux_size = resize_free;
  629.     if( add_free < 200*1024*1024 )
  630.         {
  631.         linux_size = linux_size - 200*1024*1024 + add_free;
  632.         }
  633.     min_linux_size = 300*1024*1024;
  634.     }
  635.     else if ( resize_free < 2*1024*1024*1024 )
  636.     {
  637.     linux_size = resize_free;
  638.     if( add_free < 300*1024*1024 )
  639.         {
  640.         linux_size = linux_size - 300*1024*1024 + add_free;
  641.         }
  642.     min_linux_size = 500*1024*1024;
  643.     }
  644.     else if ( resize_free < 3*1024*1024*1024 )
  645.     {
  646.     linux_size = resize_free;
  647.     if( add_free < 800*1024*1024 )
  648.         {
  649.         linux_size = linux_size - 800*1024*1024 + add_free;
  650.         }
  651.     min_linux_size = 500*1024*1024;
  652.     }
  653.     else
  654.     {
  655.     linux_size = resize_free;
  656.     if( add_free < resize_free/3 )
  657.         {
  658.         linux_size = linux_size - resize_free/3 + add_free;
  659.         }
  660.     min_linux_size = 500*1024*1024;
  661.     }
  662.  
  663.     integer new_size = used + add_free + resize_free - linux_size;
  664.  
  665.     map ret = $[ "free": (resize_free>0?resize_free:0),
  666.          "df_free" : df_free,
  667.          "used":used,
  668.          "win_disk":win_disk,
  669.          "linux_size":linux_size,
  670.          "max_win_size":used + resize_free + add_free - min_linux_size,
  671.          "ntfs" : (used_fs == `ntfs),
  672.          "new_size":new_size ];
  673.     ret["ok"] = r;
  674.     y2milestone( "GetFreeSpace %1 ret %2", device, ret );
  675.     return( ret );
  676.     };
  677.  
  678. global define map<string,map> AddWinInfo( map<string,map> targets )
  679.     ``{
  680.     y2milestone( "AddWinInfo called" );
  681.     foreach(string disk, map data, targets,
  682.     ``{
  683.     targets[disk,"partitions"] =
  684.         maplist(map p, data["partitions"]:[],
  685.         ``{
  686.         if( Partitions::IsDosWinNtPartition(p["fsid"]:0) &&
  687.             contains( [ `ntfs, `vfat ], p["used_fs"]:`none ))
  688.             {
  689.             p["winfo"] = GetFreeSpace( p["device"]:"", 0,
  690.                            p["used_fs"]:`none, false );
  691.             y2milestone( "AddWinInfo %1", p );
  692.             }
  693.         return( p );
  694.         });
  695.     });
  696.     return( targets );
  697.     };
  698.  
  699. global define string SaveDumpPath( string name )``{
  700.     string ret = Directory::tmpdir + "/" + name;
  701.     y2debug( "name=%1 path=%2", name, ret );
  702.     return ret;
  703.     }
  704.  
  705. //  add mount point for all mounted partitions
  706. global define map<string,map> AddMountPointInfo( map<string,map> target )
  707.     ``{
  708.     list<map> mounts = Partitions::CurMounted();
  709.     foreach(string diskdev, map disk, target,
  710.     ``{
  711.     // variable renamed due to some interpreter problems
  712.     list<map> tmp2 = disk["partitions"]:[];
  713.     tmp2 = maplist(map part, tmp2,
  714.         ``{
  715.         map mt = find(map mp, mounts, ``(mp["spec"]:" "==part["device"]:"" ||
  716.                        mp["loop_on"]:" "==part["device"]:""));
  717.         if( mt != nil )
  718.         {
  719.         part["mount"] = mt["file"]:"";
  720.         if( part["noauto"]:false )
  721.             {
  722.             part["active"] = true;
  723.             }
  724.         }
  725.         return( part );
  726.         });
  727.     disk["partitions"] = tmp2;
  728.     target[diskdev] = disk;
  729.     });
  730.     return( target );
  731.     }
  732.  
  733. global define list FindFstabLines( map fstab, string mount, string device,
  734.                                    string uuid, string label )
  735.     ``{
  736.     list<integer> lines = [];
  737.     if( size(mount)>0 && mount != "swap" )
  738.     {
  739.     lines = AsciiFile::FindLineField( fstab, 1, mount );
  740.     }
  741.     if( size(lines)==0 )
  742.     {
  743.     lines = AsciiFile::FindLineField( fstab, 0, device );
  744.     }
  745.     if( size(lines)>1 )
  746.     {
  747.     uuid = "UUID=" + uuid;
  748.     label = "LABEL=" + label;
  749.     map<integer,map> tlines = AsciiFile::GetLines( fstab, lines );
  750.     map<integer,map> nlist = filter(integer num, map line, tlines,
  751.                 ``( line["fields",0]:"" == device ||
  752.                 line["fields",0]:"" == uuid ||
  753.                 line["fields",0]:"" == label ));
  754.     if( size(nlist)>0 )
  755.         {
  756.         lines = maplist( integer num, map line, nlist, ``(num));
  757.         }
  758.     }
  759.     y2milestone( "lines %1", lines );
  760.     return( lines );
  761.     };
  762.  
  763. //  add info gotten from /etc/fstab to targetMap
  764. global define map<string,map> AddFstabInfo( map<string,map> target, boolean lineno )
  765.     ``{
  766.     y2milestone( "lineno=%1", lineno );
  767.     map fstab = Partitions::GetFstab( "/etc/fstab" );
  768.     map crtab = Partitions::GetCrypto( "/etc/cryptotab" );
  769.     foreach(string diskdev, map disk, target,
  770.     ``{
  771.     list new_part = [];
  772.     foreach(map part, disk["partitions"]:[],
  773.         ``{
  774.         list<string> rem = [];
  775.         if( lineno )
  776.         {
  777.         rem = [ "fstabline", "crtabline" ];
  778.         }
  779.         else
  780.         {
  781.         rem = [ "mountby", "fstopt" ];
  782.         }
  783.         part = (map<string,any>)filter(string key, any val, (map<string,any>)part, ``(!contains( rem, key )));
  784.         string mp = part["mount"]:"";
  785.         if( size(part["ori_mount"]:"")>0 )
  786.         {
  787.         mp = part["ori_mount"]:"";
  788.         }
  789.         list lines = [];
  790.         lines = FindFstabLines( fstab, mp, part["device"]:"",
  791.                                 part["uuid"]:"", part["label"]:"" );
  792.         if( size(lines)>0 )
  793.         {
  794.         if( lineno )
  795.             {
  796.             part["fstabline"] = lines[0]:-1;
  797.             }
  798.         else
  799.             {
  800.             map entry = AsciiFile::GetLine( fstab, lines[0]:-1 );
  801.             if( entry["fields",3]:"defaults" != "defaults" )
  802.             {
  803.             part["fstopt"] = entry["fields",3]:"";
  804.             }
  805.             if( search(entry["fields",0]:"", "UUID=") != nil )
  806.             {
  807.             part["mountby"] = `uuid;
  808.             }
  809.             else if( search(entry["fields",0]:"", "LABEL=") != nil )
  810.             {
  811.             part["mountby"] = `label;
  812.             }
  813.             else if( search(entry["fields",0]:"", "/dev/disk/by-id/") != nil )
  814.                 {
  815.             part["mountby"] = `id;
  816.             }
  817.             else if( search(entry["fields",0]:"", "/dev/disk/by-path/") != nil )
  818.                 {
  819.             part["mountby"] = `path;
  820.             }
  821.             }
  822.         }
  823.         lines = AsciiFile::FindLineField( crtab, 2, mp );
  824.         if( size(lines)==0 && diskdev!="/dev/loop" )
  825.         {
  826.         lines = AsciiFile::FindLineField( crtab, 1, part["device"]:"" );
  827.         }
  828.         if( size(lines)==0 && diskdev=="/dev/loop" )
  829.         {
  830.         lines = AsciiFile::FindLineField( crtab, 0, part["device"]:"" );
  831.         }
  832.         if( size(lines)>0 )
  833.         {
  834.         if( lineno )
  835.             {
  836.             part["crtabline"] = lines[0]:-1;
  837.             }
  838.         else
  839.             {
  840.             map entry = AsciiFile::GetLine( crtab, lines[0]:-1 );
  841.             if( entry["fields",5]:"defaults" != "defaults" )
  842.             {
  843.             part["fstopt"] = entry["fields",5]:"";
  844.             }
  845.             }
  846.         }
  847.         y2milestone( "part=%1", part );
  848.         new_part = add( new_part, part );
  849.         });
  850.     target[diskdev] = disk;
  851.     target[diskdev,"partitions"] = new_part;
  852.     });
  853.     return( target );
  854.     }
  855.  
  856. define string convertFsOptionMapToString( map<any,map> fsopt )
  857.     {
  858.     string ret = "";
  859.  
  860.     // do nothing
  861.     if( fsopt != nil || fsopt != $[] )
  862.     {
  863.     list ignore = [ "auto", "default", "none", "" ];
  864.  
  865.     foreach(any option_key, map option, fsopt, 
  866.         ``{
  867.         string option_str   = option["option_str"]:"";
  868.         any    option_value = option["option_value"]:(any)"";
  869.         boolean option_blank = option["option_blank"]:false;
  870.         y2milestone( "convertFsOptionMapToString k:%1 opt:%2 val:%3", 
  871.                      option_key, option, option_value );
  872.  
  873.         if( is(option_value, string) && option_value != nil )
  874.         {
  875.         if( !contains( ignore, option_value ))
  876.             {
  877.             if( size(ret)>0 )
  878.             ret = ret + " ";
  879.             ret = ret + option_str;
  880.             if( option_blank )
  881.             ret = ret + " ";
  882.             ret = ret + (string)option_value;
  883.             }
  884.         }
  885.         else if( is(option_value, boolean) && option_value != nil )
  886.         {
  887.         if( (boolean) option_value )
  888.             {
  889.             if( size(ret)>0 )
  890.             ret = ret + " ";
  891.             ret = ret + option_str;
  892.             }
  893.         }
  894.         else if( is(option_value, integer) && option_value != nil )
  895.         {
  896.         if( size(ret)>0 )
  897.             ret = ret + " ";
  898.         ret = ret + option_str;
  899.         if( option_blank )
  900.             ret = ret + " ";
  901.         ret = ret + sformat("%1", option_value);
  902.         }
  903.         });
  904.     }
  905.     if( size(fsopt)>0 || size(ret)>0 )
  906.     y2milestone( "convertFsOptionMapToString fsopt:%1 ret:%2", fsopt, ret );
  907.     return ret;
  908.     };
  909.  
  910. map convertStringToFsOptionMap( string opts, symbol fs )
  911.     {
  912.     map ret = $[];
  913.     y2milestone( "convertStringToFsOptionMap opts:\"%1\" fs:%2", opts, fs );
  914.     integer pos = findfirstnotof( opts, " \t" );
  915.     if( pos>0 )
  916.     opts = substring( opts, pos );
  917.     list<map> op = (list<map>)FileSystems::GetOptions(fs);
  918.     while( size(opts)>0 )
  919.     {
  920.     boolean found = false;
  921.     foreach( map o, op,
  922.         ``{
  923.         map m = $[];
  924.         string os = o[`option_str]:"";
  925.         if( !found && size(os)>0 && search( opts, os )==0 )
  926.         {
  927.         found = true;
  928.         m["option_str"] = os;
  929.         if( o[`type]:`text==`boolean )
  930.             {
  931.             m["option_value"] = true;
  932.             ret[o[`query_key]:""] = m;
  933.             }
  934.         opts = substring( opts, size(os) );
  935.         pos = findfirstnotof( opts, " \t" );
  936.         if( pos>0 )
  937.             opts = substring( opts, pos );
  938.         if( o[`type]:`text!=`boolean && size(opts)>0 && 
  939.             search(opts,"-")!=0 )
  940.             {
  941.             if( pos>0 )
  942.             m["option_blank"] = true;
  943.             pos = findfirstof( opts, " \t" );
  944.             if( pos==nil )
  945.             {
  946.             m["option_value"] = opts;
  947.             opts = "";
  948.             }
  949.             else
  950.             {
  951.             m["option_value"] = substring( opts, 0, pos );
  952.             opts = substring( opts, pos );
  953.             }
  954.             ret[o[`query_key]:""] = m;
  955.             }
  956.         pos = findfirstnotof( opts, " \t" );
  957.         if( pos>0 )
  958.             opts = substring( opts, pos );
  959.         }
  960.         });
  961.     if( !found )
  962.         {
  963.         pos = findfirstnotof( opts, " \t" );
  964.         if( pos>0 )
  965.         opts = substring( opts, pos );
  966.         else
  967.         opts = "";
  968.         }
  969.     y2milestone( "convertStringToFsOptionMap opts:%1 ret:%2", opts, ret );
  970.     }
  971.     y2milestone( "convertStringToFsOptionMap ret:%1", ret );
  972.     return( ret );
  973.     }
  974.  
  975. symbol toSymbol( map<string,any> conv, integer val )
  976.     {
  977.     return( conv["m",val]:(conv["def_sym"]:`invalid_conv_map) );
  978.     }
  979.  
  980. integer fromSymbol( map<string,any> conv, symbol val )
  981.     {
  982.     integer ret = conv["def_int"]:-1;
  983.     foreach( integer i, symbol s, conv["m"]:$[],
  984.     ``{
  985.     if( s==val )
  986.         ret = i;
  987.     });
  988.     return( ret );
  989.     }
  990.  
  991. global define boolean CheckBackupState( string who )
  992.     {
  993.     y2milestone( "CheckBackupStates who:%1", who );
  994.     InitLibstorage();
  995.     boolean ret = LibStorage::StorageInterface::checkBackupState( sint, who );
  996.     y2milestone( "CheckBackupStates ret:%1", ret );
  997.     return( ret );
  998.     }
  999.  
  1000. map diskMap( any dinfo, map d )
  1001.     {
  1002.     d["size_k"] = LibStorage::DiskInfo::swig_sizeK_get(dinfo);
  1003.     d["cyl_size"] = LibStorage::DiskInfo::swig_cylSizeB_get(dinfo);
  1004.     d["cyl_count"] = LibStorage::DiskInfo::swig_cyl_get(dinfo);
  1005.     d["label"] = LibStorage::DiskInfo::swig_disklabel_get(dinfo);
  1006.     d["max_logical"] = LibStorage::DiskInfo::swig_maxLogical_get(dinfo);
  1007.     d["max_primary"] = LibStorage::DiskInfo::swig_maxPrimary_get(dinfo);
  1008.     boolean bt = LibStorage::DiskInfo::swig_initDisk_get(dinfo);
  1009.     if( bt )
  1010.     d["dasdfmt"] = true;
  1011.     else if( haskey( d, "dasdfmt" ))
  1012.     d = remove( d, "dasdfmt" );
  1013.     string tmp = LibStorage::DiskInfo::swig_udevId_get(dinfo);
  1014.     if( size(tmp)>0 )
  1015.     d["udev_id"] = splitstring( tmp, " " );
  1016.     else if( haskey( d, "udev_id" ))
  1017.     d = remove( d, "udev_id" );
  1018.     tmp = LibStorage::DiskInfo::swig_udevPath_get(dinfo);
  1019.     if( size(tmp)>0 )
  1020.     d["udev_path"] = tmp;
  1021.     else if( haskey( d, "udev_path" ))
  1022.     d = remove( d, "udev_path" );
  1023.     y2milestone( "diskMap ret:%1", d );
  1024.     return( d );
  1025.     }
  1026.  
  1027. map dmPartCoMap( any infos, map d )
  1028.     {
  1029.     any dinfo = LibStorage::DmPartCoInfo::swig_d_get(infos);
  1030.     d = diskMap( dinfo, d );
  1031.     list<string> ls = splitstring( LibStorage::DmPartCoInfo::swig_devices_get(infos), " " );
  1032.     y2milestone( "ls=%1", ls );
  1033.     d["devices"] = ls;
  1034.     y2milestone( "dmPartCoMap ret:%1", d );
  1035.     return( d );
  1036.     }
  1037.  
  1038. map volumeMap( any vinfo, map p )
  1039.     {
  1040.     p["device"] = LibStorage::VolumeInfo::swig_device_get(vinfo);
  1041.     p["size_k"] = LibStorage::VolumeInfo::swig_sizeK_get(vinfo);
  1042.     p["name"] = LibStorage::VolumeInfo::swig_name_get(vinfo);
  1043.     integer t = LibStorage::VolumeInfo::swig_fs_get(vinfo);
  1044.     symbol fs = toSymbol( FileSystems::conv_fs, t );
  1045.     p["detected_fs"] = fs;
  1046.     if( fs != `unknown )
  1047.     p["used_fs"] = fs;
  1048.     boolean tbool = LibStorage::VolumeInfo::swig_format_get(vinfo);
  1049.     if( tbool )
  1050.     p["format"] = true;
  1051.     tbool = LibStorage::VolumeInfo::swig_create_get(vinfo);
  1052.     if( tbool )
  1053.     p["create"] = true;
  1054.     string tmp = LibStorage::VolumeInfo::swig_mount_get(vinfo);
  1055.     if( size(tmp)>0 )
  1056.     {
  1057.     p["mount"] = tmp;
  1058.     tbool = LibStorage::VolumeInfo::swig_is_mounted_get(vinfo);
  1059.     if( !tbool )
  1060.         p["inactive"] = true;
  1061.     t = LibStorage::VolumeInfo::swig_mount_by_get(vinfo);
  1062.     if( t!=LibStorage::MOUNTBY_DEVICE() )
  1063.         {
  1064.         p["mountby"] = toSymbol( conv_mountby, t );
  1065.         }
  1066.     }
  1067.     t = LibStorage::VolumeInfo::swig_usedBy_get(vinfo);
  1068.     if( t!=LibStorage::UB_NONE() )
  1069.     {
  1070.     p["used_by_type"] = toSymbol( conv_usedby, t );
  1071.     p["used_by"] = LibStorage::VolumeInfo::swig_usedByName_get(vinfo);
  1072.     }
  1073.     tmp = LibStorage::VolumeInfo::swig_fstab_options_get(vinfo);
  1074.     if( size(tmp)>0 )
  1075.     {
  1076.     p["fstopt"] = tmp;
  1077.     if( find( string s, splitstring( tmp, "," ), ``(s=="noauto") )!=nil )
  1078.         p["noauto"] = true;
  1079.     }
  1080.     tmp = LibStorage::VolumeInfo::swig_mkfs_options_get(vinfo);
  1081.     if( size(tmp)>0 )
  1082.     {
  1083.     p["mkfs_opt"] = tmp;
  1084.     p["fs_options"] = 
  1085.         convertStringToFsOptionMap( tmp, p["detected_fs"]:`unknown );
  1086.     }
  1087.     else
  1088.     {
  1089.     if( haskey( p, "fs_options" ))
  1090.         p = remove( p, "fs_options" );
  1091.     }
  1092.     tmp = LibStorage::VolumeInfo::swig_dtxt_get(vinfo);
  1093.     if( size(tmp)>0 )
  1094.     p["dtxt"] = tmp;
  1095.     tmp = LibStorage::VolumeInfo::swig_uuid_get(vinfo);
  1096.     if( size(tmp)>0 )
  1097.     p["uuid"] = tmp;
  1098.     tmp = LibStorage::VolumeInfo::swig_label_get(vinfo);
  1099.     if( size(tmp)>0 )
  1100.     p["label"] = tmp;
  1101.     t = LibStorage::VolumeInfo::swig_encryption_get(vinfo);
  1102.     if( t!=LibStorage::ENC_NONE() )
  1103.     {
  1104.     p["enc_type"] = toSymbol( conv_encryption, t );
  1105.     }
  1106.     tbool = LibStorage::VolumeInfo::swig_resize_get(vinfo);
  1107.     if( tbool )
  1108.     {
  1109.     p["resize"] = true;
  1110.     p["orig_size_k"] = LibStorage::VolumeInfo::swig_OrigSizeK_get(vinfo);
  1111.     }
  1112.     tbool = LibStorage::VolumeInfo::swig_ignore_fs_get(vinfo);
  1113.     if( tbool )
  1114.     p["ignore_fs"] = true;
  1115.     tmp = LibStorage::VolumeInfo::swig_loop_get(vinfo);
  1116.     if( size(tmp)>0 )
  1117.     p["loop"] = tmp;
  1118.     return( p );
  1119.     }
  1120.  
  1121. map partAddMap( any info, map p )
  1122.     {
  1123.     p["nr"] = LibStorage::PartitionAddInfo::swig_nr_get(info);
  1124.     p["fsid"] = LibStorage::PartitionAddInfo::swig_id_get(info);
  1125.     p["fstype"] = Partitions::FsIdToString( p["fsid"]:0 );
  1126.     p["region"] = [ LibStorage::PartitionAddInfo::swig_cylStart_get(info),
  1127.             LibStorage::PartitionAddInfo::swig_cylSize_get(info) ];
  1128.     integer t = LibStorage::PartitionAddInfo::swig_partitionType_get(info);
  1129.     p["type"] = toSymbol( conv_ptype, t );
  1130.     boolean boot = LibStorage::PartitionAddInfo::swig_boot_get(info);
  1131.     if( boot )
  1132.     p["boot"] = true;
  1133.     string tmp = LibStorage::PartitionAddInfo::swig_udevId_get(info);
  1134.     if( size(tmp)>0 )
  1135.     p["udev_id"] = splitstring( tmp, " " );
  1136.     tmp = LibStorage::PartitionAddInfo::swig_udevPath_get(info);
  1137.     if( size(tmp)>0 )
  1138.     p["udev_path"] = tmp;
  1139.     y2milestone( "partAddMap ret:%1", p );
  1140.     return( p );
  1141.     }
  1142.  
  1143. map dmPartMap( any info, map p )
  1144.     {
  1145.     any vinfo = LibStorage::DmPartInfo::swig_v_get(info);
  1146.     p = volumeMap( vinfo, p );
  1147.     p["nr"] = 0;
  1148.     boolean part = LibStorage::DmPartInfo::swig_part_get(info);
  1149.     if( part )
  1150.     {
  1151.     any pinfo = LibStorage::DmPartInfo::swig_p_get(info);
  1152.     p = partAddMap( pinfo, p );
  1153.     }
  1154.     y2milestone( "dmPartMap ret:%1", p );
  1155.     return( p );
  1156.     }
  1157.  
  1158. map getContainerInfo( map c )
  1159.     {
  1160.     y2milestone( "getContainerInfo %1", c );
  1161.     integer ret = 0;
  1162.     integer t = 0;
  1163.     any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
  1164.     if( c["type"]:`CT_UNKNOWN == `CT_DISK )
  1165.     {
  1166.     list<any> pinfos = [];
  1167.     any infos = LibStorage::DiskInfo::new("LibStorage::DiskInfo");
  1168.     string d = c["device"]:"";
  1169.     ret = LibStorage::StorageInterface::getDiskInfo( sint, d, infos );
  1170.     if( ret==0 )
  1171.         {
  1172.         c = diskMap( infos, c );
  1173.         }
  1174.     else
  1175.         y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
  1176.     c["partitions"] = [];
  1177.     ret = LibStorage::StorageInterface::getPartitionInfo( sint, d, pinfos );
  1178.     foreach( any info, pinfos,
  1179.         ``{
  1180.         string tmp = "";
  1181.         map p = $[];
  1182.         vinfo = LibStorage::PartitionInfo::swig_v_get(info);
  1183.         p = volumeMap( vinfo, p );
  1184.         p["nr"] = LibStorage::PartitionInfo::swig_nr_get(info);
  1185.         p["fsid"] = LibStorage::PartitionInfo::swig_id_get(info);
  1186.         p["fstype"] = Partitions::FsIdToString( p["fsid"]:0 );
  1187.         p["region"] = [ LibStorage::PartitionInfo::swig_cylStart_get(info),
  1188.                 LibStorage::PartitionInfo::swig_cylSize_get(info) ];
  1189.         t = LibStorage::PartitionInfo::swig_partitionType_get(info);
  1190.         p["type"] = toSymbol( conv_ptype, t );
  1191.         boolean boot = LibStorage::PartitionInfo::swig_boot_get(info);
  1192.         if( boot )
  1193.         p["boot"] = true;
  1194.         tmp = LibStorage::PartitionInfo::swig_udevId_get(info);
  1195.         if( size(tmp)>0 )
  1196.         p["udev_id"] = splitstring( tmp, " " );
  1197.         tmp = LibStorage::PartitionInfo::swig_udevPath_get(info);
  1198.         if( size(tmp)>0 )
  1199.         p["udev_path"] = tmp;
  1200.         c["partitions"] = add( c["partitions"]:[], p );
  1201.         });
  1202.     }
  1203.     else if( c["type"]:`CT_UNKNOWN == `CT_DMRAID )
  1204.     {
  1205.     list<any> pinfos = [];
  1206.     any infos = LibStorage::DmraidCoInfo::new("LibStorage::DmraidCoInfo");
  1207.     string d = c["device"]:"";
  1208.     ret = LibStorage::StorageInterface::getDmraidCoInfo( sint, d, infos );
  1209.     if( ret==0 )
  1210.         {
  1211.         any pinfo = LibStorage::DmraidCoInfo::swig_p_get( infos );
  1212.         c = dmPartCoMap( pinfo, c );
  1213.         }
  1214.     else
  1215.         y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
  1216.     c["partitions"] = [];
  1217.     ret = LibStorage::StorageInterface::getDmraidInfo( sint, d, pinfos );
  1218.     foreach( any info, pinfos,
  1219.         ``{
  1220.         any pinfo = LibStorage::DmraidInfo::swig_p_get( info );
  1221.         map p = $[];
  1222.         p = dmPartMap( pinfo, p );
  1223.         p["fstype"] = Partitions::dmraid_name;
  1224.         if( p["nr"]:-1 != 0 )
  1225.         c["partitions"] = add( c["partitions"]:[], p );
  1226.         });
  1227.     }
  1228.     else if( c["type"]:`CT_UNKNOWN == `CT_LVM )
  1229.     {
  1230.     list<any> pinfos = [];
  1231.     any infos = LibStorage::LvmVgInfo::new("LibStorage::LvmVgInfo");
  1232.     string n = c["name"]:"";
  1233.     ret = LibStorage::StorageInterface::getLvmVgInfo( sint, n, infos );
  1234.     if( ret==0 )
  1235.         {
  1236.         c["create"] = LibStorage::LvmVgInfo::swig_create_get(infos);
  1237.         c["size_k"] = LibStorage::LvmVgInfo::swig_sizeK_get(infos);
  1238.         c["cyl_size"] = 1024*LibStorage::LvmVgInfo::swig_peSize_get(infos);
  1239.         c["pesize"] = 1024*LibStorage::LvmVgInfo::swig_peSize_get(infos);
  1240.         c["cyl_count"] = LibStorage::LvmVgInfo::swig_peCount_get(infos);
  1241.         c["pe_free"] = LibStorage::LvmVgInfo::swig_peFree_get(infos);
  1242.         c["lvm2"] = LibStorage::LvmVgInfo::swig_lvm2_get(infos);
  1243.         list<string> ls = splitstring( LibStorage::LvmVgInfo::swig_devices_get(infos), " " );
  1244.         y2milestone( "ls=%1", ls );
  1245.         c["devices"] = ls;
  1246.         ls = splitstring( LibStorage::LvmVgInfo::swig_devices_add_get(infos), " " );
  1247.         if( size(ls)>0 )
  1248.         c["devices_add"] = ls;
  1249.         ls = splitstring( LibStorage::LvmVgInfo::swig_devices_rem_get(infos), " " );
  1250.         if( size(ls)>0 )
  1251.         c["devices_rem"] = ls;
  1252.         }
  1253.     else
  1254.         y2warning( "LVM Vg \"%1\" ret:%2", c["name"]:"", ret );
  1255.     ret = LibStorage::StorageInterface::getLvmLvInfo( sint, n, pinfos );
  1256.     foreach( any info, pinfos,
  1257.         ``{
  1258.         map p = $[];
  1259.         vinfo = LibStorage::LvmLvInfo::swig_v_get(info);
  1260.         p = volumeMap( vinfo, p );
  1261.         p["stripes"] = LibStorage::LvmLvInfo::swig_stripe_get(info);
  1262.         t = LibStorage::LvmLvInfo::swig_stripe_size_get(info);
  1263.         if( t>0 )
  1264.         p["stripesize"] = t;
  1265.         p["type"] = `lvm;
  1266.         p["fstype"] = Partitions::lv_name;
  1267.         c["partitions"] = add( c["partitions"]:[], p );
  1268.         });
  1269.     }
  1270.     else if( c["type"]:`CT_UNKNOWN == `CT_EVMS )
  1271.     {
  1272.     list<any> pinfos = [];
  1273.     any infos = LibStorage::EvmsCoInfo::new("LibStorage::EvmsCoInfo");
  1274.     string n = c["name"]:"";
  1275.     c["is_container"] = size(c["name"]:"")>0;
  1276.     if( c["is_container"]:false )
  1277.         {
  1278.         ret = LibStorage::StorageInterface::getEvmsCoInfo( sint, n, infos );
  1279.         if( ret==0 )
  1280.         {
  1281.         c["create"] = LibStorage::EvmsCoInfo::swig_create_get(infos);
  1282.         c["size_k"] = LibStorage::EvmsCoInfo::swig_sizeK_get(infos);
  1283.         c["cyl_size"] = 1024*LibStorage::EvmsCoInfo::swig_peSize_get(infos);
  1284.         c["pesize"] = 1024*LibStorage::EvmsCoInfo::swig_peSize_get(infos);
  1285.         c["cyl_count"] = LibStorage::EvmsCoInfo::swig_peCount_get(infos);
  1286.         c["pe_free"] = LibStorage::EvmsCoInfo::swig_peFree_get(infos);
  1287.         c["lvm2"] = LibStorage::EvmsCoInfo::swig_lvm2_get(infos);
  1288.         list<string> ls = splitstring( LibStorage::EvmsCoInfo::swig_devices_get(infos), " " );
  1289.         c["devices"] = ls;
  1290.         ls = splitstring( LibStorage::EvmsCoInfo::swig_devices_add_get(infos), " " );
  1291.         if( size(ls)>0 )
  1292.             c["devices_add"] = ls;
  1293.         ls = splitstring( LibStorage::EvmsCoInfo::swig_devices_rem_get(infos), " " );
  1294.         if( size(ls)>0 )
  1295.             c["devices_add"] = ls;
  1296.         }
  1297.         else
  1298.         y2warning( "EVMS Co \"%1\" ret:%2", c["name"]:"", ret );
  1299.         }
  1300.     ret = LibStorage::StorageInterface::getEvmsInfo( sint, n, pinfos );
  1301.     if( ret<0 )
  1302.         y2warning( "getEvmsInfo ret:%1", ret );
  1303.     y2milestone( "getContainerInfo n:%1 ret=%2", n, ret );
  1304.     foreach( any info, pinfos,
  1305.         ``{
  1306.         map p = $[];
  1307.         vinfo = LibStorage::EvmsInfo::swig_v_get(info);
  1308.         p = volumeMap( vinfo, p );
  1309.         p["stripes"] = LibStorage::EvmsInfo::swig_stripe_get(info);
  1310.         t = LibStorage::EvmsInfo::swig_stripe_size_get(info);
  1311.         if( t>0 )
  1312.         p["stripesize"] = t;
  1313.         boolean tbool = LibStorage::EvmsInfo::swig_compatible_get(info);
  1314.         if( !tbool )
  1315.         p["evms_native"] = true;
  1316.         p["type"] = `evms;
  1317.         p["fstype"] = Partitions::evms_name;
  1318.         y2milestone( "partition %1", p );
  1319.         c["partitions"] = add( c["partitions"]:[], p );
  1320.         });
  1321.     }
  1322.     else if( c["type"]:`CT_UNKNOWN == `CT_MD )
  1323.     {
  1324.     list<any> pinfos = [];
  1325.     ret = LibStorage::StorageInterface::getMdInfo( sint, pinfos );
  1326.     if( ret<0 )
  1327.         y2warning( "getMdInfo ret:%1", ret );
  1328.     foreach( any info, pinfos,
  1329.         ``{
  1330.         map p = $[];
  1331.         vinfo = LibStorage::MdInfo::swig_v_get(info);
  1332.         p = volumeMap( vinfo, p );
  1333.         p["nr"] = LibStorage::MdInfo::swig_nr_get(info);
  1334.         integer t = LibStorage::MdInfo::swig_type_get(info);
  1335.         p["raid_type"] = substring( sformat( "%1", toSymbol( conv_mdtype, t )), 1 );
  1336.         if( p["raid_type"]:""=="raid5" )
  1337.         {
  1338.         t = LibStorage::MdInfo::swig_parity_get(info);
  1339.         symbol pt = toSymbol( conv_mdparity, t );
  1340.         if( pt != `par_none )
  1341.             p["parity_algorithm"] = substring( sformat( "%1", pt), 1 );
  1342.         }
  1343.         p["type"] = `sw_raid;
  1344.         p["fstype"] = Partitions::raid_name;
  1345.         t = LibStorage::MdInfo::swig_chunk_get(info);
  1346.         if( t>0 )
  1347.         {
  1348.         p["chunk_size"] = t;
  1349.         }
  1350.         list<string> ls = splitstring( LibStorage::MdInfo::swig_devices_get(info), " " );
  1351.         p["devices"] = ls;
  1352.         c["partitions"] = add( c["partitions"]:[], p );
  1353.         });
  1354.     }
  1355.     else if( c["type"]:`CT_UNKNOWN == `CT_LOOP )
  1356.     {
  1357.     list<any> pinfos = [];
  1358.     ret = LibStorage::StorageInterface::getLoopInfo( sint, pinfos );
  1359.     if( ret<0 )
  1360.         y2warning( "getLoopInfo ret:%1", ret );
  1361.     foreach( any info, pinfos,
  1362.         ``{
  1363.         map p = $[];
  1364.         vinfo = LibStorage::LoopInfo::swig_v_get(info);
  1365.         p = volumeMap( vinfo, p );
  1366.         p["nr"] = LibStorage::LoopInfo::swig_nr_get(info);
  1367.         p["type"] = `loop;
  1368.         p["fstype"] = Partitions::loop_name;
  1369.         p["fpath"] = LibStorage::LoopInfo::swig_file_get(info);
  1370.         p["create_file"] = !LibStorage::LoopInfo::swig_reuseFile_get(info);
  1371.         c["partitions"] = add( c["partitions"]:[], p );
  1372.         });
  1373.     }
  1374.     else if( c["type"]:`CT_UNKNOWN == `CT_DM )
  1375.     {
  1376.     list<any> pinfos = [];
  1377.     ret = LibStorage::StorageInterface::getDmInfo( sint, pinfos );
  1378.     if( ret<0 )
  1379.         y2warning( "getDmInfo ret:%1", ret );
  1380.     foreach( any info, pinfos,
  1381.         ``{
  1382.         map p = $[];
  1383.         vinfo = LibStorage::DmInfo::swig_v_get(info);
  1384.         p = volumeMap( vinfo, p );
  1385.         p["nr"] = LibStorage::DmInfo::swig_nr_get(info);
  1386.         p["type"] = `dm;
  1387.         p["fstype"] = Partitions::dm_name;
  1388.         c["partitions"] = add( c["partitions"]:[], p );
  1389.         });
  1390.     }
  1391.     //y2milestone ("getContainerInfo container %1", remove( c, "partitions" ) );
  1392.     y2milestone ("getContainerInfo container %1", c );
  1393.     return( c );
  1394.     }
  1395.  
  1396. map toDiskMap( map disk, map cinfo )
  1397.     {
  1398.     list<string> l = [ "size_k", "cyl_size", "cyl_count", "label",
  1399.                "max_logical", "max_primary", "type", "readonly",
  1400.                "used_by_type", "used_by", "partitions", "dasdfmt",
  1401.                "udev_id", "udev_path" ];
  1402.     foreach( string s, l,
  1403.     ``{
  1404.     if( haskey( cinfo, s ) )
  1405.         disk[s] = cinfo[s]:(any)0;
  1406.     else if( haskey( disk, s ))
  1407.         disk = remove( disk, s );
  1408.     });
  1409.     return( disk );
  1410.     }
  1411.  
  1412. list<map> getContainers()
  1413.     ``{
  1414.     list<map> ret = [];
  1415.     list<any> cinfos = [];
  1416.     LibStorage::StorageInterface::getContainers( sint, cinfos );
  1417.     foreach( any info, cinfos,
  1418.     ``{
  1419.     map c = $[];
  1420.     c["name"] = LibStorage::ContainerInfo::swig_name_get(info);
  1421.     c["device"] = LibStorage::ContainerInfo::swig_device_get(info);
  1422.     integer t = LibStorage::ContainerInfo::swig_type_get(info);
  1423.     c["type"] = toSymbol( conv_ctype, t );
  1424.     t = LibStorage::ContainerInfo::swig_usedBy_get(info);
  1425.     if( t!=LibStorage::UB_NONE() )
  1426.         {
  1427.         c["used_by_type"] = toSymbol( conv_usedby, t );
  1428.         c["used_by"] = LibStorage::ContainerInfo::swig_usedByName_get(info);
  1429.         }
  1430.     boolean b = LibStorage::ContainerInfo::swig_readonly_get(info);
  1431.     if( b )
  1432.         c["readonly"] = true;
  1433.     ret = add( ret, c );
  1434.     });
  1435.     y2milestone( "getContainers ret:%1", ret );
  1436.     return( ret );
  1437.     };
  1438.  
  1439. integer count=0;
  1440.  
  1441. global void UpdateTargetMap()
  1442.     {
  1443.     conts = getContainers();
  1444.     list<string> rem_keys = [];
  1445.     map<string,map> tg = StorageMap[targets_key]:$[];
  1446.     //SCR::Write(.target.ycp, "/tmp/upd_all_bef_"+sformat("%1",count), StorageMap[targets_key]:$[] );
  1447.     foreach( string dev, map disk, tg,
  1448.     ``{
  1449.     map c = $[];
  1450.     c = find( map c, conts, ``(c["device"]:""==dev) );
  1451.     if( c==nil )
  1452.         rem_keys = add( rem_keys, dev );
  1453.     else if( c["type"]:`CT_UNKNONW==`CT_DISK )
  1454.         {
  1455.         tg[dev] = toDiskMap( tg[dev]:$[], getContainerInfo( c ) );
  1456.         }
  1457.     else
  1458.         {
  1459.         tg[dev] = getContainerInfo(c);
  1460.         }
  1461.     y2milestone( "UpdateTargetMap dev:%1 is:%2", dev, tg[dev]:$[] );
  1462.     });
  1463.     y2milestone( "UpdateTargetMap rem_keys:%1", rem_keys );
  1464.     foreach( string dev, rem_keys, ``{tg=remove(tg,dev);});
  1465.     foreach( map c, conts,
  1466.     ``{
  1467.     if( c["type"]:`CT_UNKNOWN!=`CT_DISK && !haskey( tg, c["device"]:"" ))
  1468.         {
  1469.         tg[c["device"]:""] = getContainerInfo(c);
  1470.         y2milestone( "UpdateTargetMap dev:%1 is:%2", c["device"]:"",
  1471.                      tg[c["device"]:""]:$[] );
  1472.         }
  1473.     });
  1474.     StorageMap[targets_key] = tg;
  1475.     UpdateChangeTime();
  1476.     //SCR::Write(.target.ycp, "/tmp/upd_all_aft_"+sformat("%1",count), StorageMap[targets_key]:$[] );
  1477.     //count = count+1;
  1478.     }
  1479.  
  1480. define void UpdateTargetMapDisk( string dev )
  1481.     {
  1482.     y2milestone( "UpdateTargetMapDisk" );
  1483.     conts = getContainers();
  1484.     map c = $[];
  1485.     c = find( map c, conts, ``(c["device"]:""==dev) );
  1486.     map tg = StorageMap[targets_key]:$[];
  1487.     //SCR::Write(.target.ycp, "/tmp/upd_disk_bef_"+sformat("%1",count), StorageMap[targets_key]:$[] );
  1488.     if( c==nil )
  1489.     {
  1490.     if( haskey( tg, dev ) )
  1491.         tg = remove( tg, dev );
  1492.     }
  1493.     else if( c["type"]:`CT_UNKNONW==`CT_DISK )
  1494.     {
  1495.     tg[dev] = toDiskMap( tg[dev]:$[], getContainerInfo( c ) );
  1496.     }
  1497.     else
  1498.     {
  1499.     tg[dev] = getContainerInfo(c);
  1500.     }
  1501.     StorageMap[targets_key] = tg;
  1502.     UpdateChangeTime();
  1503.     //SCR::Write(.target.ycp, "/tmp/upd_disk_aft_"+sformat("%1",count), StorageMap[targets_key]:$[] );
  1504.     //count = count+1;
  1505.     }
  1506.  
  1507. define void UpdateTargetMapDev( string dev )
  1508.     {
  1509.     y2milestone( "UpdateTargetMapDev %1", dev );
  1510.     map<string,map> tg = StorageMap[targets_key]:$[];
  1511.     //SCR::Write(.target.ycp, "/tmp/upd_dev_bef_"+sformat("%1",count), tg );
  1512.     string cdev="";
  1513.     foreach( string key, map d, tg,
  1514.     ``{
  1515.     if( size(cdev)==0 &&
  1516.         find( map p, d["partitions"]:[], ``(p["device"]:""==dev))!=nil )
  1517.         cdev = d["device"]:"";
  1518.     });
  1519.     y2milestone( "UpdateTargetMapDev cdev %1", cdev );
  1520.     map c = $[];
  1521.     c = find( map c, conts, ``(c["device"]:""==cdev) );
  1522.     map disk = $[];
  1523.     if( c!=nil )
  1524.     {
  1525.     disk = getContainerInfo( c );
  1526.     }
  1527.     if( c!=nil && haskey( tg, cdev ))
  1528.     {
  1529.     list<map> partitions = tg[cdev,"partitions"]:[];
  1530.     boolean found = false;
  1531.     partitions = maplist( map p, partitions,
  1532.         ``{
  1533.         if( p["device"]:"" == dev )
  1534.         {
  1535.         map pp = find( map q, disk["partitions"]:[],
  1536.                    ``(q["device"]:""==dev));
  1537.         if( pp!=nil )
  1538.             {
  1539.             found = true;
  1540.             p = pp;
  1541.             }
  1542.         }
  1543.         return( p );
  1544.         });
  1545.     tg[disk["device"]:"","partitions"] = partitions;
  1546.     if( !found )
  1547.         y2error( "UpdateTargetMapDev not found %1", dev );
  1548.     }
  1549.     else
  1550.     y2error( "UpdateTargetMapDev key %1 not found in target", disk["device"]:"" );
  1551.     StorageMap[targets_key] = tg;
  1552.     UpdateChangeTime();
  1553.     //SCR::Write(.target.ycp, "/tmp/upd_dev_aft_"+sformat("%1",count), StorageMap[targets_key]:$[] );
  1554.     //count = count+1;
  1555.     }
  1556.  
  1557. global define map getDiskInfo( string device, map disk )
  1558.     {
  1559.     map c = $[];
  1560.     c = find( map p, conts, ``(p["device"]:""==device ));
  1561.     if( c==nil )
  1562.     {
  1563.     map tmp = GetDiskPartition( device );
  1564.     y2milestone( "getDiskInfo map %1", tmp );
  1565.     if( tmp["disk"]:"" != device )
  1566.         c = find( map p, conts, ``(p["device"]:""==tmp["disk"]:"" ));
  1567.     }
  1568.     y2milestone( "getDiskInfo c:%1", c );
  1569.     if( c!=nil )
  1570.     {
  1571.     disk = toDiskMap( disk, getContainerInfo( c ) );
  1572.     y2milestone( "getDiskInfo ret:%1", 
  1573.                  haskey(disk,"partitions")?remove(disk,"partitions"):disk );
  1574.     }
  1575.     return( disk );
  1576.     }
  1577.  
  1578. global define void SaveExitKey( symbol key )
  1579.     ``{
  1580.     if( key == `next || key == `back )
  1581.     {
  1582.     exit_key = key;
  1583.     y2milestone( "Exit Key %1", exit_key );
  1584.     }
  1585.     };
  1586.  
  1587. global define symbol GetExitKey()
  1588.     ``{
  1589.     return( exit_key );
  1590.     };
  1591.  
  1592. global define void SetLastUsed( string device )
  1593.     {
  1594.     if( size(device)>0 )
  1595.     last_used = device;
  1596.     }
  1597.  
  1598. global define string GetLastUsed()
  1599.     {
  1600.     return( last_used );
  1601.     }
  1602.  
  1603. global define map FindFstabEntry( map fstab, string mount, string device,
  1604.                       string uuid, string label )
  1605.     {
  1606.     map ret = $[];
  1607.     list lines = [];
  1608.     lines = FindFstabLines( fstab, mount, device, uuid, label );
  1609.     y2milestone( "mount=%1 device=%2 uuid=%3 label=%4", mount, device, uuid,
  1610.                  label );
  1611.     if( size(lines)>0 )
  1612.     {
  1613.     map entry = AsciiFile::GetLine( fstab, lines[0]:-1 );
  1614.     ret = $[ "spec" : entry["fields",0]:"",
  1615.              "file" : entry["fields",1]:"",
  1616.              "vfstype" : entry["fields",2]:"",
  1617.              "mntops" : entry["fields",3]:"",
  1618.              "freq" : entry["fields",4]:0,
  1619.              "passno" : entry["fields",5]:0 ];
  1620.     }
  1621.     y2milestone( "ret:%1", ret );
  1622.     return( ret );
  1623.     }
  1624.  
  1625. global define map<string,map> GetTargetMap();
  1626.  
  1627. global define map GetOndiskTarget()
  1628.     {
  1629.     list keys = [ "mount", "enc_type", "mountby", "fstopt", "used_fs", "format" ];
  1630.     map<string,map> ret = GetTargetMap();
  1631.     foreach( string d, map disk, ret,
  1632.     ``{
  1633.     list<map> pl =
  1634.         maplist( map<string,any> p, disk["partitions"]:[],
  1635.              ``( filter( string k, any e, p, ``(!contains(keys,k)))));
  1636.     pl = maplist( map p, pl,
  1637.               ``({
  1638.               if( p["detected_fs"]:`unknown!=`unknown )
  1639.               p["used_fs"] = p["detected_fs"]:`unknown;
  1640.               return(p);
  1641.               }));
  1642.     ret[d,"partitions"] = pl;
  1643.     });
  1644.     return( ret );
  1645.     }
  1646.  
  1647. global define void CreateTargetBackup(string who)
  1648.     {
  1649.     string t = "targetMap_s_" + who + "_" + sformat("%1",count);
  1650.     count = count+1;
  1651.     SCR::Write(.target.ycp, Storage::SaveDumpPath(t), GetTargetMap() );
  1652.     y2milestone( "CreateTargetBackup who:%1", who );
  1653.     integer ret = LibStorage::StorageInterface::createBackupState( sint, who );
  1654.     if( ret<0 )
  1655.     y2error( "CreateTargetBackup sint ret:%1", ret );
  1656.     }
  1657.  
  1658. global define void DisposeTargetBackup(string who)
  1659.     {
  1660.     y2milestone( "DisposeTargetBackup who:%1", who );
  1661.     integer ret = LibStorage::StorageInterface::removeBackupState( sint, who );
  1662.     if( ret<0 )
  1663.     y2error( "DisposeTargetBackup sint ret:%1", ret );
  1664.     }
  1665.  
  1666. global define boolean EqualBackupStates( string s1, string s2, boolean vb )
  1667.     {
  1668.     y2milestone( "EqualBackupStates s1:\"%1\" s2:\"%2\" verbose:%3",
  1669.                  s1, s2, vb );
  1670.     boolean ret = LibStorage::StorageInterface::equalBackupStates( sint, s1,
  1671.                                                                    s2, vb );
  1672.     y2milestone( "EqualBackupStates ret:%1", ret );
  1673.     return( ret );
  1674.     }
  1675.  
  1676. global define void RestoreTargetBackup( string who )
  1677.     {
  1678.     y2milestone( "RestoreTargetBackup who:%1", who );
  1679.     integer ret = LibStorage::StorageInterface::restoreBackupState( sint, who );
  1680.     if( ret<0 )
  1681.     y2error( "RestoreTargetBackup sint ret:%1", ret );
  1682.     UpdateTargetMap();
  1683.     string t = "targetMap_r_" + who;
  1684.     SCR::Write(.target.ycp, Storage::SaveDumpPath(t), GetTargetMap() );
  1685.     }
  1686.  
  1687. global define void ResetOndiskTarget()
  1688.     {
  1689.     RestoreTargetBackup( "initial" );
  1690.     }
  1691.  
  1692. global define integer GetTargetChangeTime()
  1693.     {
  1694.     return( StorageMap["targets_time"]:0 );
  1695.     }
  1696.  
  1697. global define boolean GetPartProposalActive()
  1698.     {
  1699.     return StorageMap[part_proposal_active_key]:true;
  1700.     };
  1701.  
  1702. global define void SetPartProposalActive( boolean value )
  1703.     {
  1704.     StorageMap[part_proposal_active_key] = value;
  1705.     };
  1706.  
  1707. global define string GetPartMode()
  1708.     {
  1709.     y2milestone( "GetPartMode %1", StorageMap[part_mode_key]:"" );
  1710.     return StorageMap[part_mode_key]:"";
  1711.     };
  1712.  
  1713. global define void SetPartMode( string value )
  1714.     {
  1715.     y2milestone( "SetPartMode %1", value );
  1716.     StorageMap[part_mode_key] = value;
  1717.     };
  1718.  
  1719. global define boolean GetCustomDisplay()
  1720.     {
  1721.     return StorageMap[custom_display_key]:false;
  1722.     };
  1723.  
  1724. global define void SetCustomDisplay( boolean value )
  1725.     {
  1726.     StorageMap[custom_display_key] = value;
  1727.     };
  1728.  
  1729. global define string GetPartDisk()
  1730.     {
  1731.     return StorageMap[part_disk_key]:"";
  1732.     };
  1733.  
  1734. global define void SetPartDisk( string value )
  1735.     {
  1736.     StorageMap[part_disk_key] = value;
  1737.     };
  1738.  
  1739.  
  1740.   global define boolean GetTestsuite()``{
  1741.       return StorageMap[testsuite_key]:false;
  1742.   }
  1743.  
  1744.   global define void SetTestsuite( boolean value ) ``{
  1745.       StorageMap = add( StorageMap, testsuite_key, value );
  1746.   }
  1747.  
  1748.   global define boolean GetLvmViewAllMnt()``{
  1749.       return StorageMap[lvm_view_all_mnt_key]:true;
  1750.   }
  1751.  
  1752.   global define void SetLvmViewAllMnt( boolean value ) ``{
  1753.       StorageMap = add( StorageMap, lvm_view_all_mnt_key, value );
  1754.   }
  1755.  
  1756.   global define boolean GetRaidtabCreated()``{
  1757.       return StorageMap[raidtab_created_key]:false;
  1758.   }
  1759.  
  1760.   global define void SetRaidtabCreated( boolean value ) ``{
  1761.       StorageMap = add( StorageMap, raidtab_created_key, value );
  1762.   }
  1763.  
  1764.   global define string GetDoResize()``{
  1765.       return StorageMap[do_resize_key]:"NO";
  1766.   }
  1767.  
  1768.   global define void SetDoResize( string value ) ``{
  1769.       StorageMap = add( StorageMap, do_resize_key, value );
  1770.   }
  1771.  
  1772.   global define string GetPartProposalMode()``{
  1773.       return StorageMap[part_proposal_mode_key]:"accept";
  1774.   }
  1775.  
  1776.   global define void SetPartProposalMode( string value ) ``{
  1777.       StorageMap = add( StorageMap, part_proposal_mode_key, value );
  1778.   }
  1779.  
  1780.   global define boolean GetWholeDisk()``{
  1781.       return StorageMap[whole_disk_key]:false;
  1782.   }
  1783.  
  1784.   global define void SetWholeDisk( boolean value ) ``{
  1785.       StorageMap = add( StorageMap, whole_disk_key, value );
  1786.   }
  1787.  
  1788.   global define boolean GetPartProposalFirst()``{
  1789.       return StorageMap[part_proposal_first_key]:true;
  1790.   }
  1791.  
  1792.   global define void SetPartProposalFirst( boolean value ) ``{
  1793.       StorageMap = add( StorageMap, part_proposal_first_key, value );
  1794.   }
  1795.  
  1796.   global define boolean GetWinDevice()``{
  1797.       return StorageMap[win_device_key]:false;
  1798.   }
  1799.  
  1800.   global define void SetWinDevice( boolean value ) ``{
  1801.       StorageMap = add( StorageMap, win_device_key, value );
  1802.     }
  1803.  
  1804.  
  1805.  
  1806.  
  1807.     /* StorageMaps =  [
  1808.        1: $[  storage_map_key        :     $[ Storage_01],
  1809.               storage_type_key        :    `record,
  1810.           ],
  1811.        2, $[ storage_map_key        :     $[ Storage_02],
  1812.              storage_type_key        :     `custom,
  1813.              storage_doc_key         :    "create partition /dev/hda2"
  1814.          ],
  1815.        3: $[ storage_map_key        :       $[ Storage_03 ],
  1816.              storage_type_key        :    `custom,
  1817.          storage_doc_key        :    "delete partition /dev/hda1"
  1818.          ],
  1819.        4: $[ storage_map_key        :     $[ Storage_04 ],
  1820.              storage_type_key        :     `record
  1821.          ]
  1822.     ];
  1823.     */
  1824.  
  1825.  
  1826.  
  1827.     /* Record - Rollback - Commit */
  1828.     /* update focus and Storage - StorageStack */
  1829.  
  1830.     /* Find the next free position in the map StorageMaps
  1831.      * @return integer
  1832.      */
  1833.     define integer NextStorageMapsPos() ``{
  1834.     return (size( StorageMaps) + 1);
  1835.     }
  1836.  
  1837.  
  1838.     define integer FindLastRecordEntry() ``{
  1839.     map<integer,any> all_record_entries = (map<integer,any>)filter (integer key, map entry , StorageMaps, ``( entry[storage_type_key]:custom_key == record_key ));
  1840.     list<integer> all_record_keys   = (list<integer>) maplist(integer key, any entry , all_record_entries,  ``(  key ));
  1841.  
  1842.     if( size( all_record_entries ) > 0 )
  1843.         return sort(integer x, integer y, all_record_keys , ``(y < x))[0]:1;
  1844.     else return 0;
  1845.     }
  1846.  
  1847.  
  1848.     define void Rollback2Pos(integer pos ) ``{
  1849.     StorageMap = StorageMaps[pos,storage_map_key]:$[];
  1850.     StorageMaps = filter(integer key, map entry, StorageMaps, ``( key < pos ));
  1851.     }
  1852.  
  1853.  
  1854.     define void AddEntry2StorageMaps(symbol type_key, string doc )``{
  1855.     map storage_maps_entry = $[];
  1856.  
  1857.     storage_maps_entry = add(storage_maps_entry, storage_map_key  , StorageMap    );
  1858.     storage_maps_entry = add(storage_maps_entry, storage_type_key , type_key   );
  1859.  
  1860.     if( doc != "" )
  1861.         storage_maps_entry = add(storage_maps_entry, storage_type_key , doc    );
  1862.  
  1863.     StorageMaps = add( StorageMaps, NextStorageMapsPos(), storage_maps_entry );
  1864.     }
  1865.  
  1866.  
  1867.     /**
  1868.      *
  1869.      * @return boolean
  1870.      */
  1871.     global define void Record()``{
  1872.     AddEntry2StorageMaps( record_key, "");
  1873.     }
  1874.  
  1875.     /**
  1876.      *
  1877.      * @return boolean
  1878.      */
  1879.     global define boolean Rollback()``{
  1880.     integer last_record_entry =  FindLastRecordEntry();
  1881.     if( last_record_entry != 0 )
  1882.     {
  1883.         Rollback2Pos( last_record_entry );
  1884.         return true;
  1885.     }
  1886.     else
  1887.     {
  1888.         return false;
  1889.     }
  1890.     }
  1891.  
  1892.     /**
  1893.      *
  1894.      *    @return boolean
  1895.      */
  1896. global define boolean Commit()
  1897.     ``{
  1898.     integer last_record_entry = FindLastRecordEntry();
  1899.     if( last_record_entry != 0 )
  1900.     {
  1901.     StorageMaps = filter( integer key, map entry, StorageMaps,
  1902.                   ``( key < last_record_entry ));
  1903.     return true;
  1904.     }
  1905.     else
  1906.     {
  1907.     return false;
  1908.     }
  1909.     }
  1910.  
  1911. global define void InstallCallbacks()
  1912.     {
  1913.     StorageClients::InstallCallbacks();
  1914.     }
  1915.  
  1916.  
  1917. global define void Storage()
  1918.     ``{
  1919.     y2milestone( "constructor Storage()" );
  1920.     StorageMap[targets_backup_key] = $[];
  1921.     StorageMap[targets_backup_l_key] = $[];
  1922.     StorageMap[targets_backup_m_key] = $[];
  1923.     if( Mode::normal () )
  1924.     {
  1925.     Storage::SetPartMode( "CUSTOM" );
  1926.     Storage::SetPartProposalActive( false  );
  1927.     }
  1928.     InstallCallbacks();
  1929.     }
  1930.  
  1931.  
  1932.     /* Dev definitions
  1933.  
  1934.        dev     = maindev  | subdev
  1935.        maindev = "disk"   | "vg"    | "md" (raiddev)
  1936.        subdev  = "part"   | "lv"     | "raid"
  1937.  
  1938.        e.g.:     "disk" = "/dev/hda"    | "dev/sda"    | "/dev/hdd"  | ...
  1939.                 "vg"   = "/dev/system"     | "dev/group"   | ...
  1940.         "md"   = "/dev/md"  (only)
  1941.         "part" = "1//dev/hda"    | "2//dev/sda"    | ..
  1942.         "lv"   = "usr//dev/system" | "home//dev/system"
  1943.     */
  1944.  
  1945.  
  1946.     /* Key definitions
  1947.  
  1948.        key = maindevkey | subdevkey + maindevkey
  1949.  
  1950.        maindevkey    = key( disk | vg | md   )
  1951.        subdevkey    = key( part | lv | raid )
  1952.        subdevkey        = maindevkey + subdevindex | "all"
  1953.  
  1954.        subdevindex     = 1 | 2 | "home" | "usr" | ..
  1955.  
  1956.        e.g.:
  1957.        maindevkey    = "/dev/hda"    | "/dev/md"    | "/dev/system"        | "all"
  1958.        subdevkey    = "1//dev/hda"    | "1//dev/md"    | "home//dev/system"     | "all"
  1959.  
  1960.  
  1961.    */
  1962.  
  1963.     /* MainDev defines ------------------------------------------------------------------
  1964.     /* partition_defines -> isDisk */
  1965.     /* partition_defines -> isRaid */
  1966.     /* partition_defines -> isLVM  */
  1967.     symbol sw_raid_type_key = `sw_raid;
  1968.     symbol lvm_type_key        = `lvm;
  1969.     symbol extended_type_key= `extended;
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975. global define map<string,map> RemoveAllPartEntry( map<string,map> tg, string skey, string value )
  1976.     ``{
  1977.     map<string,map> new_tg = tg;
  1978.  
  1979.     foreach(string dev, map disk, tg,
  1980.     ``{
  1981.     boolean changed = false;
  1982.     list new_partitions = [];
  1983.     foreach (map partition, disk["partitions"]:[],
  1984.         ``{
  1985.         if( partition[skey]:"" == value )
  1986.         {
  1987.         partition = filter(string key, any value_inner, (map<string,any>)partition, ``( key != skey));
  1988.         changed = true;
  1989.         }
  1990.         new_partitions = add( new_partitions , partition);
  1991.         });
  1992.  
  1993.     if( changed )
  1994.         {
  1995.         disk["partitions"] = new_partitions;
  1996.         new_tg[dev] = disk;
  1997.         }
  1998.     });
  1999.     return( new_tg );
  2000.     };
  2001.  
  2002. global define list<map> RenumberS390Partitions( string dname,
  2003.                                                 list<map> partitions )
  2004.     ``{
  2005.     integer cnt = 1;
  2006.     partitions = sort( map a, map b, partitions,
  2007.                        ``(a["region",0]:0<b["region",0]:0));
  2008.     partitions = maplist( map p, partitions,
  2009.     ``{
  2010.     if( p["nr"]:0 != cnt )
  2011.         {
  2012.         if( !haskey( p, "ori_nr" ) )
  2013.         {
  2014.         p["ori_nr"] = p["nr"]:0;
  2015.         }
  2016.         p["nr"] = cnt;
  2017.         p["device"] = GetDeviceName( dname, cnt );
  2018.         }
  2019.     cnt = cnt+1;
  2020.     return( p );
  2021.     });
  2022.     y2milestone( "RenumberS390Partions %1", partitions );
  2023.     return( partitions );
  2024.     }
  2025.  
  2026. global define map<string, map>
  2027. RenameTgDevices( map<string, map> tg, map<string, string> ren )
  2028.     ``{
  2029.     y2milestone( "RenameTgDevices ren:%1", ren );
  2030.     foreach( string dev, map co, tg,
  2031.     ``{
  2032.     if( search( dev, "/dev/evms/" ) == 0 )
  2033.         {
  2034.         y2milestone( "RenameTgDevices before added:%1 removed:%2",
  2035.                      co["added"]:[], co["removed"]:[] );
  2036.         if( size(co["added"]:[])>0 )
  2037.         {
  2038.         co["added"] =
  2039.             maplist( string d, co["added"]:[],
  2040.                  ``(haskey( ren, d )?(ren[d]:""):d));
  2041.         }
  2042.         if( size(co["removed"]:[])>0 )
  2043.         {
  2044.         co["removed"] =
  2045.             maplist( string d, co["removed"]:[],
  2046.                  ``(haskey( ren, d )?(ren[d]:""):d));
  2047.         }
  2048.         y2milestone( "RenameTgDevices after added:%1 removed:%2",
  2049.                      co["added"]:[], co["removed"]:[] );
  2050.         tg[dev] = co;
  2051.         }
  2052.     });
  2053.     return( tg );
  2054.     }
  2055.  
  2056. global define map<integer, map>
  2057. RenameMtDevices( map<integer, map> mt, map<string, string> ren )
  2058.     ``{
  2059.     y2milestone( "RenameMtDevices ren:%1", ren );
  2060.     foreach( integer num, map entry, mt,
  2061.     ``{
  2062.     if( entry["type"]:""=="create_vg" && size(entry["devices"]:[])>0 )
  2063.         {
  2064.         y2milestone( "RenameMtDevices before entry:%1", entry );
  2065.         entry["devices"] =
  2066.         maplist( string d, entry["devices"]:[],
  2067.              ``(haskey( ren, d )?(ren[d]:""):d));
  2068.         y2milestone( "RenameMtDevices after entry:%1", entry );
  2069.         mt[num] = entry;
  2070.         }
  2071.     if( (entry["type"]:""=="create_pv" || entry["type"]:""=="remove_pv") &&
  2072.         haskey( ren, entry["device"]:"" ))
  2073.         {
  2074.         y2milestone( "RenameMtDevices before entry:%1", entry );
  2075.         entry["device"] = ren[entry["device"]:""]:"";
  2076.         y2milestone( "RenameMtDevices after entry:%1", entry );
  2077.         mt[num] = entry;
  2078.         }
  2079.     });
  2080.     return( mt );
  2081.     }
  2082.  
  2083. global map NextPartition( string disk, symbol ptype )
  2084.     {
  2085.     y2milestone( "NextPartition disk:%1 ptype:%2", disk, ptype );
  2086.     map ret = $[];
  2087.     integer pt = fromSymbol(conv_ptype,ptype);
  2088.     y2milestone( "NextPartition type:%1 pt:%2", ptype, pt );
  2089.     integer num = 0;
  2090.     string dev = "";
  2091.     integer r = LibStorage::StorageInterface::nextFreePartition( sint, disk,
  2092.                                                                  pt, num, dev );
  2093.     if( r<0 )
  2094.     y2error( "NextPartition ret %1", r );
  2095.     ret["device"] = dev;
  2096.     ret["nr"] = num;
  2097.     y2milestone( "NextPartition sint ret:%1 map:%2", r, ret );
  2098.     return( ret );
  2099.     }
  2100.  
  2101. global boolean CreatePartition( string disk, string device, symbol ptype,
  2102.                                 integer id, integer start, integer len )
  2103.     {
  2104.     y2milestone( "CreatePartition disk:%1 device:%2 ptype:%3 id:%4 start:%5 len:%6",
  2105.                  disk, device, ptype, id, start, len );
  2106.     string cdev = "";
  2107.     integer pt = fromSymbol(conv_ptype,ptype);
  2108.     y2milestone( "CreatePartition type:%1 pt:%2", ptype, pt );
  2109.     integer ret = LibStorage::StorageInterface::createPartition( sint, disk, pt,
  2110.                                  start, len,
  2111.                                  cdev );
  2112.     if( device!=cdev )
  2113.     y2error( "CreatePartition device:%1 cdev:%2", device, cdev );
  2114.     if( ret<0 )
  2115.     y2error( "CreatePartition ret %1", ret );
  2116.     ret = LibStorage::StorageInterface::changePartitionId( sint, device,
  2117.                                id );
  2118.     if( ret<0 )
  2119.     y2error( "CreatePartition ret %1", ret );
  2120.     y2milestone( "CreatePartition sint ret:%1", ret );
  2121.     UpdateTargetMap();
  2122.     return( ret==0 );
  2123.     }
  2124.  
  2125. global boolean UpdatePartition( string device, integer start, integer len )
  2126.     {
  2127.     y2milestone( "UpdatePartition device:%1 start:%2 len:%3",
  2128.                  device, start, len );
  2129.     integer ret = 0;
  2130.     ret = LibStorage::StorageInterface::updatePartitionArea( sint, device,
  2131.                                  start, len );
  2132.     if( ret<0 )
  2133.     y2error( "UpdatePartition sint ret:%1", ret );
  2134.     UpdateTargetMapDev( device );
  2135.     return( ret==0 );
  2136.     }
  2137.  
  2138. global boolean SetPartitionMount( string device, string mp )
  2139.     {
  2140.     y2milestone( "SetPartitionMount device:%1 mp:%2", device, mp );
  2141.     integer ret = 0;
  2142.     ret = LibStorage::StorageInterface::changeMountPoint( sint, device, mp );
  2143.     if( ret<0 )
  2144.     y2error( "SetPartitionMount sint ret:%1", ret );
  2145.     UpdateTargetMapDev( device );
  2146.     return( ret==0 );
  2147.     }
  2148.  
  2149. global boolean SetPartitionFormat( string device, boolean format, symbol fs )
  2150.     {
  2151.     y2milestone( "SetPartitionFormat device:%1 format:%2 fs:%3", device,
  2152.                  format, fs );
  2153.     integer ret = 0;
  2154.     integer tmp = fromSymbol( FileSystems::conv_fs, fs );
  2155.     y2milestone( "SetPartitionFormat fs:%1", tmp );
  2156.     ret = LibStorage::StorageInterface::changeFormatVolume( sint, device,
  2157.                                                             format, tmp );
  2158.     if( ret<0 )
  2159.     y2error( "SetPartitionFormat sint ret:%1", ret );
  2160.     UpdateTargetMapDev( device );
  2161.     return( ret==0 );
  2162.     }
  2163.  
  2164. global boolean SetPartitionId( string device, integer id )
  2165.     {
  2166.     y2milestone( "SetPartitionId device:%1 id:%2", device, id );
  2167.     integer ret = 0;
  2168.     ret = LibStorage::StorageInterface::changePartitionId( sint, device, id );
  2169.     if( ret<0 )
  2170.     y2error( "SetPartitionId sint ret:%1", ret );
  2171.     UpdateTargetMapDev( device );
  2172.     return( ret==0 );
  2173.     }
  2174.  
  2175. global boolean UnchangePartitionId( string device )
  2176.     {
  2177.     y2milestone( "UnchangePartitionId device:%1", device );
  2178.     integer ret = 0;
  2179.     ret = LibStorage::StorageInterface::forgetChangePartitionId( sint, device );
  2180.     if( ret<0 )
  2181.     y2error( "UnchangePartitionId sint ret:%1", ret );
  2182.     UpdateTargetMapDev( device );
  2183.     return( ret==0 );
  2184.     }
  2185.  
  2186. global boolean ResizeVolume( string device, string disk, integer new_size )
  2187.     {
  2188.     y2milestone( "ResizeVolume device:%1 disk:%2 new_size:%3", device, disk,
  2189.                  new_size );
  2190.     integer ret = 0;
  2191.     ret = LibStorage::StorageInterface::resizeVolume( sint, device,
  2192.                                                       (new_size+1023)/1024 );
  2193.     if( ret<0 )
  2194.     y2error( "ResizeVolume sint ret:%1", ret );
  2195.     UpdateTargetMapDisk( disk );
  2196.     return( ret==0 );
  2197.     }
  2198.  
  2199. global boolean SetCrypt( string device, boolean crpt, boolean format )
  2200.     {
  2201.     y2milestone( "SetCrypt device:%1 val:%2 format:%3", device, crpt, format );
  2202.     boolean is_crypt = false;
  2203.     integer ret = LibStorage::StorageInterface::getCrypt( sint, device, 
  2204.                                                           is_crypt );
  2205.     if( ret==0 && !format && is_crypt==crpt )
  2206.     y2milestone( "SetCrypt crypt already set" );
  2207.     else
  2208.     {
  2209.     ret = LibStorage::StorageInterface::setCrypt( sint, device, crpt );
  2210.     if( ret<0 )
  2211.         {
  2212.         y2error( "SetCrypt sint ret:%1", ret );
  2213.         if( !format && crpt )
  2214.         Popup::Error( sformat(_("Could not set encryption.
  2215. System error code is %1.
  2216.  
  2217. The crypt password provided could be incorrect.
  2218. "), ret ));
  2219.         LibStorage::StorageInterface::forgetCryptPassword( sint, device );
  2220.         }
  2221.     else
  2222.         y2milestone( "SetCrypt sint ret:%1", ret );
  2223.     }
  2224.     return( ret==0 );
  2225.     }
  2226.  
  2227. integer ChangeDescText( string dev, string txt )
  2228.     {
  2229.     integer ret = LibStorage::StorageInterface::changeDescText( sint, dev, txt );
  2230.     return( ret );
  2231.     }
  2232.  
  2233. global boolean ChangeVolumeProperties( map part )
  2234.     {
  2235.     integer ret = 0;
  2236.     integer tmp = 0;
  2237.     boolean changed = false;
  2238.     string ts = "";
  2239.     string dev = part["device"]:"";
  2240.     any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
  2241.     ret = LibStorage::StorageInterface::getVolume( sint, dev, vinfo );
  2242.     if( ret!=0 )
  2243.     y2error( "ChangeVolumeProperties device:%1 not found", dev );
  2244.     map curr = $[];
  2245.     if( ret==0 )
  2246.     {
  2247.     curr = volumeMap( vinfo, curr );
  2248.     }
  2249.     if( ret==0 && part["mount"]:"" != curr["mount"]:"" )
  2250.     {
  2251.     changed = true;
  2252.     ts = part["mount"]:"";
  2253.     ret = LibStorage::StorageInterface::changeMountPoint( sint, dev, ts );
  2254.     if( ret<0 )
  2255.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2256.     else
  2257.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2258.     }
  2259.     if( ret==0 && part["type"]:`unknown != `extended &&
  2260.         (part["format"]:false != curr["format"]:false ||
  2261.          part["used_fs"]:`none != curr["used_fs"]:`none) )
  2262.     {
  2263.     changed = true;
  2264.     tmp = fromSymbol(FileSystems::conv_fs,part["used_fs"]:`none);
  2265.     y2milestone( "ChangeVolumeProperties fs:%1 symbol:%2", tmp, part["used_fs"]:`none );
  2266.     ret = LibStorage::StorageInterface::changeFormatVolume( sint, dev,
  2267.                                 part["format"]:false,
  2268.                                 tmp );
  2269.     if( ret<0 )
  2270.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2271.     else
  2272.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2273.     }
  2274.     if( ret==0 &&
  2275.         size(part["mount"]:"")>0 && part["fstopt"]:"" != curr["fstopt"]:"" )
  2276.     {
  2277.     changed = true;
  2278.     ts = part["fstopt"]:"";
  2279.     ret = LibStorage::StorageInterface::changeFstabOptions( sint, dev, ts );
  2280.     if( ret<0 )
  2281.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2282.     else
  2283.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2284.     }
  2285.     if( ret==0 && part["mountby"]:`device != curr["mountby"]:`device )
  2286.     {
  2287.     changed = true;
  2288.     tmp = fromSymbol(conv_mountby,part["mountby"]:`device);
  2289.     y2milestone( "ChangeVolumeProperties mby:%1", tmp );
  2290.     ret = LibStorage::StorageInterface::changeMountBy( sint, dev, tmp );
  2291.     if( ret<0 )
  2292.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2293.     else
  2294.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2295.     }
  2296.     if( ret==0 && part["label"]:"" != curr["label"]:"" )
  2297.     {
  2298.     changed = true;
  2299.     ts = part["label"]:"";
  2300.     ret = LibStorage::StorageInterface::changeLabelVolume( sint, dev, ts );
  2301.     if( ret<0 )
  2302.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2303.     else
  2304.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2305.     }
  2306.     if( ret==0 && part["format"]:false && 
  2307.     convertFsOptionMapToString(part["fs_options"]:$[]) != curr["mkfs_opt"]:"" )
  2308.     {
  2309.     changed = true;
  2310.     ts = convertFsOptionMapToString(part["fs_options"]:$[]);
  2311.     y2milestone( "FsOption ts:%1", ts );
  2312.     ret = LibStorage::StorageInterface::changeMkfsOptVolume( sint, dev, ts );
  2313.     if( ret<0 )
  2314.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2315.     else
  2316.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2317.     }
  2318.     if( ret==0 &&
  2319.         part["enc_type"]:`none != `none && haskey( ClassifiedSettings, dev ) )
  2320.     {
  2321.     changed = true;
  2322.         if( size(ClassifiedSettings[dev]:"")>0 )
  2323.         {
  2324.         string pwd = ClassifiedSettings[dev]:"";
  2325.         ret = LibStorage::StorageInterface::setCryptPassword( sint, dev,
  2326.                                   pwd );
  2327.         if( ret<0 )
  2328.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2329.         else
  2330.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2331.         }
  2332.     }
  2333.     if( ret==0 && part["enc_type"]:`none != curr["enc_type"]:`none )
  2334.     {
  2335.     changed = true;
  2336.     SetCrypt( dev, part["enc_type"]:`none!=`none, part["format"]:false );
  2337.     }
  2338.     if( ret==0 && part["dtxt"]:"" != curr["dtxt"]:"" )
  2339.     {
  2340.     changed = true;
  2341.     ret = ChangeDescText( dev, part["dtxt"]:"" );
  2342.     }
  2343.     if( ret==0 &&
  2344.         ((part["resize"]:false && part["region",1]:0 != curr["region",1]:0) ||
  2345.      (part["resize"]:false != curr["resize"]:false)) )
  2346.     {
  2347.     changed = true;
  2348.     string d = part["device"]:"";
  2349.     integer i = part["region",1]:0;
  2350.     if( part["resize"]:false )
  2351.         {
  2352.         y2milestone( "ChangeVolumeProperties resize to %1 cyl", i );
  2353.         if( part["ignore_fs"]:false )
  2354.         ret = LibStorage::StorageInterface::resizePartitionNoFs( sint, d, i );
  2355.         else
  2356.         ret = LibStorage::StorageInterface::resizePartition( sint, d, i );
  2357.         }
  2358.     else
  2359.         ret = LibStorage::StorageInterface::forgetResizeVolume( sint, d );
  2360.     if( ret<0 )
  2361.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2362.     else
  2363.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2364.     }
  2365.     if( ret==0 && 
  2366.         part["change_fsid"]:false && part["fsid"]:0 != curr["fsid"]:0)
  2367.     {
  2368.     changed = true;
  2369.     string d = part["device"]:"";
  2370.     integer i = part["fsid"]:0;
  2371.     y2milestone( "ChangeVolumeProperties fsid to %1", i );
  2372.     ret = LibStorage::StorageInterface::changePartitionId( sint, d, i );
  2373.     if( ret<0 )
  2374.         y2error( "ChangeVolumeProperties sint ret:%1", ret );
  2375.     else
  2376.         y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
  2377.     }
  2378.     if( ret==0 )
  2379.     {
  2380.     y2debug( "ChangeVolumeProperties changed:%1 part:%2", changed, part );
  2381.     if( changed )
  2382.         UpdateTargetMapDev( dev );
  2383.     }
  2384.     return( ret==0 );
  2385.     }
  2386.  
  2387. global boolean DeleteDevice( string disk, string device )
  2388.     {
  2389.     y2milestone( "DeleteDevice disk:%1 device:%2", disk, device );
  2390.     integer ret = LibStorage::StorageInterface::removeVolume( sint, device );
  2391.     if( ret<0 )
  2392.     y2error( "DeleteDevice sint ret:%1", ret );
  2393.     UpdateTargetMap();
  2394.     return( ret==0 );
  2395.     }
  2396.  
  2397. global boolean DeleteLvmVg( string name )
  2398.     {
  2399.     y2milestone( "DeleteLvmVg name:%1", name );
  2400.     integer ret = LibStorage::StorageInterface::removeLvmVg( sint, name );
  2401.     if( ret<0 )
  2402.     y2error( "DeleteLvmVg sint ret:%1", ret );
  2403.     UpdateTargetMap();
  2404.     return( ret==0 );
  2405.     }
  2406.  
  2407. global boolean DeleteDmraid( string name )
  2408.     {
  2409.     y2milestone( "DeleteDmraid name:%1", name );
  2410.     integer ret = LibStorage::StorageInterface::removeDmraid( sint, name );
  2411.     if( ret<0 )
  2412.     y2error( "DeleteDmraid sint ret:%1", ret );
  2413.     UpdateTargetMap();
  2414.     return( ret==0 );
  2415.     }
  2416.  
  2417. global boolean CreateLvmVg( string name, integer pesize, boolean lvm2 )
  2418.     {
  2419.     y2milestone( "CreateLvmVg name:%1 pesize:%2 lvm2:%3", name, pesize, lvm2 );
  2420.     list<string> devs = [];
  2421.     integer ret = 0;
  2422.     ret = LibStorage::StorageInterface::createLvmVg( sint, name, pesize/1024,
  2423.                                                      !lvm2, devs );
  2424.     if( ret<0 )
  2425.     y2error( "CreateLvmVg sint ret:%1", ret );
  2426.     UpdateTargetMap();
  2427.     return( ret==0 );
  2428.     }
  2429.  
  2430. global boolean ExtendLvmVg( string name, string device )
  2431.     {
  2432.     y2milestone( "ExtendLvmVg name:%1 device:%2", name, device );
  2433.     integer ret = 0;
  2434.     list<string> devs = [ device ];
  2435.     ret = LibStorage::StorageInterface::extendLvmVg( sint, name, devs );
  2436.     if( ret<0 )
  2437.     y2error( "ExtendLvmVg sint ret:%1", ret );
  2438.     UpdateTargetMap();
  2439.     return( ret==0 );
  2440.     }
  2441.  
  2442. global boolean ReduceLvmVg( string name, string device )
  2443.     {
  2444.     y2milestone( "ReduceLvmVg name:%1 device:%2", name, device );
  2445.     integer ret = 0;
  2446.     list<string> devs = [ device ];
  2447.     ret = LibStorage::StorageInterface::shrinkLvmVg( sint, name, devs );
  2448.     if( ret<0 )
  2449.     y2error( "ReduceLvmVg sint ret:%1", ret );
  2450.     UpdateTargetMap();
  2451.     return( ret==0 );
  2452.     }
  2453.  
  2454. global boolean CreateLvmLv( string vgname, string lvname, integer sizeK,
  2455.                             integer stripe )
  2456.     {
  2457.     y2milestone( "CreateLvmLv vg:%1 name:%2 sizeK:%3 stripe:%4", vgname,
  2458.                  lvname, sizeK, stripe );
  2459.     integer ret = 0;
  2460.     string dummy = "";
  2461.     ret = LibStorage::StorageInterface::createLvmLv( sint, vgname, lvname,
  2462.                                                      (sizeK+1023)/1024, stripe,
  2463.                              dummy );
  2464.     if( ret<0 )
  2465.     y2error( "CreateLvmLv sint ret:%1", ret );
  2466.     UpdateTargetMapDisk( "/dev/"+vgname );
  2467.     return( ret==0 );
  2468.     }
  2469.  
  2470. global boolean ChangeLvStripeSize( string vgname, string lvname,
  2471.                    integer stripeSize )
  2472.     {
  2473.     y2milestone( "ChangeLvStripeSize vg:%1 name:%2 stripeSize:%3", vgname,
  2474.                  lvname, stripeSize );
  2475.     integer ret = 0;
  2476.     string dummy = "";
  2477.     ret = LibStorage::StorageInterface::changeLvStripeSize( sint, vgname,
  2478.                                                             lvname,
  2479.                                 stripeSize );
  2480.     if( ret<0 )
  2481.     y2error( "ChangeLvStripeSize sint ret:%1", ret );
  2482.     UpdateTargetMapDisk( "/dev/"+vgname );
  2483.     return( ret==0 );
  2484.     }
  2485.  
  2486. global boolean DeleteEvmsCo( string name )
  2487.     {
  2488.     y2milestone( "DeleteEvmsCo name:%1", name );
  2489.     integer ret = LibStorage::StorageInterface::removeEvmsContainer( sint, name );
  2490.     if( ret<0 )
  2491.     y2error( "DeleteEvmsCo sint ret:%1", ret );
  2492.     UpdateTargetMap();
  2493.     return( ret==0 );
  2494.     }
  2495.  
  2496. global string EvmsShortName( string lname )
  2497.     {
  2498.     string sname = lname;
  2499.     if( search( sname, "/" )!=nil )
  2500.     sname = substring( sname, search( sname, "/" )+1 );
  2501.     return( sname );
  2502.     }
  2503.  
  2504. global boolean ActivateEvms()
  2505.     {
  2506.     integer ret = 0;
  2507.     ret = LibStorage::StorageInterface::evmsActivate( sint );
  2508.     if( ret<0 )
  2509.     y2error( "activateEvms sint ret:%1", ret );
  2510.     UpdateTargetMap();
  2511.     return( ret==0 );
  2512.     }
  2513.  
  2514. global boolean CreateEvmsCo( string name, integer pesize, boolean lvm2 )
  2515.     {
  2516.     y2milestone( "CreateEvmsCo name:%1 pesize:%2 lvm2:%3", name, pesize, lvm2 );
  2517.     string sname = EvmsShortName( name );
  2518.     y2milestone( "CreateEvmsCo sname:%1", sname );
  2519.     list<string> devs = [];
  2520.     integer ret = 0;
  2521.     ret = LibStorage::StorageInterface::createEvmsContainer( sint, sname,
  2522.                                                              pesize/1024,
  2523.                                  !lvm2, devs );
  2524.     if( ret<0 )
  2525.     y2error( "CreateEvmsCo sint ret:%1", ret );
  2526.     UpdateTargetMap();
  2527.     return( ret==0 );
  2528.     }
  2529.  
  2530. global boolean ModifyEvmsCo( string old_name, string new_name, integer pesize,
  2531.                              boolean lvm2 )
  2532.     {
  2533.     y2milestone( "ModifyEvmsCo old name:%1 new name:%2 pesize:%3 lvm2:%4",
  2534.                  old_name, new_name, pesize, lvm2 );
  2535.     string sname = EvmsShortName( old_name );
  2536.     y2milestone( "CreateEvmsCo sname:%1", sname );
  2537.     list<string> devs = [];
  2538.     integer ret = 0;
  2539.     ret = LibStorage::StorageInterface::modifyEvmsContainer( sint, sname,
  2540.                                                              new_name,
  2541.                                  pesize/1024,
  2542.                                  !lvm2 );
  2543.     if( ret<0 )
  2544.     y2error( "ModifyEvmsCo sint ret:%1", ret );
  2545.     UpdateTargetMap();
  2546.     return( ret==0 );
  2547.     }
  2548.  
  2549. global boolean ExtendEvmsCo( string name, string device )
  2550.     {
  2551.     y2milestone( "ExtendEvmsCo name:%1 device:%2", name, device );
  2552.     integer ret = 0;
  2553.     string sname = EvmsShortName( name );
  2554.     y2milestone( "ExtendEvmsCo sname:%1", sname );
  2555.     list<string> devs = [ device ];
  2556.     ret = LibStorage::StorageInterface::extendEvmsContainer( sint, sname,
  2557.                                                              devs );
  2558.     if( ret<0 )
  2559.     y2error( "ExtendEvmsCo sint ret:%1", ret );
  2560.     UpdateTargetMap();
  2561.     return( ret==0 );
  2562.     }
  2563.  
  2564. global boolean ReduceEvmsCo( string name, string device )
  2565.     {
  2566.     y2milestone( "ReduceEvmsCo name:%1 device:%2", name, device );
  2567.     integer ret = 0;
  2568.     string sname = EvmsShortName( name );
  2569.     y2milestone( "ReduceEvmsCo sname:%1", sname );
  2570.     list<string> devs = [ device ];
  2571.     ret = LibStorage::StorageInterface::shrinkEvmsContainer( sint, sname,
  2572.                                                              devs );
  2573.     if( ret<0 )
  2574.     y2error( "ReduceEvmsCo sint ret:%1", ret );
  2575.     UpdateTargetMap();
  2576.     return( ret==0 );
  2577.     }
  2578.  
  2579. global boolean CreateEvmsVolume( string coname, string lvname, integer sizeK,
  2580.                  integer stripe )
  2581.     {
  2582.     y2milestone( "CreateEvmsVolume vg:%1 name:%2 sizeK:%3 stripe:%4", coname,
  2583.                  lvname, sizeK, stripe );
  2584.     integer ret = 0;
  2585.     string dummy = "";
  2586.     string sname = EvmsShortName( coname );
  2587.     y2milestone( "CreateEvmsVolume sname:%1", sname );
  2588.     ret = LibStorage::StorageInterface::createEvmsVolume( sint, sname, lvname,
  2589.                                                           (sizeK+1023)/1024,
  2590.                               stripe, dummy );
  2591.     if( ret<0 )
  2592.     y2error( "CreateEvmsVolume sint ret:%1", ret );
  2593.     UpdateTargetMapDisk( "/dev/evms/"+coname );
  2594.     return( ret==0 );
  2595.     }
  2596.  
  2597. global boolean ChangeEvmsStripeSize( string coname, string name,
  2598.                      integer stripeSize )
  2599.     {
  2600.     y2milestone( "ChangeEvmsStripeSize co:%1 name:%2 stripeSize:%3", coname,
  2601.                  name, stripeSize );
  2602.     integer ret = 0;
  2603.     string dummy = "";
  2604.     ret = LibStorage::StorageInterface::changeEvmsStripeSize( sint, coname,
  2605.                                   name,
  2606.                                   stripeSize );
  2607.     if( ret<0 )
  2608.     y2error( "ChangeEvmsStripeSize sint ret:%1", ret );
  2609.     UpdateTargetMapDisk( "/dev/evms/"+coname );
  2610.     return( ret==0 );
  2611.     }
  2612.  
  2613. global boolean CreateMd( integer nr, string type )
  2614.     {
  2615.     y2milestone( "CreateMd nr:%1 type:%2", nr, type );
  2616.     integer ret = 0;
  2617.     integer tmp = conv_mdstring[type]:0;
  2618.     list<string> dummy = [];
  2619.     string rd = sformat("/dev/md%1", nr );
  2620.     ret = LibStorage::StorageInterface::createMd( sint, rd, tmp, dummy );
  2621.     if( ret<0 )
  2622.     y2error( "CreateMd sint ret:%1", ret );
  2623.     UpdateTargetMapDisk( "/dev/md" );
  2624.     return( ret==0 );
  2625.     }
  2626.  
  2627. global boolean ExtendMd( integer nr, string dev )
  2628.     {
  2629.     y2milestone( "ExtendMd nr:%1 dev:%2", nr, dev );
  2630.     integer ret = 0;
  2631.     string rd = sformat("/dev/md%1", nr );
  2632.     ret = LibStorage::StorageInterface::extendMd( sint, rd, dev );
  2633.     if( ret<0 )
  2634.     y2error( "ExtendMd sint ret:%1", ret );
  2635.     UpdateTargetMap();
  2636.     return( ret==0 );
  2637.     }
  2638.  
  2639. global boolean ShrinkMd( integer nr, string dev )
  2640.     {
  2641.     y2milestone( "ShrinkMd nr:%1 dev:%2", nr, dev );
  2642.     integer ret = 0;
  2643.     string rd = sformat("/dev/md%1", nr );
  2644.     ret = LibStorage::StorageInterface::shrinkMd( sint, rd, dev );
  2645.     if( ret<0 )
  2646.     y2error( "ShrinkMd sint ret:%1", ret );
  2647.     UpdateTargetMap();
  2648.     return( ret==0 );
  2649.     }
  2650.  
  2651. global boolean ChangeMdType( integer nr, string mdtype )
  2652.     {
  2653.     y2milestone( "ChangeMdType nr:%1 mdtype:%2", nr, mdtype );
  2654.     integer ret = 0;
  2655.     string rd = sformat("/dev/md%1", nr );
  2656.     integer tmp = conv_mdstring[mdtype]:0;
  2657.     ret = LibStorage::StorageInterface::changeMdType( sint, rd, tmp );
  2658.     if( ret<0 )
  2659.     y2error( "ChangeMdType sint ret:%1", ret );
  2660.     UpdateTargetMapDev( rd );
  2661.     return( ret==0 );
  2662.     }
  2663.  
  2664. global boolean ChangeMdParity( integer nr, string ptype )
  2665.     {
  2666.     y2milestone( "ChangeMdParity nr:%1 parity:%2", nr, ptype );
  2667.     integer ret = 0;
  2668.     string rd = sformat("/dev/md%1", nr );
  2669.     integer tmp = conv_mdstring[ptype]:0;
  2670.     ret = LibStorage::StorageInterface::changeMdParity( sint, rd, tmp );
  2671.     if( ret<0 )
  2672.     y2error( "ChangeMdParity sint ret:%1", ret );
  2673.     UpdateTargetMapDev( rd );
  2674.     return( ret==0 );
  2675.     }
  2676.  
  2677. global boolean ChangeMdChunk( integer nr, integer chunk )
  2678.     {
  2679.     y2milestone( "ChangeMdChunk nr:%1 chunk:%2", nr, chunk );
  2680.     integer ret = 0;
  2681.     string rd = sformat("/dev/md%1", nr );
  2682.     ret = LibStorage::StorageInterface::changeMdChunk( sint, rd, chunk );
  2683.     if( ret<0 )
  2684.     y2error( "ChangeMdChunk sint ret:%1", ret );
  2685.     UpdateTargetMapDev( rd );
  2686.     return( ret==0 );
  2687.     }
  2688.  
  2689. global integer CheckMd( integer nr )
  2690.     {
  2691.     y2milestone( "CheckMd nr:%1", nr );
  2692.     integer ret = 0;
  2693.     string rd = sformat("/dev/md%1", nr );
  2694.     ret = LibStorage::StorageInterface::checkMd( sint, rd );
  2695.     if( ret!=0 )
  2696.     y2milestone( "CheckMd sint ret:%1", ret );
  2697.     return( ret );
  2698.     }
  2699.  
  2700. global string CreateLoop( string file, boolean create, integer sizeK,
  2701.                           string mp )
  2702.     {
  2703.     y2milestone( "CreateLoop file:%1 create:%2 sizeK:%3 mp:%4", file, create,
  2704.                  sizeK, mp );
  2705.     string dev = "";
  2706.     integer ret = -9999;
  2707.     if( haskey( ClassifiedSettings, file ))
  2708.     {
  2709.     string pwd = ClassifiedSettings[file]:"";
  2710.     ret = LibStorage::StorageInterface::createFileLoop( sint, file, !create,
  2711.                                 sizeK, mp, pwd,
  2712.                                 dev );
  2713.     }
  2714.     if( ret<0 )
  2715.     y2error( "CreateLoop sint ret:%1", ret );
  2716.     UpdateTargetMapDisk( "/dev/loop" );
  2717.     y2milestone( "CreateLoop dev:%1", dev );
  2718.     return( dev );
  2719.     }
  2720.  
  2721. integer loop_count = 0;
  2722.  
  2723. global string GetLoopDevice()
  2724.     {
  2725.     y2milestone( "GetLoopDevice" );
  2726.     string file = Directory::tmpdir + sformat("/dfile_%1", loop_count);
  2727.     string mp = Directory::tmpdir + sformat("/loopmp_%1", loop_count);
  2728.     loop_count = loop_count + 1;
  2729.     string dev = "";
  2730.     string pwd = "emilemil";
  2731.     integer ret = LibStorage::StorageInterface::createFileLoop( sint, file,
  2732.                                 true, 50*1024,
  2733.                                 mp, pwd, dev );
  2734.     if( ret<0 )
  2735.     y2error( "GetLoopDevice sint ret:%1", ret );
  2736.     LibStorage::StorageInterface::forgetCryptPassword( sint, dev );
  2737.     y2milestone( "GetLoopDevice dev:%1", dev );
  2738.     return( dev );
  2739.     }
  2740.  
  2741. global void UpdateClassified( string key, string pwd )
  2742.     {
  2743.     ClassifiedSettings[key] = pwd;
  2744.     //y2milestone( "ClassifiedSettings %1", ClassifiedSettings );
  2745.     }
  2746.  
  2747. global boolean UpdateLoop( string dev, string file, boolean create, 
  2748.                            integer sizeK )
  2749.     {
  2750.     y2milestone( "UpdateLoop device:%1 file:%2 create:%3 sizeK:%4", 
  2751.                  dev, file, create, sizeK );
  2752.     integer ret = LibStorage::StorageInterface::modifyFileLoop( sint, dev, file,
  2753.                                 !create,
  2754.                                 sizeK );
  2755.     if( ret<0 )
  2756.     y2error( "UpdateLoop sint ret:%1", ret );
  2757.     UpdateTargetMapDisk( "/dev/loop" );
  2758.     return( ret==0 );
  2759.     }
  2760.  
  2761. global boolean DeleteLoop( string disk, string file, boolean remove_file )
  2762.     {
  2763.     y2milestone( "DeleteLoop disk:%1 file:%2 remove_file:%3", disk, file,
  2764.                  remove_file );
  2765.     integer ret = LibStorage::StorageInterface::removeFileLoop( sint, file,
  2766.                                                                 remove_file );
  2767.     if( ret<0 )
  2768.     y2error( "DeleteLoop sint ret:%1", ret );
  2769.     UpdateTargetMapDisk( disk );
  2770.     return( ret==0 );
  2771.     }
  2772.  
  2773. global string GetCryptPwd( string device )
  2774.     {
  2775.     string pwd="";
  2776.     y2milestone( "GetCryptPwd device:%1", device );
  2777.     if( size(ClassifiedSettings[device]:"")>0 )
  2778.     pwd = ClassifiedSettings[device]:"";
  2779.     else
  2780.     {
  2781.     integer ret = 0;
  2782.     ret = LibStorage::StorageInterface::getCryptPassword( sint, device,
  2783.                                   pwd );
  2784.     if( ret<0 )
  2785.         y2error( "GetCryptPwd sint ret:%1", ret );
  2786.     }
  2787.     y2milestone( "GetCryptPwd empty:%1", size(pwd)==0 );
  2788.     return( pwd );
  2789.     }
  2790.  
  2791. global boolean SetCryptPwd( string device, string pwd )
  2792.     {
  2793.     y2milestone( "SetCryptPwd device:%1", device );
  2794.     integer ret = LibStorage::StorageInterface::setCryptPassword( sint, device,
  2795.                                                                   pwd );
  2796.     y2milestone( "SetCryptPwd sint ret:%1", ret );
  2797.     map p = GetPartition( GetTargetMap(), device );
  2798.     if( ret==LibStorage::STORAGE_VOLUME_NOT_FOUND() || p["create"]:false )
  2799.     {
  2800.     ClassifiedSettings[device] = pwd;
  2801.     y2milestone( "setting classified %1 pwd size %2", device, size(pwd) );
  2802.     ret = 0;
  2803.     }
  2804.     else if( ret<0 )
  2805.     y2error( "SetCryptPwd sint ret:%1", ret );
  2806.     return( ret==0 );
  2807.     }
  2808.  
  2809. /**
  2810.  * Delete the partition table and disk label of device
  2811.  * @param string the disk to deleted the partition table from
  2812.  * @return boolean
  2813.  */
  2814. global define boolean DeletePartitionTable(string disk)
  2815.     ``{
  2816.     y2milestone( "DeletePartitionTable %1", disk );
  2817.     string label = LibStorage::StorageInterface::defaultDiskLabel( sint );
  2818.     y2milestone( "DeletePartitionTable label:%1", label );
  2819.     integer ret =
  2820.     LibStorage::StorageInterface::destroyPartitionTable( sint, disk,
  2821.                                                          label );
  2822.     if( ret<0 )
  2823.     y2error( "DeletePartitionTable sint ret:%1", ret );
  2824.     UpdateTargetMapDisk( disk );
  2825.     UpdateTargetMapDisk( "/dev/evms" );
  2826.     return( ret==0 );
  2827.     }
  2828.  
  2829. /**
  2830.  * Set the flag if a disk needs to be initialized
  2831.  * @param string the disk to be changed
  2832.  * @return boolean
  2833.  */
  2834. global define boolean InitializeDisk(string disk, boolean value)
  2835.     ``{
  2836.     boolean rbool = true;
  2837.     y2milestone( "InitializeDisk %1 value %2", disk, value );
  2838.     integer ret =
  2839.     LibStorage::StorageInterface::initializeDisk( sint, disk, value );
  2840.     if( ret<0 )
  2841.     {
  2842.     y2error( "InitializeDisk sint ret:%1", ret );
  2843.     rbool = false;
  2844.     }
  2845.     if( rbool && value )
  2846.     {
  2847.     map<string,any> d = GetDisk( GetTargetMap(), disk );
  2848.     y2milestone( "d:%1", d );
  2849.     rbool = CreatePartition( disk, disk+"1", `primary,
  2850.                              Partitions::fsid_native,
  2851.                  0, d["cyl_count"]:1 );
  2852.     if( !rbool )
  2853.         y2error( "InitializeDisk create failed" );
  2854.     }
  2855.     UpdateTargetMapDisk( disk );
  2856.     return( rbool );
  2857.     }
  2858.  
  2859. global define boolean IsPartType( symbol t )
  2860.     {
  2861.     return( t==`CT_DMRAID || t==`CT_DISK );
  2862.     }
  2863.     
  2864. global define boolean CreateAny( symbol ctype, map d, map& p )
  2865.     {
  2866.     boolean ret = true;
  2867.     if( IsPartType(ctype) )
  2868.     {
  2869.     ret = Storage::CreatePartition( d["device"]:"", p["device"]:"",
  2870.                         p["type"]:`primary,
  2871.                         p["fsid"]:Partitions::fsid_native,
  2872.                         p["region",0]:0, p["region",1]:0 );
  2873.     }
  2874.     else if( ctype == `CT_MD )
  2875.     {
  2876.     ret = Storage::CreateMd( p["nr"]:0, p["raid_type"]:"raid1" );
  2877.     if( ret && haskey( p, "chunk_size" ))
  2878.         Storage::ChangeMdChunk( p["nr"]:0, p["chunk_size"]:4 );
  2879.     if( ret && p["raid_type"]:""=="raid5" &&
  2880.         haskey( p, "parity_algorithm" ))
  2881.         Storage::ChangeMdParity( p["nr"]:0,
  2882.                                  p["parity_algorithm"]:"" );
  2883.     foreach( string d, p["devices"]:[],
  2884.          ``{ret=Storage::ExtendMd( p["nr"]:0, d )&&ret;});
  2885.     }
  2886.     else if( ctype == `CT_LOOP )
  2887.     {
  2888.     y2milestone( "CreateAny Loop p:%1", p );
  2889.     string dev = Storage::CreateLoop( p["fpath"]:"", p["create_file"]:false,
  2890.                       p["size_k"]:0, p["mount"]:"" );
  2891.     ret = size(dev)>0;
  2892.     if( ret )
  2893.         p["device"] = dev;
  2894.     }
  2895.     else if( ctype == `CT_LVM )
  2896.     {
  2897.     ret = Storage::CreateLvmLv( d["name"]:"", p["name"]:"", p["size_k"]:0,
  2898.                     p["stripes"]:1 );
  2899.     if( ret && p["stripes"]:1>1 && p["stripesize"]:0>0 )
  2900.         {
  2901.         Storage::ChangeLvStripeSize( d["name"]:"", p["name"]:"",
  2902.                                      p["stripesize"]:0 );
  2903.         }
  2904.     }
  2905.     else if( ctype == `CT_EVMS )
  2906.     {
  2907.     ret = Storage::CreateEvmsVolume( d["name"]:"", p["name"]:"",
  2908.                                      p["size_k"]:0, p["stripes"]:1 );
  2909.     if( ret && p["stripes"]:1>1 && p["stripesize"]:0>0 )
  2910.         {
  2911.         Storage::ChangeEvmsStripeSize( d["name"]:"", p["name"]:"",
  2912.                        p["stripesize"]:0 );
  2913.         }
  2914.     }
  2915.     y2milestone( "CreateAny ret:%1", ret );
  2916.     return( ret );
  2917.     }
  2918.  
  2919. /**
  2920.  * Search in the list partitions for windows partitions and add the key
  2921.  * "mount" to the found windows partitions.
  2922.  * @parm partitions the partitions list
  2923.  * @parm primary handle primary or logical partitions
  2924.  * @return list new partitions with windows mountpoints
  2925.  */
  2926. define void AddMountPointsForWinParts( list<map> partitions, boolean primary,
  2927.                                        integer max_prim, integer& foreign_nr )
  2928.     ``{
  2929.     if( !Arch::i386 () && !Arch::ia64 () && !Arch::x86_64 () )
  2930.     return;
  2931.  
  2932.     string foreign_ids = "CDEFGHIJKLMNOPQRSTUVW";
  2933.  
  2934.     list<map> new_partitions = [];
  2935.  
  2936.     foreach(map partition, partitions,
  2937.     ``{
  2938.     map new_partition = partition;
  2939.     integer fsid      = partition["fsid"]:Partitions::fsid_native;
  2940.     integer partnum = 0;
  2941.     if( haskey( partition, "nr") && is( partition["nr"]:(any)0, integer ) )
  2942.         {
  2943.         partnum = partition["nr"]:0;
  2944.         }
  2945.  
  2946.     if( !haskey( partition, "mount") &&
  2947.         !partition["delete"]:false &&
  2948.         ((partnum<=max_prim)==primary) &&
  2949.         foreign_nr < 24 &&
  2950.         Partitions::IsDosWinNtPartition(fsid) &&
  2951.         (!Arch::ia64() || partition["size_k"]:0 >= 1024*1024) &&
  2952.         contains( [`vfat, `ntfs], partition["used_fs"]:`none ))
  2953.         {
  2954.         new_partition["fstopt"] = 
  2955.         FileSystems::DefaultFstabOptions(partition);
  2956.         if( contains( Partitions::fsid_dostypes, fsid ))
  2957.         {
  2958.         new_partition["mount"] =
  2959.             "/dos/" + substring (foreign_ids, foreign_nr, 1);
  2960.         foreign_nr = foreign_nr + 1;
  2961.         }
  2962.         else
  2963.         {
  2964.         new_partition["mount"] =
  2965.             "/windows/" + substring (foreign_ids, foreign_nr, 1);
  2966.         foreign_nr = foreign_nr + 1;
  2967.         }
  2968.         ChangeVolumeProperties( new_partition );
  2969.         y2milestone( "win part %1", new_partition );
  2970.         }
  2971.     });
  2972.     };
  2973.  
  2974. global define void AddMountPointsForWin( map<string,map> targets )
  2975.     ``{
  2976.     y2milestone( "AddMountPointsForWin called" );
  2977.     integer foreign_nr = 0;
  2978.  
  2979.     foreach(string disk, map data, targets,
  2980.     ``{
  2981.     if( data["used_by_type"]:`UB_NONE == `UB_NONE )
  2982.         AddMountPointsForWinParts( data["partitions"]:[], true,
  2983.                        data["max_primary"]:4, foreign_nr );
  2984.     });
  2985.     foreach(string disk, map data, targets,
  2986.     ``{
  2987.     if( data["used_by_type"]:`UB_NONE == `UB_NONE )
  2988.         AddMountPointsForWinParts( data["partitions"]:[], false,
  2989.                        data["max_primary"]:4, foreign_nr );
  2990.     });
  2991.     }
  2992.  
  2993. global void RemoveDmMapsTo( string device )
  2994.     {
  2995.     y2milestone( "RemoveDmMapsTo device:%1", device );
  2996.     InitLibstorage();
  2997.     if( LibStorage::StorageInterface::checkDmMapsTo( sint, device ))
  2998.     {
  2999.     LibStorage::StorageInterface::removeDmMapsTo( sint, device, true );
  3000.     }
  3001.     else
  3002.     {
  3003.     map d = GetDiskPartition( device );
  3004.     string ddev = d["disk"]:"";
  3005.     if( size(ddev)>0 && ddev!=device &&
  3006.         LibStorage::StorageInterface::checkDmMapsTo( sint, ddev ) )
  3007.         {
  3008.         LibStorage::StorageInterface::removeDmMapsTo( sint, ddev, false );
  3009.         }
  3010.     }
  3011.     }
  3012.  
  3013. global define boolean CheckSwapable( string dev )
  3014.     {
  3015.     string cmd = "swapon " + dev;
  3016.     RemoveDmMapsTo( dev );
  3017.     boolean ok = (integer)SCR::Execute(.target.bash, cmd )==0;
  3018.     if( ok )
  3019.     {
  3020.     cmd = "swapoff " + dev;
  3021.     SCR::Execute(.target.bash, cmd );
  3022.     }
  3023.     y2milestone( "CheckSwapable dev:%1 ret:%2", dev, ok );
  3024.     return( ok );
  3025.     }
  3026.  
  3027. /**
  3028.  * mark swap-partitions with pseudo Mountpoint swap in targetMap
  3029.  * @param target Disk map
  3030.  * @return map<string,map> modified target
  3031.  */
  3032. global define map<string,map> AddSwapMp( map<string,map> target )
  3033.     ``{
  3034.     list swaps = SwappingPartitions();
  3035.     y2milestone( "AddSwapMp swaps %1", swaps );
  3036.     foreach(string diskdev, map disk, target,
  3037.     ``{
  3038.      disk["partitions"] = maplist(map part, disk["partitions"]:[],
  3039.          ``{
  3040.          if( (Stage::initial() &&
  3041.           !Partitions::IsDosWinNtPartition(part["fsid"]:0) &&
  3042.           part["detected_fs"]:`unknown==`swap &&
  3043.           !part["old_swap"]:false &&
  3044.           search( diskdev, "/dev/evms" )!=0 ) ||
  3045.          (contains( swaps, part["device"]:"" )))
  3046.          {
  3047.          boolean ok = true;
  3048.          if( !contains( swaps, part["device"]:"" ))
  3049.              {
  3050.              ok = CheckSwapable( part["device"]:"" );
  3051.              y2milestone( "AddSwapMp initial ok:%1", ok );
  3052.              }
  3053.          if( ok )
  3054.              {
  3055.              part["mount"] = "swap";
  3056.              ChangeVolumeProperties( part );
  3057.              y2milestone( "AddSwapMp %1", part );
  3058.              }
  3059.          }
  3060.          return( part );
  3061.          });
  3062.     target[diskdev] = disk;
  3063.     });
  3064.     return( target );
  3065.     }
  3066.  
  3067. global define map<string,map> GetTargetMap()
  3068.     ``{
  3069.     map<string,map> tmp = $[];
  3070.     boolean changed = false;
  3071.     InitLibstorage();
  3072.     if( !probe_done && !Mode::config() )
  3073.     {
  3074.     y2milestone ("probing StorageDevices" );
  3075.     map<string,string> rename = $[];
  3076.     tmp = (map<string,map>)StorageDevices::Probe(true);
  3077.     foreach( string dev, map disk, tmp,
  3078.         ``{
  3079.         map dtmp = Storage::GetDiskPartition( dev );
  3080.         y2milestone( "probing dev %1 disk %2", dev, dtmp );
  3081.         if( size(dtmp["disk"]:"")>0 && dev != dtmp["disk"]:"" )
  3082.         {
  3083.         rename[dev] = dtmp["disk"]:"";
  3084.         y2milestone( "probing rename %1", rename );
  3085.         }
  3086.         });
  3087.     if( size(rename)>0 )
  3088.         {
  3089.         foreach( string old, string new, rename,
  3090.         ``{
  3091.         if( haskey( tmp, old ))
  3092.             {
  3093.             tmp[new] = tmp[old]:$[];
  3094.             tmp = remove( tmp, old );
  3095.             tmp[new,"device"] = new;
  3096.             y2milestone( "probing old:%1 new:%2", old, tmp[new]:$[] );
  3097.             }
  3098.         });
  3099.         }
  3100.     y2milestone ("probing done" );
  3101.     if( size(tmp)>0 )
  3102.         {
  3103.         probe_done = true;
  3104.         changed = true;
  3105.         foreach( string dev, map disk, tmp,
  3106.         ``{
  3107.         disk = getDiskInfo( dev, disk );
  3108.         integer s = disk["cyl_count"]:0 * disk["cyl_size"]:0;
  3109.         disk["name"] = disk["dname"]:"" +
  3110.            Partitions::ByteToHumanString( s ) + ", " +
  3111.            disk["device"]:"" + ", ";
  3112.         if( size( disk["vendor"]:"")>0 )
  3113.             disk["name"] = disk["name"]:"" + disk["vendor"]:"" + "-";
  3114.         disk["name"] = disk["name"]:"" + disk["model"]:"";
  3115.         if( haskey( disk, "dname" ))
  3116.             disk = remove( disk, "dname" );
  3117.         tmp[dev] = disk;
  3118.         if( disk["dasdfmt"]:false )
  3119.             Storage::InitializeDisk( dev, true );
  3120.         });
  3121.         foreach( map c, conts,
  3122.         ``{
  3123.         if( c["type"]:`CT_UNKNOWN!=`CT_DISK )
  3124.             tmp[c["device"]:""] = getContainerInfo( c );
  3125.         });
  3126.         StorageMap[targets_key] = tmp;
  3127.         }
  3128.     }
  3129.     if( changed )
  3130.     {
  3131.     tmp = StorageMap[targets_key]:$[];
  3132.     SCR::Write(.target.ycp, Storage::SaveDumpPath("targetMap_i"), tmp );
  3133.     y2milestone ("AddSwapMp" );
  3134.     tmp = AddSwapMp( tmp );
  3135.     CreateTargetBackup( "initial" );
  3136.     if( Stage::initial() || Mode::repair() )
  3137.         {
  3138.         AddMountPointsForWin( tmp );
  3139.         }
  3140.     StorageMap[targets_key] = GetTargetMap();
  3141.     SCR::Write(.target.ycp, Storage::SaveDumpPath("targetMap_ii"), tmp );
  3142.     y2milestone ("changed done" );
  3143.     }
  3144.     return StorageMap[targets_key]:$[];
  3145.     };
  3146.  
  3147. global void SetRecursiveRemoval( boolean val )
  3148.     {
  3149.     y2milestone( "SetRecursiveRemoval val:%1", val );
  3150.     LibStorage::StorageInterface::setRecursiveRemoval( sint, val );
  3151.     }
  3152.  
  3153. global boolean GetRecursiveRemoval()
  3154.     {
  3155.     return( LibStorage::StorageInterface::getRecursiveRemoval( sint ));
  3156.     }
  3157.  
  3158. global define void SetTargetMap( map<string,map> target )
  3159.     {
  3160.     y2milestone( "SetTargetMap" );
  3161.     if( !GetRecursiveRemoval() )
  3162.         SetRecursiveRemoval(true);
  3163.     //SCR::Write(.target.ycp, Storage::SaveDumpPath("targetMap_set_"+sformat("%1",count)), target );
  3164.     //count = count+1;
  3165.     integer old_change_time = StorageMap["targets_time"]:0;
  3166.     CreateTargetBackup("tmp_set");
  3167.     map<string,map> tg = GetTargetMap();
  3168.     list<string> keys = maplist( string k, any e, target, ``(k));
  3169.     foreach( string k, keys,
  3170.     ``{
  3171.     if( target[k,"delete"]:false && haskey( tg, k ) )
  3172.         {
  3173.         if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM )
  3174.         DeleteLvmVg( target[k,"name"]:"" );
  3175.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_EVMS )
  3176.         DeleteEvmsCo( target[k,"name"]:"" );
  3177.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_DMRAID )
  3178.         DeleteDmraid( k );
  3179.         target[k,"delete"] = false;
  3180.         }
  3181.     });
  3182.     keys = maplist( string k, any e, target, ``(k));
  3183.     y2milestone( "SetTargetMap keys %1", keys );
  3184.     list<string> t1 = filter( string k, keys, 
  3185.                               ``(!target[k,"delete"]:false&&
  3186.                      !target[k,"create"]:false));
  3187.     foreach( string k, t1,
  3188.     ``{
  3189.     list<map> dps = filter( map p, target[k,"partitions"]:[],
  3190.                             ``(!p["create"]:false&&!p["delete"]:false));
  3191.     if( size(dps)>0 )
  3192.         {
  3193.         foreach( map p, dps, 
  3194.         ``{
  3195.         if( p["type"]:`primary != `extended || p["resize"]:false )
  3196.             ChangeVolumeProperties( p );
  3197.         });
  3198.         }
  3199.     });
  3200.     tg = GetTargetMap();
  3201.     keys = maplist( string k, any e, tg, ``(k));
  3202.     keys = sort( string a, string b, keys,
  3203.                  ``( type_order[tg[a,"type"]:`CT_UNKNOWN]:6 >
  3204.              type_order[tg[b,"type"]:`CT_UNKNOWN]:6 ));
  3205.     y2milestone( "SetTargetMap keys %1", keys );
  3206.     foreach( string k, keys,
  3207.     ``{
  3208.     list<map> dps = filter( map p, tg[k,"partitions"]:[],
  3209.                             ``(p["create"]:false));
  3210.     if( size(dps)>1 && haskey( dps[0]:$[], "nr" ))
  3211.         {
  3212.         dps = sort( map a, map b, dps, ``(a["nr"]:0>b["nr"]:0));
  3213.         y2milestone( "SetTargetMap dps:%1", dps );
  3214.         }
  3215.     foreach( map p, dps, ``{DeleteDevice( k, p["device"]:"" );});
  3216.     if( tg[k,"create"]:false )
  3217.         {
  3218.         if( tg[k,"type"]:`CT_UNKNOWN==`CT_LVM )
  3219.         DeleteLvmVg( tg[k,"name"]:"" );
  3220.         else if( tg[k,"type"]:`CT_UNKNOWN==`CT_EVMS )
  3221.         DeleteEvmsCo( tg[k,"name"]:"" );
  3222.         }
  3223.     else if( !tg[k,"delete"]:false )
  3224.         {
  3225.         if( tg[k,"type"]:`CT_UNKNOWN==`CT_LVM &&
  3226.         size(target[k,"devices_add"]:[])>0 )
  3227.         {
  3228.         list<string> ls = target[k,"devices_add"]:[];
  3229.         foreach( string d, ls,
  3230.              ``{Storage::ReduceLvmVg( target[k,"name"]:"", d );});
  3231.         }
  3232.         else if( tg[k,"type"]:`CT_UNKNOWN==`CT_EVMS )
  3233.         {
  3234.         list<string> ls = target[k,"devices_add"]:[];
  3235.         foreach( string d, ls,
  3236.              ``{Storage::ReduceEvmsCo( target[k,"name"]:"", d );});
  3237.         }
  3238.         }
  3239.     });
  3240.     keys = maplist( string k, any e, target, ``(k));
  3241.     keys = sort( string a, string b, keys,
  3242.                  ``( type_order[target[a,"type"]:`CT_UNKNOWN]:6 >
  3243.              type_order[target[b,"type"]:`CT_UNKNOWN]:6 ));
  3244.     y2milestone( "SetTargetMap keys %1", keys );
  3245.     foreach( string k, keys,
  3246.     ``{
  3247.     list<map> dps = filter( map p, target[k,"partitions"]:[],
  3248.                             ``(p["delete"]:false));
  3249.     if( size(dps)>1 && haskey( dps[0]:$[], "nr" ))
  3250.         {
  3251.         dps = sort( map a, map b, dps, ``(a["nr"]:0>b["nr"]:0));
  3252.         }
  3253.     foreach( map p, dps, 
  3254.         ``{
  3255.         if( size(p["dtxt"]:"")>0 )
  3256.         ChangeDescText( p["device"]:"", p["dtxt"]:"" );
  3257.         DeleteDevice( k, p["device"]:"" );
  3258.         });
  3259.     if( target[k,"delete"]:false )
  3260.         {
  3261.         if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM )
  3262.         DeleteLvmVg( target[k,"name"]:"" );
  3263.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_EVMS )
  3264.         DeleteEvmsCo( target[k,"name"]:"" );
  3265.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_DISK )
  3266.         DeletePartitionTable( k );
  3267.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_DMRAID )
  3268.         DeleteDmraid( k );
  3269.         }
  3270.     if( target[k,"del_ptable"]:false && 
  3271.         IsPartType( target[k,"type"]:`CT_UNKNOWN ) )
  3272.         {
  3273.         DeletePartitionTable( k );
  3274.         }
  3275.     });
  3276.     keys = maplist( string k, any e, target, ``(k));
  3277.     keys = sort( string a, string b, keys,
  3278.                  ``( type_order[target[a,"type"]:`CT_UNKNOWN]:6 <
  3279.              type_order[target[b,"type"]:`CT_UNKNOWN]:6 ));
  3280.     y2milestone( "SetTargetMap keys %1", keys );
  3281.     foreach( string k, keys,
  3282.     ``{
  3283.     if( target[k,"create"]:false )
  3284.         {
  3285.         if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM )
  3286.         {
  3287.         CreateLvmVg( target[k,"name"]:"", target[k,"pesize"]:0,
  3288.                      target[k,"lvm2"]:true );
  3289.         list<string> ls =
  3290.             (list<string>)union( target[k,"devices"]:[],
  3291.                          target[k,"devices_add"]:[] );
  3292.         foreach( string d, ls,
  3293.              ``{Storage::ExtendLvmVg( target[k,"name"]:"", d );});
  3294.         }
  3295.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_EVMS )
  3296.         {
  3297.         CreateEvmsCo( target[k,"name"]:"", target[k,"pesize"]:0,
  3298.                       target[k,"lvm2"]:true );
  3299.         list<string> ls =
  3300.             (list<string>)union( target[k,"devices"]:[],
  3301.                          target[k,"devices_add"]:[] );
  3302.         foreach( string d, ls,
  3303.              ``{Storage::ExtendEvmsCo( target[k,"name"]:"", d );});
  3304.         }
  3305.         }
  3306.     if( !target[k,"delete"]:false && !target[k,"create"]:false )
  3307.         {
  3308.         if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM && 
  3309.             size(target[k,"devices_add"]:[])>0 )
  3310.         {
  3311.         list<string> ls = target[k,"devices_add"]:[];
  3312.         foreach( string d, ls,
  3313.              ``{Storage::ExtendLvmVg( target[k,"name"]:"", d );});
  3314.         }
  3315.         else if( target[k,"type"]:`CT_UNKNOWN==`CT_EVMS &&
  3316.             size(target[k,"devices_add"]:[])>0 )
  3317.         {
  3318.         list<string> ls = target[k,"devices_add"]:[];
  3319.         foreach( string d, ls,
  3320.              ``{Storage::ExtendEvmsCo( target[k,"name"]:"", d );});
  3321.         }
  3322.         }
  3323.     list<map> dps = filter( map p, target[k,"partitions"]:[],
  3324.                             ``(!p["delete"]:false&&p["create"]:false) );
  3325.     if( size(dps)>1 && haskey( dps[0]:$[], "nr" ))
  3326.         dps = sort( map a, map b, dps, ``(a["nr"]:0<b["nr"]:0));
  3327.     foreach( map p, dps,
  3328.         ``{
  3329.         CreateAny( target[k,"type"]:`CT_UNKNOWN, target[k]:$[], p );
  3330.         if( p["type"]:`primary != `extended )
  3331.         ChangeVolumeProperties( p );
  3332.         });
  3333.     });
  3334.     boolean changed = !EqualBackupStates( "tmp_set", "", true );
  3335.     y2milestone( "SetTargetMap changed:%1", changed );
  3336.     if( !changed )
  3337.     StorageMap["targets_time"] = old_change_time;
  3338.     DisposeTargetBackup("tmp_set");
  3339.     };
  3340.  
  3341. global define map<string,map> ReReadTargetMap()
  3342.     ``{
  3343.     y2milestone("start reread sint:%1", sint );
  3344.     probe_done = false;
  3345.     if( sint == nil )
  3346.     InitLibstorage();
  3347.     else
  3348.     LibStorage::StorageInterface::rescanEverything( sint );
  3349.     conts = getContainers();
  3350.     return GetTargetMap();
  3351.     };
  3352.  
  3353. global integer CommitChanges()
  3354.     {
  3355.     y2milestone( "CommitChanges" );
  3356.     integer ret = LibStorage::StorageInterface::commit( sint );
  3357.     if( ret<0 )
  3358.     y2error( "CommitChanges sint ret:%1", ret );
  3359.     ClassifiedSettings = $[];
  3360.     return( ret );
  3361.     }
  3362.  
  3363. global string DeviceMounted( string dev )
  3364.     {
  3365.     string ret = "";
  3366.     LibStorage::StorageInterface::checkDeviceMounted( sint, dev, ret );
  3367.     if( size(ret)>0 )
  3368.     y2milestone( "DeviceMounted %1 at %2", dev, ret );
  3369.     return( ret );
  3370.     }
  3371.  
  3372. global boolean Umount( string dev )
  3373.     {
  3374.     boolean ret = LibStorage::StorageInterface::umountDevice( sint, dev );
  3375.     y2milestone( "Umount %1 ret %2", dev, ret );
  3376.     return( ret );
  3377.     }
  3378.  
  3379. global boolean Mount( string dev, string mp )
  3380.     {
  3381.     boolean ret = LibStorage::StorageInterface::mountDevice( sint, dev, mp );
  3382.     y2milestone( "Mount %1 to %2 ret %3", dev, mp, ret );
  3383.     return( ret );
  3384.     }
  3385.  
  3386. global list ReadFstab( string dir )
  3387.     {
  3388.     list ret = [];
  3389.     list<any> vinfos = [];
  3390.     boolean r = LibStorage::StorageInterface::readFstab( sint, dir, vinfos );
  3391.     if( !r )
  3392.     y2error( "ReadFstab sint dir %1 ret %2", dir, r );
  3393.     else
  3394.     {
  3395.     foreach( any info, vinfos,
  3396.         ``{
  3397.         map p = $[];
  3398.         p = volumeMap( info, p );
  3399.         ret = add( ret, p );
  3400.         });
  3401.     }
  3402.     y2milestone( "ReadFstab from %1 ret %2", dir, ret );
  3403.     return( ret );
  3404.     }
  3405.  
  3406. global list<map> mountedPartitionsOnDisk( string disk )
  3407.     {
  3408.     map<string,any> d = GetDisk( GetTargetMap(), disk );
  3409.     list<map> ret = filter( map p, d["partitions"]:[],
  3410.                             ``(size(DeviceMounted(p["device"]:""))>0));
  3411.     return( ret );
  3412.     }
  3413.  
  3414. global string ChangeText()
  3415.     {
  3416.     list<string> l = LibStorage::StorageInterface::getCommitActions( sint, true );
  3417.     string ret = "";
  3418.     if( size(l)>0 )
  3419.     ret = HTML::List( l );
  3420.     return( ret );
  3421.     }
  3422.  
  3423. global string LastAction()
  3424.     {
  3425.     string ret = LibStorage::StorageInterface::getLastAction( sint );
  3426.     return( ret );
  3427.     }
  3428.  
  3429. global string ExtendedErrorMsg()
  3430.     {
  3431.     string ret = LibStorage::StorageInterface::getExtendedErrorMessage( sint );
  3432.     return( ret );
  3433.     }
  3434.  
  3435. global void SetZeroNewPartitions( boolean val )
  3436.     {
  3437.     y2milestone( "SetZeroNewPartitions val:%1", val );
  3438.     LibStorage::StorageInterface::setZeroNewPartitions( sint, val );
  3439.     }
  3440.  
  3441. /* GetMountPoints()
  3442.  * collect mountpoint:device as map to get a sorted list
  3443.  * @returns: map of lists, the map key is the mount point,
  3444.  *        usually starting with a "/". Exception is "swap"
  3445.  *    For directory mount points (key starting with /) the value
  3446.  *  is a list [partitionName, fsid, targetdevice, raid_type]
  3447.  *  For swap mount points, the value is a list of lists:
  3448.  *  [[partitionName, fsid, targetdevice, raid_type], ...]
  3449.  *
  3450.  */
  3451. global define map GetMountPoints()
  3452.     ``{
  3453.     map mountPoints = $[];
  3454.     list swapPoints = [];
  3455.     map<string,map> tg = GetTargetMap();
  3456.     foreach ( string targetdevice, map target, tg,
  3457.     ``{
  3458.     list<map> partitions = target["partitions"]:[];
  3459.     foreach (map partition, partitions,
  3460.         ``{
  3461.         string partitionName = partition["device"]:"";
  3462.         string mountPoint = partition["mount"]:"";
  3463.         integer fsid = partition["fsid"]:0;
  3464.         if (mountPoint != "")
  3465.         {
  3466.         string raid_type = "";
  3467.         if( partition["type"]:`undefined == `sw_raid )
  3468.             {
  3469.             raid_type = partition["raid_type"]:"";
  3470.             }
  3471.         // partition has a mount point
  3472.         if (mountPoint == "swap")
  3473.             {
  3474.             swapPoints = add( swapPoints,
  3475.                       [partitionName, fsid, targetdevice, raid_type]);
  3476.             }
  3477.         else
  3478.             {
  3479.             mountPoints = add( mountPoints, mountPoint,
  3480.                                [partitionName, fsid, targetdevice, raid_type]);
  3481.             }
  3482.         }
  3483.         });
  3484.     });
  3485.     if (size (swapPoints) > 0)
  3486.     mountPoints = add (mountPoints, "swap", swapPoints);
  3487.     if( !Stage::initial () )
  3488.     {
  3489.     list<map> cm = filter(map e, Partitions::CurMounted(),
  3490.                   ``(search(e["spec"]:"","/dev/")==0));
  3491.     foreach(map e, cm,
  3492.         ``{
  3493.         if( !haskey( mountPoints, e["file"]:"" ) )
  3494.         {
  3495.         map p = GetPartition( tg, e["spec"]:"" );
  3496.         if( size(p)>0 )
  3497.             {
  3498.             string raid_type = "";
  3499.             if( p["type"]:`undefined == `sw_raid )
  3500.             {
  3501.             raid_type = p["raid_type"]:"";
  3502.             }
  3503.             map d = GetDiskPartition( e["spec"]:"" );
  3504.             mountPoints[e["file"]:""] =
  3505.             [ p["device"]:"", p["fsid"]:0, d["disk"]:"", raid_type ];
  3506.             }
  3507.         }
  3508.         });
  3509.     }
  3510.     y2milestone( "ret %1", mountPoints );
  3511.     return mountPoints;
  3512.     }
  3513.  
  3514. global define string
  3515. GetIdSmaller( string disk, integer delim )
  3516.     ``{
  3517.     string ret = disk;
  3518.     map<string,map> tg = GetTargetMap();
  3519.     list<map> ps = filter( map p, tg[disk,"partitions"]:[], ``(p["nr"]:0<delim));
  3520.     ps = sort( map a, map b, ps, ``(a["nr"]:0>b["nr"]:0));
  3521.     if( size(ps)>0 )
  3522.     ret = ps[0,"device"]:"";
  3523.     y2milestone( "GetIdSmaller disk:%1 delim:%2 ret:%3",
  3524.                  disk, delim, ret );
  3525.     return( ret );
  3526.     }
  3527.  
  3528.  
  3529. /* set <key> in partition <device> to the given <value> and return changed map <tg> */
  3530. global define map<string,map> SetPartitionData( map<string,map> tg,
  3531.                                                 string device, string key,
  3532.                         any value )
  3533.     ``{
  3534.     y2milestone( "SetPartitionData device=%1 key=%2 value=%3", device, key,
  3535.                  value );
  3536.     map tmp = GetDiskPartition( device );
  3537.     string disk = tmp["disk"]:"";
  3538.     list r_part = filter(map part, tg[disk,"partitions"]:[],
  3539.               ``(part["device"]:"" != device ));
  3540.     if( size(r_part)!=size(tg[disk,"partitions"]:[]) )
  3541.     {
  3542.     map p = filter( map part, tg[disk,"partitions"]:[],
  3543.                 ``(part["device"]:"" == device ))[0]:$[];
  3544.     if( size(p)>0 )
  3545.         {
  3546.         p[key] = value;
  3547.         r_part    = add( r_part, p );
  3548.         tg[disk,"partitions"] = r_part;
  3549.         }
  3550.     }
  3551.     return( tg );
  3552.     }
  3553.  
  3554. /* remove <key> in partition <device> and return changed map <tg> */
  3555. global define map<string,map> DelPartitionData( map<string,map> tg,
  3556.                                                 string device, string key)
  3557.     ``{
  3558.     y2debug( "device=%1, key=%2", device, key );
  3559.     map tmp = GetDiskPartition( device );
  3560.     string disk = tmp["disk"]:"";
  3561.     list r_part = filter(map part, tg[disk,"partitions"]:[],
  3562.               ``(part["device"]:"" != device ));
  3563.     if( size(r_part)!=size(tg[disk,"partitions"]:[]) )
  3564.     {
  3565.     map p = filter( map part, tg[disk,"partitions"]:[],
  3566.             ``(part["device"]:"" == device ))[0]:$[];
  3567.     if( size(p)>0 )
  3568.         {
  3569.         p = filter(string k, any e, (map<string,any>)p, ``(k != key) );
  3570.         r_part    = add( r_part, p );
  3571.         tg[disk,"partitions"] = r_part;
  3572.         }
  3573.     }
  3574.     return( tg );
  3575.     }
  3576.  
  3577.  
  3578.  
  3579.  
  3580.  
  3581.     /* maindevkey = all | maindevkey
  3582.        what = "all"        |
  3583.               "assigned_raid"    | "assigned_vg"  | "not_assigned" | "assigned"
  3584.           "delete" | "no_delete"
  3585.           "edit_possible"    | "delete_possible" |
  3586.           "display_possible" |
  3587.           "assign_raid_possible" | "assign_vg_possible"
  3588.           "no_virtal"     | "virtual"
  3589.       how = "all"    | "key_list"  | "index_list" (   raid_lib -> get_possible_rds  )
  3590.     */
  3591.  
  3592.  
  3593.  
  3594.  
  3595. /* Contain the current key ( subdevkey ) for all wizards */
  3596. string WizardKey = "";
  3597.  
  3598. global define string GetWizardKey()
  3599.     ``{
  3600.     y2debug( " Return wizard key %1", WizardKey);
  3601.     return WizardKey;
  3602.     };
  3603.  
  3604. global define void SetWizardKey( string key )
  3605.     ``{
  3606.     y2debug(" Set WizardKey %1", WizardKey);
  3607.     WizardKey = key;
  3608.     };
  3609.  
  3610.  
  3611.     /* Functions for testing */
  3612.  
  3613.     global define void DebugStorage()``{
  3614.  
  3615.     y2milestone("StorageMaps: %1",StorageMaps);
  3616.     y2milestone("Storage:%1",StorageMap);
  3617.     }
  3618.  
  3619.  
  3620. /**
  3621.  * Check if a disk is a real disk and not RAID or LVM
  3622.  * @return boolean true if real disk
  3623.  */
  3624. global define boolean IsRealDisk( map entry )
  3625.     ``{
  3626.     return( entry["type"]:`CT_UNKNOWN==`CT_DISK &&
  3627.             !(entry["type"]:`CT_UNKNOWN==`CT_DISK && entry["readonly"]:false &&
  3628.           entry["driver"]:""=="vbd") );
  3629.     }
  3630.  
  3631. /**
  3632.  * Check if a container is partitionale 
  3633.  * @return boolean true if partitionale
  3634.  */
  3635. global define boolean IsPartitionable( map entry )
  3636.     {
  3637.     return( entry["type"]:`CT_UNKNOWN==`CT_DMRAID ||
  3638.             IsRealDisk( entry ) );
  3639.     }
  3640.  
  3641. global define boolean DeviceRealDisk( string device )
  3642.     ``{
  3643.     boolean ret = false;
  3644.  
  3645.     if( search( device, "LABEL" )!=0 && search( device, "UUID" )!=0 )
  3646.     {
  3647.     map dev = $[];
  3648.     dev = GetDiskPartition( device );
  3649.     ret = dev["disk"]:"" != "/dev/md" && dev["disk"]:"" != "/dev/loop" &&
  3650.           search( dev["disk"]:"", "/dev/evms")!=0 &&
  3651.           is( dev["nr"]:(any)0, integer );
  3652.     if( !ret && dev["disk"]:"" != "/dev/md" )
  3653.         {
  3654.         map st = (map)SCR::Read( .target.stat, dev["disk"]:"" );
  3655.         ret = !st["isdir"]:false;
  3656.         }
  3657.     }
  3658.     y2milestone( "DeviceRealDisk %1 ret %2", device, ret );
  3659.     return ret;
  3660.     }
  3661.  
  3662. /**
  3663.   * Determine if there is any Linux partition on this system.
  3664.   *
  3665.   * If there is none, we don't need to ask if the user wants to update or
  3666.   * boot an installed system - he can only do a new installation anyway.
  3667.   * No time-consuming or dangerous operations should be performed here,
  3668.   * only simple checks for existence of a Linux (type 83) partition.
  3669.   *
  3670.   * @return boolean true if there is anything that might be a Linux partition
  3671.   **/
  3672. global define boolean HaveLinuxPartitions() ``{
  3673.     boolean ret = false;
  3674.     foreach ( string dev, map disk, GetTargetMap(), ``{
  3675.         if( !ret )
  3676.         {
  3677.         if( IsPartitionable( disk ) )
  3678.         {
  3679.         foreach( map e, disk["partitions"]:[], ``{
  3680.             ret = ret ||
  3681.               Partitions::IsLinuxPartition( e["fsid"]:Partitions::fsid_native );
  3682.             });
  3683.         }
  3684.         }
  3685.     });
  3686.     y2milestone( "HaveLinuxPartitions ret=%1", ret );
  3687.     return( ret );
  3688.     };
  3689.  
  3690. /**
  3691.  * Get list of all Partitions on all real disks
  3692.  * @return list Partition list
  3693.  */
  3694. global define list GetPartitionList()``{
  3695.     list ret = [];
  3696.     foreach ( string dev, map disk, GetTargetMap(), ``{
  3697.         if( IsPartitionable( disk ) )
  3698.         {
  3699.         list<map> l = disk["partitions"]:[];
  3700.         ret = union( ret, maplist( map p, l, ``(p["device"]:"")));
  3701.         }
  3702.     });
  3703.     ret = sort( ret );
  3704.     y2debug( "GetPartitionList ret=%1", ret );
  3705.     return( ret );
  3706.     }
  3707.  
  3708. /**
  3709.  * Get list of all Linux Partitions on all real disks
  3710.  * @return list Partition list
  3711.  */
  3712. global define list GetOtherLinuxPartitions()``{
  3713.     list ret = [];
  3714.     foreach ( string dev, map disk, GetTargetMap(), ``{
  3715.         if( IsPartitionable( disk ) )
  3716.         {
  3717.         list<map> l = (list<map>) filter( map p, disk["partitions"]:[],
  3718.                          ``(!p["format"]:false &&
  3719.                     Partitions::IsLinuxPartition(p["fsid"]:0)) );
  3720.         l = filter(map p, l, ``(contains( [`xfs, `ext2, `ext3, `jfs, `reiser],
  3721.                                         p["used_fs"]:`unknown)));
  3722.         l = filter(map p, l,
  3723.             ``(!FileSystems::IsSystemMp( p["mount"]:"", false )));
  3724.         if( size(l)>0 )
  3725.         {
  3726.         ret = union( ret, l );
  3727.         }
  3728.         }
  3729.     });
  3730.     y2milestone( "GetOtherLinuxPartitions ret=%1", ret );
  3731.     return( ret );
  3732.     }
  3733.  
  3734. /**
  3735.  * Check if swap paritition is availbe on a disk
  3736.  * @param disk Disk to be checked
  3737.  * @return boolean true if swap available.
  3738.  */
  3739. global define boolean CheckSwapOn( string disk )``{
  3740.     boolean ret = false;
  3741.     list swaps = SwappingPartitions();
  3742.     while( size(swaps)>0 && !ret )
  3743.     {
  3744.     if( search( swaps[0]:"", disk )==0)
  3745.         {
  3746.         ret = true;
  3747.         }
  3748.     swaps = remove( swaps, 0 );
  3749.     }
  3750.     y2milestone( "CheckSwapOn %1 ret %2", disk, ret );
  3751.     return( ret );
  3752.     }
  3753.  
  3754. global define list GetPrimPartitions( map<string,map> targets,
  3755.                                       boolean foreign_os )
  3756.     ``{
  3757.     list<map> ret = [];
  3758.     map entry = $[];
  3759.     string text = "";
  3760.     integer num_dos = 0;
  3761.     integer num_win = 0;
  3762.     integer num_os2 = 0;
  3763.     integer num_linux = 0;
  3764.     string linux_text = "Linux other";
  3765.     string dos_text = "dos";
  3766.     string win_text = "windows";
  3767.     string os2_text = "OS/2 Boot Manager";
  3768.  
  3769.     foreach(string disk, map data, targets,
  3770.     ``{
  3771.     foreach(map part, data["partitions"]:[],
  3772.         ``{
  3773.         string device = part["device"]:"";
  3774.         if( part["type"]:`unknown == `primary &&
  3775.             SCR::Execute (.target.bash,
  3776.                       "/usr/lib/YaST2/bin/check.boot "+device) == 0)
  3777.         {
  3778.         text = "";
  3779.             if( Partitions::IsDosWinNtPartition( part["fsid"]:0 ) &&
  3780.             GetFreeSpace( device, 0, part["used_fs"]:`none, false )["win_disk"]:false )
  3781.             {
  3782.             if( contains( Partitions::fsid_dostypes, part["fsid"]:0 ) )
  3783.             {
  3784.             num_dos = num_dos+1;
  3785.             text = dos_text;
  3786.             }
  3787.             else
  3788.             {
  3789.             num_win = num_win+1;
  3790.             text = win_text;
  3791.             }
  3792.             }
  3793.         else if( part["fsid"]:0 == 0x12 && !foreign_os )
  3794.             {
  3795.             text = "Vendor diagnostic";
  3796.             }
  3797.         else if( part["fsid"]:0 == 0x0a )
  3798.             {
  3799.             text = os2_text;
  3800.             num_os2 = num_os2+1;
  3801.             }
  3802.         else if( part["fsid"]:0 == Partitions::fsid_native &&
  3803.                  size(part["mount"]:"")==0 && !foreign_os )
  3804.             {
  3805.             text = linux_text;
  3806.             num_linux = num_linux+1;
  3807.             }
  3808.         if( size(text)>0 )
  3809.             {
  3810.             entry["device"] = device;
  3811.             entry["string"] = text;
  3812.             ret = add( ret, eval(entry) );
  3813.             y2milestone( "new entry %1", entry );
  3814.             }
  3815.         }
  3816.         });
  3817.     });
  3818.     y2milestone( "GetPrimPartitions foreign_os:%5 num_linux %1 num_win %2 num_dos %3 num_os2 %4",
  3819.                  num_linux, num_win, num_dos, num_os2, foreign_os );
  3820.     integer num = 1;
  3821.     if( num_linux>1 )
  3822.     {
  3823.     ret = maplist( map entry, ret,
  3824.         ``{
  3825.         if( entry["string"]:""==linux_text )
  3826.         {
  3827.         entry["string"] = linux_text + sformat( " %1", num );
  3828.         num = num+1;
  3829.         }
  3830.         return( entry );
  3831.         });
  3832.     }
  3833.     num = 1;
  3834.     if( num_dos>1 )
  3835.     {
  3836.     ret = maplist( map entry, ret,
  3837.         ``{
  3838.         if( entry["string"]:""==dos_text )
  3839.         {
  3840.         entry["string"] = dos_text + sformat( " %1", num );
  3841.         num = num+1;
  3842.         }
  3843.         return( entry );
  3844.         });
  3845.     }
  3846.     num = 1;
  3847.     if( num_win>1 )
  3848.     {
  3849.     ret = maplist( map entry, ret,
  3850.         ``{
  3851.         if( entry["string"]:""==win_text )
  3852.         {
  3853.         entry["string"] = win_text + sformat( " %1", num );
  3854.         num = num+1;
  3855.         }
  3856.         return( entry );
  3857.         });
  3858.     }
  3859.     num = 1;
  3860.     if( num_os2>1 )
  3861.     {
  3862.     ret = maplist( map entry, ret,
  3863.         ``{
  3864.         if( entry["string"]:""==os2_text )
  3865.         {
  3866.         entry["string"] = os2_text + sformat( " %1", num );
  3867.         num = num+1;
  3868.         }
  3869.         return( entry );
  3870.         });
  3871.     }
  3872.     y2milestone( "GetPrimPartitions ret %1", ret );
  3873.     return( ret );
  3874.     }
  3875.  
  3876. global define list GetWinPrimPartitions( map<string,map> targets )
  3877.     ``{
  3878.     list ret = GetPrimPartitions( targets, true );
  3879.     y2milestone( "GetWinPrimPartitions ret %1", ret );
  3880.     return( ret );
  3881.     }
  3882.  
  3883. global define list<string> AddPackageList()
  3884.     ``{
  3885.     list<string> pl = hw_packages;
  3886.     boolean mount_lvm = false;
  3887.     boolean need_evms = false;
  3888.     map<string,map> tg = GetTargetMap();
  3889.     map<string,map> tt = filter( string k, map e, tg,
  3890.                                  ``(e["type"]:`CT_UNKNOWN==`CT_LVM ));
  3891.     boolean have_lvm = size(tt)>0;
  3892.     if( have_lvm )
  3893.     {
  3894.     list<map> part = [];
  3895.     foreach( string k, map e, tt,
  3896.          ``{
  3897.          part = (list<map>)merge( part, e["partitions"]:[]);
  3898.          });
  3899.     mount_lvm = size(filter( map p, part, ``(size(p["mount"]:"")>0)))>0;
  3900.     }
  3901.     tt = filter( string k, map e, tg, ``(k=="/dev/evms"||search(k, "/dev/evms/")==0));
  3902.     if( size(filter( string k, map e, tg, ``(e["is_container"]:false &&
  3903.                          search(e["name"]:"","lvm/")!=0 &&
  3904.                          search(e["name"]:"","lvm2/")!=0)))>0)
  3905.     {
  3906.     y2milestone( "non lvm evms container" );
  3907.     need_evms = true;
  3908.     }
  3909.     if( !need_evms )
  3910.     {
  3911.     list<map> part = [];
  3912.     foreach( string k, map e, tt,
  3913.          ``{
  3914.          part = (list<map>)merge( part, e["partitions"]:[]);
  3915.          });
  3916.     need_evms = size(filter( map p, part, ``(size(p["mount"]:"")>0)))>0;
  3917.     }
  3918.     y2milestone( "AddPackageList have_lvm %1 mount_lvm %2 need_evms %3",
  3919.                   have_lvm, mount_lvm, need_evms );
  3920.     if( have_lvm && (mount_lvm||!need_evms))
  3921.     {
  3922.     pl = add( pl, "lvm2" );
  3923.     }
  3924.     if( need_evms )
  3925.     {
  3926.     pl = add( pl, "evms" );
  3927.     pl = add( pl, "yast2-storage-evms" );
  3928.     }
  3929.     y2milestone( "AddPackageList ret %1", pl );
  3930.     return( pl );
  3931.     }
  3932.  
  3933. global define list GetForeignPrimary()
  3934.     ``{
  3935.     list ret = [];
  3936.     if( Arch::i386 () || Arch::ia64 () || Arch::x86_64 () )
  3937.     {
  3938.     foreach(map e, (list<map>)GetPrimPartitions( GetTargetMap(), false ),
  3939.         ``{
  3940.         ret = add( ret, sformat( "%1 %2", e["device"]:"", e["string"]:"" ));
  3941.         });
  3942.     }
  3943.     y2milestone( "ret=%1", ret );
  3944.     return( ret );
  3945.     }
  3946.  
  3947. global define map IsResizable( map part )
  3948.     ``{
  3949.     map ret = FileSystems::IsResizable(`unknown);
  3950.     if( !Arch::s390 () &&
  3951.         (part["type"]:`none==`lvm || Partitions::IsResizable( part["fsid"]:0 )))
  3952.     {
  3953.     if( part["fsid"]:0==Partitions::fsid_swap )
  3954.         {
  3955.         ret = FileSystems::IsResizable(`swap);
  3956.         }
  3957.     else
  3958.         {
  3959.         ret = FileSystems::IsResizable(part["used_fs"]:`unknown);
  3960.         }
  3961.     }
  3962.     y2milestone( "IsResizable part:%1 ret:%2", part, ret );
  3963.     return( ret );
  3964.     }
  3965.  
  3966. global define integer FreeCylAfter( map disk, map partition )
  3967.     ``{
  3968.     integer ret = 0;
  3969.     integer next_used_cyl = disk["cyl_count"]:0;
  3970.     integer cylinder = partition["region",0]:0;
  3971.     if( haskey( partition, "orig_size_k" ))
  3972.     {
  3973.         cylinder = cylinder + partition["orig_size_k"]:0*1024/disk["cyl_size"]:1;
  3974.         }
  3975.     else
  3976.     {
  3977.         cylinder = cylinder + partition["region",1]:0;
  3978.         }
  3979.     if( partition["type"]:`primary == `logical )
  3980.     {
  3981.     map ext = filter( map part, disk["partitions"]:[],
  3982.               ``( part["type"]:`primary==`extended ))[0]:$[];
  3983.     next_used_cyl = ext["region",0]:0+ext["region",1]:0;
  3984.     }
  3985.     if( cylinder < next_used_cyl )
  3986.     {
  3987.     foreach(map part, disk["partitions"]:[], ``{
  3988.         integer start = part["region",0]:0;
  3989.         if( start >= cylinder && start < next_used_cyl )
  3990.         {
  3991.         next_used_cyl = start;
  3992.         }
  3993.         });
  3994.     }
  3995.     if( next_used_cyl >= cylinder )
  3996.     ret = next_used_cyl-cylinder;
  3997.     y2milestone( "FreeCylAfter cyl:%1 ret:%2", cylinder, ret );
  3998.     return( ret );
  3999.     }
  4000.  
  4001. global define boolean CheckNextCreated( map disk, list region )
  4002.     ``{
  4003.     boolean ret = false;
  4004.     integer cylinder = region[0]:0 + region[1]:0;
  4005.     foreach(map part, disk["partitions"]:[], ``{
  4006.     if( part["region",0]:0 == cylinder && part["create"]:false )
  4007.         {
  4008.         ret = true;
  4009.         }
  4010.     });
  4011.     y2milestone( "CheckNextCreated region:%1 ret:%2", region, ret );
  4012.     return( ret );
  4013.     }
  4014.  
  4015. global define string PathToDestdir( string pt )
  4016.     ``{
  4017.     if( Installation::scr_destdir != "/" )
  4018.     {
  4019.     pt = Installation::scr_destdir + pt;
  4020.     }
  4021.     return( pt );
  4022.     }
  4023.  
  4024. //-----------------------------------------------------
  4025. //
  4026. // change an entry in /etc/fstab
  4027. //
  4028. global define void ChangeLineFstab( map entry )
  4029.     ``{
  4030.     string tabpath = PathToDestdir( "/etc/fstab" );
  4031.     if( Installation::scr_destdir != "/" )
  4032.     {
  4033.     if( SCR::Read( .target.size, tabpath )>= 0 )
  4034.         SCR::Execute( .target.remove, tabpath );
  4035.     }
  4036.     map fstab = Partitions::GetFstab( tabpath );
  4037.     list lines = Storage::FindFstabLines( fstab, entry["mount"]:"",
  4038.                                           entry["spec"]:"", "x", "x" );
  4039.     list fstlist = [ entry["spec"]:"", entry["mount"]:"",
  4040.              entry["vfstype"]:"", entry["mntops"]:"",
  4041.              sformat("%1",entry["freq"]:0),
  4042.              sformat("%1",entry["passno"]:0) ];
  4043.     y2milestone( "lines %1", lines );
  4044.     if( size(lines)==0 )
  4045.     {
  4046.     AsciiFile::AppendLine( fstab, fstlist );
  4047.     }
  4048.     else
  4049.     {
  4050.     integer field = 0;
  4051.     while( field<4 )
  4052.         {
  4053.         AsciiFile::ChangeLineField( fstab, lines[0]:-1, field,
  4054.                     fstlist[field]:"" );
  4055.         field = field+1;
  4056.         }
  4057.     }
  4058.     string dir = entry["mount"]:"";
  4059.     if( substring( dir, 0, 1 )== "/" )
  4060.     {
  4061.     dir = PathToDestdir( dir );
  4062.     if( SCR::Read( .target.size, dir )<=0 )
  4063.         {
  4064.         SCR::Execute( .target.mkdir, dir );
  4065.         }
  4066.     }
  4067.     AsciiFile::RewriteFile( fstab, tabpath );
  4068.     };
  4069.  
  4070. global define map MakeCdromFstabEntry( map cd )
  4071.     ``{
  4072.     map entry = FileSystems::GetFstabDefaultMap( "cdrom" );
  4073.     string cdmount = cd["linkname"]:"";
  4074.     entry["spec"] = cdmount;
  4075.     entry["mount"] = "/media/"+substring(cdmount,5);
  4076.     string enc = FileSystems::LangTypicalEncoding();
  4077.     if( !contains( [ "iso8859-1", "iso8859-15", "" ], enc ))
  4078.     {
  4079.     entry["mntops"] = entry["mntops"]:"" + ",iocharset=" + enc;
  4080.     }
  4081.     y2milestone( "ret %1", entry );
  4082.     return( entry );
  4083.     };
  4084.  
  4085. define void HandleModulesOnBoot( map<string,map> targetMap )
  4086.     ``{
  4087.     list<string> ml = filter( string e,
  4088.                               (list<string>) splitstring( Misc::SysconfigRead( .sysconfig.kernel.MODULES_LOADED_ON_BOOT, "" ), " \t"),
  4089.                   ``(size(e)>0));
  4090.     y2milestone( "HandleModulesOnBoot ml %1", ml );
  4091.     boolean need_cryptoloop = false;
  4092.     boolean need_fish2 = false;
  4093.     foreach( string disk, map e, targetMap,
  4094.     ``{
  4095.     foreach( map p, e["partitions"]:[],
  4096.         ``{
  4097.         if( p["noauto"]:false && p["enc_type"]:`none!=`none )
  4098.         {
  4099.         if( p["enc_type"]:`none == `twofish )
  4100.             need_cryptoloop = true;
  4101.         else if( p["enc_type"]:`none == `twofish_old ||
  4102.                  p["enc_type"]:`none == `twofish_256_old )
  4103.             need_fish2 = true;
  4104.         }
  4105.         });
  4106.     });
  4107.     y2milestone( "HandleModulesOnBoot need_fish2 %1 need_cryptoloop %2", need_fish2,
  4108.                  need_cryptoloop );
  4109.     if( need_fish2 && find( string e, ml, ``(e=="loop_fish2"))==nil )
  4110.     {
  4111.     ml = add( ml, "loop_fish2" );
  4112.     SCR::Write( .sysconfig.kernel.MODULES_LOADED_ON_BOOT,
  4113.             mergestring( ml, " " ) );
  4114.  
  4115.     }
  4116.     if( need_cryptoloop && find( string e, ml, ``(e=="cryptoloop"))==nil )
  4117.     {
  4118.     ml = add( ml, "cryptoloop" );
  4119.     SCR::Write( .sysconfig.kernel.MODULES_LOADED_ON_BOOT,
  4120.             mergestring( ml, " " ) );
  4121.     }
  4122.     if( need_cryptoloop && find( string e, ml, ``(e=="twofish"))==nil )
  4123.     {
  4124.     ml = add( ml, "twofish" );
  4125.     SCR::Write( .sysconfig.kernel.MODULES_LOADED_ON_BOOT,
  4126.             mergestring( ml, " " ) );
  4127.  
  4128.     }
  4129.     }
  4130.  
  4131. global define integer AddFstabEntry( map e )
  4132.     {
  4133.     y2milestone( "AddFstabEntry entry:%1", e );
  4134.     integer ret = 0;
  4135.     integer freq = e["freq"]:0;
  4136.     integer passno = e["passno"]:0;
  4137.     string dev = e["spec"]:"";
  4138.     string m = e["mount"]:"";
  4139.     string vfs = e["vfstype"]:"auto";
  4140.     string opts = e["mntops"]:"defaults";
  4141.     ret = LibStorage::StorageInterface::addFstabEntry( sint, dev, m, vfs, opts,
  4142.                                freq, passno );
  4143.     if( ret<0 )
  4144.     y2error( "ret:%1 entry:%2", ret, e );
  4145.     return( ret );
  4146.     }
  4147.  
  4148. global define void ActivateHld( boolean val )
  4149.     {
  4150.     y2milestone( "ActivateHld val:%1", val );
  4151.     LibStorage::StorageInterface::activateHld( sint, val );
  4152.     }
  4153.  
  4154. global define void SetMdOn( boolean on )
  4155.     {
  4156.     y2milestone( "SetMdOn on %1", on );
  4157.     ActivateHld( on );
  4158.     y2milestone( "return" );
  4159.     }
  4160.  
  4161. void UpdateBootFstabEvms()
  4162.     {
  4163.     string tabpath = PathToDestdir( "/etc/fstab" );
  4164.     y2milestone( "UpdateBootFstabEvms %1", 
  4165.                  SCR::Execute( .target.bash_output, "grep /boot " + tabpath ));
  4166.     map fstab = Partitions::GetFstab( tabpath );
  4167.     list lines = AsciiFile::FindLineField( fstab, 1, Partitions::BootMount() );
  4168.     y2milestone( "UpdateBootFstabEvms lines %1", lines );
  4169.     map l = AsciiFile::GetLine( fstab, lines[0]:-1 );
  4170.     if( search( l["fields",0]:"", "/dev/evms" )!=0 )
  4171.     AsciiFile::ChangeLineField( fstab, lines[0]:-1, 0, 
  4172.                                 "/dev/evms/"+substring(l["fields",0]:"",5));
  4173.     AsciiFile::RewriteFile( fstab, tabpath );
  4174.     y2milestone( "UpdateBootFstabEvms %1", 
  4175.                  SCR::Execute( .target.bash_output, "grep /boot " + tabpath ));
  4176.     }
  4177.  
  4178. global define boolean BootEvms();
  4179.  
  4180. global define void WriteFstab()
  4181.     ``{
  4182.     y2milestone( "WriteFstab called" );
  4183.     StorageDevices::MakeCDLinks();
  4184.     Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "proc" ) );
  4185.     Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "sys" ) );
  4186.     Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "debug" ) );
  4187.     if( Hotplug::haveUSB )
  4188.     Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "usb" ) );
  4189.     Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "pts" ) );
  4190.  
  4191.     map m = $[];
  4192.     integer num = 0;
  4193.     
  4194.     foreach( string tdevice, any tdata, StorageDevices::ZipDrives,
  4195.     ``{
  4196.     m = FileSystems::GetFstabDefaultMap( "zip" );
  4197.     string zfile = "/zip";
  4198.     if( num > 0 )
  4199.         zfile = zfile + sformat( "%1", num );
  4200.     m["mount"] = "/media"+zfile;
  4201.     m["spec"] = tdevice+"4";
  4202.     Storage::AddFstabEntry( m );
  4203.     num = num+1;
  4204.     });
  4205.     num = 0;
  4206.     foreach( map drive, StorageDevices::FloppyDrives,
  4207.     ``{
  4208.     m = FileSystems::GetFstabDefaultMap( "floppy" );
  4209.     string fdname = "/floppy";
  4210.     if( num > 0 )
  4211.         fdname = fdname + sformat( "%1", num );
  4212.     m["mount"] = "/media"+fdname;
  4213.     m["spec"] = drive["dev_name"]:"";
  4214.     Storage::AddFstabEntry( m );
  4215.     num = num+1;
  4216.     });
  4217.     if( BootEvms() )
  4218.     UpdateBootFstabEvms();
  4219.     HandleModulesOnBoot( GetTargetMap() );
  4220.     }
  4221.  
  4222. global define map<string,map> SpecialBootHandling( map<string,map> tg )
  4223.     ``{
  4224.     boolean have_ppc_boot = false;
  4225.     foreach( string dev, map disk, tg,
  4226.     ``{
  4227.     foreach(map part, disk["partitions"]:[],
  4228.         ``{
  4229.         if( !have_ppc_boot &&
  4230.             part["fsid"]:0 == Partitions::fsid_prep_chrp_boot &&
  4231.         size(part["mount"]:"")==0 && part["create"]:false )
  4232.         {
  4233.         have_ppc_boot = true;
  4234.         }
  4235.         });
  4236.     });
  4237.     y2milestone( "SpecialBootHandling: have_ppc_boot:%1", have_ppc_boot );
  4238.     foreach( string dev, map disk, tg,
  4239.     ``{
  4240.     list new_part = [];
  4241.     foreach(map part, disk["partitions"]:[],
  4242.         ``{
  4243.         // convert a mount point of /boot to a 41 PReP boot partition
  4244.         if( Partitions::PrepBoot() &&
  4245.         part["mount"]:"" == Partitions::BootMount() && !have_ppc_boot )
  4246.         {
  4247.         integer id = Partitions::fsid_prep_chrp_boot;
  4248.         part["format"] = false;
  4249.         part["mount"] = "";
  4250.         part["fstype"] = Partitions::FsIdToString( id );
  4251.         part["prep_install"] = true;
  4252.         if( !part["create"]:false && part["fsid"]:0 != id )
  4253.             {
  4254.             part["ori_fsid"] = part["fsid"]:0;
  4255.             part["change_fsid"] = true;
  4256.             }
  4257.         part["fsid"] = id;
  4258.         y2milestone( "SpecialBootHandling modified Prep part=%1", part );
  4259.         }
  4260.         if( Arch::board_mac () &&
  4261.         part["mount"]:"" == Partitions::BootMount() )
  4262.         {
  4263.         integer id = Partitions::fsid_mac_hfs;
  4264.         part["mount"] = "";
  4265.         part["fstype"] = Partitions::FsIdToString( id );
  4266.         part["fsid"] = id;
  4267.         part["used_fs"] = `hfs;
  4268.         part["detected_fs"] = `hfs;
  4269.         y2milestone( "SpecialBootHandling modified hfs part=%1", part );
  4270.         }
  4271.         if( Arch::ia64 () &&
  4272.         part["mount"]:"" == Partitions::BootMount() )
  4273.         {
  4274.         integer id = Partitions::fsid_gpt_boot;
  4275.         part["fsid"] = id;
  4276.         part["fstype"] = Partitions::FsIdToString( id );
  4277.         if( !part["create"]:false && part["detected_fs"]:`none==`vfat )
  4278.             {
  4279.             part["format"] = false;
  4280.             }
  4281.         y2milestone( "SpecialBootHandling modified GPT boot part=%1", part );
  4282.         }
  4283.         new_part = add( new_part, part );
  4284.         });
  4285.     tg[dev,"partitions"] = new_part;
  4286.     });
  4287.     return( tg );
  4288.     }
  4289.  
  4290. global define list<list<string> > AutodetectMultipathRaid( map<string,map> tg )
  4291.     ``{
  4292.     list<list<string> > ret = [];
  4293.     map<string, list> disks = (map<string, list>) $[];
  4294.     foreach(string dev, map disk, tg,
  4295.     ``{
  4296.     string id = disk["unique"]:"";
  4297.     integer pos = search( id, "." );
  4298.     if( pos != nil )
  4299.         {
  4300.         id = substring( id, pos+1 );
  4301.         if( haskey( disks, id ) )
  4302.         {
  4303.         disks[id] = add( disks[id]:[], dev );
  4304.         }
  4305.         else
  4306.         {
  4307.         disks[id] = [ dev ];
  4308.         }
  4309.         }
  4310.     });
  4311.     disks = (map<string, list>) filter(string key, list entry, disks, ``(size(entry)>=2) );
  4312.     y2milestone( "disks %1", disks );
  4313.     foreach( string key, list entry, disks,
  4314.     ``{
  4315.     foreach(map p, tg[entry[0]:"","partitions"]:[],
  4316.         ``{
  4317.         boolean ok = true;
  4318.         list<string> dl = [];
  4319.         foreach(string disk, (list<string>)entry,
  4320.         ``{
  4321.         string dev = p["device"]:"";
  4322.         map p1 = GetPartition( tg, dev );
  4323.         if( p1["type"]:`primary == `extended ||
  4324.             p1["used_by_type"]:`UB_NONE!=`UB_NONE ||
  4325.             size(p1["mount"]:"")>0 )
  4326.             {
  4327.             ok = false;
  4328.             }
  4329.         dl = add( dl, dev );
  4330.         });
  4331.         if( ok )
  4332.         {
  4333.         ret = add( ret, dl );
  4334.         }
  4335.         });
  4336.     });
  4337.     y2milestone( "ret %1", ret );
  4338.     return( ret );
  4339.     }
  4340.  
  4341. global define boolean PerformLosetup( map& loop, boolean format )
  4342.     ``{
  4343.     boolean crypt_ok = false;
  4344.     string pwd = loop["passwd"]:"";
  4345.     string device = loop["partitionName"]:"";
  4346.     string mdir = Storage::SaveDumpPath("tmp_mp" );
  4347.     y2milestone( "PerformLosetup mdir:%1", mdir );
  4348.     if( (integer)SCR::Read(.target.size, mdir ) >= 0 )
  4349.     {
  4350.     SCR::Execute(.target.bash, "rm -f " + mdir );
  4351.     }
  4352.     SCR::Execute(.target.mkdir, mdir );
  4353.     crypt_ok = Storage::SetCryptPwd( device, pwd ) &&
  4354.                Storage::SetCrypt( device, true, false ) &&
  4355.            Storage::Mount( device, mdir );
  4356.     if( crypt_ok )
  4357.     {
  4358.     any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
  4359.     integer ret = LibStorage::StorageInterface::getVolume( sint, device,
  4360.                                                            vinfo );
  4361.     if( ret!=0 )
  4362.         {
  4363.         y2error( "PerformLosetup device:%1 not found (ret:%2)", device, ret );
  4364.         crypt_ok = false;
  4365.         }
  4366.     else
  4367.         {
  4368.         map curr = $[];
  4369.         curr = volumeMap( vinfo, curr );
  4370.         loop["loop_dev"] = curr["loop"]:"";
  4371.         y2milestone( "PerformLosetup loop:%1", loop["loop_dev"]:"" );
  4372.         }
  4373.     SCR::Execute(.target.bash, "umount " + mdir );
  4374.     }
  4375.     y2milestone( "PerformLosetup ret %1", crypt_ok );
  4376.     return( crypt_ok );
  4377.     }
  4378.  
  4379. global define symbol DetectFs( string device )
  4380.     ``{
  4381.     symbol ret = `unknown;
  4382.     y2milestone( "DetectFs:%1", device );
  4383.     any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
  4384.     integer r = LibStorage::StorageInterface::getVolume( sint, device, vinfo );
  4385.     if( r!=0 )
  4386.     {
  4387.     y2error( "DetectFs device:%1 not found (ret:%2)", device, r );
  4388.     }
  4389.     else
  4390.     {
  4391.     map curr = $[];
  4392.     curr = volumeMap( vinfo, curr );
  4393.     ret = curr["detected_fs"]:`unknown;
  4394.     }
  4395.     y2milestone( "DetectFs ret %1", ret );
  4396.     return( ret );
  4397.     }
  4398.  
  4399. global define boolean DiskmapNeeded()
  4400.     ``{
  4401.     boolean ret = false;
  4402.     map<string,map> real_disks = filter( string k, map e, GetTargetMap(), ``(IsRealDisk( e )) );
  4403.     list<string> disks = (list<string>) maplist( string k, map e, real_disks, ``(k));
  4404.     y2milestone( "disks %1", disks );
  4405.     boolean scsi_disk = false;
  4406.     boolean ide_disk = false;
  4407.     foreach( string k, disks,
  4408.     ``{
  4409.     if( search( k, "/dev/sd" )==0 )
  4410.         {
  4411.         scsi_disk = true;
  4412.         }
  4413.     else if( search( k, "/dev/hd" )==0 )
  4414.         {
  4415.         ide_disk = true;
  4416.         }
  4417.     else
  4418.         {
  4419.         ret = true;
  4420.         }
  4421.     });
  4422.     ret = ret || (scsi_disk && ide_disk);
  4423.     if( !ret && ide_disk )
  4424.     {
  4425.     string abc = "abcdefghijklmnopqrstuvwxyz";
  4426.     integer idx = 0;
  4427.     foreach( string k, disks,
  4428.         ``{
  4429.         y2milestone( "dev %1 abc %2", substring(k, 7, 1),
  4430.                      substring(abc, idx, 1));
  4431.         if( substring(k, 7, 1) != substring(abc, idx, 1) )
  4432.         {
  4433.         ret = true;
  4434.         }
  4435.         idx = idx+1;
  4436.         });
  4437.     }
  4438.     y2milestone( "ret %1 disks %2 ide %3 scsi %4", ret, size(disks), ide_disk,
  4439.                  scsi_disk );
  4440.     return( ret );
  4441.     };
  4442.  
  4443. global define boolean UseLilo()
  4444.     ``{
  4445.     boolean ret = false;
  4446.     y2milestone( "ret %1", ret );
  4447.     return( ret );
  4448.     }
  4449.  
  4450. global define list<string> GetDirPatterns( string dir, list patterns )
  4451.     ``{
  4452.     list<string> ret = [];
  4453.     string cmd = sformat( "cd %1 && (ls %2 2>/dev/null)", dir,
  4454.                           mergestring( (list<string>)patterns, " "));
  4455.     map out = (map) SCR::Execute( .target.bash_output, cmd );
  4456.     ret = splitstring( out["stdout"]:"", "\n" );
  4457.     ret = filter( string e, ret, ``(size(e)>0) );
  4458.     ret = maplist( string e, ret, ``(dir+"/"+e));
  4459.     y2milestone( "dir %1 pat %2", dir, patterns );
  4460.     y2milestone( "ret %1", ret );
  4461.     return( ret );
  4462.     }
  4463.  
  4464. global define map GetBootPartition( string disk )
  4465.     ``{
  4466.     map ret = $[];
  4467.     map tg = GetTargetMap();
  4468.     ret = filter( map p, tg[disk,"partitions"]:[], ``(p["boot"]:false))[0]:$[];
  4469.     y2milestone( "disk:%1 ret:%2", disk, ret );
  4470.     return( ret );
  4471.     }
  4472.  
  4473. global define void UpdateFstabSubfs()
  4474.     ``{
  4475.     y2milestone( "UpdateFstabSubfs removing fstab entries for cdrom and floppy" );
  4476.     string tabpath = PathToDestdir( "/etc/fstab" );
  4477.     map fstab = Partitions::GetFstab( tabpath );
  4478.     integer line = 0;
  4479.     list<integer> rem_lines = [];
  4480.     while( line<=AsciiFile::NumLines( fstab ) )
  4481.     {
  4482.     map l = AsciiFile::GetLine( fstab, line );
  4483.     if( search( l["fields",1]:"", "/media/floppy" )==0 )
  4484.         {
  4485.        AsciiFile::ChangeLineField( fstab, line, 2, "auto" );
  4486.        AsciiFile::ChangeLineField( fstab, line, 3, FileSystems::GetFstabDefaultMntops("floppy") );
  4487.  
  4488. //        rem_lines = add( rem_lines, line );
  4489.         }
  4490.     else if( search( l["fields",1]:"", "/media/cdrom" )==0 ||
  4491.          search( l["fields",1]:"", "/media/dvd" )==0 ||
  4492.          search( l["fields",1]:"", "/media/cdrecorder" )==0 ||
  4493.          search( l["fields",1]:"", "/media/dvdrecorder" )==0 ||
  4494.          search( l["fields",1]:"", "/cdrom" )==0 ||
  4495.          search( l["fields",1]:"", "/dvd" )==0 ||
  4496.          search( l["fields",1]:"", "/cdrecorder" )==0 ||
  4497.          search( l["fields",1]:"", "/dvdrecorder" )==0 )
  4498.         {
  4499.         rem_lines = add( rem_lines, line );
  4500.         }
  4501.     line = line+1;
  4502.     }
  4503.     y2milestone( "UpdateFstabSubfs %1", rem_lines );
  4504.     if( size(rem_lines)>0 )
  4505.     {
  4506.     AsciiFile::RemoveLines( fstab, rem_lines );
  4507.     }
  4508.     AsciiFile::RewriteFile( fstab, tabpath );
  4509.     }
  4510.  
  4511. global define void UpdateFstabSysfs()
  4512.     ``{
  4513.     y2milestone( "UpdateFstabSysfs called" );
  4514.     string tabpath = PathToDestdir( "/etc/fstab" );
  4515.     map fstab = Partitions::GetFstab( tabpath );
  4516.     integer line = 0;
  4517.     boolean have_sysfs = false;
  4518.     while( !have_sysfs && line<=AsciiFile::NumLines( fstab ) )
  4519.     {
  4520.     map l = AsciiFile::GetLine( fstab, line );
  4521.     have_sysfs = l["fields",1]:"" == "/sys";
  4522.     line = line+1;
  4523.     }
  4524.     if( !have_sysfs )
  4525.     {
  4526.     map entry = FileSystems::GetFstabDefaultMap( "sys" );
  4527.     list fstlist = [ entry["spec"]:"", entry["mount"]:"",
  4528.              entry["vfstype"]:"", entry["mntops"]:"",
  4529.              sformat("%1",entry["freq"]:0),
  4530.                  sformat("%1",entry["passno"]:0) ];
  4531.     y2milestone( "UpdateFstabSysfs entry %1", entry );
  4532.     y2milestone( "UpdateFstabSysfs fstlist %1", fstlist );
  4533.     AsciiFile::AppendLine( fstab, fstlist );
  4534.     AsciiFile::RewriteFile( fstab, tabpath );
  4535.     }
  4536.     }
  4537.  
  4538. global string HdToIseries( string input )
  4539.     ``{
  4540.     string ret = input;
  4541.     string regex = "/dev/hd[a-z][0-9]*";
  4542.     if( regexpmatch( input, regex ))
  4543.     {
  4544.     ret = "/dev/iseries/vd" + substring( ret, 7 );
  4545.     }
  4546.     y2milestone( "HdToIseries input:%1 ret:%2", input, ret );
  4547.     return( ret );
  4548.     }
  4549.  
  4550. global string SLES9PersistentDevNames( string input )
  4551.     ``{
  4552.     string ret = input;
  4553.     string regex1 = "/dev/disk/by-id/.*";
  4554.     string regex2 = "/dev/disk/by-path/.*";
  4555.     string prefix = "scsi-";
  4556.     string tmpdev = "";
  4557.  
  4558.     if( regexpmatch( input, ".*-part[0-9]*$" ))
  4559.         {
  4560.     return input;
  4561.     }
  4562.  
  4563.     if( regexpmatch( input, ".*/by-id/(scsi|ccw|usb|ata)-.*$" ))
  4564.     {
  4565.     return input;
  4566.     }
  4567.  
  4568.     if( regexpmatch( input, regex1 ))
  4569.     {
  4570.     if (regexpmatch ( input, ".*/by-id/0X.{4}p?[0-9]?$" ) )
  4571.         {
  4572.         prefix = "ccw-";
  4573.         }
  4574.     tmpdev = "/dev/disk/by-id/" + prefix + 
  4575.              substring( input, findlastof(input, "/")+1 );
  4576.     y2milestone( "by id tmp %1", tmpdev );
  4577.     ret = tmpdev;
  4578.     }
  4579.     else if( regexpmatch( input, regex2 ))
  4580.     {
  4581.     tmpdev = input;
  4582.     y2milestone( "by path tmp %1", tmpdev );
  4583.     }
  4584.  
  4585.     if( size(tmpdev)>0  )
  4586.     {
  4587.     if( regexpmatch( tmpdev, ".*p[0-9]*$" ) )
  4588.         {
  4589.         ret = regexpsub( tmpdev, "(.*)p([0-9]*)$", "\\1-part\\2" );
  4590.         }
  4591.     else
  4592.         {
  4593.         ret = regexpsub( tmpdev, "(.*[[:alpha:][:punct:]])([0-9]*)$", "\\1-part\\2" );
  4594.         }
  4595.     }
  4596.     y2milestone( "SLES9PersistentDevNames input:%1 ret:%2", input, ret );
  4597.     return( ret );
  4598.     }
  4599.  
  4600. global string HdDiskMap( string input, map diskmap )
  4601.     ``{
  4602.     string ret = input;
  4603.     map d = GetDiskPartition( input );
  4604.     if( haskey( diskmap, d["disk"]:"" ))
  4605.     {
  4606.     ret = GetDeviceName( diskmap[d["disk"]:""]:"", d["nr"]:(any)0 );
  4607.     }
  4608.     y2milestone( "HdDiskMap input:%1 ret:%2", input, ret );
  4609.     return( ret );
  4610.     }
  4611.  
  4612. global define void UpdateFstabIseriesVd()
  4613.     ``{
  4614.     y2milestone( "UpdateFstabIseriesVd updating hdx to iseries/vdx" );
  4615.     string tabpath = PathToDestdir( "/etc/fstab" );
  4616.     map fstab = Partitions::GetFstab( tabpath );
  4617.     integer line = 0;
  4618.     string n = "";
  4619.     while( line<=AsciiFile::NumLines( fstab ) )
  4620.     {
  4621.     map l = AsciiFile::GetLine( fstab, line );
  4622.     n = HdToIseries( l["fields",0]:"" );
  4623.     if( n != l["fields",0]:"" )
  4624.         {
  4625.         AsciiFile::ChangeLineField( fstab, line, 0, n );
  4626.         }
  4627.     line = line+1;
  4628.     }
  4629.     AsciiFile::RewriteFile( fstab, tabpath );
  4630.     tabpath = PathToDestdir( "/etc/cryptotab" );
  4631.     map crtab = Partitions::GetCrypto( tabpath );
  4632.     line = 0;
  4633.     while( line<=AsciiFile::NumLines( crtab ) )
  4634.     {
  4635.     map l = AsciiFile::GetLine( crtab, line );
  4636.     n = HdToIseries( l["fields",1]:"" );
  4637.     if( n != l["fields",1]:"" )
  4638.         {
  4639.         AsciiFile::ChangeLineField( crtab, line, 1, n );
  4640.         }
  4641.     line = line+1;
  4642.     }
  4643.     AsciiFile::RewriteFile( crtab, tabpath );
  4644.     }
  4645.  
  4646. global define void UpdateCdromLinks( map diskmap )
  4647.     ``{
  4648.     y2milestone( "UpdateCdromLinks map %1", diskmap );
  4649.     foreach( string link, StorageDevices::TypeNames,
  4650.     ``{
  4651.     string dev = "/dev/" + link;
  4652.     string cont = (string)SCR::Read( .target.symlink, dev );
  4653.     if( cont!=nil && search( cont, "/dev/") != 0 )
  4654.         cont = "/dev/" + cont;
  4655.     y2milestone( "UpdateCdromLinks dev %1 cont %2", dev, cont );
  4656.     if( cont!=nil && haskey( diskmap, cont ) && size(diskmap[cont]:"")>0 )
  4657.         {
  4658.         y2milestone( "Change symlink %1 from %2 -> %3", dev, cont,
  4659.                      diskmap[cont]:"" );
  4660.         SCR::Execute( .target.remove, dev );
  4661.         SCR::Execute( .target.symlink, substring(diskmap[cont]:"",5), dev );
  4662.         }
  4663.     });
  4664.     }
  4665.  
  4666. global define void UpdateFstabPersistentNames()
  4667.     ``{
  4668.     y2milestone( "UpdateFstabPersistentDevNames updating to SLES10 names" );
  4669.     string tabpath = PathToDestdir( "/etc/fstab" );
  4670.     map fstab = Partitions::GetFstab( tabpath );
  4671.     integer line = 0;
  4672.     string n = "";
  4673.     while( line<=AsciiFile::NumLines( fstab ) )
  4674.     {
  4675.     map l = AsciiFile::GetLine( fstab, line );
  4676.     n = SLES9PersistentDevNames( l["fields",0]:"" );
  4677.     if( n != l["fields",0]:"" )
  4678.         {
  4679.         AsciiFile::ChangeLineField( fstab, line, 0, n );
  4680.         }
  4681.     line = line+1;
  4682.     }
  4683.     AsciiFile::RewriteFile( fstab, tabpath );
  4684.     }
  4685.  
  4686. global define void UpdateFstabDiskmap( map diskmap )
  4687.     ``{
  4688.     y2milestone( "UpdateFstabdiskmap map %1", diskmap );
  4689.     string tabpath = PathToDestdir( "/etc/fstab" );
  4690.     map fstab = Partitions::GetFstab( tabpath );
  4691.     integer line = 0;
  4692.     string n = "";
  4693.     while( line<=AsciiFile::NumLines( fstab ) )
  4694.     {
  4695.     map l = AsciiFile::GetLine( fstab, line );
  4696.     n = HdDiskMap( l["fields",0]:"", diskmap );
  4697.     if( n != l["fields",0]:"" )
  4698.         {
  4699.         AsciiFile::ChangeLineField( fstab, line, 0, n );
  4700.         }
  4701.     line = line+1;
  4702.     }
  4703.     AsciiFile::RewriteFile( fstab, tabpath );
  4704.     tabpath = PathToDestdir( "/etc/cryptotab" );
  4705.     map crtab = Partitions::GetCrypto( tabpath );
  4706.     line = 0;
  4707.     while( line<=AsciiFile::NumLines( crtab ) )
  4708.     {
  4709.     map l = AsciiFile::GetLine( crtab, line );
  4710.     n = HdDiskMap( l["fields",1]:"", diskmap );
  4711.     if( n != l["fields",1]:"" )
  4712.         {
  4713.         AsciiFile::ChangeLineField( crtab, line, 1, n );
  4714.         }
  4715.     line = line+1;
  4716.     }
  4717.     AsciiFile::RewriteFile( crtab, tabpath );
  4718.     }
  4719.  
  4720. global define void UpdateCryptoType()
  4721.     ``{
  4722.     y2milestone( "UpdateCryptoType" );
  4723.     string tabpath = PathToDestdir( "/etc/fstab" );
  4724.     map fstab = Partitions::GetFstab( tabpath );
  4725.     integer line = 0;
  4726.     integer pos = 0;
  4727.     string searchstr = "encryption=twofish256";
  4728.     while( line<=AsciiFile::NumLines( fstab ) )
  4729.     {
  4730.     map l = AsciiFile::GetLine( fstab, line );
  4731.     pos = search( l["fields",3]:"", searchstr );
  4732.     if( pos != nil )
  4733.         {
  4734.         string new = substring( l["fields",3]:"", 0, pos );
  4735.         new = new + "encryption=twofishSL92";
  4736.         new = new + substring( l["fields",3]:"", pos+size(searchstr) );
  4737.         y2milestone( "new options line in %1 is %2", l, new );
  4738.         AsciiFile::ChangeLineField( fstab, line, 3, new );
  4739.         }
  4740.     line = line+1;
  4741.     }
  4742.     AsciiFile::RewriteFile( fstab, tabpath );
  4743.     tabpath = PathToDestdir( "/etc/cryptotab" );
  4744.     map crtab = Partitions::GetCrypto( tabpath );
  4745.     line = 0;
  4746.     while( line<=AsciiFile::NumLines( crtab ) )
  4747.     {
  4748.     map l = AsciiFile::GetLine( crtab, line );
  4749.     if( l["fields",4]:"" == "twofish256" )
  4750.         {
  4751.         y2milestone( "set twofishSL92 in line %1", l );
  4752.         AsciiFile::ChangeLineField( crtab, line, 4, "twofishSL92" );
  4753.         }
  4754.     line = line+1;
  4755.     }
  4756.     AsciiFile::RewriteFile( crtab, tabpath );
  4757.     }
  4758.  
  4759. global define void UpdateFstabUsbdevfs()
  4760.     ``{
  4761.     y2milestone( "UpdateFstabUsbdevfs updating usbdevfs to usbfs" );
  4762.     boolean changed = false;
  4763.     string tabpath = PathToDestdir( "/etc/fstab" );
  4764.     map fstab = Partitions::GetFstab( tabpath );
  4765.     integer line = 0;
  4766.     while( line<=AsciiFile::NumLines( fstab ) )
  4767.     {
  4768.     map l = AsciiFile::GetLine( fstab, line );
  4769.     if( l["fields",2]:"" == "usbdevfs" )
  4770.         {
  4771.         AsciiFile::ChangeLineField( fstab, line, 2, "usbfs" );
  4772.         AsciiFile::ChangeLineField( fstab, line, 0, "usbfs" );
  4773.         changed = true;
  4774.         }
  4775.     line = line+1;
  4776.     }
  4777.     if( changed )
  4778.     {
  4779.     y2milestone( "UpdateFstabUsbdevfs changed" );
  4780.     AsciiFile::RewriteFile( fstab, tabpath );
  4781.     }
  4782.     }
  4783.  
  4784.  
  4785. define map BuildDiskmap( map oldv )
  4786.     ``{
  4787.     map d = (map)SCR::Read( .target.stat,
  4788.                             Installation::destdir + "/var/lib/hardware" );
  4789.     if( d["isdir"]:false && oldv != DiskMapVersion )
  4790.     if( oldv != DiskMapVersion )
  4791.     {
  4792.     DiskMap = $[];
  4793.     string cmd = "";
  4794.     cmd = "LIBHD_HDDB_DIR=" + Installation::destdir + "/var/lib/hardware " +
  4795.           "hwinfo --map";
  4796.     y2milestone( "BuildDiskmap cmd %1", cmd );
  4797.     map bo = (map)SCR::Execute (.target.bash_output, cmd );
  4798.     y2milestone( "BuildDiskmap bo %1", bo );
  4799.     if( bo["exit"]:1==0 && size(bo["stdout"]:"")>0 )
  4800.         {
  4801.         list<string> lines = splitstring( bo["stdout"]:"", "\n" );
  4802.         foreach( string line, lines,
  4803.         ``{
  4804.         list<string> disks = filter( string d,
  4805.                                      splitstring( line, " \t" ),
  4806.                          ``(size(d)>0));
  4807.         if( size(disks)>1 )
  4808.             {
  4809.             integer index = 1;
  4810.             while( index<size(disks) )
  4811.             {
  4812.             DiskMap[disks[index]:""] = disks[0]:"";
  4813.             index = index+1;
  4814.             }
  4815.             }
  4816.         });
  4817.         }
  4818.     if( bo["exit"]:1==0 )
  4819.         DiskMapVersion = oldv;
  4820.     else
  4821.         DiskMapVersion = $[];
  4822.     y2milestone( "BuildDiskmap bo %1", bo );
  4823.     y2milestone( "BuildDiskmap DiskMap %1", DiskMap );
  4824.     y2milestone( "BuildDiskmap DiskMapVersion %1", DiskMapVersion );
  4825.     }
  4826.     return( DiskMap );
  4827.     }
  4828.  
  4829. global define void Update( map oldv, map newv )
  4830.     ``{
  4831.     y2milestone( "Update old:%1 new:%2", oldv, newv );
  4832.  
  4833.     // Enterprise products do not have minor release number
  4834.     // map enterprise releases to corresponding code bases of SL
  4835.     map sles_major_to_minor = $[ 8 : 2, 9 : 1, 10 : 1 ];
  4836.     if( haskey( oldv, "major" ) && !haskey( oldv, "minor" ) )
  4837.     {
  4838.     oldv["minor"] = sles_major_to_minor[oldv["major"]:0]:0;
  4839.     y2milestone( "Update old:%1", oldv );
  4840.     }
  4841.     if( haskey( newv, "major" ) && !haskey( newv, "minor" ) )
  4842.     {
  4843.     newv["minor"] = sles_major_to_minor[newv["major"]:0]:0;
  4844.     y2milestone( "Update new:%1", newv );
  4845.     }
  4846.     if( !haskey( oldv, "major" ) || !haskey( newv, "major" ) )
  4847.     y2error( "Missing key major or minor" );
  4848.  
  4849.     if( oldv["major"]:0<=9 )
  4850.     {
  4851.     UpdateFstabSysfs();
  4852.     }
  4853.     if( oldv["major"]:0<9 )
  4854.     {
  4855.     UpdateFstabUsbdevfs();
  4856.     }
  4857.     if( oldv["major"]:0==9 )
  4858.         {
  4859.     UpdateFstabPersistentNames();
  4860.     }
  4861.  
  4862.     map dm = BuildDiskmap( oldv );
  4863.     if( size(dm)>0 )
  4864.     {
  4865.     UpdateFstabDiskmap( dm );
  4866.     }
  4867.     if( oldv["major"]:0<9 || (oldv["major"]:0==9 && oldv["minor"]:0<=2))
  4868.     {
  4869.     Storage::UpdateCryptoType();
  4870.     }
  4871.     if( oldv["major"]:0<10 || (oldv["major"]:0==10 && oldv["minor"]:0==0) )
  4872.     {
  4873.     string of = "/etc/udev/rules.d/20-cdrom.rules";
  4874.     y2milestone( "removing obsolete %1", of );
  4875.     SCR::Execute( .target.remove, of );
  4876.     of = "/etc/udev/rules.d/55-cdrom.rules";
  4877.     y2milestone( "removing obsolete %1", of );
  4878.     SCR::Execute( .target.remove, of );
  4879.     StorageDevices::MakeCDLinks();
  4880.     }
  4881.     if( oldv["major"]:0<10 || (oldv["major"]:0==10 && oldv["minor"]:0==0))
  4882.     UpdateFstabSubfs();
  4883.     if( oldv["major"]:0<9 || (oldv["major"]:0==9 && oldv["minor"]:0==0))
  4884.     {
  4885.     if( Arch::board_iseries () )
  4886.         {
  4887.         UpdateFstabIseriesVd();
  4888.         }
  4889.     string cmd = "cd / && /sbin/insserv -r /etc/init.d/boot.evms";
  4890.     y2milestone( "Update cmd %1", cmd );
  4891.     map bo = (map)SCR::Execute (.target.bash_output, cmd );
  4892.     y2milestone( "Update bo %1", bo );
  4893.     }
  4894.     }
  4895.  
  4896. global define list<string> GetTranslatedDevices( map oldv, map newv,
  4897.                          list<string> names )
  4898.     {
  4899.     y2milestone( "GetTranslatedDevices old:%1 new:%2", oldv, newv );
  4900.     y2milestone( "GetTranslatedDevices names %1", names );
  4901.     list<string> ret = names;
  4902.     map dm = BuildDiskmap( oldv );
  4903.     if( size(dm)>0 )
  4904.     {
  4905.     ret = maplist( string n, names, ``(HdDiskMap( n, dm )));
  4906.     }
  4907.     if( (oldv["major"]:0<9 || (oldv["major"]:0==9 && oldv["minor"]:0==0)) &&
  4908.         Arch::board_iseries () )
  4909.     {
  4910.     ret = maplist( string n, names, ``(HdToIseries( n )));
  4911.     }
  4912.     if( oldv["major"]:0==9 )
  4913.     {
  4914.     ret = maplist( string n, names, ``(SLES9PersistentDevNames( n )));
  4915.     }
  4916.     y2milestone( "GetTranslatedDevices ret %1", ret );
  4917.     return( ret );
  4918.     }
  4919.  
  4920. global define list GetUsedLvmGroups( map<string,map> tg )
  4921.     ``{
  4922.     list groups = [];
  4923.     foreach( string disk, map data, tg,
  4924.     ``{
  4925.     if( data["type"]:`CT_UNKNOWN==`CT_LVM &&
  4926.         size( filter( map p, data["partitions"]:[],
  4927.                       ``(size(p["mount"]:"")>0 ) )) > 0 )
  4928.         {
  4929.         y2milestone( "GetUsedLvmGroups %1",
  4930.                      filter( map p, data["partitions"]:[],
  4931.                  ``(size(p["mount"]:"")>0 ) ) );
  4932.         groups = add( groups, substring( disk, 5 ) );
  4933.         }
  4934.     });
  4935.     y2milestone( "GetUsedLvmGroups ret %1", groups );
  4936.     return( groups );
  4937.     };
  4938.  
  4939. /**
  4940.  * Get used real disks
  4941.  * @param tg Target map
  4942.  * @return disks List of disks
  4943.  */
  4944. global define list<string> GetUsedRealDisksNew( map<string,map> tg, 
  4945.                                                 boolean ignore_boot )
  4946.     ``{
  4947.     list<string> disks = [];
  4948.     list lvmgr = GetUsedLvmGroups( tg );
  4949.     list mdlist = [];
  4950.     foreach( map p, tg["/dev/md","partitions"]:[],
  4951.     ``{
  4952.     if( size(p["mount"]:"")>0  ||
  4953.         contains( lvmgr, p["used_by"]:"" ) )
  4954.         {
  4955.         mdlist = add( mdlist, p["device"]:"" );
  4956.         }
  4957.     });
  4958.     foreach( string disk, map data, tg,
  4959.     ``{
  4960.     if( IsRealDisk( data ) &&
  4961.         size( filter( map p, data["partitions"]:[],
  4962.                       ``( (size(p["mount"]:"")>0 &&
  4963.                    (!ignore_boot ||
  4964.                     p["mount"]:""!=Partitions::BootMount())) ||
  4965.                   contains( mdlist, p["used_by"]:"" )  ||
  4966.                   contains( lvmgr, p["used_by"]:"" ) ) )) > 0 )
  4967.         {
  4968.         disks = add( disks, disk );
  4969.         }
  4970.     });
  4971.     y2milestone( "GetUsedRealDisksNew ignore_boot %1 ret %2", 
  4972.                  ignore_boot, disks );
  4973.     return( disks );
  4974.     };
  4975.  
  4976. global define list<string> GetUsedRealDisks( map<string,map> tg )
  4977.     {
  4978.     return( GetUsedRealDisksNew( tg, false ));
  4979.     };
  4980.  
  4981. global define list<string> GetEvmsRealDisk( map<string,map> tg, map p )
  4982.     ``{
  4983.     list<string> rdisk = [];
  4984.     string name = "";
  4985.     if( size(p["device"]:"")>10 )
  4986.     name = substring( p["device"]:"", 10 );
  4987.     if( search( name, "lvm/" ) == 0 || search( name, "lvm2/" ) == 0)
  4988.     {
  4989.     name = substring( name, 0, findlastof( name, "/" ));
  4990.     }
  4991.     y2milestone( "GetEvmsRealDisk name is %1", name );
  4992.     foreach( string disk, map data, tg,
  4993.     ``{
  4994.     if( size(name)>0 &&
  4995.         (IsRealDisk( data ) || disk=="/dev/md") &&
  4996.         size( filter( map p, data["partitions"]:[],
  4997.                       ``(p["used_by"]:"" == name)))>0 )
  4998.         {
  4999.         rdisk = (list<string>)union( rdisk, [ disk ] );
  5000.         }
  5001.     });
  5002.     if( size(rdisk)==0 && !p["evms_native"]:false )
  5003.     {
  5004.     map d = GetDiskPartition( EvmsDevDisk( p["device"]:"" ));
  5005.     if( haskey( tg, d["disk"]:"" ))
  5006.         {
  5007.         rdisk = [ d["disk"]:"" ];
  5008.         }
  5009.     }
  5010.     y2milestone( "GetEvmsRealDisk %1 is %2", p["device"]:"", rdisk );
  5011.     return( rdisk );
  5012.     }
  5013.  
  5014. global define list<string> GetUsedEvmsDisks( map<string,map> tg )
  5015.     ``{
  5016.     list<string> disks = [];
  5017.     list mdlist = [];
  5018.     foreach( string disk, map data, tg,
  5019.     ``{
  5020.     if( search( disk, "/dev/evms" )==0 )
  5021.         {
  5022.         foreach( map p, data["partitions"]:[],
  5023.         ``{
  5024.         if( size(p["mount"]:"")>0 )
  5025.             {
  5026.             list<string> dl = GetEvmsRealDisk( tg, p );
  5027.             foreach( string d, dl,
  5028.             ``{
  5029.             if( search( d, "/dev/md" ) == 0 )
  5030.                 {
  5031.                 list<string> ndl = [];
  5032.                 foreach( string dd, map pp, tg,
  5033.                 ``{
  5034.                 if( pp["used_by"]:"" == substring(d,5) )
  5035.                     {
  5036.                     ndl = add( ndl, dd );
  5037.                     }
  5038.                 });
  5039.                 disks = (list<string>)union( disks, ndl );
  5040.                 }
  5041.             else
  5042.                 {
  5043.                 disks = (list<string>)add( disks, d );
  5044.                 }
  5045.             });
  5046.             }
  5047.         });
  5048.         }
  5049.     });
  5050.     disks = sort( disks );
  5051.     y2milestone( "GetUsedEvmsDisks ret %1", disks );
  5052.     return( disks );
  5053.     };
  5054.  
  5055. global define boolean CheckEvmsNonEvms()
  5056.     ``{
  5057.     boolean ret = true;
  5058.     if( DoCheckEvmsNonEvms )
  5059.     {
  5060.     map<string,map> tg = GetTargetMap();
  5061.     list<string> evms = GetUsedEvmsDisks( tg );
  5062.     list<string> nonevms = GetUsedRealDisksNew( tg, true );
  5063.     evms = filter( string d, evms, ``(contains( nonevms, d )));
  5064.     y2milestone( "CheckEvmsNonEvms intersec %1", evms );
  5065.     ret = size(evms)==0;
  5066.     }
  5067.     y2milestone( "CheckEvmsNonEvms ret %1", ret );
  5068.     return( ret );
  5069.     };
  5070.  
  5071. global define boolean CheckEvmsLvm()
  5072.     ``{
  5073.     boolean ret = true;
  5074.     if( DoCheckEvmsLvm )
  5075.     {
  5076.     map<string,map> tg = GetTargetMap();
  5077.     list evms = GetUsedEvmsDisks( tg );
  5078.     list lvms = GetUsedLvmGroups( tg );
  5079.     ret = size(evms)==0 || size(lvms)==0;
  5080.     }
  5081.     y2milestone( "CheckEvmsLvm ret %1", ret );
  5082.     return( ret );
  5083.     };
  5084.  
  5085. global list<map> GetPrepBoot( map<string,map> tg )
  5086.     {
  5087.     list<map> ret = [];
  5088.     list cl = [ 0x06, 0x41 ];
  5089.     foreach( string s, map e, tg,
  5090.     ``{
  5091.     if( IsRealDisk( e ) && Partitions::PrepBoot() )
  5092.         ret = (list<map>)merge( ret, filter( map p, e["partitions"]:[],
  5093.                                   ``( size(p["mount"]:"")==0 &&
  5094.                           contains( cl, p["fsid"]:0 ) &&
  5095.                       !p["delete"]:false )));
  5096.     });
  5097.     y2milestone( "GetPrepBoot ret:%1", ret );
  5098.     return( ret );
  5099.     }
  5100.  
  5101. global define void FinishInstall()
  5102.     ``{
  5103.     map<string,map> tg = GetTargetMap();
  5104.     HandleModulesOnBoot( tg );
  5105.     list evms = GetUsedEvmsDisks( tg );
  5106.     y2milestone( "FinishInstall evms %1", evms );
  5107.     if( size(evms)>0 )
  5108.     {
  5109.     string cmd = "cd / && /sbin/insserv /etc/init.d/boot.evms";
  5110.     y2milestone( "FinishInstall cmd %1", cmd );
  5111.     map bo = (map)SCR::Execute (.target.bash_output, cmd );
  5112.     y2milestone( "FinishInstall bo %1", bo );
  5113.     }
  5114.     list<string> nonevms = GetUsedRealDisks( tg );
  5115.     nonevms = filter( string d, nonevms, ``(!contains( evms, d )));
  5116.     nonevms = maplist( string d, nonevms, ``(substring(d,5)));
  5117.     y2milestone( "FinishInstall nonevms %1", nonevms );
  5118.     nonevms = (list<string>)merge( nonevms, maplist( map p, GetPrepBoot(tg),
  5119.                    ``(substring(p["device"]:"",5))));
  5120.     y2milestone( "FinishInstall nonevms %1", nonevms );
  5121.     if( size(nonevms)>0 && SCR::Read( .target.size, "/etc/evms.conf" )>=0 )
  5122.     {
  5123.     map evmsconf = $[];
  5124.     AsciiFile::ReadFile( evmsconf, "/etc/evms.conf" );
  5125.     boolean found = false;
  5126.     integer i = 1;
  5127.     string regex1 = "^[ \t]*activate[ \t]*\\{";
  5128.     string regex2 = "^[ \t]*exclude[ \t]*=";
  5129.     string regex3 = "^[ \t]*\\}";
  5130.     while( i<=AsciiFile::NumLines(evmsconf) && !found )
  5131.         {
  5132.         found = regexpmatch( evmsconf["l",i,"line"]:"", regex1 );
  5133.         i = i+1;
  5134.         }
  5135.     found = false;
  5136.     boolean found2 = false;
  5137.     while( i<=AsciiFile::NumLines(evmsconf) && !found && !found2)
  5138.         {
  5139.         found = regexpmatch( evmsconf["l",i,"line"]:"", regex2 );
  5140.         found2 = regexpmatch( evmsconf["l",i,"line"]:"", regex3 );
  5141.         if( found )
  5142.         {
  5143.         string li = "\texclude = [ " + mergestring( nonevms, " " ) +
  5144.                     " ]";
  5145.         y2milestone( "FinishInstall li = %1", li );
  5146.         evmsconf["l",i,"line"] = li;
  5147.         evmsconf["l",i,"buildline"] = false;
  5148.         AsciiFile::RewriteFile( evmsconf, "/etc/evms.conf" );
  5149.         }
  5150.         i = i+1;
  5151.         }
  5152.     }
  5153.     y2milestone( "FinishInstall" );
  5154.     }
  5155.  
  5156. global define map GetEntryForMountpoint( string mp )
  5157.     ``{
  5158.     list<map> all_partitions = [];
  5159.     foreach( string dev, map disk, GetTargetMap(),
  5160.     ``{
  5161.     all_partitions = (list<map>)union( all_partitions,
  5162.                                        disk["partitions"]:[] );
  5163.     });
  5164.     map partition = find( map part, all_partitions, ``(part["mount"]:""==mp) );
  5165.     if( partition==nil || partition["mount"]:"" != mp )
  5166.         {
  5167.     partition = $[];
  5168.     }
  5169.     return partition;
  5170.     }
  5171.  
  5172. global define list GetRootInitrdModules()
  5173.     ``{
  5174.     map partition = GetEntryForMountpoint( "/" );
  5175.     y2milestone("GetRootInitrdModules root partition %1", partition );
  5176.  
  5177.     map<string,map> tg = GetTargetMap();
  5178.     map disk = $[];
  5179.     foreach( string k, map d, tg, 
  5180.     ``{
  5181.     if( size(disk)==0 && 
  5182.         find( map p, d["partitions"]:[], 
  5183.               ``(!p["delete"]:false &&
  5184.              p["device"]:""==partition["device"]:""))!=nil )
  5185.         disk = d;
  5186.     });
  5187.     y2milestone( "GetRootInitrdModules disk %1", 
  5188.                  haskey(disk,"partitions")?remove(disk,"partitions"):disk );
  5189.  
  5190.     list initrdmodules =
  5191.     FileSystems::GetNeededModules( partition["used_fs"]:`ext2 );
  5192.  
  5193.     if( partition["type"]:`unknown == `sw_raid )
  5194.     {
  5195.     string t = partition["raid_type"]:"";
  5196.     if (!contains (initrdmodules, t))
  5197.         {
  5198.         initrdmodules = add (initrdmodules, t);
  5199.         }
  5200.     }
  5201.     if( partition["type"]:`unknown == `lvm )
  5202.     {
  5203.     string vgname = substring( partition["device"]:"", 5 );
  5204.     vgname = substring( vgname, 0, findfirstof( vgname, "/" ));
  5205.     list<string> mod =
  5206.         (list<string>) maplist(map k, filter(map e, tg["/dev/md","partitions"]:[],
  5207.                          ``(e["used_by"]:""==vgname) ),
  5208.                    ``(k["raid_type"]:""));
  5209.     y2milestone( "GetRootInitrdModules mod %1", mod );
  5210.     foreach(string e, mod,
  5211.         ``{
  5212.         if( size(e)>0 && !contains( initrdmodules, e ) )
  5213.         {
  5214.         initrdmodules = add( initrdmodules, e );
  5215.         }
  5216.         });
  5217.     if( !contains( initrdmodules, "dm_mod" ) )
  5218.         {
  5219.         initrdmodules = add( initrdmodules, "dm_mod" );
  5220.         }
  5221.     }
  5222.     if( partition["type"]:`unknown == `evms )
  5223.     {
  5224.     string evmsco = partition["device"]:"";
  5225.     evmsco = substring( evmsco, 0, findlastof( evmsco, "/" ));
  5226.     y2milestone( "GetRootInitrdModules evmsco %1", evmsco );
  5227.     y2milestone( "GetRootInitrdModules evms %1", tg[evmsco]:$[] );
  5228.     list<string> md = filter( string s, tg[evmsco,"devices"]:[], ``(search(s,"/dev/md")==0));
  5229.     y2milestone( "GetRootInitrdModules mddev %1", md );
  5230.     list<string> mod =
  5231.         (list<string>) maplist(map k, filter(map e, tg["/dev/md","partitions"]:[],
  5232.                          ``(contains(md,e["device"]:""))),
  5233.                    ``(k["raid_type"]:""));
  5234.     y2milestone( "GetRootInitrdModules mod %1", mod );
  5235.     foreach(string e, mod,
  5236.         ``{
  5237.         if( size(e)>0 && !contains( initrdmodules, e ) )
  5238.         {
  5239.         initrdmodules = add( initrdmodules, e );
  5240.         }
  5241.         });
  5242.     if( !contains( initrdmodules, "dm_mod" ) )
  5243.         {
  5244.         initrdmodules = add( initrdmodules, "dm_mod" );
  5245.         }
  5246.     }
  5247.     if( size(disk["modules"]:[])>0 )
  5248.     {
  5249.     y2milestone( "adding disk modules %1", disk["modules"]:[] );
  5250.     foreach( string m, disk["modules"]:[],
  5251.         ``{
  5252.         if( !contains( initrdmodules, m ))
  5253.         {
  5254.         initrdmodules = add( initrdmodules, m );
  5255.         }
  5256.         });
  5257.     }
  5258.     if( size(disk["driver_module"]:"")>0 )
  5259.     {
  5260.     string m = disk["driver_module"]:"";
  5261.     y2milestone( "adding driver modules %1", m );
  5262.     if( !contains( initrdmodules, m ))
  5263.         {
  5264.         initrdmodules = add( initrdmodules, m );
  5265.         }
  5266.     }
  5267.     SCR::UnmountAgent (.proc.modules);
  5268.     map lmod = (map) SCR::Read(.proc.modules);
  5269.     y2milestone( "GetRootInitrdModules lmod:%1", lmod );
  5270.     if( size(lmod["edd"]:$[])>0 )
  5271.     initrdmodules = add( initrdmodules, "edd" );
  5272.     y2milestone( "GetRootInitrdModules ret %1", initrdmodules );
  5273.     return initrdmodules;
  5274.     };
  5275.  
  5276. /**
  5277.  * CheckForLvmRootFs
  5278.  *---------------------------------------------------------------------
  5279.  * check if the root filesystem is a lvm logical volume
  5280.  *
  5281.  **/
  5282. global define boolean CheckForLvmRootFs()
  5283.     ``{
  5284.     map part = GetEntryForMountpoint( "/" );
  5285.     y2milestone( "CheckForLvmRootFs root=%1", part );
  5286.     boolean ret = part["type"]:`primary==`lvm;
  5287.     y2milestone( "CheckForLvmRootFs ret=%1", ret );
  5288.     return ret;
  5289.     };
  5290.  
  5291.   /**
  5292.    * CheckForEvmsRootFs
  5293.    *---------------------------------------------------------------------
  5294.    * check if the root filesystem is a evms volume
  5295.    *
  5296.    **/
  5297. global define boolean CheckForEvmsRootFs()
  5298.     ``{
  5299.     map part = GetEntryForMountpoint( "/" );
  5300.     y2milestone( "CheckForEvmsRootFs root=%1", part );
  5301.     boolean ret = part["type"]:`primary==`evms;
  5302.     y2milestone( "CheckForEvmsRootFs ret=%1", ret );
  5303.     return ret;
  5304.     };
  5305.  
  5306.  
  5307.  
  5308.   /*---------------------------------------------------------------------
  5309.    * checkForMdRootFs
  5310.    *---------------------------------------------------------------------
  5311.    * check if the root filesystem is a md device
  5312.    *---------------------------------------------------------------------
  5313.    */
  5314. global define boolean CheckForMdRootFs()
  5315.     ``{
  5316.     map part = GetEntryForMountpoint( "/" );
  5317.     boolean ret = part["type"]:`primary==`sw_raid;
  5318.     y2milestone( "CheckForMdRootFs root=%1", part );
  5319.     y2milestone( "CheckForMdRootFs ret=%1", ret );
  5320.     return ret;
  5321.     };
  5322.  
  5323. global define void AdaptResize( string maindev, list region, integer schange )
  5324.     ``{
  5325.     map<string,map> tg = GetTargetMap();
  5326.     list<map> partitions = tg[maindev,"partitions"]:[];
  5327.     integer cylinder = region[0]:0 + region[1]:0;
  5328.     boolean found = false;
  5329.     integer index = -1;
  5330.     integer e_idx = -1;
  5331.     list<integer> idx_list = [];
  5332.     map part = (map) find(map p, partitions,
  5333.                           ``(p["region",0]:0 == cylinder && p["create"]:false));
  5334.     y2milestone( "AdaptResize %1 reg %2 change %3", maindev, region, schange );
  5335.     if( part != nil )
  5336.     {
  5337.     found = false;
  5338.     index = 0;
  5339.     foreach(map p, partitions,
  5340.         ``{
  5341.         if( p["region",0]:0 == cylinder && p["create"]:false )
  5342.         {
  5343.         found = true;
  5344.         }
  5345.         else if( !found )
  5346.         {
  5347.         index = index + 1;
  5348.         }
  5349.         });
  5350.     if( partitions[index,"type"]:`primary == `extended )
  5351.         {
  5352.         e_idx = index;
  5353.         found = false;
  5354.         index = 0;
  5355.         foreach(map p, partitions,
  5356.         ``{
  5357.         if( p["region",0]:0 == cylinder && p["create"]:false &&
  5358.             p["type"]:`primary != `extended )
  5359.             {
  5360.             found = true;
  5361.             part = p;
  5362.             }
  5363.         else if( !found )
  5364.             {
  5365.             index = index + 1;
  5366.             }
  5367.         });
  5368.         }
  5369.     cylinder = part["region",0]:0 + part["region",1]:0;
  5370.     y2milestone( "AdaptResize part:%1", part );
  5371.     y2milestone( "AdaptResize index:%1 e_idx:%2 cylinder:%3", index, e_idx,
  5372.                  cylinder );
  5373.     map pnew = (map) find( map p, partitions,
  5374.                            ``( p["region",0]:0 == cylinder &&
  5375.                    p["create"]:false ));
  5376.     y2milestone( "AdaptResize pnew:%1", pnew );
  5377.     while( pnew != nil &&
  5378.            (part["mount"]:"" == Partitions::BootMount() ||
  5379.             part["fsid"]:0==Partitions::fsid_swap ||
  5380.         part["region",1]:0 < (schange<0?(-1*schange):schange)) )
  5381.         {
  5382.         y2milestone( "AdaptResize pnew:%1", pnew );
  5383.         part = pnew;
  5384.         idx_list = add( idx_list, index );
  5385.         y2milestone( "AdaptResize index:%1 idx_list:%2", index, idx_list );
  5386.         found = false;
  5387.         index = 0;
  5388.         foreach(map p, partitions, ``{
  5389.             y2milestone( "found:%1 index:%2 p=%3", found, index, p );
  5390.         if( p["nr"]:0 == pnew["nr"]:0 )
  5391.             {
  5392.             found = true;
  5393.             }
  5394.         else if( !found )
  5395.             {
  5396.             index = index + 1;
  5397.             }
  5398.         });
  5399.         cylinder = part["region",0]:0 + part["region",1]:0;
  5400.         pnew = (map) find( map p, partitions,
  5401.                            ``( p["region",0]:0 == cylinder &&
  5402.                    p["create"]:false ));
  5403.         }
  5404.     y2milestone( "AdaptResize idx:%1 list:%2", index, idx_list );
  5405.  
  5406.     foreach(integer num, idx_list, ``{
  5407.         partitions[num,"region",0] = partitions[num,"region",0]:0 - schange;
  5408.         UpdatePartition( partitions[num,"device"]:"", partitions[num,"region",0]:0,
  5409.                  partitions[num,"region",1]:1 );
  5410.         });
  5411.     partitions[index,"region",0] = partitions[index,"region",0]:0 - schange;
  5412.     partitions[index,"region",1] = partitions[index,"region",1]:0 + schange;
  5413.     if( partitions[index,"region",1]:0 <= 0 )
  5414.         {
  5415.         partitions[index,"region",1] = 1;
  5416.         }
  5417.     y2milestone( "AdaptResize increase p:%1", partitions[index]:$[] );
  5418.     UpdatePartition( partitions[index,"device"]:"", partitions[index,"region",0]:0,
  5419.                      partitions[index,"region",1]:1 );
  5420.     if( e_idx>=0 )
  5421.         {
  5422.         partitions[e_idx,"region",0] = partitions[e_idx,"region",0]:0 - schange;
  5423.         partitions[e_idx,"region",1] = partitions[e_idx,"region",1]:0 + schange;
  5424.         if( partitions[e_idx,"region",1]:0 <= 0 )
  5425.         {
  5426.         partitions[e_idx,"region",1] = 1;
  5427.         }
  5428.         UpdatePartition( partitions[e_idx,"device"]:"", partitions[e_idx,"region",0]:0,
  5429.                  partitions[e_idx,"region",1]:1 );
  5430.         }
  5431.     }
  5432.     else
  5433.     {
  5434.     y2error( "AdaptResize this should not happen %1", partitions );
  5435.     }
  5436.     y2milestone( "AdaptResize partitions:%1", partitions );
  5437.     y2milestone( "AdaptResize maindev:%1 region:%2 change:%3", maindev,
  5438.                  region, schange );
  5439.     }
  5440.  
  5441.  
  5442. global define integer NumLoopDevices()
  5443.     {
  5444.     map bo = (map)WFM::Execute (.local.bash_output, "losetup -a" );
  5445.     list<string> sl = splitstring( bo["stdout"]:"", "\n" );
  5446.     sl = filter( string s, sl, ``(search( s, "/dev/loop" )==0 ));
  5447.     sl = maplist( string s, sl, ``(substring( s, 0, search( s, ":" ))));
  5448.     sl = maplist( string s, sl, ``(substring( s, 9 )));
  5449.     list<integer> il = sort( maplist( string s, sl, ``(tointeger(s))));
  5450.     integer ret = il[size(sl)-1]:-1 + 1;
  5451.     y2milestone( "NumLoopDevices ret:%1", ret );
  5452.     return( ret );
  5453.     }
  5454.  
  5455.  
  5456. //-----------------------------------------------------
  5457. // convert partitions to fstab entries
  5458. // return map (might be empty)
  5459. global define map onepartition2fstab (map part, integer& other_nr)
  5460.     ``{
  5461.     y2milestone( "onepartition2fstab part=%1", part );
  5462.     if (part["delete"]:false ||
  5463.     part["type"]:`unknown == `extended ||
  5464.     (contains( [ `lvm, `sw_raid, `evms ], part["type"]:`unknown ) &&
  5465.      size(part["mount"]:"")==0) ||
  5466.     (part["enc_type"]:`none!=`none && !part["noauto"]:false) ||
  5467.     part["used_by_type"]:`UB_NONE != `UB_NONE ||
  5468.     (contains( [ Partitions::fsid_prep_chrp_boot, Partitions::fsid_lvm,
  5469.                  Partitions::fsid_raid ], part["fsid"]:0 ) &&
  5470.      size(part["mount"]:"")==0))
  5471.     {
  5472.     return $[];
  5473.     }
  5474.  
  5475.     string spec = part["device"]:"";
  5476.     if( part["mountby"]:`device == `label && size(part["label"]:"")>0 )
  5477.     {
  5478.     spec = sformat("LABEL=%1", part["label"]:"" );
  5479.     }
  5480.     else if( part["mountby"]:`device == `uuid && size(part["uuid"]:"")>0 )
  5481.     {
  5482.     spec = sformat("UUID=%1", part["uuid"]:"" );
  5483.     }
  5484.     y2debug( "onepartition2fstab spec=%1", spec );
  5485.     string  mount_point = part["mount"]:"";
  5486.     integer fsid = part["fsid"]:0;
  5487.  
  5488.     symbol  used_fs = part["used_fs"]:`ext2;
  5489.     boolean format  = part["format"]:false;
  5490.  
  5491.     string  vfstype = "unknown";    // keep "unknown", used again below
  5492.     integer freq    = 0;
  5493.     integer passno  = 0;
  5494.     string  mntops  = part["fstopt"]:"";
  5495.  
  5496.     if( mount_point == "swap" )
  5497.     {
  5498.     vfstype = "swap";
  5499.     if( size(mntops) == 0 )
  5500.         {
  5501.         mntops = FileSystems::GetFstabDefaultMntops( "swap" );
  5502.         }
  5503.     passno = 0;
  5504.     }
  5505.     else if( fsid==Partitions::fsid_native || fsid==Partitions::fsid_lvm ||
  5506.              (part["type"]:`unknown == `evms &&
  5507.           part["detected_fs"]:`none!=`unknown) )
  5508.     {
  5509.     vfstype = FileSystems::GetMountString( used_fs,
  5510.                                            (format ? "ext2" : "auto"));
  5511.  
  5512.     freq = 1;
  5513.     if( mount_point == "/" )
  5514.         {
  5515.         passno = 1;
  5516.         }
  5517.     else if( mount_point != "" )
  5518.         {
  5519.         passno = 2;
  5520.         }
  5521.     else if( Stage::initial () && !Arch::s390 () )
  5522.         {
  5523.         mount_point = "/data" + other_nr;
  5524.         // Don't mount and fsck this filesystem during boot, its
  5525.         // state is unknown.
  5526.         mntops = "noauto,user";
  5527.         vfstype = "auto";
  5528.         freq = 0;
  5529.         passno = 0;
  5530.         other_nr = other_nr + 1;
  5531.         y2milestone( "TT add MountPoint %1", mount_point );
  5532.         }
  5533.     }
  5534.     else if( (Arch::i386()||Arch::ia64()||Arch::x86_64()) &&
  5535.              size(mount_point)>0 &&
  5536.              (used_fs==`vfat || used_fs==`ntfs) &&
  5537.              (contains(union(union(Partitions::fsid_dostypes,
  5538.                    Partitions::fsid_ntfstypes),
  5539.                  Partitions::fsid_wintypes), fsid ) ||
  5540.           fsid==Partitions::fsid_gpt_boot))
  5541.     {
  5542.     freq = 0;
  5543.     passno = 0;
  5544.     string lower_point = tolower( mount_point );
  5545.     if( lower_point != "" && mount_point != lower_point)
  5546.         {
  5547.         if( Installation::scr_destdir != "/" )
  5548.         {
  5549.         lower_point = Installation::scr_destdir + lower_point;
  5550.         }
  5551.         y2milestone( "symlink %1 -> %2",
  5552.                      substring(mount_point,(findlastof(mount_point,"/")+1)),
  5553.              lower_point );
  5554.         SCR::Execute(.target.symlink,
  5555.                      substring(mount_point,(findlastof(mount_point,"/")+1)),
  5556.                      lower_point);
  5557.         }
  5558.     vfstype = FileSystems::GetMountString( used_fs, "auto" );
  5559.     }
  5560.     else if( (Arch::sparc () || Arch::alpha ()) &&
  5561.          contains (Partitions::fsid_skipped, fsid))
  5562.     {
  5563.     return $[];        // skip "whole disk" partition
  5564.     }
  5565.     else
  5566.     {
  5567.     return $[];            // unknown type
  5568.     }
  5569.     if( part["detected_fs"]:`unknown == `unknown || part["noauto"]:false )
  5570.     {
  5571.     passno = 0;
  5572.     }
  5573.  
  5574.     map ret = $[ "spec":spec,
  5575.                  "mount":mount_point,
  5576.          "vfstype":vfstype,
  5577.                  "mntops":mntops,
  5578.          "freq":freq,
  5579.          "device":part["device"]:"",
  5580.          "passno":passno ];
  5581.  
  5582.     if( size(ret["mntops"]:"")==0 )
  5583.     {
  5584.     ret["mntops"] = "defaults";
  5585.     }
  5586.  
  5587.     y2milestone( "onepartition2fstab ret=%1", ret );
  5588.     return( ret );
  5589.     };
  5590.  
  5591. global integer KmgtStrToByte( string input )
  5592.     ``{
  5593.     integer number = 0;
  5594.     integer pos = findfirstnotof( input, " +" );
  5595.  
  5596.     if( pos != nil && pos>0 )
  5597.     {
  5598.     input = substring( input, pos );
  5599.     }
  5600.  
  5601.     if( size(filterchars(input, "0123456789kKmMgGtTbBoO .")) != size(input))
  5602.        {
  5603.        return(0);
  5604.        }
  5605.  
  5606.     input = filterchars(input, "0123456789kKmMgGtTbBoO.");
  5607.  
  5608.     if( findfirstnotof( input, "0123456789.") != nil  )
  5609.         {
  5610.     // check whether the last char is in "kKmM" or "bB"
  5611.     string last_char = substring( input, size(input)-1, 1);
  5612.  
  5613.     if( last_char == "b" || last_char == "B" ||
  5614.         last_char == "o" || last_char == "O" )
  5615.         {
  5616.         input = substring( input, 0, size(input)-1);
  5617.         // check whether the last char is in "kKmM"
  5618.         last_char = substring( input, size(input)-1, 1);
  5619.         }
  5620.  
  5621.         string number_str = substring(input, 0, size(input)-1);
  5622.  
  5623.     if( findfirstnotof( number_str, "0123456789.") == nil )
  5624.         {
  5625.         if( last_char == "k" || last_char == "K" )
  5626.             {
  5627.         number = tointeger(tofloat( number_str ) * 1024.0) ;
  5628.         }
  5629.         else if ( last_char == "m" || last_char == "M" )
  5630.         {
  5631.         number = tointeger(tofloat( number_str ) * 1024.0 * 1024.0);
  5632.             }
  5633.         else if ( last_char == "g" || last_char == "G" )
  5634.         {
  5635.         number = tointeger(tofloat( number_str ) * 
  5636.                    1024.0 * 1024.0 * 1024.0);
  5637.         }
  5638.         else if ( last_char == "t" || last_char == "T" )
  5639.             {
  5640.         number = tointeger(tofloat( number_str ) * 
  5641.                    1024.0 * 1024.0 * 1024.0 * 1024.0);
  5642.         }
  5643.         else
  5644.         {
  5645.         number = 0;
  5646.             }
  5647.         }
  5648.         else
  5649.         {
  5650.         number = 0;
  5651.         }
  5652.         }
  5653.     else
  5654.         {
  5655.         number = tointeger( input );
  5656.         }
  5657.     return( number );
  5658.     };
  5659.  
  5660. global boolean InstallOES()
  5661.     {
  5662.     boolean ret = false;
  5663.     y2milestone( "InstallOES ret:%1", ret );
  5664.     return( ret );
  5665.     }
  5666.  
  5667. global boolean ProposalHome()
  5668.     {
  5669.     return( proposal_home );
  5670.     }
  5671.  
  5672. global void SetProposalHome(boolean val)
  5673.     {
  5674.     proposal_home = val;
  5675.     y2milestone( "SetProposalHome val:%1", proposal_home );
  5676.     }
  5677.  
  5678. global void SetProposalEvms(boolean val)
  5679.     {
  5680.     proposal_evms = val;
  5681.     if( val )
  5682.     proposal_lvm = false;
  5683.     y2milestone( "SetProposalEvms val:%1 lvm:%2 evms:%3", val,
  5684.                  proposal_lvm, proposal_evms );
  5685.     }
  5686.  
  5687. global void SetProposalLvm(boolean val)
  5688.     {
  5689.     proposal_lvm = val;
  5690.     if( val )
  5691.     proposal_evms = false;
  5692.     y2milestone( "SetProposalLvm val:%1 lvm:%2 evms:%3", val,
  5693.                  proposal_lvm, proposal_evms );
  5694.     }
  5695.  
  5696. global boolean ProposalEvms()
  5697.     {
  5698.     return( proposal_evms );
  5699.     }
  5700.  
  5701. global boolean ProposalLvm()
  5702.     {
  5703.     return( proposal_lvm );
  5704.     }
  5705.  
  5706. global void SetProposalDefault()
  5707.     {
  5708.     SetProposalHome( cfg_xml["home"]:false );
  5709.     if( cfg_xml["prop_evms"]:false )
  5710.     {
  5711.     SetProposalEvms(true);
  5712.     }
  5713.     else if( cfg_xml["prop_lvm"]:false )
  5714.     {
  5715.     SetProposalLvm(true);
  5716.     }
  5717.     else
  5718.     {
  5719.     SetProposalLvm(false);
  5720.     SetProposalEvms(false);
  5721.     }
  5722.     y2milestone( "SetProposalDefault lvm:%1 evms:%2 home:%3", 
  5723.                  proposal_lvm, proposal_evms, proposal_home );
  5724.     }
  5725.  
  5726. global map GetControlCfg()
  5727.     {
  5728.     if( size(cfg_xml)==0 )
  5729.     {
  5730.     boolean bt = ProductFeatures::GetBooleanFeature( "partitioning",
  5731.                              "try_separate_home" );
  5732.     cfg_xml["home"] = bt?true:false;
  5733.     cfg_xml["root_percent"] = 
  5734.         tointeger(ProductFeatures::GetStringFeature( "partitioning",
  5735.                              "root_space_percent"));
  5736.     if( cfg_xml["root_percent"]:0 == nil || cfg_xml["root_percent"]:0 <= 0 )
  5737.         cfg_xml["root_percent"] = 40;
  5738.     string tmp = ProductFeatures::GetStringFeature( "partitioning",
  5739.                             "limit_try_home");
  5740.     cfg_xml["home_limit"] = KmgtStrToByte(tmp) / (1024*1024);
  5741.     if( cfg_xml["home_limit"]:0 <= 0 )
  5742.         cfg_xml["home_limit"] = 5*1024;
  5743.     tmp = ProductFeatures::GetStringFeature( "partitioning",
  5744.                          "root_base_size");
  5745.     cfg_xml["root_base"] = KmgtStrToByte(tmp) / (1024*1024);
  5746.     if( cfg_xml["root_base"]:0 <= 0 )
  5747.         cfg_xml["root_base"] = 3*1024;
  5748.     tmp = ProductFeatures::GetStringFeature( "partitioning",
  5749.                          "root_max_size");
  5750.     cfg_xml["root_max"] = KmgtStrToByte(tmp) / (1024*1024);
  5751.     if( cfg_xml["root_max"]:0 <= 0 )
  5752.         cfg_xml["root_max"] = 10*1024;
  5753.     tmp = ProductFeatures::GetStringFeature( "partitioning",
  5754.                          "vm_desired_size");
  5755.     cfg_xml["vm_want"] = KmgtStrToByte(tmp) / (1024*1024);
  5756.     if( cfg_xml["vm_want"]:0 <= 0 )
  5757.         cfg_xml["vm_want"] = 15*1024;
  5758.     tmp = ProductFeatures::GetStringFeature( "partitioning",
  5759.                          "vm_home_max_size");
  5760.     cfg_xml["home_max"] = KmgtStrToByte(tmp) / (1024*1024);
  5761.     if( cfg_xml["home_max"]:0 <= 0 )
  5762.         cfg_xml["home_max"] = 25*1024;
  5763.     bt = ProductFeatures::GetBooleanFeature( "partitioning",
  5764.                          "proposal_evms" );
  5765.     cfg_xml["prop_evms"] = bt?true:false;
  5766.     bt = ProductFeatures::GetBooleanFeature( "partitioning",
  5767.                          "proposal_lvm" );
  5768.     cfg_xml["prop_lvm"] = bt?true:false;
  5769.     bt = ProductFeatures::GetBooleanFeature( "partitioning",
  5770.                          "evms_config" );
  5771.     cfg_xml["evms_config"] = bt?true:false;
  5772.     bt = ProductFeatures::GetBooleanFeature( "partitioning",
  5773.                          "evms_boot" );
  5774.     cfg_xml["evms_boot"] = bt?true:false;
  5775.     SetProposalDefault();
  5776.     y2milestone( "GetControlCfg cfg_xml %1", cfg_xml );
  5777.     }
  5778.     return( cfg_xml );
  5779.     }
  5780.  
  5781. global boolean BootEvms()
  5782.     {
  5783.     map cfg = GetControlCfg();
  5784.     boolean ret = cfg["evms_boot"]:false;
  5785.     y2milestone( "BootEvms ret %1", ret );
  5786.     return( ret );
  5787.     }
  5788.  
  5789. global string ProposalVM()
  5790.     {
  5791.     string ret = "";
  5792.     map xml = GetControlCfg();
  5793.     if( proposal_evms || proposal_lvm )
  5794.     {
  5795.     ret = "system";
  5796.     }
  5797.     y2milestone( "ProposalVM lvm:%1 evms:%2 ret:%3", 
  5798.                  proposal_lvm, proposal_evms, ret );
  5799.     return( ret );
  5800.     }
  5801.  
  5802.  
  5803. global void AddHwPackage( string name )
  5804.     {
  5805.     y2milestone( "AddHwPackage name %1 list:%2", name, hw_packages );
  5806.     if( find( string s, hw_packages, ``(s==name)) == nil )
  5807.     hw_packages = add( hw_packages, name );
  5808.     y2milestone( "AddHwPackage list:%1", hw_packages );
  5809.     }
  5810.  
  5811. global void SwitchUiAutomounter( boolean on )
  5812.     {
  5813.     y2milestone( "SwitchUiAutomounter on:%1", on );
  5814.     string cmd = "hal-set-property " +
  5815.           "--udi /org/freedesktop/Hal/devices/computer " +
  5816.           "--key storage.disable_volume_handling --bool ";
  5817.     cmd = cmd + (on?"true":"false" );
  5818.     y2milestone( "SwitchUiAutomounter cmd %1", cmd );
  5819.     SCR::Execute( .target.bash, cmd );
  5820.     y2milestone( "SwitchUiAutomounter exit" );
  5821.     }
  5822.  
  5823. global void DumpObjectList()
  5824.     {
  5825.     if( sint == nil )
  5826.     InitLibstorage();
  5827.     LibStorage::StorageInterface::dumpObjectList(sint);
  5828.     }
  5829.  
  5830. global define list<string> NoProposeDisks()
  5831.     {
  5832.     if( no_propose_disks == nil )
  5833.     {
  5834.     no_propose_disks = [];
  5835.     if( Stage::initial() && SCR::Read( .target.size, "/etc/install.inf" )>0 )
  5836.         {
  5837.         string inst = (string) SCR::Read( .etc.install_inf.Partition );
  5838.         y2milestone( "NoProposeDisks .etc.install_inf.Partition \"%1\"", 
  5839.                      inst );
  5840.         if( inst!=nil && size(inst)>0 )
  5841.         {
  5842.         if( search( inst, "/dev/" )!=0 )
  5843.             inst = "/dev/" + inst;
  5844.         map d = GetDiskPartition( inst );
  5845.         y2milestone( "NoProposeDisks inst:%1 disk:%2", inst, d );
  5846.         if( size(d["disk"]:"")>0 )
  5847.             no_propose_disks = add( no_propose_disks, d["disk"]:"" );
  5848.         }
  5849.         inst = (string) SCR::Read( .etc.install_inf.Cdrom );
  5850.         y2milestone( "NoProposeDisks .etc.install_inf.Cdrom \"%1\"", inst );
  5851.         if( inst!=nil && size(inst)>0 )
  5852.         {
  5853.         if( search( inst, "/dev/" )!=0 )
  5854.             inst = "/dev/" + inst;
  5855.         map d = GetDiskPartition( inst );
  5856.         y2milestone( "NoProposeDisks inst:%1 disk:%2", inst, d );
  5857.         if( size(d["disk"]:"")>0 )
  5858.             no_propose_disks = add( no_propose_disks, d["disk"]:"" );
  5859.         }
  5860.         }
  5861.     if( Stage::initial() )
  5862.         {
  5863.         map ret = (map)SCR::Execute( .target.bash_output, "echo $YAST2_STORAGE_NO_PROPOSE_DISKS" );
  5864.         y2milestone( "NoProposeDisks ret \"%1\"", ret["stdout"]:"" );
  5865.         list ls = filter( string e, splitstring( ret["stdout"]:"", " \t\n" ), ``(size(e)>0) );
  5866.         no_propose_disks = (list<string>)merge( no_propose_disks, ls );
  5867.         }
  5868.     y2milestone( "NoProposeDisks \"%1\"", no_propose_disks );
  5869.     }
  5870.     return( no_propose_disks );
  5871.     }
  5872.  
  5873. boolean expert_detail = nil;
  5874. path ed_path = .sysconfig.storage.EXPERT_DETAIL;
  5875.  
  5876. list FindExpertLine( map file )
  5877.     {
  5878.     list ret = [];
  5879.     list<list> t = maplist( integer k, map e, file["l"]:$[], 
  5880.                             ``([k, e["line"]:""]));
  5881.     t = filter( list e, t, ``(search(e[1]:"","EXPERT_DETAIL")==0));
  5882.     y2milestone( "FindExpertLine t:%1", t );
  5883.     ret = t[0]:[];
  5884.     y2milestone( "FindExpertLine ret:%1", ret );
  5885.     return( ret );
  5886.     }
  5887.  
  5888. global boolean GetExpertDetail()
  5889.     {
  5890.     if( expert_detail==nil )
  5891.     {
  5892.     map file = $[];
  5893.     AsciiFile::ReadFile( file, "/etc/sysconfig/storage" );
  5894.     y2milestone( "GetExpertDetail file:%1", file );
  5895.     list l = FindExpertLine( file );
  5896.     y2milestone( "GetExpertDetail l:%1", l );
  5897.     l = filter( string s, splitstring( l[1]:"", "= " ), ``(size(s)>0));
  5898.     y2milestone( "GetExpertDetail l:%1", l );
  5899.     if( tointeger(l[1]:"0")==0 )
  5900.         expert_detail=false;
  5901.     else
  5902.         expert_detail=true;
  5903.     }
  5904.     y2milestone( "GetExpertDetail ret:%1", expert_detail );
  5905.     return( expert_detail );
  5906.     }
  5907.  
  5908. global void SetExpertDetail( boolean val )
  5909.     {
  5910.     y2milestone( "SetExpertDetail val:%1", val );
  5911.     expert_detail = val;
  5912.     }
  5913.  
  5914. global boolean SaveExpertDetail()
  5915.     {
  5916.     y2milestone( "SaveExpertDetail val:%1", expert_detail );
  5917.     if( expert_detail!=nil )
  5918.     {
  5919.     map file = $[];
  5920.     AsciiFile::ReadFile( file, "/etc/sysconfig/storage" );
  5921.     list l = FindExpertLine( file );
  5922.     string e = "EXPERT_DETAIL=" + (expert_detail?"1":"0");
  5923.     integer lineno = l[0]:(size(file["l"]:$[]) + 1);
  5924.     if( size(l)==0 )
  5925.         file["l",lineno] = $[];
  5926.     file["l",lineno,"line"] = e;
  5927.     file["l",lineno,"changed"] = true;
  5928.     AsciiFile::RewriteFile( file, "/etc/sysconfig/storage" );
  5929.     }
  5930.     }
  5931.  
  5932. }
  5933.