root / snf-image-helper / tasks / 10FixPartitionTable.in @ 438f7bfb
History | View | Annotate | Download (6 kB)
1 |
#! /bin/bash |
---|---|
2 |
|
3 |
# Copyright (C) 2011 GRNET S.A. |
4 |
# |
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. |
9 |
# |
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. |
14 |
# |
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 |
18 |
# 02110-1301, USA. |
19 |
|
20 |
### BEGIN TASK INFO |
21 |
# Provides: FixPartitionTable |
22 |
# RunBefore: FilesystemResizeUnmounted |
23 |
# Short-Description: Enlarge last partition to use all the available space |
24 |
### END TASK INFO |
25 |
|
26 |
set -e |
27 |
. "@commondir@/common.sh" |
28 |
|
29 |
trap task_cleanup EXIT |
30 |
report_task_start |
31 |
# Check if the task should be prevented from running. |
32 |
check_if_excluded |
33 |
|
34 |
if [ ! -b "$SNF_IMAGE_DEV" ]; then |
35 |
log_error "Device file:\`${SNF_IMAGE_DEV}' is not a block device" |
36 |
fi |
37 |
|
38 |
if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^(open|net)bsd$ ]]; then |
39 |
@scriptsdir@/disklabel.py -d "$($BLOCKDEV --getsz "$SNF_IMAGE_DEV")" -p "$SNF_IMAGE_DEV" |
40 |
# Tell the kernel to recreate the disk partitions. |
41 |
# We cannot use partprobe to do this because partprobe uses BLKPG ioctl |
42 |
# to create the partitions device files by itself one by one. Since parted |
43 |
# does not support disklabels, the partitions with id larger than 4 will |
44 |
# not be created. |
45 |
# We need to tell the kernel to read the partition table by itself. |
46 |
$BLOCKDEV --rereadpt "$SNF_IMAGE_DEV" |
47 |
exit 0 |
48 |
fi |
49 |
|
50 |
table=$(get_partition_table "$SNF_IMAGE_DEV") |
51 |
|
52 |
if [ $(get_partition_count "$table") -eq 0 ]; then |
53 |
log_error "Device: \`${SNF_IMAGE_DEV}' does not contain any partition" |
54 |
fi |
55 |
|
56 |
table_type=$(get_partition_table_type "$table") |
57 |
|
58 |
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "freebsd" -a "$table_type" != "gpt" ]; then |
59 |
log_error "The image contains a(n) $table_type partition table. " \ |
60 |
"For FreeBSD images only GUID Partition Tables are supported." |
61 |
fi |
62 |
|
63 |
if [ "$table_type" == "gpt" ]; then |
64 |
"$SGDISK" --move-second-header "$SNF_IMAGE_DEV" |
65 |
elif [ "$table_type" != "msdos" ]; then |
66 |
log_error "Device: \'${SNF_IMAGE_DEV}' contains unsupported partition " \ |
67 |
"table type: \`$table_type'. Only msdos & gpt partitions are" \ |
68 |
"supported." |
69 |
fi |
70 |
|
71 |
last_part=$(get_last_partition "$table") |
72 |
last_part_id=$(cut -d':' -f1 <<< "$last_part") |
73 |
|
74 |
# Check if swap is defined... |
75 |
if [ -n "$SNF_IMAGE_PROPERTY_SWAP" ]; then |
76 |
if [[ "$SNF_IMAGE_PROPERTY_SWAP" =~ ^([0-9]+):([0-9]+)$ ]]; then |
77 |
swap_num=${BASH_REMATCH[1]} |
78 |
swap_size=${BASH_REMATCH[2]} |
79 |
swap_unit="MB" |
80 |
else |
81 |
log_error "SWAP property \`$SNF_IMAGE_PROPERTY_SWAP' is not valid" |
82 |
fi |
83 |
fi |
84 |
|
85 |
if [ -z "$swap_num" ]; then |
86 |
swap_num=0 |
87 |
fi |
88 |
|
89 |
# Most partition setups leave 2048s in the end. For GPT partitions you need at |
90 |
# least 34s for the secondary GPT header. |
91 |
new_end="-2049" |
92 |
|
93 |
if [ $swap_num -ne 0 ]; then |
94 |
free=$(get_last_free_sector "$SNF_IMAGE_DEV" "$swap_unit") |
95 |
free_size=$(cut -d: -f4 <<< "$free") |
96 |
free_size_val=${free_size/$swap_unit/} |
97 |
if [ $free_size_val -le $swap_size ]; then |
98 |
log_error "Not enough space for swap partition" |
99 |
fi |
100 |
|
101 |
swap_end="$new_end" |
102 |
|
103 |
swap_start=$((new_end - (swap_size * 2048) + 1)) # in sectors |
104 |
new_end=$((swap_start - 1)) |
105 |
fi |
106 |
|
107 |
extended="" |
108 |
|
109 |
if [ "$table_type" != "msdos" ]; then |
110 |
# For gpt partitions, get the partition GUID code as partition type |
111 |
last_part_type="$($SGDISK -i "$last_part_id" "$SNF_IMAGE_DEV" | grep "^Partition GUID code:" | cut -d"(" -f1 | cut -d: -f2 | xargs echo)" |
112 |
elif [ $last_part_id -gt 4 ]; then |
113 |
last_part_type="logical" |
114 |
extended=$(get_extended_partition "$table") |
115 |
last_primary=$(get_last_primary_partition "$table") |
116 |
|
117 |
ext_id=$(cut -d':' -f1 <<< "$extended") |
118 |
last_prim_id=$(cut -d':' -f1 <<< "$last_primary") |
119 |
|
120 |
if [ "$ext_id" != "$last_prim_id" ]; then |
121 |
# Mark last primary as the last partition |
122 |
last_part="$extended" |
123 |
last_part_id="$ext_id" |
124 |
last_part_type="primary" |
125 |
else |
126 |
# Enlarge the extended partition |
127 |
if [ $swap_num -ge 5 ]; then |
128 |
# This is needed because logical partitions need to have at least |
129 |
# 1 sector gap between them. We make the gap 2048 sectors to |
130 |
# properly align them. |
131 |
new_end=$((new_end - 2048)) |
132 |
enlarge_partition "$SNF_IMAGE_DEV" "$extended" "extended" "${swap_end}s" |
133 |
else |
134 |
enlarge_partition "$SNF_IMAGE_DEV" "$extended" "extended" "${new_end}s" |
135 |
fi |
136 |
fi |
137 |
elif [ $(is_extended_partition "$SNF_IMAGE_DEV" "$last_part_id") = "yes" ]; then |
138 |
last_part_type="extended" |
139 |
extended="$last_part" |
140 |
if [ $swap_num -ge 5]; then |
141 |
new_end=$swap_end |
142 |
fi |
143 |
else |
144 |
last_part_type="primary" |
145 |
if [ $swap_num -ge 5 ]; then |
146 |
# This is needed because the swap partition should be added inside a |
147 |
# new extended partition. In order to align the swap partition, we |
148 |
# need to create some extra space between the (aligned) primary and |
149 |
# the swap. |
150 |
new_end=$((new_end - 2048)) |
151 |
fi |
152 |
fi |
153 |
|
154 |
enlarge_partition "$SNF_IMAGE_DEV" "$last_part" "$last_part_type" "${new_end}s" |
155 |
|
156 |
if [ $swap_num -gt 0 ]; then |
157 |
swap_part="$swap_num:${swap_start}s:${swap_end}s:0:linux-swap(v1)::;" |
158 |
if [ "$table_type" != "msdos" ]; then |
159 |
swap_ptype="swap" # in gpt this is used as a partition name |
160 |
elif [ $swap_num -ge 5 ]; then |
161 |
if [ -z "$extended" ]; then |
162 |
extended="0:$((swap_start - 2))s:${swap_end}s:0:::;" |
163 |
create_partition "$SNF_IMAGE_DEV" "$extended" "extended" |
164 |
fi |
165 |
swap_ptype="logical" |
166 |
else |
167 |
swap_ptype="primary" |
168 |
fi |
169 |
create_partition "$SNF_IMAGE_DEV" "$swap_part" "$swap_ptype" |
170 |
fi |
171 |
|
172 |
# Inform the kernel about the changes |
173 |
partprobe "$SNF_IMAGE_DEV" |
174 |
|
175 |
exit 0 |
176 |
|
177 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |