]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
partx: fix --nr usage
authorKarel Zak <kzak@redhat.com>
Tue, 22 Mar 2016 14:49:00 +0000 (15:49 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 22 Mar 2016 14:49:00 +0000 (15:49 +0100)
Reported-by: Serge van den Boom <serge+util-linux@vdboom.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
Documentation/releases/v2.28-ReleaseNotes
disk-utils/partx.8
disk-utils/partx.c
lib/strutils.c

index 229c5f56a39da0821cf5446263ceee853595e395..127f394a6c94f822c52d333e5b0a13fa6a9897be 100644 (file)
@@ -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.
index 6a3e1b28eccc4b2c5df1f03ab4914de3e7119fc4..8830afb52aaa225054ac5b22f17785e8d981190d 100644 (file)
@@ -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:
index 50bd6a4f80afff0c3686d3e116158c633a8e1289..46224a3f0aa7e67369f67d1dbda8baae53a2cd0c 100644 (file)
@@ -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:
index d58b4b468c6e3edd7439444e70cbc2c169c22d24..9d30b83d10d1f3c03a088822c0f9be82ccf6208c 100644 (file)
@@ -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;