Statistics
| Branch: | Tag: | Revision:

root / snf-image-helper / tasks / 10FixPartitionTable.in @ de34e7aa

History | View | Annotate | Download (5.7 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" = openbsd ]; then
39
    @scriptsdir@/disklabel.py -d "$(blockdev --getsz "$SNF_IMAGE_DEV")" -p "$SNF_IMAGE_DEV"
40
    exit 0
41
fi
42

    
43
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = netbsd ]; then
44
    warn "Partition resizing currently not supported for NetBSD"
45
    exit 0
46
fi
47

    
48
table=$(get_partition_table "$SNF_IMAGE_DEV")
49

    
50
if [ $(get_partition_count "$table") -eq 0 ]; then
51
    log_error "Device: \`${SNF_IMAGE_DEV}' does not contain any partition"
52
fi
53

    
54
table_type=$(get_partition_table_type "$table")
55

    
56
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "freebsd" -a "$table_type" != "gpt" ]; then
57
    log_error "The image contains a(n) $table_type partition table. " \
58
        "For FreeBSD images only GUID Partition Tables are supported."
59
fi
60

    
61
if [ "$table_type" == "gpt" ]; then
62
    "$SGDISK" --move-second-header "$SNF_IMAGE_DEV"
63
elif [ "$table_type" != "msdos" ]; then
64
    log_error "Device: \'${SNF_IMAGE_DEV}' contains unsupported partition " \
65
              "table type: \`$table_type'. Only msdos & gpt partitions are" \
66
              "supported."
67
fi
68

    
69
last_part=$(get_last_partition "$table")
70
last_part_id=$(cut -d':' -f1 <<< "$last_part")
71

    
72
# Check if swap is defined...
73
if [ -n "$SNF_IMAGE_PROPERTY_SWAP" ]; then
74
    if [[ "$SNF_IMAGE_PROPERTY_SWAP" =~ ^([0-9]+):([0-9]+)$ ]]; then
75
        swap_num=${BASH_REMATCH[1]}
76
        swap_size=${BASH_REMATCH[2]}
77
        swap_unit="MB"
78
    else
79
        log_error "SWAP property \`$SNF_IMAGE_PROPERTY_SWAP' is not valid"
80
    fi
81
fi
82

    
83
if [ -z "$swap_num" ]; then
84
    swap_num=0
85
fi
86

    
87
# Most partition setups leave 2048s in the end. For GPT partitions you need at
88
# least 34s for the secondary GPT header.
89
new_end="-2049"
90

    
91
if [ $swap_num -ne 0 ]; then
92
    free=$(get_last_free_sector "$SNF_IMAGE_DEV" "$swap_unit")
93
    free_size=$(cut -d: -f4 <<< "$free")
94
    free_size_val=${free_size/$swap_unit/}
95
    if [ $free_size_val -le $swap_size ]; then
96
        log_error "Not enough space for swap partition"
97
    fi
98

    
99
    swap_end="$new_end"
100

    
101
    swap_start=$((new_end - (swap_size * 2048) + 1)) # in sectors
102
    new_end=$((swap_start - 1))
103
fi
104

    
105
extended=""
106

    
107
if [ "$table_type" != "msdos" ]; then
108
    # For gpt partitions, get the partition GUID code as partition type
109
    last_part_type="$($SGDISK -i "$last_part_id" "$SNF_IMAGE_DEV" | grep "^Partition GUID code:" | cut -d"(" -f1 | cut -d: -f2 | xargs echo)"
110
elif [ $last_part_id -gt 4 ]; then
111
    last_part_type="logical"
112
    extended=$(get_extended_partition "$table")
113
    last_primary=$(get_last_primary_partition "$table")
114

    
115
    ext_id=$(cut -d':' -f1 <<< "$extended")
116
    last_prim_id=$(cut -d':' -f1 <<< "$last_primary")
117

    
118
    if [ "$ext_id" != "$last_prim_id" ]; then
119
        # Mark last primary as the last partition
120
        last_part="$extended"
121
        last_part_id="$ext_id"
122
        last_part_type="primary"
123
    else
124
        # Enlarge the extended partition
125
        if [ $swap_num -ge 5 ]; then
126
            # This is needed because logical partitions need to have at least
127
            # 1 sector gap between them. We make the gap 2048 sectors to
128
            # properly align them.
129
            new_end=$((new_end - 2048))
130
            enlarge_partition "$SNF_IMAGE_DEV" "$extended" "extended" "${swap_end}s"
131
        else
132
            enlarge_partition "$SNF_IMAGE_DEV" "$extended" "extended" "${new_end}s"
133
        fi
134
    fi
135
elif [ $(is_extended_partition "$SNF_IMAGE_DEV" "$last_part_id") = "yes" ]; then
136
    last_part_type="extended"
137
    extended="$last_part"
138
    if [ $swap_num -ge 5]; then
139
        new_end=$swap_end
140
    fi
141
else
142
    last_part_type="primary"
143
    if [ $swap_num -ge 5 ]; then
144
        # This is needed because the swap partition should be added inside a
145
        # new extended partition. In order to align the swap partition, we
146
        # need to create some extra space between the (aligned) primary and
147
        # the swap.
148
        new_end=$((new_end - 2048))
149
    fi
150
fi
151

    
152
enlarge_partition "$SNF_IMAGE_DEV" "$last_part" "$last_part_type" "${new_end}s"
153

    
154
if [ $swap_num -gt 0 ]; then
155
    swap_part="$swap_num:${swap_start}s:${swap_end}s:0:linux-swap(v1)::;"
156
    if [ "$table_type" != "msdos" ]; then
157
        swap_ptype="swap" # in gpt this is used as a partition name
158
    elif [ $swap_num -ge 5 ]; then
159
        if [ -z "$extended" ]; then
160
            extended="0:$((swap_start - 2))s:${swap_end}s:0:::;"
161
            create_partition "$SNF_IMAGE_DEV" "$extended" "extended"
162
        fi
163
        swap_ptype="logical"
164
    else
165
        swap_ptype="primary"
166
    fi
167
    create_partition "$SNF_IMAGE_DEV" "$swap_part" "$swap_ptype"
168
fi
169

    
170
# Inform the kernel about the changes
171
partprobe "$SNF_IMAGE_DEV"
172

    
173
exit 0
174

    
175
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :