This patch fixes a problem when formatting multiple disks, where either another instance of iprconfig or iprinit or some similar tool ends up calling evaluate_device before the issuing iprconfig does, resulting in formatted devices that are not flagged as known zeroed. This adds some locking around this function to ensure that does not happen.
Signed-off-by: Brian King <brk...@linux.vnet.ibm.com> --- iprconfig.c | 19 ++++++++++++++++--- iprlib.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- iprlib.h | 2 ++ 3 files changed, 64 insertions(+), 4 deletions(-) diff -puN iprlib.h~iprutils_format_lock iprlib.h --- iprutils.patched/iprlib.h~iprutils_format_lock 2016-07-20 10:55:36.712598374 -0500 +++ iprutils.patched-bjking1/iprlib.h 2016-07-20 10:55:36.725598295 -0500 @@ -1484,6 +1484,8 @@ struct ipr_dev { u8 supports_4k:1; u8 supports_5xx:1; u8 read_c7:1; + u8 locked:1; + int lock_fd; u32 format_timeout; struct scsi_dev_data *scsi_dev_data; struct ipr_dev *ses[IPR_DEV_MAX_PATHS]; diff -puN iprlib.c~iprutils_format_lock iprlib.c --- iprutils.patched/iprlib.c~iprutils_format_lock 2016-07-20 10:55:36.715598356 -0500 +++ iprutils.patched-bjking1/iprlib.c 2016-07-20 10:55:36.728598276 -0500 @@ -3749,6 +3749,50 @@ static struct ipr_dev *find_multipath_jb return NULL; } +int ipr_device_lock(struct ipr_dev *dev) +{ + int fd, rc; + char *name = dev->gen_name; + + if (strlen(name) == 0) + return -ENOENT; + + if (dev->locked) { + scsi_err(dev, "Device already locked\n"); + return -EINVAL; + } + + fd = open(name, O_RDWR); + if (fd <= 1) { + if (!strcmp(tool_name, "iprconfig") || ipr_debug) + syslog(LOG_ERR, "Could not open %s. %m\n", name); + return errno; + } + + rc = flock(fd, LOCK_EX); + + if (rc) { + if (!strcmp(tool_name, "iprconfig") || ipr_debug) + syslog(LOG_ERR, "Could not lock %s. %m\n", name); + close(fd); + return errno; + } + + /* Do not close the file descriptor here as we want to hold onto the lock */ + dev->locked = 1; + dev->lock_fd = fd; + return rc; +} + +void ipr_device_unlock(struct ipr_dev *dev) +{ + if (dev->locked) { + close(dev->lock_fd); + dev->locked = 0; + dev->lock_fd = 0; + } +} + /** * ipr_format_unit - * @dev: ipr dev struct @@ -9837,11 +9881,12 @@ static int fixup_improper_devs(struct ip for_each_dev(ioa, dev) { dev->local_flag = 0; - if (ipr_improper_device_type(dev)) { + if (ipr_improper_device_type(dev) && !ipr_device_lock(dev)) { improper++; dev->local_flag = 1; scsi_dbg(dev, "Deleting improper device\n"); ipr_write_dev_attr(dev, "delete", "1"); + ipr_device_unlock(dev); } } diff -puN iprconfig.c~iprutils_format_lock iprconfig.c --- iprutils.patched/iprconfig.c~iprutils_format_lock 2016-07-20 10:55:36.719598331 -0500 +++ iprutils.patched-bjking1/iprconfig.c 2016-07-20 10:55:36.731598258 -0500 @@ -1649,6 +1649,9 @@ static void verify_device(struct ipr_dev return; } + if (ipr_device_lock(dev)) + return; + if (ipr_is_af(dev)) { if ((rc = ipr_query_command_status(dev, &cmd_status))) return; @@ -1675,6 +1678,8 @@ static void verify_device(struct ipr_dev } } } + + ipr_device_unlock(dev); } /** @@ -8818,6 +8823,8 @@ static int dev_init_complete(u8 num_devs evaluate_device(dev->dev, ioa, dev->new_block_size); } + ipr_device_unlock(dev->dev); + if (ipr_is_af_blk_size(ioa, dev->new_block_size) || ipr_is_af_dasd_device(dev->dev)) ipr_add_zeroed_dev(dev->dev); } @@ -8944,7 +8951,7 @@ int send_dev_inits(i_container *i_con) } /* Issue the format. Failure will be detected by query command status */ - rc = ipr_format_unit(cur_dev_init->dev); /* FIXME Mandatory lock? */ + rc = ipr_format_unit(cur_dev_init->dev); } else if (cur_dev_init->do_init && cur_dev_init->dev_type == IPR_JBOD_DASD_DEVICE) { num_devs++; @@ -9011,8 +9018,13 @@ int send_dev_inits(i_container *i_con) syslog(LOG_ERR, "Could not unbind %s: %m\n", cur_dev_init->dev->dev_name); - /* Issue format */ - status = ipr_format_unit(cur_dev_init->dev); /* FIXME Mandatory lock? */ + status = 0; + + if (ipr_is_af_blk_size(ioa, cur_dev_init->new_block_size)) + status = ipr_device_lock(cur_dev_init->dev); + + if (!status) + status = ipr_format_unit(cur_dev_init->dev); if (status) { /* Send a device reset to cleanup any old state */ @@ -9023,6 +9035,7 @@ int send_dev_inits(i_container *i_con) "Could not bind %s: %m\n", cur_dev_init->dev->dev_name); + ipr_device_unlock(cur_dev_init->dev); cur_dev_init->do_init = 0; num_devs--; failure++; _ ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports.http://sdm.link/zohodev2dev _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel