Hello community, here is the log from the commit of package hwinfo for openSUSE:Factory checked in at 2016-11-19 12:49:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hwinfo (Old) and /work/SRC/openSUSE:Factory/.hwinfo.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hwinfo" Changes: -------- --- /work/SRC/openSUSE:Factory/hwinfo/hwinfo.changes 2016-11-12 12:59:56.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.hwinfo.new/hwinfo.changes 2016-11-19 12:49:47.000000000 +0100 @@ -1,0 +2,14 @@ +Fri Nov 18 15:04:57 UTC 2016 - snw...@suse.com + +- increase version +- look for dmi table also in sysfs (bsc#1010276) +- 21.37 + +------------------------------------------------------------------- +Thu Nov 17 12:49:23 UTC 2016 - snw...@suse.com + +- provide also HD_MINOR_VERSION in hd.h header file +- add permanent mac address field for network cards (bsc#1007172) +- 21.36 + +------------------------------------------------------------------- Old: ---- hwinfo-21.35.tar.xz New: ---- hwinfo-21.37.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hwinfo.spec ++++++ --- /var/tmp/diff_new_pack.taBZ6A/_old 2016-11-19 12:49:48.000000000 +0100 +++ /var/tmp/diff_new_pack.taBZ6A/_new 2016-11-19 12:49:48.000000000 +0100 @@ -36,7 +36,7 @@ Group: Hardware/Other # Until migration to github this should be correct url Url: http://gitorious.org/opensuse/hwinfo -Version: 21.35 +Version: 21.37 Release: 0 Source: %{name}-%{version}.tar.xz BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ hwinfo-21.35.tar.xz -> hwinfo-21.37.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/VERSION new/hwinfo-21.37/VERSION --- old/hwinfo-21.35/VERSION 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/VERSION 2016-11-18 16:02:04.000000000 +0100 @@ -1 +1 @@ -21.35 +21.37 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/changelog new/hwinfo-21.37/changelog --- old/hwinfo-21.35/changelog 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/changelog 2016-11-18 16:02:04.000000000 +0100 @@ -1,3 +1,11 @@ +2016-11-18: 21.37 + - increase version + - look for dmi table also in sysfs (bsc #1010276) + +2016-11-17: 21.36 + - provide also HD_MINOR_VERSION in hd.h header file + - add permanent mac address field for network cards (bsc #1007172) + 2016-11-11: 21.35 - ensure network devices have a bus_id (bsc #1007172) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/Makefile new/hwinfo-21.37/src/hd/Makefile --- old/hwinfo-21.35/src/hd/Makefile 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/Makefile 2016-11-18 16:02:04.000000000 +0100 @@ -9,6 +9,7 @@ hd.h: $(TOPDIR)/VERSION @perl -pi -e "s/define\s+HD_VERSION\s+\d+/define HD_VERSION\t$(LIBHD_MAJOR_VERSION)/" $@ + @perl -pi -e "s/define\s+HD_MINOR_VERSION\s+\d+/define HD_MINOR_VERSION\t$(LIBHD_MINOR_VERSION)/" $@ $(LIBHD_D): $(OBJS) ar r $(LIBHD) $? diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/bios.c new/hwinfo-21.37/src/hd/bios.c --- old/hwinfo-21.35/src/hd/bios.c 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/bios.c 2016-11-18 16:02:04.000000000 +0100 @@ -612,10 +612,26 @@ unsigned u, u1, u2, ok, hlen = 0, ofs; unsigned addr = 0, len = 0, scnt; unsigned structs = 0, type, slen; + unsigned use_sysfs = 0; char *s; - memory_range_t memory; + memory_range_t memory, memory_sysfs; hd_smbios_t *sm; + memory_sysfs.data = get_sysfs_attr_by_path2("/sys/firmware/dmi/tables", "smbios_entry_point", &memory_sysfs.size); + + if(memory_sysfs.data) { + // get_sysfs_attr_by_path2 returns static buffer; make a copy + unsigned char *buf = memory_sysfs.data; + memory_sysfs.data = new_mem(memory_sysfs.size); + memcpy(memory_sysfs.data, buf, memory_sysfs.size); + memory_sysfs.start = 0; + dump_memory(hd_data, &memory_sysfs, 0, "SMBIOS Entry Point (sysfs)"); + if(memory_sysfs.size >= 0x10) { + use_sysfs = 1; + mem = &memory_sysfs; + } + } + if(!mem->data || mem->size < 0x10) return; for(u = ok = 0; u <= mem->size - 0x10; u += 0x10) { @@ -649,15 +665,35 @@ hd_data->smbios = smbios_free(hd_data->smbios); + ADD2LOG(" Found DMI table at 0x%08x (0x%04x bytes)\n", addr, len); + memory.start = mem->start + u; memory.size = hlen; memory.data = mem->data + u; - dump_memory(hd_data, &memory, 0, "SMBIOS Entry Point"); + if(!use_sysfs) dump_memory(hd_data, &memory, 0, "SMBIOS Entry Point"); - memory.start = addr; - memory.size = len; memory.data = NULL; - read_memory(hd_data, &memory); + memory.start = addr; + + if(use_sysfs) { + memory.data = get_sysfs_attr_by_path2("/sys/firmware/dmi/tables", "DMI", &memory.size); + if(memory.data) { + // get_sysfs_attr_by_path2 returns static buffer; make a copy + unsigned char *buf = memory.data; + memory.data = new_mem(memory.size); + memcpy(memory.data, buf, memory.size); + ADD2LOG(" Got DMI table from sysfs (0x%04x bytes)\n", memory.size); + if(memory.size != len) { + ADD2LOG(" Oops: DMI table size mismatch; expected 0x%04x bytes!\n", len); + } + } + } + + if(!memory.data) { + memory.size = len; + read_memory(hd_data, &memory); + } + if(len >= 0x4000) { ADD2LOG( " SMBIOS Structure Table at 0x%05x (size 0x%x)\n", @@ -716,6 +752,7 @@ } memory.data = free_mem(memory.data); + memory_sysfs.data = free_mem(memory_sysfs.data); smbios_parse(hd_data); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/hd.c new/hwinfo-21.37/src/hd/hd.c --- old/hwinfo-21.35/src/hd/hd.c 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/hd.c 2016-11-18 16:02:04.000000000 +0100 @@ -1740,7 +1740,7 @@ free_mem(res->pppd_option.option); } - if(res->any.type == res_hwaddr) { + if(res->any.type == res_hwaddr || res->any.type == res_phwaddr) { free_mem(res->hwaddr.addr); } @@ -6067,16 +6067,26 @@ */ char *get_sysfs_attr_by_path2(const char *path, const char *attr, unsigned *len) { - static char buf[1024]; - int i, fd; + static char *buf = NULL; + char * ptr; + int i, fd, max; if(len) *len = 0; + // init static buffer on first run + if(!buf) buf = new_mem(MAX_ATTR_SIZE + 1); + + if(!buf) return NULL; + sprintf(buf, "%s/%s", path, attr); fd = open(buf, O_RDONLY); if(fd >= 0) { - i = read(fd, buf, sizeof buf - 1); + max = MAX_ATTR_SIZE; + ptr = buf; + while((i = read(fd, ptr, max)) > 0) max -= i, ptr += i; close(fd); + // even if there was some read error, accept partial data + if(ptr != buf) i = ptr - buf; if(i >= 0) { if(len) *len = i; buf[i] = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/hd.h new/hwinfo-21.37/src/hd/hd.h --- old/hwinfo-21.35/src/hd/hd.h 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/hd.h 2016-11-18 16:02:04.000000000 +0100 @@ -20,6 +20,8 @@ /** Interface version */ #define HD_VERSION 21 +#define HD_MINOR_VERSION 37 +#define HD_FULL_VERSION (HD_VERSION * 1000 + HD_MINOR_VERSION) /** * @defgroup DEBUGpub Debug flags @@ -1636,7 +1638,7 @@ typedef enum resource_types { res_any, res_phys_mem, res_mem, res_io, res_irq, res_dma, res_monitor, res_size, res_disk_geo, res_cache, res_baud, res_init_strings, res_pppd_option, - res_framebuffer, res_hwaddr, res_link, res_wlan, res_fc + res_framebuffer, res_hwaddr, res_link, res_wlan, res_fc, res_phwaddr } hd_resource_types_t; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/hd_int.h new/hwinfo-21.37/src/hd/hd_int.h --- old/hwinfo-21.35/src/hd/hd_int.h 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/hd_int.h 2016-11-18 16:02:04.000000000 +0100 @@ -58,6 +58,10 @@ #define WITH_ISDN 1 #endif +// maximum attribute size in sysfs we expect +// (this is to avoid accidentally reading unlimited data) +#define MAX_ATTR_SIZE 0x10000 + #define PROGRESS(a, b, c) progress(hd_data, a, b, c) #define ADD2LOG(a...) hd_log_printf(hd_data, a) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/hdp.c new/hwinfo-21.37/src/hd/hdp.c --- old/hwinfo-21.35/src/hd/hdp.c 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/hdp.c 2016-11-18 16:02:04.000000000 +0100 @@ -756,6 +756,10 @@ dump_line("HW Address: %s\n", res->hwaddr.addr); break; + case res_phwaddr: + dump_line("Permanent HW Address: %s\n", res->hwaddr.addr); + break; + case res_link: dump_line("Link detected: %s\n", res->link.state ? "yes" : "no"); break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hwinfo-21.35/src/hd/net.c new/hwinfo-21.37/src/hd/net.c --- old/hwinfo-21.35/src/hd/net.c 2016-11-11 15:53:27.000000000 +0100 +++ new/hwinfo-21.37/src/hd/net.c 2016-11-18 16:02:04.000000000 +0100 @@ -37,6 +37,7 @@ static void get_ethtool_priv(hd_data_t *hd_data, hd_t *hd); static void get_driverinfo(hd_data_t *hd_data, hd_t *hd); static void get_linkstate(hd_data_t *hd_data, hd_t *hd); +static hd_res_t *get_phwaddr(hd_data_t *hd_data, hd_t *hd); static void add_xpnet(hd_data_t *hdata); static void add_uml(hd_data_t *hdata); static void add_kma(hd_data_t *hdata); @@ -52,7 +53,7 @@ int if_type, if_carrier; hd_t *hd, *hd_card; char *s, *t, *hw_addr; - hd_res_t *res, *res1; + hd_res_t *res, *res_hw, *res_phw, *res_lnk; uint64_t ul0; str_list_t *sf_class, *sf_class_e; char *sf_cdev = NULL, *sf_dev = NULL; @@ -126,14 +127,19 @@ hd->base_class.id = bc_network_interface; hd->sub_class.id = sc_nif_other; - res1 = NULL; + hd->unix_dev_name = new_str(sf_class_e->str); + hd->sysfs_id = new_str(hd_sysfs_id(sf_cdev)); + + res_hw = NULL; if(hw_addr && strspn(hw_addr, "0:") != strlen(hw_addr)) { - res1 = new_mem(sizeof *res1); - res1->hwaddr.type = res_hwaddr; - res1->hwaddr.addr = new_str(hw_addr); - add_res_entry(&hd->res, res1); + res_hw = new_mem(sizeof *res_hw); + res_hw->hwaddr.type = res_hwaddr; + res_hw->hwaddr.addr = new_str(hw_addr); + add_res_entry(&hd->res, res_hw); } + res_phw = get_phwaddr(hd_data, hd); + if(if_carrier >= 0) { res = new_mem(sizeof *res); res->link.type = res_link; @@ -141,9 +147,6 @@ add_res_entry(&hd->res, res); } - hd->unix_dev_name = new_str(sf_class_e->str); - hd->sysfs_id = new_str(hd_sysfs_id(sf_cdev)); - if(sf_drv_name) { add_str_list(&hd->drivers, sf_drv_name); } @@ -280,12 +283,12 @@ hd_set_hw_class(hd_card, hw_network_ctrl); /* add hw addr to network card */ - if(res1) { + if(res_hw) { u = 0; for(res = hd_card->res; res; res = res->next) { if( res->any.type == res_hwaddr && - !strcmp(res->hwaddr.addr, res1->hwaddr.addr) + !strcmp(res->hwaddr.addr, res_hw->hwaddr.addr) ) { u = 1; break; @@ -294,10 +297,31 @@ if(!u) { res = new_mem(sizeof *res); res->hwaddr.type = res_hwaddr; - res->hwaddr.addr = new_str(res1->hwaddr.addr); + res->hwaddr.addr = new_str(res_hw->hwaddr.addr); add_res_entry(&hd_card->res, res); } } + + /* add permanent hw addr to network card */ + if(res_phw) { + u = 0; + for(res = hd_card->res; res; res = res->next) { + if( + res->any.type == res_phwaddr && + !strcmp(res->hwaddr.addr, res_phw->hwaddr.addr) + ) { + u = 1; + break; + } + } + if(!u) { + res = new_mem(sizeof *res); + res->hwaddr.type = res_phwaddr; + res->hwaddr.addr = new_str(res_phw->hwaddr.addr); + add_res_entry(&hd_card->res, res); + } + } + /* * add interface names... * but not wmasterX (bnc #441778) @@ -396,14 +420,14 @@ } if(res) { - for(res1 = hd_card->res; res1; res1 = res1->next) { - if(res1->any.type == res_link) break; + for(res_lnk = hd_card->res; res_lnk; res_lnk = res_lnk->next) { + if(res_lnk->any.type == res_link) break; } - if(res && !res1) { - res1 = new_mem(sizeof *res1); - res1->link.type = res_link; - res1->link.state = res->link.state; - add_res_entry(&hd_card->res, res1); + if(res && !res_lnk) { + res_lnk = new_mem(sizeof *res_lnk); + res_lnk->link.type = res_link; + res_lnk->link.state = res->link.state; + add_res_entry(&hd_card->res, res_lnk); } } @@ -561,6 +585,61 @@ } +/* + * Get permanent hardware address (it's not in sysfs). + */ +hd_res_t *get_phwaddr(hd_data_t *hd_data, hd_t *hd) +{ + int fd; + struct ethtool_perm_addr *phwaddr = new_mem(sizeof (struct ethtool_perm_addr) + MAX_ADDR_LEN); + struct ifreq ifr; + hd_res_t *res = NULL; + + phwaddr->cmd = ETHTOOL_GPERMADDR; + phwaddr->size = MAX_ADDR_LEN; + + if(!hd->unix_dev_name) return res; + + if(strlen(hd->unix_dev_name) > sizeof ifr.ifr_name - 1) return res; + + if((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return res; + + /* get permanent hardware addr */ + memset(&ifr, 0, sizeof ifr); + strcpy(ifr.ifr_name, hd->unix_dev_name); + ifr.ifr_data = (caddr_t) phwaddr; + if(ioctl(fd, SIOCETHTOOL, &ifr) == 0) { + int i; + char *addr = NULL; + if(phwaddr->size > 0) { + addr = new_mem(phwaddr->size * 3 + 1); // yes, we need an extra byte + for(i = 0; i < phwaddr->size; i++) { + sprintf(addr + 3 * i, "%02x:", phwaddr->data[i]); + } + addr[3 * i - 1] = 0; + } + + ADD2LOG(" %s: ethtool permanent hw address[%d]: %s\n", hd->unix_dev_name, phwaddr->size, addr); + + if(addr && strspn(addr, "0:") != strlen(addr)) { + res = new_mem(sizeof *res); + res->hwaddr.type = res_phwaddr; + res->hwaddr.addr = new_str(addr); + add_res_entry(&hd->res, res); + } + + free_mem(addr); + } + else { + ADD2LOG(" %s: GLINK ethtool error: %s\n", hd->unix_dev_name, strerror(errno)); + } + + close(fd); + + return res; +} + + /* * SGI Altix cross partition network. */