1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-06-08 11:16:54 +03:00

python-lvm: Ensure library handle is correct after python gc() call

In a previous commit we added the ability for the library to do garbage
collection, to free all the memory used by the library handle buffer by closing
and re-opening the library handle.  When we introduced this functionality we
also opened up the opportunity that the user of the python bindings to have
an object that references the old library handle.  In this case if the user
tried to use the old object a segmentation fault could occur because the
memory had been previously freed.

This patch tries to mitigate this by storing a copy of the library handle that
was used when the object was created so that it can compare the current in
use pointer with what existed when the object was created.  In the case where
they match the operation is permitted to continue, otherwise an exception is
throw, thus avoiding a segmentation fault.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
This commit is contained in:
Tony Asleson 2013-07-31 15:16:01 -05:00
parent 1f744733a1
commit 20ffb0f721

View File

@ -30,11 +30,13 @@ static lvm_t _libh;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
vg_t vg; /* vg handle */ vg_t vg; /* vg handle */
lvm_t libh_copy;
} vgobject; } vgobject;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
struct dm_list *pvslist; struct dm_list *pvslist;
lvm_t libh_copy;
} pvslistobject; } pvslistobject;
typedef struct { typedef struct {
@ -71,9 +73,14 @@ static PyTypeObject _LibLVMpvsegType;
static PyObject *_LibLVMError; static PyObject *_LibLVMError;
#define LVM_VALID() \ #define LVM_VALID(ptr) \
do { \ do { \
if (!_libh) { \ if (ptr && _libh) { \
if (ptr != _libh) { \
PyErr_SetString(PyExc_UnboundLocalError, "LVM handle reference stale"); \
return NULL; \
} \
} else if (!_libh) { \
PyErr_SetString(PyExc_UnboundLocalError, "LVM handle invalid"); \ PyErr_SetString(PyExc_UnboundLocalError, "LVM handle invalid"); \
return NULL; \ return NULL; \
} \ } \
@ -99,17 +106,42 @@ static vgobject *_create_py_vg(void)
{ {
vgobject *vgobj = PyObject_New(vgobject, &_LibLVMvgType); vgobject *vgobj = PyObject_New(vgobject, &_LibLVMvgType);
if (vgobj) if (vgobj) {
vgobj->vg = NULL; vgobj->vg = NULL;
vgobj->libh_copy = _libh;
}
return vgobj; return vgobj;
} }
static pvslistobject *_create_py_pvlist(void)
{
pvslistobject *pvlistobj = PyObject_New(pvslistobject, &_LibLVMpvlistType);
if (pvlistobj) {
pvlistobj->pvslist = NULL;
pvlistobj->libh_copy = _libh;
}
return pvlistobj;
}
static lvobject *_create_py_lv(vgobject *parent, lv_t lv)
{
lvobject * lvobj = PyObject_New(lvobject, &_LibLVMlvType);
if (lvobj) {
lvobj->parent_vgobj = parent;
Py_INCREF(lvobj->parent_vgobj);
lvobj->lv = lv;
}
return lvobj;
}
static PyObject *_liblvm_get_last_error(void) static PyObject *_liblvm_get_last_error(void)
{ {
PyObject *info; PyObject *info;
LVM_VALID(); LVM_VALID(NULL);
if (!(info = PyTuple_New(2))) if (!(info = PyTuple_New(2)))
return NULL; return NULL;
@ -122,7 +154,7 @@ static PyObject *_liblvm_get_last_error(void)
static PyObject *_liblvm_library_get_version(void) static PyObject *_liblvm_library_get_version(void)
{ {
LVM_VALID(); LVM_VALID(NULL);
return Py_BuildValue("s", lvm_library_get_version()); return Py_BuildValue("s", lvm_library_get_version());
} }
@ -131,7 +163,7 @@ static const char _gc_doc[] = "Garbage collect the C library";
static PyObject *_liblvm_lvm_gc(void) static PyObject *_liblvm_lvm_gc(void)
{ {
LVM_VALID(); LVM_VALID(NULL);
lvm_quit(_libh); lvm_quit(_libh);
@ -152,7 +184,7 @@ static PyObject *_liblvm_lvm_list_vg_names(void)
PyObject * pytuple; PyObject * pytuple;
int i = 0; int i = 0;
LVM_VALID(); LVM_VALID(NULL);
if (!(vgnames = lvm_list_vg_names(_libh))) { if (!(vgnames = lvm_list_vg_names(_libh))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
@ -177,7 +209,7 @@ static PyObject *_liblvm_lvm_list_vg_uuids(void)
PyObject * pytuple; PyObject * pytuple;
int i = 0; int i = 0;
LVM_VALID(); LVM_VALID(NULL);
if (!(uuids = lvm_list_vg_uuids(_libh))) { if (!(uuids = lvm_list_vg_uuids(_libh))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
@ -261,23 +293,16 @@ static PyObject *_liblvm_pvlist_dealloc(pvslistobject *self)
static PyObject *_liblvm_lvm_list_pvs(void) static PyObject *_liblvm_lvm_list_pvs(void)
{ {
pvslistobject *pvslistobj; LVM_VALID(NULL);
LVM_VALID(); return (PyObject *)_create_py_pvlist();
if (!(pvslistobj = PyObject_New(pvslistobject, &_LibLVMpvlistType)))
return NULL;
pvslistobj->pvslist = NULL;
return (PyObject *)pvslistobj;
} }
static PyObject *_liblvm_lvm_pv_remove(PyObject *self, PyObject *arg) static PyObject *_liblvm_lvm_pv_remove(PyObject *self, PyObject *arg)
{ {
const char *pv_name; const char *pv_name;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "s", &pv_name)) if (!PyArg_ParseTuple(arg, "s", &pv_name))
return NULL; return NULL;
@ -297,7 +322,7 @@ static PyObject *_liblvm_lvm_pv_create(PyObject *self, PyObject *arg)
const char *pv_name; const char *pv_name;
unsigned long long size; unsigned long long size;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "sK", &pv_name, &size)) if (!PyArg_ParseTuple(arg, "sK", &pv_name, &size))
return NULL; return NULL;
@ -317,7 +342,7 @@ static PyObject *_liblvm_lvm_percent_to_float(PyObject *self, PyObject *arg)
double converted; double converted;
int percent; int percent;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "i", &percent)) if (!PyArg_ParseTuple(arg, "i", &percent))
return NULL; return NULL;
@ -332,7 +357,7 @@ static PyObject *_liblvm_lvm_vgname_from_pvid(PyObject *self, PyObject *arg)
const char *pvid; const char *pvid;
const char *vgname; const char *vgname;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "s", &pvid)) if (!PyArg_ParseTuple(arg, "s", &pvid))
return NULL; return NULL;
@ -350,7 +375,7 @@ static PyObject *_liblvm_lvm_vgname_from_device(PyObject *self, PyObject *arg)
const char *device; const char *device;
const char *vgname; const char *vgname;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "s", &device)) if (!PyArg_ParseTuple(arg, "s", &device))
return NULL; return NULL;
@ -370,7 +395,7 @@ static PyObject *_liblvm_lvm_config_find_bool(PyObject *self, PyObject *arg)
int rval; int rval;
PyObject *rc; PyObject *rc;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "s", &config)) if (!PyArg_ParseTuple(arg, "s", &config))
return NULL; return NULL;
@ -390,7 +415,7 @@ static PyObject *_liblvm_lvm_config_find_bool(PyObject *self, PyObject *arg)
static PyObject *_liblvm_lvm_config_reload(void) static PyObject *_liblvm_lvm_config_reload(void)
{ {
LVM_VALID(); LVM_VALID(NULL);
if (lvm_config_reload(_libh) == -1) { if (lvm_config_reload(_libh) == -1) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
@ -405,7 +430,7 @@ static PyObject *_liblvm_lvm_config_reload(void)
static PyObject *_liblvm_lvm_scan(void) static PyObject *_liblvm_lvm_scan(void)
{ {
LVM_VALID(); LVM_VALID(NULL);
if (lvm_scan(_libh) == -1) { if (lvm_scan(_libh) == -1) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
@ -421,7 +446,7 @@ static PyObject *_liblvm_lvm_config_override(PyObject *self, PyObject *arg)
{ {
const char *config; const char *config;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(arg, "s", &config)) if (!PyArg_ParseTuple(arg, "s", &config))
return NULL; return NULL;
@ -447,7 +472,7 @@ static PyObject *_liblvm_lvm_vg_open(PyObject *self, PyObject *args)
vgobject *vgobj; vgobject *vgobj;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(args, "s|s", &vgname, &mode)) if (!PyArg_ParseTuple(args, "s|s", &vgname, &mode))
return NULL; return NULL;
@ -472,7 +497,7 @@ static PyObject *_liblvm_lvm_vg_create(PyObject *self, PyObject *args)
const char *vgname; const char *vgname;
vgobject *vgobj; vgobject *vgobj;
LVM_VALID(); LVM_VALID(NULL);
if (!PyArg_ParseTuple(args, "s", &vgname)) if (!PyArg_ParseTuple(args, "s", &vgname))
return NULL; return NULL;
@ -495,6 +520,7 @@ static void liblvm_vg_dealloc(vgobject *self)
if (self->vg != NULL) { if (self->vg != NULL) {
lvm_vg_close(self->vg); lvm_vg_close(self->vg);
self->vg = NULL; self->vg = NULL;
self->libh_copy = NULL;
} }
PyObject_Del(self); PyObject_Del(self);
@ -504,20 +530,20 @@ static void liblvm_vg_dealloc(vgobject *self)
#define VG_VALID(vgobject) \ #define VG_VALID(vgobject) \
do { \ do { \
LVM_VALID(); \ if (!vgobject || !vgobject->vg) { \
if (!vgobject->vg) { \
PyErr_SetString(PyExc_UnboundLocalError, "VG object invalid"); \ PyErr_SetString(PyExc_UnboundLocalError, "VG object invalid"); \
return NULL; \ return NULL; \
} \ } \
LVM_VALID(vgobject->libh_copy); \
} while (0) } while (0)
#define PVSLIST_VALID(pvslistobject) \ #define PVSLIST_VALID(pvslistobject) \
do { \ do { \
LVM_VALID(); \ if (!pvslistobject || !pvslistobject->pvslist) { \
if (!pvslistobject->pvslist) { \
PyErr_SetString(PyExc_UnboundLocalError, "PVS object invalid"); \ PyErr_SetString(PyExc_UnboundLocalError, "PVS object invalid"); \
return NULL; \ return NULL; \
} \ } \
LVM_VALID(pvslistobject->libh_copy); \
} while (0) } while (0)
static PyObject *_liblvm_lvm_vg_close(vgobject *self) static PyObject *_liblvm_lvm_vg_close(vgobject *self)
@ -526,6 +552,7 @@ static PyObject *_liblvm_lvm_vg_close(vgobject *self)
if (self->vg) { if (self->vg) {
lvm_vg_close(self->vg); lvm_vg_close(self->vg);
self->vg = NULL; self->vg = NULL;
self->libh_copy = NULL;
} }
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -941,15 +968,11 @@ static PyObject *_liblvm_lvm_vg_list_lvs(vgobject *self)
dm_list_iterate_items(lvl, lvs) { dm_list_iterate_items(lvl, lvs) {
/* Create and initialize the object */ /* Create and initialize the object */
if (!(lvobj = PyObject_New(lvobject, &_LibLVMlvType))) { if (!(lvobj = _create_py_lv(self, lvl->lv))) {
Py_DECREF(pytuple); Py_DECREF(pytuple);
return NULL; return NULL;
} }
lvobj->parent_vgobj = self;
Py_INCREF(lvobj->parent_vgobj);
lvobj->lv = lvl->lv;
PyTuple_SET_ITEM(pytuple, i, (PyObject *) lvobj); PyTuple_SET_ITEM(pytuple, i, (PyObject *) lvobj);
i++; i++;
} }
@ -986,29 +1009,19 @@ static PyObject *_liblvm_lvm_vg_create_lv_linear(vgobject *self, PyObject *args)
{ {
const char *vgname; const char *vgname;
unsigned long long size; unsigned long long size;
lvobject *lvobj; lv_t lv;
VG_VALID(self); VG_VALID(self);
if (!PyArg_ParseTuple(args, "sK", &vgname, &size)) if (!PyArg_ParseTuple(args, "sK", &vgname, &size))
return NULL; return NULL;
if (!(lvobj = PyObject_New(lvobject, &_LibLVMlvType))) if (!(lv = lvm_vg_create_lv_linear(self->vg, vgname, size))) {
return NULL;
/* Initialize the parent ptr in case lv create fails and we dealloc lvobj */
lvobj->parent_vgobj = NULL;
if (!(lvobj->lv = lvm_vg_create_lv_linear(self->vg, vgname, size))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
Py_DECREF(lvobj);
return NULL; return NULL;
} }
lvobj->parent_vgobj = self; return (PyObject *)_create_py_lv(self, lv);
Py_INCREF(lvobj->parent_vgobj);
return (PyObject *)lvobj;
} }
static PyObject *_liblvm_lvm_vg_create_lv_thinpool(vgobject *self, PyObject *args) static PyObject *_liblvm_lvm_vg_create_lv_thinpool(vgobject *self, PyObject *args)
@ -1019,7 +1032,7 @@ static PyObject *_liblvm_lvm_vg_create_lv_thinpool(vgobject *self, PyObject *arg
unsigned long chunk_size = 0; unsigned long chunk_size = 0;
int skip_zero = 0; int skip_zero = 0;
lvm_thin_discards_t discard = LVM_THIN_DISCARDS_PASSDOWN; lvm_thin_discards_t discard = LVM_THIN_DISCARDS_PASSDOWN;
lvobject *lvobj; lv_t lv;
lv_create_params_t lvp = NULL; lv_create_params_t lvp = NULL;
struct lvm_property_value prop_value; struct lvm_property_value prop_value;
@ -1029,17 +1042,10 @@ static PyObject *_liblvm_lvm_vg_create_lv_thinpool(vgobject *self, PyObject *arg
&meta_size, &discard, &skip_zero)) &meta_size, &discard, &skip_zero))
return NULL; return NULL;
if (!(lvobj = PyObject_New(lvobject, &_LibLVMlvType)))
return NULL;
/* Initialize the parent ptr in case lv create fails and we dealloc lvobj */
lvobj->parent_vgobj = NULL;
if (!(lvp = lvm_lv_params_create_thin_pool(self->vg, pool_name, size, chunk_size, if (!(lvp = lvm_lv_params_create_thin_pool(self->vg, pool_name, size, chunk_size,
meta_size, discard))) { meta_size, discard))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
Py_DECREF(lvobj);
return NULL; return NULL;
} }
@ -1051,23 +1057,20 @@ static PyObject *_liblvm_lvm_vg_create_lv_thinpool(vgobject *self, PyObject *arg
if (lvm_lv_params_set_property(lvp, "skip_zero", if (lvm_lv_params_set_property(lvp, "skip_zero",
&prop_value) == -1) { &prop_value) == -1) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); goto error;
Py_DECREF(lvobj);
return NULL;
} }
} }
} }
if (!(lvobj->lv = lvm_lv_create(lvp))) { if (!(lv = lvm_lv_create(lvp))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); goto error;
Py_DECREF(lvobj);
return NULL;
} }
lvobj->parent_vgobj = self; return (PyObject *)_create_py_lv(self, lv);
Py_INCREF(lvobj->parent_vgobj);
return (PyObject *)lvobj; error:
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
return NULL;
} }
static PyObject *_liblvm_lvm_vg_create_lv_thin(vgobject *self, PyObject *args) static PyObject *_liblvm_lvm_vg_create_lv_thin(vgobject *self, PyObject *args)
@ -1075,7 +1078,7 @@ static PyObject *_liblvm_lvm_vg_create_lv_thin(vgobject *self, PyObject *args)
const char *pool_name; const char *pool_name;
const char *lv_name; const char *lv_name;
unsigned long long size = 0; unsigned long long size = 0;
lvobject *lvobj; lv_t lv;
lv_create_params_t lvp = NULL; lv_create_params_t lvp = NULL;
VG_VALID(self); VG_VALID(self);
@ -1083,28 +1086,17 @@ static PyObject *_liblvm_lvm_vg_create_lv_thin(vgobject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "ssK", &pool_name, &lv_name, &size)) if (!PyArg_ParseTuple(args, "ssK", &pool_name, &lv_name, &size))
return NULL; return NULL;
if (!(lvobj = PyObject_New(lvobject, &_LibLVMlvType)))
return NULL;
/* Initialize the parent ptr in case lv create fails and we dealloc lvobj */
lvobj->parent_vgobj = NULL;
if (!(lvp = lvm_lv_params_create_thin(self->vg, pool_name, lv_name,size))) { if (!(lvp = lvm_lv_params_create_thin(self->vg, pool_name, lv_name,size))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
Py_DECREF(lvobj);
return NULL; return NULL;
} }
if (!(lvobj->lv = lvm_lv_create(lvp))) { if (!(lv = lvm_lv_create(lvp))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
Py_DECREF(lvobj);
return NULL; return NULL;
} }
lvobj->parent_vgobj = self; return (PyObject *)_create_py_lv(self, lv);
Py_INCREF(lvobj->parent_vgobj);
return (PyObject *)lvobj;
} }
static void liblvm_lv_dealloc(lvobject *self) static void liblvm_lv_dealloc(lvobject *self)
@ -1157,7 +1149,6 @@ typedef pv_t (*pv_fetch_by_N)(vg_t vg, const char *id);
static PyObject *_liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) static PyObject *_liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method)
{ {
const char *id; const char *id;
lvobject *lvobj;
lv_t lv = NULL; lv_t lv = NULL;
VG_VALID(self); VG_VALID(self);
@ -1170,15 +1161,7 @@ static PyObject *_liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_b
return NULL; return NULL;
} }
if (!(lvobj = PyObject_New(lvobject, &_LibLVMlvType))) return (PyObject *)_create_py_lv(self, lv);
return NULL;
lvobj->parent_vgobj = self;
Py_INCREF(lvobj->parent_vgobj);
lvobj->lv = lv;
return (PyObject *)lvobj;
} }
static PyObject *_liblvm_lvm_lv_from_name(vgobject *self, PyObject *arg) static PyObject *_liblvm_lvm_lv_from_name(vgobject *self, PyObject *arg)
@ -1242,12 +1225,12 @@ static void _liblvm_pv_dealloc(pvobject *self)
/* LV Methods */ /* LV Methods */
#define LV_VALID(lvobject) \ #define LV_VALID(lvobject) \
do { \ do { \
VG_VALID(lvobject->parent_vgobj); \ if (!lvobject || !lvobject->lv) { \
if (!lvobject->lv) { \
PyErr_SetString(PyExc_UnboundLocalError, "LV object invalid"); \ PyErr_SetString(PyExc_UnboundLocalError, "LV object invalid"); \
return NULL; \ return NULL; \
} \ }\
VG_VALID(lvobject->parent_vgobj); \
} while (0) } while (0)
static PyObject *_liblvm_lvm_lv_get_attr(lvobject *self) static PyObject *_liblvm_lvm_lv_get_attr(lvobject *self)
@ -1510,7 +1493,7 @@ static PyObject *_liblvm_lvm_lv_snapshot(lvobject *self, PyObject *args)
{ {
const char *snap_name; const char *snap_name;
unsigned long long size = 0; unsigned long long size = 0;
lvobject *lvobj; lv_t lv;
lv_create_params_t lvp = NULL; lv_create_params_t lvp = NULL;
LV_VALID(self); LV_VALID(self);
@ -1518,43 +1501,33 @@ static PyObject *_liblvm_lvm_lv_snapshot(lvobject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|K", &snap_name, &size)) if (!PyArg_ParseTuple(args, "s|K", &snap_name, &size))
return NULL; return NULL;
if (!(lvobj = PyObject_New(lvobject, &_LibLVMlvType)))
return NULL;
lvobj->parent_vgobj = NULL;
if (!(lvp = lvm_lv_params_create_snapshot(self->lv, snap_name, size))) { if (!(lvp = lvm_lv_params_create_snapshot(self->lv, snap_name, size))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
Py_DECREF(lvobj);
return NULL; return NULL;
} }
if (!(lvobj->lv = lvm_lv_create(lvp))) { if (!(lv = lvm_lv_create(lvp))) {
PyErr_SetObject(_LibLVMError, _liblvm_get_last_error()); PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
Py_DECREF(lvobj);
return NULL; return NULL;
} }
lvobj->parent_vgobj = self->parent_vgobj; return (PyObject *)_create_py_lv(self->parent_vgobj, lv);
Py_INCREF(lvobj->parent_vgobj);
return (PyObject *)lvobj;
} }
/* PV Methods */ /* PV Methods */
#define PV_VALID(pvobject) \ #define PV_VALID(pvobject) \
do { \ do { \
if (!pvobject || !pvobject->pv) { \
PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \
return NULL; \
} \
if (pvobject->parent_vgobj) { \ if (pvobject->parent_vgobj) { \
VG_VALID(pvobject->parent_vgobj); \ VG_VALID(pvobject->parent_vgobj); \
} \ } \
if (pvobject->parent_pvslistobj) { \ if (pvobject->parent_pvslistobj) { \
PVSLIST_VALID(pvobject->parent_pvslistobj); \ PVSLIST_VALID(pvobject->parent_pvslistobj); \
} \ } \
if (!pvobject->pv) { \
PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \
return NULL; \
} \
} while (0) } while (0)
static PyObject *_liblvm_lvm_pv_get_name(pvobject *self) static PyObject *_liblvm_lvm_pv_get_name(pvobject *self)
@ -1673,7 +1646,14 @@ static PyObject *_liblvm_lvm_pv_list_pvsegs(pvobject *self)
* No way to close/destroy an lvseg, just need to make sure parents are * No way to close/destroy an lvseg, just need to make sure parents are
* still good * still good
*/ */
#define LVSEG_VALID(lvsegobject) LV_VALID(lvsegobject->parent_lvobj) #define LVSEG_VALID(lvsegobject) \
do { \
if ( !lvsegobject || !lvsegobject->parent_lvobj ) { \
PyErr_SetString(PyExc_UnboundLocalError, "LV segment object invalid"); \
return NULL; \
} \
LV_VALID(lvsegobject->parent_lvobj); \
} while(0)
static void _liblvm_lvseg_dealloc(lvsegobject *self) static void _liblvm_lvseg_dealloc(lvsegobject *self)
{ {
@ -1702,7 +1682,14 @@ static PyObject *_liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *arg
* No way to close/destroy a pvseg, just need to make sure parents are * No way to close/destroy a pvseg, just need to make sure parents are
* still good * still good
*/ */
#define PVSEG_VALID(pvsegobject) PV_VALID(pvsegobject->parent_pvobj) #define PVSEG_VALID(pvsegobject) \
do { \
if (!pvsegobject || !pvsegobject->parent_pvobj) { \
PyErr_SetString(PyExc_UnboundLocalError, "PV segment object invalid"); \
return NULL; \
} \
PV_VALID(pvsegobject->parent_pvobj); \
} while(0)
static void _liblvm_pvseg_dealloc(pvsegobject *self) static void _liblvm_pvseg_dealloc(pvsegobject *self)
{ {