diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-25 06:14:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-25 06:14:19 +0000 |
commit | 50f2ad8e92ef06e4dee6d7070049a96231d3a8ee (patch) | |
tree | b7cda9c5caad5948899bf7d6551262d9d7d86d09 /util.c | |
parent | Adding upstream version 4.3+20240412. (diff) | |
download | mdadm-upstream.tar.xz mdadm-upstream.zip |
Adding upstream version 4.3+20240723.upstream/4.3+20240723upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | util.c | 121 |
1 files changed, 103 insertions, 18 deletions
@@ -633,9 +633,9 @@ int check_ext2(int fd, char *name) bsize = sb[24]|(sb[25]|(sb[26]|sb[27]<<8)<<8)<<8; size = sb[4]|(sb[5]|(sb[6]|sb[7]<<8)<<8)<<8; size <<= bsize; - pr_err("%s appears to contain an ext2fs file system\n", + pr_info("%s appears to contain an ext2fs file system\n", name); - cont_err("size=%lluK mtime=%s", size, ctime(&mtime)); + pr_info("size=%lluK mtime=%s", size, ctime(&mtime)); return 1; } @@ -725,23 +725,33 @@ int stat_is_blkdev(char *devname, dev_t *rdev) return 1; } +/** + * ask() - prompt user for "yes/no" dialog. + * @mesg: message to be printed, without '?' sign. + * Returns: 1 if 'Y/y', 0 otherwise. + * + * The default value is 'N/n', thus the caps on "N" on prompt. + */ int ask(char *mesg) { - char *add = ""; - int i; - for (i = 0; i < 5; i++) { - char buf[100]; - fprintf(stderr, "%s%s", mesg, add); - fflush(stderr); - if (fgets(buf, 100, stdin)==NULL) - return 0; - if (buf[0]=='y' || buf[0]=='Y') - return 1; - if (buf[0]=='n' || buf[0]=='N') - return 0; - add = "(y/n) "; + char buf[3] = {0}; + + fprintf(stderr, "%s [y/N]? ", mesg); + fflush(stderr); + if (fgets(buf, 3, stdin) == NULL) + return 0; + if (strlen(buf) == 1) { + pr_err("assuming no.\n"); + return 0; } - pr_err("assuming 'no'\n"); + if (buf[1] != '\n') + goto bad_option; + if (toupper(buf[0]) == 'Y') + return 1; + if (toupper(buf[0]) == 'N') + return 0; +bad_option: + pr_err("bad option.\n"); return 0; } @@ -1868,6 +1878,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) if (st->ss->external) return sysfs_set_array(info); + memset(&inf, 0, sizeof(inf)); inf.major_version = info->array.major_version; inf.minor_version = info->array.minor_version; @@ -1891,7 +1902,7 @@ unsigned long long min_recovery_start(struct mdinfo *array) return recovery_start; } -int mdmon_pid(char *devnm) +int mdmon_pid(const char *devnm) { char path[100]; char pid[10]; @@ -1911,7 +1922,7 @@ int mdmon_pid(char *devnm) return atoi(pid); } -int mdmon_running(char *devnm) +int mdmon_running(const char *devnm) { int pid = mdmon_pid(devnm); if (pid <= 0) @@ -1921,6 +1932,80 @@ int mdmon_running(char *devnm) return 0; } +/* + * 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. + * + * Function waits for mdmon to start. It may need few seconds + * to start, we set timeout to 5, it should be sufficient. + * Do not wait if mdmon has been started. + * + * Return: MDADM_STATUS_SUCCESS if mdmon is running, error code otherwise. + */ +mdadm_status_t wait_for_mdmon(const char *devnm) +{ + const time_t mdmon_timeout = 5; + time_t start_time = time(0); + + if (mdmon_running(devnm)) + return MDADM_STATUS_SUCCESS; + + pr_info("Waiting for mdmon to start\n"); + while (time(0) - start_time < mdmon_timeout) { + sleep_for(0, MSEC_TO_NSEC(200), true); + if (mdmon_running(devnm)) + return MDADM_STATUS_SUCCESS; + }; + + pr_err("Timeout waiting for mdmon\n"); + return MDADM_STATUS_ERROR; +} + int start_mdmon(char *devnm) { int i; |