Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/ci #135

Merged
merged 5 commits into from
Nov 6, 2024
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
14 changes: 7 additions & 7 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ jobs:
name: Run nix flake check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v30
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v12
- uses: cachix/cachix-action@v15
with:
name: dlr-ft
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
Expand All @@ -34,15 +34,15 @@ jobs:
- treefmt --fail-on-change
- audit --deny warnings
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v30
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v12
- uses: cachix/cachix-action@v15
with:
name: dlr-ft
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
Expand Down
60 changes: 55 additions & 5 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ jobs:
DURATION: 10s
RUST_LOG: trace
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v30
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v12
- uses: cachix/cachix-action@v15
with:
name: dlr-ft
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
Expand All @@ -43,4 +43,54 @@ jobs:
- name: Check CGroup
run: systemd-run --user --scope cat /proc/self/cgroup
- name: Run example ${{ matrix.example }}
run: nix develop --command systemd-run-example-${{ matrix.example }} --duration $DURATION
shell: nix develop --command bash -e {0}
run: systemd-run-example-${{ matrix.example }} --duration "$DURATION" 2>&1 | tee ./output.log
- name: Verify output
run: |
assert_contain() {
local contain="$1"
local msg="$2"
if ! grep "$contain" ./output.log; then
printf "$msg\n"
return 1
fi
return 0
}

assert_not_contain() {
local contain="$1"
if grep "$contain" ./output.log; then
return 1
fi
return 0
}

assert_not_contain "ERROR"
assert_not_contain "panic"

if [ "${{ matrix.example }}" = "hello_part" ]; then
assert_not_contain "WARN"
assert_contain "Received via Sampling Port: CustomMessage" \
"no custom message received"
fi
if [ "${{ matrix.example }}" = "fuel_tank" ]; then
assert_not_contain "WARN"
fi
if [ "${{ matrix.example }}" = "ping" ]; then
assert_contain "received valid response" \
"no valid response received"
fi
if [ "${{ matrix.example }}" = "dev_random" ]; then
assert_not_contain "WARN"
assert_contain "got some randomness" \
"missing randomness log info"
fi
if [ "${{ matrix.example }}" = "ping_queue" ]; then
assert_contain "Received valid response" \
"no valid response received"
fi
if [ "${{ matrix.example }}" = "redirect_stdio" ]; then
assert_not_contain "WARN"
assert_contain "Terminating partition" \
"partition didn't terminate as expected"
fi
93 changes: 36 additions & 57 deletions core/src/cgroup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::io::BufRead;
use std::path::{Path, PathBuf};
use std::time::{Duration, Instant};

use anyhow::{bail, Context, Ok};
use anyhow::{bail, ensure, Context, Ok};
use itertools::Itertools;
use nix::sys::statfs;
use nix::unistd::Pid;
Expand All @@ -39,18 +39,18 @@ impl CGroup {
trace!("Create cgroup \"{name}\"");
// Double-checking if path is cgroup does not hurt, as it is
// better to not potentially create a directory at a random location.
if !is_cgroup(path.as_ref())? {
bail!("{} is not a valid cgroup", path.as_ref().display());
}
ensure!(
is_cgroup(path.as_ref())?,
"{} is not a valid cgroup",
path.as_ref().display()
);

let path = PathBuf::from(path.as_ref()).join(name);

if path.exists() {
bail!("CGroup {path:?} already exists");
} else {
// will fail if the path already exists
fs::create_dir(&path)?;
}
ensure!(!path.exists(), "CGroup {path:?} already exists");

// will fail if the path already exists
fs::create_dir(&path)?;

Self::import_root(&path)
}
Expand All @@ -60,11 +60,9 @@ impl CGroup {
trace!("Import cgroup {}", path.as_ref().display());
let path = PathBuf::from(path.as_ref());

if !is_cgroup(&path)? {
bail!("{} is not a valid cgroup", path.display());
}

Ok(CGroup { path })
let cgroup = CGroup { path };
cgroup.ensure_is_cgroup()?;
Ok(cgroup)
}

/// Creates a sub-cgroup inside this one
Expand All @@ -79,12 +77,19 @@ impl CGroup {
Ok(cgroup)
}

fn ensure_is_cgroup(&self) -> anyhow::Result<()> {
ensure!(
is_cgroup(&self.path)?,
"{} is not a valid cgroup",
self.path.display()
);
Ok(())
}

/// Moves a process to this cgroup
pub fn mv_proc(&self, pid: Pid) -> anyhow::Result<()> {
trace!("Move {pid:?} to {}", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

fs::write(self.path.join("cgroup.procs"), pid.to_string())?;
Ok(())
Expand All @@ -93,9 +98,7 @@ impl CGroup {
/// Moves a thread to this cgroup
pub fn mv_thread(&self, pid: Pid) -> anyhow::Result<()> {
trace!("Move {pid:?} to {}", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

fs::write(self.path.join("cgroup.threads"), pid.to_string())?;
Ok(())
Expand All @@ -104,19 +107,15 @@ impl CGroup {
/// Changes the cgroups type to "threaded"
fn set_threaded(&self) -> anyhow::Result<()> {
trace!("Change type of {} to threaded", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

fs::write(self.path.join("cgroup.type"), "threaded")?;
Ok(())
}

/// Returns all PIDs associated with this cgroup
pub fn get_pids(&self) -> anyhow::Result<Vec<Pid>> {
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

let pids: Vec<Pid> = fs::read(self.path.join("cgroup.procs"))?
.lines()
Expand All @@ -128,9 +127,7 @@ impl CGroup {

/// Returns all TIDs associated with this cgroup
pub fn get_tids(&self) -> anyhow::Result<Vec<Pid>> {
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

let pids: Vec<Pid> = fs::read(self.path.join("cgroup.threads"))?
.lines()
Expand All @@ -142,18 +139,14 @@ impl CGroup {

/// Checks whether this cgroup is populated
pub fn populated(&self) -> anyhow::Result<bool> {
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

Ok(fs::read_to_string(self.get_events_path())?.contains("populated 1\n"))
}

/// Checks whether this cgroup is frozen
pub fn frozen(&self) -> anyhow::Result<bool> {
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

// We need to check for the existance of cgroup.freeze, because
// this file does not exist on the root cgroup.
Expand All @@ -168,33 +161,25 @@ impl CGroup {
/// Freezes this cgroup (does nothing if already frozen)
pub fn freeze(&self) -> anyhow::Result<()> {
trace!("Freeze {}", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

// We need to check for the existance of cgroup.freeze, because
// this file does not exist on the root cgroup.
let path = self.path.join("cgroup.freeze");
if !path.exists() {
bail!("cannot freeze the root cgroup");
}
ensure!(path.exists(), "cannot freeze the root cgroup");

Ok(fs::write(path, "1")?)
}

/// Unfreezes this cgroup (does nothing if not frozen)
pub fn unfreeze(&self) -> anyhow::Result<()> {
trace!("Unfreeze {}", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

// We need to check for the existance of cgroup.freeze, because
// this file does not exist on the root cgroup.
let path = self.path.join("cgroup.freeze");
if !path.exists() {
bail!("cannot unfreeze the root cgroup");
}
ensure!(path.exists(), "cannot unfreeze the root cgroup");

Ok(fs::write(path, "0")?)
}
Expand All @@ -203,16 +188,12 @@ impl CGroup {
/// procedure is finished
pub fn kill(&self) -> anyhow::Result<()> {
trace!("Kill {}", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

// We need to check for the existance of cgroup.kill, because
// this file does not exist on the root cgroup.
let killfile = self.path.join("cgroup.kill");
if !killfile.exists() {
bail!("cannot kill the root cgroup");
}
ensure!(killfile.exists(), "cannot kill the root cgroup");

// Emit the kill signal to all processes inside the cgroup
trace!("writing '1' to {}", killfile.display());
Expand Down Expand Up @@ -244,9 +225,7 @@ impl CGroup {
/// Kills all processes and removes the current cgroup
pub fn rm(&self) -> anyhow::Result<()> {
trace!("Remove {}", self.get_path().display());
if !is_cgroup(&self.path)? {
bail!("{} is not a valid cgroup", self.path.display());
}
self.ensure_is_cgroup()?;

// Calling kill will also kill all sub cgroup processes
self.kill()?;
Expand Down
2 changes: 1 addition & 1 deletion core/src/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ where

// Serialize the received data into T
bincode::deserialize(&buffer[0..len])
.map(|r| Some(r))
.map(Some)
.typ(SystemError::Panic)
}

Expand Down
4 changes: 2 additions & 2 deletions examples/ping/ping.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ major_frame: 1s
partitions:
- id: 0
name: ping_client
duration: 10ms
duration: 30ms
offset: 0ms
period: 1s
image: ping_client
- id: 1
name: ping_server
duration: 20ms
duration: 30ms
offset: 450ms
period: 1s
image: ping_server
Expand Down
4 changes: 2 additions & 2 deletions examples/ping_queue/ping_queue.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ major_frame: 1s
partitions:
- id: 0
name: ping_queue_client
duration: 10ms
duration: 30ms
offset: 0ms
period: 1s
image: ping_queue_client
- id: 1
name: ping_queue_server
duration: 20ms
duration: 30ms
offset: 450ms
period: 1s
image: ping_queue_server
Expand Down
2 changes: 1 addition & 1 deletion hypervisor/src/hypervisor/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl<'a> PartitionTimeframeScheduler<'a> {
/// `Ok(None)`. In case of `Ok(_)` the contained value is returned as
/// `Ok(Some(_))`.
fn handle_partition_result<T>(&mut self, res: TypedResult<T>) -> LeveledResult<Option<T>> {
res.map(|t| Some(t))
res.map(Some)
.or_else(|err| self.partition.handle_error(err).map(|_| None))
}
}