示例#1
0
// -------------------------------------------------------------------------------------------------
static void DumpTreeJSON
(
    le_cfg_IteratorRef_t iterRef,  ///< Read the tree data from this iterator.
    json_t* jsonObject             ///< JSON object to hold the tree data.
)
// -------------------------------------------------------------------------------------------------
{
    // Note that because this is a recursive function, the buffer here is static in order to save on
    // stack space.  The implication here is that we then have to be careful how it is later
    // accessed.  Also, this makes the function not thread safe.  But this trade off was made as
    // this was not intended to be a multi-threaded program.
    static char strBuffer[LE_CFG_STR_LEN_BYTES] = "";

    // Build up the child array.
    json_t* childArrayPtr = json_array();

    do
    {
        // Simply grab the name and the type of the current node.
        le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer));
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            // It's a stem object, so mark this item as being a stem and recurse into the stem's
            // sub-items.
            case LE_CFG_TYPE_STEM:
                {
                    json_t* nodePtr = CreateJsonNode(strBuffer, NodeTypeStr(type));

                    le_cfg_GoToFirstChild(iterRef);
                    DumpTreeJSON(iterRef, nodePtr);
                    le_cfg_GoToParent(iterRef);
                    json_array_append(childArrayPtr, nodePtr);
                }
                break;

            default:
                {
                    json_t* nodePtr = CreateJsonNodeFromIterator(iterRef);
                    if (nodePtr != NULL)
                    {
                        json_array_append(childArrayPtr, nodePtr);
                    }
                }
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);

    // Set children into the JSON document.
    json_object_set_new(jsonObject, JSON_FIELD_CHILDREN, childArrayPtr);
}
示例#2
0
static void DumpTree(le_cfg_IteratorRef_t iterRef, size_t indent)
{
    if (le_arg_NumArgs() == 1)
    {
        return;
    }

    static char strBuffer[STR_SIZE] = { 0 };

    do
    {
        size_t i;

        for (i = 0; i < indent; i++)
        {
            printf(" ");
        }

        le_cfg_GetNodeName(iterRef, "", strBuffer, STR_SIZE);
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            case LE_CFG_TYPE_STEM:
                printf("%s/\n", strBuffer);

                le_cfg_GoToFirstChild(iterRef);
                DumpTree(iterRef, indent + 2);
                le_cfg_GoToParent(iterRef);
                break;

            case LE_CFG_TYPE_EMPTY:
                printf("%s~~\n", strBuffer);
                break;

            default:
                printf("%s<%s> == ", strBuffer, NodeTypeStr(iterRef));
                le_cfg_GetString(iterRef, "", strBuffer, STR_SIZE, "");
                printf("%s\n", strBuffer);
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);
}
示例#3
0
//--------------------------------------------------------------------------------------------------
static void SetRLimit
(
    pid_t pid,                      // The pid of the process to set the limit for.
    le_cfg_IteratorRef_t procCfg,   // The iterator for the process.  This is a iterator is owned by
                                    // the caller and should not be deleted in this function.
    const char* resourceName,       // The resource name in the config tree.
    int resourceID,                 // The resource ID that setrlimit() expects.
    rlim_t defaultValue             // The default value for this resource limit.
)
{
    // Initialize the limit to the defaults.
    struct rlimit lim = {defaultValue, defaultValue};

    // Move the iterator to the resource limit to read.
    le_cfg_GoToNode(procCfg, resourceName);
    if (le_cfg_NodeExists(procCfg, "") == false)
    {
        LE_WARN("No resource limit %s.  Using the default value %lu.", resourceName, defaultValue);
    }
    else
    {
        // Try reading the resource limit from the config tree.
        if (GetCfgResourceLimit(procCfg, &(lim.rlim_max)) != LE_OK)
        {
            LE_ERROR("Configured resource limit %s is invalid.  Using the default value %lu.",
                     resourceName, defaultValue);
        }
        else
        {
            // Check that the limit does not exceed the maximum.
            if ( (resourceID == RLIMIT_NOFILE) && (lim.rlim_max > MAX_LIMIT_NUM_FD) )
            {
                LE_ERROR("Resource limit %s is greater than the maximum allowed limit (%d).  Using the \
    maximum allowed value.", resourceName, MAX_LIMIT_NUM_FD);

                lim.rlim_max = MAX_LIMIT_NUM_FD;
            }
        }

        // Move the iterator back to where it was.
        LE_ASSERT(le_cfg_GoToParent(procCfg) == LE_OK);
    }
示例#4
0
//--------------------------------------------------------------------------------------------------
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);
}
示例#5
0
// -------------------------------------------------------------------------------------------------
static le_result_t HandleImportJSONIteration
(
    le_cfg_IteratorRef_t iterRef,  ///< Dump the JSON data into this iterator.
    json_t* nodePtr                ///< From this JSON object.
)
// -------------------------------------------------------------------------------------------------
{
    // Get value
    json_t* value = json_object_get(nodePtr, JSON_FIELD_VALUE);

    // Check type
    const char* typeStr = json_string_value(json_object_get(nodePtr, JSON_FIELD_TYPE));
    le_cfg_nodeType_t type = GetNodeTypeFromString(typeStr);

    switch (type)
    {
        case LE_CFG_TYPE_BOOL:
            le_cfg_SetBool(iterRef, "", json_is_true(value));
            break;

        case LE_CFG_TYPE_STRING:
            le_cfg_SetString(iterRef, "", json_string_value(value));
            break;

        case LE_CFG_TYPE_INT:
            le_cfg_SetInt(iterRef, "", json_integer_value(value));
            break;

        case LE_CFG_TYPE_FLOAT:
            le_cfg_SetFloat(iterRef, "", json_real_value(value));
            break;

        case LE_CFG_TYPE_STEM:
            {
                // Iterate on children
                json_t* childrenPtr = json_object_get(nodePtr, JSON_FIELD_CHILDREN);
                json_t* childPtr;
                int i;

                json_array_foreach(childrenPtr, i, childPtr)
                {
                    // Get name
                    const char* name = json_string_value(json_object_get(childPtr,
                                                                         JSON_FIELD_NAME));

                    // Is node exist with this name?
                    le_cfg_nodeType_t existingType = le_cfg_GetNodeType(iterRef, name);
                    switch (existingType)
                    {
                        case LE_CFG_TYPE_DOESNT_EXIST:
                        case LE_CFG_TYPE_STEM:
                        case LE_CFG_TYPE_EMPTY:
                            // Not existing, already a stem or empty node, nothing to do
                        break;

                        default:
                            // Issue with node creation
                            fprintf(stderr, "Node conflict when importing, at node %s", name);
                            return LE_NOT_POSSIBLE;
                        break;
                    }

                    // Iterate to this child
                    le_cfg_GoToNode(iterRef, name);

                    // Iterate
                    le_result_t subResult = HandleImportJSONIteration(iterRef, childPtr);
                    if (subResult != LE_OK)
                    {
                        // Something went wrong
                        return subResult;
                    }

                    // Go back to parent
                    le_cfg_GoToParent(iterRef);
                }
            }
            break;

        default:
            return LE_FAULT;
    }

    return LE_OK;
}
示例#6
0
// -------------------------------------------------------------------------------------------------
static int HandleGetJSON
(
    const char* nodePathPtr,  ///< Path to the node in the configTree.
    const char* filePathPtr   ///< Path to the file in the file system.  If NULL STDOUT is used
                              ///< instead of a file.
)
// -------------------------------------------------------------------------------------------------
{
    json_t* nodePtr = NULL;

    // Get the node path from our command line arguments.
    if (strcmp("*", nodePathPtr) == 0)
    {
        // Dump all trees
        // Create JSON root item
        json_t* rootPtr = CreateJsonNode("root", "root");
        json_t* treeListPtr = json_array();

        // Loop through the trees in the system.
        le_cfgAdmin_IteratorRef_t iteratorRef = le_cfgAdmin_CreateTreeIterator();
        while (le_cfgAdmin_NextTree(iteratorRef) == LE_OK)
        {
            // Allocate space for the tree name, plus space for a trailing :/ used when we create a
            // transaction for that tree.
            char treeName[MAX_TREE_NAME_BYTES + 2] = "";

            if (le_cfgAdmin_GetTreeName(iteratorRef, treeName, MAX_TREE_NAME_BYTES) != LE_OK)
            {
                continue;
            }

            // JSON node for the tree.
            json_t* treeNodePtr = CreateJsonNode(treeName, "tree");
            strcat(treeName, ":/");

            // Start a read transaction at the specified node path.  Then dump the value, (if any.)
            le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(treeName);
            le_cfg_GoToFirstChild(iterRef);

            // Dump tree to JSON
            DumpTreeJSON(iterRef, treeNodePtr);
            le_cfg_CancelTxn(iterRef);

            json_array_append(treeListPtr, treeNodePtr);
        }
        le_cfgAdmin_ReleaseTreeIterator(iteratorRef);

        // Finalize root object...
        json_object_set_new(rootPtr, "trees", treeListPtr);
        nodePtr = rootPtr;
    }
    else
    {
        // Start a read transaction at the specified node path.  Then dump the value, (if any.)
        le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(nodePathPtr);

        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");
        switch (type)
        {
            case LE_CFG_TYPE_STEM:
                {
                    char strBuffer[LE_CFG_STR_LEN_BYTES] = "";
                    char nodeType[LE_CFG_STR_LEN_BYTES] = "";
                    le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer));

                    // If no name, we are dumping a complete tree.
                    if (strlen(strBuffer) == 0)
                    {
                        strcpy(nodeType, "tree");
                    }
                    else
                    {
                        strcpy(nodeType, NodeTypeStr(type));
                    }

                    nodePtr = CreateJsonNode(strBuffer, nodeType);
                    le_cfg_GoToFirstChild(iterRef);
                    DumpTreeJSON(iterRef, nodePtr);
                    le_cfg_GoToParent(iterRef);
                }
                break;

            default:
                nodePtr = CreateJsonNodeFromIterator(iterRef);
                break;
        }

        le_cfg_CancelTxn(iterRef);
    }

    if (nodePtr == NULL)
    {
        // Empty node
        nodePtr = json_object();
    }

    // Dump Json content
    // stdout mode?

    int result = EXIT_SUCCESS;

    if (filePathPtr == NULL)
    {
        printf("%s\n", json_dumps(nodePtr, JSON_COMPACT));
    }
    else if (json_dump_file(nodePtr, filePathPtr, JSON_COMPACT) != 0)
    {
        result = EXIT_FAILURE;
    }

    json_decref(nodePtr);
    return result;
}
示例#7
0
// -------------------------------------------------------------------------------------------------
static void DumpTree
(
    le_cfg_IteratorRef_t iterRef,  ///< Write out the tree pointed to by this iterator.
    size_t indent                  ///< The amount of indentation to use for this item.
)
// -------------------------------------------------------------------------------------------------
{
    // Note that because this is a recursive function, the buffer here is static in order to save on
    // stack space.  The implication here is that we then have to be careful how it is later
    // accessed.  Also, this makes the function not thread safe.  But this trade off was made as
    // this was not intended to be a multi-threaded program.
    static char strBuffer[LE_CFG_STR_LEN_BYTES] = "";

    do
    {
        // Quick and dirty way to indent the tree item.
        size_t i;

        for (i = 0; i < indent; i++)
        {
            printf(" ");
        }

        // Simply grab the name and the type of the current node.
        le_cfg_GetNodeName(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES);
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            // It's a stem object, so mark this item as being a stem and recurse into the stem's
            // sub-items.
            case LE_CFG_TYPE_STEM:
                printf("%s/\n", strBuffer);

                le_cfg_GoToFirstChild(iterRef);
                DumpTree(iterRef, indent + 2);
                le_cfg_GoToParent(iterRef);

                // If we got back up to where we started then don't iterate the "root" node's
                // siblings.
                if (indent == 0)
                {
                    return;
                }
                break;

            // The node is empty, so simply mark it as such.
            case LE_CFG_TYPE_EMPTY:
                printf("%s<empty>\n", strBuffer);
                break;

            case LE_CFG_TYPE_BOOL:
                {
                    char* value = NULL;

                    if (le_cfg_GetBool(iterRef, "", false))
                    {
                        value = "true";
                    }
                    else
                    {
                        value = "false";
                    }

                    printf("%s<bool> == %s\n", strBuffer, value);
                }
                break;

            // The node has a different type.  So write out the name and the type.  Then print the
            // value.
            default:
                printf("%s<%s> == ", strBuffer, NodeTypeStr(le_cfg_GetNodeType(iterRef, "")));
                le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, "");
                printf("%s\n", strBuffer);
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);
}