summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorShminderjit Singh <shminderjit.singh@oracle.com>2024-06-24 10:58:51 +0200
committerMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>2024-07-02 12:15:46 +0200
commit3cbe13403ec0c78374343dcd889609aefe791f9b (patch)
tree4aa37b64750e1c2729150ea5853daf6accd08673 /util.c
parentCI: fix excluded files in checkpatch.conf (diff)
downloadmdadm-3cbe13403ec0c78374343dcd889609aefe791f9b.tar.xz
mdadm-3cbe13403ec0c78374343dcd889609aefe791f9b.zip
mdadm: Fix socket connection failure when mdmon runs in foreground mode.
While creating an IMSM RAID, mdadm will wait for the mdmon main process to finish if mdmon runs in forking mode. This is because with "Type=forking" in the mdmon service unit file, "systemctl start service" will block until the main process of mdmon exits. At that moment, mdmon has already created the socket, so the subsequent socket connect from mdadm will succeed. However, when mdmon runs in foreground mode (without "Type=forking" in the service unit file), "systemctl start service" will return once the mdmon process starts. This causes mdadm and mdmon to run in parallel, which may lead to a socket connection failure since mdmon has not yet initialized the socket when mdadm tries to connect. If the next instruction/command is to access this device and try to write to it, a permission error will occur since mdmon has not yet set the array to RW mode. Signed-off-by: Shminderjit Singh <shminderjit.singh@oracle.com>
Diffstat (limited to 'util.c')
-rw-r--r--util.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/util.c b/util.c
index 48c97545..908f8430 100644
--- a/util.c
+++ b/util.c
@@ -1933,6 +1933,51 @@ int mdmon_running(const char *devnm)
}
/*
+ * wait_for_mdmon_control_socket() - Waits for mdmon control socket
+ * to be created within specified time.
+ * @container_devnm: Device for which mdmon control socket should start.
+ *
+ * In foreground mode, when mdadm is trying to connect to control
+ * socket it is possible that the mdmon has not created it yet.
+ * Give some time to mdmon to create socket. Timeout set to 2 sec.
+ *
+ * Return: MDADM_STATUS_SUCCESS if connect succeed, otherwise return
+ * error code.
+ */
+mdadm_status_t wait_for_mdmon_control_socket(const char *container_devnm)
+{
+ enum mdadm_status status = MDADM_STATUS_SUCCESS;
+ int sfd, rv, retry_count = 0;
+ struct sockaddr_un addr;
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s/%s.sock", MDMON_DIR, container_devnm);
+ sfd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (!is_fd_valid(sfd))
+ return MDADM_STATUS_ERROR;
+
+ addr.sun_family = PF_LOCAL;
+ strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
+
+ for (retry_count = 0; retry_count < 10; retry_count++) {
+ rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
+ if (rv < 0) {
+ sleep_for(0, MSEC_TO_NSEC(200), true);
+ continue;
+ }
+ break;
+ }
+
+ if (rv < 0) {
+ pr_err("Failed to connect to control socket.\n");
+ status = MDADM_STATUS_ERROR;
+ }
+ close(sfd);
+ return status;
+}
+
+/*
* wait_for_mdmon() - Waits for mdmon within specified time.
* @devnm: Device for which mdmon should start.
*