From: Alin Nastac <alin.nas...@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.nas...@gmail.com>
---
 libfstools/overlay.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

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();
        }
-- 
2.7.4


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to