3 # Copyright (C) 2011 GRNET S.A.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 # Provides: FixPartitionTable
22 # RunBefore: FilesystemResizeUnmounted
23 # Short-Description: Enlarge last partition to use all the available space
27 . "@commondir@/common.sh"
29 trap task_cleanup EXIT
31 # Check if the task should be prevented from running.
34 if [ ! -b "$SNF_IMAGE_DEV" ]; then
35 log_error "Device file:\`${SNF_IMAGE_DEV}' is not a block device"
38 table=$(get_partition_table "$SNF_IMAGE_DEV")
40 if [ $(get_partition_count "$table") -eq 0 ]; then
41 log_error "Device: \`${SNF_IMAGE_DEV}' does not contain any partition"
44 table_type=$(get_partition_table_type "$table")
46 if [ "$table_type" == "gpt" ]; then
47 "@scriptsdir@/fix_gpt.py" "$SNF_IMAGE_DEV" $($BLOCKDEV --getsz "$SNF_IMAGE_DEV")
48 elif [ "$table_type" != "msdos" ]; then
49 log_error "Device: \'${SNF_IMAGE_DEV}' contains unsupported partition "
50 "table type: \`$table_type'. Only msdos & gpt partitions are supported."
53 last_part=$(get_last_partition "$table")
54 last_part_id=$(cut -d':' -f1 <<< "$last_part")
56 # Check if swap is defined...
57 if [ -n "$SNF_IMAGE_PROPERTY_SWAP" ]; then
58 if [[ "$SNF_IMAGE_PROPERTY_SWAP" =~ ^([0-9]+):([0-9]+)$ ]]; then
59 swap_num=${BASH_REMATCH[1]}
60 swap_size=${BASH_REMATCH[2]}
63 log_error "SWAP property \`$SNF_IMAGE_PROPERTY_SWAP' is not valid"
67 if [ -z "$swap_num" ]; then
71 # Most partition setups leave 2048s in the end. For GPT partitions you need at
72 # least 34s for the secondary GPT header.
75 if [ $swap_num -ne 0 ]; then
76 free=$(get_last_free_sector "$SNF_IMAGE_DEV" "$swap_unit")
77 free_size=$(cut -d: -f4 <<< "$free")
78 free_size_val=${free_size/$swap_unit/}
79 if [ $free_size_val -le $swap_size ]; then
80 log_error "Not enough space for swap partition"
85 swap_start=$((new_end - (swap_size * 2048) + 1)) # in sectors
86 new_end=$((swap_start - 1))
91 if [ "$table_type" != "msdos" ]; then
92 # Primary, extended and logical partitions is a concept for msdos partition
93 # tables. Parted's mkpart will use part-type as partition name if applied
94 # on a gpt table and leaving this empty is fragile: For a strange reason
95 # for swap partitions the command fails (???)
96 last_part_type="primary"
97 elif [ $last_part_id -gt 4 ]; then
98 last_part_type="logical"
99 extended=$(get_extended_partition "$table")
100 last_primary=$(get_last_primary_partition "$table")
102 ext_id=$(cut -d':' -f1 <<< "$extended")
103 last_prim_id=$(cut -d':' -f1 <<< "$last_primary")
105 if [ "$ext_id" != "$last_prim_id" ]; then
106 # Mark last primary as the last partition
107 last_part="$extended"
108 last_part_id="$ext_id"
109 last_part_type="primary"
111 # Enlarge the extended partition
112 if [ $swap_num -ge 5 ]; then
113 # This is needed because logical partitions need to have at least
114 # 1 sector gap between them. We make the gap 2048 sectors to
115 # properly align them.
116 new_end=$((new_end - 2048))
117 enlarge_partition "$SNF_IMAGE_DEV" "$extended" "extended" "${swap_end}s"
119 enlarge_partition "$SNF_IMAGE_DEV" "$extended" "extended" "${new_end}s"
122 elif [ $(is_extended_partition "$SNF_IMAGE_DEV" "$last_part_id") = "yes" ]; then
123 last_part_type="extended"
124 extended="$last_part"
125 if [ $swap_num -ge 5]; then
129 last_part_type="primary"
130 if [ $swap_num -ge 5 ]; then
131 # This is needed because the swap partition should be added inside a
132 # new extended partition. In order to align the swap partition, we
133 # need to create some extra space between the (aligned) primary and
135 new_end=$((new_end - 2048))
139 enlarge_partition "$SNF_IMAGE_DEV" "$last_part" "$last_part_type" "${new_end}s"
141 if [ $swap_num -gt 0 ]; then
142 swap_part="$swap_num:${swap_start}s:${swap_end}s:0:linux-swap(v1)::;"
143 if [ "$table_type" != "msdos" ]; then
144 swap_ptype="swap" # in gpt this is used as a partition name
145 elif [ $swap_num -ge 5 ]; then
146 if [ -z "$extended" ]; then
147 extended="0:$((swap_start - 2))s:${swap_end}s:0:::;"
148 create_partition "$SNF_IMAGE_DEV" "$extended" "extended"
154 create_partition "$SNF_IMAGE_DEV" "$swap_part" "$swap_ptype"
157 # Inform the kernel about the changes
158 partprobe "$SNF_IMAGE_DEV"
162 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :