MENU_ENT ('t', N_("change a partition type")),
MENU_BENT_E('v', N_("verify the partition table"), FDISK_DISKLABEL_BSD),
MENU_ENT ('i', N_("print information about a partition")),
+ MENU_ENT ('e', N_("resize a partition")),
MENU_XENT('d', N_("print the raw data of the first sector from the device")),
MENU_XENT('D', N_("print the raw data of the disklabel from the device")),
rc = ask_for_wipe(cxt, partno);
break;
}
+ case 'e':
+ resize_partition(cxt);
+ break;
case 't':
change_partition_type(cxt);
break;
fdisk_reset_alignment(cxt); /* reset the current label */
}
+static int strtosize_sectors(const char *str, unsigned long sector_size,
+ uintmax_t *res)
+{
+ size_t len = strlen(str);
+ int insec = 0;
+ int rc;
+
+ if (!len)
+ return 0;
+
+ if (str[len - 1] == 'S' || str[len - 1] == 's') {
+ insec = 1;
+ str = strndup(str, len - 1); /* strip trailing 's' */
+ if (!str)
+ return -errno;
+ }
+
+ rc = strtosize(str, res);
+ if (rc)
+ return rc;
+
+ if (insec) {
+ *res *= sector_size;
+ free((void *)str);
+ }
+
+ return 0;
+}
+
+void resize_partition(struct fdisk_context *cxt)
+{
+ struct fdisk_partition *pa = NULL, *npa = NULL, *next = NULL;
+ char *query = NULL, *response = NULL, *default_size;
+ struct fdisk_table *tb = NULL;
+ uint64_t max_size, size, secs;
+ size_t i;
+ int rc;
+
+ assert(cxt);
+
+ rc = fdisk_ask_partnum(cxt, &i, FALSE);
+ if (rc)
+ goto err;
+
+ rc = fdisk_partition_get_max_size(cxt, i, &max_size);
+ if (rc)
+ goto err;
+
+ max_size *= fdisk_get_sector_size(cxt);
+
+ default_size = size_to_human_string(0, max_size);
+ xasprintf(&query, _("New <size>{K,M,G,T,P} in bytes or <size>S in sectors (default %s)"),
+ default_size);
+ free(default_size);
+
+ rc = fdisk_ask_string(cxt, query, &response);
+ if (rc)
+ goto err;
+
+ size = max_size;
+ rc = strtosize_sectors(response, fdisk_get_sector_size(cxt), &size);
+ if (rc || size > max_size) {
+ fdisk_warnx(cxt, _("Invalid size"));
+ goto err;
+ }
+
+ npa = fdisk_new_partition();
+ if (!npa)
+ goto err;
+
+ secs = size / fdisk_get_sector_size(cxt);
+ fdisk_partition_size_explicit(npa, 1);
+ fdisk_partition_set_size(npa, secs);
+
+ rc = fdisk_set_partition(cxt, i, npa);
+ if (rc)
+ goto err;
+
+ fdisk_info(cxt, _("Partition %zu has been resized."), i + 1);
+
+out:
+ free(query);
+ free(response);
+ fdisk_unref_partition(next);
+ fdisk_unref_partition(pa);
+ fdisk_unref_partition(npa);
+ fdisk_unref_table(tb);
+ return;
+
+err:
+ fdisk_warnx(cxt, _("Could not resize partition %zu: %s"),
+ i + 1, strerror(-rc));
+ goto out;
+}
+
void change_partition_type(struct fdisk_context *cxt)
{
size_t i;
extern void follow_wipe_mode(struct fdisk_context *cxt);
+extern void resize_partition(struct fdisk_context *cxt);
+
#endif /* UTIL_LINUX_FDISK_H */
--- /dev/null
+Create initial partitions
+
+---layout----------
+Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / <removed> bytes
+Disklabel type: gpt
+Disk identifier: <removed>
+
+Device Start End Sectors Size Type
+<removed>1 2048 4095 2048 1M Linux filesystem
+<removed>2 8192 10239 2048 1M Linux filesystem
+-------------------
+
+Grow first to max
+
+---layout----------
+Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / <removed> bytes
+Disklabel type: gpt
+Disk identifier: <removed>
+
+Device Start End Sectors Size Type
+<removed>1 2048 8191 6144 3M Linux filesystem
+<removed>2 8192 10239 2048 1M Linux filesystem
+-------------------
+
+Grow second to max
+
+---layout----------
+Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / <removed> bytes
+Disklabel type: gpt
+Disk identifier: <removed>
+
+Device Start End Sectors Size Type
+<removed>1 2048 8191 6144 3M Linux filesystem
+<removed>2 8192 20446 12255 6M Linux filesystem
+-------------------
+
+Resize first to 4096 bytes
+
+---layout----------
+Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / <removed> bytes
+Disklabel type: gpt
+Disk identifier: <removed>
+
+Device Start End Sectors Size Type
+<removed>1 2048 2055 8 4K Linux filesystem
+<removed>2 8192 20446 12255 6M Linux filesystem
+-------------------
+
+Resize second to 8 sectors
+
+---layout----------
+Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / <removed> bytes
+Disklabel type: gpt
+Disk identifier: <removed>
+
+Device Start End Sectors Size Type
+<removed>1 2048 2055 8 4K Linux filesystem
+<removed>2 8192 8199 8 4K Linux filesystem
+-------------------
+
--- /dev/null
+#!/bin/bash
+#
+# This file is part of util-linux.
+#
+# Copyright (C) 2023 Thomas Weißschuh <thomas@t-8ch.de>
+#
+# This file 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 2 of the License, or
+# (at your option) any later version.
+#
+# This file 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.
+#
+#
+
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="resize"
+
+. "$TS_TOPDIR"/functions.sh
+ts_init "$*"
+
+ts_check_test_command "$TS_CMD_FDISK"
+
+TEST_IMAGE_NAME=$(ts_image_init 10)
+
+function print_layout {
+ echo -ne "\n---layout----------\n" >> "$TS_OUTPUT"
+ "$TS_CMD_FDISK" -l "${TEST_IMAGE_NAME}" >> "$TS_OUTPUT" 2>> "$TS_ERRLOG"
+ echo -ne "-------------------\n\n" >> "$TS_OUTPUT"
+
+ ts_fdisk_clean "${TEST_IMAGE_NAME}"
+}
+
+function test_fdisk() {
+ "$TS_CMD_FDISK" --noauto-pt "${TEST_IMAGE_NAME}" &> /dev/null
+}
+
+ts_log "Create initial partitions"
+echo -e "g\nn\n\n\n+1M\nn\n\n8192\n+1M\nw\n" | test_fdisk
+
+print_layout
+
+ts_log "Grow first to max"
+echo -e "e\n1\n\nw\n" | test_fdisk
+
+print_layout
+
+ts_log "Grow second to max"
+echo -e "e\n2\n\nw\n" | test_fdisk
+
+print_layout
+
+ts_log "Resize first to 4096 bytes"
+echo -e "e\n1\n4K\nw\n" | test_fdisk
+
+print_layout
+
+ts_log "Resize second to 8 sectors"
+echo -e "e\n2\n8S\nw\n" | test_fdisk
+
+print_layout
+
+ts_finalize