91 lines
3.6 KiB
Markdown
91 lines
3.6 KiB
Markdown
# Runtime boot pre-generated UnionFS image
|
|
|
|
Generally, every Occlum instance has to pass the `Occlum build` process.
|
|
In some scenarios, mount and boot a pre-generated UnionFS image without `Occlum build` is a good feature. This demo introduces a way to runtime boot a BASH demo.
|
|
|
|
## Flow
|
|
|
|
### First, build a [`BASH`](../bash) Occlum instance
|
|
|
|
The later step will use the image content to generate UnionFS image.
|
|
|
|
### Build and start a [`gen_rootfs`](./gen_rootfs) Occlum instance
|
|
|
|
This `gen_rootfs` mounts a empty **sefs** (uses the lower path as mount target dir), copy the BASH Occlum image content to the mount point, unmount the **sefs**. It generates an encrypted **sefs** image containing the BASH image content. The **key** used in this demo is `"c7-32-b3-ed-44-df-ec-7b-25-2d-9a-32-38-8d-58-61"`.
|
|
|
|
### Build customized [`init`](./init)
|
|
|
|
Occlum [`default init`](../../tools/init) calls syscall (363) `MountRootFS` to mount and boot Occlum instance generated by normal `occlum build`.
|
|
```
|
|
(MountRootFS = 363) => do_mount_rootfs(key_ptr: *const sgx_key_128bit_t, rootfs_config: *const user_rootfs_config)
|
|
```
|
|
The first parameter `key_ptr` is optional.
|
|
The second parameter `rootfs_config` needs to be set as NULL.
|
|
|
|
But for runtime booting pre-generated image, The first parameter `key_ptr` is must to have, the second parameter `rootfs_config` needs have valid members.
|
|
```
|
|
struct user_rootfs_config {
|
|
// length of the struct
|
|
len: usize,
|
|
// UnionFS type rootfs upper layer, read-write layer
|
|
upper_layer_path: *const i8,
|
|
// UnionFS type rootfs lower layer, read-only layer
|
|
lower_layer_path: *const i8,
|
|
entry_point: *const i8,
|
|
// HostFS source path
|
|
hostfs_source: *const i8,
|
|
// HostFS target path, default value is "/host"
|
|
hostfs_target: *const i8,
|
|
// An array of pointers to null-terminated strings
|
|
// and must be terminated by a null pointer
|
|
envp: *const *const i8,
|
|
}
|
|
```
|
|
|
|
In this demo, parameters values are provided as below.
|
|
|
|
* **len**
|
|
The length of the struct which should be the value of `size_of(user_rootfs_config)`.
|
|
It is helpful for possible future extension.
|
|
|
|
* **rootfs_key**
|
|
The key to encrypt/decrypt the rootfs, here it is `"c7-32-b3-ed-44-df-ec-7b-25-2d-9a-32-38-8d-58-61".
|
|
|
|
* **rootfs_upper_layer**
|
|
The upper layer path of the unionfs type rootfs. In this case, it is relative path `"../gen_rootfs_instance/mnt_unionfs/upper"`.
|
|
|
|
* **rootfs_lower_layer**
|
|
The lower layer path of the unionfs type rootfs. In this case, it is relative path `"../gen_rootfs_instance/mnt_unionfs/lower"`.
|
|
|
|
* **rootfs_entry**
|
|
The entry point of the rootfs. In his case, it is `"/bin"`.
|
|
|
|
* **hostfs_source**
|
|
It is set to be `/tmp` in this case.
|
|
|
|
* **envp**
|
|
An array of pointers to null-terminated strings and must be terminated by a null pointer.
|
|
For example, set it to the address of ["TEST=1234", "TEST2=4567", NULL].
|
|
|
|
In this example customized init, the above parameters are declared in the source [`main.rs`](./init/src/main.rs). In real case, they could be acquired by LA/RA or by modifying the PAL api `pal_run_init_process`.
|
|
|
|
### Build a boot template Occlum instance
|
|
|
|
This template uses the customized init. The RootFS image is not important, which will be replaced during boot.
|
|
|
|
All above steps could be done with one [`script`](./build_content.sh).
|
|
```
|
|
./build_content.sh
|
|
```
|
|
|
|
After running the script, runtime boot BASH could be done as below even if the default RootFS image has no BASH function.
|
|
```
|
|
# cd boot_instance
|
|
# occlum run /bin/occlum_bash_test.sh
|
|
```
|
|
|
|
Also, the runtime environment passed by **envp** could be verified by
|
|
```
|
|
# occlum run /bin/busybox env
|
|
```
|