Skip to content

Commit

Permalink
OTA live update infrastructure is complete. Other bug fixes...
Browse files Browse the repository at this point in the history
* user (SLIRP) networking works in QEMU.  Makefile takes different QEMU networking options now.

* support swapping crates from a given directory of kernel crates.

* Fixed CowArc issue where sharing, cloning, and weak upgrading was wrong.

* Swap app accepts crate object file paths too.
  • Loading branch information
kevinaboos committed Feb 5, 2019
1 parent ceba64d commit f676f43
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 88 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 18 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ iso: $(iso)
## This first invokes the make target that runs the actual compiler, and then copies all object files into the build dir.
## It gives all object files the KERNEL_PREFIX, except for "executable" application object files that get the APP_PREFIX.
build: $(nano_core_binary)
## Copy the object files from the target/ directory, and the core library, into the main build directory and prepend the kernel prefix
@for f in ./target/$(TARGET)/$(BUILD_MODE)/deps/*.o $(HOME)/.xargo/lib/rustlib/$(TARGET)/lib/core-*.o; do \
## Copy all object files into the main build directory and prepend the kernel prefix
## Al object files include those from the target/ directory, and the core, alloc, and compiler_builtins libraries
@for f in ./target/$(TARGET)/$(BUILD_MODE)/deps/*.o $(HOME)/.xargo/lib/rustlib/$(TARGET)/lib/*.o; do \
cp -vf $${f} $(OBJECT_FILES_BUILD_DIR)/`basename $${f} | sed -n -e 's/\(.*\)/$(KERNEL_PREFIX)\1/p'` 2> /dev/null ; \
done

Expand Down Expand Up @@ -355,7 +356,9 @@ help:
@echo -e "\t Builds Theseus documentation and then opens it in your default browser."

@echo -e "\nThe following key-value options are available for QEMU targets, like 'run' and 'debug':"
@echo -e " net=yes:"
@echo -e " net=user:"
@echo -e "\t Enable networking with an e1000 NIC in the guest and a userspace SLIRP-based interface in the host (QEMU default)."
@echo -e " net=tap:"
@echo -e "\t Enable networking with an e1000 NIC in the guest and a TAP interface in the host."
@echo -e " kvm=yes:"
@echo -e "\t Enable KVM acceleration (the host computer must support it)."
Expand Down Expand Up @@ -384,21 +387,26 @@ MAC_ADDR ?= 52:54:00:d1:55:01
## drive and devices commands from http://forum.osdev.org/viewtopic.php?f=1&t=26483 to use sata emulation
QEMU_FLAGS += -drive format=raw,file=random_data2.img,if=none,id=mydisk -device ide-hd,drive=mydisk,bus=ide.0,serial=4696886396

ifeq ($(net),yes)
## Read about QEMU networking options here: https://www.qemu.org/2018/05/31/nic-parameter/

## Read about QEMU networking options here: https://www.qemu.org/2018/05/31/nic-parameter/
ifeq ($(net),user)
## user-based networking setup with standard e1000 ethernet NIC
QEMU_FLAGS += -device e1000,netdev=network0,mac=$(MAC_ADDR) -netdev user,id=network0
## Dump network activity to a pcap file
QEMU_FLAGS += -object filter-dump,id=f1,netdev=network0,file=netdump.pcap
else ifeq ($(net),tap)
## TAP-based networking setup with a standard e1000 ethernet NIC frontent (in the guest) and the TAP backend (in the host)
QEMU_FLAGS += -device e1000,netdev=network0,mac=$(MAC_ADDR) -netdev tap,id=network0,ifname=tap0,script=no,downscript=no

## user-based networking setup with standard e1000 ethernet NIC (DOESN'T WORK)
# QEMU_FLAGS += -device e1000,netdev=network0,mac=$(MAC_ADDR) -netdev user,id=network0

## Dump network activity to a pcap file
QEMU_FLAGS += -object filter-dump,id=f1,netdev=network0,file=netdump.pcap
else ifeq ($(net),none)
QEMU_FLAGS += -net none
else ifneq (,$(net))
$(error Error: unsupported option "net=$(net)")
else
QEMU_FLAGS += -net none
endif

## Dump interrupts to the serial port log
ifeq ($(int),yes)
QEMU_FLAGS += -d int
endif
Expand Down
2 changes: 1 addition & 1 deletion applications/lsmod/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn main(args: Vec<String>) -> isize {
}
else {
for n in namespace.crate_names() {
out.push_str(&format!("{}\n", n));
out.push_str(&format!("{}\t\t{:?}\n", n, namespace.get_crate(&n).map(|c| c.lock_as_ref().object_file_abs_path.clone())));
}
}
println!("{}", out);
Expand Down
9 changes: 9 additions & 0 deletions applications/swap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,14 @@ path = "../../kernel/mod_mgmt"
[dependencies.memory]
path = "../../kernel/memory"

[dependencies.task]
path = "../../kernel/task"

[dependencies.acpi]
path = "../../kernel/acpi"

[dependencies.fs_node]
path = "../../kernel/fs_node"

[dependencies.path]
path = "../../kernel/path"
62 changes: 52 additions & 10 deletions applications/swap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,30 @@ extern crate getopts;
extern crate memory;
extern crate mod_mgmt;
extern crate acpi;
extern crate task;
extern crate path;
extern crate fs_node;

use core::ops::DerefMut;
use alloc::slice::SliceConcatExt;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use alloc::{
string::{String, ToString},
vec::Vec,
sync::Arc,
slice::SliceConcatExt,
};
use getopts::Options;
use mod_mgmt::SwapRequest;
use acpi::get_hpet;
use path::Path;
use fs_node::{FileOrDir, DirRef};


#[no_mangle]
pub fn main(args: Vec<String>) -> isize {
let mut opts = Options::new();
opts.optflag("h", "help", "print this help menu");
opts.optflag("v", "verbose", "enable verbose logging of crate swapping actions");

opts.optopt("k", "kernel-crates", "specify the absolute path of the directory where new kernel crates will be loaded from", "PATH");

let matches = match opts.parse(&args) {
Ok(m) => m,
Expand All @@ -45,6 +53,32 @@ pub fn main(args: Vec<String>) -> isize {
return 0;
}

let taskref = match task::get_my_current_task() {
Some(t) => t,
None => {
println!("failed to get current task");
return -1;
}
};
let curr_dir = {
let locked_task = taskref.lock();
let curr_env = locked_task.env.lock();
Arc::clone(&curr_env.working_dir)
};

let kernel_crates_dir = if let Some(path) = matches.opt_str("k") {
let path = Path::new(path);
match Path::get_absolute(&path) {
Ok(FileOrDir::Dir(dir)) => Some(dir),
_ => {
println!("Error: could not find specified kernel crate directory: {}.", path);
return -1;
}
}
} else {
None
};

let verbose = matches.opt_present("v");

let matches = matches.free.join(" ");
Expand All @@ -58,10 +92,10 @@ pub fn main(args: Vec<String>) -> isize {
return -1;
}
};

println!("tuples: {:?}", tuples);

match swap_modules(tuples, verbose) {

match swap_modules(tuples, &curr_dir, kernel_crates_dir, verbose) {
Ok(_) => 0,
Err(e) => {
println!("Error: {}", e);
Expand Down Expand Up @@ -116,7 +150,12 @@ fn parse_input_tuples<'a>(args: &'a str) -> Result<Vec<(&'a str, &'a str, bool)>


/// Performs the actual swapping of crate.
fn swap_modules(tuples: Vec<(&str, &str, bool)>, verbose_log: bool) -> Result<(), String> {
fn swap_modules(
tuples: Vec<(&str, &str, bool)>,
curr_dir: &DirRef,
kernel_crates_dir: Option<DirRef>,
verbose_log: bool
) -> Result<(), String> {
let namespace = mod_mgmt::get_default_namespace().ok_or("Couldn't get default crate namespace")?;

let swap_requests = {
Expand All @@ -127,9 +166,11 @@ fn swap_modules(tuples: Vec<(&str, &str, bool)>, verbose_log: bool) -> Result<()
.map(|(_name, crate_ref)| crate_ref)
.ok_or_else(|| format!("Couldn't find old crate loaded into namespace that matched {:?}", o))?;

// 2) check that the new crate file exists
let new_crate_path = namespace.get_kernel_file_starting_with(n)
.ok_or_else(|| format!("Couldn't find new kernel crate file {:?}.", n))?;
// 2) check that the new crate file exists. It could be a regular path, or a prefix for a file in the namespace's kernel dir
let new_crate_path = match Path::new(String::from(n)).get(curr_dir) {
Ok(FileOrDir::File(f)) => Ok(Path::new(f.lock().get_path_as_string())),
_ => namespace.get_kernel_file_starting_with(n).ok_or_else(|| format!("Couldn't find new kernel crate file {:?}.", n)),
}?;
mods.push(SwapRequest::new(old_crate.lock_as_ref().crate_name.clone(), new_crate_path, r));
}
mods
Expand All @@ -142,6 +183,7 @@ fn swap_modules(tuples: Vec<(&str, &str, bool)>, verbose_log: bool) -> Result<()

let swap_result = namespace.swap_crates(
swap_requests,
kernel_crates_dir,
kernel_mmi.deref_mut(),
verbose_log
);
Expand Down
8 changes: 4 additions & 4 deletions kernel/device_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ use core::str::FromStr;


/// A randomly chosen IP address that must be outside of the DHCP range.. // TODO FIXME: use DHCP to acquire IP
// const DEFAULT_LOCAL_IP: &'static str = "10.0.2.10/24; // the default QEMU user-slirp network gives IP addresses of "10.0.2.*"
const DEFAULT_LOCAL_IP: &'static str = "192.168.1.252/24"; // home router reserved IP
const DEFAULT_LOCAL_IP: &'static str = "10.0.2.15/24"; // the default QEMU user-slirp network gives IP addresses of "10.0.2.*"
// const DEFAULT_LOCAL_IP: &'static str = "192.168.1.252/24"; // home router reserved IP
// const DEFAULT_LOCAL_IP: &'static str = "10.42.0.91/24"; // rice net IP

/// Standard home router address. // TODO FIXME: use DHCP to acquire gateway IP
// const DEFAULT_GATEWAY_IP: [u8; 4] = [10, 0, 2, 2]; // the default QEMU user-slirp networking gateway IP
const DEFAULT_GATEWAY_IP: [u8; 4] = [192, 168, 1, 1]; // the default gateway for our TAP-based bridge
const DEFAULT_GATEWAY_IP: [u8; 4] = [10, 0, 2, 2]; // the default QEMU user-slirp networking gateway IP
// const DEFAULT_GATEWAY_IP: [u8; 4] = [192, 168, 1, 1]; // the default gateway for our TAP-based bridge
// const DEFAULT_GATEWAY_IP: [u8; 4] = [10, 42, 0, 1]; // rice net gateway ip


Expand Down
Loading

0 comments on commit f676f43

Please sign in to comment.