summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2016-03-22 15:49:00 +0100
committerKarel Zak <kzak@redhat.com>2016-03-22 15:49:00 +0100
commit2d47fa3921b86f16b07065a83e381708fa852d4a (patch)
tree3487ea9a12287e11f84db1d1dd9d0ca2e6bf0e8a
parent6988998b66b4b95c494d60599f8e3de2ffbaeece (diff)
downloadutil-linux-2d47fa3921b86f16b07065a83e381708fa852d4a.tar.gz
partx: fix --nr usage
Reported-by: Serge van den Boom <serge+util-linux@vdboom.org> Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--Documentation/releases/v2.28-ReleaseNotes2
-rw-r--r--disk-utils/partx.82
-rw-r--r--disk-utils/partx.c59
-rw-r--r--lib/strutils.c2
4 files changed, 48 insertions, 17 deletions
diff --git a/Documentation/releases/v2.28-ReleaseNotes b/Documentation/releases/v2.28-ReleaseNotes
index 229c5f56a..127f394a6 100644
--- a/Documentation/releases/v2.28-ReleaseNotes
+++ b/Documentation/releases/v2.28-ReleaseNotes
@@ -41,7 +41,7 @@ The library libsmartcols has been massively improved to print table ranges,
multi-line cells, table titles and to support continuous printing.
The package build system and code have been improved to be more portable to
-non-Linux systems (BSD, XOs).
+non-Linux systems (BSD, OSX).
The package does not provide fallback solutions for openat-family functions
anymore.
diff --git a/disk-utils/partx.8 b/disk-utils/partx.8
index 6a3e1b28e..8830afb52 100644
--- a/disk-utils/partx.8
+++ b/disk-utils/partx.8
@@ -68,7 +68,7 @@ Do not use it in newly written scripts.
Specify the range of partitions. For backward compatibility also the
format \fIM\fB\-\fIN\fR is supported.
The range may contain negative numbers, for example
-.B \-\-nr :\-1
+.B \-\-nr -\1:\-1
means the last partition, and
.B \-\-nr \-2:\-1
means the last two partitions. Supported range specifications are:
diff --git a/disk-utils/partx.c b/disk-utils/partx.c
index 50bd6a4f8..46224a3f0 100644
--- a/disk-utils/partx.c
+++ b/disk-utils/partx.c
@@ -267,6 +267,30 @@ dflt:
return SLICES_MAX;
}
+static int recount_range_by_pt(blkid_partlist ls, int *lower, int *upper)
+{
+ int n = 0, i, nparts = blkid_partlist_numof_partitions(ls);
+
+ for (i = 0; i < nparts; i++) {
+ blkid_partition par = blkid_partlist_get_partition(ls, i);
+ int partno = blkid_partition_get_partno(par);
+ n = max(partno, n);
+ }
+
+ if (*lower < 0)
+ *lower = n + *lower + 1;
+ if (*upper < 0)
+ *upper = n + *upper + 1;
+
+ if (*lower > *upper && *upper != 0) {
+ warnx(_("specified range <%d:%d> does not make sense"), *lower, *upper);
+ return -EINVAL;
+ }
+ if (verbose)
+ printf(_("range recount: max partno=%d, lower=%d, upper=%d\n"), n, *lower, *upper);
+ return 0;
+}
+
static void del_parts_warnx(const char *device, int first, int last)
{
if (first == last)
@@ -284,6 +308,7 @@ static int del_parts(int fd, const char *device, dev_t devno,
assert(fd >= 0);
assert(device);
+ /* recount range by information in /sys */
if (!lower)
lower = 1;
if (!upper || lower < 0 || upper < 0) {
@@ -343,12 +368,16 @@ static void add_parts_warnx(const char *device, int first, int last)
static int add_parts(int fd, const char *device,
blkid_partlist ls, int lower, int upper)
{
- int i, nparts, rc = 0, errfirst = 0, errlast = 0;
+ int i, nparts, rc, errfirst = 0, errlast = 0;
assert(fd >= 0);
assert(device);
assert(ls);
+ rc = recount_range_by_pt(ls, &lower, &upper);
+ if (rc)
+ return rc;
+
nparts = blkid_partlist_numof_partitions(ls);
for (i = 0; i < nparts; i++) {
@@ -430,6 +459,8 @@ static int upd_parts(int fd, const char *device, dev_t devno,
assert(device);
assert(ls);
+ /* recount range by information in /sys, if on disk number of
+ * partitions is greater than in /sys the use on-disk limit */
nparts = blkid_partlist_numof_partitions(ls);
if (!lower)
lower = 1;
@@ -505,10 +536,14 @@ static int upd_parts(int fd, const char *device, dev_t devno,
static int list_parts(blkid_partlist ls, int lower, int upper)
{
- int i, nparts;
+ int i, nparts, rc;
assert(ls);
+ rc = recount_range_by_pt(ls, &lower, &upper);
+ if (rc)
+ return rc;
+
nparts = blkid_partlist_numof_partitions(ls);
for (i = 0; i < nparts; i++) {
@@ -645,6 +680,10 @@ static int show_parts(blkid_partlist ls, int scols_flags, int lower, int upper)
}
}
+ rc = recount_range_by_pt(ls, &lower, &upper);
+ if (rc)
+ goto done;
+
for (i = 0; i < nparts; i++) {
blkid_partition par = blkid_partlist_get_partition(ls, i);
int n = blkid_partition_get_partno(par);
@@ -880,6 +919,9 @@ int main(int argc, char **argv)
} else {
device = argv[optind];
wholedisk = xstrdup(argv[optind + 1]);
+
+ if (device && wholedisk && !startswith(device, wholedisk))
+ errx(EXIT_FAILURE, _("partition and disk name do not match"));
}
} else if (optind == argc - 1) {
/* passed only one arg (ie: /dev/sda3 or /dev/sda) */
@@ -964,18 +1006,6 @@ int main(int argc, char **argv)
ls = get_partlist(pr, wholedisk, type);
if (ls) {
- int n = blkid_partlist_numof_partitions(ls);
-
- if (lower < 0)
- lower = n + lower + 1;
- if (upper < 0)
- upper = n + upper + 1;
- if (lower > upper) {
- warnx(_("specified range <%d:%d> "
- "does not make sense"), lower, upper);
- rc = -1, what = ACT_NONE;
- }
-
switch (what) {
case ACT_SHOW:
rc = show_parts(ls, scols_flags, lower, upper);
@@ -988,6 +1018,7 @@ int main(int argc, char **argv)
break;
case ACT_UPD:
rc = upd_parts(fd, wholedisk, disk_devno, ls, lower, upper);
+ break;
case ACT_NONE:
break;
default:
diff --git a/lib/strutils.c b/lib/strutils.c
index d58b4b468..9d30b83d1 100644
--- a/lib/strutils.c
+++ b/lib/strutils.c
@@ -734,7 +734,7 @@ int parse_range(const char *str, int *lower, int *upper, int def)
return -1;
if (*end == ':' && !*(end + 1)) /* <M:> */
- *upper = 0;
+ *upper = def;
else if (*end == '-' || *end == ':') { /* <M:N> <M-N> */
str = end + 1;
end = NULL;