How to fix a broken system configtree?


#1

Hi,

I face a not starting legato framework, caused by app issue.

The app repeatedly writes to the systems config tree, while power supply is removed from system. After reboot, legato will not start. No apps are listed.

In logread i can see this messages:

Jan 1 00:00:30 futuretelematics user.err Legato: =ERR= | configTree[708]/configTree T=main | treeDb.c InternalReadNode() 2078 | Unexpected EOF or bad token in file. Jan 1 00:00:30 futuretelematics user.err Legato: =ERR= | configTree[708]/configTree T=main | treeDb.c LoadTree() 2336 | Could not parse configuration tree file: /opt/legato/configTree/system.paper.

How to restore the config tree without reinstalling legato and user apps ?

Thanks.


#2

Hi,

Yeah, we found this during our own internal load testing too, and fixed it, but the fix hasn’t made it to GitHub yet. :blush:

You’ll notice that there are two “system.xxxx” files in /opt/legato/configTree/. One is good and the other is corrupt (probably completely empty). The Config Tree is just opening the wrong one.

To work around, delete the corrupted file, and restart legato. You can tell which one to delete by looking at the file names. These files rotate through “system.rock”, “system.paper”, and “system.scissors”, where “paper wraps rock”, “scissors cut paper”, and “rock smashes scissors”. So, if there are both system.paper and system.scissors, delete system.paper, because “scissors cut paper”. :smiley:

To fix it, replace the function “UpdateRevision()” in framework/c/src/configTree/treeDb.c with the one below.

Sorry for the inconvenience.

–Jen

// -------------------------------------------------------------------------------------------------
/**
 *  Check the filesystem and get the "valid" version of the file.  That is, if there are two files
 *  for a given tree, we use the older one.  The idea being, if there are two versions of the same
 *  file in the filesystem then it's highly likely there was a system failure during a streaming
 *  operation.  So we abandon the newer file and go with the older more reliable file.
 */
// -------------------------------------------------------------------------------------------------
static void UpdateRevision
(
    tdb_TreeRef_t treeRef  ///< [IN] Update the revision for this tree object.
)
// -------------------------------------------------------------------------------------------------
{
    int newRevision = 0;

    if (TreeFileExists(treeRef->name, 1))
    {
        if (TreeFileExists(treeRef->name, 3))
        {
            newRevision = 3;
        }
        else
        {
            newRevision = 1;
        }
    }
    else if (TreeFileExists(treeRef->name, 3))
    {
        if (TreeFileExists(treeRef->name, 2))
        {
            newRevision = 2;
        }
        else
        {
            newRevision = 3;
        }
    }
    else if (TreeFileExists(treeRef->name, 2))
    {
        newRevision = 2;
    }

    treeRef->revisionId = newRevision;
}