mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-21 11:13:30 +00:00
Close race in r268291 between port destruction, delayed by sessions
teardown, and new port creation during `service ctld restart`. Close it by returning iSCSI port internal state, that allows to identify dying ports, which should not be counted as existing, from really alive.
This commit is contained in:
parent
09132ba6ac
commit
1380b77c12
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268328
@ -3252,6 +3252,11 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
|||||||
if (retval != 0)
|
if (retval != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (port->port_info != NULL) {
|
||||||
|
retval = port->port_info(port->onoff_arg, sb);
|
||||||
|
if (retval != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
STAILQ_FOREACH(opt, &port->options, links) {
|
STAILQ_FOREACH(opt, &port->options, links) {
|
||||||
retval = sbuf_printf(sb, "\t<%s>%s</%s>\n",
|
retval = sbuf_printf(sb, "\t<%s>%s</%s>\n",
|
||||||
opt->name, opt->value, opt->name);
|
opt->name, opt->value, opt->name);
|
||||||
|
@ -49,6 +49,7 @@ typedef enum {
|
|||||||
typedef int (*fe_init_t)(void);
|
typedef int (*fe_init_t)(void);
|
||||||
typedef void (*fe_shutdown_t)(void);
|
typedef void (*fe_shutdown_t)(void);
|
||||||
typedef void (*port_func_t)(void *onoff_arg);
|
typedef void (*port_func_t)(void *onoff_arg);
|
||||||
|
typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb);
|
||||||
typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
|
typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
|
||||||
typedef uint32_t (*lun_map_func_t)(void *arg, uint32_t lun_id);
|
typedef uint32_t (*lun_map_func_t)(void *arg, uint32_t lun_id);
|
||||||
typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||||
@ -214,6 +215,7 @@ struct ctl_port {
|
|||||||
int virtual_port; /* passed to CTL */
|
int virtual_port; /* passed to CTL */
|
||||||
port_func_t port_online; /* passed to CTL */
|
port_func_t port_online; /* passed to CTL */
|
||||||
port_func_t port_offline; /* passed to CTL */
|
port_func_t port_offline; /* passed to CTL */
|
||||||
|
port_info_func_t port_info; /* passed to CTL */
|
||||||
void *onoff_arg; /* passed to CTL */
|
void *onoff_arg; /* passed to CTL */
|
||||||
lun_func_t lun_enable; /* passed to CTL */
|
lun_func_t lun_enable; /* passed to CTL */
|
||||||
lun_func_t lun_disable; /* passed to CTL */
|
lun_func_t lun_disable; /* passed to CTL */
|
||||||
|
@ -145,6 +145,7 @@ SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxcmdsn_delta, CTLFLAG_RWTUN,
|
|||||||
int cfiscsi_init(void);
|
int cfiscsi_init(void);
|
||||||
static void cfiscsi_online(void *arg);
|
static void cfiscsi_online(void *arg);
|
||||||
static void cfiscsi_offline(void *arg);
|
static void cfiscsi_offline(void *arg);
|
||||||
|
static int cfiscsi_info(void *arg, struct sbuf *sb);
|
||||||
static int cfiscsi_lun_enable(void *arg,
|
static int cfiscsi_lun_enable(void *arg,
|
||||||
struct ctl_id target_id, int lun_id);
|
struct ctl_id target_id, int lun_id);
|
||||||
static int cfiscsi_lun_disable(void *arg,
|
static int cfiscsi_lun_disable(void *arg,
|
||||||
@ -1411,6 +1412,17 @@ cfiscsi_offline(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cfiscsi_info(void *arg, struct sbuf *sb)
|
||||||
|
{
|
||||||
|
struct cfiscsi_target *ct = (struct cfiscsi_target *)arg;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
retval = sbuf_printf(sb, "\t<cfiscsi_state>%d</cfiscsi_state>\n",
|
||||||
|
ct->ct_state);
|
||||||
|
return (retval);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
|
cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
|
||||||
{
|
{
|
||||||
@ -1993,6 +2005,7 @@ cfiscsi_ioctl_port_create(struct ctl_req *req)
|
|||||||
port->virtual_port = strtoul(tag, NULL, 0);
|
port->virtual_port = strtoul(tag, NULL, 0);
|
||||||
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->onoff_arg = ct;
|
port->onoff_arg = ct;
|
||||||
port->lun_enable = cfiscsi_lun_enable;
|
port->lun_enable = cfiscsi_lun_enable;
|
||||||
port->lun_disable = cfiscsi_lun_disable;
|
port->lun_disable = cfiscsi_lun_disable;
|
||||||
|
@ -120,6 +120,7 @@ struct cctl_lun {
|
|||||||
|
|
||||||
struct cctl_port {
|
struct cctl_port {
|
||||||
uint32_t port_id;
|
uint32_t port_id;
|
||||||
|
int cfiscsi_status;
|
||||||
char *cfiscsi_target;
|
char *cfiscsi_target;
|
||||||
uint16_t cfiscsi_portal_group_tag;
|
uint16_t cfiscsi_portal_group_tag;
|
||||||
STAILQ_HEAD(,cctl_lun_nv) attr_list;
|
STAILQ_HEAD(,cctl_lun_nv) attr_list;
|
||||||
@ -332,6 +333,8 @@ cctl_end_pelement(void *user_data, const char *name)
|
|||||||
if (strcmp(name, "cfiscsi_target") == 0) {
|
if (strcmp(name, "cfiscsi_target") == 0) {
|
||||||
cur_port->cfiscsi_target = str;
|
cur_port->cfiscsi_target = str;
|
||||||
str = NULL;
|
str = NULL;
|
||||||
|
} else if (strcmp(name, "cfiscsi_status") == 0) {
|
||||||
|
cur_port->cfiscsi_status = strtoul(str, NULL, 0);
|
||||||
} else if (strcmp(name, "cfiscsi_portal_group_tag") == 0) {
|
} else if (strcmp(name, "cfiscsi_portal_group_tag") == 0) {
|
||||||
cur_port->cfiscsi_portal_group_tag = strtoul(str, NULL, 0);
|
cur_port->cfiscsi_portal_group_tag = strtoul(str, NULL, 0);
|
||||||
} else if (strcmp(name, "targ_port") == 0) {
|
} else if (strcmp(name, "targ_port") == 0) {
|
||||||
@ -494,6 +497,11 @@ conf_new_from_kernel(void)
|
|||||||
"ignoring", (uintmax_t)port->port_id);
|
"ignoring", (uintmax_t)port->port_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (port->cfiscsi_status != 1) {
|
||||||
|
log_debugx("CTL port %ju is not active (%d); ignoring",
|
||||||
|
(uintmax_t)port->port_id, port->cfiscsi_status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
targ = target_find(conf, port->cfiscsi_target);
|
targ = target_find(conf, port->cfiscsi_target);
|
||||||
if (targ == NULL) {
|
if (targ == NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user