rust-lang / rust-lang/git2-rs

How to deal with signals when using git2-rs?

Open
#908 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
2.1k
Forks
450
Avg merge
11m
Merged PRs (30d)
1

Description

Warning: If you run the test program, it will pollute your $TMP dir. Beware!

I wrote a test program to explain my question.

https://github.com/srhb/git2-rs-debug-eintr/blob/main/src/main.rs
It can be run with a ssh git repo as its first argument and assumes a private key at ~/.ssh/id_rsa:

> cargo run -- sarah@localhost:testrepo

The program does two things continuously:

  1. continuously clones the repo to a fresh temporary directory
  2. runs true in a tight loop via async-process

This causes a problem with libssh2 (via git2-rs)

Copy/paste of explanatory comment from my test program:

With it (async-process), you'll get lots of errors a la:

```
error: Failed to retrieve list of SSH authentication methods: Error waiting on socket; class=Ssh (23); code=Auth (-16)
error: SSH could not read data: Error waiting on socket; class=Ssh (23)
error: Failed to open SSH channel: Error waiting on socket; class=Ssh (23)
```

(They key error here is: "Error waiting on socket")

I believe what's happening is this:

async-process (Command::new()) works internally by dealing with SIGCHLD etc.
for process reaping. In other words, _this_ process starts receiving a bunch
of SIGCHLD signals.

This causes the following `poll()` (or `select()`, depending on
implementation)

https://github.com/libssh2/libssh2/blob/master/src/session.c#L645

... to return with errno EINTR on each signal received:

https://github.com/libssh2/libssh2/blob/master/src/session.c#L678

... which is the error that ultimately surfaces in git2-rs.

The question then is: How does one even use git2-rs from within a process
that receives signals periodically? If we simply mask it out, whomever
depends on the signal gets broken. If not, we'll have to deal with the error
all the way up here, even though we should really have been able to simply
restart a simple poll on eg. a recv() on socket. Any help or thoughts
appreciated!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/main.rs in the linked git2-rs-debug-eintr reproducer and run cargo run -- sarah@localhost:testrepo; then trace the referenced libssh2 session.c poll/select paths and git2-rs error handling. A useful resolution would identify an agreed way for git2-rs callers to handle periodic signals without losing the underlying signal behavior, with the reproducer no longer surfacing the reported EINTR errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, rust
Domain
networking, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.