Skip to content

Commit

Permalink
Add comments to command module
Browse files Browse the repository at this point in the history
  • Loading branch information
YJDoc2 committed Jun 10, 2021
1 parent 56104b0 commit b03d631
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/command/command.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//! An interface trait so that rest of Youki can call
//! necessary functions without having to worry about their
//! implementation details
use std::{any::Any, path::Path};

use anyhow::Result;
Expand All @@ -9,6 +12,8 @@ use nix::{

use oci_spec::LinuxRlimit;

/// This specifies various kernel/other functionalities required for
/// container management
pub trait Command {
fn as_any(&self) -> &dyn Any;
fn pivot_rootfs(&self, path: &Path) -> Result<()>;
Expand Down
30 changes: 30 additions & 0 deletions src/command/linux.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Implements Command trait for Linux systems
use std::{any::Any, path::Path};

use anyhow::{bail, Result};
Expand All @@ -22,36 +23,60 @@ use oci_spec::LinuxRlimit;
use super::Command;
use crate::capabilities;

/// Empty structure to implement Command trait for
#[derive(Clone)]
pub struct LinuxCommand;

impl Command for LinuxCommand {
/// To enable dynamic typing,
/// see https://doc.rust-lang.org/std/any/index.html for more information
fn as_any(&self) -> &dyn Any {
self
}

/// Function to set given path as root path inside process
fn pivot_rootfs(&self, path: &Path) -> Result<()> {
// open the path as directory and read only
let newroot = open(path, OFlag::O_DIRECTORY | OFlag::O_RDONLY, Mode::empty())?;

// make the given path as the root directory for the container
// see https://man7.org/linux/man-pages/man2/pivot_root.2.html, specially the notes
// pivot root usually changes the root directory to first argument, and then mounts the original root
// directory at second argument. Giving same path for both stacks mapping of the original root directory
// above the new directory at the same path, then the call to umount unmounts the original root directory from
// this path. This is done, as otherwise, we will need to create a separate temporary directory under the new root path
// so we can move the original root there, and then unmount that. This way saves the creation of the temporary
// directory to put original root directory.
pivot_root(path, path)?;

// Unmount the original root directory which was stacked on top of new root directory
// MNT_DETACH makes the mount point unavailable to new accesses, but waits till the original mount point
// to be free of activity to actually unmount
// see https://man7.org/linux/man-pages/man2/umount2.2.html for more information
umount2("/", MntFlags::MNT_DETACH)?;
// Change directory to root
fchdir(newroot)?;
Ok(())
}

/// Set namespace for process
fn set_ns(&self, rawfd: i32, nstype: CloneFlags) -> Result<()> {
nix::sched::setns(rawfd, nstype)?;
Ok(())
}

/// set uid and gid for process
fn set_id(&self, uid: Uid, gid: Gid) -> Result<()> {
if let Err(e) = prctl::set_keep_capabilities(true) {
bail!("set keep capabilities returned {}", e);
};
// args : real *id, effective *id, saved set *id respectively
unistd::setresgid(gid, gid, gid)?;
unistd::setresuid(uid, uid, uid)?;

// if not the root user, reset capabilities to effective capabilities,
// which are used by kernel to perform checks
// see https://man7.org/linux/man-pages/man7/capabilities.7.html for more information
if uid != Uid::from_raw(0) {
capabilities::reset_effective(self)?;
}
Expand All @@ -61,22 +86,27 @@ impl Command for LinuxCommand {
Ok(())
}

/// Disassociate parts of execution context
// see https://man7.org/linux/man-pages/man2/unshare.2.html for more information
fn unshare(&self, flags: CloneFlags) -> Result<()> {
unshare(flags)?;
Ok(())
}

/// Set capabilities for container process
fn set_capability(&self, cset: CapSet, value: &CapsHashSet) -> Result<(), CapsError> {
caps::set(None, cset, value)
}

/// Sets hostname for process
fn set_hostname(&self, hostname: &str) -> Result<()> {
if let Err(e) = sethostname(hostname) {
bail!("Failed to set {} as hostname. {:?}", hostname, e)
}
Ok(())
}

/// Sets resource limit for process
fn set_rlimit(&self, rlimit: &LinuxRlimit) -> Result<()> {
let rlim = &libc::rlimit {
rlim_cur: rlimit.soft,
Expand Down
2 changes: 2 additions & 0 deletions src/command/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Contains a wrapper of syscalls for unit tests
//! This provides a uniform interface for rest of Youki
//! to call syscalls required for container management
#[allow(clippy::module_inception)]
mod command;
Expand Down

0 comments on commit b03d631

Please sign in to comment.