libseslog.c revision e4f5a11d4a234623168c1558fcdf4341e11769e1
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * CDDL HEADER START
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * The contents of this file are subject to the terms of the
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Common Development and Distribution License (the "License").
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * You may not use this file except in compliance with the License.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * or http://www.opensolaris.org/os/licensing.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * See the License for the specific language governing permissions
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * and limitations under the License.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * When distributing Covered Code, include this CDDL HEADER in each
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * If applicable, add the following below this CDDL HEADER, with the
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * fields enclosed by brackets "[]" replaced with your own identifying
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * information: Portions Copyright [yyyy] [name of copyright owner]
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * CDDL HEADER END
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * SES Log reader library
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * This library is responsible for accessing the SES log at the target address,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * formatting and returning any log entries found.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * The data will be returned in an nvlist_t structure allocated here.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * open the device with given device name
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Initialize scsi struct
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringconstruct_scsi_pt_obj(struct uscsi_cmd *uscsi)
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (void) memset(uscsi, 0, sizeof (struct uscsi_cmd));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering uscsi->uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * set control cdb of scsi structure
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringset_scsi_pt_cdb(struct uscsi_cmd *uscsi, const unsigned char *cdb,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * initialize sense data
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringset_scsi_pt_sense(struct uscsi_cmd *uscsi, unsigned char *sense,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Initialize data going to device
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringset_scsi_pt_data_in(struct uscsi_cmd *uscsi, unsigned char *dxferp,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering uscsi->uscsi_flags = USCSI_READ | USCSI_ISOLATE |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Executes SCSI command(or at least forwards it to lower layers).
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringdo_scsi_pt(struct uscsi_cmd *uscsi, int fd, int time_secs)
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* Took an error */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Read log from device
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Invokes a SCSI LOG SENSE command.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * 0 -> success
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt * SG_LIB_CAT_INVALID_OP -> Log Sense not supported,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * SG_LIB_CAT_NOT_READY -> device not ready,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * -1 -> other failure
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringread_log(int sg_fd, unsigned char *resp, int mx_resp_len)
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering {SCMD_LOG_SENSE_G1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* pc = 1, pg_code = 0x7 (logs page) */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* (((pc << 6) & 0xc0) | (pg_code & 0x3f)) = 0x47; */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* pc = 1 current values */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering logsCmdBlk[5] = 0; /* Want all logs starting from 0 */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering logsCmdBlk[7] = (unsigned char) ((mx_resp_len >> 8) & 0xff);
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering logsCmdBlk[8] = (unsigned char) (mx_resp_len & 0xff);
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering set_scsi_pt_cdb(&uscsi, logsCmdBlk, sizeof (logsCmdBlk));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering set_scsi_pt_sense(&uscsi, sense_b, sizeof (sense_b));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering set_scsi_pt_data_in(&uscsi, resp, mx_resp_len);
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering res = do_scsi_pt(&uscsi, sg_fd, DEF_PT_TIMEOUT);
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Save the logs by walking through the entries in the response buffer.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * resp buffer looks like:
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * +=====-========-========-========-========-========-========-========-=====+
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |Byte | | | | | | | | |
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt * |=====+====================================================================|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 0 | reserved | page code |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 1 | Reserved |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 2 |(MSB) Page Length(n-3) |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 3 | (LSB) |
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 4 | Log Parameter (First)(Length X) |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |n-y+1| Log Parameter (Last)(Length y) |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * +==========================================================================+
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Log parameter field looks like:
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * +=====-========-========-========-========-========-========-========-=====+
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |Byte | | | | | | | | |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |=====+====================================================================|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 0 |(MSB) Parameter Code |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 1 | (LSB) |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt * | 2 | DU | DS | TSD | ETC | TMC | LBIN | LP |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |3 | Paramter Length(n-3) |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * | 4 | Parameter Values |
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * |-----+--------------------------------------------------------------------|
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poetteringsave_logs(unsigned char *resp, int len, nvlist_t *log_data,
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering char *last_log_entry, unsigned long *seq_num_ret, int *number_log_entries)
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering unsigned char *lpp; /* Log parameter pointer */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering unsigned char *log_str_ptr; /* ptr to ascii str returend by expander */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering unsigned long seq_num_ul = 0;
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (void) memset(seq_num, 0, sizeof (seq_num));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* Initial log paramter pointer to point to first log entry */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* The resp includes 4 bytes of header info and then log entries */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* Find last sequence number from last log read */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (strlen(last_log_entry) == SES_LOG_VALID_LOG_SIZE)) {
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt (void) strncpy(seq_num, (const char *) last_log_entry +
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* save this in case there are no new entries */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* First find if there are duplicate entries */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Start walking each log entry in return buffer looking for
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * a duplicate entry.
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering for (; k > 0; k -= paramLen) {
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Should always have at least 3 Bytes for
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * If not, it must be a bad record so stop
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering return (SES_LOG_FAILED_SHORT_LOG_PARAM_INIT);
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * initial log_str_ptr to point to string info returned
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt * by expander
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * first 4 bytes of log
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * parameter are 2 param:
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * codes Control byte, Parameter length
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Check to see if this is the
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * Found an exact
f7dc3ab9f43b67abcbd34062b9352ab42debec49Lennart Poettering (void) memset(log_event_type, 0, sizeof (log_event_type));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (void) memset(seq_num, 0, sizeof (seq_num));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (void) memset(log_code, 0, sizeof (log_code));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (void) memset(save_buffer, 0, sizeof (save_buffer));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering (void) memset(log_level, 0, sizeof (log_level));
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* K will be initialized from above */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering for (; k > 0; k -= paramLen) {
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* Should always have at least 3 Bytes for each entry */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering /* If not, it must be a bad record so stop processing */
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * initial log_str_ptr to point to string info of the log entry
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * First 4 bytes of log entry contains param code, control
66cdd0f2d0670b054bd27dad16fcb5838b11dde3Lennart Poettering * byte, length
* log_entry.log_word0, log_entry.ts_u, log_entry.ts_l,
* log_entry.seq_num, log_entry.log_code, log_entry.log_word2,
(const char *)log_str_ptr,
char *ulp;
ulp = (char *)
ulp = (char *)
&seq_num;
ulp = (char *)
&log_code;
ulp = 0;
if (ulp) {
(const char *) log_str_ptr +
NV_UNIQUE_NAME, 0) != 0) {
return (SES_LOG_FAILED_NV_UNIQUE);
save_buffer) != 0) {
return (SES_LOG_FAILED_NV_LOG);
log_code) != 0) {
return (SES_LOG_FAILED_NV_CODE);
log_level) != 0) {
return (SES_LOG_FAILED_NV_SEV);
entry) != 0) {
return (SES_LOG_FAILED_NV_ENTRY);
(*number_log_entries)++;
if (entry_added) {
int dxfer_len)
if (dxfer_len > 0) {
{SCMD_MODE_SENSE_G1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if (res) {
return (ret);
{SCMD_MODE_SELECT_G1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if (res) {
return (ret);
int bd_len;
int calc_len;
int offset;
return (offset);
int md_len;
int read_in_len = 0;
long myhostid;
int error = 0;
if (0 != res) {
return (error);
if (off < 0) {
return (error);
ref_md[0] = 0;
return (error);
return (error);
return (error);
sizeof (clear_data));
if (res != 0) {
return (error);
return (error);
int sg_fd;
unsigned long seq_num;
int error;
return (SES_LOG_FAILED_TO_OPEN_DEVICE);
if (res == 0) {
return (SES_LOG_FAILED_TO_READ_DEVICE);
if (error != 0) {
return (error);
return (error);
long poll_time;
int error;
return (SES_LOG_FAILED_NULL_TARGET_PATH);
return (SES_LOG_UNSUPPORTED_HW_ERROR);
return (SES_LOG_FAILED_BAD_TARGET_PATH);
if (error != 0) {
return (SES_LOG_FAILED_NVLIST_CREATE);
if (error != 0) {
return (SES_LOG_FAILED_NVLIST_PROTOCOL);
return (error);