Commit 93bd2085 authored by Stephen Hemminger's avatar Stephen Hemminger

[NET]: net-sysfs - use attribute group instead of kobject for statistics.

Net statistics were in a kobject only because there was no better way
to create a directory.  Latest 2.6.0-test3 bk tree, has merged in
Pat's change to provide 'attribute groups'.

This patch converts netdevice's from a statistic's kobject to attribute
group.  This is cleaner and fixes some shutdown unload issues as well.

Ps. it gets rid of of the object
parent 348f2c46
......@@ -463,9 +463,6 @@ struct net_device
/* class/net/name entry */
struct class_device class_dev;
/* statistics sub-directory */
struct kobject stats_kobj;
};
#define SET_MODULE_OWNER(dev) do { } while (0)
......
......@@ -188,107 +188,94 @@ static struct class_device_attribute *net_class_attributes[] = {
NULL
};
struct netstat_fs_entry {
struct attribute attr;
ssize_t (*show)(const struct net_device_stats *, char *);
ssize_t (*store)(struct net_device_stats *, const char *, size_t);
};
static ssize_t net_device_stat_show(unsigned long var, char *buf)
/* Show a given an attribute in the statistics group */
static ssize_t netstat_show(const struct class_device *cd, char *buf,
unsigned long offset)
{
return sprintf(buf, fmt_ulong, var);
struct net_device *dev = to_net_dev(cd);
struct net_device_stats *stats;
ssize_t ret = -EINVAL;
if (offset > sizeof(struct net_device_stats) ||
offset % sizeof(unsigned long) != 0)
WARN_ON(1);
read_lock(&dev_base_lock);
if (dev_isalive(dev) && dev->get_stats &&
(stats = (*dev->get_stats)(dev)))
ret = sprintf(buf, fmt_ulong,
*(unsigned long *)(((u8 *) stats) + offset));
read_unlock(&dev_base_lock);
return ret;
}
/* generate a read-only statistics attribute */
#define NETDEVICE_STAT(_NAME) \
static ssize_t show_stat_##_NAME(const struct net_device_stats *stats, \
char *buf) \
#define NETSTAT_ENTRY(name) \
static ssize_t show_##name(struct class_device *cd, char *buf) \
{ \
return net_device_stat_show(stats->_NAME, buf); \
return netstat_show(cd, buf, \
offsetof(struct net_device_stats, name)); \
} \
static struct netstat_fs_entry net_stat_##_NAME = { \
.attr = {.name = __stringify(_NAME), .mode = S_IRUGO }, \
.show = show_stat_##_NAME, \
}
NETDEVICE_STAT(rx_packets);
NETDEVICE_STAT(tx_packets);
NETDEVICE_STAT(rx_bytes);
NETDEVICE_STAT(tx_bytes);
NETDEVICE_STAT(rx_errors);
NETDEVICE_STAT(tx_errors);
NETDEVICE_STAT(rx_dropped);
NETDEVICE_STAT(tx_dropped);
NETDEVICE_STAT(multicast);
NETDEVICE_STAT(collisions);
NETDEVICE_STAT(rx_length_errors);
NETDEVICE_STAT(rx_over_errors);
NETDEVICE_STAT(rx_crc_errors);
NETDEVICE_STAT(rx_frame_errors);
NETDEVICE_STAT(rx_fifo_errors);
NETDEVICE_STAT(rx_missed_errors);
NETDEVICE_STAT(tx_aborted_errors);
NETDEVICE_STAT(tx_carrier_errors);
NETDEVICE_STAT(tx_fifo_errors);
NETDEVICE_STAT(tx_heartbeat_errors);
NETDEVICE_STAT(tx_window_errors);
NETDEVICE_STAT(rx_compressed);
NETDEVICE_STAT(tx_compressed);
static struct attribute *default_attrs[] = {
&net_stat_rx_packets.attr,
&net_stat_tx_packets.attr,
&net_stat_rx_bytes.attr,
&net_stat_tx_bytes.attr,
&net_stat_rx_errors.attr,
&net_stat_tx_errors.attr,
&net_stat_rx_dropped.attr,
&net_stat_tx_dropped.attr,
&net_stat_multicast.attr,
&net_stat_collisions.attr,
&net_stat_rx_length_errors.attr,
&net_stat_rx_over_errors.attr,
&net_stat_rx_crc_errors.attr,
&net_stat_rx_frame_errors.attr,
&net_stat_rx_fifo_errors.attr,
&net_stat_rx_missed_errors.attr,
&net_stat_tx_aborted_errors.attr,
&net_stat_tx_carrier_errors.attr,
&net_stat_tx_fifo_errors.attr,
&net_stat_tx_heartbeat_errors.attr,
&net_stat_tx_window_errors.attr,
&net_stat_rx_compressed.attr,
&net_stat_tx_compressed.attr,
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
NETSTAT_ENTRY(rx_packets);
NETSTAT_ENTRY(tx_packets);
NETSTAT_ENTRY(rx_bytes);
NETSTAT_ENTRY(tx_bytes);
NETSTAT_ENTRY(rx_errors);
NETSTAT_ENTRY(tx_errors);
NETSTAT_ENTRY(rx_dropped);
NETSTAT_ENTRY(tx_dropped);
NETSTAT_ENTRY(multicast);
NETSTAT_ENTRY(collisions);
NETSTAT_ENTRY(rx_length_errors);
NETSTAT_ENTRY(rx_over_errors);
NETSTAT_ENTRY(rx_crc_errors);
NETSTAT_ENTRY(rx_frame_errors);
NETSTAT_ENTRY(rx_fifo_errors);
NETSTAT_ENTRY(rx_missed_errors);
NETSTAT_ENTRY(tx_aborted_errors);
NETSTAT_ENTRY(tx_carrier_errors);
NETSTAT_ENTRY(tx_fifo_errors);
NETSTAT_ENTRY(tx_heartbeat_errors);
NETSTAT_ENTRY(tx_window_errors);
NETSTAT_ENTRY(rx_compressed);
NETSTAT_ENTRY(tx_compressed);
static struct attribute *netstat_attrs[] = {
&class_device_attr_rx_packets.attr,
&class_device_attr_tx_packets.attr,
&class_device_attr_rx_bytes.attr,
&class_device_attr_tx_bytes.attr,
&class_device_attr_rx_errors.attr,
&class_device_attr_tx_errors.attr,
&class_device_attr_rx_dropped.attr,
&class_device_attr_tx_dropped.attr,
&class_device_attr_multicast.attr,
&class_device_attr_collisions.attr,
&class_device_attr_rx_length_errors.attr,
&class_device_attr_rx_over_errors.attr,
&class_device_attr_rx_crc_errors.attr,
&class_device_attr_rx_frame_errors.attr,
&class_device_attr_rx_fifo_errors.attr,
&class_device_attr_rx_missed_errors.attr,
&class_device_attr_tx_aborted_errors.attr,
&class_device_attr_tx_carrier_errors.attr,
&class_device_attr_tx_fifo_errors.attr,
&class_device_attr_tx_heartbeat_errors.attr,
&class_device_attr_tx_window_errors.attr,
&class_device_attr_rx_compressed.attr,
&class_device_attr_tx_compressed.attr,
NULL
};
static ssize_t
netstat_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct netstat_fs_entry *entry
= container_of(attr, struct netstat_fs_entry, attr);
struct net_device *dev
= to_net_dev(to_class_dev(kobj->parent));
struct net_device_stats *stats;
ssize_t ret = -EINVAL;
read_lock(&dev_base_lock);
if (dev_isalive(dev) && entry->show && dev->get_stats &&
(stats = (*dev->get_stats)(dev)))
ret = entry->show(stats, buf);
read_unlock(&dev_base_lock);
return ret;
}
static struct sysfs_ops netstat_sysfs_ops = {
.show = netstat_attr_show,
static struct attribute_group netstat_group = {
.name = "statistics",
.attrs = netstat_attrs,
};
static struct kobj_type netstat_ktype = {
.sysfs_ops = &netstat_sysfs_ops,
.default_attrs = default_attrs,
};
#ifdef CONFIG_HOTPLUG
static int netdev_hotplug(struct class_device *cd, char **envp,
......@@ -339,32 +326,23 @@ int netdev_register_sysfs(struct net_device *net)
goto out_unreg;
}
net->stats_kobj.parent = NULL;
if (net->get_stats) {
struct kobject *k = &net->stats_kobj;
k->parent = &class_dev->kobj;
strlcpy(k->name, "statistics", KOBJ_NAME_LEN);
k->ktype = &netstat_ktype;
if (net->get_stats &&
(ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
goto out_unreg;
if((ret = kobject_register(k)))
goto out_unreg;
}
return 0;
out:
return ret;
out_unreg:
printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
net->name, ret);
class_device_unregister(class_dev);
goto out;
out:
return ret;
}
void netdev_unregister_sysfs(struct net_device *net)
{
if (net->stats_kobj.parent)
kobject_unregister(&net->stats_kobj);
class_device_unregister(&net->class_dev);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment