summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhillip Susi <psusi@ubuntu.com>2013-01-05 20:53:29 -0500
committerPhillip Susi <psusi@ubuntu.com>2013-11-23 16:58:40 -0500
commitfa815ad05db248d78ef214ea79a78c22772a9ffe (patch)
tree86c62226f5573db73ba4b0e24e8a09b569f4f79b
parent9e9588c71e358244bd41f0ca15c10676784ed41d (diff)
downloadparted-fa815ad05db248d78ef214ea79a78c22772a9ffe.tar.gz
libparted: allow some common errors to be ignored
Partitions that overlap or extend beyond the end of the disk are common errors that usually result in people having to use other tools to correct because parted refuses to operate when it sees them. Change these errors to allow you to ignore them and use parted to correct the problem.
-rw-r--r--NEWS6
-rw-r--r--libparted/cs/geom.c8
-rw-r--r--libparted/disk.c89
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/t0283-overlap-partitions.sh143
5 files changed, 176 insertions, 71 deletions
diff --git a/NEWS b/NEWS
index 3f73434..a05be02 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,12 @@ GNU parted NEWS -*- outline -*-
* Noteworthy changes in release ?.? (????-??-??) [?]
+** New Features
+
+ You can now choose to ignore errors about partitions that overlap,
+ or are longer than the disk. This allows you to use parted to
+ repair the problem.
+
** Bug Fixes
libparted: fix gpt end of disk handling. Previously if the backup
diff --git a/libparted/cs/geom.c b/libparted/cs/geom.c
index 65c10c5..b8726da 100644
--- a/libparted/cs/geom.c
+++ b/libparted/cs/geom.c
@@ -153,6 +153,7 @@ ped_geometry_set (PedGeometry* geom, PedSector start, PedSector length)
{
PED_ASSERT (geom != NULL);
PED_ASSERT (geom->dev != NULL);
+ PED_ASSERT (start >= 0);
if (length < 1) {
ped_exception_throw (
@@ -162,13 +163,6 @@ ped_geometry_set (PedGeometry* geom, PedSector start, PedSector length)
" (start sector=%jd length=%jd)"), start, length);
return 0;
}
- if (start < 0 || start + length - 1 >= geom->dev->length) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Can't have a partition outside the disk!"));
- return 0;
- }
geom->start = start;
geom->length = length;
diff --git a/libparted/disk.c b/libparted/disk.c
index d3cd5bb..ce71bfc 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -36,6 +36,7 @@
#include <parted/parted.h>
#include <parted/debug.h>
#include <stdbool.h>
+#include <limits.h>
#include "architecture.h"
#include "labels/pt-tools.h"
@@ -404,6 +405,7 @@ _ped_disk_alloc (const PedDevice* dev, const PedDiskType* disk_type)
disk->type = disk_type;
disk->update_mode = 1;
disk->part_list = NULL;
+ disk->needs_clobber = 0;
return disk;
error:
@@ -917,6 +919,8 @@ _partition_align (PedPartition* part, const PedConstraint* constraint)
PED_ASSERT (disk_type->ops->partition_align != NULL);
PED_ASSERT (part->disk->update_mode);
+ if (part->disk->needs_clobber)
+ return 1; /* do not attempt to align partitions while reading them */
return disk_type->ops->partition_align (part, constraint);
}
@@ -1771,7 +1775,7 @@ _partition_get_overlap_constraint (PedPartition* part, PedGeometry* geom)
walk = ext_part->part_list;
} else {
min_start = 0;
- max_end = part->disk->dev->length - 1;
+ max_end = LLONG_MAX - 1;
walk = part->disk->part_list;
}
@@ -1797,48 +1801,6 @@ _partition_get_overlap_constraint (PedPartition* part, PedGeometry* geom)
return ped_constraint_new_from_max (&free_space);
}
-/*
- * Returns \c 0 if the partition, \p part overlaps with any partitions on the
- * \p disk. The geometry of \p part is taken to be \p geom, NOT \p part->geom
- * (the idea here is to check if \p geom is valid, before changing \p part).
- *
- * This is useful for seeing if a resized partitions new geometry is going to
- * fit, without the existing geomtry getting in the way.
- *
- * Note: overlap with an extended partition is also allowed, provided that
- * \p geom lies completely inside the extended partition.
- */
-static int _GL_ATTRIBUTE_PURE
-_disk_check_part_overlaps (PedDisk* disk, PedPartition* part)
-{
- PedPartition* walk;
-
- PED_ASSERT (disk != NULL);
- PED_ASSERT (part != NULL);
-
- for (walk = ped_disk_next_partition (disk, NULL); walk;
- walk = ped_disk_next_partition (disk, walk)) {
- if (walk->type & PED_PARTITION_FREESPACE)
- continue;
- if (walk == part)
- continue;
- if (part->type & PED_PARTITION_EXTENDED
- && walk->type & PED_PARTITION_LOGICAL)
- continue;
-
- if (ped_geometry_test_overlap (&walk->geom, &part->geom)) {
- if (walk->type & PED_PARTITION_EXTENDED
- && part->type & PED_PARTITION_LOGICAL
- && ped_geometry_test_inside (&walk->geom,
- &part->geom))
- continue;
- return 0;
- }
- }
-
- return 1;
-}
-
static int
_partition_check_basic_sanity (PedDisk* disk, PedPartition* part)
{
@@ -1847,7 +1809,6 @@ _partition_check_basic_sanity (PedDisk* disk, PedPartition* part)
PED_ASSERT (part->disk == disk);
PED_ASSERT (part->geom.start >= 0);
- PED_ASSERT (part->geom.end < disk->dev->length);
PED_ASSERT (part->geom.start <= part->geom.end);
if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)
@@ -1934,29 +1895,30 @@ _check_partition (PedDisk* disk, PedPartition* part)
if (part->type & PED_PARTITION_LOGICAL
&& !ped_geometry_test_inside (&ext_part->geom, &part->geom)) {
- ped_exception_throw (
+ if (ped_exception_throw (
PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
+ PED_EXCEPTION_IGNORE_CANCEL,
_("Can't have a logical partition outside of the "
"extended partition on %s."),
- disk->dev->path);
- return 0;
- }
-
- if (!_disk_check_part_overlaps (disk, part)) {
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Can't have overlapping partitions."));
- return 0;
+ disk->dev->path) != PED_EXCEPTION_IGNORE)
+ return 0;
}
if (! (part->type & PED_PARTITION_LOGICAL)
&& ext_part && ext_part != part
&& ped_geometry_test_inside (&ext_part->geom, &part->geom)) {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+ if (ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL,
_("Can't have a primary partition inside an extended "
- "partition."));
+ "partition.")) != PED_EXCEPTION_IGNORE)
+ return 0;
+ }
+
+ if (part->geom.end >= disk->dev->length) {
+ if (ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("Can't have a partition outside the disk!"))
+ != PED_EXCEPTION_IGNORE )
return 0;
}
@@ -2003,16 +1965,15 @@ ped_disk_add_partition (PedDisk* disk, PedPartition* part,
constraint);
if (!constraints && constraint) {
- ped_exception_throw (
+ if (ped_exception_throw (
PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Can't have overlapping partitions."));
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("Can't have overlapping partitions.")) != PED_EXCEPTION_IGNORE)
goto error;
- }
-
+ } else constraint = constraints;
if (!_partition_enumerate (part))
goto error;
- if (!_partition_align (part, constraints))
+ if (!_partition_align (part, constraint))
goto error;
}
/* FIXME: when _check_partition fails, we end up leaking PART
diff --git a/tests/Makefile.am b/tests/Makefile.am
index eaf44a5..16ec5d2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -30,6 +30,7 @@ TESTS = \
t0280-gpt-corrupt.sh \
t0281-gpt-grow.sh \
t0282-gpt-move-backup.sh \
+ t0283-overlap-partitions.sh \
t0300-dos-on-gpt.sh \
t0301-overwrite-gpt-pmbr.sh \
t0350-mac-PT-increases-sector-size.sh \
diff --git a/tests/t0283-overlap-partitions.sh b/tests/t0283-overlap-partitions.sh
new file mode 100644
index 0000000..2a53407
--- /dev/null
+++ b/tests/t0283-overlap-partitions.sh
@@ -0,0 +1,143 @@
+#!/bin/sh
+# ensure parted can ignore partitions that overlap or are
+# longer than the disk and remove them
+
+# Copyright (C) 2009-2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+require_512_byte_sector_size_
+dev=loop-file
+
+truncate -s 10m $dev || fail=1
+
+# write damaged label
+xxd -r - $dev <<EOF
+0000000: fab8 0010 8ed0 bc00 b0b8 0000 8ed8 8ec0 ................
+0000010: fbbe 007c bf00 06b9 0002 f3a4 ea21 0600 ...|.........!..
+0000020: 00be be07 3804 750b 83c6 1081 fefe 0775 ....8.u........u
+0000030: f3eb 16b4 02b0 01bb 007c b280 8a74 018b .........|...t..
+0000040: 4c02 cd13 ea00 7c00 00eb fe00 0000 0000 L.....|.........
+0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+0000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00001b0: 0000 0000 0000 0000 72f5 0000 0000 0000 ........r.......
+00001c0: 0110 8303 204f 0008 0000 0020 0000 0000 .... O..... ....
+00001d0: 0050 8300 0a7a ff27 0000 0a15 0000 0000 .P...z.'........
+00001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U.
+EOF
+
+# print the empty table
+parted ---pretend-input-tty $dev <<EOF > out 2>&1 || fail=1
+print
+ignore
+rm
+ignore
+2
+EOF
+
+# $PWD contains a symlink-to-dir. Also, remove the ^M ...^M bogosity.
+# normalize the actual output
+mv out o2 && sed -e "s,/.*/$dev,DEVICE,;s, * ,,g;s, $,," \
+ -e "s,^.*/lt-parted: ,parted: ," -e "s/^GNU Parted .*$/GNU Parted VERSION/" o2 > out
+
+# check for expected output
+cat <<EOF > exp || fail=1
+GNU Parted VERSION
+Using DEVICE
+Welcome to GNU Parted! Type 'help' to view a list of commands.
+(parted) print
+Error: Can't have overlapping partitions.
+Ignore/Cancel? ignore
+Model: (file)
+Disk DEVICE: 10.5MB
+Sector size (logical/physical): 512B/512B
+Partition Table: msdos
+Disk Flags:
+
+Number Start End Size Type File system Flags
+ 1 1049kB 5243kB 4194kB primary
+ 2 5242kB 8000kB 2758kB primary
+
+(parted) rm
+Error: Can't have overlapping partitions.
+Ignore/Cancel? ignore
+Partition number? 2
+(parted)
+EOF
+compare exp out || fail=1
+
+truncate -s 3m $dev || fail=1
+
+# print the table, verify error, ignore it, and remove the partition
+parted ---pretend-input-tty $dev <<EOF > out 2>&1 || fail=1
+print
+ignore
+rm
+ignore
+1
+EOF
+
+# $PWD contains a symlink-to-dir. Also, remove the ^M ...^M bogosity.
+# normalize the actual output
+mv out o2 && sed -e "s,/.*/$dev,DEVICE,;s, * ,,g;s, $,," \
+ -e "s,^.*/lt-parted: ,parted: ," -e "s/^GNU Parted .*$/GNU Parted VERSION/" o2 > out
+
+# check for expected output
+cat <<EOF > exp || fail=1
+GNU Parted VERSION
+Using DEVICE
+Welcome to GNU Parted! Type 'help' to view a list of commands.
+(parted) print
+Error: Can't have a partition outside the disk!
+Ignore/Cancel? ignore
+Model: (file)
+Disk DEVICE: 3146kB
+Sector size (logical/physical): 512B/512B
+Partition Table: msdos
+Disk Flags:
+
+Number Start End Size Type File system Flags
+ 1 1049kB 5243kB 4194kB primary
+
+(parted) rm
+Error: Can't have a partition outside the disk!
+Ignore/Cancel? ignore
+Partition number? 1
+(parted)
+EOF
+compare exp out || fail=1
+
+Exit $fail