static int scheduler_proc_release(int type, uint64_t holdq, int n) { struct ibuf *buf; int r; log_debug("debug: scheduler-proc: PROC_SCHEDULER_RELEASE"); buf = imsg_create(&ibuf, PROC_SCHEDULER_RELEASE, 0, 0, sizeof(holdq) + sizeof(n)); if (buf == NULL) return (-1); if (imsg_add(buf, &type, sizeof(type)) == -1) return (-1); if (imsg_add(buf, &holdq, sizeof(holdq)) == -1) return (-1); if (imsg_add(buf, &n, sizeof(n)) == -1) return (-1); imsg_close(&ibuf, buf); scheduler_proc_call(); scheduler_proc_read(&r, sizeof(r)); scheduler_proc_end(); return (r); }
static int scheduler_proc_batch(int typemask, struct scheduler_batch *ret) { struct ibuf *buf; uint64_t *evpids; log_debug("debug: scheduler-proc: PROC_SCHEDULER_BATCH"); buf = imsg_create(&ibuf, PROC_SCHEDULER_BATCH, 0, 0, sizeof(typemask) + sizeof(ret->evpcount)); if (buf == NULL) return (-1); if (imsg_add(buf, &typemask, sizeof(typemask)) == -1) return (-1); if (imsg_add(buf, &ret->evpcount, sizeof(ret->evpcount)) == -1) return (-1); imsg_close(&ibuf, buf); evpids = ret->evpids; scheduler_proc_call(); scheduler_proc_read(ret, sizeof(*ret)); scheduler_proc_read(evpids, sizeof(*evpids) * ret->evpcount); scheduler_proc_end(); ret->evpids = evpids; if (ret->type == SCHED_NONE) return (0); return (1); }
static size_t scheduler_proc_envelopes(uint64_t from, struct evpstate *dst, size_t size) { struct ibuf *buf; size_t s; log_debug("debug: scheduler-proc: PROC_SCHEDULER_ENVELOPES"); buf = imsg_create(&ibuf, PROC_SCHEDULER_ENVELOPES, 0, 0, sizeof(from) + sizeof(size)); if (buf == NULL) return (-1); if (imsg_add(buf, &from, sizeof(from)) == -1) return (-1); if (imsg_add(buf, &size, sizeof(size)) == -1) return (-1); imsg_close(&ibuf, buf); scheduler_proc_call(); s = rlen / sizeof(*dst); scheduler_proc_read(dst, s * sizeof(*dst)); scheduler_proc_end(); return (s); }
static int imsg_add_params(struct ibuf *buf, struct dict *params) { size_t count; const char *key; char *value; void *iter; count = 0; if (params) count = dict_count(params); if (imsg_add(buf, &count, sizeof(count)) == -1) return (-1); if (count == 0) return (0); iter = NULL; while (dict_iter(params, &iter, &key, (void **)&value)) { if (imsg_add(buf, key, strlen(key) + 1) == -1) return (-1); if (imsg_add(buf, value, strlen(value) + 1) == -1) return (-1); } return (0); }
static int scheduler_proc_hold(uint64_t evpid, uint64_t holdq) { struct ibuf *buf; int r; log_debug("debug: scheduler-proc: PROC_SCHEDULER_HOLD"); buf = imsg_create(&ibuf, PROC_SCHEDULER_HOLD, 0, 0, sizeof(evpid) + sizeof(holdq)); if (buf == NULL) return (-1); if (imsg_add(buf, &evpid, sizeof(evpid)) == -1) return (-1); if (imsg_add(buf, &holdq, sizeof(holdq)) == -1) return (-1); imsg_close(&ibuf, buf); scheduler_proc_call(); scheduler_proc_read(&r, sizeof(r)); scheduler_proc_end(); return (r); }
static int table_proc_fetch(void *arg, enum table_service s, union lookup *lk) { struct table_proc_priv *priv = arg; struct ibuf *buf; int r; buf = imsg_create(&priv->ibuf, PROC_TABLE_FETCH, 0, 0, sizeof(s)); if (buf == NULL) return (-1); if (imsg_add(buf, &s, sizeof(s)) == -1) return (-1); imsg_close(&priv->ibuf, buf); table_proc_call(priv); table_proc_read(&r, sizeof(r)); if (r == 1) { if (rlen == 0) { log_warnx("warn: table-proc: empty response"); fatalx("table-proc: exiting"); } if (rdata[rlen - 1] != '\0') { log_warnx("warn: table-proc: not NUL-terminated"); fatalx("table-proc: exiting"); } r = table_parse_lookup(s, NULL, rdata, lk); table_proc_read(NULL, rlen); } table_proc_end(); return (r); }
struct buf * imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, pid_t pid, u_int16_t datalen) { struct buf *wbuf; struct imsg_hdr hdr; if (datalen > MAX_IMSGSIZE - IMSG_HEADER_SIZE) { log_warnx("imsg_create: len %u > MAX_IMSGSIZE; " "type %u peerid %lu", datalen + IMSG_HEADER_SIZE, type, peerid); return (NULL); } hdr.len = datalen + IMSG_HEADER_SIZE; hdr.type = type; hdr.peerid = peerid; hdr.pid = pid; if ((wbuf = buf_open(hdr.len)) == NULL) { log_warn("imsg_create: buf_open"); return (NULL); } if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) return (NULL); return (wbuf); }
/* ARGSUSED */ struct ibuf * imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, pid_t pid, u_int16_t datalen) { struct ibuf *wbuf; struct imsg_hdr hdr; datalen += IMSG_HEADER_SIZE; if (datalen > MAX_IMSGSIZE) { errno = ERANGE; return (NULL); } hdr.type = type; hdr.flags = 0; hdr.peerid = peerid; if ((hdr.pid = pid) == 0) hdr.pid = ibuf->pid; if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { return (NULL); } if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) return (NULL); return (wbuf); }
static int queue_proc_envelope_update(uint64_t evpid, const char *buf, size_t len) { struct ibuf *b; int r; b = imsg_create(&ibuf, PROC_QUEUE_ENVELOPE_UPDATE, 0, 0, len + sizeof(evpid)); if (imsg_add(b, &evpid, sizeof(evpid)) == -1 || imsg_add(b, buf, len) == -1) return (0); imsg_close(&ibuf, b); queue_proc_call(); queue_proc_read(&r, sizeof(r)); queue_proc_end(); return (r); }
static int table_proc_lookup(void *arg, struct dict *params, const char *k, enum table_service s, union lookup *lk) { struct table_proc_priv *priv = arg; struct ibuf *buf; int r; buf = imsg_create(&priv->ibuf, lk ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0, sizeof(s) + strlen(k) + 1); if (buf == NULL) return (-1); if (imsg_add(buf, &s, sizeof(s)) == -1) return (-1); if (imsg_add_params(buf, params) == -1) return (-1); if (imsg_add(buf, k, strlen(k) + 1) == -1) return (-1); imsg_close(&priv->ibuf, buf); table_proc_call(priv); table_proc_read(&r, sizeof(r)); if (r == 1 && lk) { if (rlen == 0) { log_warnx("warn: table-proc: empty response"); fatalx("table-proc: exiting"); } if (rdata[rlen - 1] != '\0') { log_warnx("warn: table-proc: not NUL-terminated"); fatalx("table-proc: exiting"); } r = table_parse_lookup(s, k, rdata, lk); table_proc_read(NULL, rlen); } table_proc_end(); return (r); }
static void scheduler_msg_add(const void *data, size_t len) { if (buf == NULL) buf = imsg_create(&ibuf, PROC_SCHEDULER_OK, 0, 0, 1024); if (buf == NULL) { log_warnx("warn: table-api: imsg_create failed"); fatalx("table-api: exiting"); } if (imsg_add(buf, data, len) == -1) { log_warnx("warn: table-api: imsg_add failed"); fatalx("table-api: exiting"); } }
static void queue_msg_add(const void *data, size_t len) { if (buf == NULL) buf = imsg_create(&ibuf, PROC_QUEUE_OK, 0, 0, 1024); if (buf == NULL) { log_warnx("warn: queue-api: imsg_create failed"); fatalx("queue-api: exiting"); } if (imsg_add(buf, data, len) == -1) { log_warnx("warn: queue-api: imsg_add failed"); fatalx("queue-api: exiting"); } }
static int queue_proc_envelope_create(uint32_t msgid, const char *buf, size_t len, uint64_t *evpid) { struct ibuf *b; int r; msgid = evpid_to_msgid(*evpid); b = imsg_create(&ibuf, PROC_QUEUE_ENVELOPE_CREATE, 0, 0, sizeof(msgid) + len); if (imsg_add(b, &msgid, sizeof(msgid)) == -1 || imsg_add(b, buf, len) == -1) return (0); imsg_close(&ibuf, b); queue_proc_call(); queue_proc_read(&r, sizeof(r)); if (r == 1) queue_proc_read(evpid, sizeof(*evpid)); queue_proc_end(); return (r); }
int imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, pid_t pid, int fd, const void *data, u_int16_t datalen) { struct ibuf *wbuf; if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) return (-1); if (imsg_add(wbuf, data, datalen) == -1) return (-1); wbuf->fd = fd; imsg_close(ibuf, wbuf); return (1); }
int imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, pid_t pid, void *data, u_int16_t datalen) { struct buf *wbuf; int n; if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) return (-1); if (imsg_add(wbuf, data, datalen) == -1) return (-1); if ((n = imsg_close(ibuf, wbuf)) < 0) return (-1); return (n); }
int imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, pid_t pid, int fd, const struct iovec *iov, int iovcnt) { struct ibuf *wbuf; int i, datalen = 0; for (i = 0; i < iovcnt; i++) datalen += iov[i].iov_len; if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) return (-1); for (i = 0; i < iovcnt; i++) if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) return (-1); wbuf->fd = fd; imsg_close(ibuf, wbuf); return (1); }
int dispatch_imsg(struct ntpd_conf *lconf) { struct imsg imsg; int n, cnt; double d; char *name; struct ntp_addr *h, *hn; struct ibuf *buf; if ((n = imsg_read(ibuf)) == -1) return (-1); if (n == 0) { /* connection closed */ log_warnx("dispatch_imsg in main: pipe closed"); return (-1); } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) return (-1); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_ADJTIME: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) fatalx("invalid IMSG_ADJTIME received"); memcpy(&d, imsg.data, sizeof(d)); n = ntpd_adjtime(d); imsg_compose(ibuf, IMSG_ADJTIME, 0, 0, -1, &n, sizeof(n)); break; case IMSG_ADJFREQ: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) fatalx("invalid IMSG_ADJFREQ received"); memcpy(&d, imsg.data, sizeof(d)); ntpd_adjfreq(d, 1); break; case IMSG_SETTIME: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) fatalx("invalid IMSG_SETTIME received"); if (!lconf->settime) break; log_init(lconf->debug); memcpy(&d, imsg.data, sizeof(d)); ntpd_settime(d); /* daemonize now */ if (!lconf->debug) if (daemon(1, 0)) fatal("daemon"); lconf->settime = 0; timeout = INFTIM; break; case IMSG_HOST_DNS: name = imsg.data; if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE) fatalx("invalid IMSG_HOST_DNS received"); imsg.hdr.len -= 1 + IMSG_HEADER_SIZE; if (name[imsg.hdr.len] != '\0' || strlen(name) != imsg.hdr.len) fatalx("invalid IMSG_HOST_DNS received"); if ((cnt = host_dns(name, &hn)) == -1) break; buf = imsg_create(ibuf, IMSG_HOST_DNS, imsg.hdr.peerid, 0, cnt * sizeof(struct sockaddr_storage)); if (buf == NULL) break; if (cnt > 0) for (h = hn; h != NULL; h = h->next) imsg_add(buf, &h->ss, sizeof(h->ss)); imsg_close(ibuf, buf); break; default: break; } imsg_free(&imsg); } return (0); }
void dns_dispatch_imsg(int fd, short events, void *p) { struct imsg imsg; int n, cnt; char *name; struct ypldap_addr_list hn = TAILQ_HEAD_INITIALIZER(hn); struct ypldap_addr *h; struct ibuf *buf; struct env *env = p; struct imsgev *iev = env->sc_iev; struct imsgbuf *ibuf = &iev->ibuf; int shut = 0; if ((events & (EV_READ | EV_WRITE)) == 0) fatalx("unknown event"); if (events & EV_READ) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) fatal("imsg_read error"); if (n == 0) shut = 1; } if (events & EV_WRITE) { if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) fatal("msgbuf_write"); if (n == 0) shut = 1; goto done; } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatal("client_dispatch_imsg: imsg_get error"); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_HOST_DNS: name = imsg.data; if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE) fatalx("invalid IMSG_HOST_DNS received"); imsg.hdr.len -= 1 + IMSG_HEADER_SIZE; if (name[imsg.hdr.len] != '\0' || strlen(name) != imsg.hdr.len) fatalx("invalid IMSG_HOST_DNS received"); if ((cnt = host_dns(name, &hn)) == -1) break; buf = imsg_create(ibuf, IMSG_HOST_DNS, imsg.hdr.peerid, 0, cnt * sizeof(struct sockaddr_storage)); if (buf == NULL) break; if (cnt > 0) { while(!TAILQ_EMPTY(&hn)) { h = TAILQ_FIRST(&hn); TAILQ_REMOVE(&hn, h, next); imsg_add(buf, &h->ss, sizeof(h->ss)); free(h); } } imsg_close(ibuf, buf); break; default: break; } imsg_free(&imsg); } done: if (!shut) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handler */ event_del(&iev->ev); event_loopexit(NULL); } }