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