Repository navigation
[Nexthop][bugfix] platform_manager: tolerate a failed BSP RPM query when the kmods are on disk - #1890
Open
sazeed-nexthop wants to merge 1 commit into
Open
sazeed-nexthop wants to merge 1 commit into
sazeed-nexthop wants to merge 1 commit into
Conversation
…kmods are on disk PkgManager::processAll() asked "is the BSP kmods RPM installed?" with `dnf list --installed` and treated any non-zero exit as "not installed". dnf exits 1 both for "no matching package" and for "rpmdb open failed", and on a root filesystem with <128 KB free it dies with SIGBUS (rpm's sqlite backend runs a write transaction on open). So a query that merely failed looked like a missing package: platform_manager unloaded the working BSP kmods, retried `dnf install` three times against the same unreadable rpmdb, and aborted via XLOG(FATAL). systemd then gave up after StartLimitBurst, /run/devmap never appeared, and led_service and qsfp_service crash-looped behind it. SystemInterface::isRpmInstalled() now runs `rpm -q <name> 2>&1` and returns std::optional<bool>: exit 0 without "error:" output is installed, exit 1 with "is not installed" is not installed, anything else (an "error:" line about the rpmdb, a signal exit, a spawn failure) is unknown. The command goes through PlatformUtils so it can be mocked. PkgManager::processAll() acts on unknown only when the running kernel's kmods.json is already on disk: it sets package_manager.process_rpm_failure, logs an FBOSS_ALERT (bsp_rpm_query_failed) and proceeds as installed, so the kmods it already has get loaded. If processRpms() throws while the kmods are on disk, it logs bsp_rpm_install_failed and continues instead of aborting. When the kmods are genuinely absent the behaviour is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pre-submission checklist
pip install -r requirements-dev.txt && pre-commit installpre-commit runSummary
Problem
When a switch reboots with its root filesystem full, platform_manager aborts on every start until systemd gives up (
StartLimitBurst). With platform_manager down,/run/devmapnever appears, so led_service and qsfp_service crash-loop behind it and the box comes up with no platform management and no transceivers until an operator frees disk space by hand.The abort is avoidable: the BSP kmods are already installed on disk. platform_manager only aborts because it cannot ask the package database whether they are, and it treats "could not ask" as "not installed".
Root cause
PkgManager::processAll()callsisRpmInstalled()and, onfalse, runsprocessRpms(): unload the kmods, remove installed RPMs,dnf installthree times, throw on failure.SystemInterface::isRpmInstalled()runsdnf list <rpm> --installedand returnsexitStatus == 0. dnf exits 1 both for "no matching package" and for "rpmdb open failed", so a broken query is indistinguishable from a missing package.CREATE TABLE IF NOT EXISTS 'Packages'). Measured on a Wedge800BNHP:rpm -qanddnf list --installedwork at 128 KB free on/and die with SIGBUS (exit 135) at 64 KB. On such a boot every attempt inprocessRpms()also dies, it throws, andMain.cppaborts viaXLOG(FATAL).Each platform_manager start on such a boot shows the same sequence in the journal: one dnf core (
isRpmInstalled), one rpm core (removeInstalledRpms), three dnf cores (the install retries), then platform_manager itself dumps core.Fix
SystemInterface::isRpmInstalled()returnsstd::optional<bool>and runsrpm -q <name> 2>&1instead ofdnf list --installed. Exit 0 with noerror:text is installed; exit 1 with "is not installed" is not installed; anything else (anerror:line about the rpmdb, a signal exit, a spawn failure) is unknown. The command goes throughPlatformUtilsso it can be mocked.PkgManager::processAll()acts on unknown only when the running kernel'skmods.jsonis already on disk (bspKmodsOnDisk()): set thepackage_manager.process_rpm_failurecounter, log anFBOSS_ALERT(bsp_rpm_query_failed), and proceed as installed, so the kmods it already has get loaded. IfprocessRpms()throws while the kmods are on disk, logbsp_rpm_install_failedand continue instead of aborting. When the kmods are genuinely absent the behaviour is unchanged: the exception propagates and platform_manager aborts as before.pkg_managerlinksstructured_logger(cmake + BUCK).Not changed: the unload/reload sequence after a real install, and
--local_rpm_pathhandling.Test Plan
Unit tests (gmock,
pkg_manager_test)SystemInterfaceTest.isRpmInstalled: installed, not installed,error:text with exit 1, exit 135 (SIGBUS), spawn failure.PkgManagerTest:EnablePkgMgmntRpmQueryFailsWithKmodsOnDisk(kmods loaded,processRpms()never called),EnablePkgMgmntRpmQueryFailsWithoutKmods(falls through to the existing install path),EnablePkgMgmntInstallFailsWithKmodsOnDisk(continues and loads kmods),EnablePkgMgmntInstallFailsWithoutKmods(still throws).Built on top of this branch with the OSS cmake build (
fboss/oss/scripts/docker-build.py,platform_managertarget plus a local-only test executable for the two test files) and run in the build container:On hardware (Wedge800BNHP, Tomahawk5, kernel 6.11;
/filled to 64 KB free withfallocate+dd, then reboot)/run/devmap/xcvrsFree space stayed at 64 KB for the whole boot, so the rpm query failed exactly as in the stock image; the only difference is that platform_manager now carries on with the kmods it has.
A healthy boot with ample free space is unaffected:
rpm -qanswers installed and the existing path runs.🤖 Generated with Claude Code