Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mjcheetham committed Apr 22, 2024
1 parent 64d1f76 commit 7753850
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 4 deletions.
52 changes: 52 additions & 0 deletions builtin/odb--daemon.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "config.h"
#include "object-file.h"
#include "object-store.h"
#include "oidmap.h"
#include "parse-options.h"
Expand All @@ -8,6 +9,7 @@
#include "thread-utils.h"
#include "odb-over-ipc.h"
#include "trace2.h"
#include "hex.h"

enum my_mode {
MODE_UNDEFINED = 0,
Expand Down Expand Up @@ -172,6 +174,44 @@ static int odb_ipc_cb__get_oid(struct my_odb_ipc_state *state,
return 0;
}

static int odb_ipc_cb__hash_object(struct my_odb_ipc_state *state,
const char *command, size_t command_len,
ipc_server_reply_cb *reply_cb,
struct ipc_server_reply_data *reply_data)
{
struct odb_over_ipc__hash_object__request *req;
struct odb_over_ipc__hash_object__response *resp;
const char *content;
size_t content_len;

if (command_len < sizeof(*req))
BUG("incorrect size for binary data");

req = (struct odb_over_ipc__hash_object__request *)command;

content = command + sizeof(*req);
content_len = command_len - sizeof(*req);

resp = xmalloc(sizeof(*resp));
memcpy(&resp->key.key, "hash-object", 11);

if (index_mem(the_repository->index, &resp->oid, (void *)content,
content_len, req->type, NULL, req->flags) < 0)
goto fail;

reply_cb(reply_data, (const char *)resp, sizeof(*resp));

return 0;

fail:
/*
* Send the client an error response to force it to do
* the work itself.
*/
reply_cb(reply_data, "error", 6);
return 0;
}

/*
* This callback handles IPC requests from clients. We run on an
* arbitrary thread.
Expand Down Expand Up @@ -226,6 +266,18 @@ static int odb_ipc_cb(void *data,
return ret;
}

if (!strcmp(command, "hash-object")) {
/*
* A client has requested that we hash an object and optionally
* store it in the ODB.
*/
trace2_region_enter("odb-daemon", "hash-object", NULL);
ret = odb_ipc_cb__hash_object(state, command, command_len,
reply_cb, reply_data);
trace2_region_leave("odb-daemon", "hash-object", NULL);
return 0;
}

// TODO respond to other requests from client.
//
// TODO decide how to return an error for unknown commands.
Expand Down
12 changes: 8 additions & 4 deletions object-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2490,10 +2490,10 @@ static int hash_format_check_report(struct fsck_options *opts UNUSED,
return 1;
}

static int index_mem(struct index_state *istate,
struct object_id *oid, void *buf, size_t size,
enum object_type type,
const char *path, unsigned flags)
int index_mem(struct index_state *istate,
struct object_id *oid, void *buf, size_t size,
enum object_type type,
const char *path, unsigned flags)
{
int ret = 0;
int re_allocated = 0;
Expand Down Expand Up @@ -2631,6 +2631,10 @@ int index_fd(struct index_state *istate, struct object_id *oid,
enum object_type type, const char *path, unsigned flags)
{
int ret;
if (!odb_over_ipc__hash_object(the_repository, oid, fd, type, flags)) {
close(fd);
return 0;
}

/*
* Call xsize_t() only when needed to avoid potentially unnecessary
Expand Down
1 change: 1 addition & 0 deletions object-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern int fetch_if_missing;
#define HASH_SILENT 8
int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags);
int index_mem(struct index_state *istate, struct object_id *oid, void *buf, size_t size, enum object_type type, const char *path, unsigned flags);

/*
* Create the directory containing the named path, using care to be
Expand Down
58 changes: 58 additions & 0 deletions odb-over-ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,62 @@ int odb_over_ipc__get_oid(struct repository *r, const struct object_id *oid,
return ret;
}

int odb_over_ipc__hash_object(struct repository *r, struct object_id *oid,
int fd, enum object_type type, unsigned flags)
{
struct odb_over_ipc__hash_object__request req;
struct odb_over_ipc__hash_object__response *resp;

struct strbuf answer = STRBUF_INIT;
struct strbuf content = STRBUF_INIT;
struct strbuf msg = STRBUF_INIT;
int ret;

if (is_daemon)
return -1;

if (!core_use_odb_over_ipc)
return -1;

if (r != the_repository) // TODO not dealing with this
return -1;

/*
* Read the content from the file descriptor in to the buffer and then
* send the request over IPC.
*/
if (strbuf_read(&content, fd, LARGE_PACKET_MAX) < 0)
return error_errno("could not read object content");

memset(&req, 0, sizeof(req));
memcpy(req.key.key, "hash-object", 11);
req.type = type;
req.flags = flags;
req.content_size = content.len;

/* Append the content at the end of the request */
strbuf_init(&msg, sizeof(req) + content.len);
strbuf_add(&msg, &req, sizeof(req));
strbuf_addbuf(&msg, &content);

ret = odb_over_ipc__command((const char *)msg.buf, msg.len, &answer);
if (ret)
return ret;

if (!strncmp(answer.buf, "error", 5)) {
trace2_printf("odb-over-ipc: failed");
return -1;
}

if (answer.len < sizeof(*resp))
BUG("incorrect size for binary data");
resp = (struct odb_over_ipc__hash_object__response *)answer.buf;

oidcpy(oid, &resp->oid);

strbuf_release(&content);
strbuf_release(&answer);
return ret;
}

#endif /* SUPPORTS_SIMPLE_IPC */
18 changes: 18 additions & 0 deletions odb-over-ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ struct odb_over_ipc__get_oid__response
enum object_type type;
};

struct odb_over_ipc__hash_object__request
{
struct odb_over_ipc__key key;
enum object_type type;
unsigned flags;
size_t content_size;
};

struct odb_over_ipc__hash_object__response
{
struct odb_over_ipc__key key;
struct object_id oid;
};

/*
* Connect to an existing `git odb--daemon` process and ask it for
* an object. This is intended to be inserted into the client
Expand All @@ -82,6 +96,10 @@ struct repository;
int odb_over_ipc__get_oid(struct repository *r, const struct object_id *oid,
struct object_info *oi, unsigned flags);


int odb_over_ipc__hash_object(struct repository *r, struct object_id *oid,
int fd, enum object_type type, unsigned flags);

/*
* Explicitly shutdown IPC connection to the `git odb--daemon` process.
* The connection is implicitly created upon the first request and we
Expand Down

0 comments on commit 7753850

Please sign in to comment.