[parted-devel] [PATCH 1/6] libparted: refactor device-mapper partition sync code
Jim Meyering
jim at meyering.net
Wed Oct 17 14:25:23 UTC 2012
Jim Meyering wrote:
> Phillip Susi wrote:
>> The device-mapper partition sync code was still using the remove all
>> partitions, then add new partitions method. Refactor to use the same
>> algorithm as regular disks: try to remove all, and ignore any that could
>> not be removed but have not changed.
>> ---
>> NEWS | 2 +
>> libparted/arch/linux.c | 403 +++++++++++++++++++++---------------------------
>> tests/Makefile.am | 1 +
>> tests/t6002-dm-busy.sh | 94 +++++++++++
>> 4 files changed, 275 insertions(+), 225 deletions(-)
>> create mode 100644 tests/t6002-dm-busy.sh
>>
>> diff --git a/NEWS b/NEWS
>> index 4c4716d..f182cce 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -3,6 +3,8 @@ GNU parted NEWS -*- outline -*-
>> * Noteworthy changes in release ?.? (????-??-??) [?]
>>
>> ** Bug Fixes
>> + libparted: Don't fail to manipulate partitions on dmraid disks that
>> + have other partitions in use.
>
> Thanks for putting this together!
> It's great to see both NEWS and a test addition.
>
> ...
>> +static int
>> +_dm_add_partition (PedDisk* disk, const PedPartition* part)
>> +{
>> + LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev);
>> +
>> + /* Get map name from devicemapper */
>> + struct dm_task *task = dm_task_create (DM_DEVICE_INFO);
>> + if (!task)
>> + goto err;
>> +
>> + if (!dm_task_set_major_minor (task, arch_specific->major,
>> + arch_specific->minor, 0))
>> + goto err;
>> +
>> + if (!dm_task_run(task))
>> + goto err;
>> +
>> + const char *dev_name = dm_task_get_name (task);
>> + char *vol_name;
>> + if (isdigit (dev_name[strlen (dev_name) - 1])) {
>> + if ( ! (vol_name = zasprintf ("%sp%d", dev_name, part->num)))
>> + goto err;
>> + } else if ( ! (vol_name = zasprintf ("%s%d", dev_name, part->num)))
>> + goto err;
>
> Please combine those:
>
> char *vol_name
> = zasprintf ("%s%s%d",
> dev_name,
> isdigit (dev_name[strlen (dev_name) - 1]) ? "p" : "",
> part->num);
> if (vol_name == NULL)
> goto err;
>
>> + /* Caution: dm_task_destroy frees dev_name. */
>> + dm_task_destroy (task);
>> + task = NULL;
>> + char *params;
>
> Please indent consistently.
> s/TAB/ /
> Yeah, I know it's hard, since the code does not use a consistent policy.
>
> Eventually, when there seem to be few distro patches anywhere,
> I'd like to convert all leading TABs to spaces.
>
>> + if ( ! (params = zasprintf ("%d:%d %lld", arch_specific->major,
>> + arch_specific->minor, part->geom.start)))
>> + goto err;
>> +
>> + task = dm_task_create (DM_DEVICE_CREATE);
>> + if (!task)
>> + goto err;
>> +
>> + dm_task_set_name (task, vol_name);
>> + dm_task_add_target (task, 0, part->geom.length,
>> + "linear", params);
>> + if (dm_task_run (task)) {
>> + dm_task_update_nodes();
>> + dm_task_destroy(task);
>> + free(params);
>> + free(vol_name);
>> + return 1;
>> + } else {
>> + _dm_remove_partition (disk, part->num);
>> + }
>> +err:
>> + dm_task_update_nodes();
>> + if (task)
>> + dm_task_destroy (task);
>> + free (params);
>> + free (vol_name);
>> + return 0;
>> +}
>> +#endif
>
> Please make a point always to configure with --enable-gcc-warnings.
> When I applied your patch and built, it highlights these two problems:
>
> CC arch/linux.lo
> arch/linux.c: In function '_dm_add_partition':
> arch/linux.c:2686:14: error: 'params' may be used uninitialized in this function [-Werror=maybe-uninitialized]
> free (params);
> ^
> arch/linux.c:2687:14: error: 'vol_name' may be used uninitialized in this function [-Werror=maybe-uninitialized]
> free (vol_name);
> ^
> cc1: all warnings being treated as errors
> make[3]: *** [arch/linux.lo] Error 1
>
> i.e., hitting any of the "goto err" statements before "params" is set
> would make libparted apply free to at least one uninitialized pointer.
>
> Also, there was a trailing space on one of the added lines,
> if you could remove it for a v2, that'd save me the trouble.
Looks like I'm doing a v2 for you.
Here's the first amendment, to fix the bugs highlighted by the errors
above:
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 0d5bad5..22556e8 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2634,6 +2634,8 @@ static int
_dm_add_partition (PedDisk* disk, const PedPartition* part)
{
LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev);
+ char *params = NULL;
+ char *vol_name = NULL;
/* Get map name from devicemapper */
struct dm_task *task = dm_task_create (DM_DEVICE_INFO);
@@ -2648,7 +2650,6 @@ _dm_add_partition (PedDisk* disk, const PedPartition* part)
goto err;
const char *dev_name = dm_task_get_name (task);
- char *vol_name;
if (isdigit (dev_name[strlen (dev_name) - 1])) {
if ( ! (vol_name = zasprintf ("%sp%d", dev_name, part->num)))
goto err;
@@ -2658,7 +2659,6 @@ _dm_add_partition (PedDisk* disk, const PedPartition* part)
/* Caution: dm_task_destroy frees dev_name. */
dm_task_destroy (task);
task = NULL;
- char *params;
if ( ! (params = zasprintf ("%d:%d %lld", arch_specific->major,
arch_specific->minor, part->geom.start)))
goto err;
@@ -2671,10 +2671,10 @@ _dm_add_partition (PedDisk* disk, const PedPartition* part)
dm_task_add_target (task, 0, part->geom.length,
"linear", params);
if (dm_task_run (task)) {
- dm_task_update_nodes();
- dm_task_destroy(task);
- free(params);
- free(vol_name);
+ dm_task_update_nodes ();
+ dm_task_destroy (task);
+ free (params);
+ free (vol_name);
return 1;
} else {
_dm_remove_partition (disk, part->num);
More information about the parted-devel
mailing list