Skip to content

Commit 3865ee1

Browse files
leftwoAlan Hanson
andauthored
DTrace updates (#1589)
Move dtrace scripts to /opt/oxide/dtrace/crucible, changed places that needed to know about the new paths. Updated many scripts to use three letter short names for downstairs state. Updated lookup table to new inline shortcut to reduce code duplication. Added WQ and RPL where it was missing. At some point I'll add them all, but waiting for Matt's PR to land where we update how the states work and I may decide to print things differently. ``` inline string short_state[string ss] = ss == "active" ? "ACT" : ss == "new" ? "NEW" : ss == "replaced" ? "RPL" : ss == "live_repair_ready" ? "LRR" : ss == "live_repair" ? "LR" : ss == "faulted" ? "FLT" : ss == "offline" ? "OFL" : ss == "reconcile" ? "REC" : ss == "wait_quorum" ? "WQ" : ss; ``` Fixed column width for PIDs in a number of scripts. Added example `simple.d` dtrace script from 2024 DTrace conference. Example output: get-up-state.sh: ``` BRM42220030 # /opt/oxide/crucible_dtrace/get-up-state.sh PID SESSION DS0 DS1 DS2 NEXT_JOB DELTA CONN ELR ELC ERR ERN 8 00c767d0 NEW NEW NEW 1000 0 0 0 0 0 0 8 0c5af3b7 NEW NEW NEW 1000 0 0 0 0 0 0 8 0cd7bba2 ACT ACT ACT 1000 0 3 0 0 0 0 8 0dd09245 NEW NEW NEW 1000 0 0 0 0 0 0 8 121dc7ea ACT ACT ACT 1000 0 3 0 0 0 0 17774 03419c44 ACT ACT ACT 46479 0 4 74 294 0 0 17774 f0745404 NEW NEW NEW 32271 0 3 0 0 0 0 18563 0fd262e1 NEW NEW NEW 32285 0 3 0 0 0 0 18563 eb102b5a ACT ACT ACT 46210 0 4 74 294 0 0 19622 4b0ace49 NEW NEW NEW 32271 0 3 0 0 0 0 19622 d994fe0a ACT ACT ACT 46240 0 4 74 294 0 0 ``` get-ds-state.sh ``` BRM42220030 # /opt/oxide/crucible_dtrace/get-ds-state.sh oxz_crucible_pantry_8e3b64eb 8 00c767d0 WQ NEW WQ oxz_crucible_pantry_8e3b64eb 8 00c767d0 NEW NEW NEW oxz_crucible_pantry_8e3b64eb 8 0c5af3b7 NEW NEW NEW oxz_crucible_pantry_8e3b64eb 8 0cd7bba2 ACT ACT ACT oxz_propolis-server_d3bdb604 17774 03419c44 ACT ACT ACT oxz_propolis-server_d3bdb604 17774 f0745404 NEW NEW NEW oxz_propolis-server_bfba345a 18563 eb102b5a ACT ACT ACT oxz_propolis-server_bfba345a 18563 eb102b5a NEW NEW NEW oxz_propolis-server_335eb83d 19622 4b0ace49 NEW NEW NEW oxz_propolis-server_335eb83d 19622 d994fe0a ACT ACT ACT ``` Co-authored-by: Alan Hanson <[email protected]>
1 parent bd3cc54 commit 3865ee1

File tree

9 files changed

+291
-66
lines changed

9 files changed

+291
-66
lines changed

package-manifest.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ source.rust.release = true
66
source.paths = [
77
{ from = "agent/smf", to = "/var/svc/manifest/site/crucible" },
88
{ from = "agent/downstairs_method_script.sh", to = "/opt/oxide/lib/svc/manifest/crucible/downstairs.sh" },
9-
{ from = "tools/dtrace/downstairs_count.d", to = "/opt/oxide/dtrace/downstairs_count.d" },
9+
{ from = "tools/dtrace/downstairs_count.d", to = "/opt/oxide/dtrace/crucible/downstairs_count.d" },
1010
]
1111
output.type = "zone"
1212

@@ -19,11 +19,12 @@ source.paths = [
1919
{ from = "pantry/smf/pantry.xml", to = "/var/svc/manifest/site/crucible/pantry.xml" },
2020
{ from = "tools/dtrace/upstairs_info.d", to = "/opt/oxide/dtrace/upstairs_info.d" },
2121
{ from = "tools/dtrace/upstairs_repair.d", to = "/opt/oxide/dtrace/upstairs_repair.d" },
22-
{ from = "tools/dtrace/upstairs_raw.d", to = "/opt/oxide/dtrace/upstairs_raw.d" },
23-
{ from = "tools/dtrace/get-lr-state.sh", to = "/opt/oxide/dtrace/get-lr-state.sh" },
24-
{ from = "tools/dtrace/get-ds-state.sh", to = "/opt/oxide/dtrace/get-ds-state.sh" },
25-
{ from = "tools/dtrace/single_up_info.d", to = "/opt/oxide/dtrace/single_up_info.d" },
26-
{ from = "tools/dtrace/sled_upstairs_info.d", to = "/opt/oxide/dtrace/sled_upstairs_info.d" },
27-
{ from = "tools/dtrace/all_downstairs.d", to = "/opt/oxide/dtrace/all_downstairs.d" },
22+
{ from = "tools/dtrace/upstairs_raw.d", to = "/opt/oxide/dtrace/crucible/upstairs_raw.d" },
23+
{ from = "tools/dtrace/get-lr-state.sh", to = "/opt/oxide/dtrace/crucible/get-lr-state.sh" },
24+
{ from = "tools/dtrace/get-ds-state.sh", to = "/opt/oxide/dtrace/crucible/get-ds-state.sh" },
25+
{ from = "tools/dtrace/single_up_info.d", to = "/opt/oxide/dtrace/crucible/single_up_info.d" },
26+
{ from = "tools/dtrace/sled_upstairs_info.d", to = "/opt/oxide/dtrace/crucible/sled_upstairs_info.d" },
27+
{ from = "tools/dtrace/all_downstairs.d", to = "/opt/oxide/dtrace/crucible/all_downstairs.d" },
28+
{ from = "tools/dtrace/up-info.d", to = "/opt/oxide/dtrace/crucible/up-info.d" },
2829
]
2930
output.type = "zone"

tools/dtrace/get-ds-state.d

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,40 @@
55
#pragma D option quiet
66
#pragma D option strsize=1k
77

8+
/*
9+
* Translate the longer state string into a shorter version
10+
*/
11+
inline string short_state[string ss] =
12+
ss == "active" ? "ACT" :
13+
ss == "new" ? "NEW" :
14+
ss == "replaced" ? "RPL" :
15+
ss == "live_repair_ready" ? "LRR" :
16+
ss == "live_repair" ? "LR" :
17+
ss == "faulted" ? "FLT" :
18+
ss == "offline" ? "OFL" :
19+
ss == "reconcile" ? "REC" :
20+
ss == "wait_quorum" ? "WQ" :
21+
ss;
22+
823
crucible_upstairs*:::up-status
924
{
1025
my_sesh = json(copyinstr(arg1), "ok.session_id");
1126

12-
printf("%6d %8s %17s %17s %17s\n",
27+
this->ds0state = json(copyinstr(arg1), "ok.ds_state[0]");
28+
this->d0 = short_state[this->ds0state];
29+
30+
this->ds1state = json(copyinstr(arg1), "ok.ds_state[1]");
31+
this->d1 = short_state[this->ds1state];
32+
33+
this->ds2state = json(copyinstr(arg1), "ok.ds_state[2]");
34+
this->d2 = short_state[this->ds2state];
35+
36+
printf("%6d %8s %3s %3s %3s\n",
1337
pid,
1438
substr(my_sesh, 0, 8),
15-
json(copyinstr(arg1), "ok.ds_state[0]"),
16-
json(copyinstr(arg1), "ok.ds_state[1]"),
17-
json(copyinstr(arg1), "ok.ds_state[2]"));
39+
this->d0,
40+
this->d1,
41+
this->d2);
1842
}
1943

2044
tick-5s

tools/dtrace/get-ds-state.sh

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
# it finds running on a system.
55
filename='/tmp/get-ds-state.out'
66

7+
# Clear out any previous state
8+
echo "" > "$filename"
79
# Gather state on all running propolis servers, record summary to a file
8-
dtrace -s /opt/oxide/crucible_dtrace/get-ds-state.d | sort -n | uniq | awk 'NF' > "$filename"
10+
dtrace -s /opt/oxide/dtrace/crucible/get-ds-state.d | sort -n | uniq | awk 'NF' > "$filename"
911
# Walk the lines in the file, append the zone name to each line.
1012
while read -r p; do
1113
# For each line in the file, pull out the PID we are looking at and
12-
# print the zone that process is running in.
14+
# use it to find the zone so we can print the zone name as well.
1315
pid=$(echo $p | awk '{print $1}')
1416
zone=$(ps -o zone -p $pid | tail -1 | cut -c 1-28)
15-
echo "$zone $p"
17+
# Our zone string size is already set from above, force the
18+
# rest of the line to take up 26 columns, this prevents PIDs
19+
# with fewer than 5 digits from using less columns.
20+
printf "%s %26s\n" "$zone" "$p"
1621
done < "$filename"

tools/dtrace/get-lr-state.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
# pid/session it finds running on a system.
55
filename='/tmp/get-lr-state.out'
66

7+
# Clear out any previous state
8+
echo "" > "$filename"
79
# Gather state on all running propolis servers, record summary to a file
8-
dtrace -s /opt/oxide/crucible_dtrace/get-lr-state.d | sort -n | uniq | awk 'NF' > "$filename"
10+
dtrace -s /opt/oxide/dtrace/crucible/get-lr-state.d | sort -n | uniq | awk 'NF' > "$filename"
911
# Walk the lines in the file, append the zone name to each line.
1012
while read -r p; do
1113
# For each line in the file, pull out the PID we are looking at and
1214
# print the zone that process is running in.
1315
pid=$(echo $p | awk '{print $1}')
1416
zone=$(ps -o zone -p $pid | tail -1 | cut -c 1-28)
15-
echo "$zone $p"
17+
# Our zone string size is already set from above, force the
18+
# rest of the line to take up 26 columns, this prevents PIDs
19+
# with fewer than 5 digits from using less columns.
20+
printf "%s %26s\n" "$zone" "$p"
1621
done < "$filename"

tools/dtrace/get-up-state.d

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ tick-10s
3030
exit(0);
3131
}
3232

33+
/*
34+
* Translate the longer state string into a shorter version
35+
*/
36+
inline string short_state[string ss] =
37+
ss == "active" ? "ACT" :
38+
ss == "new" ? "NEW" :
39+
ss == "replaced" ? "RPL" :
40+
ss == "live_repair_ready" ? "LRR" :
41+
ss == "live_repair" ? "LR" :
42+
ss == "faulted" ? "FLT" :
43+
ss == "offline" ? "OFL" :
44+
ss == "reconcile" ? "REC" :
45+
ss == "wait_quorum" ? "WQ" :
46+
ss;
47+
3348
/*
3449
* All variables should be this->
3550
* Otherwise, there is a chance another probe will fire and
@@ -38,60 +53,14 @@ tick-10s
3853
crucible_upstairs*:::up-status
3954
{
4055
this->ds0state = json(copyinstr(arg1), "ok.ds_state[0]");
41-
if (this->ds0state == "active") {
42-
this->d0 = "ACT";
43-
} else if (this->ds0state == "new") {
44-
this->d0 = "NEW";
45-
} else if (this->ds0state == "live_repair_ready") {
46-
this->d0 = "LRR";
47-
} else if (this->ds0state == "live_repair") {
48-
this->d0 = " LR";
49-
} else if (this->ds0state == "faulted") {
50-
this->d0 = "FLT";
51-
} else if (this->ds0state == "offline") {
52-
this->d0 = "OFL";
53-
} else {
54-
this->d0 = this->ds0state;
55-
}
56+
this->d0 = short_state[this->ds0state];
5657

5758
this->ds1state = json(copyinstr(arg1), "ok.ds_state[1]");
58-
if (this->ds1state == "active") {
59-
this->d1 = "ACT";
60-
} else if (this->ds1state == "new") {
61-
this->d1 = "NEW";
62-
} else if (this->ds1state == "live_repair_ready") {
63-
this->d1 = "LRR";
64-
} else if (this->ds1state == "live_repair") {
65-
this->d1 = " LR";
66-
} else if (this->ds1state == "faulted") {
67-
this->d1 = "FLT";
68-
} else if (this->ds1state == "offline") {
69-
this->d1 = "OFL";
70-
} else {
71-
this->d1 = this->ds1state;
72-
}
59+
this->d1 = short_state[this->ds1state];
7360

7461
this->ds2state = json(copyinstr(arg1), "ok.ds_state[2]");
75-
if (this->ds2state == "active") {
76-
this->d2 = "ACT";
77-
} else if (this->ds2state == "new") {
78-
this->d2 = "NEW";
79-
} else if (this->ds2state == "live_repair_ready") {
80-
this->d2 = "LRR";
81-
} else if (this->ds2state == "live_repair") {
82-
this->d2 = " LR";
83-
} else if (this->ds2state == "faulted") {
84-
this->d2 = "FLT";
85-
} else if (this->ds2state == "offline") {
86-
this->d2 = "OFL";
87-
} else {
88-
this->d2 = this->ds2state;
89-
}
62+
this->d2 = short_state[this->ds2state];
9063

91-
/*
92-
* All these local variables require the "this->" so the probe firing
93-
* from different sessions don't collide with each other.
94-
*/
9564
this->full_session_id = json(copyinstr(arg1), "ok.session_id");
9665
this->session_id = substr(this->full_session_id, 0, 8);
9766

tools/dtrace/get-up-state.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ final='/tmp/get-up-state.final'
77
rm -f $final
88

99
# Gather our output first.
10-
dtrace -s /opt/oxide/crucible_dtrace/get-up-state.d | awk 'NF' > "$filename"
10+
dtrace -s /opt/oxide/dtrace/crucible/get-up-state.d | awk 'NF' > "$filename"
1111
if [[ $? -ne 0 ]]; then
1212
exit 1
1313
fi

tools/dtrace/simple.d

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#pragma D option quiet
2+
#pragma D option strsize=1k
3+
4+
dtrace:::BEGIN
5+
{
6+
/*
7+
* We have to init something for the associative array last_id.
8+
* This means it will be created and later, when we have a
9+
* session ID, we can add that element.
10+
*/
11+
last_id["string"] = (int64_t)1;
12+
}
13+
14+
/*
15+
* Print our header at some interval
16+
*/
17+
tick-2s
18+
{
19+
printf("%5s %8s ", "PID", "SESSION");
20+
printf("%3s %3s %3s", "DS0", "DS1", "DS2");
21+
printf(" %10s %6s %4s", "NEXT_JOB", "DELTA", "CONN");
22+
printf(" %5s %5s", "ELR", "ELC");
23+
printf(" %5s %5s", "ERR", "ERN");
24+
printf("\n");
25+
}
26+
27+
/*
28+
* Translate the longer state string into a shorter version
29+
*/
30+
inline string short_state[string ss] =
31+
ss == "active" ? "ACT" :
32+
ss == "new" ? "NEW" :
33+
ss == "live_repair_ready" ? "LRR" :
34+
ss == "live_repair" ? "LR" :
35+
ss == "faulted" ? "FLT" :
36+
ss == "offline" ? "OFL" :
37+
ss == "reconcile" ? "REC" :
38+
ss;
39+
40+
/*
41+
* All variables should be this->
42+
* Otherwise, there is a chance another probe will fire and
43+
* clobber the contents.
44+
*/
45+
crucible_upstairs*:::up-status
46+
{
47+
this->ds0state = json(copyinstr(arg1), "ok.ds_state[0]");
48+
this->d0 = short_state[this->ds0state];
49+
50+
this->ds1state = json(copyinstr(arg1), "ok.ds_state[1]");
51+
this->d1 = short_state[this->ds1state];
52+
53+
this->ds2state = json(copyinstr(arg1), "ok.ds_state[2]");
54+
this->d2 = short_state[this->ds2state];
55+
56+
this->full_session_id = json(copyinstr(arg1), "ok.session_id");
57+
this->session_id = substr(this->full_session_id, 0, 8);
58+
59+
this->next_id_str = json(copyinstr(arg1), "ok.next_job_id");
60+
this->next_id_value = strtoll(this->next_id_str);
61+
62+
/*
63+
* The first time through, we don't know delta, so start with 0.
64+
*/
65+
if (last_id[this->session_id] == 0) {
66+
this->delta = 0;
67+
last_id[this->session_id] = this->next_id_value;
68+
} else {
69+
this->delta = this->next_id_value - last_id[this->session_id];
70+
last_id[this->session_id] = this->next_id_value;
71+
}
72+
73+
this->connections = strtoll(json(copyinstr(arg1), "ok.ds_connected[0]")) +
74+
strtoll(json(copyinstr(arg1), "ok.ds_connected[1]")) +
75+
strtoll(json(copyinstr(arg1), "ok.ds_connected[2]"));
76+
77+
/* Total of extents live repaired */
78+
this->elr = strtoll(json(copyinstr(arg1), "ok.ds_extents_repaired[0]")) +
79+
strtoll(json(copyinstr(arg1), "ok.ds_extents_repaired[1]")) +
80+
strtoll(json(copyinstr(arg1), "ok.ds_extents_repaired[2]"));
81+
82+
/* Total of extents not needing repair during live repair */
83+
this->elc = strtoll(json(copyinstr(arg1), "ok.ds_extents_confirmed[0]")) +
84+
strtoll(json(copyinstr(arg1), "ok.ds_extents_confirmed[1]")) +
85+
strtoll(json(copyinstr(arg1), "ok.ds_extents_confirmed[2]"));
86+
87+
printf("%5d %8s %3s %3s %3s %10d %6d %4d %5d %5d %5s %5s\n",
88+
pid,
89+
this->session_id,
90+
this->d0,
91+
this->d1,
92+
this->d2,
93+
this->next_id_value,
94+
this->delta,
95+
this->connections,
96+
this->elr,
97+
this->elc,
98+
json(copyinstr(arg1), "ok.ds_reconciled"),
99+
json(copyinstr(arg1), "ok.ds_reconcile_needed"));
100+
}

0 commit comments

Comments
 (0)