Download raw body.
object_qid over imsg
Add functions which transport object ID queues across the imsg layer. This will be needed for an upcoming got-read-pack commit coloring fix. ok? M lib/got_lib_privsep.h | 27+ 0- M lib/pack_create_privsep.c | 2+ 44- M lib/privsep.c | 124+ 0- 3 files changed, 153 insertions(+), 44 deletions(-) commit - ce6204164ae9cc9e4be847122484967b4c3c33c1 commit + 58cfb2ec1ed437bf474ca53c28a459adfa8e8c7c blob - a539f5cf968d5bec802bad6082fe43acfc4dc609 blob + 1252f28cd25e49bcc68c40a7a8b6ca916b188c66 --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -205,6 +205,10 @@ enum got_imsg_type { GOT_IMSG_OBJ_ID_LIST, GOT_IMSG_OBJ_ID_LIST_DONE, + /* Transfer a queue of object IDs. */ + GOT_IMSG_OBJ_ID_QUEUE, + GOT_IMSG_OBJ_ID_QUEUE_DONE, + /* Messages related to patch files. */ GOT_IMSG_PATCH_FILE, GOT_IMSG_PATCH_HUNK, @@ -573,6 +577,24 @@ struct got_imsg_object_idlist { sizeof(struct got_imsg_object_idlist)) / sizeof(struct got_object_id)) }; +/* + * Structure for GOT_IMSG_OBJ_QID_LIST data. + * Multiple such messages may be sent back-to-back, where each message + * contains a chunk of IDs. The entire list must be terminated with a + * GOT_IMSG_OBJ_QID_LIST_DONE message. + */ +struct got_imsg_object_id_queue { + size_t nids; + + /* + * Followed by nids * struct got_object_qid. + */ + +#define GOT_IMSG_OBJ_ID_QUEUE_MAX_NIDS \ + ((MAX_IMSGSIZE - IMSG_HEADER_SIZE - \ + sizeof(struct got_imsg_object_id_queue)) / sizeof(struct got_object_qid)) +}; + /* Structure for GOT_IMSG_COMMIT_TRAVERSAL_REQUEST */ struct got_imsg_commit_traversal_request { struct got_imsg_packed_object iobj; @@ -818,6 +840,11 @@ const struct got_error *got_privsep_send_object_idlist const struct got_error *got_privsep_recv_object_idlist(int *, struct got_object_id **, size_t *, struct imsgbuf *); +const struct got_error *got_privsep_send_object_id_queue(struct imsgbuf *ibuf, + struct got_object_id_queue *, size_t); +const struct got_error *got_privsep_recv_object_id_queue(int *, + struct got_object_id_queue *, size_t *, struct imsgbuf *); + const struct got_error *got_privsep_send_delta_reuse_req(struct imsgbuf *); const struct got_error *got_privsep_send_reused_deltas(struct imsgbuf *, struct got_imsg_reused_delta *, size_t); blob - 2a41e8fd7c124e45e9207604dc32308d4979cd05 blob + 8f72aa6c4993b257f992a9300fa14467f7402aa6 --- lib/pack_create_privsep.c +++ lib/pack_create_privsep.c @@ -96,38 +96,6 @@ send_idset(struct imsgbuf *ibuf, struct got_object_ids } static const struct got_error * -send_filtered_id_queue(struct imsgbuf *ibuf, struct got_object_id_queue *ids, - uintptr_t color) -{ - const struct got_error *err = NULL; - struct got_object_qid *qid; - struct got_object_id *filtered_ids[GOT_IMSG_OBJ_ID_LIST_MAX_NIDS]; - int nids = 0; - - STAILQ_FOREACH(qid, ids, entry) { - if (color != (intptr_t)qid->data) - continue; - - filtered_ids[nids++] = &qid->id; - if (nids >= GOT_IMSG_OBJ_ID_LIST_MAX_NIDS) { - err = got_privsep_send_object_idlist(ibuf, - filtered_ids, nids); - if (err) - return err; - nids = 0; - } - } - - if (nids > 0) { - err = got_privsep_send_object_idlist(ibuf, filtered_ids, nids); - if (err) - return err; - } - - return got_privsep_send_object_idlist_done(ibuf); -} - -static const struct got_error * recv_reused_delta(struct got_imsg_reused_delta *delta, struct got_object_idset *idset, struct got_pack_metavec *v) { @@ -326,21 +294,11 @@ paint_packed_commits(struct got_object_qid **qid0, if (err) return err; - err = send_filtered_id_queue(pack->privsep_child->ibuf, ids, - COLOR_KEEP); + err = got_privsep_send_object_id_queue(pack->privsep_child->ibuf, + ids, *nqueued); if (err) return err; - err = send_filtered_id_queue(pack->privsep_child->ibuf, ids, - COLOR_DROP); - if (err) - return err; - - err = send_filtered_id_queue(pack->privsep_child->ibuf, ids, - COLOR_SKIP); - if (err) - return err; - arg.ncolored = ncolored; arg.nqueued = nqueued; arg.nskip = nskip; blob - 460ebb155dc401a8750ca217414e546ddad73c5a blob + 5aaaa8e2b4a5026b7b0eaf69032bf1917b2f6d90 --- lib/privsep.c +++ lib/privsep.c @@ -3271,7 +3271,131 @@ got_privsep_recv_object_idlist(int *done, struct got_o return err; } +static const struct got_error * +send_qidlist(struct imsgbuf *ibuf, struct got_object_qid **qids, size_t nids) +{ + const struct got_error *err = NULL; + struct got_imsg_object_id_queue idqueue; + struct ibuf *wbuf; + size_t i; + + memset(&idqueue, 0, sizeof(idqueue)); + + if (nids > GOT_IMSG_OBJ_ID_QUEUE_MAX_NIDS) + return got_error(GOT_ERR_NO_SPACE); + + wbuf = imsg_create(ibuf, GOT_IMSG_OBJ_ID_QUEUE, 0, 0, + sizeof(idqueue) + nids * sizeof(struct got_object_qid)); + if (wbuf == NULL) { + err = got_error_from_errno("imsg_create OBJ_ID_QUEUE"); + return err; + } + + idqueue.nids = nids; + if (imsg_add(wbuf, &idqueue, sizeof(idqueue)) == -1) + return got_error_from_errno("imsg_add OBJ_ID_QUEUE"); + + for (i = 0; i < nids; i++) { + struct got_object_qid *qid = qids[i]; + if (imsg_add(wbuf, qid, sizeof(*qid)) == -1) + return got_error_from_errno("imsg_add OBJ_ID_LIST"); + } + + imsg_close(ibuf, wbuf); + + return flush_imsg(ibuf); +} + const struct got_error * +got_privsep_send_object_id_queue(struct imsgbuf *ibuf, + struct got_object_id_queue *ids, size_t nids) +{ + const struct got_error *err = NULL; + struct got_object_qid *qid, *qidlist[GOT_IMSG_OBJ_ID_QUEUE_MAX_NIDS]; + int i, queued = 0; + + qid = STAILQ_FIRST(ids); + for (i = 0; qid && i < nids; i++) { + qidlist[i % nitems(qidlist)] = qid; + queued++; + if (queued >= nitems(qidlist)) { + err = send_qidlist(ibuf, qidlist, queued); + if (err) + return err; + queued = 0; + } + qid = STAILQ_NEXT(qid, entry); + } + + if (queued > 0) { + err = send_qidlist(ibuf, qidlist, queued); + if (err) + return err; + } + + if (imsg_compose(ibuf, GOT_IMSG_OBJ_ID_QUEUE_DONE, 0, 0, -1, NULL, 0) + == -1) + return got_error_from_errno("imsg_compose OBJ_ID_QUEUE_DONE"); + + return flush_imsg(ibuf); +} + +const struct got_error * +got_privsep_recv_object_id_queue(int *done, struct got_object_id_queue *ids, + size_t *nids, struct imsgbuf *ibuf) +{ + const struct got_error *err = NULL; + struct imsg imsg; + struct got_imsg_object_id_queue *qidlist; + struct got_object_qid *qid, *iqid; + size_t datalen; + + *done = 0; + *nids = 0; + + err = got_privsep_recv_imsg(&imsg, ibuf, 0); + if (err) + return err; + + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; + switch (imsg.hdr.type) { + case GOT_IMSG_OBJ_ID_QUEUE: + if (datalen < sizeof(*qidlist)) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + break; + } + qidlist = imsg.data; + if (qidlist->nids > GOT_IMSG_OBJ_ID_LIST_MAX_NIDS || + qidlist->nids * sizeof(struct got_object_qid) != + datalen - sizeof(*qidlist)) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + break; + } + iqid = (struct got_object_qid *)(imsg.data + sizeof(*qidlist)); + while (*nids < qidlist->nids) { + err = got_object_qid_alloc_partial(&qid); + if (err) + break; + memcpy(qid, iqid, sizeof(*qid)); + STAILQ_INSERT_TAIL(ids, qid, entry); + (*nids)++; + iqid++; + } + break; + case GOT_IMSG_OBJ_ID_QUEUE_DONE: + *done = 1; + break; + default: + err = got_error(GOT_ERR_PRIVSEP_MSG); + break; + } + + imsg_free(&imsg); + + return err; +} + +const struct got_error * got_privsep_send_delta_reuse_req(struct imsgbuf *ibuf) { if (imsg_compose(ibuf, GOT_IMSG_DELTA_REUSE_REQUEST, 0, 0, -1, NULL, 0)
object_qid over imsg