Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 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 Down Expand Up @@ -172,6 +173,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 +265,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