X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=mdmon.c;h=73c244af91bcbd92a657f250b8f8ba55b3af7b55;hp=877cf1a16762315b6378fa62061cb155f4aed3bb;hb=e8a70c89585ddca2bcb4160808f64506c64df13b;hpb=13047e4c0708ad06a6c0a07e79a080dade94df38 diff --git a/mdmon.c b/mdmon.c index 877cf1a1..73c244af 100644 --- a/mdmon.c +++ b/mdmon.c @@ -1,3 +1,22 @@ +/* + * mdmon - monitor external metadata arrays + * + * Copyright (C) 2007-2008 Neil Brown + * Copyright (C) 2007-2008 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ /* * md array manager. @@ -60,13 +79,25 @@ int run_child(void *v) return 0; } -int clone_monitor(struct supertype *container) +#ifdef __ia64__ +int __clone2(int (*fn)(void *), + void *child_stack_base, size_t stack_size, + int flags, void *arg, ... + /* pid_t *pid, struct user_desc *tls, pid_t *ctid */ ); +#endif + int clone_monitor(struct supertype *container) { static char stack[4096]; +#ifdef __ia64__ + mon_tid = __clone2(run_child, stack, sizeof(stack), + CLONE_FS|CLONE_FILES|CLONE_VM|CLONE_SIGHAND|CLONE_THREAD, + container); +#else mon_tid = clone(run_child, stack+4096-64, CLONE_FS|CLONE_FILES|CLONE_VM|CLONE_SIGHAND|CLONE_THREAD, container); +#endif mgr_tid = syscall(SYS_gettid); @@ -139,6 +170,10 @@ static void try_kill_monitor(char *devname) close(fd); pid = strtoul(buf, NULL, 10); + /* first rule of survival... don't off yourself */ + if (pid == getpid()) + return; + /* kill this process if it is mdmon */ sprintf(buf, "/proc/%lu/cmdline", (unsigned long) pid); fd = open(buf, O_RDONLY); @@ -159,7 +194,7 @@ static void try_kill_monitor(char *devname) for ( ; mdstat; mdstat = mdstat->next) if (is_container_member(mdstat, devname)) { sprintf(buf, "/dev/%s", mdstat->dev); - WaitClean(buf); + WaitClean(buf, 0); } free_mdstat(mdstat); remove_pidfile(devname); @@ -227,7 +262,7 @@ static void wake_me(int sig) static int do_fork(void) { #ifdef DEBUG - if (env_no_mdmon()) + if (check_env("MDADM_NO_MDMON")) return 0; #endif @@ -252,6 +287,8 @@ int main(int argc, char *argv[]) int ignore; char *container_name = NULL; char *switchroot = NULL; + int devnum; + char *devname; switch (argc) { case 2: @@ -269,7 +306,14 @@ int main(int argc, char *argv[]) usage(); } - mdfd = open(container_name, O_RDWR); + devnum = devname2devnum(container_name); + devname = devnum2devname(devnum); + if (strcmp(container_name, devname) != 0) { + fprintf(stderr, "mdmon: %s is not a valid md device name\n", + container_name); + exit(1); + } + mdfd = open_dev(devnum); if (mdfd < 0) { fprintf(stderr, "mdmon: %s: %s\n", container_name, strerror(errno)); @@ -307,9 +351,8 @@ int main(int argc, char *argv[]) pfd[0] = pfd[1] = -1; container = malloc(sizeof(*container)); - container->devnum = fd2devnum(mdfd); - container->devname = devnum2devname(container->devnum); - container->device_name = container_name; + container->devnum = devnum; + container->devname = devname; container->arrays = NULL; if (!container->devname) { @@ -427,6 +470,7 @@ int main(int argc, char *argv[]) container_name); exit(3); } + close(mdfd); /* Ok, this is close enough. We can say goodbye to our parent now. */