/* 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; }