0b7af917e2
- Drop patches incorporated into upstream - Still adds the various DASD patches
388 lines
13 KiB
Diff
388 lines
13 KiB
Diff
From fa815ad05db248d78ef214ea79a78c22772a9ffe Mon Sep 17 00:00:00 2001
|
|
From: Phillip Susi <psusi@ubuntu.com>
|
|
Date: Sat, 5 Jan 2013 20:53:29 -0500
|
|
Subject: [PATCH 60/89] 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.
|
|
---
|
|
NEWS | 6 ++
|
|
libparted/cs/geom.c | 8 +--
|
|
libparted/disk.c | 89 +++++++-----------------
|
|
tests/Makefile.am | 1 +
|
|
tests/t0283-overlap-partitions.sh | 143 ++++++++++++++++++++++++++++++++++++++
|
|
5 files changed, 176 insertions(+), 71 deletions(-)
|
|
create mode 100644 tests/t0283-overlap-partitions.sh
|
|
|
|
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
|
|
--
|
|
1.8.5.3
|
|
|