summaryrefslogtreecommitdiff
diff options
-rwxr-xr-xbin/fstrim_test86
-rw-r--r--units/disk/jobs.pxu14
2 files changed, 100 insertions, 0 deletions
diff --git a/bin/fstrim_test b/bin/fstrim_test
new file mode 100755
index 00000000..c66d421c
--- /dev/null
+++ b/bin/fstrim_test
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+
+# Test fstrim functionality on a disk device
+#
+# Copyright (C) 2020 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/>.
+#
+"""
+This script checks to see if a block device supports TRIM via a call to the
+fstrim utility. This requires ensuring that a Linux partition on the target
+device be mounted, so this script does this, if necessary.
+
+The script returns 0 on success and 1 on failure, with output
+via Python logging about the nature of the success/failure.
+"""
+
+
+import logging
+import shlex
+import sys
+from argparse import ArgumentParser
+from subprocess import (
+ PIPE,
+ Popen
+)
+import disk_support
+
+
+def mount_filesystem(device):
+ if "/dev" not in device and device != "":
+ device = "/dev/" + device
+
+ test_disk = disk_support.Disk(device)
+ mount_point = None
+ if test_disk.mount_filesystem(False):
+ mount_point = test_disk.get_mount_point()
+ logging.info("mount point is {}".format(test_disk.get_mount_point()))
+ if not mount_point:
+ logging.error("Test failed; {} is not mounted!".format(device))
+
+ return mount_point
+
+
+def run_fstrim(device):
+ mount_point = mount_filesystem(device)
+ if mount_point is not None:
+ command = "fstrim -v {}".format(mount_point)
+ triminfo = Popen(shlex.split(command), stdout=PIPE)
+ lsbinfo_bytes = triminfo.communicate()[0]
+ lsbinfo = lsbinfo_bytes.decode(encoding="utf-8",
+ errors="ignore").rstrip()
+ logging.info(lsbinfo)
+ retval = triminfo.returncode
+ else:
+ retval = 1
+ return retval
+
+
+def main():
+ parser = ArgumentParser()
+ parser.add_argument('--device-file', default="sda",
+ help='The file within /dev that maps to the device')
+ args = parser.parse_args()
+ logger = logging.getLogger()
+ logger.setLevel(logging.INFO)
+ retval = run_fstrim(args.device_file)
+
+ return retval
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/units/disk/jobs.pxu b/units/disk/jobs.pxu
index 431cb2e3..caafbad8 100644
--- a/units/disk/jobs.pxu
+++ b/units/disk/jobs.pxu
@@ -82,6 +82,20 @@ template-resource: device
template-filter: device.category == 'DISK'
plugin: shell
category_id: com.canonical.plainbox::disk
+id: disk/fstrim_{name}
+estimated_duration: 1.0
+user: root
+requires:
+ block_device.rotation == 'no' and block_device.name == '{name}'
+_summary: Filesystem TRIM check for {product_slug}
+_description: Take the path of the storage device and test its TRIM capabilities
+command: fstrim_test --device-file {name}
+
+unit: template
+template-resource: device
+template-filter: device.category == 'DISK'
+plugin: shell
+category_id: com.canonical.plainbox::disk
id: disk/disk_stress_ng_{name}
estimated_duration: 4560.0
user: root