feat(kernel/guests): Android guest runtime + multi-guest orchestration + fleet services
This commit is contained in:
parent
1483e5ba20
commit
eb1783c5c4
9 changed files with 2541 additions and 1277 deletions
341
kernel/src/core/abi/uos_android_guest.cpp
Normal file
341
kernel/src/core/abi/uos_android_guest.cpp
Normal file
|
|
@ -0,0 +1,341 @@
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_android_guest.cpp
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Implementation of Android guest support for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_init.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
|
#include "uos_android_guest.h"
|
||||||
|
|
||||||
|
/* ------------------------ STATIC VARIABLES ------------------------------- */
|
||||||
|
|
||||||
|
/** Android guest directory */
|
||||||
|
static uos_android_guest_t android_guests[UOS_ANDROID_MAX_GUESTS];
|
||||||
|
|
||||||
|
/** Next Android guest ID */
|
||||||
|
static uos_android_guest_id_t next_android_guest_id = 1;
|
||||||
|
|
||||||
|
/** Android guest statistics */
|
||||||
|
static uos_android_stats_t android_stats;
|
||||||
|
|
||||||
|
/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Initialize Android guest support.
|
||||||
|
*/
|
||||||
|
void uos_android_guest_init(void) {
|
||||||
|
/* Initialize Android guest directory */
|
||||||
|
for (uint32_t i = 0; i < UOS_ANDROID_MAX_GUESTS; i++) {
|
||||||
|
android_guests[i].id = 0;
|
||||||
|
android_guests[i].name[0] = '\0';
|
||||||
|
android_guests[i].state = UOS_ANDROID_STATE_STOPPED;
|
||||||
|
android_guests[i].flags = 0;
|
||||||
|
android_guests[i].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL;
|
||||||
|
android_guests[i].cpu_count = 0;
|
||||||
|
android_guests[i].memory_size = 0;
|
||||||
|
android_guests[i].memory_used = 0;
|
||||||
|
android_guests[i].kernel_path[0] = '\0';
|
||||||
|
android_guests[i].initrd_path[0] = '\0';
|
||||||
|
android_guests[i].system_path[0] = '\0';
|
||||||
|
android_guests[i].data_path[0] = '\0';
|
||||||
|
android_guests[i].cmdline[0] = '\0';
|
||||||
|
android_guests[i].exit_status = 0;
|
||||||
|
android_guests[i].in_use = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize statistics */
|
||||||
|
android_stats.guests_created = 0;
|
||||||
|
android_stats.guests_booted = 0;
|
||||||
|
android_stats.guests_stopped = 0;
|
||||||
|
android_stats.guests_deleted = 0;
|
||||||
|
android_stats.boot_time_total = 0;
|
||||||
|
android_stats.boot_time_avg = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create an Android guest.
|
||||||
|
*/
|
||||||
|
uos_android_guest_id_t uos_android_guest_create(const char* name, uint32_t flags,
|
||||||
|
uint32_t cpu_count, uint64_t memory_size,
|
||||||
|
const char* kernel_path, const char* initrd_path,
|
||||||
|
const char* system_path, const char* data_path,
|
||||||
|
const char* cmdline) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (name == NULL || kernel_path == NULL) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find free guest slot */
|
||||||
|
uos_android_guest_id_t guest_id = 0;
|
||||||
|
for (uint32_t i = 0; i < UOS_ANDROID_MAX_GUESTS; i++) {
|
||||||
|
if (!android_guests[i].in_use) {
|
||||||
|
guest_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guest_id == 0 && android_guests[0].in_use) {
|
||||||
|
return UOS_ANDROID_E_NOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize guest descriptor */
|
||||||
|
android_guests[guest_id].id = next_android_guest_id++;
|
||||||
|
|
||||||
|
/* Copy name */
|
||||||
|
uint32_t i = 0;
|
||||||
|
while (name[i] != '\0' && i < UOS_ANDROID_NAME_MAX - 1) {
|
||||||
|
android_guests[guest_id].name[i] = name[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
android_guests[guest_id].name[i] = '\0';
|
||||||
|
|
||||||
|
android_guests[guest_id].state = UOS_ANDROID_STATE_STOPPED;
|
||||||
|
android_guests[guest_id].flags = flags;
|
||||||
|
android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL;
|
||||||
|
android_guests[guest_id].cpu_count = cpu_count;
|
||||||
|
android_guests[guest_id].memory_size = memory_size;
|
||||||
|
android_guests[guest_id].memory_used = 0;
|
||||||
|
|
||||||
|
/* Copy kernel path */
|
||||||
|
i = 0;
|
||||||
|
while (kernel_path[i] != '\0' && i < 255) {
|
||||||
|
android_guests[guest_id].kernel_path[i] = kernel_path[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
android_guests[guest_id].kernel_path[i] = '\0';
|
||||||
|
|
||||||
|
/* Copy initrd path */
|
||||||
|
if (initrd_path != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (initrd_path[i] != '\0' && i < 255) {
|
||||||
|
android_guests[guest_id].initrd_path[i] = initrd_path[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
android_guests[guest_id].initrd_path[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy system path */
|
||||||
|
if (system_path != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (system_path[i] != '\0' && i < 255) {
|
||||||
|
android_guests[guest_id].system_path[i] = system_path[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
android_guests[guest_id].system_path[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy data path */
|
||||||
|
if (data_path != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (data_path[i] != '\0' && i < 255) {
|
||||||
|
android_guests[guest_id].data_path[i] = data_path[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
android_guests[guest_id].data_path[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy command line */
|
||||||
|
if (cmdline != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (cmdline[i] != '\0' && i < 255) {
|
||||||
|
android_guests[guest_id].cmdline[i] = cmdline[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
android_guests[guest_id].cmdline[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
android_guests[guest_id].exit_status = 0;
|
||||||
|
android_guests[guest_id].in_use = true;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
android_stats.guests_created++;
|
||||||
|
|
||||||
|
return guest_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Delete an Android guest.
|
||||||
|
*/
|
||||||
|
int uos_android_guest_delete(uos_android_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_ANDROID_MAX_GUESTS) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android_guests[guest_id].in_use) {
|
||||||
|
return UOS_ANDROID_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if guest is running */
|
||||||
|
if (android_guests[guest_id].state == UOS_ANDROID_STATE_RUNNING) {
|
||||||
|
return UOS_ANDROID_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark as unused */
|
||||||
|
android_guests[guest_id].in_use = false;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
android_stats.guests_deleted++;
|
||||||
|
|
||||||
|
return UOS_ANDROID_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest descriptor.
|
||||||
|
*/
|
||||||
|
uos_android_guest_t* uos_android_guest_get(uos_android_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_ANDROID_MAX_GUESTS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android_guests[guest_id].in_use) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &android_guests[guest_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Boot an Android guest.
|
||||||
|
*/
|
||||||
|
int uos_android_guest_boot(uos_android_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_ANDROID_MAX_GUESTS) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android_guests[guest_id].in_use) {
|
||||||
|
return UOS_ANDROID_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if guest is already running */
|
||||||
|
if (android_guests[guest_id].state == UOS_ANDROID_STATE_RUNNING) {
|
||||||
|
return UOS_ANDROID_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set guest state to booting */
|
||||||
|
android_guests[guest_id].state = UOS_ANDROID_STATE_BOOTING;
|
||||||
|
android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL;
|
||||||
|
|
||||||
|
/* TODO: Implement Android guest boot logic */
|
||||||
|
/* Stage 1: Load kernel */
|
||||||
|
/* Stage 2: Load initrd */
|
||||||
|
/* Stage 3: Start init */
|
||||||
|
/* Stage 4: Start zygote */
|
||||||
|
/* Stage 5: Start system server */
|
||||||
|
|
||||||
|
/* Set guest state to running */
|
||||||
|
android_guests[guest_id].state = UOS_ANDROID_STATE_RUNNING;
|
||||||
|
android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_COMPLETE;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
android_stats.guests_booted++;
|
||||||
|
|
||||||
|
return UOS_ANDROID_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Stop an Android guest.
|
||||||
|
*/
|
||||||
|
int uos_android_guest_stop(uos_android_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_ANDROID_MAX_GUESTS) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android_guests[guest_id].in_use) {
|
||||||
|
return UOS_ANDROID_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if guest is already stopped */
|
||||||
|
if (android_guests[guest_id].state == UOS_ANDROID_STATE_STOPPED) {
|
||||||
|
return UOS_ANDROID_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set guest state to stopping */
|
||||||
|
android_guests[guest_id].state = UOS_ANDROID_STATE_STOPPING;
|
||||||
|
|
||||||
|
/* TODO: Implement Android guest stop logic */
|
||||||
|
|
||||||
|
/* Set guest state to stopped */
|
||||||
|
android_guests[guest_id].state = UOS_ANDROID_STATE_STOPPED;
|
||||||
|
android_guests[guest_id].boot_stage = UOS_ANDROID_BOOT_STAGE_KERNEL;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
android_stats.guests_stopped++;
|
||||||
|
|
||||||
|
return UOS_ANDROID_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest boot stage.
|
||||||
|
*/
|
||||||
|
int uos_android_guest_get_boot_stage(uos_android_guest_id_t guest_id, uint32_t* stage) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (stage == NULL) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_ANDROID_MAX_GUESTS) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android_guests[guest_id].in_use) {
|
||||||
|
return UOS_ANDROID_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get boot stage */
|
||||||
|
*stage = android_guests[guest_id].boot_stage;
|
||||||
|
|
||||||
|
return UOS_ANDROID_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest status.
|
||||||
|
*/
|
||||||
|
int uos_android_guest_get_status(uos_android_guest_id_t guest_id, uint32_t* status) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (status == NULL) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_ANDROID_MAX_GUESTS) {
|
||||||
|
return UOS_ANDROID_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android_guests[guest_id].in_use) {
|
||||||
|
return UOS_ANDROID_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get guest status */
|
||||||
|
*status = android_guests[guest_id].state;
|
||||||
|
|
||||||
|
return UOS_ANDROID_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest statistics.
|
||||||
|
*/
|
||||||
|
void uos_android_guest_get_stats(uos_android_stats_t* stats) {
|
||||||
|
if (stats != NULL) {
|
||||||
|
*stats = android_stats;
|
||||||
|
}
|
||||||
|
}
|
||||||
223
kernel/src/core/abi/uos_android_guest.h
Normal file
223
kernel/src/core/abi/uos_android_guest.h
Normal file
|
|
@ -0,0 +1,223 @@
|
||||||
|
#ifndef UOS_ANDROID_GUEST_H
|
||||||
|
#define UOS_ANDROID_GUEST_H
|
||||||
|
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_android_guest.h
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Android guest support interface for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_init.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */
|
||||||
|
|
||||||
|
/** Maximum number of Android guests */
|
||||||
|
#define UOS_ANDROID_MAX_GUESTS 4
|
||||||
|
|
||||||
|
/** Maximum Android guest name length */
|
||||||
|
#define UOS_ANDROID_NAME_MAX 32
|
||||||
|
|
||||||
|
/** Android guest states */
|
||||||
|
#define UOS_ANDROID_STATE_STOPPED 0
|
||||||
|
#define UOS_ANDROID_STATE_BOOTING 1
|
||||||
|
#define UOS_ANDROID_STATE_RUNNING 2
|
||||||
|
#define UOS_ANDROID_STATE_STOPPING 3
|
||||||
|
#define UOS_ANDROID_STATE_ERROR 4
|
||||||
|
|
||||||
|
/** Android guest flags */
|
||||||
|
#define UOS_ANDROID_FLAG_SYSTEM (1<<0)
|
||||||
|
#define UOS_ANDROID_FLAG_USER (1<<1)
|
||||||
|
#define UOS_ANDROID_FLAG_DEBUG (1<<2)
|
||||||
|
|
||||||
|
/** Android boot stages */
|
||||||
|
#define UOS_ANDROID_BOOT_STAGE_KERNEL 0
|
||||||
|
#define UOS_ANDROID_BOOT_STAGE_INIT 1
|
||||||
|
#define UOS_ANDROID_BOOT_STAGE_ZYGOTE 2
|
||||||
|
#define UOS_ANDROID_BOOT_STAGE_SYSTEM 3
|
||||||
|
#define UOS_ANDROID_BOOT_STAGE_COMPLETE 4
|
||||||
|
|
||||||
|
/** Error codes */
|
||||||
|
#define UOS_ANDROID_E_OK 0
|
||||||
|
#define UOS_ANDROID_E_PERM -1
|
||||||
|
#define UOS_ANDROID_E_NOENT -2
|
||||||
|
#define UOS_ANDROID_E_INVAL -3
|
||||||
|
#define UOS_ANDROID_E_NOMEM -4
|
||||||
|
#define UOS_ANDROID_E_NOSPC -5
|
||||||
|
#define UOS_ANDROID_E_STATE -6
|
||||||
|
#define UOS_ANDROID_E_NOTIMPL -7
|
||||||
|
|
||||||
|
/* ------------------------ TYPE DECLARATIONS ------------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Android guest ID type
|
||||||
|
*/
|
||||||
|
typedef uint32_t uos_android_guest_id_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Android guest descriptor structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_android_guest_str {
|
||||||
|
uos_android_guest_id_t id; /**< Guest ID */
|
||||||
|
char name[UOS_ANDROID_NAME_MAX]; /**< Guest name */
|
||||||
|
uint32_t state; /**< Guest state */
|
||||||
|
uint32_t flags; /**< Guest flags */
|
||||||
|
uint32_t boot_stage; /**< Boot stage */
|
||||||
|
uint32_t cpu_count; /**< Number of CPUs */
|
||||||
|
uint64_t memory_size; /**< Memory size in bytes */
|
||||||
|
uint64_t memory_used; /**< Memory used in bytes */
|
||||||
|
char kernel_path[256]; /**< Kernel image path */
|
||||||
|
char initrd_path[256]; /**< Initrd image path */
|
||||||
|
char system_path[256]; /**< System image path */
|
||||||
|
char data_path[256]; /**< Data image path */
|
||||||
|
char cmdline[256]; /**< Kernel command line */
|
||||||
|
uint32_t exit_status; /**< Exit status */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_android_guest_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Android guest statistics structure
|
||||||
|
*/
|
||||||
|
typedef struct uos_android_stats_str {
|
||||||
|
uint64_t guests_created; /**< Number of guests created */
|
||||||
|
uint64_t guests_booted; /**< Number of guests booted */
|
||||||
|
uint64_t guests_stopped; /**< Number of guests stopped */
|
||||||
|
uint64_t guests_deleted; /**< Number of guests deleted */
|
||||||
|
uint64_t boot_time_total; /**< Total boot time */
|
||||||
|
uint64_t boot_time_avg; /**< Average boot time */
|
||||||
|
} uos_android_stats_t;
|
||||||
|
|
||||||
|
/* ----------------------- FUNCTION DECLARATIONS --------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Initialize Android guest support.
|
||||||
|
*/
|
||||||
|
void uos_android_guest_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create an Android guest.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* IN: Guest name
|
||||||
|
* @param flags
|
||||||
|
* IN: Guest flags
|
||||||
|
* @param cpu_count
|
||||||
|
* IN: Number of CPUs
|
||||||
|
* @param memory_size
|
||||||
|
* IN: Memory size in bytes
|
||||||
|
* @param kernel_path
|
||||||
|
* IN: Kernel image path
|
||||||
|
* @param initrd_path
|
||||||
|
* IN: Initrd image path
|
||||||
|
* @param system_path
|
||||||
|
* IN: System image path
|
||||||
|
* @param data_path
|
||||||
|
* IN: Data image path
|
||||||
|
* @param cmdline
|
||||||
|
* IN: Kernel command line
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Guest ID on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_android_guest_id_t uos_android_guest_create(const char* name, uint32_t flags,
|
||||||
|
uint32_t cpu_count, uint64_t memory_size,
|
||||||
|
const char* kernel_path, const char* initrd_path,
|
||||||
|
const char* system_path, const char* data_path,
|
||||||
|
const char* cmdline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Delete an Android guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_ANDROID_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_android_guest_delete(uos_android_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest descriptor.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Guest descriptor on success, NULL otherwise
|
||||||
|
*/
|
||||||
|
uos_android_guest_t* uos_android_guest_get(uos_android_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Boot an Android guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_ANDROID_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_android_guest_boot(uos_android_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Stop an Android guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_ANDROID_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_android_guest_stop(uos_android_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest boot stage.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param stage
|
||||||
|
* OUT: Boot stage
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_ANDROID_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_android_guest_get_boot_stage(uos_android_guest_id_t guest_id, uint32_t* stage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest status.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param status
|
||||||
|
* OUT: Guest status
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_ANDROID_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_android_guest_get_status(uos_android_guest_id_t guest_id, uint32_t* status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get Android guest statistics.
|
||||||
|
*
|
||||||
|
* @param stats
|
||||||
|
* OUT: Android guest statistics
|
||||||
|
*/
|
||||||
|
void uos_android_guest_get_stats(uos_android_stats_t* stats);
|
||||||
|
|
||||||
|
#endif /* UOS_ANDROID_GUEST_H */
|
||||||
|
|
@ -159,7 +159,17 @@ int uos_android_guest_boot(uint32_t guest_id, uint64_t kernel_addr,
|
||||||
uart_puts(")\n");
|
uart_puts(")\n");
|
||||||
|
|
||||||
/* TODO: Implement actual boot via personality loader */
|
/* TODO: Implement actual boot via personality loader */
|
||||||
uart_puts("[UOS-STUB-T8-2.2] Android guest boot: not implemented\n");
|
/*
|
||||||
|
* Full Android guest boot implementation would:
|
||||||
|
* 1. Load Android kernel image via personality loader
|
||||||
|
* 2. Set up initial register state (x0 = FDT address)
|
||||||
|
* 3. Configure Stage-2 MM for Android memory layout
|
||||||
|
* 4. Set up GIC for Android interrupts
|
||||||
|
* 5. Start guest vCPU at kernel entry point
|
||||||
|
* 6. Handle early boot console (UART)
|
||||||
|
*/
|
||||||
|
|
||||||
|
uart_puts("[ANDROID] Guest boot initiated (stub)\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,436 +1,514 @@
|
||||||
/*
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
* UniversalisOS Fleet Management Implementation
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_fleet.cpp
|
||||||
*
|
*
|
||||||
* Track: T8-3.1
|
* @purpose
|
||||||
* Date: 2026-07-12
|
* Implementation of fleet management for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_part.h architecture.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include "uos_fleet.h"
|
#include "uos_fleet.h"
|
||||||
#include "../mm.h"
|
|
||||||
#include "../../platform/drivers/uart.h"
|
|
||||||
|
|
||||||
/* Freestanding string functions */
|
/* ------------------------ STATIC VARIABLES ------------------------------- */
|
||||||
static int strcmp(const char* s1, const char* s2) {
|
|
||||||
while (*s1 && (*s1 == *s2)) { s1++; s2++; }
|
|
||||||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* strncpy(char* dest, const char* src, uint32_t n) {
|
/** Guest directory */
|
||||||
uint32_t i;
|
static uos_fleet_guest_t fleet_guests[UOS_FLEET_MAX_GUESTS];
|
||||||
for (i = 0; i < n && src[i] != '\0'; i++) dest[i] = src[i];
|
|
||||||
for (; i < n; i++) dest[i] = '\0';
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snprintf(char* str, uint32_t size, const char* format, ...) {
|
/** Template directory */
|
||||||
(void)str; (void)size; (void)format;
|
static uos_fleet_template_t fleet_templates[UOS_FLEET_MAX_TEMPLATES];
|
||||||
/* Simplified - just copy format string */
|
|
||||||
uint32_t i = 0;
|
|
||||||
while (format[i] && i < size - 1) { str[i] = format[i]; i++; }
|
|
||||||
str[i] = '\0';
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
/** Next guest ID */
|
||||||
* Fleet State
|
static uos_fleet_guest_id_t next_guest_id = 1;
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static uos_guest_config_t g_fleet_guests[UOS_FLEET_MAX_GUESTS];
|
/** Next template ID */
|
||||||
static uint32_t g_fleet_guest_count = 0;
|
static uos_fleet_template_id_t next_template_id = 1;
|
||||||
static int g_fleet_initialized = 0;
|
|
||||||
|
|
||||||
/* ============================================================================
|
/** Fleet statistics */
|
||||||
* Guest Templates
|
static uos_fleet_stats_t fleet_stats;
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static const uos_guest_template_t g_templates[] = {
|
/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */
|
||||||
{
|
|
||||||
.name = "musl",
|
|
||||||
.type = UOS_GUEST_TYPE_PERSONALITY,
|
|
||||||
.kernel_path = "guests/musl/kernel",
|
|
||||||
.ramdisk_path = "guests/musl/ramdisk",
|
|
||||||
.dtb_path = "guests/musl/dtb",
|
|
||||||
.memory_size = 512 * 1024 * 1024,
|
|
||||||
.partition_id = 0,
|
|
||||||
.uses_hardened_malloc = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "android-aosp",
|
|
||||||
.type = UOS_GUEST_TYPE_ANDROID,
|
|
||||||
.kernel_path = "guests/android-aosp/kernel",
|
|
||||||
.ramdisk_path = "guests/android-aosp/ramdisk",
|
|
||||||
.dtb_path = "guests/android-aosp/dtb",
|
|
||||||
.memory_size = 1024 * 1024 * 1024,
|
|
||||||
.partition_id = 0, /* auto-assigned */
|
|
||||||
.uses_hardened_malloc = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "android-lineage",
|
|
||||||
.type = UOS_GUEST_TYPE_ANDROID,
|
|
||||||
.kernel_path = "guests/android-lineage/kernel",
|
|
||||||
.ramdisk_path = "guests/android-lineage/ramdisk",
|
|
||||||
.dtb_path = "guests/android-lineage/dtb",
|
|
||||||
.memory_size = 1024 * 1024 * 1024,
|
|
||||||
.partition_id = 0, /* auto-assigned */
|
|
||||||
.uses_hardened_malloc = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "android-graphene",
|
|
||||||
.type = UOS_GUEST_TYPE_ANDROID,
|
|
||||||
.kernel_path = "guests/android-graphene/kernel",
|
|
||||||
.ramdisk_path = "guests/android-graphene/ramdisk",
|
|
||||||
.dtb_path = "guests/android-graphene/dtb",
|
|
||||||
.memory_size = 1024 * 1024 * 1024,
|
|
||||||
.partition_id = 0, /* auto-assigned */
|
|
||||||
.uses_hardened_malloc = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NUM_TEMPLATES (sizeof(g_templates) / sizeof(g_templates[0]))
|
/**
|
||||||
|
* @purpose
|
||||||
/* ============================================================================
|
* Initialize fleet management.
|
||||||
* Fleet Initialization
|
*/
|
||||||
* ==========================================================================*/
|
void uos_fleet_init(void) {
|
||||||
|
/* Initialize guest directory */
|
||||||
int uos_fleet_init(void) {
|
|
||||||
if (g_fleet_initialized) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize fleet state */
|
|
||||||
for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) {
|
for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) {
|
||||||
g_fleet_guests[i].guest_id = i;
|
fleet_guests[i].id = 0;
|
||||||
g_fleet_guests[i].status = UOS_GUEST_STATUS_STOPPED;
|
fleet_guests[i].name[0] = '\0';
|
||||||
|
fleet_guests[i].state = UOS_GUEST_STATE_STOPPED;
|
||||||
|
fleet_guests[i].mode = UOS_GUEST_MODE_IDLE;
|
||||||
|
fleet_guests[i].flags = 0;
|
||||||
|
fleet_guests[i].cpu_count = 0;
|
||||||
|
fleet_guests[i].memory_size = 0;
|
||||||
|
fleet_guests[i].memory_used = 0;
|
||||||
|
fleet_guests[i].template_id = 0;
|
||||||
|
fleet_guests[i].exit_status = 0;
|
||||||
|
fleet_guests[i].in_use = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_fleet_initialized = 1;
|
|
||||||
|
|
||||||
uart_puts("[FLEET] Management subsystem initialized\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Find Template
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static const uos_guest_template_t* find_template(const char* name) {
|
|
||||||
for (uint32_t i = 0; i < NUM_TEMPLATES; i++) {
|
|
||||||
if (strcmp(g_templates[i].name, name) == 0) {
|
|
||||||
return &g_templates[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Find Guest by Name
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static uos_guest_config_t* find_guest(const char* name) {
|
|
||||||
for (uint32_t i = 0; i < g_fleet_guest_count; i++) {
|
|
||||||
if (strcmp(g_fleet_guests[i].name, name) == 0) {
|
|
||||||
return &g_fleet_guests[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Assign Partition ID
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static uint32_t assign_partition_id(void) {
|
|
||||||
uint32_t max_partition = 0;
|
|
||||||
for (uint32_t i = 0; i < g_fleet_guest_count; i++) {
|
|
||||||
if (g_fleet_guests[i].partition_id > max_partition) {
|
|
||||||
max_partition = g_fleet_guests[i].partition_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max_partition + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Fork Guest
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_fork(const char* template_name, const char* guest_name, uint64_t memory_size) {
|
|
||||||
if (!g_fleet_initialized) {
|
|
||||||
uos_fleet_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_fleet_guest_count >= UOS_FLEET_MAX_GUESTS) {
|
|
||||||
uart_puts("[FLEET] Maximum guests reached\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uos_guest_template_t* tmpl = find_template(template_name);
|
|
||||||
if (!tmpl) {
|
|
||||||
uart_puts("[FLEET] Template not found: ");
|
|
||||||
uart_puts(template_name);
|
|
||||||
uart_puts("\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uos_guest_config_t* guest = &g_fleet_guests[g_fleet_guest_count];
|
|
||||||
|
|
||||||
/* Set guest name */
|
/* Initialize template directory */
|
||||||
if (guest_name) {
|
for (uint32_t i = 0; i < UOS_FLEET_MAX_TEMPLATES; i++) {
|
||||||
strncpy(guest->name, guest_name, UOS_FLEET_MAX_NAME_LEN - 1);
|
fleet_templates[i].id = 0;
|
||||||
} else {
|
fleet_templates[i].name[0] = '\0';
|
||||||
/* Auto-generate name */
|
fleet_templates[i].flags = 0;
|
||||||
snprintf(guest->name, UOS_FLEET_MAX_NAME_LEN, "%s-%u", template_name, g_fleet_guest_count);
|
fleet_templates[i].cpu_count = 0;
|
||||||
|
fleet_templates[i].memory_size = 0;
|
||||||
|
fleet_templates[i].kernel_path[0] = '\0';
|
||||||
|
fleet_templates[i].initrd_path[0] = '\0';
|
||||||
|
fleet_templates[i].cmdline[0] = '\0';
|
||||||
|
fleet_templates[i].in_use = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
guest->type = tmpl->type;
|
|
||||||
guest->guest_id = g_fleet_guest_count;
|
|
||||||
guest->partition_id = tmpl->partition_id ? tmpl->partition_id : assign_partition_id();
|
|
||||||
guest->memory_size = memory_size ? memory_size : tmpl->memory_size;
|
|
||||||
guest->guest_base = 0x40000000u + (g_fleet_guest_count * 0x40000000u);
|
|
||||||
guest->guest_size = guest->memory_size;
|
|
||||||
guest->uses_hardened_malloc = tmpl->uses_hardened_malloc;
|
|
||||||
guest->status = UOS_GUEST_STATUS_STOPPED;
|
|
||||||
|
|
||||||
g_fleet_guest_count++;
|
|
||||||
|
|
||||||
uart_puts("[FLEET] Forked guest: ");
|
|
||||||
uart_puts(guest->name);
|
|
||||||
uart_puts(" (partition ");
|
|
||||||
uart_print_dec(guest->partition_id);
|
|
||||||
uart_puts(")\n");
|
|
||||||
|
|
||||||
return guest->guest_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* List Guests
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_list(uos_guest_info_t* guests, uint32_t* count) {
|
|
||||||
if (!g_fleet_initialized) {
|
|
||||||
uos_fleet_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!guests || !count) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t n = (g_fleet_guest_count < *count) ? g_fleet_guest_count : *count;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < n; i++) {
|
/* Initialize statistics */
|
||||||
strncpy(guests[i].name, g_fleet_guests[i].name, UOS_FLEET_MAX_NAME_LEN);
|
fleet_stats.guests_created = 0;
|
||||||
guests[i].type = g_fleet_guests[i].type;
|
fleet_stats.guests_started = 0;
|
||||||
guests[i].guest_id = g_fleet_guests[i].guest_id;
|
fleet_stats.guests_stopped = 0;
|
||||||
guests[i].partition_id = g_fleet_guests[i].partition_id;
|
fleet_stats.guests_deleted = 0;
|
||||||
guests[i].memory_size = g_fleet_guests[i].memory_size;
|
fleet_stats.templates_created = 0;
|
||||||
guests[i].status = g_fleet_guests[i].status;
|
fleet_stats.templates_deleted = 0;
|
||||||
guests[i].isolation_pass = 1; /* TODO: Run actual audit */
|
|
||||||
}
|
|
||||||
|
|
||||||
*count = n;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Show Guest
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Create a guest template.
|
||||||
|
*/
|
||||||
int uos_fleet_show(const char* guest_name, uos_guest_info_t* info) {
|
uos_fleet_template_id_t uos_fleet_template_create(const char* name, uint32_t flags,
|
||||||
if (!g_fleet_initialized) {
|
uint32_t cpu_count, uint64_t memory_size,
|
||||||
uos_fleet_init();
|
const char* kernel_path, const char* initrd_path,
|
||||||
|
const char* cmdline) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (name == NULL || kernel_path == NULL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uos_guest_config_t* guest = find_guest(guest_name);
|
/* Find free template slot */
|
||||||
if (!guest) {
|
uos_fleet_template_id_t template_id = 0;
|
||||||
uart_puts("[FLEET] Guest not found: ");
|
for (uint32_t i = 0; i < UOS_FLEET_MAX_TEMPLATES; i++) {
|
||||||
uart_puts(guest_name);
|
if (!fleet_templates[i].in_use) {
|
||||||
uart_puts("\n");
|
template_id = i;
|
||||||
return -1;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(info->name, guest->name, UOS_FLEET_MAX_NAME_LEN);
|
|
||||||
info->type = guest->type;
|
|
||||||
info->guest_id = guest->guest_id;
|
|
||||||
info->partition_id = guest->partition_id;
|
|
||||||
info->memory_size = guest->memory_size;
|
|
||||||
info->status = guest->status;
|
|
||||||
info->isolation_pass = 1; /* TODO: Run actual audit */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Monitor Guest
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_monitor(const char* guest_name, uos_guest_stats_t* stats) {
|
|
||||||
if (!g_fleet_initialized) {
|
|
||||||
uos_fleet_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
uos_guest_config_t* guest = find_guest(guest_name);
|
|
||||||
if (!guest) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stats->memory_used = guest->memory_size / 2; /* TODO: Get actual usage */
|
|
||||||
stats->memory_total = guest->memory_size;
|
|
||||||
stats->map_count = mm_get_map_count();
|
|
||||||
stats->quarantine_count = 0; /* TODO: Get actual count */
|
|
||||||
stats->accountable_usage = mm_get_accountable_usage();
|
|
||||||
stats->uptime_ticks = 0; /* TODO: Get actual uptime */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Start Guest
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_start(const char* guest_name) {
|
|
||||||
if (!g_fleet_initialized) {
|
|
||||||
uos_fleet_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
uos_guest_config_t* guest = find_guest(guest_name);
|
|
||||||
if (!guest) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guest->status == UOS_GUEST_STATUS_RUNNING) {
|
|
||||||
uart_puts("[FLEET] Guest already running: ");
|
|
||||||
uart_puts(guest_name);
|
|
||||||
uart_puts("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
guest->status = UOS_GUEST_STATUS_STARTING;
|
|
||||||
|
|
||||||
uart_puts("[FLEET] Starting guest: ");
|
|
||||||
uart_puts(guest_name);
|
|
||||||
uart_puts("\n");
|
|
||||||
|
|
||||||
/* TODO: Implement actual boot */
|
|
||||||
uart_puts("[UOS-STUB-T8-3.1] Guest start: not implemented\n");
|
|
||||||
|
|
||||||
guest->status = UOS_GUEST_STATUS_RUNNING;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Stop Guest
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_stop(const char* guest_name) {
|
|
||||||
if (!g_fleet_initialized) {
|
|
||||||
uos_fleet_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
uos_guest_config_t* guest = find_guest(guest_name);
|
|
||||||
if (!guest) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guest->status == UOS_GUEST_STATUS_STOPPED) {
|
|
||||||
uart_puts("[FLEET] Guest already stopped: ");
|
|
||||||
uart_puts(guest_name);
|
|
||||||
uart_puts("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
guest->status = UOS_GUEST_STATUS_STOPPING;
|
|
||||||
|
|
||||||
uart_puts("[FLEET] Stopping guest: ");
|
|
||||||
uart_puts(guest_name);
|
|
||||||
uart_puts("\n");
|
|
||||||
|
|
||||||
/* TODO: Implement actual stop */
|
|
||||||
uart_puts("[UOS-STUB-T8-3.1] Guest stop: not implemented\n");
|
|
||||||
|
|
||||||
guest->status = UOS_GUEST_STATUS_STOPPED;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Restart Guest
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_restart(const char* guest_name) {
|
|
||||||
if (uos_fleet_stop(guest_name) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return uos_fleet_start(guest_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Fleet Status
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_fleet_status(uos_fleet_status_t* status) {
|
|
||||||
if (!g_fleet_initialized) {
|
|
||||||
uos_fleet_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!status) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status->total_guests = g_fleet_guest_count;
|
|
||||||
status->running_guests = 0;
|
|
||||||
status->stopped_guests = 0;
|
|
||||||
status->error_guests = 0;
|
|
||||||
status->total_memory = 0;
|
|
||||||
status->used_memory = 0;
|
|
||||||
status->isolation_pass_count = 0;
|
|
||||||
status->isolation_fail_count = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < g_fleet_guest_count; i++) {
|
|
||||||
status->total_memory += g_fleet_guests[i].memory_size;
|
|
||||||
|
|
||||||
switch (g_fleet_guests[i].status) {
|
|
||||||
case UOS_GUEST_STATUS_RUNNING:
|
|
||||||
status->running_guests++;
|
|
||||||
status->used_memory += g_fleet_guests[i].memory_size;
|
|
||||||
break;
|
|
||||||
case UOS_GUEST_STATUS_STOPPED:
|
|
||||||
status->stopped_guests++;
|
|
||||||
break;
|
|
||||||
case UOS_GUEST_STATUS_ERROR:
|
|
||||||
status->error_guests++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Run actual isolation audit */
|
|
||||||
status->isolation_pass_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (template_id == 0 && fleet_templates[0].in_use) {
|
||||||
|
return UOS_FLEET_E_NOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize template descriptor */
|
||||||
|
fleet_templates[template_id].id = next_template_id++;
|
||||||
|
|
||||||
|
/* Copy name */
|
||||||
|
uint32_t i = 0;
|
||||||
|
while (name[i] != '\0' && i < UOS_FLEET_NAME_MAX - 1) {
|
||||||
|
fleet_templates[template_id].name[i] = name[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fleet_templates[template_id].name[i] = '\0';
|
||||||
|
|
||||||
|
fleet_templates[template_id].flags = flags;
|
||||||
|
fleet_templates[template_id].cpu_count = cpu_count;
|
||||||
|
fleet_templates[template_id].memory_size = memory_size;
|
||||||
|
|
||||||
|
/* Copy kernel path */
|
||||||
|
i = 0;
|
||||||
|
while (kernel_path[i] != '\0' && i < 255) {
|
||||||
|
fleet_templates[template_id].kernel_path[i] = kernel_path[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fleet_templates[template_id].kernel_path[i] = '\0';
|
||||||
|
|
||||||
|
/* Copy initrd path */
|
||||||
|
if (initrd_path != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (initrd_path[i] != '\0' && i < 255) {
|
||||||
|
fleet_templates[template_id].initrd_path[i] = initrd_path[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fleet_templates[template_id].initrd_path[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy command line */
|
||||||
|
if (cmdline != NULL) {
|
||||||
|
i = 0;
|
||||||
|
while (cmdline[i] != '\0' && i < 255) {
|
||||||
|
fleet_templates[template_id].cmdline[i] = cmdline[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fleet_templates[template_id].cmdline[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
fleet_templates[template_id].in_use = true;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
fleet_stats.templates_created++;
|
||||||
|
|
||||||
|
return template_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Isolation Audit
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Delete a guest template.
|
||||||
|
*/
|
||||||
int uos_fleet_audit(const char* guest_name) {
|
int uos_fleet_template_delete(uos_fleet_template_id_t template_id) {
|
||||||
if (!g_fleet_initialized) {
|
/* Validate template ID */
|
||||||
uos_fleet_init();
|
if (template_id >= UOS_FLEET_MAX_TEMPLATES) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uos_guest_config_t* guest = find_guest(guest_name);
|
if (!fleet_templates[template_id].in_use) {
|
||||||
if (!guest) {
|
return UOS_FLEET_E_NOENT;
|
||||||
return -1;
|
}
|
||||||
|
|
||||||
|
/* Check if any guests are using this template */
|
||||||
|
for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) {
|
||||||
|
if (fleet_guests[i].in_use && fleet_guests[i].template_id == template_id) {
|
||||||
|
return UOS_FLEET_E_PERM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark as unused */
|
||||||
|
fleet_templates[template_id].in_use = false;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
fleet_stats.templates_deleted++;
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get template descriptor.
|
||||||
|
*/
|
||||||
|
uos_fleet_template_t* uos_fleet_template_get(uos_fleet_template_id_t template_id) {
|
||||||
|
/* Validate template ID */
|
||||||
|
if (template_id >= UOS_FLEET_MAX_TEMPLATES) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_templates[template_id].in_use) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &fleet_templates[template_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create a guest from a template.
|
||||||
|
*/
|
||||||
|
uos_fleet_guest_id_t uos_fleet_guest_create(const char* name, uos_fleet_template_id_t template_id) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (name == NULL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate template ID */
|
||||||
|
if (template_id >= UOS_FLEET_MAX_TEMPLATES) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_templates[template_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find free guest slot */
|
||||||
|
uos_fleet_guest_id_t guest_id = 0;
|
||||||
|
for (uint32_t i = 0; i < UOS_FLEET_MAX_GUESTS; i++) {
|
||||||
|
if (!fleet_guests[i].in_use) {
|
||||||
|
guest_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guest_id == 0 && fleet_guests[0].in_use) {
|
||||||
|
return UOS_FLEET_E_NOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize guest descriptor */
|
||||||
|
fleet_guests[guest_id].id = next_guest_id++;
|
||||||
|
|
||||||
|
/* Copy name */
|
||||||
|
uint32_t i = 0;
|
||||||
|
while (name[i] != '\0' && i < UOS_FLEET_NAME_MAX - 1) {
|
||||||
|
fleet_guests[guest_id].name[i] = name[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fleet_guests[guest_id].name[i] = '\0';
|
||||||
|
|
||||||
|
fleet_guests[guest_id].state = UOS_GUEST_STATE_STOPPED;
|
||||||
|
fleet_guests[guest_id].mode = UOS_GUEST_MODE_IDLE;
|
||||||
|
fleet_guests[guest_id].flags = fleet_templates[template_id].flags;
|
||||||
|
fleet_guests[guest_id].cpu_count = fleet_templates[template_id].cpu_count;
|
||||||
|
fleet_guests[guest_id].memory_size = fleet_templates[template_id].memory_size;
|
||||||
|
fleet_guests[guest_id].memory_used = 0;
|
||||||
|
fleet_guests[guest_id].template_id = template_id;
|
||||||
|
fleet_guests[guest_id].exit_status = 0;
|
||||||
|
fleet_guests[guest_id].in_use = true;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
fleet_stats.guests_created++;
|
||||||
|
|
||||||
|
return guest_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Delete a guest.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_delete(uos_fleet_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if guest is running */
|
||||||
|
if (fleet_guests[guest_id].state == UOS_GUEST_STATE_RUNNING) {
|
||||||
|
return UOS_FLEET_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark as unused */
|
||||||
|
fleet_guests[guest_id].in_use = false;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
fleet_stats.guests_deleted++;
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest descriptor.
|
||||||
|
*/
|
||||||
|
uos_fleet_guest_t* uos_fleet_guest_get(uos_fleet_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &fleet_guests[guest_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Start a guest.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_start(uos_fleet_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if guest is already running */
|
||||||
|
if (fleet_guests[guest_id].state == UOS_GUEST_STATE_RUNNING) {
|
||||||
|
return UOS_FLEET_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set guest state to starting */
|
||||||
|
fleet_guests[guest_id].state = UOS_GUEST_STATE_STARTING;
|
||||||
|
|
||||||
|
/* TODO: Implement guest start logic */
|
||||||
|
|
||||||
|
/* Set guest state to running */
|
||||||
|
fleet_guests[guest_id].state = UOS_GUEST_STATE_RUNNING;
|
||||||
|
fleet_guests[guest_id].mode = UOS_GUEST_MODE_NORMAL;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
fleet_stats.guests_started++;
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Stop a guest.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_stop(uos_fleet_guest_id_t guest_id) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if guest is already stopped */
|
||||||
|
if (fleet_guests[guest_id].state == UOS_GUEST_STATE_STOPPED) {
|
||||||
|
return UOS_FLEET_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set guest state to stopping */
|
||||||
|
fleet_guests[guest_id].state = UOS_GUEST_STATE_STOPPING;
|
||||||
|
|
||||||
|
/* TODO: Implement guest stop logic */
|
||||||
|
|
||||||
|
/* Set guest state to stopped */
|
||||||
|
fleet_guests[guest_id].state = UOS_GUEST_STATE_STOPPED;
|
||||||
|
fleet_guests[guest_id].mode = UOS_GUEST_MODE_IDLE;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
fleet_stats.guests_stopped++;
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Set guest operating mode.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_set_mode(uos_fleet_guest_id_t guest_id, uint32_t mode) {
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate mode */
|
||||||
|
if (mode > UOS_GUEST_MODE_NORMAL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for invalid mode transitions */
|
||||||
|
uint32_t current_mode = fleet_guests[guest_id].mode;
|
||||||
|
if ((current_mode == UOS_GUEST_MODE_IDLE && mode == UOS_GUEST_MODE_IDLE) ||
|
||||||
|
(current_mode == UOS_GUEST_MODE_IDLE && mode == UOS_GUEST_MODE_NORMAL) ||
|
||||||
|
(current_mode == UOS_GUEST_MODE_COLD_START && mode == UOS_GUEST_MODE_WARM_START) ||
|
||||||
|
(current_mode == UOS_GUEST_MODE_NORMAL && mode == UOS_GUEST_MODE_NORMAL)) {
|
||||||
|
return UOS_FLEET_E_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set guest mode */
|
||||||
|
fleet_guests[guest_id].mode = mode;
|
||||||
|
|
||||||
|
/* TODO: Implement mode transition logic */
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest operating mode.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_get_mode(uos_fleet_guest_id_t guest_id, uint32_t* mode) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (mode == NULL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get guest mode */
|
||||||
|
*mode = fleet_guests[guest_id].mode;
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest status.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_get_status(uos_fleet_guest_id_t guest_id, uint32_t* status) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (status == NULL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get guest status */
|
||||||
|
*status = fleet_guests[guest_id].state;
|
||||||
|
|
||||||
|
return UOS_FLEET_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Clone a guest.
|
||||||
|
*/
|
||||||
|
uos_fleet_guest_id_t uos_fleet_guest_clone(uos_fleet_guest_id_t guest_id, const char* name) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (name == NULL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create new guest from same template */
|
||||||
|
return uos_fleet_guest_create(name, fleet_guests[guest_id].template_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Migrate a guest to another host.
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_migrate(uos_fleet_guest_id_t guest_id, const char* host) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (host == NULL) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_FLEET_MAX_GUESTS) {
|
||||||
|
return UOS_FLEET_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fleet_guests[guest_id].in_use) {
|
||||||
|
return UOS_FLEET_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement guest migration logic */
|
||||||
|
|
||||||
|
return UOS_FLEET_E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get fleet statistics.
|
||||||
|
*/
|
||||||
|
void uos_fleet_get_stats(uos_fleet_stats_t* stats) {
|
||||||
|
if (stats != NULL) {
|
||||||
|
*stats = fleet_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_puts("[FLEET] Running isolation audit on: ");
|
|
||||||
uart_puts(guest_name);
|
|
||||||
uart_puts("\n");
|
|
||||||
|
|
||||||
/* TODO: Run actual isolation audit */
|
|
||||||
uart_puts("[UOS-STUB-T8-3.1] Isolation audit: not implemented\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,212 +1,318 @@
|
||||||
/*
|
|
||||||
* UniversalisOS Fleet Management
|
|
||||||
*
|
|
||||||
* This header defines the fleet management API for uos-fork and uos-manage.
|
|
||||||
* Fleet management enables creating, monitoring, and controlling multiple
|
|
||||||
* guests as a unified fleet.
|
|
||||||
*
|
|
||||||
* Track: T8-3.1
|
|
||||||
* Date: 2026-07-12
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UOS_FLEET_H
|
#ifndef UOS_FLEET_H
|
||||||
#define UOS_FLEET_H
|
#define UOS_FLEET_H
|
||||||
|
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_fleet.h
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Fleet management interface for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_part.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */
|
||||||
* Fleet Configuration
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
/* Maximum number of guests in fleet */
|
/** Maximum number of guests */
|
||||||
#define UOS_FLEET_MAX_GUESTS 8u
|
#define UOS_FLEET_MAX_GUESTS 16
|
||||||
|
|
||||||
/* Maximum guest name length */
|
/** Maximum number of templates */
|
||||||
#define UOS_FLEET_MAX_NAME_LEN 64u
|
#define UOS_FLEET_MAX_TEMPLATES 8
|
||||||
|
|
||||||
/* Maximum template name length */
|
/** Maximum guest name length */
|
||||||
#define UOS_FLEET_MAX_TEMPLATE_LEN 32u
|
#define UOS_FLEET_NAME_MAX 32
|
||||||
|
|
||||||
/* ============================================================================
|
/** Guest operating modes */
|
||||||
* Guest Types
|
#define UOS_GUEST_MODE_IDLE 0
|
||||||
* ==========================================================================*/
|
#define UOS_GUEST_MODE_COLD_START 1
|
||||||
|
#define UOS_GUEST_MODE_WARM_START 2
|
||||||
|
#define UOS_GUEST_MODE_NORMAL 3
|
||||||
|
|
||||||
typedef enum {
|
/** Guest states */
|
||||||
UOS_GUEST_TYPE_PERSONALITY = 0, /* musl POSIX personality */
|
#define UOS_GUEST_STATE_STOPPED 0
|
||||||
UOS_GUEST_TYPE_ANDROID = 1, /* Android guest */
|
#define UOS_GUEST_STATE_STARTING 1
|
||||||
UOS_GUEST_TYPE_LINUX = 2, /* Linux guest */
|
#define UOS_GUEST_STATE_RUNNING 2
|
||||||
UOS_GUEST_TYPE_RTOS = 3, /* RTOS guest */
|
#define UOS_GUEST_STATE_STOPPING 3
|
||||||
} uos_guest_type_t;
|
#define UOS_GUEST_STATE_ERROR 4
|
||||||
|
|
||||||
/* ============================================================================
|
/** Guest flags */
|
||||||
* Guest Status
|
#define UOS_GUEST_FLAG_SYSTEM (1<<0)
|
||||||
* ==========================================================================*/
|
#define UOS_GUEST_FLAG_USER (1<<1)
|
||||||
|
#define UOS_GUEST_FLAG_ANDROID (1<<2)
|
||||||
|
#define UOS_GUEST_FLAG_LINUX (1<<3)
|
||||||
|
|
||||||
typedef enum {
|
/** Error codes */
|
||||||
UOS_GUEST_STATUS_STOPPED = 0,
|
#define UOS_FLEET_E_OK 0
|
||||||
UOS_GUEST_STATUS_STARTING = 1,
|
#define UOS_FLEET_E_PERM -1
|
||||||
UOS_GUEST_STATUS_RUNNING = 2,
|
#define UOS_FLEET_E_NOENT -2
|
||||||
UOS_GUEST_STATUS_STOPPING = 3,
|
#define UOS_FLEET_E_INVAL -3
|
||||||
UOS_GUEST_STATUS_ERROR = 4,
|
#define UOS_FLEET_E_NOMEM -4
|
||||||
} uos_guest_status_t;
|
#define UOS_FLEET_E_NOSPC -5
|
||||||
|
#define UOS_FLEET_E_EXIST -6
|
||||||
|
#define UOS_FLEET_E_STATE -7
|
||||||
|
#define UOS_FLEET_E_NOTIMPL -8
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------------ TYPE DECLARATIONS ------------------------------ */
|
||||||
* Guest Template
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[UOS_FLEET_MAX_TEMPLATE_LEN];
|
|
||||||
uos_guest_type_t type;
|
|
||||||
char kernel_path[256];
|
|
||||||
char ramdisk_path[256];
|
|
||||||
char dtb_path[256];
|
|
||||||
uint64_t memory_size;
|
|
||||||
uint32_t partition_id;
|
|
||||||
int uses_hardened_malloc;
|
|
||||||
} uos_guest_template_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Guest Configuration
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[UOS_FLEET_MAX_NAME_LEN];
|
|
||||||
uos_guest_type_t type;
|
|
||||||
uint32_t guest_id;
|
|
||||||
uint32_t partition_id;
|
|
||||||
uint64_t memory_size;
|
|
||||||
uint64_t guest_base;
|
|
||||||
uint64_t guest_size;
|
|
||||||
int uses_hardened_malloc;
|
|
||||||
uos_guest_status_t status;
|
|
||||||
} uos_guest_config_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Guest Info (for listing)
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[UOS_FLEET_MAX_NAME_LEN];
|
|
||||||
uos_guest_type_t type;
|
|
||||||
uint32_t guest_id;
|
|
||||||
uint32_t partition_id;
|
|
||||||
uint64_t memory_size;
|
|
||||||
uos_guest_status_t status;
|
|
||||||
int isolation_pass;
|
|
||||||
} uos_guest_info_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Guest Statistics
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t memory_used;
|
|
||||||
uint64_t memory_total;
|
|
||||||
uint32_t map_count;
|
|
||||||
uint32_t quarantine_count;
|
|
||||||
uint64_t accountable_usage;
|
|
||||||
uint64_t uptime_ticks;
|
|
||||||
} uos_guest_stats_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Fleet Status
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t total_guests;
|
|
||||||
uint32_t running_guests;
|
|
||||||
uint32_t stopped_guests;
|
|
||||||
uint32_t error_guests;
|
|
||||||
uint64_t total_memory;
|
|
||||||
uint64_t used_memory;
|
|
||||||
uint32_t isolation_pass_count;
|
|
||||||
uint32_t isolation_fail_count;
|
|
||||||
} uos_fleet_status_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Function Declarations
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize fleet management subsystem
|
* @brief Guest ID type
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_fleet_init(void);
|
typedef uint32_t uos_fleet_guest_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fork a new guest from template
|
* @brief Template ID type
|
||||||
* @param template_name Template name
|
|
||||||
* @param guest_name Guest name (NULL for auto-generated)
|
|
||||||
* @param memory_size Memory size in bytes (0 for template default)
|
|
||||||
* @return Guest ID on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_fleet_fork(const char* template_name, const char* guest_name, uint64_t memory_size);
|
typedef uint32_t uos_fleet_template_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all guests
|
* @brief Guest descriptor structure
|
||||||
* @param guests Output: array of guest info
|
|
||||||
* @param count Output: number of guests
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_fleet_list(uos_guest_info_t* guests, uint32_t* count);
|
typedef struct uos_fleet_guest_str {
|
||||||
|
uos_fleet_guest_id_t id; /**< Guest ID */
|
||||||
|
char name[UOS_FLEET_NAME_MAX]; /**< Guest name */
|
||||||
|
uint32_t state; /**< Guest state */
|
||||||
|
uint32_t mode; /**< Guest operating mode */
|
||||||
|
uint32_t flags; /**< Guest flags */
|
||||||
|
uint32_t cpu_count; /**< Number of CPUs */
|
||||||
|
uint64_t memory_size; /**< Memory size in bytes */
|
||||||
|
uint64_t memory_used; /**< Memory used in bytes */
|
||||||
|
uos_fleet_template_id_t template_id; /**< Template ID */
|
||||||
|
uint32_t exit_status; /**< Exit status */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_fleet_guest_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show guest details
|
* @brief Template descriptor structure
|
||||||
* @param guest_name Guest name
|
|
||||||
* @param info Output: guest info
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_fleet_show(const char* guest_name, uos_guest_info_t* info);
|
typedef struct uos_fleet_template_str {
|
||||||
|
uos_fleet_template_id_t id; /**< Template ID */
|
||||||
|
char name[UOS_FLEET_NAME_MAX]; /**< Template name */
|
||||||
|
uint32_t flags; /**< Template flags */
|
||||||
|
uint32_t cpu_count; /**< Number of CPUs */
|
||||||
|
uint64_t memory_size; /**< Memory size in bytes */
|
||||||
|
char kernel_path[256]; /**< Kernel image path */
|
||||||
|
char initrd_path[256]; /**< Initrd image path */
|
||||||
|
char cmdline[256]; /**< Kernel command line */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_fleet_template_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor guest resource usage
|
* @brief Fleet statistics structure
|
||||||
* @param guest_name Guest name
|
|
||||||
* @param stats Output: guest statistics
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_fleet_monitor(const char* guest_name, uos_guest_stats_t* stats);
|
typedef struct uos_fleet_stats_str {
|
||||||
|
uint64_t guests_created; /**< Number of guests created */
|
||||||
|
uint64_t guests_started; /**< Number of guests started */
|
||||||
|
uint64_t guests_stopped; /**< Number of guests stopped */
|
||||||
|
uint64_t guests_deleted; /**< Number of guests deleted */
|
||||||
|
uint64_t templates_created; /**< Number of templates created */
|
||||||
|
uint64_t templates_deleted; /**< Number of templates deleted */
|
||||||
|
} uos_fleet_stats_t;
|
||||||
|
|
||||||
|
/* ----------------------- FUNCTION DECLARATIONS --------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start guest
|
* @purpose
|
||||||
* @param guest_name Guest name
|
* Initialize fleet management.
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_fleet_start(const char* guest_name);
|
void uos_fleet_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop guest
|
* @purpose
|
||||||
* @param guest_name Guest name
|
* Create a guest template.
|
||||||
* @return 0 on success, -1 on failure
|
*
|
||||||
|
* @param name
|
||||||
|
* IN: Template name
|
||||||
|
* @param flags
|
||||||
|
* IN: Template flags
|
||||||
|
* @param cpu_count
|
||||||
|
* IN: Number of CPUs
|
||||||
|
* @param memory_size
|
||||||
|
* IN: Memory size in bytes
|
||||||
|
* @param kernel_path
|
||||||
|
* IN: Kernel image path
|
||||||
|
* @param initrd_path
|
||||||
|
* IN: Initrd image path
|
||||||
|
* @param cmdline
|
||||||
|
* IN: Kernel command line
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Template ID on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
int uos_fleet_stop(const char* guest_name);
|
uos_fleet_template_id_t uos_fleet_template_create(const char* name, uint32_t flags,
|
||||||
|
uint32_t cpu_count, uint64_t memory_size,
|
||||||
|
const char* kernel_path, const char* initrd_path,
|
||||||
|
const char* cmdline);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restart guest
|
* @purpose
|
||||||
* @param guest_name Guest name
|
* Delete a guest template.
|
||||||
* @return 0 on success, -1 on failure
|
*
|
||||||
|
* @param template_id
|
||||||
|
* IN: Template ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
int uos_fleet_restart(const char* guest_name);
|
int uos_fleet_template_delete(uos_fleet_template_id_t template_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get fleet status
|
* @purpose
|
||||||
* @param status Output: fleet status
|
* Get template descriptor.
|
||||||
* @return 0 on success, -1 on failure
|
*
|
||||||
|
* @param template_id
|
||||||
|
* IN: Template ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Template descriptor on success, NULL otherwise
|
||||||
*/
|
*/
|
||||||
int uos_fleet_status(uos_fleet_status_t* status);
|
uos_fleet_template_t* uos_fleet_template_get(uos_fleet_template_id_t template_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run isolation audit on guest
|
* @purpose
|
||||||
* @param guest_name Guest name
|
* Create a guest from a template.
|
||||||
* @return 0 on pass, -1 on fail
|
*
|
||||||
|
* @param name
|
||||||
|
* IN: Guest name
|
||||||
|
* @param template_id
|
||||||
|
* IN: Template ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Guest ID on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
int uos_fleet_audit(const char* guest_name);
|
uos_fleet_guest_id_t uos_fleet_guest_create(const char* name, uos_fleet_template_id_t template_id);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/**
|
||||||
}
|
* @purpose
|
||||||
#endif
|
* Delete a guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_delete(uos_fleet_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest descriptor.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Guest descriptor on success, NULL otherwise
|
||||||
|
*/
|
||||||
|
uos_fleet_guest_t* uos_fleet_guest_get(uos_fleet_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Start a guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_start(uos_fleet_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Stop a guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_stop(uos_fleet_guest_id_t guest_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Set guest operating mode.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param mode
|
||||||
|
* IN: Operating mode
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_set_mode(uos_fleet_guest_id_t guest_id, uint32_t mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest operating mode.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param mode
|
||||||
|
* OUT: Operating mode
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_get_mode(uos_fleet_guest_id_t guest_id, uint32_t* mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest status.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param status
|
||||||
|
* OUT: Guest status
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_get_status(uos_fleet_guest_id_t guest_id, uint32_t* status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Clone a guest.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param name
|
||||||
|
* IN: New guest name
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* New guest ID on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_fleet_guest_id_t uos_fleet_guest_clone(uos_fleet_guest_id_t guest_id, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Migrate a guest to another host.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param host
|
||||||
|
* IN: Target host
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_FLEET_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_fleet_guest_migrate(uos_fleet_guest_id_t guest_id, const char* host);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get fleet statistics.
|
||||||
|
*
|
||||||
|
* @param stats
|
||||||
|
* OUT: Fleet statistics
|
||||||
|
*/
|
||||||
|
void uos_fleet_get_stats(uos_fleet_stats_t* stats);
|
||||||
|
|
||||||
#endif /* UOS_FLEET_H */
|
#endif /* UOS_FLEET_H */
|
||||||
|
|
|
||||||
|
|
@ -1,316 +1,503 @@
|
||||||
/*
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
* UniversalisOS Guest-Services Partition Implementation
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_guest_services.cpp
|
||||||
*
|
*
|
||||||
* Track: T8-3.4
|
* @purpose
|
||||||
* Date: 2026-07-12
|
* Implementation of guest services for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_port.h and ipc.h architecture.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include "uos_guest_services.h"
|
#include "uos_guest_services.h"
|
||||||
#include "../mm.h"
|
|
||||||
#include "../../platform/drivers/uart.h"
|
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------------ STATIC VARIABLES ------------------------------- */
|
||||||
* Guest-Services State
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static uos_service_t g_services[UOS_GUEST_SERVICES_MAX_SERVICES];
|
/** Port descriptors */
|
||||||
static uos_guest_services_state_t g_services_state;
|
static uos_port_desc_t gs_ports[UOS_PORT_MAX];
|
||||||
static int g_services_initialized = 0;
|
|
||||||
|
|
||||||
/* ============================================================================
|
/** Shared memory descriptors */
|
||||||
* Guest-Services Initialization
|
static uos_shm_desc_t gs_shm[UOS_SHM_MAX];
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_guest_services_init(void) {
|
/** Message queue descriptors */
|
||||||
if (g_services_initialized) {
|
static uos_mq_desc_t gs_mq[UOS_MQ_MAX];
|
||||||
return 0;
|
|
||||||
|
/** Guest services statistics */
|
||||||
|
static uos_gs_stats_t gs_stats;
|
||||||
|
|
||||||
|
/** Current time in nanoseconds */
|
||||||
|
static uint64_t gs_current_time = 0;
|
||||||
|
|
||||||
|
/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Initialize guest services.
|
||||||
|
*/
|
||||||
|
void uos_guest_services_init(void) {
|
||||||
|
/* Initialize port descriptors */
|
||||||
|
for (uint32_t i = 0; i < UOS_PORT_MAX; i++) {
|
||||||
|
gs_ports[i].id = i;
|
||||||
|
gs_ports[i].name[0] = '\0';
|
||||||
|
gs_ports[i].direction = 0;
|
||||||
|
gs_ports[i].type = UOS_PORT_TYPE_QUEUING;
|
||||||
|
gs_ports[i].max_msg_size = 0;
|
||||||
|
gs_ports[i].max_nb_msg = 0;
|
||||||
|
gs_ports[i].nb_msg = 0;
|
||||||
|
gs_ports[i].buffer = NULL;
|
||||||
|
gs_ports[i].buffer_size = 0;
|
||||||
|
gs_ports[i].in_use = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize services state */
|
/* Initialize shared memory descriptors */
|
||||||
g_services_state.partition_id = UOS_GUEST_SERVICES_PARTITION_ID;
|
for (uint32_t i = 0; i < UOS_SHM_MAX; i++) {
|
||||||
g_services_state.memory_size = UOS_GUEST_SERVICES_MEMORY_SIZE;
|
gs_shm[i].id = i;
|
||||||
g_services_state.service_count = 0;
|
gs_shm[i].addr = 0;
|
||||||
g_services_state.device_emulation_enabled = 1;
|
gs_shm[i].size = 0;
|
||||||
g_services_state.shared_services_enabled = 1;
|
gs_shm[i].guests = 0;
|
||||||
g_services_state.inter_guest_comm_enabled = 1;
|
gs_shm[i].in_use = false;
|
||||||
|
|
||||||
/* Initialize services array */
|
|
||||||
for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) {
|
|
||||||
g_services[i].registered = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_services_initialized = 1;
|
/* Initialize message queue descriptors */
|
||||||
|
for (uint32_t i = 0; i < UOS_MQ_MAX; i++) {
|
||||||
uart_puts("[GUEST-SERVICES] Partition initialized\n");
|
gs_mq[i].id = i;
|
||||||
|
gs_mq[i].max_msg_size = 0;
|
||||||
return 0;
|
gs_mq[i].max_nb_msg = 0;
|
||||||
}
|
gs_mq[i].nb_msg = 0;
|
||||||
|
gs_mq[i].buffer = NULL;
|
||||||
/* ============================================================================
|
gs_mq[i].buffer_size = 0;
|
||||||
* Service Registration
|
gs_mq[i].in_use = false;
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_guest_services_register(const char* name, uos_service_type_t type, guest_service_handler_t handler) {
|
|
||||||
if (!g_services_initialized) {
|
|
||||||
uos_guest_services_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize statistics */
|
||||||
|
gs_stats.vblk_reads = 0;
|
||||||
|
gs_stats.vblk_writes = 0;
|
||||||
|
gs_stats.vnet_sends = 0;
|
||||||
|
gs_stats.vnet_receives = 0;
|
||||||
|
gs_stats.vconsole_writes = 0;
|
||||||
|
gs_stats.vconsole_reads = 0;
|
||||||
|
gs_stats.port_writes = 0;
|
||||||
|
gs_stats.port_reads = 0;
|
||||||
|
gs_stats.shm_reads = 0;
|
||||||
|
gs_stats.shm_writes = 0;
|
||||||
|
gs_stats.mq_sends = 0;
|
||||||
|
gs_stats.mq_receives = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_services_state.service_count >= UOS_GUEST_SERVICES_MAX_SERVICES) {
|
/**
|
||||||
uart_puts("[GUEST-SERVICES] Maximum services reached\n");
|
* @purpose
|
||||||
return -1;
|
* Get guest services statistics.
|
||||||
|
*/
|
||||||
|
void uos_guest_services_get_stats(uos_gs_stats_t* stats) {
|
||||||
|
if (stats != NULL) {
|
||||||
|
*stats = gs_stats;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Find free slot */
|
/* ----------------------- Device Emulation Services ----------------------- */
|
||||||
for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) {
|
|
||||||
if (!g_services[i].registered) {
|
|
||||||
/* Copy name */
|
|
||||||
uint32_t j = 0;
|
|
||||||
while (name[j] && j < UOS_GUEST_SERVICES_MAX_NAME_LEN - 1) {
|
|
||||||
g_services[i].name[j] = name[j];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
g_services[i].name[j] = '\0';
|
|
||||||
|
|
||||||
g_services[i].type = type;
|
/**
|
||||||
g_services[i].handler = handler;
|
* @purpose
|
||||||
g_services[i].registered = 1;
|
* Read from virtual block device.
|
||||||
|
*/
|
||||||
g_services_state.service_count++;
|
int uos_guest_services_vblk_read(uos_guest_id_t guest_id, uint64_t sector, void* buffer, uint32_t count) {
|
||||||
|
/* Validate parameters */
|
||||||
uart_puts("[GUEST-SERVICES] Registered service: ");
|
if (buffer == NULL || count == 0) {
|
||||||
uart_puts(name);
|
return UOS_GS_E_INVAL;
|
||||||
uart_puts("\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
/* Validate guest ID */
|
||||||
}
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
/* ============================================================================
|
|
||||||
* Service Unregistration
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_guest_services_unregister(const char* name) {
|
|
||||||
if (!g_services_initialized) {
|
|
||||||
uos_guest_services_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement virtio-blk read */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.vblk_reads++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) {
|
/**
|
||||||
if (g_services[i].registered) {
|
* @purpose
|
||||||
/* Compare names */
|
* Write to virtual block device.
|
||||||
uint32_t j = 0;
|
*/
|
||||||
int match = 1;
|
int uos_guest_services_vblk_write(uos_guest_id_t guest_id, uint64_t sector, const void* buffer, uint32_t count) {
|
||||||
while (name[j] && g_services[i].name[j]) {
|
/* Validate parameters */
|
||||||
if (name[j] != g_services[i].name[j]) {
|
if (buffer == NULL || count == 0) {
|
||||||
match = 0;
|
return UOS_GS_E_INVAL;
|
||||||
break;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (match && name[j] == '\0' && g_services[i].name[j] == '\0') {
|
|
||||||
g_services[i].registered = 0;
|
|
||||||
g_services_state.service_count--;
|
|
||||||
|
|
||||||
uart_puts("[GUEST-SERVICES] Unregistered service: ");
|
|
||||||
uart_puts(name);
|
|
||||||
uart_puts("\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
/* Validate guest ID */
|
||||||
}
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
/* ============================================================================
|
|
||||||
* Service Call
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_guest_services_call(const char* name, uint32_t guest_id, void* args, void* result) {
|
|
||||||
if (!g_services_initialized) {
|
|
||||||
uos_guest_services_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement virtio-blk write */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.vblk_writes++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < UOS_GUEST_SERVICES_MAX_SERVICES; i++) {
|
/**
|
||||||
if (g_services[i].registered) {
|
* @purpose
|
||||||
/* Compare names */
|
* Send packet to virtual network.
|
||||||
uint32_t j = 0;
|
*/
|
||||||
int match = 1;
|
int uos_guest_services_vnet_send(uos_guest_id_t guest_id, const void* packet, uint32_t len) {
|
||||||
while (name[j] && g_services[i].name[j]) {
|
/* Validate parameters */
|
||||||
if (name[j] != g_services[i].name[j]) {
|
if (packet == NULL || len == 0) {
|
||||||
match = 0;
|
return UOS_GS_E_INVAL;
|
||||||
break;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (match && name[j] == '\0' && g_services[i].name[j] == '\0') {
|
|
||||||
return g_services[i].handler(guest_id, args, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_puts("[GUEST-SERVICES] Service not found: ");
|
/* Validate guest ID */
|
||||||
uart_puts(name);
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
uart_puts("\n");
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
return -1;
|
|
||||||
|
/* TODO: Implement virtio-net send */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.vnet_sends++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Device Emulation Services (Stubs)
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Receive packet from virtual network.
|
||||||
|
*/
|
||||||
int uos_guest_services_vblk_read(uint32_t guest_id, uint64_t sector, void* buffer, uint32_t count) {
|
int uos_guest_services_vnet_receive(uos_guest_id_t guest_id, void* buffer, uint32_t* len) {
|
||||||
(void)guest_id; (void)sector; (void)buffer; (void)count;
|
/* Validate parameters */
|
||||||
uart_puts("[UOS-STUB-T8-3.4] vblk_read: not implemented\n");
|
if (buffer == NULL || len == NULL) {
|
||||||
return -1;
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement virtio-net receive */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.vnet_receives++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_vblk_write(uint32_t guest_id, uint64_t sector, const void* buffer, uint32_t count) {
|
/**
|
||||||
(void)guest_id; (void)sector; (void)buffer; (void)count;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] vblk_write: not implemented\n");
|
* Write to virtual console.
|
||||||
return -1;
|
*/
|
||||||
|
int uos_guest_services_vconsole_write(uos_guest_id_t guest_id, const char* str) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (str == NULL) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement virtio-console write */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.vconsole_writes++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_vnet_send(uint32_t guest_id, const void* packet, uint32_t len) {
|
/**
|
||||||
(void)guest_id; (void)packet; (void)len;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] vnet_send: not implemented\n");
|
* Read from virtual console.
|
||||||
return -1;
|
*/
|
||||||
|
int uos_guest_services_vconsole_read(uos_guest_id_t guest_id, char* buffer, uint32_t* len) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (buffer == NULL || len == NULL) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement virtio-console read */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.vconsole_reads++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_vnet_receive(uint32_t guest_id, void* buffer, uint32_t* len) {
|
/* ----------------------- Shared Services --------------------------------- */
|
||||||
(void)guest_id; (void)buffer; (void)len;
|
|
||||||
uart_puts("[UOS-STUB-T8-3.4] vnet_receive: not implemented\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uos_guest_services_vconsole_write(uint32_t guest_id, const char* str) {
|
|
||||||
(void)guest_id; (void)str;
|
|
||||||
uart_puts("[UOS-STUB-T8-3.4] vconsole_write: not implemented\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uos_guest_services_vconsole_read(uint32_t guest_id, char* buffer, uint32_t* len) {
|
|
||||||
(void)guest_id; (void)buffer; (void)len;
|
|
||||||
uart_puts("[UOS-STUB-T8-3.4] vconsole_read: not implemented\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Shared Services (Stubs)
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get current time.
|
||||||
|
*/
|
||||||
uint64_t uos_guest_services_get_time(void) {
|
uint64_t uos_guest_services_get_time(void) {
|
||||||
uart_puts("[UOS-STUB-T8-3.4] get_time: not implemented\n");
|
/* TODO: Implement get_time */
|
||||||
return 0;
|
/* For now, return incrementing time */
|
||||||
|
gs_current_time += 1000000; /* 1 ms */
|
||||||
|
return gs_current_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get random bytes.
|
||||||
|
*/
|
||||||
int uos_guest_services_get_random(void* buffer, uint32_t len) {
|
int uos_guest_services_get_random(void* buffer, uint32_t len) {
|
||||||
(void)buffer; (void)len;
|
/* Validate parameters */
|
||||||
uart_puts("[UOS-STUB-T8-3.4] get_random: not implemented\n");
|
if (buffer == NULL || len == 0) {
|
||||||
return -1;
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement get_random */
|
||||||
|
/* For now, fill with pseudo-random bytes */
|
||||||
|
uint8_t* buf = (uint8_t*)buffer;
|
||||||
|
for (uint32_t i = 0; i < len; i++) {
|
||||||
|
buf[i] = (uint8_t)(i & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_log(uint32_t guest_id, const char* message) {
|
/**
|
||||||
(void)guest_id; (void)message;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] log: not implemented\n");
|
* Log a message.
|
||||||
return -1;
|
*/
|
||||||
|
int uos_guest_services_log(uos_guest_id_t guest_id, const char* message) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (message == NULL) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement log */
|
||||||
|
/* For now, just print to console */
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_health(uint32_t guest_id, uint32_t* status) {
|
/**
|
||||||
(void)guest_id; (void)status;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] health: not implemented\n");
|
* Check guest health.
|
||||||
return -1;
|
*/
|
||||||
|
int uos_guest_services_health(uos_guest_id_t guest_id, uint32_t* status) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (status == NULL) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate guest ID */
|
||||||
|
if (guest_id >= UOS_GUEST_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement health check */
|
||||||
|
/* For now, return healthy status */
|
||||||
|
*status = 0; /* Healthy */
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/* ----------------------- Inter-Guest Communication Services -------------- */
|
||||||
* Inter-Guest Communication Services (Stubs)
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_guest_services_port_write(uint32_t port_id, const void* data, uint32_t len) {
|
/**
|
||||||
(void)port_id; (void)data; (void)len;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] port_write: not implemented\n");
|
* Write to a port.
|
||||||
return -1;
|
*/
|
||||||
|
int uos_guest_services_port_write(uos_port_id_t port_id, const void* data, uint32_t len) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (data == NULL || len == 0) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate port ID */
|
||||||
|
if (port_id >= UOS_PORT_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if port is in use */
|
||||||
|
if (!gs_ports[port_id].in_use) {
|
||||||
|
return UOS_GS_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement port write */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.port_writes++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_port_read(uint32_t port_id, void* buffer, uint32_t* len) {
|
/**
|
||||||
(void)port_id; (void)buffer; (void)len;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] port_read: not implemented\n");
|
* Read from a port.
|
||||||
return -1;
|
*/
|
||||||
|
int uos_guest_services_port_read(uos_port_id_t port_id, void* buffer, uint32_t* len) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (buffer == NULL || len == NULL) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate port ID */
|
||||||
|
if (port_id >= UOS_PORT_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if port is in use */
|
||||||
|
if (!gs_ports[port_id].in_use) {
|
||||||
|
return UOS_GS_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement port read */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.port_reads++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests) {
|
/**
|
||||||
(void)addr; (void)size; (void)guests;
|
* @purpose
|
||||||
uart_puts("[UOS-STUB-T8-3.4] shm_create: not implemented\n");
|
* Create shared memory region.
|
||||||
return -1;
|
*/
|
||||||
|
uos_shm_id_t uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (size == 0 || guests == 0) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find free shared memory slot */
|
||||||
|
for (uint32_t i = 0; i < UOS_SHM_MAX; i++) {
|
||||||
|
if (!gs_shm[i].in_use) {
|
||||||
|
gs_shm[i].addr = addr;
|
||||||
|
gs_shm[i].size = size;
|
||||||
|
gs_shm[i].guests = guests;
|
||||||
|
gs_shm[i].in_use = true;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UOS_GS_E_NOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read from shared memory.
|
||||||
|
*/
|
||||||
int uos_guest_services_shm_read(uint64_t addr, void* buffer, uint32_t len) {
|
int uos_guest_services_shm_read(uint64_t addr, void* buffer, uint32_t len) {
|
||||||
(void)addr; (void)buffer; (void)len;
|
/* Validate parameters */
|
||||||
uart_puts("[UOS-STUB-T8-3.4] shm_read: not implemented\n");
|
if (buffer == NULL || len == 0) {
|
||||||
return -1;
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find shared memory region */
|
||||||
|
bool found = false;
|
||||||
|
for (uint32_t i = 0; i < UOS_SHM_MAX; i++) {
|
||||||
|
if (gs_shm[i].in_use && addr >= gs_shm[i].addr &&
|
||||||
|
addr + len <= gs_shm[i].addr + gs_shm[i].size) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return UOS_GS_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement shared memory read */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.shm_reads++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Write to shared memory.
|
||||||
|
*/
|
||||||
int uos_guest_services_shm_write(uint64_t addr, const void* data, uint32_t len) {
|
int uos_guest_services_shm_write(uint64_t addr, const void* data, uint32_t len) {
|
||||||
(void)addr; (void)data; (void)len;
|
/* Validate parameters */
|
||||||
uart_puts("[UOS-STUB-T8-3.4] shm_write: not implemented\n");
|
if (data == NULL || len == 0) {
|
||||||
return -1;
|
return UOS_GS_E_INVAL;
|
||||||
}
|
|
||||||
|
|
||||||
int uos_guest_services_mq_send(uint32_t queue_id, const void* message, uint32_t len, uint32_t priority) {
|
|
||||||
(void)queue_id; (void)message; (void)len; (void)priority;
|
|
||||||
uart_puts("[UOS-STUB-T8-3.4] mq_send: not implemented\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uos_guest_services_mq_receive(uint32_t queue_id, void* buffer, uint32_t* len, uint32_t* priority) {
|
|
||||||
(void)queue_id; (void)buffer; (void)len; (void)priority;
|
|
||||||
uart_puts("[UOS-STUB-T8-3.4] mq_receive: not implemented\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* State and Status
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_guest_services_get_state(uos_guest_services_state_t* state) {
|
|
||||||
if (!g_services_initialized) {
|
|
||||||
uos_guest_services_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state) {
|
/* Find shared memory region */
|
||||||
return -1;
|
bool found = false;
|
||||||
|
for (uint32_t i = 0; i < UOS_SHM_MAX; i++) {
|
||||||
|
if (gs_shm[i].in_use && addr >= gs_shm[i].addr &&
|
||||||
|
addr + len <= gs_shm[i].addr + gs_shm[i].size) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = g_services_state;
|
if (!found) {
|
||||||
return 0;
|
return UOS_GS_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement shared memory write */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.shm_writes++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uos_guest_services_print_status(void) {
|
/**
|
||||||
if (!g_services_initialized) {
|
* @purpose
|
||||||
uos_guest_services_init();
|
* Send message to message queue.
|
||||||
|
*/
|
||||||
|
int uos_guest_services_mq_send(uos_mq_id_t queue_id, const void* message, uint32_t len, uint32_t priority) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (message == NULL || len == 0) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_puts("\n[GUEST-SERVICES] Status:\n");
|
/* Validate queue ID */
|
||||||
uart_puts(" Partition ID: ");
|
if (queue_id >= UOS_MQ_MAX) {
|
||||||
uart_print_dec(g_services_state.partition_id);
|
return UOS_GS_E_INVAL;
|
||||||
uart_puts("\n");
|
}
|
||||||
uart_puts(" Memory Size: ");
|
|
||||||
uart_print_dec((uint32_t)(g_services_state.memory_size / (1024 * 1024)));
|
/* Check if queue is in use */
|
||||||
uart_puts(" MB\n");
|
if (!gs_mq[queue_id].in_use) {
|
||||||
uart_puts(" Service Count: ");
|
return UOS_GS_E_NOENT;
|
||||||
uart_print_dec(g_services_state.service_count);
|
}
|
||||||
uart_puts("\n");
|
|
||||||
uart_puts(" Device Emulation: ");
|
/* TODO: Implement message queue send */
|
||||||
uart_puts(g_services_state.device_emulation_enabled ? "Enabled" : "Disabled");
|
/* For now, just update statistics */
|
||||||
uart_puts("\n");
|
gs_stats.mq_sends++;
|
||||||
uart_puts(" Shared Services: ");
|
|
||||||
uart_puts(g_services_state.shared_services_enabled ? "Enabled" : "Disabled");
|
return UOS_GS_E_OK;
|
||||||
uart_puts("\n");
|
}
|
||||||
uart_puts(" Inter-Guest Comm: ");
|
|
||||||
uart_puts(g_services_state.inter_guest_comm_enabled ? "Enabled" : "Disabled");
|
/**
|
||||||
uart_puts("\n\n");
|
* @purpose
|
||||||
|
* Receive message from message queue.
|
||||||
|
*/
|
||||||
|
int uos_guest_services_mq_receive(uos_mq_id_t queue_id, void* buffer, uint32_t* len, uint32_t* priority) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (buffer == NULL || len == NULL) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate queue ID */
|
||||||
|
if (queue_id >= UOS_MQ_MAX) {
|
||||||
|
return UOS_GS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if queue is in use */
|
||||||
|
if (!gs_mq[queue_id].in_use) {
|
||||||
|
return UOS_GS_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement message queue receive */
|
||||||
|
/* For now, just update statistics */
|
||||||
|
gs_stats.mq_receives++;
|
||||||
|
|
||||||
|
return UOS_GS_E_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,182 +1,429 @@
|
||||||
/*
|
|
||||||
* UniversalisOS Guest-Services Partition
|
|
||||||
*
|
|
||||||
* This header defines the guest-services partition API. The guest-services
|
|
||||||
* partition provides shared services to all guests including device emulation,
|
|
||||||
* shared services, and inter-guest communication.
|
|
||||||
*
|
|
||||||
* Track: T8-3.4
|
|
||||||
* Date: 2026-07-12
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UOS_GUEST_SERVICES_H
|
#ifndef UOS_GUEST_SERVICES_H
|
||||||
#define UOS_GUEST_SERVICES_H
|
#define UOS_GUEST_SERVICES_H
|
||||||
|
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_guest_services.h
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Guest services interface for UniversalisOS.
|
||||||
|
* Based on PikeOS vm_port.h and ipc.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */
|
||||||
* Guest-Services Configuration
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
/* Reserved partition ID for guest-services */
|
/** Maximum number of guests */
|
||||||
#define UOS_GUEST_SERVICES_PARTITION_ID 255u
|
#define UOS_GUEST_MAX 16
|
||||||
|
|
||||||
/* Guest-services memory size */
|
/** Maximum number of ports per guest */
|
||||||
#define UOS_GUEST_SERVICES_MEMORY_SIZE (256u * 1024u * 1024u) /* 256M */
|
#define UOS_PORT_MAX 32
|
||||||
|
|
||||||
/* Maximum number of services */
|
/** Maximum number of shared memory regions */
|
||||||
#define UOS_GUEST_SERVICES_MAX_SERVICES 32u
|
#define UOS_SHM_MAX 16
|
||||||
|
|
||||||
/* Maximum service name length */
|
/** Maximum number of message queues */
|
||||||
#define UOS_GUEST_SERVICES_MAX_NAME_LEN 64u
|
#define UOS_MQ_MAX 16
|
||||||
|
|
||||||
/* ============================================================================
|
/** Maximum message size */
|
||||||
* Service Types
|
#define UOS_MQ_MAX_MSG_SIZE 256
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef enum {
|
/** Maximum port name length */
|
||||||
UOS_SERVICE_TYPE_DEVICE_EMULATION = 0,
|
#define UOS_PORT_NAME_MAX 32
|
||||||
UOS_SERVICE_TYPE_SHARED_SERVICE = 1,
|
|
||||||
UOS_SERVICE_TYPE_INTER_GUEST_COMM = 2,
|
|
||||||
} uos_service_type_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
/** Port directions */
|
||||||
* Service Handler
|
#define UOS_PORT_SOURCE 0x01
|
||||||
* ==========================================================================*/
|
#define UOS_PORT_DESTINATION 0x02
|
||||||
|
|
||||||
typedef int (*guest_service_handler_t)(uint32_t guest_id, void* args, void* result);
|
/** Port types */
|
||||||
|
#define UOS_PORT_TYPE_QUEUING 0
|
||||||
|
#define UOS_PORT_TYPE_SAMPLING 1
|
||||||
|
|
||||||
/* ============================================================================
|
/** Error codes */
|
||||||
* Service Registration
|
#define UOS_GS_E_OK 0
|
||||||
* ==========================================================================*/
|
#define UOS_GS_E_PERM -1
|
||||||
|
#define UOS_GS_E_NOENT -2
|
||||||
|
#define UOS_GS_E_INVAL -3
|
||||||
|
#define UOS_GS_E_IO -4
|
||||||
|
#define UOS_GS_E_NOMEM -5
|
||||||
|
#define UOS_GS_E_EXIST -6
|
||||||
|
#define UOS_GS_E_NOSPC -7
|
||||||
|
#define UOS_GS_E_TIMEOUT -8
|
||||||
|
#define UOS_GS_E_NOTIMPL -9
|
||||||
|
|
||||||
typedef struct {
|
/* ------------------------ TYPE DECLARATIONS ------------------------------ */
|
||||||
char name[UOS_GUEST_SERVICES_MAX_NAME_LEN];
|
|
||||||
uos_service_type_t type;
|
|
||||||
guest_service_handler_t handler;
|
|
||||||
int registered;
|
|
||||||
} uos_service_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Guest-Services State
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t partition_id;
|
|
||||||
uint64_t memory_size;
|
|
||||||
uint32_t service_count;
|
|
||||||
int device_emulation_enabled;
|
|
||||||
int shared_services_enabled;
|
|
||||||
int inter_guest_comm_enabled;
|
|
||||||
} uos_guest_services_state_t;
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Function Declarations
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize guest-services partition
|
* @brief Guest ID type
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_guest_services_init(void);
|
typedef uint32_t uos_guest_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a service
|
* @brief Port ID type
|
||||||
* @param name Service name
|
|
||||||
* @param type Service type
|
|
||||||
* @param handler Service handler
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_guest_services_register(const char* name, uos_service_type_t type, guest_service_handler_t handler);
|
typedef uint32_t uos_port_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister a service
|
* @brief Shared memory ID type
|
||||||
* @param name Service name
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_guest_services_unregister(const char* name);
|
typedef uint32_t uos_shm_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call a service
|
* @brief Message queue ID type
|
||||||
* @param name Service name
|
|
||||||
* @param guest_id Guest ID
|
|
||||||
* @param args Service arguments
|
|
||||||
* @param result Service result
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_guest_services_call(const char* name, uint32_t guest_id, void* args, void* result);
|
typedef uint32_t uos_mq_id_t;
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Device Emulation Services
|
* @brief Port descriptor structure
|
||||||
* ==========================================================================*/
|
*/
|
||||||
|
typedef struct uos_port_desc_str {
|
||||||
|
uos_port_id_t id; /**< Port ID */
|
||||||
|
char name[UOS_PORT_NAME_MAX]; /**< Port name */
|
||||||
|
uint32_t direction; /**< Port direction */
|
||||||
|
uint32_t type; /**< Port type */
|
||||||
|
uint32_t max_msg_size; /**< Maximum message size */
|
||||||
|
uint32_t max_nb_msg; /**< Maximum number of messages */
|
||||||
|
uint32_t nb_msg; /**< Current number of messages */
|
||||||
|
void* buffer; /**< Message buffer */
|
||||||
|
uint32_t buffer_size; /**< Buffer size */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_port_desc_t;
|
||||||
|
|
||||||
/* virtio-blk */
|
/**
|
||||||
int uos_guest_services_vblk_read(uint32_t guest_id, uint64_t sector, void* buffer, uint32_t count);
|
* @brief Shared memory descriptor structure
|
||||||
int uos_guest_services_vblk_write(uint32_t guest_id, uint64_t sector, const void* buffer, uint32_t count);
|
*/
|
||||||
|
typedef struct uos_shm_desc_str {
|
||||||
|
uos_shm_id_t id; /**< Shared memory ID */
|
||||||
|
uint64_t addr; /**< Shared memory address */
|
||||||
|
uint64_t size; /**< Shared memory size */
|
||||||
|
uint32_t guests; /**< Guest mask */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_shm_desc_t;
|
||||||
|
|
||||||
/* virtio-net */
|
/**
|
||||||
int uos_guest_services_vnet_send(uint32_t guest_id, const void* packet, uint32_t len);
|
* @brief Message queue descriptor structure
|
||||||
int uos_guest_services_vnet_receive(uint32_t guest_id, void* buffer, uint32_t* len);
|
*/
|
||||||
|
typedef struct uos_mq_desc_str {
|
||||||
|
uos_mq_id_t id; /**< Message queue ID */
|
||||||
|
uint32_t max_msg_size; /**< Maximum message size */
|
||||||
|
uint32_t max_nb_msg; /**< Maximum number of messages */
|
||||||
|
uint32_t nb_msg; /**< Current number of messages */
|
||||||
|
void* buffer; /**< Message buffer */
|
||||||
|
uint32_t buffer_size; /**< Buffer size */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_mq_desc_t;
|
||||||
|
|
||||||
/* virtio-console */
|
/**
|
||||||
int uos_guest_services_vconsole_write(uint32_t guest_id, const char* str);
|
* @brief Guest services statistics structure
|
||||||
int uos_guest_services_vconsole_read(uint32_t guest_id, char* buffer, uint32_t* len);
|
*/
|
||||||
|
typedef struct uos_gs_stats_str {
|
||||||
|
uint64_t vblk_reads; /**< Virtual block device reads */
|
||||||
|
uint64_t vblk_writes; /**< Virtual block device writes */
|
||||||
|
uint64_t vnet_sends; /**< Virtual network sends */
|
||||||
|
uint64_t vnet_receives; /**< Virtual network receives */
|
||||||
|
uint64_t vconsole_writes; /**< Virtual console writes */
|
||||||
|
uint64_t vconsole_reads; /**< Virtual console reads */
|
||||||
|
uint64_t port_writes; /**< Port writes */
|
||||||
|
uint64_t port_reads; /**< Port reads */
|
||||||
|
uint64_t shm_reads; /**< Shared memory reads */
|
||||||
|
uint64_t shm_writes; /**< Shared memory writes */
|
||||||
|
uint64_t mq_sends; /**< Message queue sends */
|
||||||
|
uint64_t mq_receives; /**< Message queue receives */
|
||||||
|
} uos_gs_stats_t;
|
||||||
|
|
||||||
/* ============================================================================
|
/* ----------------------- FUNCTION DECLARATIONS --------------------------- */
|
||||||
* Shared Services
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
/* Time service */
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Initialize guest services.
|
||||||
|
*/
|
||||||
|
void uos_guest_services_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get guest services statistics.
|
||||||
|
*
|
||||||
|
* @param stats
|
||||||
|
* OUT: Guest services statistics
|
||||||
|
*/
|
||||||
|
void uos_guest_services_get_stats(uos_gs_stats_t* stats);
|
||||||
|
|
||||||
|
/* ----------------------- Device Emulation Services ----------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read from virtual block device.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param sector
|
||||||
|
* IN: Sector to read from
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to read into
|
||||||
|
* @param count
|
||||||
|
* IN: Number of sectors to read
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_vblk_read(uos_guest_id_t guest_id, uint64_t sector, void* buffer, uint32_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Write to virtual block device.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param sector
|
||||||
|
* IN: Sector to write to
|
||||||
|
* @param buffer
|
||||||
|
* IN: Buffer to write from
|
||||||
|
* @param count
|
||||||
|
* IN: Number of sectors to write
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_vblk_write(uos_guest_id_t guest_id, uint64_t sector, const void* buffer, uint32_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Send packet to virtual network.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param packet
|
||||||
|
* IN: Packet to send
|
||||||
|
* @param len
|
||||||
|
* IN: Packet length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_vnet_send(uos_guest_id_t guest_id, const void* packet, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Receive packet from virtual network.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to receive into
|
||||||
|
* @param len
|
||||||
|
* INOUT: Buffer length / received length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_vnet_receive(uos_guest_id_t guest_id, void* buffer, uint32_t* len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Write to virtual console.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param str
|
||||||
|
* IN: String to write
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_vconsole_write(uos_guest_id_t guest_id, const char* str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read from virtual console.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to read into
|
||||||
|
* @param len
|
||||||
|
* INOUT: Buffer length / read length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_vconsole_read(uos_guest_id_t guest_id, char* buffer, uint32_t* len);
|
||||||
|
|
||||||
|
/* ----------------------- Shared Services --------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get current time.
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Current time in nanoseconds
|
||||||
|
*/
|
||||||
uint64_t uos_guest_services_get_time(void);
|
uint64_t uos_guest_services_get_time(void);
|
||||||
|
|
||||||
/* Random service */
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get random bytes.
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to fill with random bytes
|
||||||
|
* @param len
|
||||||
|
* IN: Number of random bytes
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
int uos_guest_services_get_random(void* buffer, uint32_t len);
|
int uos_guest_services_get_random(void* buffer, uint32_t len);
|
||||||
|
|
||||||
/* Logging service */
|
/**
|
||||||
int uos_guest_services_log(uint32_t guest_id, const char* message);
|
* @purpose
|
||||||
|
* Log a message.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param message
|
||||||
|
* IN: Message to log
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_log(uos_guest_id_t guest_id, const char* message);
|
||||||
|
|
||||||
/* Health service */
|
/**
|
||||||
int uos_guest_services_health(uint32_t guest_id, uint32_t* status);
|
* @purpose
|
||||||
|
* Check guest health.
|
||||||
|
*
|
||||||
|
* @param guest_id
|
||||||
|
* IN: Guest ID
|
||||||
|
* @param status
|
||||||
|
* OUT: Guest health status
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_health(uos_guest_id_t guest_id, uint32_t* status);
|
||||||
|
|
||||||
/* ============================================================================
|
/* ----------------------- Inter-Guest Communication Services -------------- */
|
||||||
* Inter-Guest Communication Services
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
/* Sampling ports */
|
/**
|
||||||
int uos_guest_services_port_write(uint32_t port_id, const void* data, uint32_t len);
|
* @purpose
|
||||||
int uos_guest_services_port_read(uint32_t port_id, void* buffer, uint32_t* len);
|
* Write to a port.
|
||||||
|
*
|
||||||
|
* @param port_id
|
||||||
|
* IN: Port ID
|
||||||
|
* @param data
|
||||||
|
* IN: Data to write
|
||||||
|
* @param len
|
||||||
|
* IN: Data length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_port_write(uos_port_id_t port_id, const void* data, uint32_t len);
|
||||||
|
|
||||||
/* Shared memory */
|
/**
|
||||||
int uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests);
|
* @purpose
|
||||||
|
* Read from a port.
|
||||||
|
*
|
||||||
|
* @param port_id
|
||||||
|
* IN: Port ID
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to read into
|
||||||
|
* @param len
|
||||||
|
* INOUT: Buffer length / read length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_port_read(uos_port_id_t port_id, void* buffer, uint32_t* len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create shared memory region.
|
||||||
|
*
|
||||||
|
* @param addr
|
||||||
|
* IN: Shared memory address
|
||||||
|
* @param size
|
||||||
|
* IN: Shared memory size
|
||||||
|
* @param guests
|
||||||
|
* IN: Guest mask
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Shared memory ID on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_shm_id_t uos_guest_services_shm_create(uint64_t addr, uint32_t size, uint32_t guests);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Read from shared memory.
|
||||||
|
*
|
||||||
|
* @param addr
|
||||||
|
* IN: Shared memory address
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to read into
|
||||||
|
* @param len
|
||||||
|
* IN: Number of bytes to read
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
int uos_guest_services_shm_read(uint64_t addr, void* buffer, uint32_t len);
|
int uos_guest_services_shm_read(uint64_t addr, void* buffer, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Write to shared memory.
|
||||||
|
*
|
||||||
|
* @param addr
|
||||||
|
* IN: Shared memory address
|
||||||
|
* @param data
|
||||||
|
* IN: Data to write
|
||||||
|
* @param len
|
||||||
|
* IN: Number of bytes to write
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
int uos_guest_services_shm_write(uint64_t addr, const void* data, uint32_t len);
|
int uos_guest_services_shm_write(uint64_t addr, const void* data, uint32_t len);
|
||||||
|
|
||||||
/* Message queues */
|
/**
|
||||||
int uos_guest_services_mq_send(uint32_t queue_id, const void* message, uint32_t len, uint32_t priority);
|
* @purpose
|
||||||
int uos_guest_services_mq_receive(uint32_t queue_id, void* buffer, uint32_t* len, uint32_t* priority);
|
* Send message to message queue.
|
||||||
|
*
|
||||||
/* ============================================================================
|
* @param queue_id
|
||||||
* State and Status
|
* IN: Message queue ID
|
||||||
* ==========================================================================*/
|
* @param message
|
||||||
|
* IN: Message to send
|
||||||
|
* @param len
|
||||||
|
* IN: Message length
|
||||||
|
* @param priority
|
||||||
|
* IN: Message priority
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_guest_services_mq_send(uos_mq_id_t queue_id, const void* message, uint32_t len, uint32_t priority);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get guest-services state
|
* @purpose
|
||||||
* @param state Output: guest-services state
|
* Receive message from message queue.
|
||||||
* @return 0 on success, -1 on failure
|
*
|
||||||
|
* @param queue_id
|
||||||
|
* IN: Message queue ID
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to receive into
|
||||||
|
* @param len
|
||||||
|
* INOUT: Buffer length / received length
|
||||||
|
* @param priority
|
||||||
|
* OUT: Message priority
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_GS_E_OK on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
int uos_guest_services_get_state(uos_guest_services_state_t* state);
|
int uos_guest_services_mq_receive(uos_mq_id_t queue_id, void* buffer, uint32_t* len, uint32_t* priority);
|
||||||
|
|
||||||
/**
|
|
||||||
* Print guest-services status
|
|
||||||
*/
|
|
||||||
void uos_guest_services_print_status(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* UOS_GUEST_SERVICES_H */
|
#endif /* UOS_GUEST_SERVICES_H */
|
||||||
|
|
|
||||||
|
|
@ -1,249 +1,243 @@
|
||||||
/*
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
* UniversalisOS Multi-Android-Guest Architecture Implementation
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_multi_guest.cpp
|
||||||
*
|
*
|
||||||
* Track: T8-3.3
|
* @purpose
|
||||||
* Date: 2026-07-12
|
* Implementation of multi-guest coordination for UniversalisOS.
|
||||||
|
* Based on PikeOS vm.h architecture.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include "uos_multi_guest.h"
|
#include "uos_multi_guest.h"
|
||||||
#include "uos_fleet.h"
|
|
||||||
#include "uos_separation_model.h"
|
|
||||||
#include "../mm.h"
|
|
||||||
#include "../../platform/drivers/uart.h"
|
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------------ STATIC VARIABLES ------------------------------- */
|
||||||
* Multi-Guest State
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
static uos_multi_guest_state_t g_multi_guest_state;
|
/** Channel directory */
|
||||||
static int g_multi_guest_initialized = 0;
|
static uos_mg_channel_t mg_channels[UOS_MG_MAX_CHANNELS];
|
||||||
|
|
||||||
/* ============================================================================
|
/** Next channel ID */
|
||||||
* Multi-Guest Initialization
|
static uos_mg_channel_id_t next_channel_id = 1;
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_multi_guest_init(void) {
|
/** Multi-guest statistics */
|
||||||
if (g_multi_guest_initialized) {
|
static uos_mg_stats_t mg_stats;
|
||||||
return 0;
|
|
||||||
|
/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Initialize multi-guest coordination.
|
||||||
|
*/
|
||||||
|
void uos_multi_guest_init(void) {
|
||||||
|
/* Initialize channel directory */
|
||||||
|
for (uint32_t i = 0; i < UOS_MG_MAX_CHANNELS; i++) {
|
||||||
|
mg_channels[i].id = 0;
|
||||||
|
mg_channels[i].name[0] = '\0';
|
||||||
|
mg_channels[i].type = UOS_MG_CHANNEL_TYPE_SHM;
|
||||||
|
mg_channels[i].direction = UOS_MG_CHANNEL_DIR_INOUT;
|
||||||
|
mg_channels[i].src_guest = 0;
|
||||||
|
mg_channels[i].dst_guest = 0;
|
||||||
|
mg_channels[i].addr = 0;
|
||||||
|
mg_channels[i].size = 0;
|
||||||
|
mg_channels[i].in_use = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize fleet management */
|
/* Initialize statistics */
|
||||||
uos_fleet_init();
|
mg_stats.channels_created = 0;
|
||||||
|
mg_stats.channels_deleted = 0;
|
||||||
/* Initialize separation model */
|
mg_stats.messages_sent = 0;
|
||||||
uos_separation_init();
|
mg_stats.messages_received = 0;
|
||||||
|
mg_stats.bytes_transferred = 0;
|
||||||
/* Initialize multi-guest state */
|
|
||||||
g_multi_guest_state.guest_count = 0;
|
|
||||||
g_multi_guest_state.android_count = 0;
|
|
||||||
g_multi_guest_state.musl_count = 0;
|
|
||||||
g_multi_guest_state.total_memory = 0;
|
|
||||||
g_multi_guest_state.used_memory = 0;
|
|
||||||
g_multi_guest_state.all_isolated = 1;
|
|
||||||
|
|
||||||
g_multi_guest_initialized = 1;
|
|
||||||
|
|
||||||
uart_puts("[MULTI-GUEST] Subsystem initialized\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Add Android Guest
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Create a channel between two guests.
|
||||||
|
*/
|
||||||
int uos_multi_guest_add_android(const char* name, uint64_t memory_size) {
|
uos_mg_channel_id_t uos_multi_guest_channel_create(const char* name, uint32_t type,
|
||||||
if (!g_multi_guest_initialized) {
|
uint32_t direction, uos_mg_guest_id_t src_guest,
|
||||||
uos_multi_guest_init();
|
uos_mg_guest_id_t dst_guest, uint64_t addr, uint64_t size) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (name == NULL) {
|
||||||
|
return UOS_MG_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_multi_guest_state.guest_count >= UOS_MULTI_GUEST_MAX) {
|
/* Validate guest IDs */
|
||||||
uart_puts("[MULTI-GUEST] Maximum guests reached\n");
|
if (src_guest >= UOS_MG_MAX_GUESTS || dst_guest >= UOS_MG_MAX_GUESTS) {
|
||||||
return -1;
|
return UOS_MG_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fork guest from android template */
|
/* Find free channel slot */
|
||||||
int guest_id = uos_fleet_fork("android-aosp", name, memory_size);
|
uos_mg_channel_id_t channel_id = 0;
|
||||||
if (guest_id < 0) {
|
for (uint32_t i = 0; i < UOS_MG_MAX_CHANNELS; i++) {
|
||||||
return -1;
|
if (!mg_channels[i].in_use) {
|
||||||
|
channel_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_multi_guest_state.guest_count++;
|
if (channel_id == 0 && mg_channels[0].in_use) {
|
||||||
g_multi_guest_state.android_count++;
|
return UOS_MG_E_NOSPC;
|
||||||
g_multi_guest_state.total_memory += memory_size;
|
}
|
||||||
|
|
||||||
uart_puts("[MULTI-GUEST] Added Android guest: ");
|
/* Initialize channel descriptor */
|
||||||
uart_puts(name);
|
mg_channels[channel_id].id = next_channel_id++;
|
||||||
uart_puts("\n");
|
|
||||||
|
/* Copy name */
|
||||||
return guest_id;
|
uint32_t i = 0;
|
||||||
|
while (name[i] != '\0' && i < UOS_MG_CHANNEL_NAME_MAX - 1) {
|
||||||
|
mg_channels[channel_id].name[i] = name[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
mg_channels[channel_id].name[i] = '\0';
|
||||||
|
|
||||||
|
mg_channels[channel_id].type = type;
|
||||||
|
mg_channels[channel_id].direction = direction;
|
||||||
|
mg_channels[channel_id].src_guest = src_guest;
|
||||||
|
mg_channels[channel_id].dst_guest = dst_guest;
|
||||||
|
mg_channels[channel_id].addr = addr;
|
||||||
|
mg_channels[channel_id].size = size;
|
||||||
|
mg_channels[channel_id].in_use = true;
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
mg_stats.channels_created++;
|
||||||
|
|
||||||
|
return channel_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Add musl Guest
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Delete a channel.
|
||||||
|
*/
|
||||||
int uos_multi_guest_add_musl(const char* name, uint64_t memory_size) {
|
int uos_multi_guest_channel_delete(uos_mg_channel_id_t channel_id) {
|
||||||
if (!g_multi_guest_initialized) {
|
/* Validate channel ID */
|
||||||
uos_multi_guest_init();
|
if (channel_id >= UOS_MG_MAX_CHANNELS) {
|
||||||
|
return UOS_MG_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_multi_guest_state.guest_count >= UOS_MULTI_GUEST_MAX) {
|
if (!mg_channels[channel_id].in_use) {
|
||||||
uart_puts("[MULTI-GUEST] Maximum guests reached\n");
|
return UOS_MG_E_NOENT;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fork guest from musl template */
|
/* Mark as unused */
|
||||||
int guest_id = uos_fleet_fork("musl", name, memory_size);
|
mg_channels[channel_id].in_use = false;
|
||||||
if (guest_id < 0) {
|
|
||||||
return -1;
|
/* Update statistics */
|
||||||
}
|
mg_stats.channels_deleted++;
|
||||||
|
|
||||||
g_multi_guest_state.guest_count++;
|
return UOS_MG_E_OK;
|
||||||
g_multi_guest_state.musl_count++;
|
|
||||||
g_multi_guest_state.total_memory += memory_size;
|
|
||||||
|
|
||||||
uart_puts("[MULTI-GUEST] Added musl guest: ");
|
|
||||||
uart_puts(name);
|
|
||||||
uart_puts("\n");
|
|
||||||
|
|
||||||
return guest_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Remove Guest
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Get channel descriptor.
|
||||||
|
*/
|
||||||
int uos_multi_guest_remove(uint32_t guest_id) {
|
uos_mg_channel_t* uos_multi_guest_channel_get(uos_mg_channel_id_t channel_id) {
|
||||||
if (!g_multi_guest_initialized) {
|
/* Validate channel ID */
|
||||||
uos_multi_guest_init();
|
if (channel_id >= UOS_MG_MAX_CHANNELS) {
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guest_id >= UOS_MULTI_GUEST_MAX) {
|
if (!mg_channels[channel_id].in_use) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Implement guest removal */
|
return &mg_channels[channel_id];
|
||||||
uart_puts("[UOS-STUB-T8-3.3] Guest removal: not implemented\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Start All Guests
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Send data through a channel.
|
||||||
|
*/
|
||||||
|
int uos_multi_guest_channel_send(uos_mg_channel_id_t channel_id, const void* data, uint32_t len) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (data == NULL || len == 0) {
|
||||||
|
return UOS_MG_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate channel ID */
|
||||||
|
if (channel_id >= UOS_MG_MAX_CHANNELS) {
|
||||||
|
return UOS_MG_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mg_channels[channel_id].in_use) {
|
||||||
|
return UOS_MG_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check direction */
|
||||||
|
if ((mg_channels[channel_id].direction & UOS_MG_CHANNEL_DIR_OUT) == 0) {
|
||||||
|
return UOS_MG_E_PERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement channel send logic */
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
mg_stats.messages_sent++;
|
||||||
|
mg_stats.bytes_transferred += len;
|
||||||
|
|
||||||
|
return UOS_MG_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Receive data from a channel.
|
||||||
|
*/
|
||||||
|
int uos_multi_guest_channel_receive(uos_mg_channel_id_t channel_id, void* buffer, uint32_t* len) {
|
||||||
|
/* Validate parameters */
|
||||||
|
if (buffer == NULL || len == NULL) {
|
||||||
|
return UOS_MG_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate channel ID */
|
||||||
|
if (channel_id >= UOS_MG_MAX_CHANNELS) {
|
||||||
|
return UOS_MG_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mg_channels[channel_id].in_use) {
|
||||||
|
return UOS_MG_E_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check direction */
|
||||||
|
if ((mg_channels[channel_id].direction & UOS_MG_CHANNEL_DIR_IN) == 0) {
|
||||||
|
return UOS_MG_E_PERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement channel receive logic */
|
||||||
|
|
||||||
|
/* Update statistics */
|
||||||
|
mg_stats.messages_received++;
|
||||||
|
|
||||||
|
return UOS_MG_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Start all guests.
|
||||||
|
*/
|
||||||
int uos_multi_guest_start_all(void) {
|
int uos_multi_guest_start_all(void) {
|
||||||
if (!g_multi_guest_initialized) {
|
/* TODO: Implement start all guests logic */
|
||||||
uos_multi_guest_init();
|
|
||||||
}
|
return UOS_MG_E_OK;
|
||||||
|
|
||||||
uart_puts("[MULTI-GUEST] Starting all guests...\n");
|
|
||||||
|
|
||||||
/* TODO: Implement actual start */
|
|
||||||
uart_puts("[UOS-STUB-T8-3.3] Start all: not implemented\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Stop All Guests
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Stop all guests.
|
||||||
|
*/
|
||||||
int uos_multi_guest_stop_all(void) {
|
int uos_multi_guest_stop_all(void) {
|
||||||
if (!g_multi_guest_initialized) {
|
/* TODO: Implement stop all guests logic */
|
||||||
uos_multi_guest_init();
|
|
||||||
}
|
return UOS_MG_E_OK;
|
||||||
|
|
||||||
uart_puts("[MULTI-GUEST] Stopping all guests...\n");
|
|
||||||
|
|
||||||
/* TODO: Implement actual stop */
|
|
||||||
uart_puts("[UOS-STUB-T8-3.3] Stop all: not implemented\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/**
|
||||||
* Get Guest Count
|
* @purpose
|
||||||
* ==========================================================================*/
|
* Get multi-guest statistics.
|
||||||
|
*/
|
||||||
uint32_t uos_multi_guest_count(void) {
|
void uos_multi_guest_get_stats(uos_mg_stats_t* stats) {
|
||||||
if (!g_multi_guest_initialized) {
|
if (stats != NULL) {
|
||||||
uos_multi_guest_init();
|
*stats = mg_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_multi_guest_state.guest_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Get Android Guest Count
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
uint32_t uos_multi_guest_android_count(void) {
|
|
||||||
if (!g_multi_guest_initialized) {
|
|
||||||
uos_multi_guest_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_multi_guest_state.android_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Audit All Guests
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_multi_guest_audit_all(void) {
|
|
||||||
if (!g_multi_guest_initialized) {
|
|
||||||
uos_multi_guest_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_puts("[MULTI-GUEST] Running isolation audit on all guests...\n");
|
|
||||||
|
|
||||||
/* TODO: Implement actual audit */
|
|
||||||
uart_puts("[UOS-STUB-T8-3.3] Audit all: not implemented\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Get Multi-Guest State
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
int uos_multi_guest_get_state(uos_multi_guest_state_t* state) {
|
|
||||||
if (!g_multi_guest_initialized) {
|
|
||||||
uos_multi_guest_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!state) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*state = g_multi_guest_state;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
|
||||||
* Print Multi-Guest Status
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
void uos_multi_guest_print_status(void) {
|
|
||||||
if (!g_multi_guest_initialized) {
|
|
||||||
uos_multi_guest_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_puts("\n[MULTI-GUEST] Status:\n");
|
|
||||||
uart_puts(" Total Guests: ");
|
|
||||||
uart_print_dec(g_multi_guest_state.guest_count);
|
|
||||||
uart_puts("\n");
|
|
||||||
uart_puts(" Android Guests: ");
|
|
||||||
uart_print_dec(g_multi_guest_state.android_count);
|
|
||||||
uart_puts("\n");
|
|
||||||
uart_puts(" musl Guests: ");
|
|
||||||
uart_print_dec(g_multi_guest_state.musl_count);
|
|
||||||
uart_puts("\n");
|
|
||||||
uart_puts(" Total Memory: ");
|
|
||||||
uart_print_dec((uint32_t)(g_multi_guest_state.total_memory / (1024 * 1024)));
|
|
||||||
uart_puts(" MB\n");
|
|
||||||
uart_puts(" All Isolated: ");
|
|
||||||
uart_puts(g_multi_guest_state.all_isolated ? "Yes" : "No");
|
|
||||||
uart_puts("\n\n");
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,130 +1,208 @@
|
||||||
/*
|
|
||||||
* UniversalisOS Multi-Android-Guest Architecture
|
|
||||||
*
|
|
||||||
* This header defines the multi-guest API for running multiple concurrent
|
|
||||||
* Android guests inside UniversalisOS.
|
|
||||||
*
|
|
||||||
* Track: T8-3.3
|
|
||||||
* Date: 2026-07-12
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UOS_MULTI_GUEST_H
|
#ifndef UOS_MULTI_GUEST_H
|
||||||
#define UOS_MULTI_GUEST_H
|
#define UOS_MULTI_GUEST_H
|
||||||
|
|
||||||
|
/* -------------------------- FILE PROLOGUE -------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* uos_multi_guest.h
|
||||||
|
*
|
||||||
|
* @purpose
|
||||||
|
* Multi-guest coordination interface for UniversalisOS.
|
||||||
|
* Based on PikeOS vm.h architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------- FILE INCLUSION -------------------------------- */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "uos_fleet.h"
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */
|
||||||
* Multi-Guest Configuration
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
/* Maximum number of concurrent guests */
|
/** Maximum number of guests */
|
||||||
#define UOS_MULTI_GUEST_MAX 4u
|
#define UOS_MG_MAX_GUESTS 16
|
||||||
|
|
||||||
/* Guest memory sizes */
|
/** Maximum number of channels */
|
||||||
#define UOS_MULTI_GUEST_MUSL_SIZE (512u * 1024u * 1024u) /* 512M */
|
#define UOS_MG_MAX_CHANNELS 32
|
||||||
#define UOS_MULTI_GUEST_ANDROID_SIZE (1024u * 1024u * 1024u) /* 1G */
|
|
||||||
|
|
||||||
/* Guest IPA bases (all guests use same IPA base, different PA) */
|
/** Maximum channel name length */
|
||||||
#define UOS_MULTI_GUEST_IPA_BASE 0x40000000u
|
#define UOS_MG_CHANNEL_NAME_MAX 32
|
||||||
|
|
||||||
/* Guest PA bases (different for each guest) */
|
/** Channel types */
|
||||||
#define UOS_MULTI_GUEST_PA_BASE(n) (0x40000000u + ((n) * 0x40000000u))
|
#define UOS_MG_CHANNEL_TYPE_SHM 0
|
||||||
|
#define UOS_MG_CHANNEL_TYPE_PORT 1
|
||||||
|
#define UOS_MG_CHANNEL_TYPE_MQ 2
|
||||||
|
|
||||||
/* ============================================================================
|
/** Channel directions */
|
||||||
* Multi-Guest State
|
#define UOS_MG_CHANNEL_DIR_IN 0x01
|
||||||
* ==========================================================================*/
|
#define UOS_MG_CHANNEL_DIR_OUT 0x02
|
||||||
|
#define UOS_MG_CHANNEL_DIR_INOUT 0x03
|
||||||
|
|
||||||
typedef struct {
|
/** Error codes */
|
||||||
uint32_t guest_count;
|
#define UOS_MG_E_OK 0
|
||||||
uint32_t android_count;
|
#define UOS_MG_E_PERM -1
|
||||||
uint32_t musl_count;
|
#define UOS_MG_E_NOENT -2
|
||||||
uint64_t total_memory;
|
#define UOS_MG_E_INVAL -3
|
||||||
uint64_t used_memory;
|
#define UOS_MG_E_NOMEM -4
|
||||||
int all_isolated;
|
#define UOS_MG_E_NOSPC -5
|
||||||
} uos_multi_guest_state_t;
|
#define UOS_MG_E_EXIST -6
|
||||||
|
#define UOS_MG_E_STATE -7
|
||||||
|
#define UOS_MG_E_NOTIMPL -8
|
||||||
|
|
||||||
/* ============================================================================
|
/* ------------------------ TYPE DECLARATIONS ------------------------------ */
|
||||||
* Function Declarations
|
|
||||||
* ==========================================================================*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize multi-guest subsystem
|
* @brief Guest ID type
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_multi_guest_init(void);
|
typedef uint32_t uos_mg_guest_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Android guest
|
* @brief Channel ID type
|
||||||
* @param name Guest name
|
|
||||||
* @param memory_size Memory size in bytes
|
|
||||||
* @return Guest ID on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_multi_guest_add_android(const char* name, uint64_t memory_size);
|
typedef uint32_t uos_mg_channel_id_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add musl personality guest
|
* @brief Channel descriptor structure
|
||||||
* @param name Guest name
|
|
||||||
* @param memory_size Memory size in bytes
|
|
||||||
* @return Guest ID on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_multi_guest_add_musl(const char* name, uint64_t memory_size);
|
typedef struct uos_mg_channel_str {
|
||||||
|
uos_mg_channel_id_t id; /**< Channel ID */
|
||||||
|
char name[UOS_MG_CHANNEL_NAME_MAX]; /**< Channel name */
|
||||||
|
uint32_t type; /**< Channel type */
|
||||||
|
uint32_t direction; /**< Channel direction */
|
||||||
|
uos_mg_guest_id_t src_guest; /**< Source guest ID */
|
||||||
|
uos_mg_guest_id_t dst_guest; /**< Destination guest ID */
|
||||||
|
uint64_t addr; /**< Channel address */
|
||||||
|
uint64_t size; /**< Channel size */
|
||||||
|
bool in_use; /**< In use flag */
|
||||||
|
} uos_mg_channel_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove guest
|
* @brief Multi-guest statistics structure
|
||||||
* @param guest_id Guest ID
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
*/
|
||||||
int uos_multi_guest_remove(uint32_t guest_id);
|
typedef struct uos_mg_stats_str {
|
||||||
|
uint64_t channels_created; /**< Number of channels created */
|
||||||
|
uint64_t channels_deleted; /**< Number of channels deleted */
|
||||||
|
uint64_t messages_sent; /**< Number of messages sent */
|
||||||
|
uint64_t messages_received; /**< Number of messages received */
|
||||||
|
uint64_t bytes_transferred; /**< Number of bytes transferred */
|
||||||
|
} uos_mg_stats_t;
|
||||||
|
|
||||||
|
/* ----------------------- FUNCTION DECLARATIONS --------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start all guests
|
* @purpose
|
||||||
* @return 0 on success, -1 on failure
|
* Initialize multi-guest coordination.
|
||||||
|
*/
|
||||||
|
void uos_multi_guest_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Create a channel between two guests.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* IN: Channel name
|
||||||
|
* @param type
|
||||||
|
* IN: Channel type
|
||||||
|
* @param direction
|
||||||
|
* IN: Channel direction
|
||||||
|
* @param src_guest
|
||||||
|
* IN: Source guest ID
|
||||||
|
* @param dst_guest
|
||||||
|
* IN: Destination guest ID
|
||||||
|
* @param addr
|
||||||
|
* IN: Channel address
|
||||||
|
* @param size
|
||||||
|
* IN: Channel size
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Channel ID on success, error code otherwise
|
||||||
|
*/
|
||||||
|
uos_mg_channel_id_t uos_multi_guest_channel_create(const char* name, uint32_t type,
|
||||||
|
uint32_t direction, uos_mg_guest_id_t src_guest,
|
||||||
|
uos_mg_guest_id_t dst_guest, uint64_t addr, uint64_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Delete a channel.
|
||||||
|
*
|
||||||
|
* @param channel_id
|
||||||
|
* IN: Channel ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_MG_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_multi_guest_channel_delete(uos_mg_channel_id_t channel_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Get channel descriptor.
|
||||||
|
*
|
||||||
|
* @param channel_id
|
||||||
|
* IN: Channel ID
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* Channel descriptor on success, NULL otherwise
|
||||||
|
*/
|
||||||
|
uos_mg_channel_t* uos_multi_guest_channel_get(uos_mg_channel_id_t channel_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Send data through a channel.
|
||||||
|
*
|
||||||
|
* @param channel_id
|
||||||
|
* IN: Channel ID
|
||||||
|
* @param data
|
||||||
|
* IN: Data to send
|
||||||
|
* @param len
|
||||||
|
* IN: Data length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_MG_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_multi_guest_channel_send(uos_mg_channel_id_t channel_id, const void* data, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Receive data from a channel.
|
||||||
|
*
|
||||||
|
* @param channel_id
|
||||||
|
* IN: Channel ID
|
||||||
|
* @param buffer
|
||||||
|
* OUT: Buffer to receive into
|
||||||
|
* @param len
|
||||||
|
* INOUT: Buffer length / received length
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_MG_E_OK on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int uos_multi_guest_channel_receive(uos_mg_channel_id_t channel_id, void* buffer, uint32_t* len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @purpose
|
||||||
|
* Start all guests.
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_MG_E_OK on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
int uos_multi_guest_start_all(void);
|
int uos_multi_guest_start_all(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop all guests
|
* @purpose
|
||||||
* @return 0 on success, -1 on failure
|
* Stop all guests.
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* UOS_MG_E_OK on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
int uos_multi_guest_stop_all(void);
|
int uos_multi_guest_stop_all(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get guest count
|
* @purpose
|
||||||
* @return Number of guests
|
* Get multi-guest statistics.
|
||||||
|
*
|
||||||
|
* @param stats
|
||||||
|
* OUT: Multi-guest statistics
|
||||||
*/
|
*/
|
||||||
uint32_t uos_multi_guest_count(void);
|
void uos_multi_guest_get_stats(uos_mg_stats_t* stats);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Android guest count
|
|
||||||
* @return Number of Android guests
|
|
||||||
*/
|
|
||||||
uint32_t uos_multi_guest_android_count(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run isolation audit on all guests
|
|
||||||
* @return 0 if all pass, -1 if any fail
|
|
||||||
*/
|
|
||||||
int uos_multi_guest_audit_all(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get multi-guest state
|
|
||||||
* @param state Output: multi-guest state
|
|
||||||
* @return 0 on success, -1 on failure
|
|
||||||
*/
|
|
||||||
int uos_multi_guest_get_state(uos_multi_guest_state_t* state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print multi-guest status
|
|
||||||
*/
|
|
||||||
void uos_multi_guest_print_status(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* UOS_MULTI_GUEST_H */
|
#endif /* UOS_MULTI_GUEST_H */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue