lvm2app: Implementation of pv resize (v4)
PATCH 1/3 lvm2app: Implementation of pv resize (v4)
Patch correctly checks for update lock before allowing resize to process and also requires lvm_vg_write to make changes persistent. As the API does not allow the re-size of a orphaned pv this is accomplished through the existing vg_write, vg_commit sequence which is done in lvm_vg_write.
--- lib/metadata/metadata-exported.h | 8 +++++-- lib/metadata/pv_manip.c | 48 +++++++++++++++++++++++++++++++++++++++- liblvm/lvm2app.h | 5 +++-- liblvm/lvm_pv.c | 21 ++++++++++++++---- tools/pvresize.c | 26 +--------------------- 5 files changed, 74 insertions(+), 34 deletions(-)
lib/metadata/metadata-exported.h +6 -2
@@ -482,8 +482,12 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,unsigned pvmetadatacopies, uint64_t pvmetadatasize, unsigned metadataignore); -int pv_resize (struct physical_volume *pv,struct volume_group *vg, -uint64_t size); + +int pv_resize (struct cmd_context *cmd, +struct volume_group *vg, +struct physical_volume *pv, +const uint64_t new_size); +int pv_analyze (struct cmd_context *cmd,const char *pv_name,uint64_t label_sector);
lib/metadata/pv_manip.c +47 -1
63 lines not on this page · raw message
liblvm/lvm2app.h +3 -2
@@ -1624,9 +1624,10 @@ pv_t lvm_pv_from_uuid(vg_t vg, const char *uuid);/** * Resize physical volume to new_size bytes. * -* \memberof pv_t +* Note: Make sure to do a lvm_vg_write on the containing vg to save the +* new size. * -* NOTE: This function is currently not implemented. +* \memberof pv_t * * \param pv * Physical volume handle.
liblvm/lvm_pv.c +17 -4
@@ -120,10 +120,23 @@ pv_t lvm_pv_from_uuid(vg_t vg, const char *uuid)return NULL ; } -int lvm_pv_resize (const pv_t pv,uint64_t new_size) { -/* FIXME: add pv resize code here */ -log_error ("NOT IMPLEMENTED YET" ); -return -1 ; +uint64_t size = new_size >>SECTOR_SHIFT ; + +if (new_size %SECTOR_SIZE ) { +log_errno (EINVAL ,"Size not a multiple of 512" ); +return -1 ; + } + +if (!vg_check_write_mode (pv->vg)) { +return -1 ; + } + +if (!pv_resize (pv->vg->cmd, pv->vg, pv, size)) { +log_error ("PV re-size failed!" ); +return -1 ; + }else { +return 0 ; + } }
tools/pvresize.c +1 -25
@@ -30,7 +30,6 @@ static int _pv_resize_single(struct cmd_context *cmd, const uint64_t new_size) {struct pv_list *pvl; -uint64_t size =0 ;int r =0 ;const char *pv_name =pv_dev_name (pv);const char *vg_name =pv_vg_name (pv);
@@ -70,33 +69,10 @@ static int _pv_resize_single(struct cmd_context *cmd, goto out; } -if (!(pv->fmt->features &FMT_RESIZE_PV )) { -log_error ("Physical volume %s format does not support resizing." , - pv_name); - goto out; - } - -/* Get new size */ -if (!dev_get_size (pv_dev (pv), &size)) { -log_error ("%s: Couldn't get size." , pv_name); +if ( !pv_resize (cmd, vg, pv, new_size)) { goto out; } -if (new_size) { -if (new_size > size) -log_warn ("WARNING: %s: Overriding real size. " -"You could lose data." , pv_name); -log_verbose ("%s: Pretending size is %" PRIu64" not %" PRIu64 -" sectors." , pv_name, new_size,pv_size (pv)); - size = new_size; - } - -log_verbose ("Resizing volume \"%s\" to %" PRIu64" sectors." , - pv_name,pv_size (pv)); - -if (!pv_resize (pv, vg, size)) - goto_out; -log_verbose ("Updating physical volume \"%s\"" , pv_name);/* Write PV label only if this an orphan PV or it has 2nd mda. */
Signature · 1 line
1.7.11.7
PATCH 2/3 lvm2app: Implementation of lv resize (v1)
When re-sizing a LV with the command line, after the re-size occurs the code used to do a vg_write and then a number of operations before and after the commit. As the API requires the ability to have the re-size done independantly of the write and commit a flag was added so that when we go through vg_commit we will do the same required steps to commit the lv size change regardless if it was done through the command line or the API.
The core functionality was moved to lv_manip so that the command line and the API could call it. To make this work all the argument parsing functions are being done in tools/lv_resize.c and all the parameters are expected to be passed in with the struct lvresize_params.
--- lib/format_text/flags.c | 1 + lib/metadata/lv_manip.c | 665 ++++++++++++++++++++++++++++++++ lib/metadata/metadata-exported.h | 76 +++- lib/metadata/metadata.c | 91 ++++- lib/misc/lvm-percent.c | 5 + lib/misc/lvm-percent.h | 2 + liblvm/lvm2app.h | 2 - liblvm/lvm_lv.c | 19 +- tools/lvresize.c | 811 +++------------------------------------ tools/toollib.c | 6 - tools/tools.h | 17 - 11 files changed, 906 insertions(+), 789 deletions(-)
lib/format_text/flags.c +1 -0
@@ -77,6 +77,7 @@ static const struct flag _lv_flags[] = { {THIN_POOL, NULL, 0}, {THIN_POOL_DATA, NULL, 0}, {THIN_POOL_METADATA, NULL, 0}, + {LV_RESIZE, NULL, 0}, {0, NULL, 0} };
lib/metadata/lv_manip.c +665 -0
677 lines not on this page · raw message
lib/metadata/metadata-exported.h +75 -1
101 lines not on this page · raw message
lib/metadata/metadata.c +90 -1
111 lines not on this page · raw message
lib/misc/lvm-percent.c +5 -0
@@ -38,3 +38,8 @@ percent_t make_percent(uint64_t numerator, uint64_t denominator) } } +uint32_t percent_of_extents (uint32_t percents,uint32_t count,int roundup) +{ +return (uint32_t )(((uint64_t )percents * (uint64_t )count + + ((roundup) ?99 :0 )) /100 ); +}
lib/misc/lvm-percent.h +2 -0
@@ -41,4 +41,6 @@ typedef enum {float percent_to_float (percent_t v);percent_t make_percent (uint64_t numerator,uint64_t denominator); +uint32_t percent_of_extents (uint32_t percents,uint32_t count,int roundup); +#endif
liblvm/lvm2app.h +0 -2
@@ -1365,8 +1365,6 @@ int lvm_lv_rename(lv_t lv, const char *new_name);* * \memberof lv_t * -* NOTE: This function is currently not implemented. -* * \param lv * Logical volume handle. *
liblvm/lvm_lv.c +16 -3
@@ -309,9 +309,22 @@ int lvm_lv_rename(lv_t lv, const char *new_name)int lvm_lv_resize (const lv_t lv,uint64_t new_size) { -/* FIXME: add lv resize code here */ -log_error ("NOT IMPLEMENTED YET" ); -return -1 ; +struct lvresize_params lp = {0 }; + + lp.vg_name = lv->vg->name; + lp.lv_name = lv->name; + lp.sign =SIGN_NONE ; + lp.percent =PERCENT_NONE ; + lp.resize =LV_ANY ; + lp.size = new_size >>SECTOR_SHIFT ; + lp.ac_force =1 ;/* Assume the user has a good backup? */ + +if (ECMD_PROCESSED !=lv_resize (lv->vg->cmd, lv->vg, &lp, &lv->vg->pvs)) { +log_verbose ("LV Re-size failed." ); +return -1 ; + } + +return 0 ; }lv_t lvm_lv_snapshot (const lv_t lv,const char *snap_name,uint64_t max_snap_size)
tools/lvresize.c +52 -759
853 lines not on this page · raw message
tools/toollib.c +0 -6
@@ -1814,9 +1814,3 @@ int change_tag(struct cmd_context *cmd, struct volume_group *vg,return 1 ; } -/* Return percents of extents and avoid overflow, with optional roundup */ -uint32_t percent_of_extents (uint32_t percents,uint32_t count,int roundup) -{ -return (uint32_t )(((uint64_t )percents * (uint64_t )count + - ((roundup) ?99 :0 )) /100 ); -}
tools/tools.h +0 -17
@@ -34,7 +34,6 @@#include "dev-cache.h" #include "device.h" #include "display.h" -#include "errors.h" #include "filter.h" #include "filter-composite.h" #include "filter-persistent.h"
@@ -73,21 +72,6 @@ enum {#undef arg }; -typedef enum { -SIGN_NONE =0 , -SIGN_PLUS =1 , -SIGN_MINUS =2 -}sign_t ; - -typedef enum { -PERCENT_NONE =0 , -PERCENT_VG , -PERCENT_FREE , -PERCENT_LV , -PERCENT_PVS , -PERCENT_ORIGIN -}percent_type_t ; -#define ARG_COUNTABLE 0x00000001/* E.g. -vvvv */ #define ARG_GROUPABLE 0x00000002/* E.g. --addtag */
@@ -187,7 +171,6 @@ int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv, unsignedint mirror_remove_missing (struct cmd_context *cmd,struct logical_volume *lv,int force); -uint32_t percent_of_extents (uint32_t percents,uint32_t count,int roundup);int vgchange_activate (struct cmd_context *cmd,struct volume_group *vg,activation_change_t activate);
Signature · 1 line
1.7.11.7
PATCH 2/3 lvm2app: Implementation of lv resize (v1)
Dne 7.1.2013 22:02, Tony Asleson napsal(a):
Quoted 9 lines
When re-sizing a LV with the command line, after the re-size occurs the code used to do a
vg_writeand then a number of operations before and after the commit. As the API requires the ability to have the re-size done independantly of the write and commit a flag was added so that when we go throughvg_commitwe will do the same required steps to commit the lv size change regardless if it was done through the command line or the API.
Quoted 6 lines
The core functionality was moved to
lv_manipso that the command line and the API could call it. To make this work all the argument parsing functions are being done intools/lv_resize.cand all the parameters are expected to be passed in with the structlvresize_params.
I'd prefer here to see separate patches which are
just moving code and then new patches for changes
of moved code.
Quoted 40 lines
Signed-off-by Tony Asleson <[email protected]>--- lib/format_text/flags.c | 1 + lib/metadata/lv_manip.c | 665 ++++++++++++++++++++++++++++++++ lib/metadata/metadata-exported.h | 76 +++- lib/metadata/metadata.c | 91 ++++- lib/misc/lvm-percent.c | 5 + lib/misc/lvm-percent.h | 2 + liblvm/lvm2app.h | 2 - liblvm/lvm_lv.c | 19 +- tools/lvresize.c | 811 +++------------------------------------ tools/toollib.c | 6 - tools/tools.h | 17 - 11 files changed, 906 insertions(+), 789 deletions(-)lib/format_text/flags.c +1
-0@@ -77,6 +77,7 @@ static const struct flag _lv_flags[] = { {THIN_POOL, NULL, 0}, {THIN_POOL_DATA, NULL, 0}, {THIN_POOL_METADATA, NULL, 0}, + {LV_RESIZE, NULL, 0}, {0, NULL, 0} };lib/metadata/lv_manip.c +1
-0@@ -27,6 +27,7 @@#include "activate.h" #include "str_list.h" #include "defaults.h" +#include "lvm-exec.h" typedef enum { PREFERRED,
lib/metadata/lv_manip.c int lv_rename(struct cmd_context *cmd, struct logical_volume *lv, · line 3045
Quoted 4 lines
lib/metadata/lv_manip.c +1
-0@@ -3041,6 +3042,670 @@ int lv_rename(struct cmd_context *cmd, struct logical_volume *lv,return lv_rename_update (cmd, lv, new_name,1 ); } +static uint32_t lvseg_get_stripes (struct lv_segment *seg,uint32_t *stripesize)
After moving code - try to add '_' prefixes to internal 'static' functions.
Quoted 4 lines
lib/metadata/lv_manip.c +4
-0+/* We could have been called after an error has occurred, in that +case we will not do the next step */ +if (ok) { +
lib/metadata/lv_manip.c int lv_rename(struct cmd_context *cmd, struct logical_volume *lv, · line 3059
Quoted 10 lines
lib/metadata/lv_manip.c +10
-0+/* +* Update lvm pool metadata (drop messages) if the pool has been +* resumed and do a pool active/deactivate in other case. +* +* Note: Active thin pool can be waiting for resize. +* +* FIXME: Activate only when thin volume is active +*/ +if (lv_is_thin_pool (lvl->lv) && + !update_pool_lv (lvl->lv, !lv_is_active (lvl->lv))) {
alignment
lib/metadata/lv_manip.c int lv_rename(struct cmd_context *cmd, struct logical_volume *lv, · line 3061
Quoted 2 lines
lib/metadata/lv_manip.c +2
-0+ stack; +return 0 ;
we have macro shortcut - return_0;
Quoted 16 lines
lib/metadata/lv_manip.c +9
-0+ } + } + } + } + +return 1 ; +} + +/* Commit pending changes */ int vg_commit (struct volume_group *vg) {@@ -2714,9 +2788,15 @@ int vg_commit(struct volume_group *vg)return cache_updated; }
lib/metadata/lv_manip.c int vg_commit(struct volume_group *vg) · line 2799
Quoted 10 lines
lib/metadata/lv_manip.c +7
-1+if (!_pre_lv_resize (vg)) + return_0; +/* Skip if we already did this in vg_write */ if ((vg->fid->fmt->features &FMT_PRECOMMIT ) && !lvmetad_vg_update (vg)) - return_0; + { + cache_updated =0 ; + goto out; + }
goto_out
Quoted 5 lines
lib/metadata/lv_manip.c +0
-0cache_updated =_vg_commit_mdas (vg);@@ -2736,6 +2816,15 @@ int vg_commit(struct volume_group *vg) log_error("Attempt to drop cached metadata failed "
lib/metadata/lv_manip.c int vg_commit(struct volume_group *vg) · line 2826
Quoted 10 lines
lib/metadata/lv_manip.c +8
-0"after commit for VG %s.", vg->name); +out: +if (!_post_lv_resize (vg, cache_updated)) { + cache_updated =0 ; + } + +if (!cache_updated) { + stack; + }
{} around single commands unneeded
Zdenek
PATCH 2/3 lvm2app: Implementation of lv resize (v1)
Quoted 3 lines · Zdenek Kabelac
I'd prefer here to see separate patches which are
just moving code and then new patches for changes
of moved code.
New patch set submitted. Some changes needed to occur to allow the code to be moved. This is broken down step by step. Hopefully this will make it easier to see what is going on.
Quoted 2 lines
After moving code - try to add '_' prefixes to internal 'static' functions.
OK
Quoted 1 line
we have macro shortcut -
return_0;
Using it now.
Quoted 1 line
goto_out
Using this too...
Quoted 1 line
{} around single commands unneeded
OK
Thanks,
Tony
PATCH 3/3 python-lvm: Add ability to disable vg auto write (v1)
In reply to Tony AslesonPreviously, whenever changes were made to volume groups the changes were immediately written out and committed. With this change the user has the ability to turn off this behavior and manually save the changes for the vg. A new method lvm.vgAutoWrite(bool) has been added to control this behavior. Default behavior matches previous behavior, implicit calls to lvm_vg_write.
--- python/liblvm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 11 deletions(-)
python/liblvm.c +79 -11
@@ -26,6 +26,9 @@static lvm_t libh; +/*Determines if we should write out changes automatically for vg state change*/ +static int auto_vg_write; + typedef struct { PyObject_HEAD
@@ -88,6 +91,14 @@ liblvm_get_last_error(void)return info; } +static int lvm_vg_write_auto (vg_t vg) +{ +if (auto_vg_write) { +return lvm_vg_write (vg); + } +return 0 ; +} +static PyObject *liblvm_library_get_version (void ) {
@@ -152,6 +163,27 @@ liblvm_lvm_list_vg_uuids(void)return pytuple; } +/* Return the previous value, set current to passed in */ +static PyObject * +liblvm_lvm_vg_autowrite (PyObject *self,PyObject *arg) +{ +PyObject *prev =NULL ; +int rval =0 ; +int bool =0 ; + +LVM_VALID (); + +/* In later version of python they introduced "p" */ +if (!PyArg_ParseTuple (arg,"i" , &bool)) +return NULL ; + + prev = (auto_vg_write) ? Py_True : Py_False; +Py_INCREF (prev); + auto_vg_write = bool; + +return prev; +} +static PyObject *liblvm_lvm_percent_to_float (PyObject *self,PyObject *arg) {
@@ -374,6 +406,32 @@ liblvm_lvm_vg_close(vgobject *self) }static PyObject * +liblvm_lvm_vg_write (vgobject *self) +{ +int rval; + +VG_VALID (self); + +if (!auto_vg_write) { + rval =lvm_vg_write (self->vg); +if (-1 == rval) { +PyErr_SetObject (LibLVMError,liblvm_get_last_error ()); +return NULL ; + }else { +Py_INCREF (Py_None); +return Py_None; + } + } + +/* +* Can't call this function directly if we have auto vg write +* enabled +*/ +PyErr_SetString (PyExc_ValueError,"lvm.vgAutoWrite() == True" ); \ +return NULL ; +} + +static PyObject *liblvm_lvm_vg_get_name (vgobject *self) {VG_VALID (self);
@@ -400,14 +458,17 @@ liblvm_lvm_vg_remove(vgobject *self)if ((rval =lvm_vg_remove (self->vg)) ==-1 ) goto error; -if (lvm_vg_write (self->vg) ==-1 ) - goto error; +/* If we aren't writing out the change leave the object ref. alone */ +if (auto_vg_write) { -/* Not much you can do with a vg that is removed so close it */ -if (lvm_vg_close (self->vg) ==-1 ) - goto error; +if (lvm_vg_write (self->vg) ==-1 ) + goto error; - self->vg =NULL ; +if (lvm_vg_close (self->vg) ==-1 ) + goto error; + + self->vg =NULL ; + }Py_INCREF (Py_None);return Py_None;
@@ -432,8 +493,9 @@ liblvm_lvm_vg_extend(vgobject *self, PyObject *args)if ((rval =lvm_vg_extend (self->vg, device)) ==-1 ) goto error; -if (lvm_vg_write (self->vg) ==-1 ) +if (lvm_vg_write_auto (self->vg) ==-1 ) { goto error; + }Py_INCREF (Py_None);return Py_None;
@@ -458,8 +520,9 @@ liblvm_lvm_vg_reduce(vgobject *self, PyObject *args)if ((rval =lvm_vg_reduce (self->vg, device)) ==-1 ) goto error; -if (lvm_vg_write (self->vg) ==-1 ) +if (lvm_vg_write_auto (self->vg) ==-1 ) { goto error; + }Py_INCREF (Py_None);return Py_None;
@@ -483,8 +546,9 @@ liblvm_lvm_vg_add_tag(vgobject *self, PyObject *args)if ((rval =lvm_vg_add_tag (self->vg, tag)) ==-1 ) goto error; -if (lvm_vg_write (self->vg) ==-1 ) +if (lvm_vg_write_auto (self->vg) ==-1 ) { goto error; + }return Py_BuildValue ("i" , rval);
@@ -508,8 +572,9 @@ liblvm_lvm_vg_remove_tag(vgobject *self, PyObject *args)if ((rval =lvm_vg_remove_tag (self->vg, tag)) ==-1 ) goto error; -if (lvm_vg_write (self->vg) ==-1 ) +if (lvm_vg_write_auto (self->vg) ==-1 ) { goto error; + }Py_INCREF (Py_None);return Py_None;
@@ -731,7 +796,7 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) goto lvmerror; } -if (lvm_vg_write (self->vg) ==-1 ) { +if (lvm_vg_write_auto (self->vg) ==-1 ) { goto lvmerror; }
@@ -1553,6 +1618,7 @@ static PyMethodDef Liblvm_methods[] = { { "percentToFloat", (PyCFunction)liblvm_lvm_percent_to_float, METH_VARARGS }, { "vgNameFromPvid", (PyCFunction)liblvm_lvm_vgname_from_pvid, METH_VARARGS }, { "vgNameFromDevice", (PyCFunction)liblvm_lvm_vgname_from_device, METH_VARARGS }, + { "vgAutoWrite", (PyCFunction)liblvm_lvm_vg_autowrite, METH_VARARGS }, { NULL, NULL } /* sentinel */ };
@@ -1589,6 +1655,7 @@ static PyMethodDef liblvm_vg_methods[] = { { "pvFromUuid", (PyCFunction)liblvm_lvm_pv_from_uuid, METH_VARARGS }, { "getTags", (PyCFunction)liblvm_lvm_vg_get_tags, METH_NOARGS }, { "createLvLinear", (PyCFunction)liblvm_lvm_vg_create_lv_linear, METH_VARARGS }, + { "write", (PyCFunction)liblvm_lvm_vg_write, METH_VARARGS }, { NULL, NULL } /* sentinel */ };
@@ -1704,6 +1771,7 @@ initlvm(void) {PyObject *m; + auto_vg_write =1 ; libh =lvm_init (NULL );if (PyType_Ready (&LibLVMvgType) <0 )
Signature · 1 line
1.7.11.7
PATCH 1/3 lvm2app: Implementation of pv resize (v4)
In reply to Tony AslesonDne 7.1.2013 22:02, Tony Asleson napsal(a):
Quoted 35 lines
Patch correctly checks for update lock before allowing resize to process and also requires
lvm_vg_writeto make changes persistent. As the API does not allow the re-size of a orphaned pv this is accomplished through the existingvg_write,vg_commitsequence which is done inlvm_vg_write.Signed-off-by Tony Asleson <[email protected]>--- lib/metadata/metadata-exported.h | 8 +++++-- lib/metadata/pv_manip.c | 48 +++++++++++++++++++++++++++++++++++++++- liblvm/lvm2app.h | 5 +++-- liblvm/lvm_pv.c | 21 ++++++++++++++---- tools/pvresize.c | 26 +--------------------- 5 files changed, 74 insertions(+), 34 deletions(-)tools/pvresize.c +0
-4@@ -30,7 +30,6 @@ static int _pv_resize_single(struct cmd_context *cmd, const uint64_t new_size) {struct pv_list *pvl; -uint64_t size =0 ;int r =0 ;const char *pv_name =pv_dev_name (pv);const char *vg_name =pv_vg_name (pv);@@ -70,33 +69,10 @@ static int _pv_resize_single(struct cmd_context *cmd, goto out; } -if (!(pv->fmt->features &FMT_RESIZE_PV )) { -log_error ("Physical volume %s format does not support resizing." , - pv_name);
tools/pvresize.c static int _pv_resize_single(struct cmd_context *cmd, · line 75
Quoted 10 lines
tools/pvresize.c +1
-6- goto out; - } - -/* Get new size */ -if (!dev_get_size (pv_dev (pv), &size)) { -log_error ("%s: Couldn't get size." , pv_name); +if ( !pv_resize (cmd, vg, pv, new_size)) { goto out; }
To get nicer backtrace logging - goto_out;
Zdenek