summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Hopkins <liamh@google.com>2020-03-25 10:17:50 -0700
committerGitHub <noreply@github.com>2020-03-25 10:17:50 -0700
commitdad8239611d85fc697ff0905d60f00cc66ad747d (patch)
tree4db9108aa9e7e32008176add3455b6a6ab987e4b
parenteff97a73ff7e8a8f06ba77175e91f4b1dfc6d05e (diff)
downloadgoogle-compute-image-packages-dad8239611d85fc697ff0905d60f00cc66ad747d.tar.gz
fix bugs in disk-expand (#879)
-rw-r--r--packages/gce-disk-expand/packaging/debian/control1
-rw-r--r--packages/gce-disk-expand/packaging/gce-disk-expand.spec4
-rwxr-xr-xpackages/gce-disk-expand/src/expandfs-lib.sh42
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh19
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install1
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/initramfs-tools/hooks/expand-rootfs2
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/initramfs-tools/scripts/local-premount/expand_rootfs16
7 files changed, 50 insertions, 35 deletions
diff --git a/packages/gce-disk-expand/packaging/debian/control b/packages/gce-disk-expand/packaging/debian/control
index ac38b5d..92f2e1b 100644
--- a/packages/gce-disk-expand/packaging/debian/control
+++ b/packages/gce-disk-expand/packaging/debian/control
@@ -9,6 +9,7 @@ Homepage: https://github.com/GoogleCloudPlatform/compute-image-packages
Package: gce-disk-expand
Architecture: all
Depends: parted,
+ gdisk,
${misc:Depends}
Description: Automatically resize the root partition on first boot.
This package resizes the root partition on first boot using parted.
diff --git a/packages/gce-disk-expand/packaging/gce-disk-expand.spec b/packages/gce-disk-expand/packaging/gce-disk-expand.spec
index 409d898..3f6c0dc 100644
--- a/packages/gce-disk-expand/packaging/gce-disk-expand.spec
+++ b/packages/gce-disk-expand/packaging/gce-disk-expand.spec
@@ -20,9 +20,11 @@ License: Apache Software License
Group: System Environment/Base
URL: https://github.com/GoogleCloudPlatform/compute-image-packages
Source0: %{name}_%{version}.orig.tar.gz
-Requires: e2fsprogs, dracut, grep, util-linux, parted
+Requires: e2fsprogs, dracut, grep, util-linux, parted, gdisk
Conflicts: dracut-modules-growroot
+BuildRequires: rsync
+
# Allow other files in the source that don't end up in the package.
%define _unpackaged_files_terminate_build 0
diff --git a/packages/gce-disk-expand/src/expandfs-lib.sh b/packages/gce-disk-expand/src/expandfs-lib.sh
index 69f67ed..4a02b9f 100755
--- a/packages/gce-disk-expand/src/expandfs-lib.sh
+++ b/packages/gce-disk-expand/src/expandfs-lib.sh
@@ -29,8 +29,8 @@ resize_filesystem() {
;;
ext*)
if ! out=$(e2fsck -pf "$disk"); then
- echo "Calling e2fsck \"${disk}\" failed: ${out}"
- return 1
+ local ret=$?
+ echo "Calling e2fsck \"${disk}\" failed: ${out} exit code ${ret}"
fi
if ! out=$(resize2fs "$disk"); then
echo "Calling resize2fs \"${disk}\" failed: ${out}"
@@ -60,32 +60,31 @@ blkid_get_fstype() (
echo $ID_FS_TYPE
)
+sgdisk_get_label() {
+ local root="$1"
+ [ -z "$root" ] && return 0
+
+ if sgdisk -p "$root" | grep -q "Found invalid GPT and valid MBR"; then
+ echo "mbr"
+ else
+ echo "gpt"
+ fi
+}
-# Checks for and corrects the end-of-disk GPT backup block in case of expanded
-# disk.
-parted_fix_gpt() {
+sgdisk_fix_gpt() {
local disk="$1"
[ -z "$disk" ] && return
- if parted -sm "$disk" print 2>&1 | grep -q "fix the GPT"; then
- # Running parted prompts the user to fix this condition, but only does so in
- # the interactive exception handler. In order to pass input we must use the
- # hidden triple-dash flag and pass both print and Fix arguments. `print`
- # alone will not perform the fix, but `Fix` alone will fail the argument
- # parser.
- parted -m ---pretend-input-tty "$disk" print Fix >/dev/null 2>&1 </dev/null
- parted -m ---pretend-input-tty "$disk" print Fix >/dev/null 2>&1 </dev/null
- if parted -sm "$disk" print 2>&1 | grep -q "fix the GPT"; then
- echo "Failed to fix the GPT."
- return 1
- fi
- fi
+ local label=$(sgdisk_get_label "$disk")
+ [ "$label" != "gpt" ] && return
+
+ sgdisk --move-second-header "$disk"
}
# Returns "disk:partition", supporting multiple block types.
split_partition() {
local root="$1" disk="" partnum=""
- [ -z "$root" ] && return
+ [ -z "$root" ] && return 0
if [ -e /sys/block/${root##*/} ]; then
echo "Root is not a partition, skipping partition resize."
@@ -104,7 +103,10 @@ split_partition() {
# Checks if partition needs resizing.
parted_needresize() {
local disk="$1" partnum="$2" disksize="" partend=""
- [ -z "$root" ] && return
+ if [ -z "$disk" ] || [ -z "$partnum" ]; then
+ echo "invalid args to parted_needresize"
+ return 1
+ fi
if ! out=$(parted -sm "$disk" unit b print 2>&1); then
echo "Failed to get disk details: ${out}"
diff --git a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh
index 3d12b35..62d7171 100755
--- a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh
+++ b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh
@@ -16,6 +16,12 @@
# Contains dracut-specific logic for detecting disk, then calls appropriate
# library functions.
+# Notes for developing dracut modules: this module must never exit with anything
+# other than a 0 exit code. That means no use of set -e or traps on err, and
+# every command must be defensively written so that errors are caught and
+# logged, rather than causing end of execution. Note that error handling in the
+# main() function always calls return 0
+
kmsg() {
echo "expand_rootfs: $@" > /dev/kmsg
}
@@ -49,13 +55,14 @@ main() {
kmsg "Resizing disk ${rootdev}"
+ # First, move the secondary GPT to the end.
+ if ! out=$(sgdisk_fix_gpt "$disk"); then
+ kmsg "Failed to fix GPT: ${out}"
+ fi
+
if ! out=$(parted_resizepart "$disk" "$partnum"); then
- # Try fixing the GPT and try resizing again.
- parted_fix_gpt "$disk"
- if ! out=$(parted_resizepart "$disk" "$partnum"); then
- kmsg "Failed to resize partition: ${out}"
- return
- fi
+ kmsg "Failed to resize partition: ${out}"
+ return
fi
if ! out=$(resize_filesystem "$rootdev"); then
diff --git a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install
index cdd021d..4fa6a5b 100755
--- a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install
+++ b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install
@@ -21,6 +21,7 @@ inst_hook pre-mount 50 "$moddir/expand_rootfs.sh"
inst_hook pre-pivot 99 "$moddir/xfs_growfs.sh"
dracut_install parted
+dracut_install sgdisk
dracut_install cut
dracut_install sed
dracut_install grep
diff --git a/packages/gce-disk-expand/src/usr/share/initramfs-tools/hooks/expand-rootfs b/packages/gce-disk-expand/src/usr/share/initramfs-tools/hooks/expand-rootfs
index dae461a..a463ea5 100755
--- a/packages/gce-disk-expand/src/usr/share/initramfs-tools/hooks/expand-rootfs
+++ b/packages/gce-disk-expand/src/usr/share/initramfs-tools/hooks/expand-rootfs
@@ -36,3 +36,5 @@ copy_exec /sbin/e2fsck /bin
copy_exec /sbin/blkid /bin
copy_exec /sbin/resize2fs /bin
copy_exec /bin/udevadm /bin
+copy_exec /usr/sbin/dmidecode /bin
+copy_exec /sbin/sgdisk /bin
diff --git a/packages/gce-disk-expand/src/usr/share/initramfs-tools/scripts/local-premount/expand_rootfs b/packages/gce-disk-expand/src/usr/share/initramfs-tools/scripts/local-premount/expand_rootfs
index a380bc2..9b59b20 100755
--- a/packages/gce-disk-expand/src/usr/share/initramfs-tools/scripts/local-premount/expand_rootfs
+++ b/packages/gce-disk-expand/src/usr/share/initramfs-tools/scripts/local-premount/expand_rootfs
@@ -29,15 +29,15 @@ esac
. /scripts/expandfs-lib.sh
if ! rootdev=$(resolve_device "${ROOT}"); then
- log_failure_message "Failed to resolve root device for \"${ROOT}\""
+ log_failure_msg "Failed to resolve root device for \"${ROOT}\""
fi
if ! fs_type=$(get_fstype "${rootdev}"); then
- log_failure_message "Failed to determine fstype for \"${rootdev}\""
+ log_failure_msg "Failed to determine fstype for \"${rootdev}\""
fi
if ! out=$(split_partition "$rootdev"); then
- log_failure_message "Failed to detect disk and partition info: ${out}"
+ log_failure_msg "Failed to detect disk and partition info: ${out}"
exit 0
fi
@@ -45,23 +45,23 @@ disk=${out%:*}
partnum=${out#*:}
if ! parted_needresize "${disk}" "${partnum}"; then
- log_success_message "Disk ${rootdev} doesn't need resizing."
+ log_success_msg "Disk ${rootdev} doesn't need resizing."
exit 0
fi
-if ! out=$(parted_fix_gpt "$disk"); then
- log_failure_message "Failed to fix GPT: ${out}"
+if ! out=$(sgdisk_fix_gpt "$disk"); then
+ log_failure_msg "Failed to fix GPT: ${out}"
exit 0
fi
echo "Resizing partition on ${rootdev}"
if ! out=$(parted_resizepart "${disk}" "${partnum}"); then
- log_failure_message "Failed to resize partition: ${out}"
+ log_failure_msg "Failed to resize partition: ${out}"
exit 0
fi
echo "Resizing filesystem on ${rootdev}"
if ! out=$(resize_filesystem "${rootdev}"); then
- log_failure_message "Failed to resize filesystem: ${out}"
+ log_failure_msg "Failed to resize filesystem: ${out}"
exit 0
fi