summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>2015-08-25 10:33:14 +1000
committerSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>2015-09-10 15:49:23 +1000
commit6c1a9dda927ec7404a55d4e11c3c9c47b4b52dce (patch)
treea5439c5c58d2b31b6c62ab6f461d360746a0131f
parent9384b0ab3b9bec1744c19c64ac5431db99110b04 (diff)
downloadpetitboot-6c1a9dda927ec7404a55d4e11c3c9c47b4b52dce.zip
petitboot-6c1a9dda927ec7404a55d4e11c3c9c47b4b52dce.tar.gz
discover: Allow fs recovery if snapshot available
If we have a device-mapper snapshot available we can now guarantee filesystem recovery will not write back to a read-only mounted disk. Allow recovery on those devices with the notable exception of XFS which may fail to mount if the filesystem is the opposite endian of Petitboot. Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
-rw-r--r--discover/device-handler.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/discover/device-handler.c b/discover/device-handler.c
index 9246f0d..4e25e07 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -1225,16 +1225,26 @@ 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)
+static const char *fs_parameters(struct discover_device *dev,
+ unsigned int rw_flags)
{
+ const char *fstype = discover_device_get_param(dev, "ID_FS_TYPE");
+
+ /* XFS journals are not cross-endian compatible; don't try recovery
+ * even if we have a snapshot */
+ if (!strncmp(fstype, "xfs", strlen("xfs")))
+ return "norecovery";
+
+ /* If we have a snapshot available allow touching the filesystem */
+ if (dev->ramdisk)
+ return "";
+
if ((rw_flags | MS_RDONLY) != MS_RDONLY)
return "";
- /* Avoid writing back to the disk on journaled filesystems */
+ /* Avoid writes due to journal replay if we don't have a snapshot */
if (!strncmp(fstype, "ext4", strlen("ext4")))
return "norecovery";
- if (!strncmp(fstype, "xfs", strlen("xfs")))
- return "norecovery";
return "";
}
@@ -1342,7 +1352,7 @@ static int mount_device(struct discover_device *dev)
errno = 0;
rc = mount(device_path, dev->mount_path, fstype,
MS_RDONLY | MS_SILENT,
- fs_parameters(MS_RDONLY, fstype));
+ fs_parameters(dev, MS_RDONLY));
if (!rc) {
dev->mounted = true;
dev->mounted_rw = false;
@@ -1422,7 +1432,7 @@ int device_request_write(struct discover_device *dev, bool *release)
rc = mount(device_path, dev->mount_path, fstype,
MS_SILENT,
- fs_parameters(MS_REMOUNT, fstype));
+ fs_parameters(dev, MS_REMOUNT));
if (rc)
goto mount_ro;
@@ -1435,7 +1445,7 @@ mount_ro:
device_path, strerror(errno));
if (mount(device_path, dev->mount_path, fstype,
MS_RDONLY | MS_SILENT,
- fs_parameters(MS_RDONLY, fstype)))
+ fs_parameters(dev, MS_RDONLY)))
pb_log("Unable to recover mount for %s: %s\n",
device_path, strerror(errno));
return -1;
@@ -1469,7 +1479,7 @@ void device_release_write(struct discover_device *dev, bool release)
mount(device_path, dev->mount_path, fstype,
MS_RDONLY | MS_SILENT,
- fs_parameters(MS_RDONLY, fstype));
+ fs_parameters(dev, MS_RDONLY));
if (rc)
pb_log("Failed to remount %s read-only: %s\n",
device_path, strerror(errno));
OpenPOWER on IntegriCloud