If the iprinit daemon runs prior to the sg module being loaded, it is not able to talk to the ipr adapters and do much of anything that is useful. This was observed on a system where the adapter write cache was not getting enabled at times during boot. This modifies iprinit to check to see if the sg module is loaded and also checks to see if its actually been bound to each ipr adapter yet. If not, it makes iprinit wait for a bit until this happens. Some distros load sg via a udev rule which can happen in parallel to iprinit starting, so this fixes this race. It also adds some informational logging to make it easier to track when this indeed does occur in case a system never loads the sg driver.
Signed-off-by: Brian King <brk...@linux.vnet.ibm.com> --- iprconfig.c | 19 ------------------- iprinit.c | 33 +++++++++++++++++++++++++++++---- iprlib.c | 23 +++++++++++++++++++++-- iprlib.h | 1 + 4 files changed, 51 insertions(+), 25 deletions(-) diff -puN iprconfig.c~iprutils_wait_for_sg_iprinit iprconfig.c --- iprutils.patched/iprconfig.c~iprutils_wait_for_sg_iprinit 2016-09-22 21:08:29.842241924 -0500 +++ iprutils.patched-bjking1/iprconfig.c 2016-09-22 21:08:29.861242017 -0500 @@ -19419,25 +19419,6 @@ static int non_intenactive_cmd(char *cmd return -EINVAL; } -int check_sg_module() -{ - DIR *sg_dirfd; - char devpath[PATH_MAX]; - - sprintf(devpath, "%s", "/sys/module/sg"); - - sg_dirfd = opendir(devpath); - - if (!sg_dirfd) { - syslog_dbg("Failed to open sg parameter.\n"); - return -1; - } - - closedir(sg_dirfd); - - return 0; -} - void list_options() { int i; diff -puN iprlib.c~iprutils_wait_for_sg_iprinit iprlib.c --- iprutils.patched/iprlib.c~iprutils_wait_for_sg_iprinit 2016-09-22 21:08:29.845241938 -0500 +++ iprutils.patched-bjking1/iprlib.c 2016-09-22 21:08:29.864242032 -0500 @@ -6571,8 +6571,8 @@ void check_current_config(bool allow_reb int *qac_entry_ref; struct ipr_dev_identify_vpd di_vpd; char *pchr; - struct ipr_mode_pages mode_pages; - struct ipr_ioa_mode_page *page; + struct ipr_mode_pages mode_pages; + struct ipr_ioa_mode_page *page; if (ipr_qac_data == NULL) { ipr_qac_data = @@ -10360,3 +10360,22 @@ int ipr_ses_set_time(struct ipr_dev *dev return ipr_send_diagnostics(dev, &set_time, sizeof(set_time)); } + +int check_sg_module() +{ + DIR *sg_dirfd; + char devpath[PATH_MAX]; + + sprintf(devpath, "%s", "/sys/module/sg"); + + sg_dirfd = opendir(devpath); + + if (!sg_dirfd) { + syslog_dbg("Failed to open sg parameter.\n"); + return -1; + } + + closedir(sg_dirfd); + + return 0; +} diff -puN iprlib.h~iprutils_wait_for_sg_iprinit iprlib.h --- iprutils.patched/iprlib.h~iprutils_wait_for_sg_iprinit 2016-09-22 21:08:29.849241958 -0500 +++ iprutils.patched-bjking1/iprlib.h 2016-09-22 21:08:29.865242037 -0500 @@ -2956,6 +2956,7 @@ void ipr_count_devices_in_vset(struct ip int ipr_known_zeroed_is_saved(struct ipr_dev *); int get_sg_name(struct scsi_dev_data *); int ipr_sg_inquiry(struct scsi_dev_data *, u8, void *, u8); +int check_sg_module(); static inline u32 ipr_get_dev_res_handle(struct ipr_ioa *ioa, struct ipr_dev_record *dev_rcd) { diff -puN iprinit.c~iprutils_wait_for_sg_iprinit iprinit.c --- iprutils.patched/iprinit.c~iprutils_wait_for_sg_iprinit 2016-09-22 21:08:29.854241983 -0500 +++ iprutils.patched-bjking1/iprinit.c 2016-09-22 21:08:29.865242037 -0500 @@ -27,7 +27,7 @@ char *tool_name = "iprinit"; -static void init_all() +static int init_all() { struct ipr_ioa *ioa; int rc = tool_init(1); @@ -39,8 +39,12 @@ static void init_all() syslog(LOG_ERR, "Error initializing adapters. Perhaps run with sudo?\n"); } check_current_config(false); - for_each_ioa(ioa) + for_each_ioa(ioa) { + if (!strlen(ioa->ioa.gen_name)) + rc |= -EAGAIN; ipr_init_ioa(ioa); + } + return rc; } static void kevent_handler(char *buf) @@ -65,7 +69,7 @@ static void poll_ioas() int main(int argc, char *argv[]) { - int i; + int i, rc, delay_secs, wait; ipr_sg_required = 1; @@ -81,10 +85,31 @@ int main(int argc, char *argv[]) } } - init_all(); + rc = check_sg_module(); + + if (!rc) + rc = init_all(); if (daemonize) { ipr_daemonize(); + if (rc) { + syslog(LOG_INFO, "Waiting for ipr adapters and sg module to come ready.\n"); + + delay_secs = 2; + sleep(delay_secs); + + for (wait = 0; rc && wait < 300; wait += delay_secs) { + rc = check_sg_module(); + sleep(delay_secs); + if (!rc) + rc = init_all(); + } + + if (rc) + syslog(LOG_ERR, "Timeout reached. Ensure the sg module is loaded, then " + "run iprinit manually to ensure all " + "ipr RAID adapters are running optimally\n"); + } return handle_events(poll_ioas, 60, kevent_handler); } _ ------------------------------------------------------------------------------ _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel