From Fedora Project Wiki
High Level API Proposal
/********************************* lvm handle ********************************/ /* * lvm_handle_t */ struct lib_context; /* internal context data */ typedef struct lib_context *lvm_handle_t; /* * lvm_create * * Description: Create an LVM handle used in many other APIs. * Parameters: system directory: path or NULL * Returns: NULL: Fail - unable to initialise handle. * non-NULL: Success - valid LVM handle returned */ lvm_handle_t lvm_create(const char *system_dir); /* * lvm_destroy * * Description: Destroy an LVM handle allocated with lvm_create * Parameters: libh (IN): handle obtained from lvm_create */ int lvm_destroy(lvm_handle_t libh); /* * lvm_mknodes * * Description: (Re)Create device nodes for volume path. * The volume path can be a volume group, logical volume or NULL. * If volume is NULL, then all devides will be (re)created. * Parameters: libh (IN): handle obtained from lvm_create * Returns: Status */ int lvm_mknodes(lvm_handle_t libh, const char *volume); /****************************** physical volume ******************************/ /* * The lvm physical volume object. */ struct lvm_pv_obj; typedef struct lvm_pv_obj *lvm_pv_obj_t; /* with mode inside (r/rw) */ /* * The lvm physical volume object list. */ typedef struct lvm_pv_list { dm_list list; lvm_pv_obj_t obj; } *lvm_pv_list_t; /* * lvm_pv_obj_get * * Description: Get object for a physical volume by volume path * Retuns: lvm_pv_obj_t on success, otherwide NULL. errno is used to * indicate the error. * Parameters: phys_vol: device * mode: "r" or "rw" */ lvm_pv_obj_t lvm_pv_obj_get(lvm_handle_t libh, const char *phys_vol, const char *mode); /* * Returns list of physical volumes. * Retuns lvm_pv_obj_list_t on success, otherwide NULL. errno is used to * indicate the error. The objects are read only. */ lvm_pv_obj_list_t lvm_pv_obj_list(lvm_handle_t libh); /* rescan arg? */ /* lvm_pv_obj_list_t lvm_pv_obj_scan(lvm_handle_t libh); */ /* * Creates object for a physical volume path. "Object is readonly."? * Retuns lvm_pv_obj_t on success, otherwide NULL. errno is used to indicate * the error. */ lvm_pv_obj_t lvm_pv_obj_create(lvm_handle_t libh, const char *phys_vol); /* * Write physical volume obj to disk. * Returns error code (see errno). */ int lvm_pv_obj_write(lvm_pv_obj_t pv_obj); /* * Closes and frees obj. */ int lvm_pv_obj_close(lvm_pv_obj_t pv_obj); /* * Closes and frees obj list. */ int lvm_pv_obj_list_close(lvm_pv_obj_list_t pv_obj_list); /* * Accessors and mutators for object attributes in memory. */ int lvm_pv_obj_set_attribute(lvm_pv_obj_t pv_obj, const char *attribute, void *value); void* lvm_pv_obj_get_attribute(lvm_pv_obj_t pv_obj, const char *attribute); /* * Removes physical volume. */ int lvm_pv_obj_remove(lvm_pv_obj_t pv_obj); #ifdef FUTURE_FEATURE /* * Checks physical volume metadata for consistency. */ int lvm_pv_obj_check(lvm_pv_obj_t pv_obj); /* * Loads physical volume attributes from a file using the UUID. * Use lvm_pv_obj_write afterwards. */ lvm_pv_obj_t lvm_pv_obj_load_from(const char *uuid, const char *restore_file); #endif /* FUTURE_FEATURE */ /******************************* volume group ********************************/ /* * The lvm volume group object. */ struct lvm_vg_obj; typedef struct lvm_vg_obj *lvm_vg_obj_t; /* with mode inside (r/rw) */ /* * The lvm volume group object list. */ typedef struct lvm_vg_list { dm_list list; lvm_vg_obj_t obj; } *lvm_vg_list_t; /* * Gets object for a volume group by volume group name * Retuns lvm_vg_obj_t on success, otherwide NULL. errno is used to indicate * the error. * mode: "r" or "rw" */ lvm_vg_obj_t lvm_vg_obj_get(lvm_handle_t libh, const char *vol_group, const char *mode); /* * Returns list of volumes groups. * Retuns lvm_vg_obj_list_t on success, otherwide NULL. errno is used to * indicate the error. The objects are read only. */ lvm_vg_obj_list_t lvm_vg_obj_list(lvm_handle_t libh); /* rescan arg? */ /* lvm_vg_obj_list_t lvm_vg_obj_scan(lvm_handle_t libh); */ /* * Creates object for a physical volume path. "Object is readonly."? * Retuns lvm_pv_obj_t on success, otherwide NULL. errno is used to indicate * the error. */ lvm_vg_obj_t lvm_vg_obj_create(lvm_handle_t libh, const char *vol_group, lvm_pv_obj_t pv_obj); /* * Write volume group obj to disk. * Returns error code (see errno). */ int lvm_vg_obj_write(lvm_vg_obj_t vg_obj); /* * Closes and frees obj. */ int lvm_vg_obj_close(lvm_vg_obj_t vg_obj); /* * Closes and frees obj list. */ int lvm_vg_obj_list_close(lvm_vg_obj_list_t vg_obj_list); /* * Accessors and mutators for object attributes in memory. */ int lvm_vg_obj_set_attribute(lvm_vg_obj_t vg_obj, const char *attribute, void *value); void* lvm_vg_obj_get_attribute(lvm_vg_obj_t vg_obj, const char *attribute); /* * Removes volume group. */ int lvm_vg_obj_remove(lvm_vg_obj_t vg_obj); /* * List physical volumes in volume group. */ lvm_pv_obj_list_t lvm_vg_obj_list_pvs(lvm_vg_obj_t vg_obj); /* * Extend volume group by physical volume. */ int lvm_vg_obj_add_pv(lvm_vg_obj_t vg_obj, lvm_pv_obj_t pv_obj); /* * Remove physical volume from volume group. */ int lvm_vg_obj_remove_pv(lvm_vg_obj_t vg_obj, lvm_pv_obj_t pv_obj); /* * Activate physical volume. */ int lvm_vg_obj_activate(lvm_vg_obj_t vg_obj); /* * Deactivate physical volume. */ int lvm_vg_obj_deactivate(lvm_vg_obj_t vg_obj); /* * Check if physical volume is active. */ int lvm_vg_obj_is_active(lvm_vg_obj_t vg_obj); /****************************** logical volume *******************************/ struct lvm_lv_obj; typedef struct lvm_lv_obj *lvm_lv_obj_t; /* with mode inside (r/rw) */ typedef struct lvm_lv_list { dm_list list; lvm_lv_obj_t obj; } *lvm_lv_list_t; lvm_lv_obj_t lvm_lv_obj_get(lvm_handle_t libh, const char *logical_vol, const char *mode); lvm_lv_obj_list_t lvm_lv_obj_list(lvm_handle_t libh); /* rescan arg? */ /* lvm_lv_obj_list_t lvm_lv_obj_scan(lvm_handle_t libh); */ lvm_lv_obj_t lvm_lv_obj_create(lvm_handle_t libh, const char *logical_vol, lvm_vg_obj_t vg_obj); int lvm_lv_obj_write(lvm_lv_obj_t lv_obj); int lvm_lv_obj_close(lvm_lv_obj_t lv_obj); int lvm_lv_obj_list_close(lvm_lv_obj_list_t lv_obj_list); int lvm_lv_obj_set_attribute(lvm_lv_obj_t lv_obj, const char *attribute, void *value); void* lvm_lv_obj_get_attribute(lvm_lv_obj_t lv_obj, const char *attribute); int lvm_lv_obj_remove(lvm_lv_obj_t lv_obj); /********************************* examples ********************************** Example 1 --------- lvm_handle_t handle; lvm_pv_obj_t pv_obj; handle = lvm_create(NULL); pv_obj = lvm_pv_obj_get(handle, "/dev/sda1", "r"); if (pv_obj == NULL) { fprintf(stderr, strerror(errno)); lvm_destroy(handle); exit(-1); } printf("PV Name: '%s'\n", lvm_pv_obj_get_attribute(pv_obj, "pv_name")); printf("VG Name: '%s'\n", lvm_pv_obj_get_attribute(pv_obj, "vg_name")); lvm_pv_obj_close(pv_obj); lvm_destroy(handle); Example 2 --------- lvm_handle_t handle; lvm_pv_obj_t pv_obj; handle = lvm_create(NULL); pv_obj = lvm_pv_obj_create(handle, "/dev/sda2"); if (pv_obj == NULL) { fprintf(stderr, strerror(errno)); lvm_destroy(handle); exit(-1); } status = lvm_pv_obj_set_attribute(pv_obj, "uuid", "FOOBAR"); if (status == -1) { fprintf(stderr, "UUID is not valid.\n"); lvm_pv_obj_close(pv_obj); lvm_destroy(handle); exit(-1); } status = lvm_pv_obj_write(pv_obj); if (status == -1) { fprintf(stderr, "Creation of device failed.\n"); lvm_pv_obj_close(pv_obj); lvm_destroy(handle); exit(-1); } lvm_pv_obj_close(pv_obj); lvm_destroy(handle); Example 3 --------- lvm_handle_t handle; lvm_pv_obj_list_t pv_obj_list; lvm_pv_obj_t pv_obj; handle = lvm_create(NULL); pv_obj_list = lvm_pv_obj_list(handle); if (pv_obj_list == NULL) { fprintf(stderr, strerror(errno)); lvm_destroy(handle); exit(-1); } /*TODO: dm_list_iterate_items ... */ lvm_pv_obj_close(pv_obj); lvm_destroy(handle); ******************************************************************************* ANACONDA: --------- pvcreate: pvcreate -ff -y -v <node> pvlist: pvdisplay -C --noheadings --units b --nosuffix --separator : \ --options pv_name,vg_name,dev_size returns: [(dev, vg, size)] vgactivate: vgchange -ay -v [<volgroup>] vgmknodes(volgroup) vgcreate: vgcreate -v -An --physicalextentsize <PESize>k <vgname> <nodes> vgcheckactive: lvs --noheadings --units b --nosuffix --separator : \ --options vg_name,lv_name,attr returns: True if there is an active logical volume, else False vgdeactivate: vgchange -an -v [<volgroup>] vglist: vgdisplay -C --noheadings --units b --nosuffix --separator : \ --options vg_name,vg_size,vg_extent_size returns: [(vg, size, pesize)] vgmknodes: vgmknodes -v [<volgroup>] vgremove: pvs = [ pv[0] for pv in pvlist() if pv[1] == vgname ] vgdeactivate(vgname) vgremove -v vgname for pvname in pvs: pvremove -ff -y -v pvname pvcreate -ff -y -v pvname wipeOtherMetadataFromPV(pvname) vgscan: vgscan -v lvcreate: vgscan() lvcreate -v -L <size>M -n <lvname> -An <vgname> lvlist: lvdisplay -C --noheadings --units b --nosuffix --separator : \ --options vg_name,lv_name,lv_size,origin returns: [(vg, lv, size, origin)] lvremove: lvremove -f -v /dev/<vgname>/<lvname> partialvgs: vgdisplay -C -P --noheadings --units b --nosuffix --separator : returns: [(vg)] if vgs are partial ******************************************************************************/