LVM/liblvm/api
From FedoraProject
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
******************************************************************************/