Compare commits
6 commits
ac53850fd1
...
420fac5f18
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
420fac5f18 | ||
|
|
aed73e99be | ||
|
|
88be53cd2f | ||
|
|
bd3ec3a904 | ||
|
|
e016c37634 | ||
|
|
373e300b59 |
11 changed files with 102 additions and 83 deletions
10
.cargo/config.toml
Normal file
10
.cargo/config.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-FileCopyrightText: 2026 Qyriad <qyriad@qyriad.me>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.1
|
||||
# vim: tabstop=2 shiftwidth=0 noexpandtab
|
||||
|
||||
[build]
|
||||
rustflags = [
|
||||
"-C", "force-frame-pointers=yes",
|
||||
"-C", "force-unwind-tables=yes",
|
||||
]
|
||||
16
Cargo.toml
16
Cargo.toml
|
|
@ -47,3 +47,19 @@ tap = "1.0.1"
|
|||
tracing = { version = "0.1.44", features = ["attributes"] }
|
||||
tracing-human-layer = "0.2.1"
|
||||
tracing-subscriber = { version = "0.3.22", default-features = false, features = ["std", "env-filter", "fmt", "ansi", "registry", "parking_lot"] }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
lto = "thin"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
lto = true
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 1
|
||||
|
||||
[profile.release.package."*"]
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@
|
|||
in import src { inherit pkgs; },
|
||||
}: let
|
||||
inherit (qpkgs) lib;
|
||||
dynix = qpkgs.callPackage ./package.nix { }
|
||||
dynix = (qpkgs.callPackage ./package.nix { })
|
||||
.overrideAttrs (final: prev: {
|
||||
dynixCommand = qpkgs.stdlib.mkStdenvPretty prev.dynixCommand;
|
||||
dynixModules = qpkgs.stdlib.mkStdenvPretty prev.dynixModules;
|
||||
})
|
||||
|> qpkgs.stdlib.mkStdenvPretty;
|
||||
byStdenv = lib.mapAttrs (stdenvName: stdenv: let
|
||||
withStdenv = dynix.override { clangStdenv = stdenv; };
|
||||
|
|
|
|||
12
flake.lock
generated
12
flake.lock
generated
|
|
@ -3,11 +3,11 @@
|
|||
"fenix": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1773126504,
|
||||
"narHash": "sha256-/iXlg2V5UMlgCmyRHkPHjlD6NdMfFOnwFMvH7REigD4=",
|
||||
"lastModified": 1774163246,
|
||||
"narHash": "sha256-gzlqyLjP44LWraUd3Zn4xrQKOtK+zcBJ77pnsSUsxcM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "64407ddb1932af06ed5cd711f6a2ed946b2548b9",
|
||||
"rev": "4cd28929c68cae521589bc21958d3793904ed1e2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -37,11 +37,11 @@
|
|||
"nixpkgs": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1772956932,
|
||||
"narHash": "sha256-M0yS4AafhKxPPmOHGqIV0iKxgNO8bHDWdl1kOwGBwRY=",
|
||||
"lastModified": 1773840656,
|
||||
"narHash": "sha256-9tpvMGFteZnd3gRQZFlRCohVpqooygFuy9yjuyRL2C0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "608d0cadfed240589a7eea422407a547ad626a14",
|
||||
"rev": "9cf7092bdd603554bd8b63c216e8943cf9b12512",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
11
package.nix
11
package.nix
|
|
@ -7,14 +7,23 @@
|
|||
clangStdenv,
|
||||
callPackage,
|
||||
linkFarm,
|
||||
llvmPackages,
|
||||
rustHooks,
|
||||
rustPackages,
|
||||
versionCheckHook,
|
||||
wrapBintoolsWith,
|
||||
}: lib.callWith' rustPackages ({
|
||||
rustPlatform,
|
||||
cargo,
|
||||
}: let
|
||||
stdenv = clangStdenv;
|
||||
# Use LLD for faster link times.
|
||||
stdenv = clangStdenv.override {
|
||||
cc = clangStdenv.cc.override {
|
||||
bintools = wrapBintoolsWith {
|
||||
bintools = llvmPackages.bintools;
|
||||
};
|
||||
};
|
||||
};
|
||||
cargoToml = lib.importTOML ./Cargo.toml;
|
||||
cargoPackage = cargoToml.package;
|
||||
in stdenv.mkDerivation (finalAttrs: let
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
inherit (pkgs) lib;
|
||||
|
||||
mkDevShell = dynix: qpkgs.callPackage dynix.mkDevShell { inherit fenixToolchain; };
|
||||
devShell = mkDevShell dynix;
|
||||
devShell = mkDevShell dynix |> qpkgs.stdlib.mkStdenvPretty;
|
||||
|
||||
byStdenv = lib.mapAttrs (lib.const mkDevShell) dynix.byStdenv;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use std::{
|
||||
env, io, mem,
|
||||
env, io,
|
||||
ops::Deref,
|
||||
os::fd::{AsFd, BorrowedFd, IntoRawFd, OwnedFd, RawFd},
|
||||
sync::{
|
||||
|
|
@ -26,7 +26,7 @@ use crate::{
|
|||
|
||||
use crate::{OwnedFdWithFlags, TokenFd};
|
||||
|
||||
pub static UID: LazyLock<Uid> = LazyLock::new(|| rustix::process::getuid());
|
||||
pub static UID: LazyLock<Uid> = LazyLock::new(rustix::process::getuid);
|
||||
|
||||
pub static USER_SOCKET_DIR: LazyLock<&'static Path> = LazyLock::new(|| {
|
||||
let dir: Box<Path> = env::var_os("XDG_RUNTIME_DIR")
|
||||
|
|
@ -52,19 +52,23 @@ pub enum ConvenientAttrPath {
|
|||
}
|
||||
|
||||
impl ConvenientAttrPath {
|
||||
/// Not currently used, but here for completeness.
|
||||
#[expect(dead_code)]
|
||||
pub fn clone_from_dotted(s: &str) -> Self {
|
||||
Self::Dotted(Box::from(s))
|
||||
}
|
||||
|
||||
/// Not currently used, but here for completeness.
|
||||
#[expect(dead_code)]
|
||||
pub fn clone_from_split(s: &[&str]) -> Self {
|
||||
Self::from_str_iter(s.into_iter().map(Deref::deref))
|
||||
Self::from_str_iter(s.iter().map(Deref::deref))
|
||||
}
|
||||
|
||||
pub fn from_str_iter<'i, I>(iter: I) -> Self
|
||||
where
|
||||
I: Iterator<Item = &'i str>,
|
||||
{
|
||||
let boxed = iter.map(|s| Box::from(s));
|
||||
let boxed = iter.map(Box::from);
|
||||
Self::Split(Box::from_iter(boxed))
|
||||
}
|
||||
|
||||
|
|
@ -135,9 +139,6 @@ pub struct Daemon {
|
|||
|
||||
// Bijective mapping of [`mio::Token`]s to [`RawFd`]s.
|
||||
tokfd: BiHashMap<TokenFd>,
|
||||
|
||||
cmd_buffer: Vec<u8>,
|
||||
next_timeout: Option<Duration>,
|
||||
}
|
||||
|
||||
/// `tokfd` handling.
|
||||
|
|
@ -222,6 +223,8 @@ impl Daemon {
|
|||
.copied()
|
||||
}
|
||||
|
||||
/// Not currently used, but here for completeness.
|
||||
#[expect(dead_code)]
|
||||
fn token_for_fd(&self, fd: RawFd) -> Option<Token> {
|
||||
self.tokfd
|
||||
.get2(&fd)
|
||||
|
|
@ -255,10 +258,10 @@ impl Daemon {
|
|||
|
||||
debug!("opened daemon to {:?} file descriptor {fd:?}", name);
|
||||
|
||||
let path = match &name {
|
||||
Some(name) => Some(PathBuf::from(name).into_boxed_path()),
|
||||
None => None,
|
||||
};
|
||||
let path = name
|
||||
.as_ref()
|
||||
.map(PathBuf::from)
|
||||
.map(PathBuf::into_boxed_path);
|
||||
|
||||
Self {
|
||||
config_path,
|
||||
|
|
@ -267,8 +270,6 @@ impl Daemon {
|
|||
poller,
|
||||
fd_info,
|
||||
tokfd: Default::default(),
|
||||
cmd_buffer: Vec::with_capacity(1024),
|
||||
next_timeout: TIMEOUT_NEVER,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -345,16 +346,12 @@ impl Daemon {
|
|||
/// Private helpers.
|
||||
impl Daemon {
|
||||
fn read_cmd(&mut self, fd: &BorrowedFd) -> Result<(), IoError> {
|
||||
if self.cmd_buffer.len() == self.cmd_buffer.capacity() {
|
||||
self.cmd_buffer.reserve(1024);
|
||||
}
|
||||
// FIXME: don't use a new allocation every time.
|
||||
let mut cmd_buffer: Vec<u8> = Vec::with_capacity(1024);
|
||||
|
||||
let _count = rustix::io::read(fd, spare_capacity(&mut self.cmd_buffer))
|
||||
let _count = rustix::io::read(fd, spare_capacity(&mut cmd_buffer))
|
||||
.tap_err(|e| error!("read() on daemon fd {fd:?} failed: {e}"))?;
|
||||
|
||||
// So that the loop doesn't borrow from `self`.
|
||||
let mut cmd_buffer = mem::take(&mut self.cmd_buffer);
|
||||
|
||||
// The buffer might have existing data from the last read.
|
||||
let deserializer = serde_json::Deserializer::from_slice(&cmd_buffer);
|
||||
let stream: StreamDeserializer<_, DaemonCmd> = deserializer.into_iter();
|
||||
|
|
@ -362,16 +359,13 @@ impl Daemon {
|
|||
let cmd = match cmd {
|
||||
Ok(cmd) => cmd,
|
||||
Err(e) if e.is_eof() => {
|
||||
self.next_timeout = Some(Duration::from_secs(4));
|
||||
warn!("Didn't get a valid daemon command; giving the other side 4 seconds...");
|
||||
let _ = mem::replace(&mut self.cmd_buffer, cmd_buffer);
|
||||
warn!("Got EOF before a valid command");
|
||||
debug!("command buffer was: {:?}", cmd_buffer.as_bstr());
|
||||
return Ok(());
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("error deserializing command: {e}");
|
||||
debug!("command buffer was: {:?}", cmd_buffer.as_bstr());
|
||||
cmd_buffer.clear();
|
||||
let _ = mem::replace(&mut self.cmd_buffer, cmd_buffer);
|
||||
// Don't propagate the error unless we have too many.
|
||||
self.fd_error_push(fd.as_raw_fd(), e.into()).tap_err(|e| {
|
||||
error!("Accumulated too many errors for daemon fd {fd:?}: {e}")
|
||||
|
|
@ -385,9 +379,6 @@ impl Daemon {
|
|||
self.dispatch_cmd(cmd).unwrap_or_else(|e| todo!("{e}"));
|
||||
}
|
||||
|
||||
cmd_buffer.clear();
|
||||
let _ = mem::replace(&mut self.cmd_buffer, cmd_buffer);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -469,25 +460,19 @@ impl Daemon {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(timeout) = self.next_timeout {
|
||||
debug!(
|
||||
"epoll_wait() with a timeout: {}",
|
||||
humantime::format_duration(timeout),
|
||||
);
|
||||
}
|
||||
|
||||
match self.poller.poll(&mut events, self.next_timeout.take()) {
|
||||
match self.poller.poll(&mut events, TIMEOUT_NEVER) {
|
||||
Ok(_) => {
|
||||
trace!(
|
||||
"mio::Poller::poll() got events: {:?}",
|
||||
events.iter().size_hint().0,
|
||||
);
|
||||
if events.is_empty() {
|
||||
warn!("timeout expired");
|
||||
self.cmd_buffer.clear();
|
||||
} else {
|
||||
let _ = self.fd_error_pop(self.poller.as_raw_fd());
|
||||
unreachable!(
|
||||
"epoll_wait() with a \"forever\" timeout should never give empty events",
|
||||
);
|
||||
}
|
||||
|
||||
let _ = self.fd_error_pop(self.poller.as_raw_fd());
|
||||
},
|
||||
Err(e) if e.kind() == IoErrorKind::Interrupted => {
|
||||
// EINTR is silly.
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ impl From<OwnedFd> for OwnedFdWithFlags {
|
|||
|
||||
impl Read for &OwnedFdWithFlags {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
|
||||
debug_assert!(buf.len() > 0);
|
||||
debug_assert!(!buf.is_empty());
|
||||
loop {
|
||||
buf.fill(0);
|
||||
match rustix::io::read(self.as_ref_owned(), &mut *buf) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ impl FdInfo {
|
|||
|
||||
match Self::guess_name(self.fd) {
|
||||
Ok(name) => {
|
||||
let prev = self.name.set(Box::from(name));
|
||||
let prev = self.name.set(name);
|
||||
debug_assert_eq!(prev, Ok(()));
|
||||
},
|
||||
Err(e) => {
|
||||
|
|
@ -105,13 +105,14 @@ impl<'a> Display for FdInfoDisplay<'a> {
|
|||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
#[non_exhaustive]
|
||||
pub enum FdKind {
|
||||
File,
|
||||
Socket,
|
||||
SockStream,
|
||||
Poller,
|
||||
#[default]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
|
|
@ -128,12 +129,6 @@ impl FdKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for FdKind {
|
||||
fn default() -> FdKind {
|
||||
FdKind::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct TokenFd {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use tracing_subscriber::{EnvFilter, layer::SubscriberExt};
|
|||
|
||||
fn main_wrapped() -> Result<(), Box<dyn StdError + Send + Sync + 'static>> {
|
||||
// Default RUST_LOG to warn if it's not specified.
|
||||
if let None = env::var_os("RUST_LOG") {
|
||||
if env::var_os("RUST_LOG").is_none() {
|
||||
unsafe {
|
||||
env::set_var("RUST_LOG", "warn");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,27 +5,27 @@
|
|||
#[allow(unused_imports)]
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub(crate) struct NixEvalExpr<E, A> {
|
||||
pub(crate) expr: E,
|
||||
pub(crate) attrpath: A,
|
||||
}
|
||||
|
||||
impl<E, A> NixEvalExpr<E, A>
|
||||
where
|
||||
E: AsRef<OsStr>,
|
||||
A: AsRef<OsStr>,
|
||||
{
|
||||
pub(crate) fn into_command(self) -> Command {
|
||||
let mut cmd = Command::new("nix-instantiate");
|
||||
cmd.arg("--eval")
|
||||
.arg("--json")
|
||||
.arg("--strict")
|
||||
.arg("--expr")
|
||||
.arg(self.expr)
|
||||
.arg("-A")
|
||||
.arg(self.attrpath);
|
||||
|
||||
cmd
|
||||
}
|
||||
}
|
||||
//#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
//pub(crate) struct NixEvalExpr<E, A> {
|
||||
// pub(crate) expr: E,
|
||||
// pub(crate) attrpath: A,
|
||||
//}
|
||||
//
|
||||
//impl<E, A> NixEvalExpr<E, A>
|
||||
//where
|
||||
// E: AsRef<OsStr>,
|
||||
// A: AsRef<OsStr>,
|
||||
//{
|
||||
// pub(crate) fn into_command(self) -> Command {
|
||||
// let mut cmd = Command::new("nix-instantiate");
|
||||
// cmd.arg("--eval")
|
||||
// .arg("--json")
|
||||
// .arg("--strict")
|
||||
// .arg("--expr")
|
||||
// .arg(self.expr)
|
||||
// .arg("-A")
|
||||
// .arg(self.attrpath);
|
||||
//
|
||||
// cmd
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue