2

Let us say that we have the following bash script on a Linux machine, beginning with:

#!/bin/bash
#This setsetcor script takes four arguments: setsector a b c d
#Both a, b, and c and d are integers

a=$1; #The end sector (in 512 byte sectors) of the sdx1 partition
b=$2; #The end sector (in 512 byte sectors) of the sdx2 partition
c=$3; #The end sector (in 512 byte sectors) of the sdx3 partition
d=$4; #The end sector (in 512 byte sectors) of the free space

I have a small SSD disk drive that I copy on to a larger SSD or HD drive in its entirety using the dd utility to make an initial identical copy of the smaller drive to the larger drive.

After that, I want to accomplish the following using calculations made in the script:

  • Keep partitions 1 and 2 exactly the same.
  • Copy partition 3 contents with the dd command to the end of the large disk drive space.
  • Use the cfdisk command to delete the partition in the partition table only, but not its contents for partition 3.
  • Expand partition 2 so that its end is right before the beginning of the copy of partition 3.
  • Recreate partition 3 with the command cfdisk at the very end of the disk drive with its original size.
  • Use the command ntfsresize to expand partition 2.
  • I am assuming that if the proper dd options are used, that it will not need any NTFS resizing of the partition number 3 at the end of the drive. If needed, I need help figuring this out.
  • Because of the complexity of calculating all this, the script should print out the necessary steps.

I keep on trying to use the command cfdisk to accomplish this but am still not arriving at the correct formulas to use to type in the start partition sector number and resize partition sector values there when recreating the partition.

Are there any suggestions on how to calculate and re-partition the three partitions using the end of partition sector values given by variables a, b, c and d at the beginning of the bash script?

terdon
  • 234,489
  • 66
  • 447
  • 667
  • Can you express the formula using math instead of the shell? – choroba May 16 '23 at 07:57
  • "Expand partition 2 ..." then "Delete the partition 2 in order to accomplish this" is that right? You want to expand partition 2 and then delete that very partition and _then_ resize it? – muru May 16 '23 at 08:03
  • Re: @choraba - the Linux **cfdisk** utility just gives these **End sector** values for each partition and also the free space on the copied large disk. Values **a, b, c, and d** are simply inputs to the script. I did not put any calculations here yet as I am totally open as to what formulas and calculations to use in any form you wish to convey these. My problem is that I am having trouble (for some reason) of coming up with the correct formulas so that I can type the results into the Linux **dd** command and **cfdisk** utility to copy and repartition correctly, just using the large disk. – Stephen Elliott May 16 '23 at 08:15
  • Should we assume that the partitions and their corresponding end sectors are in ascending order, that there are no overlaps, and all partitions are contiguous without gaps? (None of these are guaranteed in the real world.) – roaima May 16 '23 at 09:21
  • I found this hint that might be very helpful to arrive at the answer. [Sectors are numbered from 0](https://unix.stackexchange.com/questions/510868/how-to-calculate-partition-start-end-sector) Start: 2048 End: 250069679 Sectors: 250067632 is correct, 250069679 minus 2048 plus one is 250067632: the partition contains 250067632 sectors, starting at offset 2048. – Stephen Elliott May 16 '23 at 09:22
  • I copied another small 64 GB SSD disk to a 500GB larger HD using the Linux **dd** command. I am left with three partitions sectors and free space ending as: sdb1 104447 sdb2 122578943 sdb3 123666431 and free space 976773167. End (sdb3)-End(sdb2)=1087488 Sectors, **equals** the Size(sdb3), The sdb3 partition needs to be moved to the end of the disk, ending at 976773167 sectors. So that sdb2 can be expanded, sdb3 needs to be initially deleted (without a write). If sdb2 is resized to end(free space)-end(sdb1)-size(sdb2), it is still at 1085488 sectors, not the correct 1087488 sectors. – Stephen Elliott May 16 '23 at 11:13
  • 1
    Re: @roaima I checked carefully that the end of the first sector is one less than the beginning of the next sector, all the way through the free space beginning at one sector after the end of the third partition on the large HD. if I understand your question correctly. If not, please update your comment with additional information to help me answer further. – Stephen Elliott May 16 '23 at 12:43
  • I found out with third-party partitioning software, that Windows 10 accepts the partitioning, versus errors (especially with SSD drives that had less than 100% health). So I tried another tool also, downloadable in Ubuntu called GParted. GParted seems to work much better for now versus other (non-GUI) partitioning schemes (especially with 1 MB of margin). – Stephen Elliott Jun 07 '23 at 08:32

1 Answers1

0

The following code implements the answer to the question:

#!/bin/bash
#This setsetcor script takes four arguments: setsector a b c d
#Both a, b, and c and d are integers

a=$1; #The end sector (in 512 byte sectors) of the sdx1 partition
b=$2; #The end sector (in 512 byte sectors) of the sdx2 partition
c=$3; #The end sector (in 512 byte sectors) of the sdx3 partition
d=$4; #The end sector (in 512 byte sectors) of the free space

#Input quantities are printed out
printf "The end (in 512 byte sectors) of the sdx1 partition is a=%dS (512-Byte) Sectors.\n" $((a))
printf "The end (in 512 byte sectors) of the sdx2 partition is b=%dS (512-Byte) Sectors.\n" $((b))
printf "The end (in 512 byte sectors) of the sdx3 partition is c=%dS (512-Byte) Sectors.\n" $((c))
printf "The end (in 512 byte sectors) of the free space     is d=%dS (512-Byte) Sectors.\n" $((d))
printf "\n"

#Simple derivative quantities are calculated and printed
sizeofp2=$(($b-$a))
sizeofp2GB=$((10**2*($b-$a)*512/1024/1024/1024))

sizeofp3=$(($c-$b));
sizeofp3MB=$((10**2*($c-$b)*512/1024/1024));

freespace=$(($d-$c));
freespaceGB=$((10**2*($d-$c)*512/1024/1024/1024));

printf "The size of Partition 2 equals %3.1fGB and %dS (512-Byte) Sectors. \n" $(($sizeofp2GB))e-2 $sizeofp2
printf "The size of Partition 3 equals %3.1fMB and %dS (512-Byte) Sectors. \n" $(($sizeofp3MB))e-2 $sizeofp3
printf "The Free Space equals %3.2fGB and %dS (512-Byte) Sectors.\n" $(($freespaceGB))e-2 $freespace
printf "\n"

#Calculate the new partition #2 and partition #3, Sectors and MB.  Adjustments need to be made in Sectors to avoid rounding.
printf "Delete Partition 3; then delete the Partition 2 (without saving the partition table). \n\n"

printf "A new Partition 2 needs to be formed, (type 7) with the Sector size (of the origninal partition 2 Sectors \n"
printf "plus the original Free Space Sectors). \n\n"

printf "Then Partition 3 (type 27) is formed with its original Sector size, to avoid rounding errors:\n\n"

sizeofnewp2=$(($sizeofp2+$freespace))
sizeofnewp2GB=$((10**2*($sizeofp2+$freespace)*512/1024/1024/1024));

printf "The size of the new partition 2 equals %3.1fGB and %dS (512-Byte) Sectors. \n" $(($sizeofnewp2GB))e-2 $sizeofnewp2
printf "The size of the new partition 3 equals %3.1fMB and %dS (512-Byte) Sectors. \n\n" $(($sizeofp3MB))e-2 $sizeofp3

printf "After all of the ajustements are made (including setting the Partition types properly), save the Partition Table.\n"

There are a few situations where the size of the partition number two needs to be decreased slightly, say around 0.1 GB, to make more room for the original partition 3 in sectors. Other than that, it seems to work well with cfdisk. (I suspect some round-off error is creating this small variance, but for now I have something useful. Note also that I print out the cfdisk partition-types that I use for my convenience. It should be adjusted according to the end-user's application.)