Example #1
0
static void
send_fma_cap_to_ilom(fmd_hdl_t *hdl, uint32_t fma_cap)
{
    int error;
    char *msg;
    ipmi_handle_t *ipmi_hdl;
    ipmi_cmd_t cmd;
    uint8_t oem_data[OEM_DATA_LENGTH];

    if ((ipmi_hdl = ipmi_open(&error, &msg, IPMI_TRANSPORT_BMC, NULL))
            == NULL) {
        /*
         * If /dev/ipmi0 doesn't exist on the system, then return
         * without doing anything.
         */
        if (error != EIPMI_BMC_OPEN_FAILED)
            fmd_hdl_abort(hdl, "Failed to initialize IPMI "
                          "connection: %s\n", msg);
        fmd_hdl_debug(hdl, "Failed: no IPMI connection present");
        return;
    }

    /*
     * Check if it's Sun ILOM
     */
    if (check_sunoem(ipmi_hdl) != 0) {
        fmd_hdl_debug(hdl, "Service Processor does not run "
                      "Sun ILOM");
        ipmi_close(ipmi_hdl);
        return;
    }

    oem_data[0] = CORE_TUNNEL_SUBCMD_HOSTFMACAP;
    oem_data[1] = VERSION;
    oem_data[2] = fma_cap;

    cmd.ic_netfn = IPMI_NETFN_OEM;
    cmd.ic_lun = 0;
    cmd.ic_cmd = CMD_SUNOEM_CORE_TUNNEL;
    cmd.ic_dlen = OEM_DATA_LENGTH;
    cmd.ic_data = oem_data;

    if (ipmi_send(ipmi_hdl, &cmd) == NULL) {
        fmd_hdl_debug(hdl, "Failed to send Solaris FMA "
                      "capability to ilom: %s", ipmi_errmsg(ipmi_hdl));
    }

    ipmi_close(ipmi_hdl);
}
Example #2
0
int hservice_ipmi_msg(uint8_t netfn, uint8_t cmd,
		void *tx_buf, size_t tx_size,
		void *rx_buf, size_t *rx_size)
{
	struct timeval start, now, delta;
	struct pollfd pollfds[1];
	static long seq;
	size_t size;
	int rc, fd;

	size = be64toh(*rx_size);

	fd = open(ipmi_devnode, O_RDWR);
	if (fd < 0) {
		pr_log(LOG_WARNING, "IPMI: Failed to open IPMI device %s: %m",
				ipmi_devnode);
		return -1;
	}

	seq++;
	pr_debug("IPMI: sending %zd bytes (netfn 0x%02x, cmd 0x%02x)",
			tx_size, netfn, cmd);

	rc = ipmi_send(fd, netfn, cmd, seq, tx_buf, tx_size);
	if (rc) {
		pr_log(LOG_WARNING, "IPMI: send failed");
		goto out;
	}

	gettimeofday(&start, NULL);

	pollfds[0].fd = fd;
	pollfds[0].events = POLLIN;

	for (;;) {
		long rx_seq;
		int timeout;

		gettimeofday(&now, NULL);
		timersub(&now, &start, &delta);
		timeout = ipmi_timeout_ms - ((delta.tv_sec * 1000) +
				(delta.tv_usec / 1000));
		if (timeout < 0)
			timeout = 0;

		rc = poll(pollfds, 1, timeout);
		if (rc < 0) {
			pr_log(LOG_ERR, "IPMI: poll(%s) failed: %m",
					ipmi_devnode);
			break;
		}

		if (rc == 0) {
			pr_log(LOG_WARNING, "IPMI: response timeout (>%dms)",
					ipmi_timeout_ms);
			rc = -1;
			break;
		}

		rc = ipmi_recv(fd, &netfn, &cmd, &rx_seq, rx_buf, &size);
		if (rc)
			break;

		if (seq != rx_seq) {
			pr_log(LOG_NOTICE, "IPMI: out-of-sequence reply: %ld, "
					"expected %ld. Dropping message.",
					rx_seq, seq);
			continue;
		}

		pr_debug("IPMI: received %zd bytes", tx_size);
		*rx_size = be64toh(size);
		rc = 0;
		break;
	}

out:
	close(fd);
	return rc;
}
Example #3
0
int ipmi_transaction(struct ipmi *ipmi, uint8_t netfn, uint8_t cmd,
		uint8_t *req_buf, uint16_t req_len,
		uint8_t *resp_buf, uint16_t *resp_len,
		int timeout_ms)
{
	struct timeval start, now, delta;
	struct pollfd pollfds[1];
	struct flock lock;
	int expired_ms, rc;

	memset(&lock, 0, sizeof(lock));
	lock.l_type = F_WRLCK;
	lock.l_whence = SEEK_SET;
	rc = fcntl(ipmi->fd, F_SETLKW, &lock);
	if (rc == -1) {
		pb_log("IPMI: error locking IPMI device: %m\n");
		return rc;
	}

	rc = ipmi_send(ipmi, netfn, cmd, req_buf, req_len);
	if (rc)
		goto out;

	pollfds[0].fd = ipmi->fd;
	pollfds[0].events = POLLIN;

	gettimeofday(&start, NULL);
	expired_ms = 0;

	for (;;) {
		uint8_t resp_netfn, resp_cmd;
		long seq;

		rc = poll(pollfds, 1, timeout_ms - expired_ms);

		if (rc < 0) {
			pb_log("IPMI: poll() error %m");
			break;
		}
		if (rc == 0) {
			pb_log("IPMI: timeout waiting for response "
					"(netfn %d, cmd %d)\n", netfn, cmd);
			rc = -1;
			break;
		}

		if (!(pollfds[0].revents & POLLIN)) {
			pb_log("IPMI: unexpected fd status from poll?\n");
			rc = -1;
			break;
		}

		rc = ipmi_recv(ipmi, &resp_netfn, &resp_cmd, &seq,
				resp_buf, resp_len);
		if (rc)
			break;

		if (seq != ipmi->seq - 1) {
			pb_log("IPMI: out-of-sequence reply: "
					"exp %ld, got %ld\n",
					ipmi->seq, seq);

			if (timeout_ms) {
				gettimeofday(&now, NULL);
				timersub(&now, &start, &delta);
				expired_ms = (delta.tv_sec * 1000) +
						(delta.tv_usec / 1000);

				if (expired_ms >= timeout_ms) {
					rc = -1;
					break;
				}
			}
		} else {
			pb_debug("IPMI: netfn(%x->%x), cmd(%x->%x)\n",
					netfn, resp_netfn, cmd, resp_cmd);
			rc = 0;
			goto out;
		}
	}

out:
	lock.l_type = F_UNLCK;
	if (fcntl(ipmi->fd, F_SETLKW, &lock) == -1)
		pb_log("IPMI: error unlocking IPMI device: %m\n");
	return rc ? -1 : 0;
}