4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * config.c: support for the scadm configlog option (to display the
31 * service processor configuration log)
37 #include <time.h> /* required by librsc.h */
46 ADM_Process_fru_log(int all
)
49 struct timespec Timeout
;
50 dp_get_config_log_r_t
*rscReply
;
51 rsci64 bytes_remaining
, seqno
;
52 rsci16 request_size
, response_size
;
53 dp_get_config_log_t rscCmd
;
58 * Start by sending a zero-length request to ALOM, so that
59 * we can learn the length of the console log. We expect
60 * ALOM to return the length of the entire log. We get
61 * a snapshot of the length of the log here - it may however
62 * continue to grow as we're reading it. We read only as
63 * much of the log as we get in this snapshot.
67 Message
.type
= DP_GET_CONFIG_LOG
;
68 Message
.len
= sizeof (rscCmd
);
69 Message
.data
= (char *)&rscCmd
;
73 Timeout
.tv_sec
= ADM_TIMEOUT
;
74 ADM_Recv(&Message
, &Timeout
,
75 DP_GET_CONFIG_LOG_R
, sizeof (*rscReply
));
77 rscReply
= (dp_get_config_log_r_t
*)Message
.data
;
80 * If we do not want the whole log, and the log is bigger than
81 * the length limit, then fetch just the last ADM_DEFAULT_LOG_LENGTH
82 * bytes from the log. Else just get the whole thing.
84 if ((all
== 0) && (rscReply
->remaining_log_bytes
>
85 ADM_DEFAULT_LOG_LENGTH
)) {
86 bytes_remaining
= ADM_DEFAULT_LOG_LENGTH
;
87 seqno
= (rscReply
->remaining_log_bytes
+
88 rscReply
->next_seq
) - bytes_remaining
;
90 bytes_remaining
= rscReply
->remaining_log_bytes
;
91 seqno
= rscReply
->next_seq
;
93 request_size
= sizeof (rscReply
->buffer
);
97 * Timeout for RSC response.
100 Timeout
.tv_sec
= ADM_TIMEOUT
;
103 * This loop runs as long as there is data in the log, or until
104 * we hit the default limit (above). It's possible that ALOM may
105 * shrink the log - we need to account for this. If ALOM returns
106 * no data, we bail out.
108 while (bytes_remaining
) {
109 rscCmd
.start_seq
= seqno
;
110 rscCmd
.length
= (bytes_remaining
< request_size
) ?
111 bytes_remaining
: request_size
;
112 Message
.type
= DP_GET_CONFIG_LOG
;
113 Message
.len
= sizeof (rscCmd
);
114 Message
.data
= (char *)&rscCmd
;
117 ADM_Recv(&Message
, &Timeout
,
118 DP_GET_CONFIG_LOG_R
, sizeof (*rscReply
));
120 rscReply
= (dp_get_config_log_r_t
*)Message
.data
;
122 /* If ALOM returns zero bytes, we're done. */
123 response_size
= rscReply
->length
;
124 if (response_size
== 0) {
128 bytes_remaining
-= response_size
;
129 if (rscReply
->remaining_log_bytes
< bytes_remaining
) {
130 bytes_remaining
= rscReply
->remaining_log_bytes
;
134 * If the byte at the original sequence number is no
135 * longer in the log, print a message.
137 if (rscReply
->next_seq
> seqno
+ response_size
) {
138 printf(gettext("\nscadm: lost %d bytes of log data\n"),
139 rscReply
->next_seq
- (seqno
+ response_size
));
141 seqno
= rscReply
->next_seq
;
143 /* Print the config log */
144 if (fwrite(rscReply
->buffer
, sizeof (char), response_size
,
145 stdout
) != response_size
) {
146 perror(gettext("\ncouldn't write config log buffer"