X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=msg.c;h=d2d844589a1c565efe1b1686cced5e8d55395eee;hb=ecdbb368f8ce8bdb710d124c9b5b5e021474a77d;hp=78fd7f7e26380c9c05e6392438fa2a93ce01b3ad;hpb=eb2c876f4deef9da9eda6359647e2f6ad2083957;p=thirdparty%2Fmdadm.git diff --git a/msg.c b/msg.c index 78fd7f7e..d2d84458 100644 --- a/msg.c +++ b/msg.c @@ -81,12 +81,12 @@ static int recv_buf(int fd, void* buf, int len, int tmo) int send_message(int fd, struct metadata_update *msg, int tmo) { - __u32 len = msg->len; + __s32 len = msg->len; int rv; rv = send_buf(fd, &start_magic, 4, tmo); rv = rv ?: send_buf(fd, &len, 4, tmo); - if (len) + if (len > 0) rv = rv ?: send_buf(fd, msg->buf, msg->len, tmo); rv = send_buf(fd, &end_magic, 4, tmo); @@ -96,7 +96,7 @@ int send_message(int fd, struct metadata_update *msg, int tmo) int receive_message(int fd, struct metadata_update *msg, int tmo) { __u32 magic; - __u32 len; + __s32 len; int rv; rv = recv_buf(fd, &magic, 4, tmo); @@ -105,7 +105,7 @@ int receive_message(int fd, struct metadata_update *msg, int tmo) rv = recv_buf(fd, &len, 4, tmo); if (rv < 0 || len > MSG_MAX_LEN) return -1; - if (len) { + if (len > 0) { msg->buf = malloc(len); if (msg->buf == NULL) return -1; @@ -144,8 +144,21 @@ int connect_monitor(char *devname) int sfd; long fl; struct sockaddr_un addr; + int pos; + char *c; + + pos = sprintf(path, "%s/", pid_dir); + if (is_subarray(devname)) { + devname++; + c = strchr(devname, '/'); + if (!c) + return -1; + snprintf(&path[pos], c - devname + 1, "%s", devname); + pos += c - devname; + } else + pos += sprintf(&path[pos], "%s", devname); + sprintf(&path[pos], ".sock"); - sprintf(path, "/var/run/mdadm/%s.sock", devname); sfd = socket(PF_LOCAL, SOCK_STREAM, 0); if (sfd < 0) return -1; @@ -164,9 +177,8 @@ int connect_monitor(char *devname) return sfd; } -int ping_monitor(char *devname) +int fping_monitor(int sfd) { - int sfd = connect_monitor(devname); int err = 0; if (sfd < 0) @@ -176,6 +188,40 @@ int ping_monitor(char *devname) if (ack(sfd, 20) != 0) err = -1; + /* check the reply */ + if (!err && wait_reply(sfd, 20) != 0) + err = -1; + + return err; +} + + +/* give the monitor a chance to update the metadata */ +int ping_monitor(char *devname) +{ + int sfd = connect_monitor(devname); + int err = fping_monitor(sfd); + + close(sfd); + return err; +} + +/* give the manager a chance to view the updated container state. This + * would naturally happen due to the manager noticing a change in + * /proc/mdstat; however, pinging encourages this detection to happen + * while an exclusive open() on the container is active + */ +int ping_manager(char *devname) +{ + int sfd = connect_monitor(devname); + struct metadata_update msg = { .len = -1 }; + int err = 0; + + if (sfd < 0) + return sfd; + + err = send_message(sfd, &msg, 20); + /* check the reply */ if (!err && wait_reply(sfd, 20) != 0) err = -1;