CPUSet cgroup allows for pinning the memory associated with a cpuset to
a given numa node. Similar to cpuset.cpus, we should take cpuset.mems
into account for the sandbox-cgroup that Kata creates.
Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
CPUSet cgroup allows for pinning the memory associated with a cpuset to
a given numa node. Similar to cpuset.cpus, we should take cpuset.mems
into account for the sandbox-cgroup that Kata creates.
Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
Pulled from 1.18.4 Kubernetes, adding the cpuset pkg for managing
CPUSet calculations on the host. Go mod'ing the original code from
k8s.io/kubernetes was very painful, and this is very static, so let's
just pull in what we need.
Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
Dave Gilbert brough up that passing --thread-pool-size=1 to virtiofsd
may result in a performance improvement especially when using
`cache=none`. While our current default is `cache=auto`, Dave mentioned
that he seems no harm in having it set and he also mentiond that it may
use a lot less stack space on aarch/arm.
Fixes: #943
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
To update device resource entries from host to guest, we search for
the right entry by host major:minor numbers, then later update it.
However block and character devices exist in separate major:minor
namespaces so we could have one block and one character device with
matching major:minor and thus incorrectly update both with the details
for whichever device is processed second.
Add a check on device type to prevent this.
Port from the Kata 1 Go agent
https://github.com/kata-containers/agent/commit/27ebdc9d2761Fixes: #703
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The agent needs to update device entries in the OCI spec so that it
has the correct major:minor numbers for the guest, which may differ
from the host.
Entries in the main device list are looked up by device path, but
entries in the device resources list are looked up by (host)
major:minor. This is done one device at a time, updating as we go in
update_spec_device_list().
But since the host and guest have different namespaces, one device
might have the same major:minor as a different device on the host. In
that case we could update one resource entry to the correct guest
values, then mistakenly update it again because it now matches a
different host device.
To avoid this, rather than looking up and updating one by one, we make
all the lookups in advance, creating a map from (host) device path to
the indices in the spec where the device and resource entries can be
found.
Port from the Go agent in Kata 1,
https://github.com/kata-containers/agent/commit/d88d46849130Fixes: #703
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The Kata 1 Go agent included a unit test for updateSpecDeviceList, but no
such unit test exists for the Rust agent's equivalent
update_spec_device_list(). Port the Kata1 test to Rust.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
If update_spec_device_list() is given a device that can't be found in the
OCI spec, it currently does nothing, and returns Ok(()). That doesn't
seem like what we'd expect and is not what the Go agent in Kata 1 does.
Change it to return an error in that case, like Kata 1.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Allow for constraining the cpuset as well as the devices-whitelist . Revert
sandbox constraints for cpu/memory, as they break the K8S use case. Can
re-add behind a non-default flag in the future.
The sandbox CPUSet should be updated every time a container is created,
updated, or removed.
To facilitate this without rewriting the 'non constrained cgroup'
handling, let's add to the Sandbox's cgroupsUpdate function.
Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
We were assuming base 10 string before, when the block size from sysfs
is actually a hex string. Let's fix that.
Fixes: #908
Signed-off-by: Eric Ernst <eric.g.ernst@gmail.com>
Sometimes `Option.or_or` and `Result.map_err` may be simpler
than match statement. Especially in rpc.rs, there are
many `ctr.get_process` and `sandbox.get_container` which
are using `match`.
Signed-off-by: bin liu <bin@hyper.sh>
There are some uses/codes/struct fields are commented out, and
may not turn into un-comment these codes, so delete these comments.
Signed-off-by: bin liu <bin@hyper.sh>
Use rust `Result`'s `or_else`/`and_then` can write clean codes.
And can avoid early return by check wether the `Result`
is `Ok` or `Err`.
Signed-off-by: bin liu <bin@hyper.sh>
This commit includes:
- update comments that not matched the function name
- file path with doubled slash
Fixes: #922
Signed-off-by: bin liu <bin@hyper.sh>
In function parse_cmdline there are some similar codes, if we want
to add more commandline arguments, the code will grow too long.
Use macro can reduce some codes with the same logic/processing.
Fixes: #914
Signed-off-by: bin liu <bin@hyper.sh>
Attackers might use it to explore other containers in the same pod.
While it is still safe to allow it, we can just close the race window
like runc does.
Fixes: #885
Signed-off-by: Peng Tao <bergwolf@hyper.sh>
On old kernels (like v4.9), kernel applies CLOECEC in wrong order w.r.t.
dumpable task flags. As a result, we might leak guest file descriptor to
containers. This is a former runc CVE-2016-9962 and still applies to
kata agent. Although Kata container is still valid at protecting the
host, we should not leak extra resources to user containers.
This sets the init processes that join and setup the container's
namespaces as non-dumpable before they setns to the container's pid (or
any other ) namespace.
This settings is automatically reset to the default after the Exec in
the container so that it does not change functionality for the
applications that are running inside, just our init processes.
This prevents parent processes, the pid 1 of the container, to ptrace
the init process before it drops caps and other sets LSMs.
The order during the exec syscall is that the process is set back to
dumpable before O_CLOEXEC are processed.
Refs:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=613cc2b6f272c1a8ad33aefa21cad77af23139f7https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318opencontainers/runc@50a19c6https://nvd.nist.gov/vuln/detail/CVE-2016-9962Fixes: #890
Signed-off-by: Peng Tao <bergwolf@hyper.sh>
virtiofs DAX support is not stable today, there are
a few corner cases to make it default.
Fixes: #862Fixes: #875
Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
Assign unused results to _ in order to silence warnings.
This addresses the following warnings:
warning: unused `std::result::Result` that must be used
--> rustjail/src/mount.rs:1182:16
|
1182 | defer!(unistd::chdir(&olddir););
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/mount.rs:1183:9
|
1183 | unistd::chdir(tempdir.path());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
While in regular code, we want to log possible errors, in test code
it's OK to simply ignore the returned value.
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
In a number of cases, we have functions that return a Result<...>
and where the possible error case is simply ignored. This is a bit
unhealthy.
Add a `check!` macro that allows us to not ignore error values
that we want to log, while not interrupting the flow by returning
them. This is useful for low-level functions such as `signal::kill` or
`unistd::close` where an error is probably significant, but should not
necessarily interrupt the flow of the program (i.e. using `call()?` is
not the right answer.
The check! macro is then used on low-level calls. This addresses the
following warnings from #750:
This addresses the following warning:
warning: unused `std::result::Result` that must be used
--> /home/ddd/go/src/github.com/kata-containers-2.0/src/agent/rustjail/src/container.rs:903:17
|
903 | signal::kill(Pid::from_raw(p.pid), Some(Signal::SIGKILL));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> /home/ddd/go/src/github.com/kata-containers-2.0/src/agent/rustjail/src/container.rs:916:17
|
916 | signal::kill(Pid::from_raw(child.id() as i32), Some(Signal::SIGKILL));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:340:13
|
340 | write_sync(cwfd, SYNC_FAILED, format!("{:?}", e).as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:554:13
|
554 | / write_sync(
555 | | cwfd,
556 | | SYNC_FAILED,
557 | | format!("setgroups failed: {:?}", e).as_str(),
558 | | );
| |______________^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:340:13
|
340 | write_sync(cwfd, SYNC_FAILED, format!("{:?}", e).as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:340:13
|
340 | write_sync(cwfd, SYNC_FAILED, format!("{:?}", e).as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:554:13
|
554 | / write_sync(
555 | | cwfd,
556 | | SYNC_FAILED,
557 | | format!("setgroups failed: {:?}", e).as_str(),
558 | | );
| |______________^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:626:5
|
626 | unistd::close(cfd_log);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:627:5
|
627 | unistd::close(crfd);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:628:5
|
628 | unistd::close(cwfd);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:770:9
|
770 | fcntl::fcntl(pfd_log, FcntlArg::F_SETFD(FdFlag::FD_CLOEXEC));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:799:9
|
799 | fcntl::fcntl(prfd, FcntlArg::F_SETFD(FdFlag::FD_CLOEXEC));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:800:9
|
800 | fcntl::fcntl(pwfd, FcntlArg::F_SETFD(FdFlag::FD_CLOEXEC));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:803:13
|
803 | unistd::close(prfd);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:930:9
|
930 | log_handler.join();
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:803:13
|
803 | unistd::close(prfd);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:804:13
|
804 | unistd::close(pwfd);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:842:13
|
842 | sched::setns(old_pid_ns, CloneFlags::CLONE_NEWPID);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/container.rs:843:13
|
843 | unistd::close(old_pid_ns);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
Fixes: #844Fixes: #750
Suggested-by: Tim Zhang <tim@hyper.sh>
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
Various recently added error-causing calls
This addresses the following warning:
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:93:9
|
93 | cg.add_task(CgroupPid::from(pid as u64));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:196:17
|
196 | freezer_controller.thaw();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:199:17
|
199 | freezer_controller.freeze();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:365:9
|
365 | cpuset_controller.set_cpus(&cpu.cpus);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:369:9
|
369 | cpuset_controller.set_mems(&cpu.mems);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:381:13
|
381 | cpu_controller.set_shares(shares);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:385:5
|
385 | cpu_controller.set_cfs_quota_and_period(cpu.quota, cpu.period);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
warning: unused `std::result::Result` that must be used
--> rustjail/src/cgroups/fs/mod.rs:1061:13
|
1061 | cpuset_controller.set_cpus(cpuset_cpus);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
The specific case of cpu_controller.set_cfs_quota_and_period is
addressed in a way that changes the logic following a suggestion by
Liu Bin, who had just added the code.
Fixes: #750
Suggested-by: Liu Bin <bin@hyper.sh>
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
When we are writing to the logs and there is an error doing so, there
is not much we can do. Chances are that a panic would make things
worse. So let it go through.
warning: unused `std::result::Result` that must be used
--> rustjail/src/sync.rs:26:9
|
26 | write_count(lfd, log_str.as_bytes(), log_str.len());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
::: rustjail/src/container.rs:339:13
|
339 | log_child!(cfd_log, "child exit: {:?}", e);
| ------------------------------------------- in this macro invocation
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
Some functions have undefined behavior and are not actually used.
This addresses the following warning:
warning: the type `oci::User` does not permit zero-initialization
--> rustjail/src/lib.rs:99:18
|
99 | unsafe { MaybeUninit::zeroed().assume_init() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `#[warn(invalid_value)]` on by default
note: `std::ptr::Unique<u32>` must be non-null (in this struct field)
warning: the type `protocols::oci::Process` does not permit zero-initialization
--> rustjail/src/lib.rs:146:14
|
146 | unsafe { MaybeUninit::zeroed().assume_init() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
note: `std::ptr::Unique<std::string::String>` must be non-null (in this struct field)
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
Addresses the following warning (and a few similar ones):
warning: variable does not need to be mutable
--> rustjail/src/container.rs:369:9
|
369 | let mut oci_process: oci::Process = serde_json::from_str(process_str)?;
| ----^^^^^^^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
This addresses the following:
warning: use of deprecated item 'std::error::Error::description': use the Display impl or to_string()
--> rustjail/src/container.rs:1598:31
|
1598 | ... e.description(),
| ^^^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
Parameters that are never used were removed.
Parameters that are unused, but necessary because of some common
interface were renamed with a _ prefix.
In one case, consume the parameter by adding an info! call, and fix a
minor typo in a message in the same function.
This addresses the following warning:
warning: unused variable: `child`
--> rustjail/src/container.rs:1128:5
|
1128 | child: &mut Child,
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_child`
warning: unused variable: `logger`
--> rustjail/src/container.rs:1049:22
|
1049 | fn update_namespaces(logger: &Logger, spec: &mut Spec, init_pid: RawFd) -> Result<()> {
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_logger`
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
Remove variables that are simply not used.
Rename as _ variables where only initialization matters.
This addresses the following warnings:
warning: unused variable: `writer`
--> src/main.rs:130:9
|
130 | let writer = unsafe { File::from_raw_fd(wfd) };
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_writer`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `ctx`
--> src/rpc.rs:782:9
|
782 | ctx: &ttrpc::TtrpcContext,
| ^^^ help: if this is intentional, prefix it with an underscore: `_ctx`
warning: unused variable: `ctx`
--> src/rpc.rs:808:9
|
808 | ctx: &ttrpc::TtrpcContext,
| ^^^ help: if this is intentional, prefix it with an underscore: `_ctx`
warning: unused variable: `dns_list`
--> src/rpc.rs:1152:16
|
1152 | Ok(dns_list) => {
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_dns_list`
warning: value assigned to `child_stdin` is never read
--> rustjail/src/container.rs:807:13
|
807 | let mut child_stdin = std::process::Stdio::null();
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_assignments)]` on by default
= help: maybe it is overwritten before being read?
warning: value assigned to `child_stdout` is never read
--> rustjail/src/container.rs:808:13
|
808 | let mut child_stdout = std::process::Stdio::null();
| ^^^^^^^^^^^^^^^^
|
= help: maybe it is overwritten before being read?
warning: value assigned to `child_stderr` is never read
--> rustjail/src/container.rs:809:13
|
809 | let mut child_stderr = std::process::Stdio::null();
| ^^^^^^^^^^^^^^^^
|
= help: maybe it is overwritten before being read?
warning: value assigned to `stdin` is never read
--> rustjail/src/container.rs:810:13
|
810 | let mut stdin = -1;
| ^^^^^^^^^
|
= help: maybe it is overwritten before being read?
warning: value assigned to `stdout` is never read
--> rustjail/src/container.rs:811:13
|
811 | let mut stdout = -1;
| ^^^^^^^^^^
|
= help: maybe it is overwritten before being read?
warning: value assigned to `stderr` is never read
--> rustjail/src/container.rs:812:13
|
812 | let mut stderr = -1;
| ^^^^^^^^^^
|
= help: maybe it is overwritten before being read?
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
This addresses the following warning:
warning: unnecessary braces around assigned value
--> src/rpc.rs:1411:26
|
1411 | detail.init_daemon = { unistd::getpid() == Pid::from_raw(1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these braces
|
= note: `#[warn(unused_braces)]` on by default
Fixes: #750
Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
We can rely on the error handling of the actual HTTP API calls to catch
errors, and don't need to call VmmPing explicitly in advance.
Signed-off-by: Bo Chen <chen.bo@intel.com>