Remove mgr_pipe for communicating from manage to monitor.

Data is being passed in shared memory, so the pipe is only being
use as a wakeup.  This can more easily be done with a thread-signal.
This commit is contained in:
Neil Brown 2008-07-12 20:27:40 +10:00
parent 2f64e61a50
commit 4d43913ce0
7 changed files with 48 additions and 98 deletions

View File

@ -85,6 +85,7 @@
#endif
#include "mdadm.h"
#include "mdmon.h"
#include <sys/syscall.h>
#include <sys/socket.h>
#include <signal.h>
@ -143,15 +144,11 @@ static struct active_array *duplicate_aa(struct active_array *aa)
return newa;
}
static void write_wakeup(struct supertype *c)
static void wakeup_monitor(void)
{
static struct md_generic_cmd cmd = { .action = md_action_ping_monitor };
int err;
active_cmd = &cmd;
/* send the monitor thread a pointer to the ping action */
write(c->mgr_pipe[1], &err, 1);
/* tgkill(getpid(), mon_tid, SIGUSR1); */
int pid = getpid();
syscall(SYS_tgkill, pid, mon_tid, SIGUSR1);
}
static void remove_old(void)
@ -177,7 +174,7 @@ static void replace_array(struct supertype *container,
*/
remove_old();
while (pending_discard) {
write_wakeup(container);
wakeup_monitor();
while (discard_this == NULL)
sleep(1);
remove_old();
@ -186,7 +183,7 @@ static void replace_array(struct supertype *container,
new->replaces = old;
new->next = container->arrays;
container->arrays = new;
write_wakeup(container);
wakeup_monitor();
}
struct metadata_update *update_queue = NULL;
@ -207,7 +204,7 @@ void check_update_queue(struct supertype *container)
update_queue_pending) {
update_queue = update_queue_pending;
update_queue_pending = NULL;
write_wakeup(container);
wakeup_monitor();
}
}
@ -433,16 +430,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
static int handle_message(struct supertype *container, struct md_message *msg)
{
struct md_generic_cmd *cmd = msg->buf;
if (!cmd)
return 0;
switch (cmd->action) {
default:
return -1;
}
return -1;
}
void read_sock(struct supertype *container)
@ -485,26 +473,17 @@ void read_sock(struct supertype *container)
close(fd);
}
static int woke = 0;
void wake_me(int sig)
{
woke = 1;
}
int exit_now = 0;
int manager_ready = 0;
void do_manager(struct supertype *container)
{
struct mdstat_ent *mdstat;
sigset_t block, orig;
sigset_t set;
sigemptyset(&block);
sigaddset(&block, SIGUSR1);
signal(SIGUSR1, wake_me);
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
do {
woke = 0;
if (exit_now)
exit(0);
@ -522,9 +501,7 @@ void do_manager(struct supertype *container)
check_update_queue(container);
manager_ready = 1;
sigprocmask(SIG_SETMASK, &block, &orig);
if (woke == 0)
mdstat_wait_fd(container->sock, &orig);
sigprocmask(SIG_SETMASK, &orig, NULL);
mdstat_wait_fd(container->sock, &set);
} while(1);
}

View File

@ -582,7 +582,6 @@ struct supertype {
/* extra stuff used by mdmon */
struct active_array *arrays;
int sock; /* listen to external programs */
int mgr_pipe[2]; /* communicate between threads */
int devnum;
char *devname; /* e.g. md0. This appears in metadata_verison:
* external:/md0/12

39
mdmon.c
View File

@ -26,10 +26,12 @@
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@ -43,17 +45,14 @@
struct active_array *discard_this;
struct active_array *pending_discard;
struct md_generic_cmd *active_cmd;
int mon_tid, mgr_tid;
int run_child(void *v)
{
struct supertype *c = v;
sigset_t set;
/* SIGUSR is sent from child to parent, So child must block it */
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigprocmask(SIG_BLOCK, &set, NULL);
mon_tid = syscall(SYS_gettid);
do_monitor(c);
return 0;
}
@ -63,22 +62,13 @@ int clone_monitor(struct supertype *container)
static char stack[4096];
int rv;
rv = pipe(container->mgr_pipe);
if (rv < 0)
return rv;
rv = clone(run_child, stack+4096-64,
CLONE_FS|CLONE_FILES|CLONE_VM|CLONE_SIGHAND|CLONE_THREAD,
container);
if (rv < 0)
goto err_clone;
else
return rv;
err_clone:
close(container->mgr_pipe[0]);
close(container->mgr_pipe[1]);
mgr_tid = syscall(SYS_gettid);
return rv;
}
@ -176,11 +166,18 @@ static int make_control_sock(char *devname)
return sfd;
}
static void wake_me(int sig)
{
}
int main(int argc, char *argv[])
{
int mdfd;
struct mdinfo *mdi, *di;
struct supertype *container;
sigset_t set;
if (argc != 2) {
fprintf(stderr, "Usage: md-manage /device/name/for/container\n");
exit(2);
@ -277,6 +274,14 @@ int main(int argc, char *argv[])
mlockall(MCL_FUTURE);
/* SIGUSR is sent between parent and child. So both block it
* and enable it only with pselect.
*/
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigprocmask(SIG_BLOCK, &set, NULL);
signal(SIGUSR1, wake_me);
if (clone_monitor(container) < 0) {
fprintf(stderr, "md-manage: failed to start monitor process: %s\n",
strerror(errno));

View File

@ -66,3 +66,4 @@ int read_dev_state(int fd);
struct mdstat_ent *mdstat_read(int hold, int start);
extern int exit_now, manager_ready;
extern int mon_tid, mgr_tid;

View File

@ -1,7 +1,7 @@
#include "mdadm.h"
#include "mdmon.h"
#include <sys/syscall.h>
#include <sys/select.h>
#include <signal.h>
@ -138,7 +138,9 @@ int read_dev_state(int fd)
static void signal_manager(void)
{
kill(getpid(), SIGUSR1);
/* tgkill(getpid(), mon_tid, SIGUSR1); */
int pid = getpid();
syscall(SYS_tgkill, pid, mgr_tid, SIGUSR1);
}
/* Monitor a set of active md arrays - all of which share the
@ -367,16 +369,6 @@ static void reconcile_failed(struct active_array *aa, struct mdinfo *failed)
}
}
static int handle_pipe(struct md_generic_cmd *cmd, struct active_array *aa)
{
switch (cmd->action) {
case md_action_ping_monitor:
return 0;
}
return -1;
}
#ifdef DEBUG
static void dprint_wake_reasons(fd_set *fds)
{
@ -407,8 +399,7 @@ static void dprint_wake_reasons(fd_set *fds)
}
#endif
static int wait_and_act(struct supertype *container, int pfd,
int nowait)
static int wait_and_act(struct supertype *container, int nowait)
{
fd_set rfds;
int maxfd = 0;
@ -419,7 +410,6 @@ static int wait_and_act(struct supertype *container, int pfd,
FD_ZERO(&rfds);
add_fd(&rfds, &maxfd, pfd);
for (ap = aap ; *ap ;) {
a = *ap;
/* once an array has been deactivated we want to
@ -463,21 +453,15 @@ static int wait_and_act(struct supertype *container, int pfd,
}
if (!nowait) {
rv = select(maxfd+1, &rfds, NULL, NULL, NULL);
sigset_t set;
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
rv = pselect(maxfd+1, &rfds, NULL, NULL, NULL, &set);
#ifdef DEBUG
dprint_wake_reasons(&rfds);
#endif
if (rv <= 0)
return rv;
if (FD_ISSET(pfd, &rfds)) {
int err = -1;
if (read(pfd, &err, 1) > 0)
err = handle_pipe(active_cmd, *aap);
}
}
if (update_queue) {
@ -526,8 +510,7 @@ void do_monitor(struct supertype *container)
int rv;
int first = 1;
do {
rv = wait_and_act(container, container->mgr_pipe[0],
first);
rv = wait_and_act(container, first);
first = 0;
} while (rv >= 0);
}

2
msg.c
View File

@ -88,7 +88,7 @@ tx_rx_message(int fd, struct md_message *msg, int recv_send, int tmo)
break;
case TX_RX_NUM_BYTES:
if (msg->num_bytes >
sizeof(union md_message_commands))
1024*1024)
state = TX_RX_ERR;
else if (recv_send && msg->num_bytes) {
msg->buf = malloc(msg->num_bytes);

15
msg.h
View File

@ -27,21 +27,6 @@ struct md_message {
void *buf;
};
enum md_message_action {
md_action_ping_monitor,
};
struct md_generic_cmd {
enum md_message_action action;
};
/* union of all known command types, used to sanity check ->num_bytes
* on the receive path
*/
union md_message_commands {
struct md_generic_cmd generic;
};
extern const int start_magic;
extern const int end_magic;