# Occlum Configuration

Occlum can be configured easily via a configuration file named `Occlum.json`, which is generated by the `occlum init` command in the Occlum instance directory. The user can modify `Occlum.json` to configure Occlum.

The template of `Occlum.json` is shown below.

## Default Legacy Mode (without EDMM support) 

```json
{
    // Resource limits
    "resource_limits": {
        // The total size of enclave memory available to LibOS processes
        "user_space_size": "256MB",
        // The heap size of LibOS kernel
        "kernel_space_heap_size": "32MB",
        // The stack size of LibOS kernel
        "kernel_space_stack_size": "1MB",
        // The max number of LibOS threads/processes
        "max_num_of_threads": 32
    },
    // Process
    "process": {
        // The stack size of the "main" thread
        "default_stack_size": "4MB",
        // The max size of memory allocated by brk syscall
        "default_heap_size": "16MB",
        // The max size of memory by mmap syscall (OBSOLETE. Users don't need to modify this field. Keep it only for compatibility)
        "default_mmap_size": "32MB"
    },
    // Entry points
    //
    // Entry points specify all valid path prefixes for <path> in `occlum run
    // <path> <args>`. This prevents outside attackers from executing arbitrary
    // commands inside an Occlum-powered enclave.
    "entry_points": [
        "/bin"
    ],
    // Environment variables
    //
    // This gives a list of environment variables for the "root"
    // process started by `occlum exec` command.
    "env": {
        // The default env vars given to each "root" LibOS process. As these env vars
        // are specified in this config file, they are considered trusted.
        "default": [
            "OCCLUM=yes"
        ],
        // The untrusted env vars that are captured by Occlum from the host environment
        // and passed to the "root" LibOS processes. These untrusted env vars can
        // override the trusted, default envs specified above.
        "untrusted": [
            "EXAMPLE"
        ]
    },
    // Enclave metadata
    "metadata": {
        // Enclave signature structure's ISVPRODID field
        "product_id": 0,
        // Enclave signature structure's ISVSVN field
        "version_number": 0,
        // Whether the enclave is debuggable through special SGX instructions.
        // For production enclave, it is IMPORTANT to set this value to false.
        "debuggable": true,
        // Whether the enclave is allowable to print Occlum log.
        // Optional, if not set, in default it is false for debuggable enclave
        // but true for production/release enclave for better security.
        // Production/release enclave could explicitly set it false to have log
        // output for debugging purpose. In this case, error log level is the
        // only allowed log level.
        "disable_log": false,
    },
    // Features
    "feature": {
        // Whether to turn on AMX feature in Occlum
        // Occlum supports AMX instruction running inside the enclave when user enables it
        //
        // "amx" = 0: AMX feature must be disabled
        // "amx" = 1: AMX feature must be enabled
        // "amx" = 2: AMX feature is enabled if the platform supports it
        "amx": 0,
        // Whether to turn on PKU feature in Occlum
        // Occlum uses PKU for isolation between LibOS and userspace program,
        // It is useful for developers to detect potential bugs.
        //
        // "pkru" = 0: PKU feature must be disabled
        // "pkru" = 1: PKU feature must be enabled
        // "pkru" = 2: PKU feature is enabled if the platform supports it
        "pkru": 0,
        // Whether to enable the EDMM feature
        // Enabling EDMM feature can make the enclave initialize faster and sometimes can also
        // bring performance benifit for the entire application
        //
        // Enabling EDMM feature will need more configuration on the memory related fields, for more information,
        // please visit [EDMM Configuration Guide](https://github.com/occlum/occlum/blob/master/docs/edmm/edmm_config_guide.md)
        "enable_edmm": false,
        // Whether to enable POSIX shared memory feature
        // Enabling POSIX shm allows processes to communicate by sharing a region of memory
        //
        // Set "enable_posix_shm" to true, the syscall `mmap` with flag `MAP_SHARED` 
        // is supported more comprehensively, implies that the file-backed memory mapping
        // become shared among processes.
        // More API information of POSIX shm is listed in [shm_overview](https://man7.org/linux/man-pages/man7/shm_overview.7.html).
        "enable_posix_shm": false
    },
    // Mount points and their file systems
    //
    // The default configuration is shown below.
    "mount": [
        {
            "target": "/",
            "type": "unionfs",
            "options": {
                "layers": [
                    {
                        "target": "/",
                        "type": "sefs",
                        "source": "./build/mount/__ROOT",
                        "options": {
                            "MAC": ""
                        }
                    },
                    {
                        "target": "/",
                        "type": "sefs",
                        "source": "./run/mount/__ROOT"
                    }
                ]
            }
        },
        {
            "target": "/host",
            "type": "hostfs",
            "source": "."
        },
        {
            "target": "/proc",
            "type": "procfs"
        },
        {
            "target": "/dev",
            "type": "devfs"
        }
    ]
}
```

## EDMM Configuration Add-on

In general, three optional fields have been added to the existing Occlum.json configuration: `kernel_space_heap_max_size`, `user_space_max_size`, and `init_num_of_threads`. An example of the memory section configuration in `Occlum.json` when all the EDMM-related configurations are enabled:

```json
{
  "resource_limits": {
    "kernel_space_stack_size": "1MB",       // (Legacy, Required)
    "kernel_space_heap_size": "4MB",        // (Legacy, Required)
    "kernel_space_heap_max_size": "40MB",   // !!! (Newly-Introduced，Optional)
    "user_space_size": "1MB",               // (Legacy, Required)
    "user_space_max_size": "600MB",         // !!! (Newly-Introduced，Optional)
    "init_num_of_threads": 2,               // !!! (Newly-Introduced，Optional)
    "max_num_of_threads": 64                // (Legacy, Required)
  },
  "process": {
    "default_stack_size": "4MB",            // (Legacy, Required)
    "default_heap_size": "8MB",             // (Legacy, Required)
    "default_mmap_size": "100MB"            // (Legacy, Required, but inoperative)
  },
}
```

More details please refer to [edmm_config_guide](./edmm_config_guide.md).

## Runtime Resource Configuration for Occlum process

Occlum has enabled per process resource configuration via [prlimit](https://man7.org/linux/man-pages//man2/prlimit.2.html) syscall and shell built-in command [ulimit](https://fishshell.com/docs/current/cmds/ulimit.html).

```shell
#! /usr/bin/bash
ulimit -a

# ulimit defined below will override configuration in Occlum.json
ulimit -Ss 10240 # stack size 10M
ulimit -Sd 40960 # heap size 40M
ulimit -Sv 102400 # virtual memory size 100M (including heap, stack, mmap size)

echo "ulimit result:"
ulimit -a

# Run applications with the new resource limits
...
```

For more info, please check [demos/fish](https://github.com/occlum/occlum/tree/master/demos/fish).