On Sun, Aug 20, 2017 at 01:33:53AM +0300, Dmitry V. Levin wrote: > On Sat, Aug 19, 2017 at 09:50:10AM +0800, JingPiao Chen wrote: > > * configure.ac (AC_CHECK_HEADERS): Add linux/if_link.h. > > (AC_CHECK_TYPES): Check for struct rtnl_link_stats64 in linux/if_link.h. > > (AC_CHECK_MEMBERS): Check for rx_nohandler field > > in struct rtnl_link_stats and struct rtnl_link_stats64. > > * rtnl_link.c: Include <arpa/inet.h>, <linux/if_arp.h>, > > <linux/if_link.h> and <linux/netdevice.h>. > > (min_ifla_address_len, ifla_address_default_decoder, > > ifla_address_type_specific_decoder, > > decode_ifla_address, decode_rtnl_link_stats, > > decode_rtnl_link_ifmap, decode_rtnl_link_stats64, > > print_item_id, decode_ifla_phys_item_id): New functions. > > (decode_ifla_phys_item_id): New array. > > How could decode_ifla_phys_item_id be both a function and an array? > > > (decode_ifinfomsg): Use it. > > --- [...] > > +static bool > > +decode_rtnl_link_stats(struct tcb *const tcp, > > + const kernel_ulong_t addr, > > + const unsigned int len, > > + const void *const opaque_data) > > +{ > > + struct rtnl_link_stats st; > > + > > + if (len < sizeof(st)) > > + return false; > > The kernel may not transfer struct rtnl_link_stats.rx_nohandler despite > the latter being defined by linux/if_link.h, e.g. if the kernel uses > an older version of struct rtnl_link_stats. > The minimal size is therefore not sizeof(struct rtnl_link_stats) > but offsetofend(struct rtnl_link_stats, tx_compressed). > > Likewise, with struct rtnl_link_stats64.rx_nohandler.
You means: struct rtnl_link_stats st; const unsigned int sizeof_stat = offsetofend(struct rtnl_link_stats, tx_compressed); if (len < sizeof_stat) return false; else if (!umoven_or_printaddr(tcp, addr, sizeof_stat, &st)) { ... I can not understand where I can know kernel not transfer struct rtnl_link_stats.rx_nohandler. net/core/rtnetlink.c: static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb, struct net_device *dev) { struct rtnl_link_stats64 *sp; struct nlattr *attr; /* It seem here include rtnl_link_stats64.rx_nohandler */ attr = nla_reserve_64bit(skb, IFLA_STATS64, sizeof(struct rtnl_link_stats64), IFLA_PAD); if (!attr) return -EMSGSIZE; sp = nla_data(attr); dev_get_stats(dev, sp); /* It seem here include rtnl_link_stats.rx_nohandler */ attr = nla_reserve(skb, IFLA_STATS, sizeof(struct rtnl_link_stats)); if (!attr) return -EMSGSIZE; copy_rtnl_link_stats(nla_data(attr), sp); return 0; } struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, struct rtnl_link_stats64 *storage) { ... storage->rx_nohandler += (unsigned long)atomic_long_read(&dev->rx_nohandler); .... } static void copy_rtnl_link_stats(struct rtnl_link_stats *a, const struct rtnl_link_stats64 *b) { ... a->rx_nohandler = b->rx_nohandler; } rtnl_link_stats.rx_nohandler and rtnl_link_stats64.rx_nohandler introduce by linux commit v4.5-rc2-193-g6e7333d. > > > + else if (!umove_or_printaddr(tcp, addr, &st)) { > > + PRINT_FIELD_U("{", st, rx_packets); > > + PRINT_FIELD_U(", ", st, tx_packets); > > + PRINT_FIELD_U(", ", st, rx_bytes); > > + PRINT_FIELD_U(", ", st, tx_bytes); > > + PRINT_FIELD_U(", ", st, rx_errors); > > + PRINT_FIELD_U(", ", st, tx_errors); > > + PRINT_FIELD_U(", ", st, rx_dropped); > > + PRINT_FIELD_U(", ", st, tx_dropped); > > + PRINT_FIELD_U(", ", st, multicast); > > + PRINT_FIELD_U(", ", st, collisions); > > + > > + PRINT_FIELD_U(", ", st, rx_length_errors); > > + PRINT_FIELD_U(", ", st, rx_over_errors); > > + PRINT_FIELD_U(", ", st, rx_crc_errors); > > + PRINT_FIELD_U(", ", st, rx_frame_errors); > > + PRINT_FIELD_U(", ", st, rx_fifo_errors); > > + PRINT_FIELD_U(", ", st, rx_missed_errors); > > + > > + PRINT_FIELD_U(", ", st, tx_aborted_errors); > > + PRINT_FIELD_U(", ", st, tx_carrier_errors); > > + PRINT_FIELD_U(", ", st, tx_fifo_errors); > > + PRINT_FIELD_U(", ", st, tx_heartbeat_errors); > > + PRINT_FIELD_U(", ", st, tx_window_errors); > > + > > + PRINT_FIELD_U(", ", st, rx_compressed); > > + PRINT_FIELD_U(", ", st, tx_compressed); > > +#ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER > > + PRINT_FIELD_U(", ", st, rx_nohandler); > > +#endif > > + tprints("}"); > > + } > > + > > + return true; > > +} > > + > > +static bool > > +decode_rtnl_link_ifmap(struct tcb *const tcp, > > + const kernel_ulong_t addr, > > + const unsigned int len, > > + const void *const opaque_data) > > +{ > > + struct rtnl_link_ifmap map; > > + const unsigned int sizeof_ifmap = > > + offsetofend(struct rtnl_link_ifmap, port); > > + > > + if (len < sizeof_ifmap) > > + return false; > > + else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) { > > + PRINT_FIELD_X("{", map, mem_start); > > + PRINT_FIELD_X(", ", map, mem_end); > > + PRINT_FIELD_X(", ", map, base_addr); > > + PRINT_FIELD_U(", ", map, irq); > > + PRINT_FIELD_U(", ", map, dma); > > + PRINT_FIELD_U(", ", map, port); > > + tprints("}"); > > + } > > + > > + return true; > > +} > > + > > +static bool > > +decode_rtnl_link_stats64(struct tcb *const tcp, > > + const kernel_ulong_t addr, > > + const unsigned int len, > > + const void *const opaque_data) > > +{ > > +#ifdef HAVE_STRUCT_RTNL_LINK_STATS64 > > + struct rtnl_link_stats64 st; > > + > > + if (len < sizeof(st)) > > + return false; > > + else if (!umove_or_printaddr(tcp, addr, &st)) { > > + PRINT_FIELD_U("{", st, rx_packets); > > + PRINT_FIELD_U(", ", st, tx_packets); > > + PRINT_FIELD_U(", ", st, rx_bytes); > > + PRINT_FIELD_U(", ", st, tx_bytes); > > + PRINT_FIELD_U(", ", st, rx_errors); > > + PRINT_FIELD_U(", ", st, tx_errors); > > + PRINT_FIELD_U(", ", st, rx_dropped); > > + PRINT_FIELD_U(", ", st, tx_dropped); > > + PRINT_FIELD_U(", ", st, multicast); > > + PRINT_FIELD_U(", ", st, collisions); > > + > > + PRINT_FIELD_U(", ", st, rx_length_errors); > > + PRINT_FIELD_U(", ", st, rx_over_errors); > > + PRINT_FIELD_U(", ", st, rx_crc_errors); > > + PRINT_FIELD_U(", ", st, rx_frame_errors); > > + PRINT_FIELD_U(", ", st, rx_fifo_errors); > > + PRINT_FIELD_U(", ", st, rx_missed_errors); > > + > > + PRINT_FIELD_U(", ", st, tx_aborted_errors); > > + PRINT_FIELD_U(", ", st, tx_carrier_errors); > > + PRINT_FIELD_U(", ", st, tx_fifo_errors); > > + PRINT_FIELD_U(", ", st, tx_heartbeat_errors); > > + PRINT_FIELD_U(", ", st, tx_window_errors); > > + > > + PRINT_FIELD_U(", ", st, rx_compressed); > > + PRINT_FIELD_U(", ", st, tx_compressed); > > +#ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER > > + PRINT_FIELD_U(", ", st, rx_nohandler); > > +#endif > > + tprints("}"); > > + } > > + > > + return true; > > +#else > > + return false; > > +#endif > > +} > > + > > +static bool > > +print_item_id(struct tcb *const tcp, void *const elem_buf, > > + const size_t elem_size, void *const opaque_data) > > +{ > > + unsigned int *const count = opaque_data; > > + > > + /* MAX_PHYS_ITEM_ID_LEN = 32 */ > > + if ((*count)++ >= 32) { > > + tprints("..."); > > + return false; > > + } > > + > > + tprintf("%" PRIu8, *(uint8_t *) elem_buf); I changed: tprintf("%02x", *(uint8_t *) elem_buf); > > + > > + return true; > > +} > > + > > +static bool > > +decode_ifla_phys_item_id(struct tcb *const tcp, > > + const kernel_ulong_t addr, > > + const unsigned int len, > > + const void *const opaque_data) > > +{ > > + uint8_t id; > > + unsigned int count = 0; > > + > > + print_array(tcp, addr, len, &id, sizeof(id), > > + umoven_or_printaddr, print_item_id, &count); > > I'm not sure it's the best way to decode struct netdev_phys_item_id.id. Or I can reference iproute2/lib/utils.c: hexstring_n2a Now: [xx, xx, xx, xx, xx] hexstring_n2a: xx xx xx xx xx xx strace print xx xx xx xx xx xx seems strange, here space as delimiter, easy to misunderstand it is in memory. what do think? > > > + > > + return true; > > +} > > + > > +static const nla_decoder_t ifinfomsg_nla_decoders[] = { > > + [IFLA_ADDRESS] = decode_ifla_address, > > + [IFLA_BROADCAST] = decode_ifla_address, > > + [IFLA_IFNAME] = decode_nla_str, > > + [IFLA_MTU] = decode_nla_u32, > > + [IFLA_LINK] = decode_nla_u32, > > + [IFLA_QDISC] = decode_nla_str, > > + [IFLA_STATS] = decode_rtnl_link_stats, > > + [IFLA_COST] = NULL, > > + [IFLA_PRIORITY] = NULL, > > + [IFLA_MASTER] = decode_nla_u32, > > + [IFLA_WIRELESS] = NULL, > > Here a parser of struct iw_event is expected. > > > + [IFLA_PROTINFO] = NULL, > > This one seems to be used in the kernel. > > > + [IFLA_TXQLEN] = decode_nla_u32, > > + [IFLA_MAP] = decode_rtnl_link_ifmap, > > + [IFLA_WEIGHT] = decode_nla_u32, > > + [IFLA_OPERSTATE] = decode_nla_u8, > > + [IFLA_LINKMODE] = decode_nla_u8, > > + [IFLA_LINKINFO] = NULL, > > This one also seems to be used in the kernel. > > > + [IFLA_NET_NS_PID] = decode_nla_u32, > > + [IFLA_IFALIAS] = decode_nla_str, > > + [IFLA_NUM_VF] = decode_nla_u32, > > + [IFLA_VFINFO_LIST] = NULL, > > Likewise. > > > + [IFLA_STATS64] = decode_rtnl_link_stats64, > > + [IFLA_VF_PORTS] = NULL, > > Likewise. > > > + [IFLA_PORT_SELF] = NULL, > > Likewise. > > > + [IFLA_AF_SPEC] = NULL, > > Likewise. > > > + [IFLA_GROUP] = decode_nla_u32, > > + [IFLA_NET_NS_FD] = decode_nla_u32, > > + [IFLA_EXT_MASK] = decode_nla_u32, > > + [IFLA_PROMISCUITY] = decode_nla_u32, > > + [IFLA_NUM_TX_QUEUES] = decode_nla_u32, > > + [IFLA_NUM_RX_QUEUES] = decode_nla_u32, > > + [IFLA_CARRIER] = decode_nla_u8, > > + [IFLA_PHYS_PORT_ID] = decode_ifla_phys_item_id, > > + [IFLA_CARRIER_CHANGES] = decode_nla_u32, > > + [IFLA_PHYS_SWITCH_ID] = decode_ifla_phys_item_id, > > + [IFLA_LINK_NETNSID] = decode_nla_s32, > > + [IFLA_PHYS_PORT_NAME] = decode_nla_str, > > + [IFLA_PROTO_DOWN] = decode_nla_u8, > > + [IFLA_GSO_MAX_SEGS] = decode_nla_u32, > > + [IFLA_GSO_MAX_SIZE] = decode_nla_u32, > > + [IFLA_PAD] = NULL, > > + [IFLA_XDP] = NULL, > > Likewise. You means that I should decode all the attributes? Decode all the attributes in one commit the patch will very big, and I'm not familiar with some attribute data, e.g. struct iw_event. So need a lot of time. -- JingPiao Chen ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel