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 / lvm_pv_lib.ycp < prev    next >
Text File  |  2006-11-29  |  10KB  |  360 lines

  1. /**
  2.  * File:
  3.  *   lvm_pv_lib.ycp
  4.  *
  5.  * Module: 
  6.  *    configuration of lvm: lib for handling of physical volumes
  7.  *
  8.  * Summary:
  9.  *
  10.  * Authors:
  11.  *   mike <mike@suse.de>
  12.  *
  13.  *
  14.  * $Id: lvm_pv_lib.ycp 32707 2006-09-05 16:42:51Z fehr $
  15.  *
  16.  */
  17.  
  18.  
  19. {
  20.      textdomain "storage";
  21.      import "Storage";
  22.      import "Partitions";
  23.      import "Package";
  24.  
  25.      include "partitioning/lvm_lib.ycp";
  26.      include "partitioning/lvm_lv_lib.ycp";
  27.      
  28.     //////////////////////////////////////////////////////////////////////
  29.     // add a partition to the current volume group
  30.     //
  31.     //        $[ 1 : $[  "use_module" : "lvm_ll"
  32.     //               "type"       : "create_pv",
  33.     //               "vgname"     : "system"     -- optional, wenn da dann vgextend nach pvcreate
  34.     //               "device"     : "/dev/sda1"
  35.     //
  36.     //   !!!!!!! changes targetMap by reference !!!!!!
  37.     //     
  38.     //////////////////////////////////////////////////////////////////////
  39.  
  40. define boolean addPhysicalVolume( map<string,map> targetMap, string id, 
  41.                   string current_vg )
  42.     ``{
  43.     map partition = Storage::GetPartition( targetMap, id );
  44.     y2milestone( "partition %1", partition );
  45.     
  46.     if( partition["fsid"]:0 != Partitions::fsid_lvm && 
  47.         contains( [`primary, `logical], partition["type"]:`none ) )
  48.     {
  49.     Storage::SetPartitionId( id, Partitions::fsid_lvm );
  50.     }
  51.     Storage::SetPartitionMount( id, "" );
  52.     Storage::SetPartitionFormat( id, false, `none );
  53.     boolean ret = Storage::ExtendLvmVg( current_vg, id );
  54.     return( ret );
  55.     };
  56.     
  57.  
  58. define boolean removePhysicalVolume( map<string,map> targetMap, string id,
  59.                                  string current_vg )
  60.     ``{
  61.     map partition = Storage::GetPartition( targetMap, id );
  62.  
  63.     if( partition["fsid"]:0 == Partitions::fsid_lvm &&
  64.         contains( [`primary, `logical], partition["type"]:`none ) )
  65.     {
  66.     Storage::UnchangePartitionId( id );
  67.     }
  68.     boolean ret = Storage::ReduceLvmVg( current_vg, id );
  69.     if( !ret )
  70.     {
  71.     // message popup
  72.     Popup::Error(_("If you remove the selected device from the volume group,
  73. there will not be enough space for all logical volumes in 
  74. this group.  To delete the volume group completely, remove 
  75. its logical volumes first.
  76. "));
  77.     }
  78.     return( ret );
  79.     };
  80.     
  81.  
  82. //////////////////////////////////////////////////////////////////////
  83. // belongs the the partition "id" already to a volume group
  84. //////////////////////////////////////////////////////////////////////
  85.  
  86. define boolean isItemPv( map<string,map> tg, string id )
  87.     ``{
  88.     map part = $[];
  89.     if( haskey( tg, id ))
  90.     part = tg[id]:$[];
  91.     else
  92.     part = Storage::GetPartition( tg, id );
  93.     return( part["used_by_type"]:`UB_NONE == `UB_LVM ||
  94.             part["used_by_type"]:`UB_NONE == `UB_EVMS );
  95.     };
  96.  
  97.  
  98. //////////////////////////////////////////////////////////////////////
  99. // belongs the the partition "id" already to a volume group
  100. // if YES: popup a proper Message and return(false)
  101. //////////////////////////////////////////////////////////////////////
  102.  
  103. define boolean CheckItemIsNotPv( map<string,map> tg, string id )
  104.     ``{
  105.     if( !isItemPv(tg,id) )
  106.     {
  107.     //////////////
  108.     return( true );
  109.     //////////////
  110.     }
  111.  
  112.     // error case:
  113.     if( id != nil )
  114.     {
  115.     // message popup
  116.     Popup::Message(sformat(_("The item %1 is already a physical volume.
  117. To add it to a different volume group,
  118. remove it from its current volume group
  119. then add it to the new group.
  120. "), id ));
  121.     }
  122.     else
  123.     {
  124.     // message popup
  125.     Popup::Message(_("You have to select one device in the table"));
  126.     }
  127.     return( false );
  128.     };
  129.  
  130.     //////////////////////////////////////////////////////////////////////
  131.     // belongs the the partition "id" already to a volume group?
  132.     // if NO: popup a proper Message and return(false)
  133.     //////////////////////////////////////////////////////////////////////
  134.  
  135. define boolean CheckItemIsPv( map<string,map> tg, string id )
  136.     ``{
  137.     if ( isItemPv(tg,id) )
  138.     {
  139.     //////////////
  140.     return( true );
  141.     //////////////
  142.     }
  143.  
  144.     // error case: 
  145.     if ( id != nil )
  146.     {
  147.     // Message popup
  148.     Popup::Message(sformat(_("The item %1 cannot be removed.
  149. It does not belong to a volume group.
  150. "), id ));
  151.     }
  152.     else
  153.     {
  154.     //Message popup
  155.     Popup::Message(_("You have to select one device in the table"));
  156.     }
  157.     return( false );
  158.     };
  159.  
  160.  
  161. /////////////////////////////////////////////////////////////////
  162. // Get all partitions, we can probably use as physical volumes
  163. // Add needed information: disksize 
  164.  
  165. define list<map> get_possible_pvs( map<string,map> targetMap )
  166.     ``{
  167.     list<map> ret = [];
  168.     
  169.     //////////////////////////////////////////////////////////////////////
  170.     // add the devicename i.e /dev/hda1 or /dev/system/usr to partition list
  171.     // and the device key  <subdevice>/<maindevice> i.e. 1//dev/hda
  172.     
  173.     targetMap = mapmap( string dev, map devmap, targetMap,
  174.     ``{
  175.     list partitions = maplist( map part, devmap["partitions"]:[],
  176.         ``{
  177.         part["maindev"] = dev;
  178.         return( part );
  179.         });
  180.     return( $[ dev: add(devmap, "partitions", partitions) ] );
  181.     });
  182.  
  183.     ////////////////////////////////////////////////////////////
  184.     // Look for all partitions:
  185.     // not LVM ( here I mean /dev/<lvm_volumegroup>/<lv> entries!
  186.     //           there are only the lv's in the targetMap under /dev/<lvm_volumegroup>/<lv> !)
  187.     // no mountpoint
  188.     // id 0x83 or 0x8e or 0xfe
  189.  
  190.     list types_no = [ `lvm, `evms, `extended ];
  191.     list fsids = [ Partitions::fsid_lvm, Partitions::fsid_raid,
  192.            Partitions::fsid_native ];
  193.     list ubs = [ `UB_NONE, `UB_LVM, `UB_EVMS ];
  194.  
  195.     foreach( string dev, map devmap, targetMap,
  196.     ``{
  197.     y2milestone( "get_possible_pvs parts:%1", devmap["partitions"]:[] );
  198.     list<map> parts = 
  199.         filter( map part, devmap["partitions"]:[],
  200.             ``( size(part["mount"]:"")==0 &&
  201.             !contains( types_no, part["type"]:`primary ) &&
  202.             contains( ubs, part["used_by_type"]:`UB_NONE ) &&
  203.             (part["type"]:`primary==`sw_raid||
  204.              part["type"]:`primary==`dm||
  205.             contains( fsids, part["fsid"]:0 ))));
  206.     y2milestone( "get_possible_pvs filter:%1", parts );
  207.     if( devmap["used_by_type"]:`UB_NONE!=`UB_NONE )
  208.         {
  209.         parts = [];
  210.         y2milestone( "get_possible_pvs no parts, disk used by %1 %2",
  211.                      devmap["used_by_type"]:`UB_NONE, devmap["used_by"]:"" );
  212.         }
  213.     if( size(devmap["partitions"]:[])==0 && 
  214.         Storage::IsPartType(devmap["type"]:`CT_UNKNOWN) &&
  215.         contains( ubs, devmap["used_by_type"]:`UB_NONE ))
  216.         {
  217.         map p = $[ "device":dev, "maindev":dev, 
  218.                    "size_k":devmap["size_k"]:0 ];
  219.         if( devmap["used_by_type"]:`UB_NONE != `UB_NONE )
  220.         {
  221.         p["used_by_type"] = devmap["used_by_type"]:`UB_NONE;
  222.         p["used_by"] = devmap["used_by"]:"";
  223.         }
  224.         parts = [ p ];
  225.         }
  226.     ret = (list<map>)merge( ret, parts );
  227.     });
  228.     ret = maplist( map p, ret,
  229.     ``{
  230.     p["used_by"] = lvmVg( p["used_by"]:"" );
  231.     return( p );
  232.     });
  233.     y2milestone( "get_possible_pvs ret %1", ret );
  234.     return( ret );
  235.     };
  236.  
  237.  
  238.     
  239.     //////////////////////////////////////////////////////////////////////
  240.     // partition list to widget table
  241.     // in:
  242.     // [  $["fsid":Partitions::fsid_lvm,
  243.     //      "fstype":"LVM",
  244.     //      "nr":"var",
  245.     //      "region":[255, 16],
  246.     //      "type":`primary],
  247.     //      $[
  248.     //       "fsid":131,
  249.     //       "fstype":"Linux native",
  250.     //       "nr":4, "region":[271, 844],
  251.     //    ...
  252.     //
  253.     // out:
  254.     // [
  255.     //     `item(`id("/dev/hda1"), "/dev/hda1 ",   " 2G ",  " LVM ",   " system"),
  256.     //     `item(`id("/dev/hda2"), "/dev/hda2 ",   " 1G ",  " Linux ", " ")
  257.     // ];
  258.  
  259. define list get_pv_widget_table( list<map> possPvList )
  260.     ``{
  261.     list    ret = [];
  262.  
  263.     possPvList = 
  264.     sort( map x, map y, possPvList,
  265.       ``{
  266.       if( x["maindev"]:"" == y["maindev"]:"")
  267.           {
  268.           if( haskey( x, "nr" ))
  269.           return( x["nr"]:0 < y["nr"]:0);
  270.           else
  271.           return( x["name"]:"" < y["name"]:"");
  272.           }
  273.       else
  274.           {
  275.           return( x["maindev"]:"" < y["maindev"]:"" );
  276.           }
  277.       });
  278.     
  279.     return( maplist( map p, possPvList,
  280.      ``{
  281.          return(`item( `id(p["device"]:"--"),
  282.                p["device"]:"--",
  283.                ByteToHumanStringWithZero(p["size_k"]:0*1024),
  284.                p["fstype"]:"--",
  285.                p["used_by"]:"--"
  286.                ));
  287.         }
  288.       ));
  289.     };
  290.  
  291.     
  292.  
  293. /**
  294.  * Check if the user can delete the partition.
  295.  * -> Existing LVM partition with volume group
  296.  * -> size of volume group to small for all logical partition
  297.  */
  298. define boolean check_pv_delete( map<string,map> targetMap, string id, 
  299.                                 string current_vg ) 
  300.     ``{
  301.     boolean ret = true;
  302.     y2milestone( "check_pv_delete id %1 current_vg: %2", id, current_vg );
  303.     integer num_pvs = size( filter( map p, get_possible_pvs(targetMap),
  304.                     ``(p["used_by"]:""==current_vg)));
  305.     y2milestone( "check_pv_delete num_pvs:%1", num_pvs );
  306.     if( num_pvs<=1 )
  307.     {
  308.     // message popup
  309.     Popup::Error(_("You cannot remove the last PV from a volume group.
  310. Delete the volume group completely instead.
  311. "));
  312.     y2milestone( "check_pv_delete `nodelete" );
  313.     ret = false;
  314.     }
  315.  
  316.     y2milestone( "check_pv_delete ret:%1", ret );
  317.     return( ret );
  318.     }
  319.     
  320. define boolean check_lvm_possible( map<string,map> targetMap )
  321.    ``{
  322.    boolean possible_part_found = size(get_possible_pvs(targetMap))>0;
  323.    if( !possible_part_found )
  324.        {
  325.        // Translators: the text 'do not format' must match the label in the corresponding popup!
  326.        Popup::Message(_("To use LVM, at least one partition of type 0x8e (or 0x83)
  327. is required. Change your partition table accordingly.
  328. In most cases, this can be done in the following way:
  329. click 'Create', select 'Do not format', and set the partition ID to 0x8e.
  330. "));
  331.        }
  332.    else if( Mode::normal() )
  333.        {
  334.        possible_part_found = Package::InstallAll( ["lvm2"] );
  335.        }
  336.    return possible_part_found;
  337.    }
  338.  
  339. boolean check_vgname_dev( string vgname )
  340.     {
  341.     boolean ret = true;
  342.     string devdir = "/dev/" + vgname;
  343.     map stat = (map) SCR::Read( .target.stat, devdir );
  344.     y2milestone( "check_vgname_dev stat %1", stat );
  345.     if( size(stat)>0 )
  346.     {
  347.     ret = stat["isdir"]:false;
  348.     if( ret )
  349.         {
  350.         map out = (map)SCR::Execute( .target.bash_output, 
  351.                                      "find "+devdir+" ! -type l | sed 1d" );
  352.         ret = size(out["stdout"]:"")==0;
  353.         }
  354.     }
  355.     y2milestone( "check_vgname_dev %1 ret %2", vgname, ret );
  356.     return( ret );
  357.     }
  358. }
  359.  
  360.