Hi.

The Fujitsu's iRMC has implemented proprietary function for reading/writing internal configuration variables.

Some of them hold the informations related to host operating system - for example OS version, hostname, system location and so on.

Then they are shown on (for example) CLI and WWW interface of iRMC. It's important especially when you have several boxes - without such identification and with several sessions opened to different computers it's hard to distinguish which window is which.

On supported operating OSes those variables are set by ServerView drivers. On unsupported OSes they are not set.

The IPMI interface for reading/writing configspace is proprietary interface not documented by FSC. I consulted some aspect of problem with Holger Liebig, but it changes nothing on previous sentence - I get no documentation of the interface from H.L nor FSC.

Despite of it I have working implementation in the form of patch against version 0.8.9 of ipmi-oem. It's tested on PRIMERGY RX100 S5 firmware 3.77A but it should work on similar system as well - and (more important) - in the case it doesn't work, it should not harm.

The resulting implementation work this way:
1 (write):
ipmi-oem Fujitsu set-system-info SystemName "$( hostname )"

2 (read):
ipmi-oem Fujitsu get-system-info SystemName
SystemName="master7.m<censored>z"


List of configspace variables I can read/write now:

Key: CabinetLocation <string> /* SNMP SysLocation */
Key: SystemName <string>
Key: SystemDescription <string>
Key: SystemContact <string> /* SNMP SysContact */
Key: ServerCabinetModel <string>
Key: ServerChassisModel <string>
Key: ServerSerialNumber <string>
Key: SystemIP0 <IPv4 (A.B.C.D)>
Key: SystemIP1 <IPv4 (A.B.C.D)>
Key: SystemIP2 <IPv4 (A.B.C.D)>
Key: SystemIP3 <IPv4 (A.B.C.D)>
Key: ServerOperatingSystem <string>
Key: AssetTAG <string>

My implementation is generic, it's easy to add support for other variables (I know many other than those listed above), but we need to be careful as blind playing with configspace may cause BMC malfunction.

Well - after this long prologue, the question is simple.

I don't know the project policy related to implementation of undocumented function. Are you interested to implement such think in public release of freeipmi ?

You can freely ignore this message if not interested.

Dan


--- ipmi-oem/src/ipmi-oem-fujitsu.h.ORIG        2010-08-15 20:18:44.000000000 
+0200
+++ ipmi-oem/src/ipmi-oem-fujitsu.h     2010-08-15 22:08:23.000000000 +0200
@@ -36,4 +36,6 @@
 
 int ipmi_oem_fujitsu_get_error_led (ipmi_oem_state_data_t *state_data);
 
+int ipmi_oem_fujitsu_get_sel_entry_long_text (ipmi_oem_state_data_t 
*state_data);
+
 #endif
--- ipmi-oem/src/ipmi-oem-fujitsu.c.ORIG        2010-08-15 20:18:50.000000000 
+0200
+++ ipmi-oem/src/ipmi-oem-fujitsu.c     2010-08-16 01:45:30.000000000 +0200
@@ -1290,3 +1292,193 @@
  cleanup:
   return (rv);
 }
+
+#define IPMI_OEM_FUJITSU_SEL_NUMBER_MIN 1
+#define IPMI_OEM_FUJITSU_SEL_NUMBER_MAX 0xFFFE
+#define min(a,b) ((a)<(b) ? (a) : (b))
+
+int
+ipmi_oem_fujitsu_get_sel_entry_long_text (ipmi_oem_state_data_t *state_data)
+{
+  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
+  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
+  int rs_len;
+  uint16_t sel_number;
+  uint16_t next_record_id, actual_record_id;
+  uint8_t record_type;
+  uint32_t timestamp;
+  uint8_t severity;
+  uint8_t data_len;
+  char *text;
+  int text_len;
+  const char *severity_text;
+  long tmp;
+  char *ptr;
+  int rv = -1;
+  struct tm tm;
+  char timestr[512];
+  time_t t;
+
+  assert (state_data);
+  assert (state_data->prog_data->args->oem_options_count == 1);
+  
+  tmp = strtol (state_data->prog_data->args->oem_options[0],
+                &ptr,
+                0);
+  if (tmp < -1
+      || tmp > UCHAR_MAX*UCHAR_MAX
+      || (*ptr) != '\0')
+    {
+      pstdout_fprintf (state_data->pstate,
+                       stderr,
+                       "%s:%s invalid OEM option argument '%s'\n",
+                       state_data->prog_data->args->oem_id,
+                       state_data->prog_data->args->oem_command,
+                       state_data->prog_data->args->oem_options[0]);
+      goto cleanup;
+    }
+
+  if (!((tmp >= IPMI_OEM_FUJITSU_SEL_NUMBER_MIN
+        && tmp <= IPMI_OEM_FUJITSU_SEL_NUMBER_MAX) || tmp == 0 || tmp == -1))
+    {
+      pstdout_fprintf (state_data->pstate,
+                       stderr,
+                       "%s:%s invalid OEM option argument '%s' : out of 
range\n",
+                       state_data->prog_data->args->oem_id,
+                       state_data->prog_data->args->oem_command,
+                       state_data->prog_data->args->oem_options[0]);
+      goto cleanup;
+    }
+    
+  if (tmp == -1)
+    tmp = 0xFFFF;
+
+  sel_number = tmp;
+  
+  /* Fujitsu OEM
+   * 
+   * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-ug-en.pdf
+   *
+   * Request
+   *
+   * 0x2E - OEM network function
+   * 0xF5 - OEM cmd
+   * 0x?? - Fujitsu IANA (LSB first)
+   * 0x?? - Fujitsu IANA
+   * 0x?? - Fujitsu IANA
+   * 0x43 - Command Specifier
+   * 0x?? - Record ID (LSB first)
+   * 0x?? - Record ID ; 0x0000 = "first record", 0xFFFF = "last record"
+   * 0x?? - Offset (in response SEL text)
+   * 0x?? - MaxResponseDataSize (size of converted SEL data 16:n in response, 
maximum is 100)
+   *
+   * Response
+   *
+   * 0xF5 - OEM cmd
+   * 0x?? - Completion code
+   * 0x?? - Fujitsu IANA (LSB first)
+   * 0x?? - Fujitsu IANA
+   * 0x?? - Fujitsu IANA
+   * 0x?? - Next Record ID (LSB)
+   * 0x?? - Next Record ID (MSB)
+   * 0x?? - Actual Record ID (LSB)
+   * 0x?? - Actual Record ID (MSB)
+   * 0x?? - Record type
+   * 0x?? - timestamp (LSB first)
+   * 0x?? - timestamp
+   * 0x?? - timestamp
+   * 0x?? - timestamp
+   * 0x?? - severity   
+   *      bit 7   - CSS component
+   *      bit 6-4 - 000 = INFORMATIONAL
+   *                001 = MINOR
+   *                010 = MAJOR
+   *                011 = CRITICAL
+   *                1xx = unknown
+   *      bit 3-0 - reserved
+   * 0x?? - data length (of the whole text)
+   * 0x?? - converted SEL data
+     requested number of bytes starting at requested offset 
(MaxResponseDataSize-1 bytes of data)
+   .....
+   * 0x00 - trailing '\0' character
+   */
+     
+  bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM;
+  bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF);
+  bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8;
+  bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16;
+  bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SEL_ENTRY_LONG_TEXT;
+  bytes_rq[5] = (sel_number & 0x00FF);
+  bytes_rq[6] = (sel_number & 0xFF00) >> 8;
+  bytes_rq[7] = 0;
+  bytes_rq[8] = min(IPMI_OEM_MAX_BYTES-17, 100);
+
+  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
+                              0, /* lun */
+                              IPMI_NET_FN_OEM_GROUP_RQ, /* network function */
+                              bytes_rq, /* data */
+                              9, /* num bytes */
+                              bytes_rs,
+                              IPMI_OEM_MAX_BYTES)) < 0)
+    {
+      pstdout_fprintf (state_data->pstate,
+                       stderr,
+                       "ipmi_cmd_raw: %s\n",
+                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
+      goto cleanup;
+    }
+  
+  if (ipmi_oem_check_response_and_completion_code (state_data,
+                                                   bytes_rs,
+                                                   rs_len,
+                                                   21,
+                                                   IPMI_CMD_OEM_FUJITSU_SYSTEM,
+                                                   IPMI_NET_FN_OEM_GROUP_RS,
+                                                   NULL) < 0)
+    goto cleanup;
+
+  next_record_id = bytes_rs[5] + (bytes_rs[6] << 8);
+  actual_record_id = bytes_rs[7] + (bytes_rs[8] << 8);
+  record_type = bytes_rs[9];
+  timestamp = bytes_rs[10] + (bytes_rs[11] << 8) + (bytes_rs[12] << 16) + 
(bytes_rs[13] << 24);
+  severity = bytes_rs[14];
+  data_len = bytes_rs[15];
+  text = (char *)&(bytes_rs[16]);
+  bytes_rs[IPMI_OEM_MAX_BYTES-1]='\0';
+  
+  text_len = strlen(text);
+
+  switch (severity >> 3) {
+  case  0: severity_text = "INFORMATIONAL:"; break;
+  case  1: severity_text = "MINOR:"; break;
+  case  2: severity_text = "MAJOR:"; break;
+  case  3: severity_text = "CRITICAL:"; break;
+  case  4: 
+  case  5:
+  case  6:
+  case  7: severity_text = ""; break;
+  case  8: severity_text = "INFORMATIONAL/CSS:"; break;
+  case  9: severity_text = "MINOR/CSS:"; break;
+  case 10: severity_text = "MAJOR/CSS:"; break;
+  case 11: severity_text = "CRITICAL/CSS:"; break;
+  case 12: 
+  case 13:
+  case 14:
+  case 15: severity_text = "unknown/CSS:"; break;
+  }
+
+  memset(&tm, 0, sizeof(tm));
+  t = timestamp;
+  localtime_r(&t, &tm);
+  strftime(timestr, sizeof(timestr), "%b-%d-%Y | %H:%M:%S", &tm);
+  
+  pstdout_printf (state_data->pstate,
+                    "%u | %s | %s %s%s\n",
+                    (int)actual_record_id,
+                    timestr,
+                    severity_text, text, data_len == text_len ? "" : " ... 
(text incomplete)");
+  rv = 0;
+ cleanup:
+  return (rv);
+}
+
--- ipmi-oem/src/ipmi-oem.c.ORIG        2010-08-15 22:05:39.000000000 +0200
+++ ipmi-oem/src/ipmi-oem.c     2010-08-15 22:10:31.000000000 +0200
@@ -431,6 +431,13 @@
       ipmi_oem_fujitsu_get_error_led
     },
     {
+      "get-sel-entry-long-text",
+      "<record_number or 0 for first or -1 for last>",
+      1,
+      IPMI_OEM_COMMAND_FLAGS_DEFAULT,
+      ipmi_oem_fujitsu_get_sel_entry_long_text
+    },
+    {
       NULL,
       NULL,
       0,

_______________________________________________
Freeipmi-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/freeipmi-devel

Reply via email to