summaryrefslogtreecommitdiff
diff options
-rwxr-xr-xbin/disk_stress_ng43
-rwxr-xr-xbin/efi-pxeboot149
-rw-r--r--jobs/miscellanea.txt.in14
3 files changed, 201 insertions, 5 deletions
diff --git a/bin/disk_stress_ng b/bin/disk_stress_ng
index 8445488..802d116 100755
--- a/bin/disk_stress_ng
+++ b/bin/disk_stress_ng
@@ -63,11 +63,40 @@ get_params() {
} # get_params()
-# Find the largest partition that holds a supported filesystem on $disk_device.
+# Find the largest logical volume in an LVM partition.
# Output:
# $largest_part -- Device filename of largest qualifying partition
# $largest_size -- Size of largest qualifying partition
# $largest_fs -- Filesystem (ext4, etc.) used on largest qualifying partition
+# Note: Above variables are initialized in find_largest_partition(), which
+# calls this function.
+# Caveat: If LVM is used, there can be no guarantee that a specific disk
+# device is actually being tested. Thus, an LVM configuration should span
+# just one disk device. LVM may be used on one disk, but subsequent disks
+# should use "raw" partitions.
+find_largest_lv() {
+ local partonly=$(echo $partition | cut -f 3 -d "/")
+ for syslv in $(ls -d /sys/block/dm-*/slaves/$partonly) ; do
+ lv=$(echo "$syslv" | cut -f 4 -d "/")
+ size=$(cat /sys/block/$lv/size)
+ sector_size=$(cat /sys/block/$lv/queue/hw_sector_size)
+ let size=$size*$sector_size
+ local blkid_info=$(blkid -s TYPE /dev/$lv | grep -E ext2\|ext3\|ext4\|xfs\|jfs\|btrfs)
+ if [ "$size" -gt "$largest_size" ] && [ -n "$blkid_info" ] ; then
+ local blkid_info=$(blkid -s TYPE /dev/$lv)
+ largest_size=$size
+ largest_part="/dev/$lv"
+ largest_fs=$(blkid -s TYPE "/dev/$lv" | cut -d "=" -f 2)
+ fi
+ done
+} # find_largest_lv()
+
+
+# Find the largest partition that holds a supported filesystem on $disk_device.
+# Output:
+# $largest_part -- Device filename of largest qualifying partition or logical volume
+# $largest_size -- Size of largest qualifying partition or logical volume
+# $largest_fs -- Filesystem (ext4, etc.) used on largest qualifying partition or logicl volume
# $unsupported_fs -- Empty or contains name of unsupported filesystem found on disk
find_largest_partition() {
largest_part=""
@@ -76,11 +105,15 @@ find_largest_partition() {
unsupported_fs=""
for partition in $(echo "$partitions" | cut -d " " -f 1) ; do
part_size=$(echo "$partitions" | grep "$partition " | cut -d " " -f 2)
- local blkid_info=$(blkid -s TYPE /dev/$partition | grep -E ext2\|ext3\|ext4\|xfs\|jfs\|btrfs)
+ local blkid_info=$(blkid -s TYPE /dev/$partition | grep -E ext2\|ext3\|ext4\|xfs\|jfs\|btrfs\|LVM2_member)
if [ "$part_size" -gt "$largest_size" ] && [ -n "$blkid_info" ] ; then
- largest_size=$part_size
- largest_part="/dev/$partition"
- largest_fs=$(blkid -s TYPE "/dev/$partition" | cut -d "=" -f 2)
+ if [[ "$blkid_info" =~ .*LVM2_member.* ]] ; then
+ find_largest_lv
+ else
+ largest_size=$part_size
+ largest_part="/dev/$partition"
+ largest_fs=$(blkid -s TYPE "/dev/$partition" | cut -d "=" -f 2)
+ fi
fi
local blkid_info=$(blkid -s TYPE /dev/$partition | grep -E ntfs\|vfat\|hfs)
if [ -n "$blkid_info" ] ; then
diff --git a/bin/efi-pxeboot b/bin/efi-pxeboot
new file mode 100755
index 0000000..724fefb
--- /dev/null
+++ b/bin/efi-pxeboot
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+
+"""
+Script to test that the system PXE-booted, if run in EFI mode
+
+Copyright (c) 2016 Canonical Ltd.
+
+Authors
+ Rod Smith <rod.smith@canonical.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3,
+as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+The purpose of this script is to identify whether an EFI-based
+system booted from the network (test passes) or from a local disk
+(test fails).
+
+Usage:
+ efi-pxeboot
+"""
+
+import os
+import shlex
+import shutil
+import sys
+
+from subprocess import Popen, PIPE
+
+
+def discover_data():
+ """Extract boot entry and boot order information.
+
+ :returns:
+ boot_entries, boot_order, boot_current
+ """
+ command = "efibootmgr -v"
+ bootinfo_bytes = (Popen(shlex.split(command), stdout=PIPE)
+ .communicate()[0])
+ bootinfo = (bootinfo_bytes.decode(encoding="utf-8", errors="ignore")
+ .splitlines())
+ boot_entries = {}
+ boot_order = []
+ if len(bootinfo) > 1:
+ for s in bootinfo:
+ if "BootOrder" in s:
+ try:
+ boot_order = s.split(":")[1].replace(" ", "").split(",")
+ except IndexError:
+ pass
+ elif "BootCurrent" in s:
+ try:
+ boot_current = s.split(":")[1].strip()
+ except IndexError:
+ pass
+ else:
+ # On Boot#### lines, #### is characters 4-8....
+ hex_value = s[4:8]
+ # ....and the description starts at character 10
+ name = s[10:]
+ try:
+ # In normal efibootmgr output, only Boot#### entries
+ # have characters 4-8 that can be interpreted as
+ # hex values, so this will harmlessly error out on all
+ # but Boot#### entries....
+ int(hex_value, 16)
+ boot_entries[hex_value] = name
+ except ValueError:
+ pass
+ return boot_entries, boot_order, boot_current
+
+
+def is_pxe_booted(boot_entries, boot_order, boot_current):
+ retval = 0
+ desc = boot_entries[boot_current]
+ print("The current boot item is {}".format(boot_current))
+ print("The first BootOrder item is {}".format(boot_order[0]))
+ print("The description of Boot{} is '{}'".format(boot_current, desc))
+ if boot_current != boot_order[0]:
+ # If the BootCurrent entry isn't the same as the first of the
+ # BootOrder entries, then something is causing the first boot entry
+ # to fail or be bypassed. This could be a Secure Boot failure, manual
+ # intervention, a bad boot entry, etc. This is not necessarily a
+ # problem, but warn of it anyhow....
+ desc2 = boot_entries[boot_order[0]]
+ print("The description of Boot{} is '{}'".format(boot_order[0], desc2))
+ print("WARNING: The system is booted using Boot{}, but the first".
+ format(boot_current))
+ print("boot item is Boot{}!".format(boot_order[0]))
+ if "Network" in desc or "PXE" in desc or "NIC" in desc \
+ or "Ethernet" in desc or "IP4" in desc or "IP6" in desc:
+ # These strings are present in network-boot descriptions.
+ print("The system seems to have PXE-booted; all OK.")
+ elif "ubuntu" in desc or "grub" in desc or "shim" in desc or "rEFInd" \
+ or "refind_" in desc:
+ # This string indicates a boot directly from the normal Ubuntu GRUB
+ # or rEFInd installation on the hard disk.
+ print("The system seems to have booted directly from the hard disk!")
+ retval = 1
+ elif "SATA" in desc or "Sata" in desc or "Hard Drive" in desc:
+ # These strings indicate booting with a "generic" disk entry (one
+ # that uses the fallback filename, EFI/BOOT/bootx64.efi or similar).
+ print("The system seems to have booted from a disk with the fallback "
+ "boot loader!")
+ retval = 1
+ else:
+ # Probably a rare description. Call it an error so we can flag it and
+ # improve this script.
+ print("Unable to identify boot path.")
+ retval = 1
+ return retval
+
+
+def main():
+ """Check to see if the system PXE-booted."""
+
+ if shutil.which("efibootmgr") is None:
+ print("The efibootmgr utility is not installed; exiting!")
+ return(4)
+ if not os.geteuid() == 0:
+ print("This program must be run as root (or via sudo); exiting!")
+ return(4)
+
+ retval = 0
+ boot_entries, boot_order, boot_current = discover_data()
+ if boot_entries == {}:
+ print("No EFI boot entries are available. This may indicate a "
+ "firmware problem.")
+ retval = 2
+ if boot_order == []:
+ print("The EFI BootOrder variable is not available. This may "
+ "indicate a firmware")
+ print("problem.")
+ retval = 3
+ if (retval == 0):
+ retval = is_pxe_booted(boot_entries, boot_order, boot_current)
+ return(retval)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/jobs/miscellanea.txt.in b/jobs/miscellanea.txt.in
index b5544c2..e018be5 100644
--- a/jobs/miscellanea.txt.in
+++ b/jobs/miscellanea.txt.in
@@ -132,6 +132,20 @@ command: boot_mode_test secureboot
plugin: shell
category_id: 2013.com.canonical.plainbox::miscellanea
+estimated_duration: 0.5
+user: root
+id: miscellanea/efi_pxeboot
+requires:
+ cpuinfo.platform in ("i386", "x86_64", "aarch64")
+depends: miscellanea/efi_boot_mode
+_summary: Test that system booted from the network
+_description:
+ Test to verify that the system booted from the network.
+ Works only on EFI-based systems.
+command: efi-pxeboot
+
+plugin: shell
+category_id: 2013.com.canonical.plainbox::miscellanea
id: miscellanea/bmc_info
requires:
package.name == 'ipmitool'