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 / include / partitioning / custom_part_lib.ycp < prev    next >
Text File  |  2006-11-29  |  30KB  |  1,040 lines

  1. /*************************************************************
  2.  *
  3.  *     YaST2      SuSE Labs                        -o)
  4.  *     --------------------                        /\\
  5.  *                                                _\_v
  6.  *           www.suse.de / www.suse.com
  7.  * ----------------------------------------------------------
  8.  *
  9.  * Author:        Johannes Buchhold <jbuch@suse.de>
  10.  *
  11.  * Description:   lib
  12.  *
  13.  *
  14.  *************************************************************
  15.  *
  16.  $Id: custom_part_lib.ycp 33040 2006-09-21 17:13:41Z fehr $
  17.  *
  18. */
  19.  
  20. {
  21.   textdomain "storage";
  22.   import "Mode";
  23.   import "Arch";
  24.   import "Installation";
  25.   import "Partitions";
  26.   import "Product";
  27.   import "FileSystems";
  28.  
  29.   #include "partitioning/partition_defines.ycp";
  30.  
  31.   /**
  32.    * Find and read fstab by installation. Scan existing partitions.
  33.    * @parm targetMap all targets
  34.    * @parm search_point mount point where partitions can be mounted
  35.    * @return list list with fstab data found
  36.    */
  37. define list<list> findExistingFstab( map<string,map> targetMap, string search_point )
  38.     ``{
  39.     /////////////////////////////////////////////////////////////////
  40.     // foreach partition on each target
  41.     list<list>    fstab = [];
  42.     list    skip_fs = [ `unknown, `swap, `vfat, `ntfs ];
  43.  
  44.     foreach( string dev, map disk, targetMap,
  45.     ``{
  46.     foreach( map part,
  47.              filter( map p, disk["partitions"]:[],
  48.                 ``(!contains( skip_fs, p["detected_fs"]:`unknown) )),
  49.         ``{
  50.         /////////////////////////////////////////////////////
  51.         // try to mount
  52.         boolean mount_success = Storage::Mount( part["device"]:"",
  53.                                                 search_point );
  54.  
  55.         if( mount_success &&
  56.         SCR::Read(.target.size, search_point+"/etc/fstab") > 0 )
  57.         {
  58.         list tmp = Storage::ReadFstab( search_point+"/etc" );
  59.         y2milestone( "findExistingFstab fstab %1", tmp );
  60.         if( size(tmp)>0 )
  61.             {
  62.             fstab = add( fstab, tmp );
  63.             }
  64.         }
  65.  
  66.         /////////////////////////////////////////////////////
  67.         // unmount
  68.         if( mount_success )
  69.         Storage::Umount( part["device"]:"" );
  70.         });
  71.     });
  72.     y2milestone( "findExistingFstab count_fstab_found %1", size(fstab) );
  73.     y2milestone( "findExistingFstab fstab %1", fstab );
  74.     return fstab;
  75.     };
  76.  
  77.  
  78. /**
  79.   * Scan and Read and return fstab.
  80.   * @parm targetMap all targets
  81.   * @parm file_systems filesystem map
  82.   * @return list list with fstab
  83.   */
  84. define list<list> scanAndReadExistingFstab( map<string,map> targetMap )
  85.     ``{
  86.     string search_point = "/mnt";
  87.  
  88.     /////////////////////////////////////////////////////////////////
  89.     // make search dir
  90.  
  91.     if( SCR::Execute(.target.bash, "/usr/bin/test -d " + search_point ) != 0)
  92.     {
  93.     SCR::Execute(.target.mkdir, search_point );
  94.     }
  95.  
  96.     list<list> fstab = findExistingFstab( targetMap, search_point );
  97.  
  98.     return fstab;
  99.     };
  100.  
  101.  
  102.  
  103.  
  104.     /**
  105.      * Only for check in installed system.
  106.      * Please do not use this define by installation.
  107.      * @parm part1 partition 1
  108.      * @parm part2 partition 2
  109.      * @return boolean
  110.      */
  111. define boolean arePartitionsEqual( map part1, map part2 )
  112.     ``{
  113.     if( part1["create"]:false )
  114.     return true;
  115.  
  116.     // -> not all keys
  117.     if( part1["nr"]:0            == part2["nr"]:0 &&
  118.     part1["fsid"]:0            == part2["fsid"]:0 &&
  119.     part1["region"]:[]            == part2["region"]:[] &&
  120.     part1["create"]:false      == part2["create"]:false &&
  121.     part1["format"]:false      == part2["format"]:false &&
  122.     part1["used_fs"]:`unknown  == part2["used_fs"]:`unknown &&
  123.     part1["enc_type"]:`none    == part2["enc_type"]:`none &&
  124.     part1["fstab_mnt"]:`device == part2["fstab_mnt"]:`device &&
  125.     part1["label"]:""          == part2["label"]:"" &&
  126.     part1["mount"]:""          == part2["mount"]:"" )
  127.     {
  128.     return true;
  129.     }
  130.     return false;
  131.     }
  132.  
  133.   /**
  134.    * Check lvm mount points
  135.    * @param mount mount point
  136.    * @return boolean
  137.    */
  138. define boolean check_lvm_mount_points( string mount )
  139.     ``{
  140.     list not_allowed_lvm_mount_points  = [ Partitions::BootMount() ];
  141.     y2milestone( " check lvm mount");
  142.     if( contains( not_allowed_lvm_mount_points, mount ))
  143.         {
  144.         // error popup text
  145.     Popup::Error(sformat(_("You cannot use the mount point \"%1\" for LVM.\n"), Partitions::BootMount()));
  146.  
  147.         return false;
  148.     }
  149.     return true;
  150.     };
  151.  
  152.  
  153.   /**
  154.    * Check raid mount points
  155.    * @param mount mount point
  156.    * @return boolean
  157.    **/
  158. define boolean check_raid_mount_points( string mount )
  159.     ``{
  160.     list not_allowed_raid_mount_points  = [ ];
  161.     if( Arch::ppc () || Arch::s390 () || Arch::ia64 () || Arch::sparc () )
  162.         {
  163.         not_allowed_raid_mount_points =
  164.         add( not_allowed_raid_mount_points, Partitions::BootMount() );
  165.         }
  166.     y2milestone( " check raid mount");
  167.     if( contains( not_allowed_raid_mount_points, mount ))
  168.     {
  169.            // error popup text
  170.         Popup::Error(sformat(_("You cannot use the mount point %1 for RAID."), Partitions::BootMount()));
  171.  
  172.         return false;
  173.     }
  174.     return true;
  175.     };
  176.  
  177.  
  178.  
  179.   /**
  180.    * Check if the noauto option is permitted for this mount point.
  181.    * @param mount mount point
  182.    * @return boolean
  183.    **/
  184. define boolean check_noauto_mount( string mount )
  185.     ``{
  186.     boolean ret = true;
  187.     if( FileSystems::IsSystemMp( mount, true ) )
  188.     {
  189.         // error popup text
  190.     ret = Popup::YesNo(
  191. _("You have selected not to mount automatically at start-up a file system
  192. that may contain files that the system needs to work properly.
  193.  
  194. This might lead to trouble.
  195.  
  196. Really do this?
  197. "));
  198.     y2milestone( "ret %1", ret );
  199.     }
  200.     return ret;
  201.     };
  202.  
  203.   /**
  204.    * Check crypted mount points and return true if the mount point is ok.
  205.    * @param mount mount point
  206.    * @param crypt_fs boolean
  207.    * @return boolean
  208.    **/
  209. define boolean check_crypt_fs_mount_points( string mount, boolean crypt_fs )
  210.     ``{
  211.     if( crypt_fs &&
  212.         (FileSystems::IsCryptMp( mount, false ) || mount=="swap" ))
  213.     {
  214.         // error popup text
  215.     Popup::Error(
  216. _("You have assigned an encrypted file system to a partition
  217. with one of the following mount points: \"/\", \"/usr\", \"/boot\",
  218. \"swap\".  This is not possible. Change the mount point or use a
  219. nonloopbacked file system.
  220. "));
  221.         return false;
  222.     }
  223.     return true;
  224.     };
  225.  
  226.  
  227.     /**
  228.      * Check all label and return true if the label is unique.
  229.      * @param targetMap the TargetMap
  230.      * @param part      partition to check
  231.      * @return boolean
  232.      **/
  233. define boolean check_unique_label( map<string,map> targetMap, map part )
  234.     ``{
  235.     boolean unique = true;
  236.  
  237.     // check if the label is already in use
  238.     foreach( string disk, map diskinfo, targetMap, ``{
  239.     foreach( map p, diskinfo["partitions"]:[], ``{
  240.         if ( p["device"]:"" != part["device"]:"" )
  241.         {
  242.         // all valid partitions
  243.         if ( p["label"]:"" == part["label"]:"" ) unique = false;
  244.         }
  245.         });
  246.     });
  247.     return( unique );
  248.     };
  249.  
  250. define boolean CheckFstabOptions( map part )
  251.     ``{
  252.     boolean ret = true;
  253.     if( FileSystems::IsSystemMp( part["mount"]:"", true ) &&
  254.         FileSystems::HasFstabOption( part, "user", false ) )
  255.     {
  256.         // error popup text
  257.     ret = Popup::YesNo(
  258. _("You have set the option to be mountable by users for a file system
  259. that may contain files that need to be executable.
  260.  
  261. This usually causes problems.
  262.  
  263. Really do this?
  264. "));
  265.     y2milestone( "system mp user ret %1", ret );
  266.     }
  267.     if( ret && part["noauto"]:false )
  268.     {
  269.     ret = check_noauto_mount( part["mount"]:"" ) && ret;
  270.     }
  271.     y2milestone( "CheckFstabOptions ret %1 part %2", ret, part );
  272.     return( ret );
  273.     }
  274.  
  275.     /**
  276.      * Check all mount points and return true if the mount point is ok.
  277.      * @param targetMap the TargetMap
  278.      * @param mount mount point
  279.      * @return boolean
  280.      **/
  281. define boolean check_mount_point( map<string,map> targetMap, string dev,
  282.                                   map part )
  283.     ``{
  284.     string mount = part["mount"]:"";
  285.     symbol used_fs = part["used_fs"]:`unknown;
  286.  
  287.     boolean allowed = true;
  288.     list not_allowed_system_mount_points  =
  289.     [ "/proc", "/dev", "/mnt", "/var/adm/mnt", "/lost+found", "/lib",
  290.       "/bin", "/etc", "/sbin" ];
  291.  
  292.     if ( mount != "" && mount != "swap"  )
  293.     {
  294.     // check if the mount point is already in use
  295.     foreach( string disk, map diskinfo, targetMap, ``{
  296.         foreach( map part, diskinfo["partitions"]:[], ``{
  297.         if( part["device"]:"" != dev )
  298.             {
  299.             // all valid partitions
  300.             if ( part["mount"]:"" == mount ) allowed = false;
  301.             }
  302.         });
  303.         });
  304.  
  305.     if( allowed == false )
  306.         {
  307.         // error popup text
  308.         Popup::Error(_("This mount point is already in use. Select a different one."));
  309.         }
  310.     // check if a dos filesystem is used for system purposes
  311.     else if( used_fs == `vfat &&
  312.          (mount == "/" || mount == "/usr" || mount == "/opt" ||
  313.           mount == "/var" || mount == "/home"))
  314.         {
  315.         allowed = false;
  316.         // error popup text
  317.         Popup::Error(_("FAT filesystem used for system mount point (/, /usr, /opt, /var, /home).\nThis is not possible."));
  318.         }
  319.     // check if the mount countains chars making trouble
  320.     else if( findfirstof( mount, " `'┤!\"%#" ) != nil )
  321.         {
  322.         allowed = false;
  323.         // error popup text
  324.         Popup::Error(_("Invalid character in mount point. Dont use \"`'!\"%#\" in a mount point."));
  325.         }
  326.  
  327.     // check if the mount point is a system mount point
  328.     else if ( contains( not_allowed_system_mount_points , mount) )
  329.         {
  330.         allowed = false;
  331.         // error popup text
  332.         Popup::Error(_("You cannot use any of the following mount points:
  333. /proc, /dev, /lib, /bin, /etc, /sbin, /mnt, /var/adm/mnt, /lost+found
  334. "));
  335.         }
  336.     else if ( substring( mount, 0, 1 ) != "/"  )
  337.         {
  338.         allowed = false;
  339.         // error popup text
  340.         Popup::Error(_("Your mount point must start with a \"/\" "));
  341.         }
  342.     }
  343.     else if( !part["format"]:false && part["detected_fs"]:`none != `swap )
  344.     {
  345.     // error popup text
  346. string message = _("
  347. WARNING:
  348.  
  349. You chose a swap partition but did not direct YaST2 to format it.
  350. This swap partition will probably not be usable.
  351.  
  352. Change the setup?
  353. ");
  354.  
  355.     allowed = !Popup::YesNo(message);
  356.     }
  357.     else
  358.     {
  359.     allowed = true;
  360.     }
  361.     if( allowed )
  362.     {
  363.     allowed = CheckFstabOptions( part );
  364.     }
  365.     return( allowed );
  366.     };
  367.  
  368. define boolean check_ok_fssize( integer siz, map part )
  369.     ``{
  370.     boolean ret = true;
  371.     if( part["format"]:false )
  372.     {
  373.     symbol fs = part["used_fs"]:`unknown;
  374.     integer min_size = FileSystems::MinFsSizeK( fs ) * 1024;
  375.     y2milestone( "check_ok_fssize fs:%1 size:%2", fs, min_size );
  376.     if( fs==`reiser && siz<min_size )
  377.         {
  378.         // popup text
  379.         Popup::Warning(_("Your partition is too small to use ReiserFS.
  380. ReiserFS is a journaling file system that requires
  381. at least 30 MB space for the journal alone.
  382. Use ReiserFS on larger partitions.
  383. "));
  384.         ret = false;
  385.         }
  386.     else if( fs==`jfs && siz<min_size )
  387.         {
  388.         Popup::Warning(_("Your partition is too small to use JFS.
  389. JFS is a journaling file system that requires
  390. at least 16 MB space for the journal alone.
  391. Use JFS on larger partitions.
  392. "));
  393.         ret = false;
  394.         }
  395.     else if( fs!=`unknown && siz<min_size )
  396.         {
  397.         // warning message, %1 is replaced by fs name (e.g. Ext3)
  398.         // %2 is prelaced by a size (e.g. 10 MB)
  399.         Popup::Warning(sformat(_("Your partition is too small to use %1.
  400. The minimum size for this file system is %2.
  401. "), FileSystems::GetName(fs,""), ByteToHumanStringWithZero(min_size) ));
  402.         ret = false;
  403.         }
  404.     }
  405.     return( ret );
  406.     };
  407.  
  408.     /**
  409.      * Do all checks concerning mount points, uuid, volume labels and
  410.      * fstab options
  411.      * @param targetMap the TargetMap
  412.      * @param mount mount point
  413.      * @return map
  414.      **/
  415. define map CheckOkMount( string dev, map old, map<string,any> new )
  416.     ``{
  417.     y2milestone( "CheckOkMount old:%1 new:%2", old, new );
  418.     map ret = $[];
  419.     ret["ok"] = true;
  420.     new["mount"] = UI::QueryWidget(`id(`mount_point), `Value);
  421.     new["mount"] = deletechars( new["mount"]:"", " \t" );
  422.     if( ret["ok"]:false && size(new["mount"]:"")>0 )
  423.     {
  424.     boolean crypt_fs = false;
  425.     if( !check_mount_point( Storage::GetTargetMap(), dev, new ))
  426.         {
  427.         ret["ok"] = false;
  428.         ret["field"] = `mount_point;
  429.         }
  430.     if( UI::WidgetExists( `id(`crypt_fs) ))
  431.         {
  432.         crypt_fs = (boolean)UI::QueryWidget(`id(`crypt_fs), `Value );
  433.         }
  434.     if( !check_crypt_fs_mount_points(new["mount"]:"", crypt_fs ))
  435.         {
  436.         ret["ok"] = false;
  437.         ret["field"] = `mount_point;
  438.         }
  439.     if( new["noauto"]:false && !check_noauto_mount( new["mount"]:"" ))
  440.         {
  441.         ret["ok"] = false;
  442.         ret["field"] = `mount_point;
  443.         }
  444.     if( new["type"]:`primary == `sw_raid )
  445.         {
  446.         if( !check_raid_mount_points(new["mount"]:""))
  447.         {
  448.         ret["ok"] = false;
  449.         ret["field"] = `mount_point;
  450.         }
  451.         }
  452.     else if( new["type"]:`primary == `lvm )
  453.         {
  454.         if( !check_lvm_mount_points(new["mount"]:""))
  455.         {
  456.         ret["ok"] = false;
  457.         ret["field"] = `mount_point;
  458.         }
  459.         }
  460.     }
  461.     if( !new["format"]:false )
  462.     {
  463.     new = filter(string key, any value, new, ``(key != "fs_options"));
  464.     }
  465.     y2milestone( "ret:%1 new:%2", ret, new );
  466.     ret["map"] = new;
  467.     return( ret );
  468.     };
  469.  
  470. /**
  471.   * Do all checks concerning handling of crypt fs
  472.   * @param new partition map
  473.   * @return map
  474.   **/
  475. define map CheckCryptOk( map new )
  476.     ``{
  477.     map ret = $[ "ok" : true ];
  478.     boolean crypt_fs = false;
  479.     if( UI::WidgetExists( `id(`crypt_fs) ))
  480.     {
  481.     crypt_fs = (boolean)UI::QueryWidget(`id(`crypt_fs), `Value );
  482.     }
  483.     if( crypt_fs )
  484.     new["enc_type"] = new["format"]:false?`twofish:`twofish_old;
  485.     else
  486.     new["enc_type"] = `none;
  487.     if( crypt_fs &&
  488.         size(Storage::GetCryptPwd( new["device"]:"" ))==0 )
  489.     {
  490.     string fs_passwd = DlgCreateCryptFs( new["device"]:"", new["format"]:false?8:5, new["format"]:false );
  491.     // Ask the user for a password for cryptofs, else set crypto to nil??
  492.     if( fs_passwd != nil && size(fs_passwd)>0 )
  493.         {
  494.         string dev = new["device"]:"";
  495.         boolean popup = !new["format"]:false;
  496.         y2milestone( "CheckCryptOk dev %1 popup %2", dev, popup );
  497.         if( popup )
  498.         UI::OpenDialog( `opt(`decorated),
  499.                     `VBox(
  500.                      `VSpacing(1),
  501.                     `HBox(`HSpacing(1), 
  502.                       `Label(_("Detecting encryption type...")),
  503.                       `HSpacing(1)),
  504.                      `VSpacing(1)));
  505.  
  506.         ret["ok"] = Storage::SetCryptPwd( dev, fs_passwd ) && 
  507.                     (new["format"]:false ||
  508.              Storage::SetCrypt( dev, true, new["format"]:false ));
  509.         if( ret["ok"]:false && new["type"]:`unknown == `loop )
  510.         Storage::UpdateClassified( new["fpath"]:"", fs_passwd );
  511.         if( popup )
  512.         UI::CloseDialog();
  513.         }
  514.     else
  515.         {
  516.         ret["ok"] = false;
  517.         }
  518.     }
  519.     ret["map"] = new;
  520.     y2milestone( "CheckCryptOk ret:%1", ret );
  521.     return( ret );
  522.     };
  523.  
  524. define map CheckDeviceFinalOk( map new )
  525.     ``{
  526.     y2milestone( "CheckDeviceFinalOk new:%1", new );
  527.     map ret = CheckCryptOk( new );
  528.     y2milestone( "CheckDeviceFinalOk ret:%1", ret );
  529.     return( ret );
  530.     }
  531.  
  532. define map<string,any> HandleFsChanged( boolean init, map<string,any> new, 
  533.                                         symbol old_fs, map file_systems )
  534.     ``{
  535.     boolean undo_change = false;
  536.     list<string> not_used_mp = [];
  537.     symbol used_fs = new["used_fs"]:`unknown;
  538.     map selected_fs = file_systems[used_fs]:$[];
  539.     y2milestone( "HandleFsChanged init:%1 used_fs:%2 old_fs:%3 new:%4",
  540.                  init, used_fs, old_fs, new );
  541.  
  542.     if( !init && used_fs != old_fs )
  543.     {
  544.     y2milestone( "HandleFsChanged IsUnsupported:%1", 
  545.                  FileSystems::IsUnsupported( used_fs ));
  546.     if( FileSystems::IsUnsupported( new["used_fs"]:`unknown ))
  547.         {
  548.         // warning message, %1 is replaced by fs name (e.g. Ext3)
  549.         string message = sformat(_("
  550. WARNING:
  551.  
  552. This file system is not supported in %1;.
  553. It is completely untested and might not be well-integrated 
  554. in the system.  Do not file bugs against the file system 
  555. itself if it does not work properly or at all.
  556.  
  557. Undo the change of file system?
  558. "), Product::name );
  559.  
  560.         undo_change = Popup::YesNo(message);
  561.         }
  562.     if( undo_change )
  563.         {
  564.         new["used_fs"] = old_fs;
  565.         UI::ChangeWidget(`id(`fs), `Value, old_fs );
  566.         }
  567.     }
  568.  
  569.     if( !undo_change && UI::WidgetExists( `id(`crypt_fs) ))
  570.     {
  571.     boolean cr = selected_fs[`crypt]:true;
  572.  
  573.     UI::ChangeWidget( `id(`crypt_fs), `Enabled, cr );
  574.     if( !cr )
  575.         {
  576.         y2milestone( "HandleFsChanged crypt set to false" );
  577.         UI::ChangeWidget(`id(`crypt_fs), `Value, false );
  578.         }
  579.     }
  580.  
  581.     if( !undo_change )
  582.     {
  583.     ////////////////////////////////////////////////
  584.     // switch between swap and other mountpoints
  585.     string mount = (string)UI::QueryWidget( `id(`mount_point), `Value);
  586.     new["mount"] = mount;
  587.     if( used_fs == `swap )
  588.         {
  589.         not_used_mp = selected_fs[`mountpoints]:[];
  590.         if( mount != "swap" && (new["type"]:`primary!=`lvm || mount!=""))
  591.         new["mount"] = "swap";
  592.         }
  593.     else
  594.         {
  595.         not_used_mp =
  596.         notUsedMountpoints( Storage::GetTargetMap(),
  597.                     selected_fs[`mountpoints]:[] );
  598.         if( new["type"]:`primary == `lvm ||
  599.         (new["type"]:`primary == `sw_raid&&
  600.          new["raid_type"]:"raid0"!="raid1") )
  601.         {
  602.         not_used_mp = filter( string mp, not_used_mp,
  603.                       ``( mp != Partitions::BootMount() ));
  604.         }
  605.         else if( new["type"]:`primary == `loop )
  606.         {
  607.         not_used_mp =
  608.             filter( string mp, not_used_mp,
  609.                 ``(!contains( FileSystems::system_m_points, mp)));
  610.         }
  611.         if(mount == "swap")
  612.         new["mount"] = "";
  613.         }
  614.     UI::ReplaceWidget(`id(`mount_dlg_rp), MountDlg( new, not_used_mp));
  615.     UI::ChangeWidget( `id(`mount_point), `Value, new["mount"]:"" );
  616.  
  617.     UI::ChangeWidget(`id(`fstab_options), `Enabled, true );
  618.     UI::ChangeWidget(`id(`fs_options), `Enabled,
  619.              new["format"]:false && selected_fs[`options]:[]!=[] );
  620.     string fstopt = FileSystems::DefaultFstabOptions( new );
  621.     if( size(fstopt)>0 && size(new["fstopt"]:"")==0 )
  622.         new["fstopt"] = fstopt;
  623.     if( !init )
  624.         {
  625.         new["fs_options"] = FileSystems::DefaultFormatOptions(new);
  626.         new["fstopt"] = fstopt;
  627.  
  628.         integer max_len = FileSystems::LabelLength( used_fs );
  629.         if( size(new["label"]:"") > max_len )
  630.         {
  631.         new["label"] = substring( new["label"]:"", 0, max_len );
  632.         }
  633.         symbol mountby = new["mountby"]:`device;
  634.         if( (mountby == `uuid && !FileSystems::MountUuid( used_fs )) ||
  635.         (mountby == `label && !FileSystems::MountLabel( used_fs )) )
  636.         {
  637.         new["mountby"] = `device;
  638.         }
  639.         if( !FileSystems::MountLabel( used_fs ) && size(new["label"]:"")>0 )
  640.         {
  641.         new["label"] = "";
  642.         }
  643.         }
  644.     }
  645.     y2milestone( "HandleFsChanged new %1", new );
  646.     return( new );
  647.     };
  648.  
  649.  
  650. define map<string,any> HandlePartWidgetChanges( boolean init, any ret,
  651.                                                 map file_systems,
  652.                         map<string,any> old,
  653.                         map<string,any> new )
  654.     ``{
  655.     y2milestone( "HandlePartWidgetChanges init:%1 ret:%2 new:%3",
  656.                  init, ret, new );
  657.     symbol used_fs = new["used_fs"]:`unknown;
  658.     map selected_fs = file_systems[used_fs]:$[];
  659.     /////////////////////////////////////////////////////////
  660.     // configure main dialog and modify map new
  661.     if( !init && new["mount"]:"" != old["mount"]:"" )
  662.     {
  663.     if( Arch::ia64 () && new["mount"]:"" == Partitions::BootMount() )
  664.         {
  665.         new = filter(string key, any value, new, ``( key != "fstopt"));
  666.         }
  667.     }
  668.     if( init || ret == `format_true || ret == `format_false )
  669.     {
  670.     boolean format = UI::QueryWidget(`id(`format), `CurrentButton) ==
  671.                      `format_true;
  672.  
  673.     boolean old_format = new["format"]:false;
  674.  
  675.     ////////////////////////////////////////////////
  676.     // format partition
  677.     new["format"] = format;
  678.  
  679.     ////////////////////////////////////////////////
  680.     // modify widgets
  681.     UI::ChangeWidget( `id(`fs), `Enabled, format );
  682.     UI::ChangeWidget( `id(`fs_options), `Enabled,
  683.               format && selected_fs[`options]:[] != [] );
  684.     if( UI::WidgetExists( `id(`crypt_fs) ))
  685.         {
  686.         UI::ChangeWidget( `id(`crypt_fs), `Enabled,
  687.                   selected_fs[`crypt]:true );
  688.         }
  689.     if( UI::WidgetExists( `id(`fsid_point) ))
  690.         {
  691.         UI::ChangeWidget( `id(`fsid_point), `Enabled, !format);
  692.         }
  693.  
  694.     if( old_format != format )
  695.         {
  696.         symbol dfs = `unknown;
  697.         if( format )
  698.         {
  699.         dfs = (symbol)UI::QueryWidget(`id(`fs), `Value);
  700.         }
  701.         else
  702.         {
  703.         if( new["detected_fs"]:`unknown != `unknown )
  704.             {
  705.             dfs = new["detected_fs"]:Partitions::DefaultFs();
  706.             }
  707.         else
  708.             {
  709.             dfs = new["used_fs"]:Partitions::DefaultFs();
  710.             }
  711.         UI::ChangeWidget( `id(`fs), `Value, dfs );
  712.         }
  713.         map selected_fs = file_systems[dfs]:$[];
  714.         new["used_fs"] = dfs;
  715.         y2milestone( "HandlePartWidgetChanges used_fs %1", dfs );
  716.         if( new["used_fs"]:`unknown != old["used_fs"]:`unknown )
  717.         new = HandleFsChanged( init, new, old["used_fs"]:`unknown,
  718.                                file_systems );
  719.         if( format )
  720.         {
  721.         new["fs_options"] = FileSystems::DefaultFormatOptions(new);
  722.         if( !contains( selected_fs[`alt_fsid]:[], new["fsid"]:0 ))
  723.             new["fsid"] = selected_fs[`fsid]:Partitions::fsid_native;
  724.         }
  725.         else
  726.         {
  727.         if( haskey( new, "ori_fsid" ) )
  728.             {
  729.             new["fsid"] = new["ori_fsid"]:0;
  730.             }
  731.         else
  732.             {
  733.             new["fsid"] = old["fsid"]:0;
  734.             }
  735.         }
  736.         if( UI::WidgetExists( `id(`fsid_point) ))
  737.         {
  738.         if( size(selected_fs)>0 &&
  739.             new["fsid"]:0 != selected_fs[`fsid]:0 &&
  740.             !contains( selected_fs[`alt_fsid]:[], new["fsid"]:0 ))
  741.             {
  742.             UI::ChangeWidget( `id(`fsid_point), `Value,
  743.                       selected_fs[`fsid_item]:"" );
  744.             }
  745.         }
  746.         if( !format )
  747.         {
  748.         new["fs_options"] = $[];
  749.         }
  750.         new["fstopt"] = FileSystems::DefaultFstabOptions( new );
  751.         }
  752.     }
  753.     if( init || ret == `fs )
  754.     {
  755.     symbol new_fs = (symbol)UI::QueryWidget(`id(`fs), `Value);
  756.     if( init )
  757.         {
  758.         if( !new["format"]:false && new["detected_fs"]:`unknown != `unknown )
  759.         new_fs = new["detected_fs"]:`unknown;
  760.         else if( new["fsid"]:0 == Partitions::fsid_gpt_boot )
  761.         new_fs = `vfat;
  762.         if( used_fs != new_fs )
  763.         UI::ChangeWidget(`id(`fs), `Value, new_fs );
  764.         }
  765.     y2milestone( "HandlePartWidgetChanges new_fs %1",
  766.                  UI::QueryWidget(`id(`fs), `Value) );
  767.     y2milestone( "HandlePartWidgetChanges init=%1 used_fs:%2 new_fs:%3",
  768.                  init, used_fs, new_fs );
  769.     if( init || used_fs != new_fs )
  770.         {
  771.         map selected_fs = file_systems[new_fs]:$[];
  772.         new["used_fs"] = new_fs;
  773.  
  774.         new = HandleFsChanged( init, new, used_fs, file_systems );
  775.  
  776.         if( !init )
  777.         {
  778.         if( !contains( selected_fs[`alt_fsid]:[], new["fsid"]:0 ))
  779.             new["fsid"] = selected_fs[`fsid]:Partitions::fsid_native;
  780.         y2milestone( "HandlePartWidgetChanges fsid %1", new["fsid"]:0 );
  781.         if( UI::WidgetExists( `id(`fsid_point) ))
  782.             {
  783.             UI::ChangeWidget( `id(`fsid_point), `Value,
  784.                       selected_fs[`fsid_item]:"");
  785.             }
  786.         }
  787.         }
  788.     }
  789.     if( (init && UI::WidgetExists(`id(`fsid_point))) || ret == `fsid_point )
  790.     {
  791.     ////////////////////////////////////////////////
  792.     // modify map new
  793.     string fs_string = (string)UI::QueryWidget(`id(`fsid_point), `Value);
  794.     y2milestone("HandlePartWidgetChanges fs_string:%1", fs_string );
  795.     fs_string        = substring( fs_string, 0, 5  );
  796.     integer fs_int   = tointeger( fs_string );
  797.     integer old_id   = new["fsid"]:0;
  798.  
  799.     y2milestone( "HandlePartWidgetChanges fs_int:%1 old_id:%2",
  800.                  fs_int, old_id );
  801.  
  802.     if( fs_int != old_id )
  803.         {
  804.         new["fsid"] = fs_int;
  805.         boolean no_fs = contains( [ Partitions::fsid_lvm,
  806.                                     Partitions::fsid_raid,
  807.                     Partitions::fsid_hibernation,
  808.                     Partitions::fsid_prep_chrp_boot ],
  809.                       fs_int );
  810.  
  811.         UI::ChangeWidget( `id(`fstab_options), `Enabled, !no_fs );
  812.         UI::ChangeWidget( `id(`format_true), `Enabled, !no_fs );
  813.         UI::ChangeWidget( `id(`mount_point), `Enabled, !no_fs );
  814.         if( no_fs )
  815.         {
  816.         new["mount"] = "";
  817.         UI::ChangeWidget( `id(`mount_point), `Value, new["mount"]:"" );
  818.         if( UI::WidgetExists( `id(`crypt_fs) ))
  819.             {
  820.             UI::ChangeWidget( `id(`crypt_fs), `Enabled, false );
  821.             }
  822.         ChangeExistingSymbolsState( [ `fs_options, `fs ], false );
  823.         }
  824.         else if( fs_int == Partitions::fsid_native )
  825.         {
  826.         new["used_fs"] = Partitions::DefaultFs();
  827.         UI::ChangeWidget( `id(`fs), `Value, new["used_fs"]:`unknown );
  828.         new = HandleFsChanged( init, new, Partitions::DefaultFs(),
  829.                                file_systems );
  830.         }
  831.         else if( fs_int == Partitions::fsid_swap )
  832.         {
  833.         new["used_fs"] = `swap;
  834.         UI::ChangeWidget( `id(`fs), `Value, new["used_fs"]:`unknown );
  835.         new = HandleFsChanged( init, new, `swap, file_systems );
  836.         }
  837.         else if( contains( Partitions::fsid_wintypes, fs_int ) ||
  838.                  fs_int==Partitions::fsid_gpt_boot )
  839.         {
  840.         new["mount"] = "";
  841.         new["used_fs"] = `vfat;
  842.         UI::ChangeWidget( `id(`fs), `Value, new["used_fs"]:`unknown );
  843.         new = HandleFsChanged( init, new, `vfat, file_systems );
  844.         }
  845.         else if( fs_int == Partitions::fsid_mac_hfs )
  846.         {
  847.         new["mount"] = "";
  848.         new["used_fs"] = `hfs;
  849.         UI::ChangeWidget( `id(`fs), `Value, new["used_fs"]:`unknown );
  850.         new = HandleFsChanged( init, new, `hfs, file_systems );
  851.         }
  852.         }
  853.     }
  854.     if( ret == `fstab_options )
  855.     {
  856.     new["mount"] = UI::QueryWidget( `id(`mount_point), `Value );
  857.     new = FstabOptions( old, new );
  858.     }
  859.     if( ret == `crypt_fs )
  860.     {
  861.     boolean val = (boolean)UI::QueryWidget( `id(`crypt_fs), `Value );
  862.     new["enc_type"] = val?(new["format"]:false?`twofish:`twofish_old):`none;
  863.     if( val )
  864.         {
  865.         new["mountby"] = `device;
  866.         new["label"] = "";
  867.         new["ori_label"] = "";
  868.         }
  869.     }
  870.     if( ret == `fs_options )
  871.     {
  872.     new["fs_options"] = FileSystemOptions( new["fs_options"]:$[],
  873.                                            selected_fs );
  874.     }
  875.     if( Mode::repair () )
  876.         {
  877.         UI::ChangeWidget(`id(`mount_point),   `Enabled, false);
  878.         UI::ChangeWidget(`id(`fstab_options), `Enabled, false);
  879.         UI::ChangeWidget(`id(`crypt_fs) ,     `Enabled, false);
  880.         }
  881.     y2milestone( "HandlePartWidgetChanges old:%1", old );
  882.     y2milestone( "HandlePartWidgetChanges new:%1", new );
  883.     return( new );
  884.     };
  885.  
  886. /**
  887.  * Merge readed list fstab with targetMap
  888.  * @parm targetMap all targets
  889.  * @parm fstab readed fstab list
  890.  * @return return ( [ targetMap, table_input ]
  891.  *
  892.  */
  893. define list AddFstabToData( map<string,map> targetMap, list<map> fstab )
  894.     ``{
  895.     if( fstab == nil )
  896.     return [targetMap] ;
  897.  
  898.     y2milestone( "AddFstabToData fstab = %1", fstab );
  899.  
  900.     map new_targetMap = targetMap;
  901.     map table_input = $["tbl":[]];
  902.  
  903.     foreach( string dev, map disk, targetMap,
  904.     ``{
  905.     list new_partitions = [];
  906.     map target = disk;
  907.     foreach( map partition, disk["partitions"]:[],
  908.         ``{
  909.         map new_partition = partition;
  910.  
  911.         foreach( map fstab_entry, fstab,
  912.         ``{
  913.         string dev_fstab   = fstab_entry["device"]:"";
  914.         string mount_fstab = fstab_entry["mount"]:"";
  915.         boolean found = false;
  916.  
  917.         if( dev_fstab == partition["device"]:"" )
  918.             {
  919.             found = true;
  920.             }
  921.         if( found )
  922.             {
  923.             new_partition["mount"] = mount_fstab;
  924.             if( size(fstab_entry["fstopt"]:"")>0 &&
  925.             fstab_entry["fstopt"]:"" != "default" )
  926.             {
  927.             new_partition["fstopt"] = fstab_entry["fstopt"]:"";
  928.             }
  929.             if( fstab_entry["mountby"]:`device != `device )
  930.             new_partition["mountby"] = fstab_entry["mountby"]:`device;
  931.             if( fstab_entry["enc_type"]:`none != `none )
  932.             new_partition["enc_type"] = fstab_entry["enc_type"]:`none;
  933.  
  934.             /////////////////////////////////////////////
  935.             // entries for table
  936.             term a = `item(`id(dev_fstab));
  937.             a = add( a, dev_fstab );
  938.             a = add( a, mount_fstab );
  939.             if( mount_fstab=="/" )
  940.             {
  941.             table_input["root"] = dev_fstab;
  942.             }
  943.             table_input["tbl"] = add( table_input["tbl"]:[], a );
  944.             }
  945.         });
  946.         new_partitions = add( new_partitions, new_partition);
  947.         });
  948.     target["partitions"] = new_partitions;
  949.     new_targetMap[dev] = target;
  950.     });
  951.  
  952.     y2milestone( "AddFstabToData table_input %1", table_input );
  953.     y2milestone( "AddFstabToData tbl %1", table_input["tbl"]:[] );
  954.  
  955.     if( size( table_input["tbl"]:[] )>1 )
  956.     {
  957.     table_input["tbl"] = sort( term a, term b, table_input["tbl"]:[],
  958.                                ``(a[2]:""<b[2]:""));
  959.     }
  960.     y2milestone( "AddFstabToData ret %1", [ new_targetMap, table_input ] );
  961.  
  962.     return [ new_targetMap, table_input ];
  963.     };
  964.  
  965. define boolean check_max_size( integer byte_size, integer max_size )
  966.     ``{
  967.     y2milestone( "icheck_lv_size byte_size=%1 max_size=%2", byte_size,
  968.                  max_size );
  969.  
  970.     if( byte_size == 0 )
  971.         {
  972.     if( max_size>0 )
  973.         // error popup text
  974.         Popup::Error(sformat(_("The size entered is invalid.
  975. Enter a size from 1M to %1. For example, 40M or 1G."),
  976.                    ByteToHumanStringWithZero(max_size)) );
  977.     else
  978.         // error popup text
  979.         Popup::Error(_("The size entered is invalid.
  980. Enter a valid size, such as 500k, 40M, or 1G.
  981. "));
  982.         return( false );
  983.         }
  984.  
  985.     if( max_size>0 && byte_size>max_size )
  986.         {
  987.     // error popup text
  988.         Popup::Error(sformat(_("The size entered is too large.
  989. Enter a size from 1M to %1."),
  990.                                ByteToHumanStringWithZero(max_size)) );
  991.         return( false );
  992.         }
  993.  
  994.     return( true );
  995.     };
  996.  
  997. define boolean CheckResizePossible( boolean ask, boolean lvm, integer resize,
  998.                                     symbol fsys, string mount )
  999.     ``{
  1000.     map poss = FileSystems::IsResizable( fsys );
  1001.     boolean ret = true;
  1002.  
  1003.     y2milestone( "CheckResizePossible resize %1 ask %2 lvm %3 fsys %4 mount %5",
  1004.                  resize, ask, lvm, fsys, mount );
  1005.     if( size(mount)>0 && !Stage::initial() && resize < 0 &&
  1006.         !poss["mount_shrink"]:false && poss["shrink"]:false )
  1007.         {
  1008.     FsysCannotResizeMountPopup( lvm, mount );
  1009.     ret = false;
  1010.     }
  1011.     else if( size(mount)>0 && !Stage::initial() && resize > 0 &&
  1012.              !poss["mount_extend"]:false && poss["extend"]:false )
  1013.         {
  1014.     FsysCannotResizeMountPopup( lvm, mount );
  1015.     ret = false;
  1016.     }
  1017.     else if( size(mount)>0 && !Stage::initial() && resize != 0 && !lvm )
  1018.         {
  1019.     FsysCannotResizeMountPopup( lvm, mount );
  1020.     ret = false;
  1021.     }
  1022.     else if( resize < 0 && !poss["shrink"]:false )
  1023.     {
  1024.     ret = FsysCannotShrinkPopup( ask, lvm );
  1025.     }
  1026.     else if( resize < 0 && fsys==`reiser )
  1027.     {
  1028.     ret = FsysShrinkReiserWarning( lvm );
  1029.     }
  1030.     else if( resize>0 && !poss["extend"]:false )
  1031.     {
  1032.     ret = FsysCannotGrowPopup( ask, lvm );
  1033.     }
  1034.     y2milestone( "ret %1", ret );
  1035.     return( ret );
  1036.     }
  1037.  
  1038.  
  1039. }
  1040.