[SCSI] libiscsi: handle param allocation failures
If we could not allocate the initiator name or some other id like the hwaddress or netdev, then userspace could deal with the failure by just running in a dregraded mode. Now we want to be able to switch values for the params and we want some feedback, so this patch will check if a string like the initiatorname could not be allocated and return an error. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
Родитель
184b57c630
Коммит
5700b1af93
|
@ -2656,6 +2656,23 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iscsi_conn_bind);
|
EXPORT_SYMBOL_GPL(iscsi_conn_bind);
|
||||||
|
|
||||||
|
static int iscsi_switch_str_param(char **param, char *new_val_buf)
|
||||||
|
{
|
||||||
|
char *new_val;
|
||||||
|
|
||||||
|
if (*param) {
|
||||||
|
if (!strcmp(*param, new_val_buf))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_val = kstrdup(new_val_buf, GFP_NOIO);
|
||||||
|
if (!new_val)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
kfree(*param);
|
||||||
|
*param = new_val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
||||||
enum iscsi_param param, char *buf, int buflen)
|
enum iscsi_param param, char *buf, int buflen)
|
||||||
|
@ -2728,38 +2745,15 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
||||||
sscanf(buf, "%u", &conn->exp_statsn);
|
sscanf(buf, "%u", &conn->exp_statsn);
|
||||||
break;
|
break;
|
||||||
case ISCSI_PARAM_USERNAME:
|
case ISCSI_PARAM_USERNAME:
|
||||||
kfree(session->username);
|
return iscsi_switch_str_param(&session->username, buf);
|
||||||
session->username = kstrdup(buf, GFP_KERNEL);
|
|
||||||
if (!session->username)
|
|
||||||
return -ENOMEM;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_USERNAME_IN:
|
case ISCSI_PARAM_USERNAME_IN:
|
||||||
kfree(session->username_in);
|
return iscsi_switch_str_param(&session->username_in, buf);
|
||||||
session->username_in = kstrdup(buf, GFP_KERNEL);
|
|
||||||
if (!session->username_in)
|
|
||||||
return -ENOMEM;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_PASSWORD:
|
case ISCSI_PARAM_PASSWORD:
|
||||||
kfree(session->password);
|
return iscsi_switch_str_param(&session->password, buf);
|
||||||
session->password = kstrdup(buf, GFP_KERNEL);
|
|
||||||
if (!session->password)
|
|
||||||
return -ENOMEM;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_PASSWORD_IN:
|
case ISCSI_PARAM_PASSWORD_IN:
|
||||||
kfree(session->password_in);
|
return iscsi_switch_str_param(&session->password_in, buf);
|
||||||
session->password_in = kstrdup(buf, GFP_KERNEL);
|
|
||||||
if (!session->password_in)
|
|
||||||
return -ENOMEM;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_TARGET_NAME:
|
case ISCSI_PARAM_TARGET_NAME:
|
||||||
/* this should not change between logins */
|
return iscsi_switch_str_param(&session->targetname, buf);
|
||||||
if (session->targetname)
|
|
||||||
break;
|
|
||||||
|
|
||||||
session->targetname = kstrdup(buf, GFP_KERNEL);
|
|
||||||
if (!session->targetname)
|
|
||||||
return -ENOMEM;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_TPGT:
|
case ISCSI_PARAM_TPGT:
|
||||||
sscanf(buf, "%d", &session->tpgt);
|
sscanf(buf, "%d", &session->tpgt);
|
||||||
break;
|
break;
|
||||||
|
@ -2767,25 +2761,11 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
|
||||||
sscanf(buf, "%d", &conn->persistent_port);
|
sscanf(buf, "%d", &conn->persistent_port);
|
||||||
break;
|
break;
|
||||||
case ISCSI_PARAM_PERSISTENT_ADDRESS:
|
case ISCSI_PARAM_PERSISTENT_ADDRESS:
|
||||||
/*
|
return iscsi_switch_str_param(&conn->persistent_address, buf);
|
||||||
* this is the address returned in discovery so it should
|
|
||||||
* not change between logins.
|
|
||||||
*/
|
|
||||||
if (conn->persistent_address)
|
|
||||||
break;
|
|
||||||
|
|
||||||
conn->persistent_address = kstrdup(buf, GFP_KERNEL);
|
|
||||||
if (!conn->persistent_address)
|
|
||||||
return -ENOMEM;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_IFACE_NAME:
|
case ISCSI_PARAM_IFACE_NAME:
|
||||||
if (!session->ifacename)
|
return iscsi_switch_str_param(&session->ifacename, buf);
|
||||||
session->ifacename = kstrdup(buf, GFP_KERNEL);
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_INITIATOR_NAME:
|
case ISCSI_PARAM_INITIATOR_NAME:
|
||||||
if (!session->initiatorname)
|
return iscsi_switch_str_param(&session->initiatorname, buf);
|
||||||
session->initiatorname = kstrdup(buf, GFP_KERNEL);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
@ -2856,10 +2836,7 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
|
||||||
len = sprintf(buf, "%s\n", session->ifacename);
|
len = sprintf(buf, "%s\n", session->ifacename);
|
||||||
break;
|
break;
|
||||||
case ISCSI_PARAM_INITIATOR_NAME:
|
case ISCSI_PARAM_INITIATOR_NAME:
|
||||||
if (!session->initiatorname)
|
len = sprintf(buf, "%s\n", session->initiatorname);
|
||||||
len = sprintf(buf, "%s\n", "unknown");
|
|
||||||
else
|
|
||||||
len = sprintf(buf, "%s\n", session->initiatorname);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
@ -2925,29 +2902,16 @@ int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case ISCSI_HOST_PARAM_NETDEV_NAME:
|
case ISCSI_HOST_PARAM_NETDEV_NAME:
|
||||||
if (!ihost->netdev)
|
len = sprintf(buf, "%s\n", ihost->netdev);
|
||||||
len = sprintf(buf, "%s\n", "default");
|
|
||||||
else
|
|
||||||
len = sprintf(buf, "%s\n", ihost->netdev);
|
|
||||||
break;
|
break;
|
||||||
case ISCSI_HOST_PARAM_HWADDRESS:
|
case ISCSI_HOST_PARAM_HWADDRESS:
|
||||||
if (!ihost->hwaddress)
|
len = sprintf(buf, "%s\n", ihost->hwaddress);
|
||||||
len = sprintf(buf, "%s\n", "default");
|
|
||||||
else
|
|
||||||
len = sprintf(buf, "%s\n", ihost->hwaddress);
|
|
||||||
break;
|
break;
|
||||||
case ISCSI_HOST_PARAM_INITIATOR_NAME:
|
case ISCSI_HOST_PARAM_INITIATOR_NAME:
|
||||||
if (!ihost->initiatorname)
|
len = sprintf(buf, "%s\n", ihost->initiatorname);
|
||||||
len = sprintf(buf, "%s\n", "unknown");
|
|
||||||
else
|
|
||||||
len = sprintf(buf, "%s\n", ihost->initiatorname);
|
|
||||||
break;
|
break;
|
||||||
case ISCSI_HOST_PARAM_IPADDRESS:
|
case ISCSI_HOST_PARAM_IPADDRESS:
|
||||||
if (!strlen(ihost->local_address))
|
len = sprintf(buf, "%s\n", ihost->local_address);
|
||||||
len = sprintf(buf, "%s\n", "unknown");
|
|
||||||
else
|
|
||||||
len = sprintf(buf, "%s\n",
|
|
||||||
ihost->local_address);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
@ -2964,17 +2928,11 @@ int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param,
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case ISCSI_HOST_PARAM_NETDEV_NAME:
|
case ISCSI_HOST_PARAM_NETDEV_NAME:
|
||||||
if (!ihost->netdev)
|
return iscsi_switch_str_param(&ihost->netdev, buf);
|
||||||
ihost->netdev = kstrdup(buf, GFP_KERNEL);
|
|
||||||
break;
|
|
||||||
case ISCSI_HOST_PARAM_HWADDRESS:
|
case ISCSI_HOST_PARAM_HWADDRESS:
|
||||||
if (!ihost->hwaddress)
|
return iscsi_switch_str_param(&ihost->hwaddress, buf);
|
||||||
ihost->hwaddress = kstrdup(buf, GFP_KERNEL);
|
|
||||||
break;
|
|
||||||
case ISCSI_HOST_PARAM_INITIATOR_NAME:
|
case ISCSI_HOST_PARAM_INITIATOR_NAME:
|
||||||
if (!ihost->initiatorname)
|
return iscsi_switch_str_param(&ihost->initiatorname, buf);
|
||||||
ihost->initiatorname = kstrdup(buf, GFP_KERNEL);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче