(root)/
util-linux-2.39/
disk-utils/
resizepart.c
       1  #include <getopt.h>
       2  #include <stdio.h>
       3  #include <stdlib.h>
       4  #include <fcntl.h>
       5  #include <sys/types.h>
       6  #include <sys/stat.h>
       7  #include <unistd.h>
       8  
       9  #include "c.h"
      10  #include "nls.h"
      11  #include "partx.h"
      12  #include "sysfs.h"
      13  #include "strutils.h"
      14  #include "closestream.h"
      15  
      16  static void __attribute__((__noreturn__)) usage(void)
      17  {
      18  	FILE *out = stdout;
      19  	fputs(USAGE_HEADER, out);
      20  	fprintf(out, _(" %s <disk device> <partition number> <length>\n"),
      21  		program_invocation_short_name);
      22  
      23  	fputs(USAGE_SEPARATOR, out);
      24  	fputs(_("Tell the kernel about the new size of a partition.\n"), out);
      25  
      26  	fputs(USAGE_OPTIONS, out);
      27  	printf(USAGE_HELP_OPTIONS(16));
      28  	printf(USAGE_MAN_TAIL("resizepart(8)"));
      29  	exit(EXIT_SUCCESS);
      30  }
      31  
      32  static int get_partition_start(int fd, int partno, uint64_t *start)
      33  {
      34  	struct stat st;
      35  	struct path_cxt *disk = NULL, *part = NULL;
      36  	dev_t devno = 0;
      37  	int rc = -1;
      38  
      39  	/*
      40  	 * wholedisk
      41  	 */
      42  	if (fstat(fd, &st) || !S_ISBLK(st.st_mode))
      43  		goto done;
      44  	devno = st.st_rdev;
      45  	disk = ul_new_sysfs_path(devno, NULL, NULL);
      46  	if (!disk)
      47  		goto done;
      48  	/*
      49  	 * partition
      50  	 */
      51  	devno = sysfs_blkdev_partno_to_devno(disk, partno);
      52  	if (!devno)
      53  		goto done;
      54  
      55  	part = ul_new_sysfs_path(devno, disk, NULL);
      56  	if (!part)
      57  		goto done;
      58  	if (ul_path_read_u64(part, start, "start"))
      59  		goto done;
      60  
      61  	rc = 0;
      62  done:
      63  	ul_unref_path(part);
      64  	ul_unref_path(disk);
      65  	return rc;
      66  }
      67  
      68  int main(int argc, char **argv)
      69  {
      70  	int c, fd, partno;
      71  	const char *wholedisk;
      72  	uint64_t start;
      73  
      74  	static const struct option longopts[] = {
      75  		{"help", no_argument, NULL, 'h'},
      76  		{"version", no_argument, NULL, 'V'},
      77  		{NULL, 0, NULL, '0'},
      78  	};
      79  
      80  	setlocale(LC_ALL, "");
      81  	bindtextdomain(PACKAGE, LOCALEDIR);
      82  	textdomain(PACKAGE);
      83  	close_stdout_atexit();
      84  
      85  	while ((c = getopt_long(argc, argv, "Vh", longopts, NULL)) != -1)
      86  		switch (c) {
      87  		case 'V':
      88  			print_version(EXIT_SUCCESS);
      89  		case 'h':
      90  			usage();
      91  		default:
      92  			errtryhelp(EXIT_FAILURE);
      93  		}
      94  
      95  	if (argc != 4) {
      96  		warnx(_("not enough arguments"));
      97  		errtryhelp(EXIT_FAILURE);
      98  	}
      99  
     100  	wholedisk = argv[1];
     101  	partno = strtou32_or_err(argv[2], _("invalid partition number argument"));
     102  
     103  	if ((fd = open(wholedisk, O_RDONLY)) < 0)
     104  		err(EXIT_FAILURE, _("cannot open %s"), wholedisk);
     105  
     106  	if (get_partition_start(fd, partno, &start))
     107  		err(EXIT_FAILURE, _("%s: failed to get start of the partition number %s"),
     108  				wholedisk, argv[2]);
     109  
     110  	if (partx_resize_partition(fd, partno, start,
     111  			strtou64_or_err(argv[3], _("invalid length argument"))))
     112  		err(EXIT_FAILURE, _("failed to resize partition"));
     113  
     114  	if (close_fd(fd) != 0)
     115  		err(EXIT_FAILURE, _("write failed"));
     116  
     117  	return 0;
     118  }