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

API from Firerunner to VM for managing local FS over vsock #34

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
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
53 changes: 53 additions & 0 deletions firerunner/src/fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::{fs, str};

pub fn handle_req(req: Vec<&[u8]>) -> std::io::Result<Vec<u8>> {
let op = str::from_utf8(&req[0]).unwrap().to_owned();
match op.as_str() {
"create_dir" => {
let path = str::from_utf8(&req[1]).unwrap();
println!("creating dir named: {:?}", path);
fs::create_dir(path)?;
Ok(vec![])
},
"copy" => {
let from = str::from_utf8(&req[1]).unwrap();
let to = str::from_utf8(&req[2]).unwrap();
println!("copying from {:?} to {:?}", from ,to);
fs::copy(from, to)?;
Ok(vec![])
},
"write" => {
let file = str::from_utf8(&req[1]).unwrap();
let body = &req[2];
let bodystr = str::from_utf8(&req[2]).unwrap();
println!("writing to file: {:?}, body: {:?}", file, bodystr);
fs::write(file, body)?;
Ok(vec![])
},
"read" => {
let file = str::from_utf8(&req[1]).unwrap();
println!("reading from file : {:?}", file);
let body = fs::read(file)?;
println!("BODY: {:?}", body);
Ok(body)
},
"remove_dir_all" => {
let path = str::from_utf8(&req[1]).unwrap();
println!("removing dir: {:?}", path);
fs::remove_dir_all(path)?;
Ok(vec![])

},
"remove_dir" => {
let path = str::from_utf8(&req[1]).unwrap();
println!("removing empty dir: {:?}", path);
fs::remove_dir(path)?;
Ok(vec![])
},
_ => {
Ok(b"Op not supported".to_vec())
}
}


}
1 change: 1 addition & 0 deletions firerunner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ pub mod runner;
pub mod vmm_wrapper;
pub mod vsock;
pub mod pipe_pair;
pub mod fs;

54 changes: 53 additions & 1 deletion firerunner/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ use vmm::vmm_config::boot_source::BootSourceConfig;
use vmm::vmm_config::drive::BlockDeviceConfig;
use vmm::vmm_config::machine_config::VmConfig;
use vmm::vmm_config::instance_info::{InstanceInfo, InstanceState};
use vmm::vmm_config::vsock::VsockDeviceConfig;
use std::{io::{Read, Write}, str, thread};

use crate::vmm_wrapper::VmmWrapper;
use super::pipe_pair::PipePair;
use crate::vsock::*;
use crate::fs::*;

#[derive(Debug)]
pub struct VmAppConfig {
Expand Down Expand Up @@ -155,7 +159,54 @@ impl VmAppConfig {
};
vmm.insert_block_device(block_config).expect("AppBlk");
}

vmm.add_vsock(
VsockDeviceConfig {id: libc::VMADDR_CID_HOST.to_string(),
guest_cid: self.vsock_cid}).expect("vsock");

let vthread = thread::spawn(move || {
let mut vlistener = VsockListener::bind(VMADDR_CID_HOST, 52).unwrap();
let vconnection = vlistener.accept();
let mut vcloser = vlistener.closer();
match vconnection {
Ok((mut vstream, vaddr)) => {
println!("Successfully connected to {:?}", vaddr);
let mut buffer = [0;256];
while match vstream.read(&mut buffer) {
Ok(msg_len) => {
if msg_len != 0 {
let reqs : Vec<&[u8]>= buffer
.split(|x| *x == b'\r')
.collect();
for rreq in reqs.iter() {
let req : Vec<&[u8]> = rreq
.split(|x| *x == 0)
.filter(|x| !x.is_empty())
.collect();
if !req.is_empty() {
let res =
handle_req(req.clone()).unwrap();
if !res.is_empty() {
let ress =
str::from_utf8(&res).unwrap();
vstream.write(&res);
}
}
}
buffer = [0;256];
true
} else { false }
},
Err(e) => {
println!("Error reading from vstream :( {:?}", e);
false
}
} {}
println!("closing vsock");
vcloser.close();
},
Err(err) => println!("Vsock connection error: {:?}", err)
}
});

evict_pid.map(|evict_pid| {
nix::sys::wait::waitpid(evict_pid, None);
Expand All @@ -164,6 +215,7 @@ impl VmAppConfig {

vmm.start_instance().expect("Start");
vmm.join();
vthread.join();
std::process::exit(0);
}
}
Expand Down
1 change: 1 addition & 0 deletions images/runtimes/c-vsock/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
workload
6 changes: 6 additions & 0 deletions images/runtimes/c-vsock/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mkfile_path := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

all: workload

workload: workload.c
echo "apk add alpine-sdk linux-headers; gcc -o /runtime/workload /runtime/workload.c" | docker run -i --rm -v $(mkfile_path):/runtime alpine
2 changes: 2 additions & 0 deletions images/runtimes/c-vsock/rootfs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cp /runtime/workload /bin/runtime-workload
chmod +x /bin/runtime-workload
117 changes: 117 additions & 0 deletions images/runtimes/c-vsock/workload.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include <stdio.h>
#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <string.h>
#include <unistd.h>

int main () {
printf("hello pipi");
/*
* Connect to VMM over vsock
*
* */
int sock;
struct sockaddr_vm sock_addr;
int res;
sock = socket(AF_VSOCK, SOCK_STREAM, 0);
if (sock == -1) {
printf("cannot create sock :(");
} else {
printf("created sock :)");
}
sock_addr.svm_family = AF_VSOCK;
sock_addr.svm_reserved1 = 0;
sock_addr.svm_port = 52;
sock_addr.svm_cid = 2;
res = connect(sock, (const struct sockaddr *)&sock_addr, sizeof(sock_addr));
if (res == -1) {
printf("cannot connect :(");
} else {
printf("connected :)");
}

/*
* Send requests to VMM to manage VMM's local FS
*
* - create a new directory
* - create a text file
* - read from the text file
* - create a new text file from read result
* - copy to a new file
* - remove the whole directory
* - create a new directory
* - remove the empty directory
*
* */
char req0[32];
char op[] = "create_dir";
char dir[] = "pidir";
char end[] = "\r";
memcpy(req0, &op, sizeof(op));
memcpy(req0 + sizeof(op), &dir, sizeof(dir));
memcpy(req0 + sizeof(op) + sizeof(dir), &end, sizeof(end));
write(sock, req0, sizeof(op) + sizeof(dir) + sizeof(end));

char req1[64];
char op1[] = "write";
char filename[] = "pidir/todo.txt";
char body[] = "1. take out trash\n2. laundry\n3. call grandma\n";
memcpy(req1, &op1, sizeof(op1));
memcpy(req1 + sizeof(op1), &filename, sizeof(filename));
memcpy(req1 + sizeof(op1) + sizeof(filename), &body, sizeof(body));
memcpy(req1 + sizeof(op1) + sizeof(filename) + sizeof(body), &end, sizeof(end));
write(sock, req1, sizeof(op1) + sizeof(filename) + sizeof(body) + sizeof(end));

char req2[32];
char op2[] = "read";
memcpy(req2, &op2, sizeof(op2));
memcpy(req2 + sizeof(op2), &filename, sizeof(filename));
memcpy(req2 + sizeof(op2) + sizeof(filename), &end, sizeof(end));
write(sock, req2, sizeof(op2) + sizeof(filename) + sizeof(end));
char op2_buffer[128];
bzero(op2_buffer, 128);
ssize_t size = read(sock, op2_buffer, 128);
printf("[C client] read value size %ld: %s", size, op2_buffer);

char req22[64];
char filename22[] = "pidir/todo-test.txt";
memcpy(req22, &op1, sizeof(op1));
memcpy(req22 + sizeof(op1), &filename22, sizeof(filename22));
memcpy(req22 + sizeof(op1) + sizeof(filename22), &op2_buffer, size);
memcpy(req22 + sizeof(op1) + sizeof(filename22) + size, &end, sizeof(end));
write(sock, req22, sizeof(op1) + sizeof(filename22) + size + sizeof(end));

char req3[32];
char op3[] = "copy";
char filename_cp[] = "pidir/todo-copy.txt";
memcpy(req3, &op3, sizeof(op3));
memcpy(req3 + sizeof(op3), &filename, sizeof(filename));
memcpy(req3 + sizeof(op3) + sizeof(filename), &filename_cp, sizeof(filename_cp));
memcpy(req3 + sizeof(op3) + sizeof(filename) + sizeof(filename_cp), &end, sizeof(end));
write(sock, req3, sizeof(op3) + sizeof(filename) + sizeof(filename_cp) + sizeof(end));

char req4[32];
char pidir1[] = "pidir1";
memcpy(req4, &op, sizeof(op));
memcpy(req4 + sizeof(op), &pidir1, sizeof(pidir1));
memcpy(req4 + sizeof(op) + sizeof(pidir1), &end, sizeof(end));
write(sock, req4, sizeof(op) + sizeof(pidir1) + sizeof(end));

char req5[64];
char op5[] = "remove_dir_all";
memcpy(req5, &op5, sizeof(op5));
memcpy(req5 + sizeof(op5), &dir, sizeof(dir));
memcpy(req5 + sizeof(op5) + sizeof(dir), &end, sizeof(end));
write(sock, req5, sizeof(op5) + sizeof(dir) + sizeof(end));

char req6[64];
char op6[] = "remove_dir";
memcpy(req6, &op6, sizeof(op6));
memcpy(req6 + sizeof(op6), &pidir1, sizeof(pidir1));
memcpy(req6 + sizeof(op6) + sizeof(pidir1), &end, sizeof(end));
write(sock, req6, sizeof(op6) + sizeof(pidir1) + sizeof(end));

close(sock);

return 0;
}