Re: PATCH: pyblock: Make dm.c / dmraid.c handle tables with more then one row correctly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Have not tested but it looks ok.
On Tue, Feb 24, 2009 at 10:41:50PM +0100, Hans de Goede wrote:
> 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, &params);
> +		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

-- 
Joel Andres Granados
Brno, Czech Republic, Red Hat.

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux