fix(os): improve service status checking reliability

- Handle specific exit codes for systemd services (inactive/unknown states)
- Add better error handling for init.d services
- Move string conversion before error checking for consistency
- Update log levels for better service state visibility
This commit is contained in:
2026-03-26 16:20:21 +08:00
parent e83436fe9b
commit 61e4ad6ecc
2 changed files with 28 additions and 4 deletions

View File

@@ -68,6 +68,7 @@ For detailed API documentation, please see [docs/api.md](docs/api.md)
- [ ] Fix random database lock when processing logs
- [ ] Add frpc createdBy storage and display
- [x] Fix backend can still start frpc instance when it is already running
- [ ] Develop an agent software to handle windows service management
## License

31
os.go
View File

@@ -411,12 +411,13 @@ func IsInstanceRunning(instanceID int) bool {
output, err := cmd.CombinedOutput()
postLog.Debug(fmt.Sprintf("[IsInstanceRunning] Sc query output: %s", output))
outputStr := string(output)
if err != nil {
postLog.Error(fmt.Sprintf("[IsInstanceRunning] Failed to check Windows service status: %s, output: %s", err, output))
return false
}
outputStr := string(output)
if strings.Contains(outputStr, "RUNNING") {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is running", instance.Name))
return true
@@ -429,12 +430,25 @@ func IsInstanceRunning(instanceID int) bool {
cmd := exec.Command("systemctl", "is-active", serviceName)
output, err := cmd.CombinedOutput()
status := strings.TrimSpace(string(output))
if err != nil {
exitError, ok := err.(*exec.ExitError)
if ok {
exitCode := exitError.ExitCode()
if exitCode == 3 && status == "inactive" {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Systemd service %s is stopped", serviceName))
return false
}
if exitCode == 4 && status == "unknown" {
postLog.Warning(fmt.Sprintf("[IsInstanceRunning] Systemd service %s does not exist", serviceName))
return false
}
}
postLog.Error(fmt.Sprintf("[IsInstanceRunning] Failed to check systemd service status: %s, output: %s", err, output))
return false
}
status := strings.TrimSpace(string(output))
if status == "active" {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Systemd service %s is running", serviceName))
return true
@@ -446,19 +460,28 @@ func IsInstanceRunning(instanceID int) bool {
case "init.d":
servicePath := fmt.Sprintf("/etc/init.d/%s", serviceName)
if _, err := os.Stat(servicePath); err != nil {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Init.d service %s not found", serviceName))
postLog.Warning(fmt.Sprintf("[IsInstanceRunning] Init.d service %s not found", serviceName))
return false
}
cmd := exec.Command(servicePath, "status")
output, err := cmd.CombinedOutput()
outputStr := strings.TrimSpace(string(output))
if err != nil {
exitError, ok := err.(*exec.ExitError)
if ok {
exitCode := exitError.ExitCode()
if exitCode != 0 && !strings.Contains(outputStr, "is running") {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Init.d service %s is stopped", serviceName))
return false
}
}
postLog.Error(fmt.Sprintf("[IsInstanceRunning] Failed to check init.d service status: %s, output: %s", err, output))
return false
}
outputStr := strings.TrimSpace(string(output))
if strings.Contains(outputStr, "is running") {
return true
} else {