JNIEXPORT jint JNICALL JavaEnclave_TeeLibOSNativeCreateEnclave()

in sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.c [69:205]


JNIEXPORT jint JNICALL JavaEnclave_TeeLibOSNativeCreateEnclave(JNIEnv *env, jobject obj, jint debug, jint sim, jint portHost, jint portEnclave, jobject config, jstring path) {
    char* occlum_pal_path = OCCLUM_HARDWARE_PAL_PATH;
    if (sim == 1) {
        occlum_pal_path = OCCLUM_SIMULATE_PAL_PATH;
    }

    void *lib_occlum_pal_handle = dlopen(occlum_pal_path, RTLD_LOCAL | RTLD_LAZY);
    if (!lib_occlum_pal_handle) {
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlopen occlum_pal_path.so failed.")
    }

    // set .so file handle back to java enclave object.
    jclass class_enclave = (*env)->GetObjectClass(env, obj);
    set_long_field_value(env, class_enclave, obj, "enclaveHandle", (jlong)lib_occlum_pal_handle);

    // lookup symbol occlum_pal_init in libocclum-pal.so
    int (*occlum_pal_init)(const struct occlum_pal_attr *attr);
    occlum_pal_init = (int (*)(const struct occlum_pal_attr *))dlsym((void *)lib_occlum_pal_handle, "occlum_pal_init");
    if (!occlum_pal_init) {
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlsym symbol occlum_pal_init failed.")
    }

    /* lookup symbol occlum_pal_create_process in libocclum-pal.so */
    int (*occlum_pal_create_process)(struct occlum_pal_create_process_args *args);
    occlum_pal_create_process = (int (*)(struct occlum_pal_create_process_args *))dlsym((void *)lib_occlum_pal_handle, "occlum_pal_create_process");
    if (!occlum_pal_create_process) {
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlsym symbol occlum_pal_create_process failed.")
    }

    // lookup symbol occlum_pal_exec in libocclum-pal.so
    int (*occlum_pal_exec)(struct occlum_pal_exec_args *args);
    occlum_pal_exec = (int (*)(struct occlum_pal_exec_args *))dlsym((void *)lib_occlum_pal_handle, "occlum_pal_exec");
    if (!occlum_pal_exec) {
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlsym symbol occlum_pal_exec failed.")
    }

    // parse occlum enclave log level.
    jstring log_level = parse_log_level(env, config);
    const char *log_level_str = (*env)->GetStringUTFChars(env, log_level, 0);
    const char *path_str = (path == 0) ? 0 : (*env)->GetStringUTFChars(env, path, 0);
    occlum_pal_attr_t pal_attr = OCCLUM_PAL_ATTR_INITVAL;
    pal_attr.instance_dir = path_str;
    pal_attr.log_level = log_level_str;
    if (occlum_pal_init(&pal_attr) < 0) {
        (*env)->ReleaseStringUTFChars(env, path, path_str);
        (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: occlum_pal_init failed.")
    }

    const char *cmd_path = OCCLUM_CMD_PATH;
    char *cmd_args[OCCLUM_CMD_ARGS_MAX_LENGTH] = {NULL};
    t_jvm_args jvm_args_record[OCCLUM_CMD_ARGS_MAX_LENGTH] = {NULL};

    // parse jvm args from user config file.
    cmd_args[0] = cmd_path;
    jobjectArray jvm_args = parse_jvm_cmd_args(env, config);
    jsize length = (*env)->GetArrayLength(env, jvm_args);
    if (length >= OCCLUM_CMD_ARGS_MAX_LENGTH) {
        (*env)->ReleaseStringUTFChars(env, path, path_str);
        (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: jvm args number exceeds max limitation 50.")
    }

    // parse jvm args and cache them in jvm_args_record for later release.
    int index = 0x0;
    for (; index < length; index++) {
        jvm_args_record[index].handler = (jstring)(*env)->GetObjectArrayElement(env, jvm_args, index);
        jvm_args_record[index].handler_str = (char *)(*env)->GetStringUTFChars(env, jvm_args_record[index].handler, 0);
        cmd_args[1+index] = jvm_args_record[index].handler_str;
    }
    // add cp path, main class name in cmd_args's tail.
    cmd_args[1+index++] = OCCLUM_JVM_CMD_CP;
    cmd_args[1+index++] = OCCLUM_JVM_CMD_JAR_PATH;
    cmd_args[1+index++] = OCCLUM_JVM_CMD_MAIN_CLASS;

    // add portHost number as java args.
    char port_host_buf[10];
    sprintf(port_host_buf, "%d", portHost);
    cmd_args[1+index++] = port_host_buf;

    // add portEnclave number as java args.
    char port_enclave_buf[10];
    sprintf(port_enclave_buf, "%d", portEnclave);
    cmd_args[1+index++] = port_enclave_buf;

    // add http thread pool size as java args.
    char thread_pool_size[10];
    sprintf(thread_pool_size, "%d", parse_http_handler_thread_pool_size(env, config));
    cmd_args[1+index] = thread_pool_size;

    struct occlum_stdio_fds io_fds = {
        .stdin_fd = STDIN_FILENO,
        .stdout_fd = STDOUT_FILENO,
        .stderr_fd = STDERR_FILENO,
    };

    // Use Occlum PAL to create new process
    int libos_tid = 0;
    struct occlum_pal_create_process_args create_process_args = {
        .path = cmd_path,
        .argv = cmd_args,
        .env = NULL,
        .stdio = (const struct occlum_stdio_fds *) &io_fds,
        .pid = &libos_tid,
    };
    if (occlum_pal_create_process(&create_process_args) < 0) {
        (*env)->ReleaseStringUTFChars(env, path, path_str);
        (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
        for (int i = 0x0; i < length; i++) {
            (*env)->ReleaseStringUTFChars(env, jvm_args_record[i].handler, jvm_args_record[i].handler_str);
        }
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: occlum_pal_create_process failed.")
    }

    // Use Occlum PAL to execute the cmd
    int exit_status = 0;
    struct occlum_pal_exec_args exec_args = {
        .pid = libos_tid,
        .exit_value = &exit_status,
    };
    // occlum_pal_exec will block until application run in occlum enclave exit.
    if (occlum_pal_exec(&exec_args) < 0) {
        (*env)->ReleaseStringUTFChars(env, path, path_str);
        (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
        for (int i = 0x0; i < length; i++) {
            (*env)->ReleaseStringUTFChars(env, jvm_args_record[i].handler, jvm_args_record[i].handler_str);
        }
        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: occlum_pal_exec failed.")
    }

    (*env)->ReleaseStringUTFChars(env, path, path_str);
    (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
    for (int i = 0x0; i < length; i++) {
        (*env)->ReleaseStringUTFChars(env, jvm_args_record[i].handler, jvm_args_record[i].handler_str);
    }
    return 0;
}