summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-10-01 18:50:43 -0700
committerDan Williams <dan.j.williams@intel.com>2008-10-15 14:15:52 -0700
commit695154b2e7f975527f8f3f9591f0a21474bfe1b1 (patch)
tree98a16315f08174369ce8038bc1948a68ae2e60a9
parent1e4bc070a73716292c1681a86524f46f656f8acb (diff)
downloadmdadm-695154b2e7f975527f8f3f9591f0a21474bfe1b1.tar.gz
mdadm-695154b2e7f975527f8f3f9591f0a21474bfe1b1.tar.xz
mdadm-695154b2e7f975527f8f3f9591f0a21474bfe1b1.zip
mdmon: periodically retry to create the socket
If initial socket creation fails, EROFS, set a periodic alarm to wake up the manager and retry. Include a kernel patch that will wake us up if the mount flags are changed. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--kernel-patch-2.6.2736
-rw-r--r--managemon.c16
-rw-r--r--mdmon.c4
3 files changed, 50 insertions, 6 deletions
diff --git a/kernel-patch-2.6.27 b/kernel-patch-2.6.27
new file mode 100644
index 0000000..8d0785d
--- /dev/null
+++ b/kernel-patch-2.6.27
@@ -0,0 +1,36 @@
+touch_mnt_namespace when the mount flags change
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+Daemons that need to be launched while the rootfs is read-only can now
+poll /proc/mounts to be notified when their O_RDWR requests may no
+longer end in EROFS.
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Cc: Neil Brown <neilb@suse.de>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+---
+
+ fs/namespace.c | 7 ++++++-
+ 1 files changed, 6 insertions(+), 1 deletions(-)
+
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 6e283c9..1bd5ba2 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
+ if (!err)
+ nd->path.mnt->mnt_flags = mnt_flags;
+ up_write(&sb->s_umount);
+- if (!err)
++ if (!err) {
+ security_sb_post_remount(nd->path.mnt, flags, data);
++
++ spin_lock(&vfsmount_lock);
++ touch_mnt_namespace(nd->path.mnt->mnt_ns);
++ spin_unlock(&vfsmount_lock);
++ }
+ return err;
+ }
+
diff --git a/managemon.c b/managemon.c
index dc3ff7f..730334c 100644
--- a/managemon.c
+++ b/managemon.c
@@ -606,10 +606,13 @@ void do_manager(struct supertype *container)
{
struct mdstat_ent *mdstat;
sigset_t set;
+ int proc_fd;
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
sigdelset(&set, SIGHUP);
+ sigdelset(&set, SIGALRM);
+ proc_fd = open("/proc/mounts", O_RDONLY);
do {
@@ -627,12 +630,14 @@ void do_manager(struct supertype *container)
read_sock(container);
- if (socket_hup_requested) {
+ if (container->sock < 0 || socket_hup_requested) {
close(container->sock);
container->sock = make_control_sock(container->devname);
make_pidfile(container->devname, 0);
socket_hup_requested = 0;
}
+ if (container->sock < 0)
+ alarm(30);
free_mdstat(mdstat);
}
@@ -642,9 +647,12 @@ void do_manager(struct supertype *container)
manager_ready = 1;
- if (update_queue == NULL)
- mdstat_wait_fd(container->sock, &set);
- else
+ if (update_queue == NULL) {
+ if (container->sock < 0)
+ mdstat_wait_fd(proc_fd, &set);
+ else
+ mdstat_wait_fd(container->sock, &set);
+ } else
/* If an update is happening, just wait for signal */
pselect(0, NULL, NULL, NULL, NULL, &set);
} while(1);
diff --git a/mdmon.c b/mdmon.c
index 3f5edbb..28b0139 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -282,8 +282,6 @@ int main(int argc, char *argv[])
}
container->sock = make_control_sock(container->devname);
- if (container->sock < 0)
- fprintf(stderr, "mdmon: Cannot create socket in /var/run/mdadm\n");
container->arrays = NULL;
mdi = sysfs_read(mdfd, container->devnum,
@@ -356,10 +354,12 @@ int main(int argc, char *argv[])
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGHUP);
+ sigaddset(&set, SIGALRM);
sigprocmask(SIG_BLOCK, &set, NULL);
act.sa_handler = wake_me;
act.sa_flags = 0;
sigaction(SIGUSR1, &act, NULL);
+ sigaction(SIGALRM, &act, NULL);
act.sa_handler = hup;
sigaction(SIGHUP, &act, NULL);
act.sa_handler = SIG_IGN;