[OpenWrt-Devel,v2] fstools: add a hook before mounting the overlay
diff mbox series

Message ID 1570780880-11992-1-git-send-email-alin.nastac@technicolor.com
State Under Review
Delegated to: John Crispin
Headers show
Series
  • [OpenWrt-Devel,v2] fstools: add a hook before mounting the overlay
Related show

Commit Message

Alin Năstac Oct. 11, 2019, 8:01 a.m. UTC
From: Alin Nastac <alin.nastac@gmail.com>

Scripts located in the directory /etc/mount_root.d will be executed
before mounting the overlay. It can be used to implement
configuration merges between old & new setup after doing sysupgrade.

Signed-off-by: Alin Nastac <alin.nastac@gmail.com>
---
 libfstools/overlay.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

Comments

Alin Năstac Oct. 31, 2019, 12:21 p.m. UTC | #1
On Thu, Oct 24, 2019 at 11:24 PM Karl Palsson <karlp@tweak.net.au> wrote:
>
>
> Alin Nastac <alin.nastac@gmail.com> wrote:
> > From: Alin Nastac <alin.nastac@gmail.com>
> >
> > Scripts located in the directory /etc/mount_root.d will be
> > executed before mounting the overlay. It can be used to
> > implement configuration merges between old & new setup after
> > doing sysupgrade.
>
> >From the name of the directory it's unclear when these would be
> executed. (You say pre, it's what you needed, but what if I
> wanted afterwards? where would they go?)
>
> Perhaps these could be made compatible with the hotplug.d
> scripts, where they have environment variables passed to them
> with the ACTION (pre/post) and so on. See
> https://openwrt.org/docs/guide-user/base-system/hotplug
>
> You could even just have another directory under /etc/hotplug.d ?

The only action handled in my scripts is "pre-overlay-activation" and
I used it to merge parts of the old config into the new overlay file
system. If community finds this useful, I can move the scripts to
/etc/hotplug.d/overlay and run the equivalent of the shell command
   ACTION=activate /sbin/hotplug-call overlay

Patch
diff mbox series

diff --git a/libfstools/overlay.c b/libfstools/overlay.c
index 14214a3..46c87c9 100644
--- a/libfstools/overlay.c
+++ b/libfstools/overlay.c
@@ -14,6 +14,7 @@ 
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/mount.h>
+#include <sys/wait.h>
 
 #include <asm/byteorder.h>
 
@@ -400,6 +401,49 @@  int fs_state_set(const char *dir, enum fs_state state)
 	return symlink(valstr, path);
 }
 
+static inline int hook_execute(const char *path)
+{
+	DIR *dir;
+	struct dirent *dent;
+	char script[256];
+	pid_t pid;
+
+	ULOG_INFO("executing scripts in %s\n", path);
+
+	if ((dir = opendir(path)) == NULL) {
+		ULOG_INFO("cannot open %s (%s)\n", path, strerror(errno));
+		return 0;
+	}
+
+	while ((dent = readdir(dir)) != NULL) {
+		struct stat st;
+		int wstatus;
+
+		snprintf(script, sizeof(script), "%s/%s", path, dent->d_name);
+		if (stat(script, &st))
+			continue;
+		if (!S_ISREG(st.st_mode))
+			continue;
+		ULOG_INFO("%s\n", script);
+		pid = fork();
+		if (!pid) {
+			char *cmd[] = {script, NULL};
+
+			execvp(cmd[0], cmd);
+			ULOG_ERR("Failed to execute %s\n", script);
+			exit(-1);
+		}
+		if (pid <= 0) {
+			ULOG_INFO("Failed to fork() for %s\n", script);
+			continue;
+		}
+		waitpid(pid, &wstatus, 0);
+	}
+
+	closedir(dir);
+
+	return 0;
+}
 
 int mount_overlay(struct volume *v)
 {
@@ -439,7 +483,7 @@  int mount_overlay(struct volume *v)
 
 	fs_name = overlay_fs_name(volume_identify(v));
 	ULOG_INFO("switching to %s overlay\n", fs_name);
-	if (mount_move("/tmp", "", "/overlay") || fopivot("/overlay", "/rom")) {
+	if (mount_move("/tmp", "", "/overlay") || hook_execute("/etc/mount_root.d") || fopivot("/overlay", "/rom")) {
 		ULOG_ERR("switching to %s failed - fallback to ramoverlay\n", fs_name);
 		return ramoverlay();
 	}