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

Reply via email to