//-------------------------------------------------------------------------------------------------- void userAddRemove_Add ( const char* appName ) //-------------------------------------------------------------------------------------------------- { le_result_t result; uid_t uid; gid_t gid; char userName[256] = "app"; result = le_utf8_Append(userName, appName, sizeof(userName), NULL); LE_FATAL_IF(result != LE_OK, "App name '%s' is too long.", appName); LE_INFO("Creating user '%s' for application '%s'.", userName, appName); // Start a read transaction and go to node /apps/app-name le_cfg_ConnectService(); le_cfg_IteratorRef_t i = le_cfg_CreateReadTxn("/apps"); le_cfg_GoToNode(i, appName); // If the node doesn't exist, bail out. if (!le_cfg_NodeExists(i, "")) { fprintf(stderr, "** ERROR: App '%s' doesn't exist in the system configuration.\n", appName); } else { result = user_Create(userName, &uid, &gid); if (result == LE_OK) { printf("Created user '%s' (uid %u, gid %u).\n", userName, uid, gid); // TODO: Groups configuration. le_cfg_CancelTxn(i); exit(EXIT_SUCCESS); } else if (result == LE_DUPLICATE) { // TODO: Verify correct groups configuration. printf("User '%s' already exists (uid %u, gid %u).\n", userName, uid, gid); le_cfg_CancelTxn(i); exit(EXIT_SUCCESS); } else { fprintf(stderr, "** ERROR: user_Create() failed for user '%s'.\n", userName); } } le_cfg_CancelTxn(i); exit(EXIT_FAILURE); }
//-------------------------------------------------------------------------------------------------- static void ResetApp ( void ) { le_cfg_ConnectService(); le_cfgAdmin_ConnectService(); // Get a write iterator to the application node. le_cfg_IteratorRef_t cfgIter = le_cfg_CreateWriteTxn("/apps"); le_cfg_GoToNode(cfgIter, AppName); // Check if this is a temporary configuration that was previously created by this or a similar // tool. if (le_cfg_IsEmpty(cfgIter, CFG_DEBUG_TOOL)) { fprintf(stderr, "This application already has its original configuration.\n"); exit(EXIT_FAILURE); } // Blow away what's in there now. le_cfg_GoToNode(cfgIter, "/apps"); le_cfg_DeleteNode(cfgIter, AppName); le_cfg_CommitTxn(cfgIter); // NOTE: Currently there is a bug in the config DB where deletions and imports cannot be done in // the same transaction so we must do it in two transactions. cfgInstall_Add(AppName); }
//-------------------------------------------------------------------------------------------------- static void* CellNetThread ( void* contextPtr ) { // Connect to the services required by this thread le_cfg_ConnectService(); le_mrc_ConnectService(); le_sim_ConnectService(); LE_INFO("CellNet Thread Started"); // Register for command events le_event_AddHandler("ProcessCommand", CommandEvent, ProcessCommand); // Register for SIM state changes le_sim_AddNewStateHandler(SimStateHandler, NULL); // Register for MRC Network Registration state changes le_mrc_AddNetRegStateEventHandler(MrcNetRegHandler, NULL); // Run the event loop le_event_RunLoop(); return NULL; }
//-------------------------------------------------------------------------------------------------- static void StartFramework ( void ) { // Start a daemon start-up watchdog timer. // If we don't cancel this timer within 30 seconds, a SIGALRM will be generated, which will // kill the Supervisor. alarm(30); // Start all framework daemons. fwDaemons_Start(); // Connect to the services we need from the framework daemons. LE_DEBUG("---- Connecting to services ----"); le_cfg_ConnectService(); logFd_ConnectService(); le_instStat_ConnectService(); // Cancel the start-up watchdog timer. alarm(0); // Insert kernel modules kernelModules_Insert(); // Advertise services. LE_DEBUG("---- Advertising the Supervisor's APIs ----"); le_sup_ctrl_AdvertiseService(); le_sup_wdog_AdvertiseService(); le_appInfo_AdvertiseService(); le_appProc_AdvertiseService(); // Initialize the apps sub system. apps_Init(); State = STATE_NORMAL; if (AppStartMode == APP_START_AUTO) { // Launch all user apps in the config tree that should be launched on system startup. LE_INFO("Auto-starting apps."); apps_AutoStart(); } else { LE_INFO("Skipping app auto-start."); } }
//-------------------------------------------------------------------------------------------------- static void Load ( void ) //-------------------------------------------------------------------------------------------------- { le_result_t result; // Connect to the Configuration API server. le_cfg_ConnectService(); // Initialize the "User API". user_Init(); // Start a read transaction on the root of the "system" configuration tree. le_cfg_IteratorRef_t i = le_cfg_CreateReadTxn("system:"); // Tell the Service Directory to delete all existing bindings. SendUnbindAllRequest(); // Iterate over the users collection. le_cfg_GoToNode(i, "/users"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { uid_t uid; if (GetUserUid(i, &uid) == LE_OK) { // For each user, iterate over the bindings collection, sending the binding to // the Service Directory. le_cfg_GoToNode(i, "bindings"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { SendBindRequest(uid, i); result = le_cfg_GoToNextSibling(i); } // Go back up to the user name node. le_cfg_GoToNode(i, "../.."); } // Move on to the next user. result = le_cfg_GoToNextSibling(i); } // Iterate over the apps collection. le_cfg_GoToNode(i, "/apps"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { uid_t uid; if (GetAppUid(i, &uid) == LE_OK) { // For each app, iterate over the bindings collection, sending the binding to // the Service Directory. le_cfg_GoToNode(i, "bindings"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { SendBindRequest(uid, i); result = le_cfg_GoToNextSibling(i); } // Go back up to the app's node. le_cfg_GoToNode(i, "../.."); } // Move on to the next app. result = le_cfg_GoToNextSibling(i); } exit(EXIT_SUCCESS); }
//-------------------------------------------------------------------------------------------------- static void ConfigureGdb ( void ) { le_cfg_ConnectService(); le_cfgAdmin_ConnectService(); // Get a write iterator to the application node. le_cfg_IteratorRef_t cfgIter = le_cfg_CreateWriteTxn("/apps"); le_cfg_GoToNode(cfgIter, AppName); // Check if this is a temporary configuration that was previously created by this or a similar // tool. if (!le_cfg_IsEmpty(cfgIter, CFG_DEBUG_TOOL)) { char debugTool[LIMIT_MAX_PATH_BYTES]; // Don't need to check return code because the value is just informative and does not matter // if it is truncated. le_cfg_GetString(cfgIter, CFG_DEBUG_TOOL, debugTool, sizeof(debugTool), ""); fprintf(stderr, "This application has already been configured for %s debug mode.\n", debugTool); exit(EXIT_FAILURE); } // Write into the config's debug tool node to indicate that this configuration has been modified. le_cfg_SetString(cfgIter, CFG_DEBUG_TOOL, "gdb"); // Add 512K to the maxFileSytemBytes so that we can debug this app in sandboxed mode uint32_t maxBytes; maxBytes = le_cfg_GetInt(cfgIter, "maxFileSystemBytes", DEFAULT_LIMIT_MAX_FILE_SYSTEM_BYTES); maxBytes += ADD_FILE_SYSTEM_BYTES; // add an additional 512KBytes LE_INFO("Resetting maxFileSystemBytes to %d bytes", maxBytes); le_cfg_SetInt(cfgIter, "maxFileSystemBytes", maxBytes); // Add gdbserver and libs to the app's 'requires/files' section. le_cfg_GoToNode(cfgIter, "requires/files"); AddImportFiles(cfgIter, &GdbFilesImports, NUM_ARRAY_MEMBERS(GdbFilesImports)); // Add /proc to the app's dirs section. le_cfg_GoToParent(cfgIter); le_cfg_GoToNode(cfgIter, "dirs"); AddImportFiles(cfgIter, &GdbDirsImports, NUM_ARRAY_MEMBERS(GdbDirsImports)); // Delete the list of processes. le_cfg_GoToParent(cfgIter); le_cfg_GoToParent(cfgIter); int i; for (i = 0; i < NumProcs; i++) { char nodePath[LIMIT_MAX_PATH_BYTES]; int n = snprintf(nodePath, sizeof(nodePath), "procs/%s", ProcNames[i]); INTERNAL_ERR_IF(n >= sizeof(nodePath), "Node name is too long."); INTERNAL_ERR_IF(n < 0, "Format error. %m"); le_cfg_DeleteNode(cfgIter, nodePath); } le_cfg_CommitTxn(cfgIter); }