]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - msg.c
imsm: enforce "all member disks must be members of all arrays"
[thirdparty/mdadm.git] / msg.c
diff --git a/msg.c b/msg.c
index 78fd7f7e26380c9c05e6392438fa2a93ce01b3ad..5a4839fad7bf40e6fadd745b7228e15b3df1204e 100644 (file)
--- 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, "/var/run/mdadm/");
+       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,6 +177,7 @@ int connect_monitor(char *devname)
        return sfd;
 }
 
+/* give the monitor a chance to update the metadata */
 int ping_monitor(char *devname)
 {
        int sfd = connect_monitor(devname);
@@ -183,3 +197,27 @@ int ping_monitor(char *devname)
        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;
+
+       close(sfd);
+       return err;
+}