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,8 +42,9 @@ 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  | ||||
|          * arguments. | ||||
|  | ||||
| @ -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