Home Man
Today's Posts

Linux & Unix Commands - Search Man Pages

CentOS 7.0 - man page for edac (centos section 3)

EDAC(3) 				     EDAC error reporting library				      EDAC(3)

libedac - EDAC error reporting library
#include <edac.h> cc ... -ledac edac_handle * edac_handle_create (void); void edac_handle_destroy (edac_handle *edac); int edac_handle_init (edac_handle *edac); unsigned int edac_mc_count (edac_handle *edac); int edac_handle_reset (edac_handle *edac); int edac_error_totals (edac_handle *edac, struct edac_totals *totals); edac_mc * edac_next_mc (edac_handle *edac); int edac_mc_get_info (edac_mc *mc, struct edac_mc_info *info); edac_mc *edac_next_mc_info (edac_handle *edac, struct edac_mc_info *info); int edac_mc_reset (struct edac_mc *mc); edac_csrow * edac_next_csrow (struct edac_mc *mc); int edac_csrow_get_info (edac_csrow *csrow, struct edac_csrow_info *info); edac_csrow * edac_next_csrow_info (edac_mc *mc, struct edac_csrow_info *info); const char * edac_strerror (edac_handle *edac); edac_for_each_mc_info (edac_handle *edac, edac_mc *mc, struct edac_csrow_info *info) { ... } edac_for_each_csrow_info (edac_mc *mc, edac_csrow *csrow, struct edac_csrow_info *info) { ... }
The libedac library offers a very simple programming interface to the information exported from in-kernel EDAC (Error Detection and Correction) drivers in sysfs. The edac-util(8) utility uses libedac to report errors in a user-friendly manner from the command line. EDAC errors for most systems are recorded in sysfs on a per memory controller (MC) basis. Memory controllers are further subdivided by csrow and channel. The libedac library provides a method to loop through multiple MCs, and their corresponding csrows, obtaining information about each component from sysfs along the way. There is also a simple single call to retrieve the total error counts for a given machine. In order to use libedac an edac_handle must first be opened via the call edac_handle_create(). Once the handle is created, sysfs data can be loaded into the handle with edac_handle_init(). A final call to edac_han- dle_destroy() will free all memory and open files associated with the edac handle. edac_handle_create() will return NULL on failure to allocate memory. The edac_strerror function will return a descriptive string representation of the last error for the libedac handle edac. The edac_error_totals() function will return the total counts of memory and pci errors in the totals structure passed to the function. The totals structure is of type edac_totals which has the form: struct edac_totals { unsigned int ce_total; /* Total corrected errors */ unsigned int ue_total; /* Total uncorrected errors */ unsigned int pci_parity_total; /* Total PCI Parity errors */ };
Systems may have one or more memory controllers (MCs) with EDAC information. The number of MCs detected by EDAC drivers may be queried with the edac_mc_count() function, while the edac_next_mc function will return a handle to the next memory controller in the libedac handle's internal list. This memory controller is repre- sented by the opaque edac_mc type. edac_next_mc will return NULL when there are no further memory controllers to return. Thus the following exam- ple code is another method to count all EDAC MCs (assuming the EDAC library handle edac has already been ini- tialized): int i = 0; edac_mc *mc; while ((mc = edac_next_mc (edac))) i++; return (i); To query information about an edac_mc, use the edac_mc_get_info function. This function fills in the given info structure, which is of type edac_mc_info: struct edac_mc_info { char id[]; /* Id of memory controller */ char mc_name[]; /* Name of MC */ unsigned int size_mb; /* Amount of RAM in MB */ unsigned int ce_count; /* Corrected error count */ unsigned int ce_noinfo_count;/* noinfo Corrected errors */ unsigned int ue_count; /* Uncorrected error count */ unsigned int ue_noinfo_count;/* noinfo Uncorrected errors*/ }; The function edac_next_mc_info() can be used to loop through all EDAC memory controllers and obtain MC infor- mation in a single call. It is a combined edac_next_mc() and edac_mc_get_info(). The function edac_handle_reset() will reset the internal memory controller iterator in the libedac handle. A subsequent call to edac_next_mc() would thus return the first EDAC MC. A convenience macro, edac_for_each_mc_info(), is provided which defines a for loop that iterates through all memory controller objects for a given EDAC handle, returning the MC information in the info structure on each iteration. For example (assuming initialized libedac handle edac): edac_mc *mc; struct edac_mc_info info; int count = 0; edac_for_each_mc_info (edac, mc, info) { count++; printf ("MC info: id=%s name=%s\n", info.id, info.mc_name); }
Each EDAC memory controller may have one or more csrows associated with it. Similar to the MC iterator func- tions described above, the edac_next_csrow() function allows libedac users to loop through all csrows within a given MC. Once the last csrow is reached, the function will return NULL. The edac_csrow_get_info() function returns information about edac_csrow in the edac_csrow_info structure, which has the contents: struct edac_csrow_info { char id[]; /* CSROW Identity (e.g. csrow0) */ unsigned int size_mb; /* CSROW size in MB */ unsigned int ce_count; /* Total corrected errors */ unsigned int ue_count; /* Total uncorrected errors */ struct edac_channel channel[EDAC_MAX_CHANNELS]; }; struct edac_channel { int valid; /* Is this channel valid */ unsigned int ce_count; /* Corrected error count */ int dimm_label_valid; /* Is DIMM label valid? */ char dimm_label[]; /* DIMM name */ }; The edac_next_csrow_info() function is a combined version of edac_next_csrow() and edac_csrow_get_info() for convenience. The edac_mc_reset() function is provided to reset the edac_mc internal csrow iterator. A convenience macro, edac_for_each_csrow_info(), is provided which defines a for loop that iterates through all csrow objects in an EDAC memory controller, returning the csrow information in the info structure on each iteration.
Initialize libedac handle: edac_handle *edac; if (!(edac = edac_handle_create ())) { fprintf (stderr, "edac_handle_create: Out of memory!\n"); exit (1); } if (edac_handle_init (edac) < 0) { fprintf (stderr, "Unable to get EDAC data: %s\n", edac_strerror (edac)); exit (1); } printf ("EDAC initialized with %d MCs\n", edac_mc_count (edac)); edac_handle_destroy (edac); Report all DIMM labels for MC:csrow:channel combinations edac_mc *mc; edac_csrow *csrow; struct edac_mc_info mci; struct edac_csrow_info csi; edac_for_each_mc_info (ctx->edac, mc, mci) { edac_for_each_csrow_info (mc, csrow, csi) { char *label[2] = { "unset", "unset" }; if (csi.channel[0].dimm_label_valid) label[0] = csi.channel[0].dimm_label; if (csi.channel[1].dimm_label_valid) label[1] = csi.channel[1].dimm_label; printf ("%s:%s:ch0 = %s\n", mci.id, csi.id, label[0]); printf ("%s:%s:ch1 = %s\n", mci.id, csi.id, label[1]); } }
edac-util(8), edac-ctl(8) @META_ALIAS 2009-01-30 EDAC(3)

All times are GMT -4. The time now is 01:16 AM.

Unix & Linux Forums Content Copyrightę1993-2018. All Rights Reserved.
Show Password