Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/ctl/ctl_frontend_iscsi.c
Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/unistd.h> | #include <sys/unistd.h> | ||||
#include <sys/nv.h> | |||||
#include <sys/dnv.h> | |||||
#include <vm/uma.h> | #include <vm/uma.h> | ||||
#include <cam/scsi/scsi_all.h> | #include <cam/scsi/scsi_all.h> | ||||
#include <cam/scsi/scsi_da.h> | #include <cam/scsi/scsi_da.h> | ||||
#include <cam/ctl/ctl_io.h> | #include <cam/ctl/ctl_io.h> | ||||
#include <cam/ctl/ctl.h> | #include <cam/ctl/ctl.h> | ||||
#include <cam/ctl/ctl_backend.h> | #include <cam/ctl/ctl_backend.h> | ||||
#include <cam/ctl/ctl_error.h> | #include <cam/ctl/ctl_error.h> | ||||
▲ Show 20 Lines • Show All 2,020 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
copyout(ip->ip_bhs, cirp->bhs, sizeof(*ip->ip_bhs)); | copyout(ip->ip_bhs, cirp->bhs, sizeof(*ip->ip_bhs)); | ||||
if (ip->ip_data_len > 0) { | if (ip->ip_data_len > 0) { | ||||
data = malloc(ip->ip_data_len, M_CFISCSI, M_WAITOK); | data = malloc(ip->ip_data_len, M_CFISCSI, M_WAITOK); | ||||
icl_pdu_get_data(ip, 0, data, ip->ip_data_len); | icl_pdu_get_data(ip, 0, data, ip->ip_data_len); | ||||
copyout(data, cirp->data_segment, ip->ip_data_len); | copyout(data, cirp->data_segment, ip->ip_data_len); | ||||
free(data, M_CFISCSI); | free(data, M_CFISCSI); | ||||
} | } | ||||
mav: This change is probably not needed. I am usually trying to clean such ones during final patch… | |||||
icl_pdu_free(ip); | icl_pdu_free(ip); | ||||
ci->status = CTL_ISCSI_OK; | ci->status = CTL_ISCSI_OK; | ||||
} | } | ||||
#endif /* !ICL_KERNEL_PROXY */ | #endif /* !ICL_KERNEL_PROXY */ | ||||
static void | static void | ||||
cfiscsi_ioctl_port_create(struct ctl_req *req) | cfiscsi_ioctl_port_create(struct ctl_req *req) | ||||
{ | { | ||||
struct cfiscsi_target *ct; | struct cfiscsi_target *ct; | ||||
struct ctl_port *port; | struct ctl_port *port; | ||||
Done Inline ActionsType conversion is not needed here any more. mav: Type conversion is not needed here any more. | |||||
const char *target, *alias, *tags; | const char *target, *alias, *val; | ||||
struct scsi_vpd_id_descriptor *desc; | struct scsi_vpd_id_descriptor *desc; | ||||
ctl_options_t opts; | |||||
int retval, len, idlen; | int retval, len, idlen; | ||||
uint16_t tag; | uint16_t tag; | ||||
ctl_init_opts(&opts, req->num_args, req->kern_args); | target = dnvlist_get_string(req->args_nvl, "cfiscsi_target", NULL); | ||||
target = ctl_get_opt(&opts, "cfiscsi_target"); | alias = dnvlist_get_string(req->args_nvl, "cfiscsi_target_alias", NULL); | ||||
alias = ctl_get_opt(&opts, "cfiscsi_target_alias"); | val = dnvlist_get_string(req->args_nvl, "cfiscsi_portal_group_tag", | ||||
tags = ctl_get_opt(&opts, "cfiscsi_portal_group_tag"); | NULL); | ||||
if (target == NULL || tags == NULL) { | |||||
if (target == NULL || val == NULL) { | |||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"Missing required argument"); | "Missing required argument"); | ||||
ctl_free_opts(&opts); | |||||
return; | return; | ||||
} | } | ||||
tag = strtol(tags, (char **)NULL, 10); | |||||
tag = strtoul(val, NULL, 0); | |||||
ct = cfiscsi_target_find_or_create(&cfiscsi_softc, target, alias, tag); | ct = cfiscsi_target_find_or_create(&cfiscsi_softc, target, alias, tag); | ||||
if (ct == NULL) { | if (ct == NULL) { | ||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"failed to create target \"%s\"", target); | "failed to create target \"%s\"", target); | ||||
ctl_free_opts(&opts); | |||||
return; | return; | ||||
} | } | ||||
if (ct->ct_state == CFISCSI_TARGET_STATE_ACTIVE) { | if (ct->ct_state == CFISCSI_TARGET_STATE_ACTIVE) { | ||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"target \"%s\" for portal group tag %u already exists", | "target \"%s\" for portal group tag %u already exists", | ||||
target, tag); | target, tag); | ||||
cfiscsi_target_release(ct); | cfiscsi_target_release(ct); | ||||
ctl_free_opts(&opts); | |||||
return; | return; | ||||
} | } | ||||
port = &ct->ct_port; | port = &ct->ct_port; | ||||
// WAT | // WAT | ||||
Not Done Inline ActionsHere should also be (uint16_t), same as in other cases. I would much prefer uint16_t variable, if not the error checking using magic -1 value. mav: Here should also be (uint16_t), same as in other cases. I would much prefer uint16_t variable… | |||||
if (ct->ct_state == CFISCSI_TARGET_STATE_DYING) | if (ct->ct_state == CFISCSI_TARGET_STATE_DYING) | ||||
goto done; | goto done; | ||||
port->frontend = &cfiscsi_frontend; | port->frontend = &cfiscsi_frontend; | ||||
port->port_type = CTL_PORT_ISCSI; | port->port_type = CTL_PORT_ISCSI; | ||||
/* XXX KDM what should the real number be here? */ | /* XXX KDM what should the real number be here? */ | ||||
port->num_requested_ctl_io = 4096; | port->num_requested_ctl_io = 4096; | ||||
port->port_name = "iscsi"; | port->port_name = "iscsi"; | ||||
port->physical_port = tag; | port->physical_port = (int)tag; | ||||
port->virtual_port = ct->ct_target_id; | port->virtual_port = ct->ct_target_id; | ||||
port->port_online = cfiscsi_online; | port->port_online = cfiscsi_online; | ||||
port->port_offline = cfiscsi_offline; | port->port_offline = cfiscsi_offline; | ||||
port->port_info = cfiscsi_info; | port->port_info = cfiscsi_info; | ||||
port->onoff_arg = ct; | port->onoff_arg = ct; | ||||
port->fe_datamove = cfiscsi_datamove; | port->fe_datamove = cfiscsi_datamove; | ||||
port->fe_done = cfiscsi_done; | port->fe_done = cfiscsi_done; | ||||
port->targ_port = -1; | port->targ_port = -1; | ||||
port->options = nvlist_clone(req->args_nvl); | |||||
port->options = opts; | |||||
STAILQ_INIT(&opts); | |||||
/* Generate Port ID. */ | /* Generate Port ID. */ | ||||
idlen = strlen(target) + strlen(",t,0x0001") + 1; | idlen = strlen(target) + strlen(",t,0x0001") + 1; | ||||
idlen = roundup2(idlen, 4); | idlen = roundup2(idlen, 4); | ||||
len = sizeof(struct scsi_vpd_device_id) + idlen; | len = sizeof(struct scsi_vpd_device_id) + idlen; | ||||
port->port_devid = malloc(sizeof(struct ctl_devid) + len, | port->port_devid = malloc(sizeof(struct ctl_devid) + len, | ||||
M_CTL, M_WAITOK | M_ZERO); | M_CTL, M_WAITOK | M_ZERO); | ||||
port->port_devid->len = len; | port->port_devid->len = len; | ||||
desc = (struct scsi_vpd_id_descriptor *)port->port_devid->data; | desc = (struct scsi_vpd_id_descriptor *)port->port_devid->data; | ||||
Show All 9 Lines | cfiscsi_ioctl_port_create(struct ctl_req *req) | ||||
len = sizeof(struct scsi_vpd_device_id) + idlen; | len = sizeof(struct scsi_vpd_device_id) + idlen; | ||||
port->target_devid = malloc(sizeof(struct ctl_devid) + len, | port->target_devid = malloc(sizeof(struct ctl_devid) + len, | ||||
M_CTL, M_WAITOK | M_ZERO); | M_CTL, M_WAITOK | M_ZERO); | ||||
port->target_devid->len = len; | port->target_devid->len = len; | ||||
desc = (struct scsi_vpd_id_descriptor *)port->target_devid->data; | desc = (struct scsi_vpd_id_descriptor *)port->target_devid->data; | ||||
desc->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8; | desc->proto_codeset = (SCSI_PROTO_ISCSI << 4) | SVPD_ID_CODESET_UTF8; | ||||
desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_TARGET | | desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_TARGET | | ||||
SVPD_ID_TYPE_SCSI_NAME; | SVPD_ID_TYPE_SCSI_NAME; | ||||
desc->length = idlen; | desc->length = idlen; | ||||
Done Inline ActionsHere should better be NULL instead of 0. mav: Here should better be NULL instead of 0. | |||||
strlcpy(desc->identifier, target, idlen); | strlcpy(desc->identifier, target, idlen); | ||||
retval = ctl_port_register(port); | retval = ctl_port_register(port); | ||||
if (retval != 0) { | if (retval != 0) { | ||||
ctl_free_opts(&port->options); | |||||
free(port->port_devid, M_CFISCSI); | free(port->port_devid, M_CFISCSI); | ||||
free(port->target_devid, M_CFISCSI); | free(port->target_devid, M_CFISCSI); | ||||
cfiscsi_target_release(ct); | cfiscsi_target_release(ct); | ||||
Done Inline ActionsSame as above. mav: Same as above. | |||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"ctl_port_register() failed with error %d", retval); | "ctl_port_register() failed with error %d", retval); | ||||
return; | return; | ||||
} | } | ||||
done: | done: | ||||
ct->ct_state = CFISCSI_TARGET_STATE_ACTIVE; | ct->ct_state = CFISCSI_TARGET_STATE_ACTIVE; | ||||
req->status = CTL_LUN_OK; | req->status = CTL_LUN_OK; | ||||
memcpy(req->kern_args[0].kvalue, &port->targ_port, | req->result_nvl = nvlist_create(0); | ||||
sizeof(port->targ_port)); //XXX | nvlist_add_number(req->result_nvl, "port_id", port->targ_port); | ||||
} | } | ||||
static void | static void | ||||
cfiscsi_ioctl_port_remove(struct ctl_req *req) | cfiscsi_ioctl_port_remove(struct ctl_req *req) | ||||
{ | { | ||||
struct cfiscsi_target *ct; | struct cfiscsi_target *ct; | ||||
const char *target, *tags; | const char *target, *val; | ||||
ctl_options_t opts; | |||||
uint16_t tag; | uint16_t tag; | ||||
ctl_init_opts(&opts, req->num_args, req->kern_args); | target = dnvlist_get_string(req->args_nvl, "cfiscsi_target", NULL); | ||||
target = ctl_get_opt(&opts, "cfiscsi_target"); | val = dnvlist_get_string(req->args_nvl, "cfiscsi_portal_group_tag", | ||||
tags = ctl_get_opt(&opts, "cfiscsi_portal_group_tag"); | NULL); | ||||
if (target == NULL || tags == NULL) { | |||||
ctl_free_opts(&opts); | if (target == NULL || val == NULL) { | ||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"Missing required argument"); | "Missing required argument"); | ||||
return; | return; | ||||
} | } | ||||
tag = strtol(tags, (char **)NULL, 10); | |||||
tag = strtoul(val, NULL, 0); | |||||
ct = cfiscsi_target_find(&cfiscsi_softc, target, tag); | ct = cfiscsi_target_find(&cfiscsi_softc, target, tag); | ||||
if (ct == NULL) { | if (ct == NULL) { | ||||
ctl_free_opts(&opts); | |||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"can't find target \"%s\"", target); | "can't find target \"%s\"", target); | ||||
return; | return; | ||||
} | } | ||||
if (ct->ct_state != CFISCSI_TARGET_STATE_ACTIVE) { | if (ct->ct_state != CFISCSI_TARGET_STATE_ACTIVE) { | ||||
ctl_free_opts(&opts); | |||||
req->status = CTL_LUN_ERROR; | req->status = CTL_LUN_ERROR; | ||||
snprintf(req->error_str, sizeof(req->error_str), | snprintf(req->error_str, sizeof(req->error_str), | ||||
"target \"%s\" is already dying", target); | "target \"%s\" is already dying", target); | ||||
return; | return; | ||||
} | } | ||||
ctl_free_opts(&opts); | |||||
ct->ct_state = CFISCSI_TARGET_STATE_DYING; | ct->ct_state = CFISCSI_TARGET_STATE_DYING; | ||||
ctl_port_offline(&ct->ct_port); | ctl_port_offline(&ct->ct_port); | ||||
cfiscsi_target_release(ct); | cfiscsi_target_release(ct); | ||||
cfiscsi_target_release(ct); | cfiscsi_target_release(ct); | ||||
req->status = CTL_LUN_OK; | req->status = CTL_LUN_OK; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 773 Lines • Show Last 20 Lines |
This change is probably not needed. I am usually trying to clean such ones during final patch review.