`git_remote_disconnect` leaves open file descriptors behind
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 86/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- c, git
- 领域
- backend, networking
调研方向
先在 src/libgit2/transports/http.c 中阅读 http_close 和 http_free,然后针对 git_remote_disconnect 运行 issue 中的 reproducer。确认 transport 会释放其 HTTP 客户端,并且 socket 文件描述符会在不需要 git_remote_free 的情况下关闭;如果有可用的相关 transport 测试,请添加或运行这些测试。
由索引模型根据 Issue 内容生成。
描述
As of 1.9.7, the program below shows that, after git_remote_disconnect, an open file descriptor (socket connected to the Git server) is left behind:
#include <git2.h>
#include <assert.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <sys/socket.h>
#include <assert.h>
#define REPO_URL "https://codeberg.org/shepherd/shepherd.git"
GIT_EXTERN(int) git_repository__cleanup(git_repository *repo);
static void
show_open_file_descriptors ()
{
DIR *dir;
struct dirent *ent;
dir = opendir ("/proc/self/fd");
chdir ("/proc/self/fd");
for (ent = NULL; ent = readdir (dir), ent != NULL; )
{
if (strcmp (ent->d_name, ".") == 0 || strcmp (ent->d_name, "..") == 0)
continue;
char target[1024];
ssize_t size;
size = readlink (ent->d_name, target, sizeof target);
target[size < 0 ? 0 : size] = '\0';
printf ("%s -> %s\n", ent->d_name, target);
}
closedir (dir);
}
int
main ()
{
int err;
err = git_libgit2_init ();
assert (err == 1);
git_clone_options opts;
err = git_clone_init_options (&opts, GIT_CLONE_OPTIONS_VERSION);
assert (err == 0);
git_repository *repo;
err = git_clone (&repo, REPO_URL, "/tmp/example", &opts);
assert (err == 0);
git_repository_free (repo);
show_open_file_descriptors ();
err = git_repository_open (&repo, "/tmp/example");
assert (err == 0);
git_remote *remote;
err = git_remote_lookup (&remote, repo, "origin");
assert (err == 0);
err = git_remote_fetch (remote, NULL, NULL, NULL);
assert (err == 0);
err = git_remote_disconnect (remote);
assert (err == 0);
/* git_remote_free (remote); */
/* assert (err == 0); */
/* git_repository__cleanup (repo); */
git_repository_free (repo);
printf ("%s:%i\n", __FILE__, __LINE__);
show_open_file_descriptors ();
return 0;
}
Uncomment the git_remote_free call and the socket gets closed.
My suggestion is to change git_remote_disconnect or rather its backend so that no file descriptor is left open once it's been called; the patch below does exactly that:
diff --git a/src/libgit2/transports/http.c b/src/libgit2/transports/http.c
index f344888d0..15fe8dfb6 100644
--- a/src/libgit2/transports/http.c
+++ b/src/libgit2/transports/http.c
@@ -729,6 +729,10 @@ static int http_close(git_smart_subtransport *t)
git_net_url_dispose(&transport->server.url);
git_net_url_dispose(&transport->proxy.url);
+ /* The call below closes associated file descriptors. */
+ git_http_client_free(transport->http_client);
+ transport->http_client = NULL;
+
return 0;
}
@@ -736,8 +740,6 @@ static void http_free(git_smart_subtransport *t)
{
http_subtransport *transport = GIT_CONTAINER_OF(t, http_subtransport, parent);
- git_http_client_free(transport->http_client);
-
http_close(t);
git__free(transport);
}
WDYT? I can make it a pull request if that sounds like the right approach.
(This was originally reported here.)
- 主要语言
- C
- 星标
- 10.6k
- 派生
- 2.7k
- PR 合并指标
- 30 天内没有已合并 PR
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
libgit2/libgit2 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 88/100
-
难度 2/5 1-3 小时 新手友好度 78/100
-
难度 2/5 1-3 小时 新手友好度 62/100
-
难度 2/5 1-3 小时 新手友好度 74/100
-
难度 4/5 3-5 天 新手友好度 68/100
相似的 Issue
-
难度 1/5 1 小时以内 新手友好度 92/100
libsdl-org/SDL#16372 ·
-
难度 2/5 1-3 小时 新手友好度 84/100
corazawaf/coraza-nginx#140 ·
-
难度 2/5 1-3 小时 新手友好度 75/100
BasedHardware/omi#15662 · 1 条评论 ·
-
难度 1/5 1-3 小时 新手友好度 88/100
jamesstringer90/appsandbox#160 ·
-
难度 2/5 1-3 小时 新手友好度 84/100