From f4190c2f12527e37304f7c185afa0449fa9dee1c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 6 Jul 2010 12:48:56 -0700 Subject: mdmon: satisfy glibc tls abi requirements with pthreads Setting up a proper tls descriptor is required to conform to the abi [1]. Until it can be implemented in mdmon use pthreads instead of clone(2) to let glibc handle the details. The old behaviour can be had by un-defining USE_PTHREADS. Note, the "O2" builds need LDFLAGS now to pick up the '-pthread' option. [1]: http://people.redhat.com/drepper/tls.pdf Signed-off-by: Dan Williams --- Makefile | 14 +++++++++++--- mdmon.c | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 237f4fc..0f42f88 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,14 @@ ALTFLAGS = -DALT_RUN=\"$(ALT_RUN)\" -DALT_MAPFILE=\"$(ALT_MAPFILE)\" VARFLAGS = -DVAR_RUN=\"$(VAR_RUN)\" CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(ALTFLAGS) $(VARFLAGS) +# The glibc TLS ABI requires applications that call clone(2) to set up +# TLS data structures, use pthreads until mdmon implements this support +USE_PTHREADS = 1 +ifdef USE_PTHREADS +CFLAGS += -DUSE_PTHREADS +LDFLAGS += -pthread +endif + # If you want a static binary, you might uncomment these # LDFLAGS = -static # STRIP = -s @@ -149,13 +157,13 @@ mdadm.klibc : $(SRCS) mdadm.h $(CC) -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIBC)/linux/include -I$(KLIBC)/klibc/arch/i386/include -I$(KLIBC)/klibc/include/bits32 $(CFLAGS) $(SRCS) mdadm.Os : $(SRCS) mdadm.h - $(CC) -o mdadm.Os $(CFLAGS) -DHAVE_STDINT_H -Os $(SRCS) + $(CC) -o mdadm.Os $(CFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -Os $(SRCS) mdadm.O2 : $(SRCS) mdadm.h mdmon.O2 - $(CC) -o mdadm.O2 $(CFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(SRCS) + $(CC) -o mdadm.O2 $(CFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(SRCS) mdmon.O2 : $(MON_SRCS) mdadm.h mdmon.h - $(CC) -o mdmon.O2 $(CFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS) + $(CC) -o mdmon.O2 $(CFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS) # use '-z now' to guarantee no dynamic linker interactions with the monitor thread mdmon : $(MON_OBJS) diff --git a/mdmon.c b/mdmon.c index 0c37426..c4c0181 100644 --- a/mdmon.c +++ b/mdmon.c @@ -58,8 +58,11 @@ #include #include #include - +#ifdef USE_PTHREADS +#include +#else #include +#endif #include "mdadm.h" #include "mdmon.h" @@ -71,7 +74,39 @@ int mon_tid, mgr_tid; int sigterm; -int run_child(void *v) +#ifdef USE_PTHREADS +static void *run_child(void *v) +{ + struct supertype *c = v; + + mon_tid = syscall(SYS_gettid); + do_monitor(c); + return 0; +} + +static int clone_monitor(struct supertype *container) +{ + pthread_attr_t attr; + pthread_t thread; + int rc; + + mon_tid = -1; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 4096); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + rc = pthread_create(&thread, &attr, run_child, container); + if (rc) + return rc; + while (mon_tid == -1) + usleep(10); + pthread_attr_destroy(&attr); + + mgr_tid = syscall(SYS_gettid); + + return mon_tid; +} +#else /* USE_PTHREADS */ +static int run_child(void *v) { struct supertype *c = v; @@ -85,7 +120,7 @@ int __clone2(int (*fn)(void *), int flags, void *arg, ... /* pid_t *pid, struct user_desc *tls, pid_t *ctid */ ); #endif - int clone_monitor(struct supertype *container) +static int clone_monitor(struct supertype *container) { static char stack[4096]; @@ -103,6 +138,7 @@ int __clone2(int (*fn)(void *), return mon_tid; } +#endif /* USE_PTHREADS */ static int make_pidfile(char *devname) { -- cgit From 569cc43ffb0634510defee91407d261555c7a991 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 6 Jul 2010 12:48:59 -0700 Subject: imsm: fix a -O2 build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit super-intel.c: In function ‘imsm_add_spare’: super-intel.c:4833: error: ‘array_start’ may be used uninitialized in this function super-intel.c:4834: error: ‘array_end’ may be used uninitialized in this function This is valid, if we don't find a spare candidate then array_{start,end} will be uninitialized. Signed-off-by: Dan Williams --- super-intel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/super-intel.c b/super-intel.c index daf811f..6826d9b 100644 --- a/super-intel.c +++ b/super-intel.c @@ -4830,8 +4830,8 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot, struct extent *ex; int i, j; int found; - __u32 array_start; - __u32 array_end; + __u32 array_start = 0; + __u32 array_end = 0; struct dl *dl; for (dl = super->disks; dl; dl = dl->next) { -- cgit From 1dccfff910ce9d854330302b9a34636d63cdac7b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 19 Jul 2010 14:59:25 -0700 Subject: Incremental: restore assembly for inactive containers, block active GET_ARRAY_INFO always succeeds on an inactive container, so we need to be a bit more diligent about adding a disk to an active container. Signed-off-by: Dan Williams --- Incremental.c | 11 ++++++++++- mdadm.h | 1 + util.c | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Incremental.c b/Incremental.c index 96bfcec..abfea24 100644 --- a/Incremental.c +++ b/Incremental.c @@ -376,7 +376,16 @@ int Incremental(char *devname, int verbose, int runstop, * statement about this. */ if (runstop < 1) { - if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) { + int active = 0; + + if (st->ss->external) { + char *devname = devnum2devname(fd2devnum(mdfd)); + + active = devname && is_container_active(devname); + free(devname); + } else if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) + active = 1; + if (active) { fprintf(stderr, Name ": not adding %s to active array (without --run) %s\n", devname, chosen_name); diff --git a/mdadm.h b/mdadm.h index 55e9e46..f1fe24f 100644 --- a/mdadm.h +++ b/mdadm.h @@ -930,6 +930,7 @@ extern int open_mddev(char *dev, int report_errors); extern int open_container(int fd); extern int is_container_member(struct mdstat_ent *ent, char *devname); extern int is_subarray_active(char *subarray, char *devname); +int is_container_active(char *devname); extern int open_subarray(char *dev, struct supertype *st, int quiet); extern struct superswitch *version_to_superswitch(char *vers); diff --git a/util.c b/util.c index d22b0d0..1ce6a7a 100644 --- a/util.c +++ b/util.c @@ -1427,7 +1427,7 @@ int is_subarray_active(char *subarray, char *container) if (is_container_member(ent, container)) { char *inst = &ent->metadata_version[10+strlen(container)+1]; - if (strcmp(inst, subarray) == 0) + if (!subarray || strcmp(inst, subarray) == 0) break; } } @@ -1437,6 +1437,11 @@ int is_subarray_active(char *subarray, char *container) return ent != NULL; } +int is_container_active(char *container) +{ + return is_subarray_active(NULL, container); +} + /* open_subarray - opens a subarray in a container * @dev: container device name * @st: supertype with only ->subarray set -- cgit