[RHEL7,COMMIT] overlayfs: add mnt_id paths options

Submitted by Konstantin Khorenko on June 11, 2020, 4:05 p.m.

Details

Message ID 202006111605.05BG5cOC020910@finist-ce7.sw.ru
State New
Series "overlayfs: C/R enhancements"
Headers show

Commit Message

Konstantin Khorenko June 11, 2020, 4:05 p.m.
The commit is pushed to "branch-rh7-3.10.0-1127.10.1.vz7.162.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.10.1.vz7.162.2
------>
commit c14b3044c39507ebd65e1f41c085d9920fa2a6e0
Author: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
Date:   Thu Jun 4 11:34:35 2020 +0300

    overlayfs: add mnt_id paths options
    
    This patch adds config OVERLAY_FS_PATH_OPTIONS_MNT_ID
    compile-time option, and "mnt_id_path_opts" runtime module option.
    If enabled, user may see mnt_ids for lowerdir, upperdir paths
    in mountinfo in separate lowerdir_mnt_id/upperdir_mnt_id options.
    
    This patch is very helpful to checkpoint/restore functionality
    of overlayfs mounts in case when we have overmounts on
    lowerdir, workdir, upperdir paths.
    
    https://jira.sw.ru/browse/PSBM-58614
    
    Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
    Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
    
    =====================
    Patchset description:
    overlayfs: C/R enhancements
    
    This patchset aimed to make C/R of overlayfs mounts with CRIU possible.
    We introduce two new overlayfs module options -- dyn_path_opts and
    mnt_id_path_opts. If enabled this options allows to see real *full* paths
    in lowerdir, workdir, upperdir options, and also mnt_ids for corresponding
    paths.
    
    This changes should not break anything because for showing mnt_ids we simply
    introduce new show-time mount options. And for paths we simply *always*
    provide *full paths* instead of relative path on mountinfo.
    
    BEFORE
    
    overlay on /var/lib/docker/overlay2/XYZ/merged type overlay (rw,relatime,
    lowerdir=/var/lib/docker/overlay2/XYZ-init/diff:/var/lib/docker/overlay2/
    ABC/diff,upperdir=/var/lib/docker/overlay2/XYZ/diff,workdir=/var/lib/docker
    /overlay2/XYZ/work)
    none on /sys type sysfs (rw,relatime)
    
    AFTER
    
    overlay on /var/lib/docker/overlay2/XYZ/merged type overlay (rw,relatime,
    lowerdir=/var/lib/docker/overlay2/XYZ-init/diff:/var/lib/docker/overlay2/
    ABC/diff,upperdir=/var/lib/docker/overlay2/XYZ/diff,workdir=/var/lib/docker
    /overlay2/XYZ/work,lowerdir_mnt_id=175:175,upperdir_mnt_id=175)
    none on /sys type sysfs (rw,relatime)
    
    Alexander Mikhalitsyn (2):
      overlayfs: add dynamic path resolving in mount options
      overlayfs: add mnt_id paths options
---
 fs/overlayfs/Kconfig     | 26 ++++++++++++++++++++++++++
 fs/overlayfs/overlayfs.h |  4 ++++
 fs/overlayfs/super.c     | 16 ++++++++++++++++
 fs/overlayfs/util.c      | 22 ++++++++++++++++++++++
 4 files changed, 68 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig
index 6a076014718db..32e8195a0cbef 100644
--- a/fs/overlayfs/Kconfig
+++ b/fs/overlayfs/Kconfig
@@ -134,3 +134,29 @@  config OVERLAY_FS_DYNAMIC_RESOLVE_PATH_OPTIONS
 	  For more information, see Documentation/filesystems/overlayfs.txt
 
 	  If unsure, say N.
+
+config OVERLAY_FS_PATH_OPTIONS_MNT_ID
+	bool "Overlayfs: show mnt_id for all mount paths options"
+	default y
+	depends on OVERLAY_FS
+	help
+	  This option helps checkpoint/restore of overlayfs mounts.
+	  If N selected, old behavior is saved.
+
+	  If this config option is enabled then in overlay filesystems mount
+	  options you will be able to see additional parameters
+	  lowerdir_mnt_id/upperdir_mnt_id with corresponding mnt_ids.
+
+	  It's also possible to change this behavior on overlayfs module
+	  loading or through sysfs (mnt_id_path_opts parameter).
+
+	  Disable this to get a backward compatible with previous kernels
+	  configuration, but in this case checkpoint/restore functionality
+	  for overlayfs mounts may not fully work.
+
+	  If backward compatibility is not an issue, then it is safe and
+	  recommended to say Y here.
+
+	  For more information, see Documentation/filesystems/overlayfs.txt
+
+	  If unsure, say N.
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index f508cd2e93dbc..1b3a2c9d8a126 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -256,6 +256,10 @@  int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
 void print_path_option(struct seq_file *m, const char *name, struct path *path);
 void print_paths_option(struct seq_file *m, const char *name,
 			struct path *paths, unsigned int num);
+void print_mnt_id_option(struct seq_file *m, const char *name,
+			 struct path *path);
+void print_mnt_ids_option(struct seq_file *m, const char *name,
+			  struct path *paths, unsigned int num);
 
 static inline bool ovl_is_impuredir(struct dentry *dentry)
 {
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 374e243ca07a2..6a2611834480f 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -62,6 +62,10 @@  static bool ovl_dyn_path_opts =
 module_param_named(dyn_path_opts, ovl_dyn_path_opts, bool, 0644);
 MODULE_PARM_DESC(dyn_path_opts, "dyn_path_opts feature enabled");
 
+static bool ovl_mnt_id_path_opts = IS_ENABLED(OVERLAY_FS_PATH_OPTIONS_MNT_ID);
+module_param_named(mnt_id_path_opts, ovl_mnt_id_path_opts, bool, 0644);
+MODULE_PARM_DESC(mnt_id_path_opts, "mnt_id_path_opts feature enabled");
+
 static void ovl_entry_stack_free(struct ovl_entry *oe)
 {
 	unsigned int i;
@@ -394,6 +398,18 @@  static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
 		}
 	}
 
+	if (ovl_mnt_id_path_opts) {
+		print_mnt_ids_option(m, "lowerdir_mnt_id", ofs->lowerpaths,
+				     ofs->numlower);
+		/*
+		 * We don't need to show mnt_id for workdir because it
+		 * on the same mount as upperdir.
+		 */
+		if (ofs->config.upperdir)
+			print_mnt_id_option(m, "upperdir_mnt_id",
+					    &ofs->upperpath);
+	}
+
 	if (ofs->config.default_permissions)
 		seq_puts(m, ",default_permissions");
 	if (strcmp(ofs->config.redirect_mode, ovl_redirect_mode_def()) != 0)
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index bb670ee99ff16..52a5116d4b6e6 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -18,6 +18,7 @@ 
 #include <linux/namei.h>
 #include <linux/ratelimit.h>
 #include <linux/seq_file.h>
+#include "../mount.h"
 #include "overlayfs.h"
 
 int ovl_want_write(struct dentry *dentry)
@@ -699,3 +700,24 @@  void print_paths_option(struct seq_file *m, const char *name,
 		seq_path(m, &paths[i], ", \t\n\\");
 	}
 }
+
+void print_mnt_id_option(struct seq_file *m, const char *name,
+			 struct path *path)
+{
+	seq_show_option(m, name, "");
+	seq_printf(m, "%i", real_mount(path->mnt)->mnt_id);
+}
+
+void print_mnt_ids_option(struct seq_file *m, const char *name,
+			struct path *paths, unsigned int num)
+{
+	int i;
+
+	seq_show_option(m, name, "");
+
+	for (i = 0; i < num; i++) {
+		if (i)
+			seq_putc(m, ':');
+		seq_printf(m, "%i", real_mount(paths[i].mnt)->mnt_id);
+	}
+}