fix(tty): implement TIOCGPTPEER and correct devpts slave lifecycle#1982
Conversation
TIOCGPTPEER must open the peer inode cached on the master rather than re-resolving /dev/pts/N after unlink. Track multiple slave fds with a counter and add fd-table reservation so ioctl can install the new fd atomically. Add dunitest coverage for lock, unlink, and index reuse. Signed-off-by: longjin <longjin@dragonos.org> Co-authored-by: Cursor <cursoragent@cursor.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d74674ca1d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: longjin <longjin@dragonos.org>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 77ce34edc7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: longjin <longjin@dragonos.org>
Signed-off-by: longjin <longjin@dragonos.org>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fcbaf1ca81
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: longjin <longjin@dragonos.org>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 95478ac711
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: longjin <longjin@dragonos.org>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45be36149f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: longjin <longjin@dragonos.org>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd9551cf67
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let drain_len = done.min(self.outbuf.len()); | ||
| if drain_len != 0 { | ||
| self.outbuf.drain(0..drain_len); |
There was a problem hiding this comment.
在 virtio-console 的发送队列完成时,complete_tx() 返回的是 used ring 的 len,而 TX 描述符只有 device-readable buffer,常见设备会把这个长度报告为 0;这里用 done 去 drain 会导致已经发送的字节一直留在 outbuf 中。结果是在 /dev/hvc0 有输出完成中断后,同一前缀会被反复重新提交,write_room() 也会逐步被已发送数据占满,最终阻塞/返回 EAGAIN;应按当初提交的 tx_len 清理缓冲,而不是按 used len。
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I re-checked the current branch, and this issue does not appear to exist in the current implementation.
complete_tx() uses pop_used() only to confirm and reclaim the matching TX descriptor. The current code does not propagate the virtqueue used-ring len to the upper layer. Instead, it saves the originally submitted tx_len, calls pop_used(token, &[tx_buf], &mut [])?, clears the pending TX state, and returns Ok(Some(tx_len)). Therefore, the done value used by flush_output_locked() for outbuf.drain(0..drain_len) is the originally submitted length, not the device-reported used length.
This also matches the Linux virtio-console model: on TX completion, virtqueue_get_buf(out_vq, &len) is used to reclaim the submitted buffer, while output progress is tied to the submitted buffer lifecycle rather than treating the used length as the number of transmitted bytes. So even if a device reports 0 for a device-readable TX buffer, the current DragonOS code will not repeatedly resubmit the same prefix or fill write_room() for that reason.
Summary
TIOCGPTPEERso a PTY master fd can open its slave peer through the cached slave inode on the master, instead of resolving/dev/pts/Nagain after the devpts entry may have been unlinked.TIOCGPTPEERslave fds exist.O_PATHopen file description semantics in VFS:O_PATHno longer triggers inode open/flush/close paths and no longer replaces FIFO path fds with the internal pipe inode.TIOCGPTPEER(O_PATH | ...)creates only a path fd, does not become a real PTY slave open, and does not keep the devpts index reserved after master close.fcntldup handling accordingly.EPOLLOUTwaiting to avoid lost wakeups.TCIFLUSH/TCOFLUSH/TCIOFLUSHwith Linux-compatible input/output responsibilities.TIOCGPTPEER, unlinked devpts access, multiple slave fd index retention/reuse,O_PATHpeer behavior, FIFOO_PATHidentity, PTY hangup behavior, large PTY backlog draining, canonical reads, and OPOST/flush edge cases.Test plan
make fmtmake fmt -C kernelmake kernelmake -C user/apps/tests/dunitest build-suitesmake -C user/apps/tests/dunitest bin/normal/tty_pty_hangup_testuser/apps/tests/dunitest/bin/normal/tty_pty_hangup_test --gtest_filter='TtyPtyHangup.TiocgptpeerOPath*:TtyPtyHangup.OPathFifoKeepsPathInodeAndDoesNotBlock:TtyPtyHangup.MultipleTiocgptpeerSlaveFdsKeepIndexReserved'user/apps/tests/dunitest/bin/normal/tty_pty_hangup_test --gtest_filter='TtyPtyHangup.LargeOpostSlaveWriteDrainsAndPreservesOnlcr:TtyPtyHangup.LargeRawSlaveWriteDrainsWithSmallMasterReads:TtyPtyHangup.LargeCanonicalMasterWriteDrainsWithSmallSlaveReads:TtyPtyHangup.TciflushDoesNotDiscardLargeOpostSlaveOutput'/opt/tests/dunitest/bin/normal/tty_pty_hangup_test, 28/28 passedfailed to close file/slave file close without active openNote:
make test-dunitpreviously failed before entering QEMU while writing the disk image, with an existingcp: cannot stat ... Bad messageissue for gVisor test files. The kernel and updated dunitest binary were then validated in a DragonOS QEMU guest withmake qemu-nographic.Made with Cursor