A devicemapper map's table can have multiple rows (targets in devicemapper
speak), but we assume their is always only one. This patch updates the C
part of pyblock to take account that their may be multiple rows in a table
and makes functions which return / expect a PydmTableObject return / expect
a list of PydmTableObject's. Maybe we should rename PydmTableObject to
PydmTableRowObject to reflect it does not abstract a complete table, but only
one row / target of a complete table.
Together with the mathching python changes this fixes fakeraid jbod / spanning
setups.
---
dm.c | 54 ++++++++++++-------
dmraid.c | 175 +++++++++++++++++++++++++++++++++-----------------------------
2 files changed, 129 insertions(+), 100 deletions(-)
diff --git a/dm.c b/dm.c
index 195afd7..f279cb0 100644
--- a/dm.c
+++ b/dm.c
@@ -872,9 +872,10 @@ pydm_map_simple(PydmMapObject *map, int taskno)
}
static int
-pydm_map_create(PydmMapObject *map, PydmTableObject *table)
+pydm_map_create(PydmMapObject *map, PyObject *table)
{
struct dm_task *task;
+ int i;
if (!map->name) {
PyErr_SetString(PyExc_ValueError,
@@ -896,9 +897,14 @@ pydm_map_create(PydmMapObject *map, PydmTableObject *table)
dm_task_set_uuid(task, map->uuid);
python_error_destroy_task(task, -1);
- dm_task_add_target(task, table->start, table->size,
- table->type, table->params);
- python_error_destroy_task(task, -1);
+ for (i = 0; i < PyList_Size(table); i++) {
+ PydmTableObject *row =
+ (PydmTableObject *)PyList_GET_ITEM(table, i);
+
+ dm_task_add_target(task, row->start, row->size,
+ row->type, row->params);
+ python_error_destroy_task(task, -1);
+ }
if (map->dev) {
PydmDeviceObject *dev = (PydmDeviceObject *)map->dev;
@@ -930,13 +936,13 @@ pydm_map_init_method(PyObject *self, PyObject *args,
PyObject *kwds)
char *kwlist[] = {"name", "table", "uuid", "dev", NULL};
PydmMapObject *map = (PydmMapObject *)self;
PydmDeviceObject *dev = NULL;
- PydmTableObject *table = NULL;
+ PyObject *table = NULL;
char *uuid = NULL, *name = NULL;
pydm_map_clear(map);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zO!zO!:map.__init__",
- kwlist, &name, &PydmTable_Type, &table, &uuid,
+ kwlist, &name, &PyList_Type, &table, &uuid,
&PydmDevice_Type, &dev))
return -1;
@@ -1088,7 +1094,7 @@ pydm_map_get_table(PydmMapObject *map)
struct pydm_map_key key;
int rc;
void *next = NULL;
- PydmTableObject *table = NULL;
+ PyObject *table = NULL, *table_list = NULL;
rc = pydm_map_get_best_key(map, &key);
if (rc < 0) {
@@ -1114,25 +1120,35 @@ pydm_map_get_table(PydmMapObject *map)
next = dm_get_next_target(task, next, &start, &length,
&target_type, ¶ms);
+ if (!target_type) {
+ PyErr_SetString(PyExc_RuntimeError, "no dm table found");
+ Py_CLEAR(table_list);
+ break;
+ }
+ if (!table_list) {
+ table_list = PyList_New(0);
+ if (!table_list)
+ break;
+ }
+
+ table = PydmTable_FromInfo(start, length, target_type, params);
if (!table) {
- python_error_destroy_task(task, NULL);
-
- table = (PydmTableObject *)PydmTable_FromInfo(start,
- length, target_type, params);
- } else if (PyErr_Occurred()) {
- /* this means it happened in one of
- the dm_get_next_target iterations that we didn't
- expect and don't really care about. */
- PyErr_Clear();
+ Py_CLEAR(table_list);
+ break;
+ }
+
+ rc = PyList_Append(table_list, table);
+ Py_DECREF(table);
+ if (rc < 0) {
+ Py_CLEAR(table_list);
+ break;
}
} while (next);
- if (!table)
- PyErr_SetString(PyExc_RuntimeError, "no dm table found");
dm_task_update_nodes();
dm_task_destroy(task);
- return (PyObject *)table;
+ return table_list;
}
static PyObject *
diff --git a/dmraid.c b/dmraid.c
index f2f8d9e..5b5cf6c 100644
--- a/dmraid.c
+++ b/dmraid.c
@@ -704,9 +704,9 @@ pydmraid_raidset_get_dm_table(PyObject *self, void *data)
size_t spn;
PyObject *m = NULL, *md = NULL;
- PyObject *type = NULL, *args = NULL;
+ PyObject *type = NULL;
PyObject *table = NULL;
-
+ PyObject *table_list = NULL;
PyObject *iret = NULL;
/* ugh, there's no generic way of telling if this should even
@@ -715,119 +715,132 @@ pydmraid_raidset_get_dm_table(PyObject *self, void *data)
if (a) {
s = strdupa(a);
free(a);
- a = b = s;
}
if (!s) {
PyErr_SetString(PyExc_RuntimeError, "no mapping possible");
return NULL;
}
- /* find the beginning of the start */
- spn = strspn(s, " \t");
- a += spn;
- if (*a == '\0')
- goto out;
- b = NULL;
- errno = 0;
- start = strtoull(a, &b, 10);
- if (start == ULLONG_MAX && errno != 0)
- goto out;
-
- /* find the length */
- spn = strspn(b, " \t");
- a = b + spn;
- if (!spn || *a == '\0')
+ /* get the DSO for block.dm loaded */
+ m = PyImport_ImportModule("block.dm");
+ if (!m)
goto out;
- b = NULL;
- errno = 0;
- length = strtoull(a, &b, 10);
- if (length == ULLONG_MAX && errno != 0)
+ md = PyModule_GetDict(m);
+ if (!md)
goto out;
- /* now the dm type */
- spn = strspn(b, " \t");
- a = b + spn;
- if (!spn || *a == '\0')
+ type = PyDict_GetItemString(md, "table");
+ if (!type)
goto out;
- spn = strcspn(a, " \t");
- if (!spn)
+ table_list = PyList_New(0);
+ if (!table_list)
goto out;
- dmtype = strndupa(a, spn);
- a += spn;
- spn = strspn(a, " \t");
- a += spn;
- if (a)
- rule=strdupa(a);
+ s = strtok(s, "\n");
+ do {
+ a = b = s;
+ /* find the beginning of the start */
+ spn = strspn(s, " \t");
+ a += spn;
+ if (*a == '\0')
+ goto out;
+
+ b = NULL;
+ errno = 0;
+ start = strtoull(a, &b, 10);
+ if (start == ULLONG_MAX && errno != 0)
+ goto out;
+
+ /* find the length */
+ spn = strspn(b, " \t");
+ a = b + spn;
+ if (!spn || *a == '\0')
+ goto out;
+
+ b = NULL;
+ errno = 0;
+ length = strtoull(a, &b, 10);
+ if (length == ULLONG_MAX && errno != 0)
+ goto out;
+
+ /* now the dm type */
+ spn = strspn(b, " \t");
+ a = b + spn;
+ if (!spn || *a == '\0')
+ goto out;
+
+ spn = strcspn(a, " \t");
+ if (!spn)
+ goto out;
+ dmtype = strndupa(a, spn);
+
+ a += spn;
+ spn = strspn(a, " \t");
+ a += spn;
+ if (a)
+ rule=strdupa(a);
#ifndef ALLOW_NOSYNC
- /* XXX FIXME we shouldn't need to do this */
- /* transform "core 2 64 nosync" into "core 1 64" */
- a = strstr(rule, "core");
- if (a) {
- /* find the first space */
- a += strcspn(a, " ");
- /* find the first nonspace */
- a += strspn(a, " ");
- /* if it's not 2, don't change anything */
- if (!strncmp(a, "2 ", 2)) {
- /* change "2 " to a "1 " */
- a[0]='1';
- a+=2;
- /* find the end of this arg (the space after "64") */
+ /* XXX FIXME we shouldn't need to do this */
+ /* transform "core 2 64 nosync" into "core 1 64" */
+ a = strstr(rule, "core");
+ if (a) {
+ /* find the first space */
a += strcspn(a, " ");
- /* .. and the arg we want rid of */
+ /* find the first nonspace */
a += strspn(a, " ");
- /* now find the beginning of our replacement */
- b = a + strcspn(a, " ");
- b += strspn(b, " ");
- /* and now clobber it */
- spn = strlen(b);
- memmove(a, b, spn+1);
+ /* if it's not 2, don't change anything */
+ if (!strncmp(a, "2 ", 2)) {
+ /* change "2 " to a "1 " */
+ a[0]='1';
+ a+=2;
+ /* find the end of this arg (the space after "64") */
+ a += strcspn(a, " ");
+ /* .. and the arg we want rid of */
+ a += strspn(a, " ");
+ /* now find the beginning of our replacement */
+ b = a + strcspn(a, " ");
+ b += strspn(b, " ");
+ /* and now clobber it */
+ spn = strlen(b);
+ memmove(a, b, spn+1);
+ }
}
- }
#endif
+ table = PyType_GenericNew((PyTypeObject *)type, NULL, NULL);
+ if (!table)
+ goto out;
- args = Py_BuildValue("(LLss)", start, length, dmtype, rule);
- if (!args)
- goto out;
-
- /* get the DSO for block.dm loaded */
- m = PyImport_ImportModule("block.dm");
- if (!m)
- goto out;
+ iret = PyObject_CallMethod(table, "__init__", "LLss", start, length, dmtype,
rule);
+ if (!iret)
+ goto out;
- md = PyModule_GetDict(m);
- if (!md)
- goto out;
+ if (PyList_Append(table_list, table) < 0)
+ goto out;
- type = PyDict_GetItemString(md, "table");
- if (!type)
- goto out;
+ Py_CLEAR(iret);
+ Py_CLEAR(table);
+ } while ((s = strtok(NULL, "\n")));
- table = PyType_GenericNew((PyTypeObject *)type, args, NULL);
- if (!table)
- goto out;
+ Py_DECREF(m);
- iret = PyObject_CallMethod(table, "__init__", "LLss", start, length, dmtype,
rule);
- if (!iret) {
- Py_DECREF(table);
- goto out;
- }
+ return table_list;
out:
Py_XDECREF(iret);
- Py_XDECREF(args);
- if (!table && !PyErr_Occurred()) {
+ Py_XDECREF(table);
+ Py_XDECREF(table_list);
+ Py_XDECREF(m);
+ if (!PyErr_Occurred()) {
if (errno != 0)
PyErr_SetFromErrno(PyExc_SystemError);
else
pyblock_PyErr_Format(PyExc_ValueError,
"invalid map '%s'", s);
}
- return table;
+ return NULL;
}
static PyObject *
--
1.6.1.3
_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list