-/* $OpenBSD: control.c,v 1.7 2014/04/20 18:17:12 claudio Exp $ */
+/* $OpenBSD: control.c,v 1.8 2014/04/21 17:41:52 claudio Exp $ */
/*
* Copyright (c) 2010 Claudio Jeker <claudio@openbsd.org>
return -1;
}
- if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ if ((fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) == -1) {
log_warn("control_init: socket");
return -1;
}
}
if (event & EV_WRITE) {
if ((pdu = TAILQ_FIRST(&c->channel)) != NULL) {
- TAILQ_REMOVE(&c->channel, pdu, entry);
-
for (niov = 0; niov < PDU_MAXIOV; niov++) {
iov[niov].iov_base = pdu->iov[niov].iov_base;
iov[niov].iov_len = pdu->iov[niov].iov_len;
bzero(&msg, sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = niov;
- if (sendmsg(fd, &msg, 0) == -1 &&
- !(errno == EAGAIN || errno == ENOBUFS)) {
+ if (sendmsg(fd, &msg, 0) == -1) {
+ if (errno == EAGAIN || errno == ENOBUFS)
+ goto requeue;
control_close(c);
return;
}
+ TAILQ_REMOVE(&c->channel, pdu, entry);
}
}
+requeue:
if (!TAILQ_EMPTY(&c->channel))
flags |= EV_WRITE;
return p;
}
-int
+void
control_queue(void *ch, struct pdu *pdu)
{
struct control *c = ch;
event_del(&c->ev);
event_set(&c->ev, c->fd, EV_READ|EV_WRITE, control_dispatch, c);
event_add(&c->ev, NULL);
-
- return 0;
-}
-
-int
-control_compose(void *ch, u_int16_t type, void *buf, size_t len)
-{
- struct pdu *pdu;
- struct ctrlmsghdr *cmh;
- void *ptr;
-
- if (PDU_LEN(len) > CONTROL_READ_SIZE - PDU_LEN(sizeof(*cmh)))
- return -1;
- if ((pdu = pdu_new()) == NULL)
- return -1;
- if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL)
- goto fail;
- bzero(cmh, sizeof(*cmh));
- cmh->type = type;
- cmh->len[0] = len;
- pdu_addbuf(pdu, cmh, sizeof(*cmh), 0);
- if (len > 0) {
- if ((ptr = pdu_alloc(len)) == NULL)
- goto fail;
- memcpy(ptr, buf, len);
- pdu_addbuf(pdu, ptr, len, 1);
- }
-
- return control_queue(ch, pdu);
-fail:
- pdu_free(pdu);
- return -1;
}
-/* $OpenBSD: iscsid.h,v 1.12 2014/04/21 09:48:31 claudio Exp $ */
+/* $OpenBSD: iscsid.h,v 1.13 2014/04/21 17:41:52 claudio Exp $ */
/*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
u_int16_t len[3];
};
+struct ctrldata {
+ void *buf;
+ size_t len;
+};
+
+#define CTRLARGV(x...) ((struct ctrldata []){ x })
+
/* Control message types */
#define CTRL_SUCCESS 1
#define CTRL_FAILURE 2
int control_init(char *);
void control_cleanup(char *);
void control_event_init(void);
-int control_queue(void *, struct pdu *);
+void control_queue(void *, struct pdu *);
int control_compose(void *, u_int16_t, void *, size_t);
+int control_build(void *, u_int16_t, int, struct ctrldata *);
struct session *session_find(struct initiator *, char *);
struct session *session_new(struct initiator *, u_int8_t);
-/* $OpenBSD: util.c,v 1.3 2014/04/19 18:31:33 claudio Exp $ */
+/* $OpenBSD: util.c,v 1.4 2014/04/21 17:41:52 claudio Exp $ */
/*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
+#include <sys/param.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/uio.h>
snprintf(buf, sizeof(buf), "[%s]:%s", host, port);
return buf;
}
+
+int
+control_compose(void *ch, u_int16_t type, void *buf, size_t len)
+{
+ return control_build(ch, type, 1, CTRLARGV({ buf, len }));
+}
+
+int
+control_build(void *ch, u_int16_t type, int argc, struct ctrldata *argv)
+{
+ struct pdu *pdu;
+ struct ctrlmsghdr *cmh;
+ size_t size = 0;
+ int i;
+
+ if (argc > (int)nitems(cmh->len))
+ return -1;
+
+ for (i = 0; i < argc; i++)
+ size += argv[i].len;
+ if (PDU_LEN(size) > CONTROL_READ_SIZE - PDU_LEN(sizeof(*cmh)))
+ return -1;
+
+ if ((pdu = pdu_new()) == NULL)
+ return -1;
+ if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL)
+ goto fail;
+ bzero(cmh, sizeof(*cmh));
+ cmh->type = type;
+ pdu_addbuf(pdu, cmh, sizeof(*cmh), 0);
+
+ for (i = 0; i < argc; i++)
+ if (argv[i].len > 0) {
+ void *ptr;
+
+ cmh->len[i] = argv[i].len;
+ if ((ptr = pdu_alloc(argv[i].len)) == NULL)
+ goto fail;
+ memcpy(ptr, argv[i].buf, argv[i].len);
+ pdu_addbuf(pdu, ptr, argv[i].len, i + 1);
+ }
+
+ control_queue(ch, pdu);
+ return 0;
+fail:
+ pdu_free(pdu);
+ return -1;
+}