utils

package
v0.0.0-...-9a980d2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	VBOOT_NONE             VbootEnforcementType = "NONE"
	VBOOT_SOFTWARE_ENFORCE                      = "SOFTWARE_ENFORCE"
	VBOOT_HARDWARE_ENFORCE                      = "HARDWARE_ENFORCE"
)
View Source
const AST_SRAM_VBS_BASE = 0x1E720200 // ast2400, ast2500

AST_SRAM_VBS_BASE is the location in SRAM used for verified boot content/flags.

View Source
const AST_SRAM_VBS_BASE_G6 = 0x10015800 // ast2600
View Source
const AST_SRAM_VBS_SIZE = 56

AST_SRAM_VBS_SIZE is the size of verified boot content/flags.

View Source
const ProcMtdFilePath = "/proc/mtd"

Variables

View Source
var BMCLitePlatforms = []string{
	"acctonbmc",
	"celesticabmc",
	"fbdarwin",
	"janga",
	"meru",
	"minipack3n",
	"montblanc",
	"morgan800cc",
	"nexthopbmc",
	"tahan",
}

BMCLitePlatforms contains the list of BMC lite platform names

View Source
var CheckOtherFlasherRunning = func(flashyStepBaseNames []string) error {
	allFlasherBaseNames := SafeAppendString(otherFlasherBaseNames, flashyStepBaseNames)

	otherProcCmdlinePaths := getOtherProcCmdlinePaths()

	err := checkNoBaseNameExistsInProcCmdlinePaths(allFlasherBaseNames,
		otherProcCmdlinePaths)
	if err != nil {
		return fmt.Errorf("Another flasher running: %v", err)
	}
	return nil
}

CheckOtherFlasherRunning return an error if any other flashers are running. It takes in the baseNames of all flashy's steps (e.g. 00_truncate_logs) to make sure no other instance of flashy is running.

View Source
var GetBSMFlashManufacturerFromFile = func() (string, error) {
	spiManufacturerBuf, err := fileutils.ReadFile(spiManufacturerPath)
	if err != nil {
		return "", fmt.Errorf("Error reading '%v': %v",
			spiManufacturerPath, err)
	}
	if len(spiManufacturerBuf) == 0 {
		return "", fmt.Errorf("'%v' file is empty", spiManufacturerPath)
	}
	return strings.TrimSpace(string(spiManufacturerBuf)), nil
}

Checks SPI flash manufacturer on BSM (ie Winbond or Macronix). Related to S483584, which is a SEV affecting specific versions on Winbond chips

View Source
var GetHealthdConfig = func() (*gabs.Container, error) {
	buf, err := fileutils.ReadFile(healthdConfigFilePath)
	if err != nil {
		return nil, fmt.Errorf("Unable to open healthd-config.json: %w", err)
	}
	healthdConfig, err := gabs.ParseJSON(buf)
	if err != nil {
		return nil, fmt.Errorf("Unable to parse healthd-config.json: %w", err)
	}
	return healthdConfig, nil
}

GetHealthdConfig gets the healthd config in a JSON container.

View Source
var GetMTDInfoFromSpecifier = func(deviceSpecifier string) (MtdInfo, error) {
	var mtdInfo MtdInfo

	procMTDBuf, err := fileutils.ReadFile(ProcMtdFilePath)
	if err != nil {
		return mtdInfo, fmt.Errorf("Unable to read from /proc/mtd: %v", err)
	}
	procMTD := string(procMTDBuf)

	const rDev = "dev"
	const rSize = "size"
	const rErasesize = "erasesize"

	regEx := fmt.Sprintf("(?m)^(?P<%v>mtd[0-9a-f]+): (?P<%v>[0-9a-f]+) (?P<%v>[0-9a-f]+) \"%v\"$",
		rDev, rSize, rErasesize, deviceSpecifier)

	mtdMap, err := GetRegexSubexpMap(regEx, procMTD)
	if err != nil {
		return mtdInfo, fmt.Errorf("Error finding MTD entry in /proc/mtd for flash device 'mtd:%v'",
			deviceSpecifier)
	}

	size, err := strconv.ParseUint(mtdMap[rSize], 16, 32)
	if err != nil {
		return mtdInfo, fmt.Errorf("Failed to parse size: %v", err)
	}
	erasesize, err := strconv.ParseUint(mtdMap[rErasesize], 16, 32)
	if err != nil {
		return mtdInfo, fmt.Errorf("Failed to parse erasesize: %v", err)
	}
	return MtdInfo{
		Dev:       mtdMap[rDev],
		Size:      uint32(size),
		Erasesize: uint32(erasesize),
	}, nil
}

GetMtdInfoFromSpecifier MtdInfo for the mtd device specifier. Information is obtained from /proc/mtd.

View Source
var GetMachine = func() (string, error) {
	var uts syscall.Utsname

	err := syscall.Uname(&uts)
	if err != nil {
		return "unknown", err
	}

	machine := make([]byte, 0, len(uts.Machine))
	for _, v := range uts.Machine {
		if v == 0 {
			break
		}
		machine = append(machine, byte(v))
	}
	return string(machine), nil
}
View Source
var GetMemInfo = func() (*MemInfo, error) {
	buf, err := fileutils.ReadFile("/proc/meminfo")
	if err != nil {
		return nil, fmt.Errorf("Unable to open /proc/meminfo: %v", err)
	}

	memInfoStr := string(buf)

	memFreeRegex := regexp.MustCompile(`(?m)^MemFree: +([0-9]+) kB$`)
	memTotalRegex := regexp.MustCompile(`(?m)^MemTotal: +([0-9]+) kB$`)

	memFreeMatch := memFreeRegex.FindStringSubmatch(memInfoStr)
	if len(memFreeMatch) < 2 {
		return nil, fmt.Errorf("Unable to get MemFree in /proc/meminfo")
	}
	memFree, _ := strconv.ParseUint(memFreeMatch[1], 10, 64)
	memFree *= 1024

	memTotalMatch := memTotalRegex.FindStringSubmatch(memInfoStr)
	if len(memTotalMatch) < 2 {
		return nil, fmt.Errorf("Unable to get MemTotal in /proc/meminfo")
	}
	memTotal, _ := strconv.ParseUint(memTotalMatch[1], 10, 64)
	memTotal *= 1024

	return &MemInfo{
		memTotal,
		memFree,
	}, nil
}

GetMemInfo gets MemInfo from /proc/meminfo. Note that this assumes kB units for MemFree and MemTotal and will fail otherwise.

View Source
var GetOpenBMCPlatformFromIssueFile = func() (string, error) {
	const rPlatform = "platform"
	const re = `(?i)(?:.*\s)?(?P<%v>[^\s-]+)-v[0-9]+(?:\.[0-9]+)*(?:[^\s]*)?`
	etcIssuePlatformRegEx := fmt.Sprintf(re, rPlatform)

	etcIssueBuf, err := fileutils.ReadFile(etcIssueFilePath)
	if err != nil {
		return "", fmt.Errorf("Error reading %v: %v",
			etcIssueFilePath, err)
	}
	etcIssueStr := string(etcIssueBuf)

	if strings.HasPrefix(strings.ToLower(etcIssueStr), "openbmc release \n") {
		return "unknown", nil
	}

	etcIssueMap, err := GetRegexSubexpMap(
		etcIssuePlatformRegEx, etcIssueStr)

	if err != nil {

		fallbackPatterns := []string{

			`(?i)(?:.*\s)?(?P<platform>[^\s-]+)-[a-f0-9]{8,}`,

			`(?i)(?:.*\s)?(?P<platform>[^\s-]+)\s+v[0-9]+`,
		}

		for _, pattern := range fallbackPatterns {
			fallbackRegEx := fmt.Sprintf(pattern)
			etcIssueMap, err = GetRegexSubexpMap(fallbackRegEx, etcIssueStr)
			if err == nil {
				break
			}
		}

		if err != nil {
			return "", fmt.Errorf("Unable to get platform from %v: %v",
				etcIssueFilePath, err)
		}
	}

	platform := etcIssueMap[rPlatform]
	if platform == "" {
		return "", fmt.Errorf("Unable to get platform from %v: missing platform info",
			etcIssueFilePath)
	}

	return strings.ToLower(platform), nil
}

GetOpenBMCPlatformFromIssueFile gets OpenBMC platform from /etc/issue. examples: fbtp, wedge100 WARNING: There is no guarantee that /etc/issue is well-formed in old images.

View Source
var GetOpenBMCVersionFromIssueFile = func() (string, error) {
	const rVersion = "version"
	const re = `^(?P<facebook>facebook )?open ?bmc(?P<release> release)? ?(?P<%v>[^\s]+)`
	etcIssueVersionRegEx := fmt.Sprintf(re, rVersion)

	etcIssueBuf, err := fileutils.ReadFile(etcIssueFilePath)
	if err != nil {
		return "", fmt.Errorf("Error reading %v: %v",
			etcIssueFilePath, err)
	}
	etcIssueStr := strings.ToLower(string(etcIssueBuf))

	if strings.HasPrefix(etcIssueStr, "openbmc release \n") {
		return "unknown-v1", nil
	}

	etcIssueMap, err := GetRegexSubexpMap(
		etcIssueVersionRegEx, etcIssueStr)

	if err != nil {

		return "",
			fmt.Errorf("Unable to get version from %v: %v",
				etcIssueFilePath, err)
	}

	version := etcIssueMap[rVersion]
	if version == "release" {

		return "",
			fmt.Errorf("Unable to get version from %v: missing version info",
				etcIssueFilePath)
	}

	if version[0] == 'v' && !strings.Contains(version, "-") {
		version = "unknown-" + version
	}
	return version, nil
}

GetOpenBMCVersionFromIssueFile gets OpenBMC version from /etc/issue. examples: fbtp-v2020.09.1, wedge100-v2020.07.1 WARNING: There is no guarantee that /etc/issue is well-formed in old images.

View Source
var GetVbootEnforcement = func() VbootEnforcementType {
	vbs, err := GetVbs()
	if err != nil {
		log.Printf("Assuming this is not a vboot system because: %v", err)
		return VBOOT_NONE
	}

	if vbs.Hardware_enforce == 1 {
		return VBOOT_HARDWARE_ENFORCE
	} else if vbs.Software_enforce == 1 {
		return VBOOT_SOFTWARE_ENFORCE
	}
	return VBOOT_NONE
}

GetVbootEnforcement gets the vboot enforcement type of the system.

View Source
var GetVbs = func() (Vbs, error) {
	var vbs Vbs
	var baseaddr uint32

	if !vbootPartitionExists() {
		return vbs, fmt.Errorf("Not a Vboot system: vboot partition (rom) does not exist.")
	}

	machine, err := GetMachine()
	if err != nil {
		return vbs, fmt.Errorf("Unable to fetch utsinfo: %w", err)
	}

	if machine == "armv7l" {
		baseaddr = AST_SRAM_VBS_BASE_G6
	} else {
		baseaddr = AST_SRAM_VBS_BASE
	}
	log.Printf("Machine type from utsinfo: %v, base address: 0x%x", machine, baseaddr)

	mmapOffset := fileutils.GetPageOffsettedBase(baseaddr)
	length := fileutils.Pagesize

	pageData, err := fileutils.MmapFileRange("/dev/mem", int64(mmapOffset),
		length, syscall.PROT_READ, syscall.MAP_SHARED)
	if err != nil {
		return vbs, fmt.Errorf("Unable to mmap /dev/mem: %w", err)
	}
	defer fileutils.Munmap(pageData)

	dataOffset := fileutils.GetPageOffsettedOffset(baseaddr)
	vbsEndOffset, err := AddU32(dataOffset, AST_SRAM_VBS_SIZE)
	if err != nil {
		return vbs, fmt.Errorf("VBS end offset overflowed: %w", err)
	}
	vbsData, err := BytesSliceRange(pageData, dataOffset, vbsEndOffset)
	if err != nil {
		return vbs, fmt.Errorf("Failed to get vbs data: %w", err)
	}

	return decodeVbs(vbsData)
}

GetVbs tries to get the Vbs struct by reading off /dev/mem. This errors out if the vboot partition ("rom") does not exist.

View Source
var HealthdExists = func() bool {
	return fileutils.FileExists(healthdConfigFilePath)
}

HealthdExists checks if healthd exists in this system by checking existence of the healthd config file.

View Source
var IsBMCLite = func() bool {
	issueBuf, err := fileutils.ReadFile(etcIssueFilePath)
	if err != nil {
		return false
	}

	for _, platform := range BMCLitePlatforms {
		if strings.Contains(string(issueBuf), platform) {
			return true
		}
	}
	return false
}

IsBMCLite check whether the system is running BMC-lite For S368275. Uses dynamically generated list.

View Source
var IsDataPartitionMounted = func() (bool, error) {
	procMountsDat, err := fileutils.ReadFile(procMountsPath)
	if err != nil {
		return false, fmt.Errorf("Cannot read /proc/mounts: %v", err)
	}

	regEx := `(?m)^[^ ]+ /mnt/data [^ ]+ [^ ]+ [0-9]+ [0-9]+$`
	regExMap, err := GetAllRegexSubexpMap(regEx, string(procMountsDat))
	if err != nil {
		return false, fmt.Errorf("regex error: %v", err)
	}

	return len(regExMap) != 0, nil
}

IsDataPartitionMounted checks if /mnt/data is mounted

View Source
var IsLFOpenBMC = func() bool {
	const magic = "OPENBMC_TARGET_MACHINE"

	osReleaseBuf, err := fileutils.ReadFile(etcOsReleaseFilePath)
	if err != nil {
		return false
	}

	return strings.Contains(string(osReleaseBuf), magic)
}

IsLFOpenBMC check whether the system is running LF-OpenBMC by checking whether the string "OPENBMC_TARGET_MACHINE" exists in /etc/os-release.

View Source
var IsOpenBMC = func() (bool, error) {
	const magic = "OpenBMC"
	const ancient_magic = "Open BMC Release"

	etcIssueBuf, err := fileutils.ReadFile(etcIssueFilePath)
	if err != nil {
		return false, fmt.Errorf("Error reading '%v': %v",
			etcIssueFilePath, err)
	}

	isOpenBMC := strings.Contains(string(etcIssueBuf), magic)
	if !isOpenBMC {
		isOpenBMC = strings.Contains(string(etcIssueBuf), ancient_magic)
	}
	return isOpenBMC, nil
}

IsOpenBMC check whether the system is an OpenBMC by checking whether the string "OpenBMC" exists in /etc/issue.

View Source
var IsPfrSystem = func() bool {
	log.Printf("Checking whether the system is PFR-enabled")

	exitCode, _, _, _ := RunCommand(
		[]string{"i2craw", "12", "0x38", "-r", "1", "-w", "0x0A"},
		30*time.Second,
	)
	isPfr := exitCode == 0
	if isPfr {
		log.Printf("This system is PFR-enabled")
	} else {
		log.Printf("This system is not PFR-enabled")
	}
	return isPfr
}

IsPfrSystem checks whether the system is a PFR-enabled system or not. This is just a temporary method, due to be replaced by pfr-util.

View Source
var ListProcessesMatchingRegex = func(regex *regexp.Regexp) ([]*os.Process, error) {

	allProcCmdlines, _ := fileutils.Glob("/proc/[0-9]*/cmdline")

	procs := []*os.Process{}
	pidRegex := regexp.MustCompile(`/proc/([0-9]+)/`)

	for _, cmdlinePath := range allProcCmdlines {
		buf, err := fileutils.ReadFile(cmdlinePath)

		if err == nil && regex.Match(buf) {
			pidRegexMatch := pidRegex.FindStringSubmatch(cmdlinePath)

			pid, _ := strconv.Atoi(pidRegexMatch[1])
			if proc, err := os.FindProcess(pid); err == nil {
				procs = append(procs, proc)
			}

		}
	}

	return procs, nil
}
View Source
var PetWatchdog = func() {

	if IsBMCLite() {
		log.Printf("Watchdog not petted; BMC Lite")
		return
	}

	for i := 0; i < 10; i++ {
		if tryPetWatchdog(false) {
			log.Printf("Watchdog petted")
			return
		}
		time.Sleep(1 * time.Second)
	}
	log.Printf("Watchdog not petted; yielded CPU instead")
}

Try to pet the watchdog and increase its timeout. This works in two ways:

  • When /dev/watchdog is busy because it's held open by healthd / systemd / fscd, the delay here will hopefully allow the thread petting the watchdog to get some CPU time.

  • When /dev/watchdog it NOT busy and there are no concurrent instances of wdtcli, the watchdog timeout will be extended and the watchdog petted.

View Source
var PetWatchdogLoop = func() {

	if IsBMCLite() {
		log.Printf("Not starting PetWatchdogLoop; BMC Lite")
		return
	}

	log.Printf("PetWatchdogLoop started")
	for {
		if tryPetWatchdog(true) {
			log.Printf("Watchdog petted")
		}
		time.Sleep(5 * time.Second)
	}
}
View Source
var RestartHealthd = func(wait bool, supervisor string) error {
	if !fileutils.PathExists("/etc/sv/healthd") {
		return fmt.Errorf("Error restarting healthd: '/etc/sv/healthd' does not exist")
	}

	code, err, _, _ := RunCommand([]string{supervisor, "status", "healthd"}, 60*time.Second)
	if err != nil || code != 0 {
		log.Printf("healthd doesn't seem to be running.  Wait for 30s to " +
			"ensure watchdog is stable.")
		Sleep(30 * time.Second)
		return nil
	}

	RunCommand([]string{supervisor, "stop", "healthd"}, 60*time.Second)

	PetWatchdog()

	_, err, _, _ = RunCommand([]string{supervisor, "start", "healthd"}, 60*time.Second)

	if wait {
		log.Printf("Sleeping for 30s after healthd restart to make sure " +
			"healthd is stable.")
		Sleep(30 * time.Second)
	}

	return err
}

RestartHealthd restarts the healthd process.

View Source
var RunCommand = func(cmdArr []string, timeout time.Duration) (int, error, string, string) {
	start := time.Now()
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	if len(cmdArr) == 0 {
		return 1, fmt.Errorf("Cannot run empty command"), "", ""
	}

	fullCmdStr := strings.Join(cmdArr[:], " ")
	log.Printf("Running command '%v' with %v timeout", fullCmdStr, timeout)
	cmd := exec.CommandContext(ctx, cmdArr[0], cmdArr[1:]...)

	var stdoutStr, stderrStr string
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return 1, fmt.Errorf("Unable to open stdout pipe: %v", err), "", ""
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return 1, fmt.Errorf("Unable to open stderr pipe: %v", err), "", ""
	}
	stdoutScanner := bufio.NewScanner(stdout)
	stderrScanner := bufio.NewScanner(stderr)
	stdoutDone := make(chan struct{})
	stderrDone := make(chan struct{})
	go logScanner(stdoutScanner, stdoutDone, "stdout: ", &stdoutStr)
	go logScanner(stderrScanner, stderrDone, "stderr: ", &stderrStr)

	exitCode := 1

	if err := cmd.Start(); err != nil {
		log.Printf("Command '%v' failed to start: %v", fullCmdStr, err)

		return exitCode, err, stdoutStr, stderrStr
	}

	<-stdoutDone
	<-stderrDone

	err = cmd.Wait()
	if err != nil {
		if exitErr, ok := err.(*exec.ExitError); ok {

			waitStatus := exitErr.Sys().(syscall.WaitStatus)
			exitCode = waitStatus.ExitStatus()
		} else {
			log.Printf("Could not get exit code, defaulting to '1'")
		}
	} else {

		waitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus)
		exitCode = waitStatus.ExitStatus()
	}

	elapsed := time.Since(start)

	if ctx.Err() == context.DeadlineExceeded {
		log.Printf("Command '%v' timed out after %v", fullCmdStr, timeout)

		err = ctx.Err()
	} else {
		log.Printf("Command '%v' exited with code %v after %v", fullCmdStr, exitCode, elapsed)
	}

	return exitCode, err, stdoutStr, stderrStr
}

RunCommand runs command and pipes live output. Returns exitcode, error, stdout (string), stderr (string) if non-zero/error returned or timed out. Returns 0, nil, stdout (string), stderr (string) if successfully run.

View Source
var RunCommandWithRetries = func(cmdArr []string, timeout time.Duration, maxAttempts int, interval time.Duration) (int, error, string, string) {
	exitCode, err, stdoutStr, stderrStr := 1, fmt.Errorf("Command failed to run"), "", ""

	if maxAttempts < 1 {
		err = fmt.Errorf("Command failed to run: maxAttempts must be > 0 (got %v)", maxAttempts)
		return exitCode, err, stdoutStr, stderrStr
	}

	fullCmdStr := strings.Join(cmdArr[:], " ")
	for attempt := 1; attempt <= maxAttempts; attempt++ {
		log.Printf("Attempt %v of %v: Running command '%v' with timeout %v and retry interval %v",
			attempt, maxAttempts, fullCmdStr, timeout, interval)

		exitCode, err, stdoutStr, stderrStr = RunCommand(cmdArr, timeout)
		if err == nil {
			log.Printf("Attempt %v of %v succeeded", attempt, maxAttempts)
			break
		} else {
			log.Printf("Attempt %v of %v failed", attempt, maxAttempts)
			if attempt < maxAttempts {
				log.Printf("Sleeping for %v before retrying", interval)
				Sleep(interval)
			} else {
				log.Printf("Max attempts (%v) reached. Returning with error.", maxAttempts)
			}
		}
	}
	return exitCode, err, stdoutStr, stderrStr
}

RunCommandWithRetries calls RunCommand repeatedly until succeeded or maxAttempts is reached. Between attempts, an interval is applied. Returns the results from the first succeeding run or last tried run.

View Source
var Sleep = time.Sleep

Sleep function variable for mocking purposes.

View Source
var SystemdAvailable = func() (bool, error) {
	const cmdlinePath = "/proc/1/cmdline"

	if fileutils.FileExists(cmdlinePath) {
		buf, err := fileutils.ReadFile(cmdlinePath)
		if err != nil {
			return false, fmt.Errorf("%v exists but cannot be read: %v",
				cmdlinePath, err)
		}

		contains := strings.Contains(string(buf), "systemd")

		return contains, nil
	}

	return false, nil
}

SystemdAvailable checks whether systemd is available.

Functions

func AddU32

func AddU32(x, y uint32) (uint32, error)

AddU32 returns an error if the result overflowed Uint32 bounds.

func BytesSliceRange

func BytesSliceRange(s []byte, start, end uint32) ([]byte, error)

BytesSliceRange returns s[start:end] but with bounds checks

func CRC16

func CRC16(data []byte) uint16

CRC16 returns the crc16 checksum of data.

func GetAllRegexSubexpMap

func GetAllRegexSubexpMap(regEx, inputString string) ([](map[string]string), error)

GetAllRegexSubexpMap is the 'All' version of GetRegexSubexpMap that tries to match as many strings as possible. Returns an empty list of subexpMap if no matches are found.

func GetBytesRegexSubexpMap

func GetBytesRegexSubexpMap(regEx string, buf []byte) (map[string]string, error)

GetBytesRegexSubexpMap is the bytes version of GetRegexSubexpMap for convenience, it is used on image/mtds that have long slices of bytes. For convenience, map[string]string is returned.

func GetRegexSubexpMap

func GetRegexSubexpMap(regEx, inputString string) (map[string]string, error)

GetRegexSubexpMap takes a regex with capturing groups and an input string, and returns a map of the regex subexpNames to their respective matched values. NOTE: this function is used only for regex with valid capturing groups uses beyond well-defined regexes with valid capturing groups will result in errors or undefined behavior e.g. regex: "(?P<type>[a-z]+):(?P<specifier>.+)"

inputString: "mtd:flash0"

-> map[string]string { "type": "mtd", "specifier": "flash0" } Returns an error if match was not successful.

func GetStringKeys

func GetStringKeys(m map[string]interface{}) []string

GetStringKeys gets all the string keys in a string-keyed map. The sequence of the keys is not guaranteed.

func GetStringKeysFromJSONData

func GetStringKeysFromJSONData(data []byte) ([]string, error)

GetStringKeysFromJSONData takes in data which contains JSON data and returns all the string keys. The sequence of the keys is not guaranteed.

func GetWord

func GetWord(data []byte, offset uint32) (uint32, error)

GetWord gets a 4 byte uint32 from a byte slice 'data' from offset to offset+4. It returns an error if the offset is out of range.

func HealthdRemoveMemUtilRebootEntryIfExists

func HealthdRemoveMemUtilRebootEntryIfExists(h *gabs.Container) error

HealthdRemoveMemUtilRebootEntryIfExists removes the "reboot" entry that will trigger system reboot after mem util reaches a threshold. This is to prevent healthd reboots during flashing. If the "reboot" entry exists, remove it and write back to the file.

func HealthdWriteConfigToFile

func HealthdWriteConfigToFile(h *gabs.Container) error

HealthdWriteConfigToFile writes back into /etc/healthd-config.json.

func LogAndIgnoreErr

func LogAndIgnoreErr(err error)

LogAndIgnoreErr logs the error info and ignores the error

func SafeAppendBytes

func SafeAppendBytes(a, b []byte) []byte

SafeAppendBytes safely appends byte slices b to a. c := append(a, b...) is unsafe, if a has enough capacity, b will be directly appended. SafeAppendBytes makes guarantees that a is not changed.

func SafeAppendString

func SafeAppendString(a, b []string) []string

SafeAppendString is the string version of SafeAppendBytes.

func SetWord

func SetWord(data []byte, word, offset uint32) ([]byte, error)

SetWord sets a 4 byte uint32 in a byte slice 'data' from offset to offset+4. It returns an error if offset will cause an out of range write. Warning: make an explicit copy if the original array is required again after SetWord.

func StringDifference

func StringDifference(a, b []string) []string

StringDifference returns the elements in 'a' not in 'b'

func StringFind

func StringFind(val string, arr []string) int

StringFind takes a string slice and looks if a given item is in it. If found it will return its index, otherwise it will return -1.

func Uint32Find

func Uint32Find(val uint32, arr []uint32) int

Uint32Find takes a uint32 slice and looks if a given item is in it. If found it will return its index, otherwise it will return -1.

Types

type BmcMemThres

type BmcMemThres struct {
	Value   float32  `json:"value"`
	Actions []string `json:"action"`
}

BmcMemThres is a struct for parsing the healthd-config.json.

type BmcMemUtil

type BmcMemUtil struct {
	Threshold []BmcMemThres `json:"threshold"`
}

BmcMemUtil is a struct for parsing the healthd-config.json.

type MemInfo

type MemInfo struct {
	MemTotal uint64
	MemFree  uint64
}

MemInfo represents memory information in bytes.

type MtdInfo

type MtdInfo struct {
	Dev       string
	Size      uint32
	Erasesize uint32
}

type VbootEnforcementType

type VbootEnforcementType = string

VbootEnforcementType is an enum representing the vboot type of the system

type Vbs

type Vbs struct {
	Uboot_exec_address  uint32 /* Location in MMIO where U-Boot/Recovery U-Boot is execution */
	Rom_exec_address    uint32 /* Location in MMIO where ROM is executing from */
	Rom_keys            uint32 /* Location in MMIO where the ROM FDT is located */
	Subordinate_keys    uint32 /* Location in MMIO where subordinate FDT is located */
	Rom_handoff         uint32 /* Marker set when ROM is handing execution to U-Boot. */
	Force_recovery      uint8  /* Set by ROM when recovery is requested */
	Hardware_enforce    uint8  /* Set by ROM when WP pin of SPI0.0 is active low */
	Software_enforce    uint8  /* Set by ROM when RW environment uses verify=yes */
	Recovery_boot       uint8  /* Set by ROM when recovery is used */
	Recovery_retries    uint8  /* Number of attempts to recovery from verification failure */
	Error_type          uint8  /* Type of error, or 0 for success */
	Error_code          uint8  /* Unique error code, or 0 for success */
	Error_tpm           uint8  /* The last-most-recent error from the TPM. */
	Crc                 uint16 /* A CRC of the vbs structure */
	Error_tpm2          uint16 /* The last-most-recent error from the TPM2. */
	Subordinate_last    uint32 /* Status reporting only: the last booted subordinate. */
	Uboot_last          uint32 /* Status reporting only: the last booted U-Boot. */
	Kernel_last         uint32 /* Status reporting only: the last booted kernel. */
	Subordinate_current uint32 /* Status reporting only: the current booted subordinate. */
	Uboot_current       uint32 /* Status reporting only: the current booted U-Boot. */
	Kernel_current      uint32 /* Status reporting only: the current booted kernel. */
}

Vbs represents the verified content flags. This is taken from common/recipes-utils/vboot-utils/files/vbs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址