[ Previous | Next | Contents | Glossary | Home | Search ]
AIX Version 4.3 General Programming Concepts: Writing and Debugging Programs

Logical Volume Program Example

/*      This program is designed to demonstrate the use of Logical
 *      Volume Manager subroutines. 
 */ 
/*      The program objectives are:
 *      -  to create a volume group with two logical volumes and
 *         two physical volumes
 *      -  to then delete the physical volumes, logical volumes 
 *         and volume group that were previously created.
 */ 

/*      The following subroutines are demonstrated: 
 *      -  lvm_createvg
 *      -  lvm_createlv
 *      -  lvm_installpv
 *      -  lvm_extendlv
 *      -  lvm_reducelv
 *      -  lvm_deletelv
 *      -  lvm_deletepv
 *      -  lvm_varyonvg
*/
 
#include <lvm.h>
 
#define SUCCESS 0         /* Successful return code. */
#define VGNAME "rvg34"
        /*  Name of volume group, must be raw device. */
#define VGMAJOR 34
        /*  Major number for this volume group the major number 
            can be any unused major number in the system. */
#define PVNAME1 "rhdisk1" 
        /*  Name of physical volume, should define a raw device. */
#define PVNAME2 "rhdisk2"
        /*  Name of physical volume, should define a raw device. */
#define MAX_LVS 32
        /*  Max number of logical volumes desired in 
            the volume group, can be no more that 256. */
#define PPSIZE  22
        /*  Size of physical partitions in volume group, 
            2^22 or 4Meg. Possible values range from 
            LVM_MINPPSIZ and LVM_MAXPPSIZ both found in lvm.h. */
#define VGDASIZE 32 
        /*  Size of volume group descriptor area. 
            Possible values are in the range of 
            LVM_MINVGDASIZ and LVM_MAXVGDASIZ 
            found in lvm.h. */
#define PVID1_W1 0x00000002
        /*  Physical volume id word one for pv1. */
#define PVID1_W2 0x00004321
        /*  Physical volume id word two for pv1. */
#define PVID2_W1 0x00000003
        /*  Physical volume id word one for pv2. */
#define PVID2_W2 0x00004322
        /*  Physical volume id word two for pv2. */
#define LVNAME1 "rhd34.1" 
        /*  Logical volume name, must be raw device. */
#define LVNAME2 "rhd34.2"
        /*  Logical volume name, must be raw device. */
#define MAXSIZE 128 
        /*  Max number of logical partitions on the 
            logical volumes in the volume group. */
#define MINOR1  0x1 
        /*  Minor number for first logical volume. */
#define MINOR2  0x2 
        /*  Minor number for second logical volume. */
#define LV1_PPS 2 
        /*  Number of physical partitions being used to 
            extend the first logical volume created. */
#define LV2_PPS 4 
        /*  Number of physical partitions being used to 
            extend the second logical volume created. */
  
struct createvg cvg;    /* Createvg structure */
struct createlv clv;    /* Createlv structure */
struct lv_id    lid;    /* LV ID structure */
struct ext_redlv e_r;   /* Extend/Reduce LV structure */
struct changelv chlv;   /* Change LV structure*/
struct varyonvg von;    /* Varyonvg structure*/
struct varyoffvg voff;  /* Varyoffvg structure*/
struct changepv cpv;    /* Change PV structure*/
struct pp        pps1[LV1_PPS]; 
        /* Structures for physical partition. */
struct pp       pps2[LV2_PPS];
        /* Maps to be passed into extendlv and reducelv. */
struct unique_id pv1 = {PVID1_W1, PVID1_W2};  
        /* ID of first physical volume. */
struct unique_id pv2 = {PVID2_W1, PVID2_W2};
        /* ID of second physical volume. */            
 
int
sample()
{
        int     rc;     /* Return code. */
 
        /*
         *  Call the procedure to create a volume group with two 
         *  logical volumes and two physical volumes.
         */
 
        rc = build();
        if (rc < SUCCESS) 
          return(rc);
 
        /*
         *  Call the procedure to delete everything created
         *  in the build routine
         */
 
        rc = destroy();
        if (rc < SUCCESS)
          return(rc);
 
        return(SUCCESS);
}
 
int
build()
{
        int              rc;      /* Return code. */
 
        /*
         *  Fill in the fields of the createvg structure to be
         *  passed into the lvm_createvg subroutine.
         */
        cvg.kmid         = KMID;
        cvg.vgname       = VGNAME;
        cvg.vg_major     = VGMAJOR;
        cvg.pvname       = PVNAME1;
        cvg.maxlvs       = MAX_LVS;
        cvg.ppsize       = PPSIZE; 
        cvg.vgda_size    = VGDASIZE;
 
        /*
         *  Call lvm_createvg() to create a volume group.
         */
 
        rc = lvm_createvg(&cvg);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         *  Fill in the fields of the varyonvg structure to be
         *  passed into lvm_varyonvg().
         */
 
        von.kmid                         = KMID;
        von.vgname                       = VGNAME;
        von.vg_major                     = VGMAJOR;
        von.vg_id.word1                  = cvg.vg_id.word1; 
        von.vg_id.word2                  = cvg.vg_id.word2;
        von.noopen_lvs                   = FALSE; 
        von.auto_resync                  = TRUE,
        von.misspv_von                   = TRUE;
        von.missname_von                 = TRUE;
        von.vvg_in.pv[0].pv_id   = pv1;
        von.vvg_in.pv[0].pvname  = PVNAME1;
        von.vvg_in.num_pvs       = 1;
 
        /*
         *  Call lvm_varyonvg() to vary the newly created volume 
         *  group on-line.
         */
 
        rc = lvm_varyonvg(&von);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         *  Install a second physical volume Into the volume group.
         */
 
        rc = lvm_installpv(PVNAME2, &(cvg.vg_id));
        if(rc < SUCCESS)
          return(rc);
 
        /*
         *  Fill in the fields of the createlv structure to be
         *  passed into lvm_createlv().
         */
 
        clv.vg_id.word1          = cvg.vg_id.word1;
        clv.vg_id.word2          = cvg.vg_id.word2;
        clv.lvname               = LVNAME1;
        clv.maxsize                      = MAXSIZE;
        clv.minor_num                    = MINOR1;
        clv.mirror_policy                = LVM_PARALLEL;
        clv.permissions          = LVM_RDWR;
        clv.bb_relocation                = LVM_RELOC;
        clv.write_verify                 = LVM_NOVERIFY;
        clv.mirwrt_consist               = LVM_CONSIST; 
 
        /*
         *  Call lvm_createlv() to create a logical volume.
        */
 
        rc = lvm_createlv(&clv);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         * Fill in the pp structs that will map physical partitions 
         * to logical partitions. There should be one entry for each          * physical partition being added.
         * NOTE that all physical partitions for this logical volume
         * are on the same (one) physical volume (hardfile)
         */
 
        pps1[0].pv_id            = pv1;   
        pps1[0].lp_num   = 1;
        pps1[0].pp_num   = 1;
 
        pps1[1].pv_id            = pv1;
        pps1[1].lp_num   = 2;
        pps1[1].pp_num   = 2;
 
        e_r.parts                = pps1;
        /* 
         *  e_r.size is two because there are two physical
         *  partitions being added.
         */
 
        e_r.size = 2; 
        /*
         *  Set up the id of the logical volume being extended.
         */
 
        lid.minor_num            = MINOR1;
        lid.vg_id.word1   = cvg.vg_id.word1;
        lid.vg_id.word2   = cvg.vg_id.word2;
 
        /*
         *  Call lvm_extendlv() to extend the logical volume so that
         *  it has two logical partitions.
         */
 
        rc = lvm_extendlv(&lid, &e_r);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         * Fill in the fields of the createlv structure to be passed
         * into lvm_createlv().
         */
 
        clv.vg_id.word1         = cvg.vg_id.word1;
        clv.vg_id.word2         = cvg.vg_id.word2;
        clv.lvname              = LVNAME2;
        clv.maxsize             = MAXSIZE;
        clv.minor_num           = MINOR2;
        clv.mirror_policy       = LVM_PARALLEL;  /* from <lvm.h>  */
        clv.permissions   = LVM_RDWR;         /* from <lvm.h>  */
        clv.bb_relocation       = LVM_RELOC;     /* from <lvm.h>  */
        clv.write_verify        = LVM_NOVERIFY;  /* from <lvm.h> */
        clv.mirwrt_consist      = LVM_CONSIST;   /* from <lvm.h>  */           
        /*
         * Call lvm_createlv() to create a second logical volume.
         */
 
        rc = lvm_createlv(&clv);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         * Fill in the pp structs that will map physical partitions               * to logical partitions. There should be one entry for each
         * physical partition being added. NOTE that the physical  
         * partitions on this logical volume are spread across two
         * physical volumes or hardfiles. Also, this logical volume 
         * is mirrored; it has two copies of each logical partition.
         */
 
        pps2[0].pv_id   = pv1;          /* First physical volume. */
        pps2[0].lp_num  = 1;
        pps2[0].pp_num  = 3;
 
        pps2[1].pv_id   = pv1;
        pps2[1].lp_num  = 2;
        pps2[1].pp_num  = 7;
 
        pps2[2].pv_id   = pv2;    /* Second physical volume. */
        pps2[2].lp_num  = 1;
        pps2[2].pp_num  = 5;
 
        pps2[3].pv_id   = pv2;
        pps2[3].lp_num  = 2;
        pps2[3].pp_num  = 9;
 
        e_r.parts       = pps2;

        /*
         *  e_r.size is four because there are four physical 
         *  partitions being extended.
          */
 
        e_r.size = 4;
 
        /*
         *  Set up the id of the logical volume being extended.
         */
 
        lid.minor_num       =  MINOR2;
        lid.vg_id.word1   =  cvg.vg_id.word1;
        lid.vg_id.word2   =  cvg.vg_id.word2;
 
        /*
         *  Call lvm_extendlv() to extend the logical volume.
         */
 
        rc = lvm_extendlv(&lid, &e_r);
        if(rc < SUCCESS)
          return(rc);
 
        return SUCCESS;
}
 
int
destroy()
{
        int     rc;      /* Return code. */
 
        /*
         * Fill in the physical partition structures for the 
         * physical partitions to be deleted, or reduced. 
         */
 
        pps2[0].pv_id = pv1;
        pps2[0].lp_num = 1;
        pps2[0].pp_num = 3;
 
        pps2[1].pv_id = pv1;
        pps2[1].lp_num = 2;
        pps2[1].pp_num = 7;
 
        pps2[2].pv_id = pv2;
        pps2[2].lp_num = 1;
        pps2[2].pp_num = 5;
 
        pps2[3].pv_id = pv2; 
        pps2[3].lp_num = 2;
        pps2[3].pp_num = 9;

        e_r.parts = pps2;

        /*
         * The size field should correspond to the number of 
         * physical partitions being reduced. 
         */
 
        e_r.size = 4;
 
        /*  Fill in the id of the logical volume to be reduced. */
          
        lid.minor_num            = MINOR2;
        lid.vg_id.word1  = cvg.vg_id.word1;
        lid.vg_id.word2  = cvg.vg_id.word2;
 
        /*
         *  Call lvm_reducelv() to reduce the logical volume.
         */
 
        rc = lvm_reducelv(&lid, &e_r);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         * Fill in the id of the logical volume to be deleted and
         * call lvm_deletelv() to delete the logical volume.
         */
  
        lid.minor_num    = MINOR2;
        lid.vg_id.word1  = cvg.vg_id.word1;
        lid.vg_id.word2  = cvg.vg_id.word2;
        rc = lvm_deletelv(&lid);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         *  Fill in the physical partition structure for the other 
         *  logical volume that is being reduced.
         */
 
        pps1[0].pv_id            = pv1;
        pps1[0].lp_num   = 1;
        pps1[0].pp_num   = 1;
 
        pps1[1].pv_id            = pv1;
        pps1[1].lp_num   = 2;
        pps1[1].pp_num   = 2;
 
        e_r.parts                = pps1;
        
        /*
         *  The size field should correspond to the number of  
         *  physical partitions being reduced, in this case two.
         */
 
        e_r.size = 2;
 
        lid.minor_num            = MINOR1;
        lid.vg_id.word1  = cvg.vg_id.word1;
        lid.vg_id.word2  = cvg.vg_id.word2;
 
        /*
         *  Call lvm_reducelv() to reduce the logical volume.
         */ 
 
        rc = lvm_reducelv(&lid, &e_r);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         * Fill in the id for the logical volume to be  
         * deleted and call lvm_deletelv() to delete it from 
         * the volume group.
         */
 
        lid.minor_num    = MINOR1;
        lid.vg_id.word1  = cvg.vg_id.word1;
        lid.vg_id.word2  = cvg.vg_id.word2;
        rc = lvm_deletelv(&lid);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         * Call lvm_deletepv() to delete a physical volume  
         * from the volume group.
         */
 
        rc = lvm_deletepv(&(cvg.vg_id), &pv2);
        if(rc < SUCCESS)
          return(rc);
 
        /*
         *  Call lvm_deletepv() to delete the last 
         *  physical volume from the volume group. Because we are
         *  deleting the last physical volume in the volume group,            *  the volume group itself will also be deleted.
         */
 
        rc = lvm_deletepv(&(cvg.vg_id), &pv1);
        if(rc < SUCCESS)
          return(rc);
 
        return SUCCESS;
}

[ Previous | Next | Contents | Glossary | Home | Search ]