summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Create.c6
-rw-r--r--mdadm.h1
-rw-r--r--util.c45
3 files changed, 50 insertions, 2 deletions
diff --git a/Create.c b/Create.c
index bd4875e4..479c2715 100644
--- a/Create.c
+++ b/Create.c
@@ -1344,9 +1344,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
if (c->verbose >= 0)
pr_info("array %s started.\n", chosen_name);
if (st->ss->external && st->container_devnm[0]) {
- if (need_mdmon)
+ if (need_mdmon) {
start_mdmon(st->container_devnm);
-
+ if (wait_for_mdmon_control_socket(st->container_devnm) != MDADM_STATUS_SUCCESS)
+ goto abort;
+ }
ping_monitor(st->container_devnm);
close(container_fd);
}
diff --git a/mdadm.h b/mdadm.h
index e9f764a2..27009154 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1776,6 +1776,7 @@ extern int is_subarray_active(char *subarray, char *devname);
extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet);
extern struct superswitch *version_to_superswitch(char *vers);
+extern mdadm_status_t wait_for_mdmon_control_socket(const char *container_devnm);
extern int mdmon_running(const char *devnm);
extern int mdmon_pid(const char *devnm);
extern mdadm_status_t wait_for_mdmon(const char *devnm);
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.
*