Add hosts and hostname file
This commit is contained in:
parent
3e15eb059c
commit
15932a54b6
@ -6,11 +6,6 @@ targets:
|
||||
- target: /bin
|
||||
copy:
|
||||
- from: ../flink-1.10.1
|
||||
# copy hosts file
|
||||
- target: /etc
|
||||
copy:
|
||||
- files:
|
||||
- ../hosts
|
||||
# copy localtime
|
||||
- target: /etc
|
||||
copy:
|
||||
|
@ -1,4 +0,0 @@
|
||||
127.0.0.1 occlum-node
|
||||
127.0.0.1 localhost
|
||||
::1 occlum-node
|
||||
::1 localhost
|
@ -42,7 +42,8 @@ enclave {
|
||||
* EEXIST - The LibOS has already been initialized.
|
||||
* EINVAL - The value of an argument are invalid.
|
||||
*/
|
||||
public int occlum_ecall_init([in, string] const char* log_level, [in, string] const char* instance_dir, [in, string] const char* resolv_conf_ptr);
|
||||
|
||||
public int occlum_ecall_init([in, string] const char* log_level, [in, string] const char* instance_dir, [in] const struct host_file_buffer* file_buffer);
|
||||
|
||||
/*
|
||||
* Create a new LibOS process to do the task specified by the given
|
||||
|
@ -29,6 +29,13 @@ typedef struct itimerspec{
|
||||
struct _timespec it_value;
|
||||
} itimerspec_t;
|
||||
|
||||
// todo: more detailed description
|
||||
struct host_file_buffer {
|
||||
const char* resolv_conf_ptr;
|
||||
const char* hosts_ptr;
|
||||
const char* hostname_ptr;
|
||||
};
|
||||
|
||||
#define FD_SETSIZE 1024
|
||||
typedef struct {
|
||||
unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
|
||||
|
@ -11,9 +11,9 @@ use crate::process::idle_reap_zombie_children;
|
||||
use crate::process::{ProcessFilter, SpawnAttr};
|
||||
use crate::signal::SigNum;
|
||||
use crate::time::up_time::init;
|
||||
use crate::util::host_file_util::{host_file_buffer, parse_host_file, write_host_file, HostFile};
|
||||
use crate::util::log::LevelFilter;
|
||||
use crate::util::mem_util::from_untrusted::*;
|
||||
use crate::util::resolv_conf_util::{parse_resolv_conf, write_resolv_conf};
|
||||
use crate::util::sgx::allow_debug as sgx_allow_debug;
|
||||
use crate::vm::USER_SPACE_VM_MANAGER;
|
||||
use sgx_tse::*;
|
||||
@ -27,6 +27,8 @@ lazy_static! {
|
||||
pub static ref ENTRY_POINTS: RwLock<Vec<PathBuf>> =
|
||||
RwLock::new(config::LIBOS_CONFIG.entry_points.clone());
|
||||
pub static ref RESOLV_CONF_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||
pub static ref HOSTNAME_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||
pub static ref HOSTS_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
macro_rules! ecall_errno {
|
||||
@ -40,7 +42,7 @@ macro_rules! ecall_errno {
|
||||
pub extern "C" fn occlum_ecall_init(
|
||||
log_level: *const c_char,
|
||||
instance_dir: *const c_char,
|
||||
resolv_conf_ptr: *const c_char,
|
||||
file_buffer: *const host_file_buffer,
|
||||
) -> i32 {
|
||||
if HAS_INIT.load(Ordering::SeqCst) == true {
|
||||
return ecall_errno!(EEXIST);
|
||||
@ -95,18 +97,46 @@ pub extern "C" fn occlum_ecall_init(
|
||||
unsafe { backtrace::enable_backtrace(&ENCLAVE_PATH, PrintFormat::Short) };
|
||||
});
|
||||
|
||||
match parse_resolv_conf(resolv_conf_ptr) {
|
||||
// Parse host file
|
||||
let resolv_conf_ptr = unsafe { (*file_buffer).resolv_conf_ptr };
|
||||
match parse_host_file(HostFile::RESOLV_CONF, resolv_conf_ptr) {
|
||||
Err(e) => {
|
||||
error!("failed to parse /etc/resolv.conf: {}", e.backtrace());
|
||||
}
|
||||
Ok(resolv_conf_str) => {
|
||||
*RESOLV_CONF_STR.write().unwrap() = Some(resolv_conf_str);
|
||||
if let Err(e) = write_resolv_conf() {
|
||||
if let Err(e) = write_host_file(HostFile::RESOLV_CONF) {
|
||||
error!("failed to write /etc/resolv.conf: {}", e.backtrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let hostname_ptr = unsafe { (*file_buffer).hostname_ptr };
|
||||
match parse_host_file(HostFile::HOSTNAME, hostname_ptr) {
|
||||
Err(e) => {
|
||||
error!("failed to parse /etc/hostname: {}", e.backtrace());
|
||||
}
|
||||
Ok(hostname_str) => {
|
||||
*HOSTNAME_STR.write().unwrap() = Some(hostname_str);
|
||||
if let Err(e) = write_host_file(HostFile::HOSTNAME) {
|
||||
error!("failed to write /etc/hostname: {}", e.backtrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let hosts_ptr = unsafe { (*file_buffer).hosts_ptr };
|
||||
match parse_host_file(HostFile::HOSTS, hosts_ptr) {
|
||||
Err(e) => {
|
||||
error!("failed to parse /etc/hosts: {}", e.backtrace());
|
||||
}
|
||||
Ok(hosts_str) => {
|
||||
*HOSTS_STR.write().unwrap() = Some(hosts_str);
|
||||
if let Err(e) = write_host_file(HostFile::HOSTS) {
|
||||
error!("failed to write /etc/hosts: {}", e.backtrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Once;
|
||||
|
||||
use config::{parse_key, parse_mac, ConfigMount, ConfigMountFsType, ConfigMountOptions};
|
||||
use rcore_fs_mountfs::MNode;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Once;
|
||||
use util::host_file_util::{write_host_file, HostFile};
|
||||
use util::mem_util::from_user;
|
||||
use util::resolv_conf_util::write_resolv_conf;
|
||||
|
||||
use super::rootfs::{mount_nonroot_fs_according_to, open_root_fs_according_to, umount_nonroot_fs};
|
||||
use super::*;
|
||||
@ -30,10 +29,19 @@ pub fn do_mount_rootfs(
|
||||
*rootfs = new_rootfs;
|
||||
*ENTRY_POINTS.write().unwrap() = user_config.entry_points.to_owned();
|
||||
});
|
||||
|
||||
// Write resolv.conf file into mounted file system
|
||||
write_resolv_conf()?;
|
||||
write_host_file(HostFile::RESOLV_CONF)?;
|
||||
*RESOLV_CONF_STR.write().unwrap() = None;
|
||||
|
||||
// Write hostname file into mounted file system
|
||||
write_host_file(HostFile::HOSTNAME)?;
|
||||
*HOSTNAME_STR.write().unwrap() = None;
|
||||
|
||||
// Write hosts file into mounted file system
|
||||
write_host_file(HostFile::HOSTS)?;
|
||||
*HOSTS_STR.write().unwrap() = None;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::*;
|
||||
use crate::fs::{AccessMode, CreationFlags, FileMode, FsView};
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use std::str;
|
||||
/// A sample of `struct utsname`
|
||||
/// ```
|
||||
/// sysname = Linux
|
||||
@ -25,7 +26,7 @@ pub struct utsname_t {
|
||||
|
||||
pub fn do_uname(name: &mut utsname_t) -> Result<()> {
|
||||
copy_from_cstr_to_u8_array(&SYSNAME, &mut name.sysname);
|
||||
copy_from_cstr_to_u8_array(&NODENAME, &mut name.nodename);
|
||||
obtain_nodename(&mut name.nodename);
|
||||
copy_from_cstr_to_u8_array(&RELEASE, &mut name.release);
|
||||
copy_from_cstr_to_u8_array(&VERSION, &mut name.version);
|
||||
copy_from_cstr_to_u8_array(&MACHINE, &mut name.machine);
|
||||
@ -48,3 +49,32 @@ fn copy_from_cstr_to_u8_array(src: &CStr, dst: &mut [u8]) {
|
||||
dst[..len].copy_from_slice(&src[..len]);
|
||||
dst[len] = 0;
|
||||
}
|
||||
|
||||
fn obtain_nodename(dst: &mut [u8]) {
|
||||
const HOSTNAME_PATH: &'static str = "/etc/hostname";
|
||||
|
||||
let fs_view = FsView::new();
|
||||
|
||||
let hostname_file = match fs_view.open_file(
|
||||
HOSTNAME_PATH,
|
||||
AccessMode::O_RDONLY as u32,
|
||||
FileMode::from_bits(0o666).unwrap(),
|
||||
) {
|
||||
Ok(file) => file,
|
||||
Err(e) => {
|
||||
// If failed to open hostname file, use "occlum-node" nodename.
|
||||
error!("failed to open /etc/hostname: {}", e.backtrace());
|
||||
copy_from_cstr_to_u8_array(&NODENAME, dst);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut nodename: [u8; 65] = [0; 65];
|
||||
hostname_file.read(&mut nodename);
|
||||
|
||||
// The \n need to be eliminated.
|
||||
let nodename_string = str::from_utf8(&nodename).unwrap().replace("\n", "");
|
||||
let len = nodename_string.len();
|
||||
dst[..len].copy_from_slice(&nodename_string.into_bytes());
|
||||
dst[len] = 0;
|
||||
}
|
||||
|
77
src/libos/src/util/host_file_util.rs
Normal file
77
src/libos/src/util/host_file_util.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use super::*;
|
||||
use crate::fs::{AccessMode, CreationFlags, FileMode, FsView};
|
||||
use resolv_conf::*;
|
||||
use std::ffi::CStr;
|
||||
use std::str;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct host_file_buffer {
|
||||
pub resolv_conf_ptr: *const c_char,
|
||||
pub hosts_ptr: *const c_char,
|
||||
pub hostname_ptr: *const c_char,
|
||||
}
|
||||
|
||||
pub enum HostFile {
|
||||
HOSTS,
|
||||
HOSTNAME,
|
||||
RESOLV_CONF,
|
||||
}
|
||||
|
||||
pub fn write_host_file(host_file: HostFile) -> Result<()> {
|
||||
let file_path: &str = match host_file {
|
||||
HostFile::HOSTS => "/etc/hosts",
|
||||
HostFile::HOSTNAME => "/etc/hostname",
|
||||
HostFile::RESOLV_CONF => "/etc/resolv.conf",
|
||||
_ => return_errno!(EINVAL, "Unsupported host file"),
|
||||
};
|
||||
|
||||
let fs_view = FsView::new();
|
||||
// overwrite host file if existed in Occlum fs
|
||||
let enclave_file = fs_view.open_file(
|
||||
file_path,
|
||||
AccessMode::O_RDWR as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits(),
|
||||
FileMode::from_bits(0o666).unwrap(),
|
||||
)?;
|
||||
|
||||
let host_file_str = match host_file {
|
||||
HostFile::HOSTS => HOSTS_STR.read().unwrap(),
|
||||
HostFile::HOSTNAME => HOSTNAME_STR.read().unwrap(),
|
||||
HostFile::RESOLV_CONF => RESOLV_CONF_STR.read().unwrap(),
|
||||
_ => return_errno!(EINVAL, "Unsupported host file"),
|
||||
};
|
||||
|
||||
match &*host_file_str {
|
||||
Some(str) => {
|
||||
enclave_file.write(str.as_bytes());
|
||||
}
|
||||
None => {
|
||||
warn!("The host file: {:?} does not exist", file_path);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_host_file(host_file: HostFile, host_file_ptr: *const c_char) -> Result<String> {
|
||||
// Read host file
|
||||
let host_file_bytes = unsafe { CStr::from_ptr(host_file_ptr).to_bytes() };
|
||||
let host_file_str = str::from_utf8(host_file_bytes)
|
||||
.map_err(|_| errno!(EINVAL, "host file contains non UTF-8 characters"))?;
|
||||
|
||||
match host_file {
|
||||
HostFile::HOSTS => {
|
||||
// TODO: Parsing hosts
|
||||
}
|
||||
HostFile::HOSTNAME => {
|
||||
// TODO: Parsing hostname
|
||||
}
|
||||
HostFile::RESOLV_CONF => {
|
||||
// Parse and inspect host file
|
||||
if let Err(_) = resolv_conf::Config::parse(host_file_bytes) {
|
||||
return_errno!(EINVAL, "malformated host /etc/resolv.conf");
|
||||
}
|
||||
}
|
||||
_ => return_errno!(EINVAL, "Unsupported host file"),
|
||||
};
|
||||
|
||||
Ok(host_file_str.to_string())
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
use super::*;
|
||||
|
||||
pub mod dirty;
|
||||
pub mod host_file_util;
|
||||
pub mod log;
|
||||
pub mod mem_util;
|
||||
pub mod mpx_util;
|
||||
pub mod resolv_conf_util;
|
||||
pub mod sgx;
|
||||
pub mod sync;
|
||||
|
@ -1,37 +0,0 @@
|
||||
use super::*;
|
||||
use crate::fs::{AccessMode, CreationFlags, FileMode, FsView};
|
||||
use resolv_conf::*;
|
||||
use std::ffi::CStr;
|
||||
use std::str;
|
||||
|
||||
pub fn write_resolv_conf() -> Result<()> {
|
||||
const RESOLV_CONF_PATH: &'static str = "/etc/resolv.conf";
|
||||
let fs_view = FsView::new();
|
||||
// overwrite /etc/resolv.conf if existed
|
||||
let resolv_conf_file = fs_view.open_file(
|
||||
RESOLV_CONF_PATH,
|
||||
AccessMode::O_RDWR as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits(),
|
||||
FileMode::from_bits(0o666).unwrap(),
|
||||
)?;
|
||||
let resolv_conf_str = RESOLV_CONF_STR.read().unwrap();
|
||||
match &*resolv_conf_str {
|
||||
Some(str) => {
|
||||
resolv_conf_file.write(str.as_bytes());
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_resolv_conf(resolv_conf_ptr: *const c_char) -> Result<String> {
|
||||
// Read resolv.conf file from host
|
||||
let resolv_conf_bytes = unsafe { CStr::from_ptr(resolv_conf_ptr).to_bytes() };
|
||||
let resolv_conf_str = str::from_utf8(resolv_conf_bytes)
|
||||
.map_err(|_| errno!(EINVAL, "/etc/resolv.conf contains non UTF-8 characters"))?;
|
||||
|
||||
// Parse and inspect resolv.conf file
|
||||
if let Err(_) = resolv_conf::Config::parse(resolv_conf_bytes) {
|
||||
return_errno!(EINVAL, "malformated host /etc/resolv.conf");
|
||||
}
|
||||
Ok(resolv_conf_str.to_string())
|
||||
}
|
@ -93,6 +93,13 @@ struct occlum_pal_create_process_args {
|
||||
int *pid;
|
||||
};
|
||||
|
||||
// todo: more detailed description
|
||||
struct host_file_buffer {
|
||||
const char *resolv_conf_ptr;
|
||||
const char *hosts_ptr;
|
||||
const char *hostname_ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* The struct which consists of arguments needed by occlum_pal_exec
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "Enclave_u.h"
|
||||
#include "pal_enclave.h"
|
||||
#include "pal_error.h"
|
||||
#include "pal_load_resolv_conf.h"
|
||||
#include "pal_load_file.h"
|
||||
#include "pal_interrupt_thread.h"
|
||||
#include "pal_log.h"
|
||||
#include "pal_sig_handler.h"
|
||||
@ -107,11 +107,24 @@ int occlum_pal_init(const struct occlum_pal_attr *attr) {
|
||||
eid = pal_get_enclave_id();
|
||||
|
||||
int ecall_ret = 0;
|
||||
const char *resolv_conf_ptr = pal_load_resolv_conf();
|
||||
struct host_file_buffer file_buffer = {
|
||||
.hostname_ptr = pal_load_file("/etc/hostname"),
|
||||
.hosts_ptr = pal_load_file("/etc/hosts"),
|
||||
.resolv_conf_ptr = pal_load_file("/etc/resolv.conf"),
|
||||
};
|
||||
|
||||
const struct host_file_buffer *file_buffer_ptr = &file_buffer;
|
||||
|
||||
sgx_status_t ecall_status = occlum_ecall_init(eid, &ecall_ret, attr->log_level,
|
||||
resolved_path, resolv_conf_ptr);
|
||||
free((void *)resolv_conf_ptr);
|
||||
resolv_conf_ptr = NULL;
|
||||
resolved_path, file_buffer_ptr);
|
||||
|
||||
free((void *)file_buffer.hostname_ptr);
|
||||
file_buffer.hostname_ptr = NULL;
|
||||
free((void *)file_buffer.hosts_ptr);
|
||||
file_buffer.hosts_ptr = NULL;
|
||||
free((void *)file_buffer.resolv_conf_ptr);
|
||||
file_buffer.resolv_conf_ptr = NULL;
|
||||
|
||||
if (ecall_status != SGX_SUCCESS) {
|
||||
const char *sgx_err = pal_get_sgx_error_msg(ecall_status);
|
||||
PAL_ERROR("Failed to do ECall with error code 0x%x: %s", ecall_status, sgx_err);
|
||||
|
24
src/pal/src/pal_load_file.c
Normal file
24
src/pal/src/pal_load_file.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pal_log.h"
|
||||
|
||||
char *pal_load_file(const char *filename) {
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
PAL_WARN("Warning: Failed to open file: %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *file_buffer = malloc(fsize + 1);
|
||||
if (file_buffer == NULL) {
|
||||
PAL_WARN("Warning: Failed to malloc buffer for file: %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
fread(file_buffer, 1, fsize, fp);
|
||||
file_buffer[fsize] = 0;
|
||||
fclose(fp);
|
||||
return file_buffer;
|
||||
}
|
6
src/pal/src/pal_load_file.h
Normal file
6
src/pal/src/pal_load_file.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __PAL_LOAD_FILE_H__
|
||||
#define __PAL_LOAD_FILE_H__
|
||||
|
||||
char *pal_load_file(const char *filename);
|
||||
|
||||
#endif /* __PAL_LOAD_FILE_H__ */
|
@ -1,24 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pal_log.h"
|
||||
|
||||
char *pal_load_resolv_conf(void) {
|
||||
FILE *fp = fopen("/etc/resolv.conf", "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
PAL_WARN("Warning: Failed to open /etc/resolv.conf file");
|
||||
return NULL;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *resolv_conf_buffer = malloc(fsize + 1);
|
||||
if (resolv_conf_buffer == NULL) {
|
||||
PAL_WARN("Warning: Failed to malloc for /etc/resolv.conf buffer");
|
||||
return NULL;
|
||||
}
|
||||
fread(resolv_conf_buffer, 1, fsize, fp);
|
||||
resolv_conf_buffer[fsize] = 0;
|
||||
fclose(fp);
|
||||
return resolv_conf_buffer;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef __PAL_LOAD_RESOLV_CONF_H__
|
||||
#define __PAL_LOAD_RESOLV_CONF_H__
|
||||
|
||||
char *pal_load_resolv_conf(void);
|
||||
|
||||
#endif /* __PAL_LOAD_RESOLV_CONF_H__ */
|
Loading…
Reference in New Issue
Block a user