[PATCH] discover: Mount with norecovery, avoid rw mount of XFS filesystems

Samuel Mendoza-Jonas sam.mj at au1.ibm.com
Wed Mar 25 14:14:56 AEDT 2015


Journaled filesytems may still write to their disk even if the disk is
mounted read only. Petitboot should avoid modifying any disks
automatically, and in mixed-endian systems this can also cause journal
operations to fail. Use the 'norecovery' option on filesystems that
support it to skip the journal replay.

Additionally, mounting an XFS filesystem as read-write in such a case
will cause the call to mount to hang indefinitely. Avoid writing to XFS
filesystems until direct writes are supported.

Signed-off-by: Samuel Mendoza-Jonas <sam.mj at au1.ibm.com>
---
 discover/device-handler.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/discover/device-handler.c b/discover/device-handler.c
index 5d9f988..d07df25 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -1082,6 +1082,20 @@ static void device_handler_reinit_sources(struct device_handler *handler)
 			handler->dry_run);
 }
 
+static const char *fs_parameters(unsigned int rw_flags, const char *fstype)
+{
+	if ((rw_flags | MS_RDONLY) != MS_RDONLY)
+		return "";
+
+	/* Avoid writing back to the disk on journaled filesystems */
+	if (!strncmp(fstype, "ext4", strlen("ext4")))
+		return "norecovery";
+	if (!strncmp(fstype, "xfs", strlen("xfs")))
+		return "norecovery";
+
+	return "";
+}
+
 static bool check_existing_mount(struct discover_device *dev)
 {
 	struct stat devstat, mntstat;
@@ -1155,6 +1169,13 @@ static int mount_device(struct discover_device *dev)
 	if (!fstype)
 		return 0;
 
+	/* ext3 treats the norecovery option as an error, so mount the device
+	 * as an ext4 filesystem instead */
+	if (!strncmp(fstype, "ext3", strlen("ext3"))) {
+		pb_debug("Mounting ext3 filesystem as ext4\n");
+		fstype = talloc_asprintf(dev, "ext4");
+	}
+
 	dev->mount_path = join_paths(dev, mount_base(),
 					dev->device_path);
 
@@ -1167,7 +1188,8 @@ static int mount_device(struct discover_device *dev)
 	pb_log("mounting device %s read-only\n", dev->device_path);
 	errno = 0;
 	rc = mount(dev->device_path, dev->mount_path, fstype,
-			MS_RDONLY | MS_SILENT, "");
+			MS_RDONLY | MS_SILENT,
+			fs_parameters(MS_RDONLY, fstype));
 	if (!rc) {
 		dev->mounted = true;
 		dev->mounted_rw = false;
@@ -1209,6 +1231,7 @@ static int umount_device(struct discover_device *dev)
 
 int device_request_write(struct discover_device *dev, bool *release)
 {
+	const char *fstype;
 	int rc;
 
 	*release = false;
@@ -1219,9 +1242,16 @@ int device_request_write(struct discover_device *dev, bool *release)
 	if (dev->mounted_rw)
 		return 0;
 
+	fstype = discover_device_get_param(dev, "ID_FS_TYPE");
+	if (!strncmp(fstype, "xfs", strlen("xfs"))) {
+		pb_debug("read-write mounting of XFS partitions unsupported\n");
+		return -1;
+	}
+
 	pb_log("remounting device %s read-write\n", dev->device_path);
 	rc = mount(dev->device_path, dev->mount_path, "",
-			MS_REMOUNT | MS_SILENT, "");
+			MS_REMOUNT | MS_SILENT,
+			fs_parameters(MS_REMOUNT, ""));
 	if (rc)
 		return -1;
 
@@ -1237,7 +1267,8 @@ void device_release_write(struct discover_device *dev, bool release)
 
 	pb_log("remounting device %s read-only\n", dev->device_path);
 	mount(dev->device_path, dev->mount_path, "",
-			MS_REMOUNT | MS_RDONLY | MS_SILENT, "");
+			MS_REMOUNT | MS_RDONLY | MS_SILENT,
+			fs_parameters(MS_RDONLY, ""));
 	dev->mounted_rw = false;
 }
 
-- 
2.1.0



More information about the Petitboot mailing list