iprutils: Unbind device before JBOD -> AF formatting.

Introducing a new function for binding and unbinding a JBOD device, which is
used before formatting and in case we need to rollback because of a
failure. This prevents overlength errors when a read is issued to the disk
during formatting.

Changes since v1:
- Added two missing close() to ipr_jbod_sysfs_bind()

Signed-off-by: Heitor Ricardo Alves de Siqueira <halves@linux.vnet.ibm.com>
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
This commit is contained in:
Heitor Ricardo Alves de Siqueira 2015-11-26 10:17:47 -02:00 • committed by Brian King
commit 0b693bd29c
3 changed files with 62 additions and 0 deletions

View file

@ -8862,12 +8862,23 @@ int send_dev_inits(i_container *i_con)
continue;
}
/* unbind device */
if (ipr_jbod_sysfs_bind(cur_dev_init->dev,
IPR_JBOD_SYSFS_UNBIND))
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? */
if (status) {
/* Send a device reset to cleanup any old state */
rc = ipr_reset_device(cur_dev_init->dev);
if (ipr_jbod_sysfs_bind(cur_dev_init->dev,
IPR_JBOD_SYSFS_BIND))
syslog(LOG_ERR,
"Could not bind %s: %m\n",
cur_dev_init->dev->dev_name);
cur_dev_init->do_init = 0;
num_devs--;

View file

@ -10031,3 +10031,51 @@ int ipr_query_io_dev_port(struct ipr_dev *dev, struct ipr_query_io_port *io_port
return rc;
}
/**
* ipr_jbod_sysfs_bind -
* @dev: ipr dev struct
* @op: sysfs operation
*
* Returns:
* 0 if success / non-zero on failure
**/
int ipr_jbod_sysfs_bind(struct ipr_dev *dev, u8 op)
{
struct ipr_dev *mp_dev;
int rc, fd, size;
char *sysfs_device_name;
sysfs_device_name = dev->scsi_dev_data->sysfs_device_name;
size = strnlen(sysfs_device_name, sizeof(sysfs_device_name));
if (op == IPR_JBOD_SYSFS_BIND) {
fd = open("/sys/bus/scsi/drivers/sd/bind", O_WRONLY);
} else if (op == IPR_JBOD_SYSFS_UNBIND) {
fd = open("/sys/bus/scsi/drivers/sd/unbind", O_WRONLY);
} else {
fd = -1;
errno = ENOTSUP;
}
if (fd < 0)
return errno;
rc = write(fd, sysfs_device_name, size);
if (rc < 0) {
close(fd);
return errno;
}
mp_dev = find_multipath_jbod(dev);
if (mp_dev) {
sysfs_device_name = mp_dev->scsi_dev_data->sysfs_device_name;
size = strnlen(sysfs_device_name, sizeof(sysfs_device_name));
rc = write(fd, sysfs_device_name, size);
if (rc < 0) {
close(fd);
return errno;
}
}
close(fd);
return 0;
}

View file

@ -1321,6 +1321,9 @@ struct ipr_mode_page_28_scsi_dev_bus_attr {
#define IPR_MAX_XFER_RATE 320
#define IPR_SAFE_XFER_RATE 160
#define IPR_JBOD_SYSFS_UNBIND 0
#define IPR_JBOD_SYSFS_BIND 1
/* Internal return codes */
#define RC_SUCCESS 0
#define RC_FAILED -1