commit 8c39831b06ec0976139042564390b6064cb9cb5e from: Stefan Sperling date: Tue Mar 12 09:59:22 2024 UTC fix message passing to notifier commit - 8285e71aecfd159643f1705f24709fc30a8cbda0 commit + 8c39831b06ec0976139042564390b6064cb9cb5e blob - 2e293cfda482ac271343e8604d92b018614777f7 blob + 28e61b6461c301e8d425680ae7af678007fc4ce8 --- gotd/repo_write.c +++ gotd/repo_write.c @@ -1788,11 +1788,16 @@ render_notification(struct imsg *imsg, struct gotd_ims { const struct got_error *err = NULL; struct gotd_imsg_notification_content ireq; - size_t datalen; + size_t datalen, len; char *refname; + struct ibuf *wbuf; + int fd; - if (imsg->fd == -1) + fd = imsg_get_fd(imsg); + if (fd == -1) { + log_debug("%s: no fd!", __func__); return got_error(GOT_ERR_PRIVSEP_NO_FD); + } datalen = imsg->hdr.len - IMSG_HEADER_SIZE; if (datalen < sizeof(ireq)) @@ -1809,20 +1814,44 @@ render_notification(struct imsg *imsg, struct gotd_ims switch (ireq.action) { case GOTD_NOTIF_ACTION_CREATED: - err = notify_created_ref(refname, ireq.new_id, iev, imsg->fd); + err = notify_created_ref(refname, ireq.new_id, iev, fd); break; case GOTD_NOTIF_ACTION_REMOVED: - err = notify_removed_ref(refname, ireq.old_id, iev, imsg->fd); + err = notify_removed_ref(refname, ireq.old_id, iev, fd); break; case GOTD_NOTIF_ACTION_CHANGED: err = notify_changed_ref(refname, ireq.old_id, ireq.new_id, - iev, imsg->fd); + iev, fd); break; } - /* TODO send GOTD_IMSG_NOTIFY */ + if (fsync(fd) == -1) { + err = got_error_from_errno("fsync"); + goto done; + } + len = sizeof(ireq) + ireq.refname_len; + wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFY, PROC_REPO_WRITE, + repo_write.pid, len); + if (wbuf == NULL) { + err = got_error_from_errno("imsg_create REF"); + goto done; + } + if (imsg_add(wbuf, &ireq, sizeof(ireq)) == -1) { + err = got_error_from_errno("imsg_add NOTIFY"); + goto done; + } + if (imsg_add(wbuf, refname, ireq.refname_len) == -1) { + err = got_error_from_errno("imsg_add NOTIFY"); + goto done; + } + + imsg_close(&iev->ibuf, wbuf); + gotd_imsg_event_add(iev); +done: free(refname); + if (close(fd) == -1 && err == NULL) + err = got_error_from_errno("close"); return err; } blob - 133e70534548d1d8d4987921c6de3a96618c9da2 blob + 44fc1ca64be81248433595c7649791a84625645a --- gotd/session.c +++ gotd/session.c @@ -496,18 +496,16 @@ static const struct got_error * forward_notification(struct gotd_session_client *client, struct imsg *imsg) { const struct got_error *err = NULL; - struct gotd_imsgev *iev = &client->repo_child_iev; + struct gotd_imsgev *iev = &gotd_session.notifier_iev; struct gotd_session_notif *notif, *tmp; struct gotd_imsg_notification_content icontent; char *refname = NULL; size_t datalen; struct gotd_imsg_notify inotify; char hostname[HOST_NAME_MAX + 1]; + int fd = -1; memset(&inotify, 0, sizeof(inotify)); - - if (imsg->fd == -1) - return got_error(GOT_ERR_PRIVSEP_NO_FD); datalen = imsg->hdr.len - IMSG_HEADER_SIZE; if (datalen < sizeof(icontent)) @@ -520,7 +518,7 @@ forward_notification(struct gotd_session_client *clien return got_error_from_errno("strndup"); STAILQ_FOREACH_SAFE(notif, ¬ifications, entry, tmp) { - if (notif->action != icontent.action || + if (notif->action != icontent.action || notif->fd == -1 || strcmp(notif->refname, refname) != 0) continue; if (notif->action == GOTD_NOTIF_ACTION_CREATED) { @@ -573,8 +571,13 @@ forward_notification(struct gotd_session_client *clien "%s: %s: UID %d %s %s", hostname, gotd_session.repo_cfg->name, client->euid, action, notif->refname); + fd = dup(notif->fd); + if (fd == -1) { + err = got_error_from_errno("dup"); + goto done; + } if (gotd_imsg_compose_event(iev, GOTD_IMSG_NOTIFY, - PROC_SESSION_WRITE, imsg->fd, &inotify, sizeof(inotify)) + PROC_SESSION_WRITE, fd, &inotify, sizeof(inotify)) == -1) { err = got_error_from_errno("imsg compose NOTIFY"); goto done; @@ -841,7 +844,7 @@ recv_notification_content(uint32_t *client_id, struct log_debug("notification content received"); datalen = imsg->hdr.len - IMSG_HEADER_SIZE; - if (datalen != sizeof(inotif)) + if (datalen < sizeof(inotif)) return got_error(GOT_ERR_PRIVSEP_LEN); memcpy(&inotif, imsg->data, sizeof(inotif)); @@ -920,6 +923,7 @@ session_dispatch_repo_child(int fd, short event, void err = recv_notification_content(&client_id, &imsg); if (err == NULL) do_notify = 1; + break; default: log_debug("unexpected imsg %d", imsg.hdr.type); break; @@ -1673,6 +1677,7 @@ recv_notifier(struct imsg *imsg) struct gotd_imsgev *iev = &gotd_session.notifier_iev; struct gotd_session_client *client = &gotd_session_client; size_t datalen; + int fd; if (client->state != GOTD_STATE_EXPECT_LIST_REFS) return got_error(GOT_ERR_PRIVSEP_MSG); @@ -1685,10 +1690,11 @@ recv_notifier(struct imsg *imsg) if (datalen != 0) return got_error(GOT_ERR_PRIVSEP_LEN); - if (imsg->fd == -1) + fd = imsg_get_fd(imsg); + if (fd == -1) return NULL; /* notifications unused */ - imsg_init(&iev->ibuf, imsg->fd); + imsg_init(&iev->ibuf, fd); iev->handler = session_dispatch_notifier; iev->events = EV_READ; iev->handler_arg = NULL;