-
Notifications
You must be signed in to change notification settings - Fork 93
[update-status] Handle svcs in-transition and unrecognized states #11025
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
karencfv
wants to merge
4
commits into
oxidecomputer:main
Choose a base branch
from
karencfv:handle-intermediate-states
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -101,7 +101,9 @@ impl SvcsResult { | |||||
| | SvcState::Disabled | ||||||
| | SvcState::Offline | ||||||
| | SvcState::Online | ||||||
| | SvcState::Uninitialized => { | ||||||
| | SvcState::Uninitialized | ||||||
| | SvcState::InTransition | ||||||
| | SvcState::Unrecognized => { | ||||||
| let fmri = if let Some(fmri) = svc.next() { | ||||||
| fmri.to_string() | ||||||
| } else { | ||||||
|
|
@@ -166,6 +168,9 @@ impl SvcsResult { | |||||
| SvcState::Maintenance => { | ||||||
| SvcEnabledNotOnlineState::Maintenance | ||||||
| } | ||||||
| SvcState::Unrecognized => { | ||||||
| SvcEnabledNotOnlineState::Unrecognized | ||||||
| } | ||||||
| // `legacy_run` is excluded here because this state doesn't | ||||||
| // really say anything about whether a service is running or | ||||||
| // not. It just states that this is a service that isn't | ||||||
|
|
@@ -176,10 +181,16 @@ impl SvcsResult { | |||||
| // returns, so we exclude it as well. | ||||||
| // More detail in | ||||||
| // https://github.com/oxidecomputer/omicron/issues/10316 | ||||||
| // | ||||||
| // `InTransition` (or state with '*' appended as represented | ||||||
| // in svcs) is excluded because it is a momentary state | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| // while a service moves between two states, not a stable | ||||||
| // "enabled not online" condition worth reporting. | ||||||
| SvcState::Online | ||||||
| | SvcState::Uninitialized | ||||||
| | SvcState::Disabled | ||||||
| | SvcState::LegacyRun => return None, | ||||||
| | SvcState::LegacyRun | ||||||
| | SvcState::InTransition => return None, | ||||||
| }; | ||||||
| Some(SvcEnabledNotOnline { | ||||||
| fmri: svc.fmri, | ||||||
|
|
@@ -198,6 +209,11 @@ impl SvcsResult { | |||||
| } | ||||||
|
|
||||||
| fn parse_svc_state(state: &str) -> Option<SvcState> { | ||||||
| // Per `man svcs`, an asterisk (*) is appended to the state of instances | ||||||
| // that are in transition from one state to another. | ||||||
| if state.ends_with('*') { | ||||||
| return Some(SvcState::InTransition); | ||||||
| } | ||||||
| match state { | ||||||
| "uninitialized" => Some(SvcState::Uninitialized), | ||||||
| "offline" => Some(SvcState::Offline), | ||||||
|
|
@@ -206,6 +222,9 @@ fn parse_svc_state(state: &str) -> Option<SvcState> { | |||||
| "maintenance" => Some(SvcState::Maintenance), | ||||||
| "disabled" => Some(SvcState::Disabled), | ||||||
| "legacy_run" => Some(SvcState::LegacyRun), | ||||||
| // Per `man svcs`, absent or unrecognized states are denoted by a | ||||||
| // question mark (?) character. | ||||||
| "?" => Some(SvcState::Unrecognized), | ||||||
| _ => None, | ||||||
| } | ||||||
| } | ||||||
|
|
@@ -440,6 +459,44 @@ disabled svc:/network/tcpkey:default global | |||||
| ); | ||||||
| } | ||||||
|
|
||||||
| #[test] | ||||||
| fn test_svc_parse_in_transition_and_unrecognized() { | ||||||
| let output = r#"online* svc:/milestone/sysconfig:default global | ||||||
| ? svc:/site/fake-service:default global | ||||||
| disabled svc:/network/tcpkey:default global | ||||||
| "#; | ||||||
|
|
||||||
| let log = log(); | ||||||
| let result = SvcsResult::parse(&log, output.as_bytes()); | ||||||
|
|
||||||
| assert_eq!(result.services.len(), 3); | ||||||
| assert_eq!(result.errors.len(), 0); | ||||||
| assert_eq!( | ||||||
| result.services[0], | ||||||
| Svc { | ||||||
| fmri: "svc:/milestone/sysconfig:default".to_string(), | ||||||
| zone: "global".to_string(), | ||||||
| state: SvcState::InTransition, | ||||||
| } | ||||||
| ); | ||||||
| assert_eq!( | ||||||
| result.services[1], | ||||||
| Svc { | ||||||
| fmri: "svc:/site/fake-service:default".to_string(), | ||||||
| zone: "global".to_string(), | ||||||
| state: SvcState::Unrecognized, | ||||||
| } | ||||||
| ); | ||||||
| assert_eq!( | ||||||
| result.services[2], | ||||||
| Svc { | ||||||
| fmri: "svc:/network/tcpkey:default".to_string(), | ||||||
| zone: "global".to_string(), | ||||||
| state: SvcState::Disabled, | ||||||
| } | ||||||
| ); | ||||||
| } | ||||||
|
|
||||||
| #[test] | ||||||
| fn test_to_enabled_not_online() { | ||||||
| let mk_svc = |i: usize, state: SvcState| Svc { | ||||||
|
|
@@ -466,6 +523,8 @@ disabled svc:/network/tcpkey:default global | |||||
| mk_svc(7, SvcState::Maintenance), | ||||||
| mk_svc(8, SvcState::Maintenance), | ||||||
| mk_svc(9, SvcState::Uninitialized), | ||||||
| mk_svc(10, SvcState::Unrecognized), | ||||||
| mk_svc(11, SvcState::InTransition), | ||||||
| ]; | ||||||
| let result = SvcsResult { | ||||||
| services, | ||||||
|
|
@@ -482,6 +541,7 @@ disabled svc:/network/tcpkey:default global | |||||
| mk_e_not_o_svc(3, SvcEnabledNotOnlineState::Degraded), | ||||||
| mk_e_not_o_svc(7, SvcEnabledNotOnlineState::Maintenance), | ||||||
| mk_e_not_o_svc(8, SvcEnabledNotOnlineState::Maintenance), | ||||||
| mk_e_not_o_svc(10, SvcEnabledNotOnlineState::Unrecognized), | ||||||
| ] | ||||||
| ); | ||||||
| } | ||||||
|
|
||||||
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 1a20a12eb13a20c58f91dfae51bb3c4836b4e069:openapi/sled-agent/sled-agent-45.0.0-264d85.json |
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| sled-agent-45.0.0-264d85.json | ||
| sled-agent-46.0.0-1baf31.json |
7 changes: 7 additions & 0 deletions
7
schema/crdb/add-unrecognized-svc-enabled-not-online-state/up.sql
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| ALTER TYPE | ||
| omicron.public.inv_svc_enabled_not_online_state | ||
| ADD VALUE IF NOT EXISTS | ||
| 'unrecognized' | ||
| AFTER | ||
| 'maintenance' | ||
| ; |
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
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems okay for what we're trying to do with this consumer, but it doesn't seem great for a general-purpose layer because it doesn't tell you anything about what state it's currently in or what it's going to. It means you lose all information about its state while it's transitioning.
I believe that at the SMF layer (in the database, visible with
svcprop), this information is exposed asstateandnext_state, and the asterisk gets appended ifnext_stateis not NULL:We could similarly expose both here. Or we could add the current and next state to the
Transitioningvariant?Or maybe it would also be okay to simply ignore the asterisk? On the grounds that if it's
offline*, then it is offline, even though it's transitioning. But that seems likely to lead to false positives while things are starting up. I think it matters to our consumer whether something isofflineoroffline*because the first is a problem and the second isn't.Or might we also have false positives today if something is
offlineand not transitioning yet because its dependencies are still being started? In which case we just need to treat this at a higher level as transient. Or report thestate_timestamptoo, and only consider something broken if its in one of our broken states and its state hasn't changed recently (as a form of hysteresis)?As I write that, I wonder if we're going to keep playing whack-a-mole with false positives unless we do something like that.