Skip to content

Commit

Permalink
Merge remote-tracking branch 'freebsd/master' into hardened/current/m…
Browse files Browse the repository at this point in the history
…aster
  • Loading branch information
opntr-auto committed Sep 23, 2015
2 parents bdd7a1d + 6711ffe commit fe313e7
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 23 deletions.
46 changes: 46 additions & 0 deletions sys/cam/ctl/ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,20 @@ ctl_isc_ha_link_up(struct ctl_softc *softc)
{
struct ctl_port *port;
struct ctl_lun *lun;
union ctl_ha_msg msg;
int i;

/* Announce this node parameters to peer for validation. */
msg.login.msg_type = CTL_MSG_LOGIN;
msg.login.version = CTL_HA_VERSION;
msg.login.ha_mode = softc->ha_mode;
msg.login.ha_id = softc->ha_id;
msg.login.max_luns = CTL_MAX_LUNS;
msg.login.max_ports = CTL_MAX_PORTS;
msg.login.max_init_per_port = CTL_MAX_INIT_PER_PORT;
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg.login, sizeof(msg.login),
M_WAITOK);

STAILQ_FOREACH(port, &softc->port_list, links) {
ctl_isc_announce_port(port);
for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) {
Expand Down Expand Up @@ -999,6 +1011,36 @@ ctl_isc_iid_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
port->wwpn_iid[iid].name = NULL;
}

static void
ctl_isc_login(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
{

if (msg->login.version != CTL_HA_VERSION) {
printf("CTL HA peers have different versions %d != %d\n",
msg->login.version, CTL_HA_VERSION);
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
return;
}
if (msg->login.ha_mode != softc->ha_mode) {
printf("CTL HA peers have different ha_mode %d != %d\n",
msg->login.ha_mode, softc->ha_mode);
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
return;
}
if (msg->login.ha_id == softc->ha_id) {
printf("CTL HA peers have same ha_id %d\n", msg->login.ha_id);
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
return;
}
if (msg->login.max_luns != CTL_MAX_LUNS ||
msg->login.max_ports != CTL_MAX_PORTS ||
msg->login.max_init_per_port != CTL_MAX_INIT_PER_PORT) {
printf("CTL HA peers have different limits\n");
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
return;
}
}

/*
* ISC (Inter Shelf Communication) event handler. Events from the HA
* subsystem come in here.
Expand Down Expand Up @@ -1275,9 +1317,13 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
case CTL_MSG_IID_SYNC:
ctl_isc_iid_sync(softc, msg, param);
break;
case CTL_MSG_LOGIN:
ctl_isc_login(softc, msg, param);
break;
default:
printf("Received HA message of unknown type %d\n",
msg->hdr.msg_type);
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
break;
}
if (msg != &msgbuf)
Expand Down
35 changes: 31 additions & 4 deletions sys/cam/ctl/ctl_ha.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,9 @@ ctl_ha_rx_thread(void *arg)
else
next = sizeof(wire_hdr);
SOCKBUF_LOCK(&so->so_rcv);
while (sbavail(&so->so_rcv) < next) {
if (softc->ha_connected == 0 || so->so_error ||
while (sbavail(&so->so_rcv) < next || softc->ha_disconnect) {
if (softc->ha_connected == 0 || softc->ha_disconnect ||
so->so_error ||
(so->so_rcv.sb_state & SBS_CANTRCVMORE)) {
goto errout;
}
Expand Down Expand Up @@ -541,6 +542,18 @@ ctl_ha_listen(struct ha_softc *softc)
printf("%s: REUSEADDR setting failed %d\n",
__func__, error);
}
bzero(&opt, sizeof(struct sockopt));
opt.sopt_dir = SOPT_SET;
opt.sopt_level = SOL_SOCKET;
opt.sopt_name = SO_REUSEPORT;
opt.sopt_val = &val;
opt.sopt_valsize = sizeof(val);
val = 1;
error = sosetopt(softc->ha_lso, &opt);
if (error) {
printf("%s: REUSEPORT setting failed %d\n",
__func__, error);
}
SOCKBUF_LOCK(&softc->ha_lso->so_rcv);
soupcall_set(softc->ha_lso, SO_RCV, ctl_ha_lupcall, softc);
SOCKBUF_UNLOCK(&softc->ha_lso->so_rcv);
Expand Down Expand Up @@ -572,7 +585,8 @@ ctl_ha_conn_thread(void *arg)
while (1) {
if (softc->ha_disconnect || softc->ha_shutdown) {
ctl_ha_close(softc);
ctl_ha_lclose(softc);
if (softc->ha_disconnect == 2 || softc->ha_shutdown)
ctl_ha_lclose(softc);
softc->ha_disconnect = 0;
if (softc->ha_shutdown)
break;
Expand Down Expand Up @@ -666,7 +680,7 @@ ctl_ha_peer_sysctl(SYSCTL_HANDLER_ARGS)
sa->sin_addr.s_addr =
htonl((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
}
softc->ha_disconnect = 1;
softc->ha_disconnect = 2;
softc->ha_wakeup = 1;
mtx_unlock(&softc->ha_lock);
wakeup(&softc->ha_wakeup);
Expand Down Expand Up @@ -811,6 +825,19 @@ ctl_ha_msg_send(ctl_ha_channel channel, const void *addr, size_t len,
return (ctl_ha_msg_send2(channel, addr, len, NULL, 0, wait));
}

ctl_ha_status
ctl_ha_msg_abort(ctl_ha_channel channel)
{
struct ha_softc *softc = &ha_softc;

mtx_lock(&softc->ha_lock);
softc->ha_disconnect = 1;
softc->ha_wakeup = 1;
mtx_unlock(&softc->ha_lock);
wakeup(&softc->ha_wakeup);
return (CTL_HA_STATUS_SUCCESS);
}

/*
* Allocate a data transfer request structure.
*/
Expand Down
1 change: 1 addition & 0 deletions sys/cam/ctl/ctl_ha.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ ctl_ha_status ctl_ha_msg_send(ctl_ha_channel channel, const void *addr,
size_t len, int wait);
ctl_ha_status ctl_ha_msg_send2(ctl_ha_channel channel, const void *addr,
size_t len, const void *addr2, size_t len2, int wait);
ctl_ha_status ctl_ha_msg_abort(ctl_ha_channel channel);
ctl_ha_status ctl_ha_msg_deregister(ctl_ha_channel channel);

struct ctl_ha_dt_req * ctl_dt_req_alloc(void);
Expand Down
24 changes: 21 additions & 3 deletions sys/cam/ctl/ctl_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ typedef enum {
CTL_MSG_PORT_SYNC, /* Information about port. */
CTL_MSG_LUN_SYNC, /* Information about LUN. */
CTL_MSG_IID_SYNC, /* Information about initiator. */
CTL_MSG_LOGIN, /* Information about HA peer. */
CTL_MSG_FAILOVER /* Fake, never sent though the wire */
} ctl_msg_type;

Expand Down Expand Up @@ -358,6 +359,25 @@ struct ctl_taskio {
uint8_t task_resp[3];/* Response information */
};


/*
* HA link messages.
*/
#define CTL_HA_VERSION 1

/*
* Used for CTL_MSG_LOGIN.
*/
struct ctl_ha_msg_login {
ctl_msg_type msg_type;
int version;
int ha_mode;
int ha_id;
int max_luns;
int max_ports;
int max_init_per_port;
};

typedef enum {
CTL_PR_REG_KEY,
CTL_PR_UNREG_KEY,
Expand Down Expand Up @@ -523,16 +543,14 @@ union ctl_ha_msg {
struct ctl_ha_msg_port port;
struct ctl_ha_msg_lun lun;
struct ctl_ha_msg_iid iid;
struct ctl_ha_msg_login login;
};


struct ctl_prio {
struct ctl_io_hdr io_hdr;
struct ctl_ha_msg_pr pr_msg;
};



union ctl_io {
struct ctl_io_hdr io_hdr; /* common to all I/O types */
struct ctl_scsiio scsiio; /* Normal SCSI commands */
Expand Down
24 changes: 8 additions & 16 deletions sys/kern/kern_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,28 +759,25 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
struct filedesc *fdp;
struct kqueue *kq;
struct file *fp;
struct proc *p;
struct ucred *cred;
int fd, error;

p = td->td_proc;
fdp = td->td_proc->p_fd;
cred = td->td_ucred;
crhold(cred);
if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES))) {
crfree(cred);
if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES)))
return (ENOMEM);
}

fdp = p->p_fd;
error = falloc_caps(td, &fp, &fd, flags, fcaps);
if (error)
goto done2;
if (error != 0) {
chgkqcnt(cred->cr_ruidinfo, -1, 0);
return (error);
}

/* An extra reference on `fp' has been held for us by falloc(). */
kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO);
kqueue_init(kq);
kq->kq_fdp = fdp;
kq->kq_cred = cred;
kq->kq_cred = crhold(cred);

FILEDESC_XLOCK(fdp);
TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
Expand All @@ -790,12 +787,7 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
fdrop(fp, td);

td->td_retval[0] = fd;
done2:
if (error != 0) {
chgkqcnt(cred->cr_ruidinfo, -1, 0);
crfree(cred);
}
return (error);
return (0);
}

#ifndef _SYS_SYSPROTO_H_
Expand Down

0 comments on commit fe313e7

Please sign in to comment.