bond_sysfs.c
来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,365 行 · 第 1/3 页
C
1,365 行
bond->params.downdelay * bond->params.miimon); if (bond->params.arp_interval) { printk(KERN_INFO DRV_NAME ": %s: MII monitoring cannot be used with " "ARP monitoring. Disabling ARP monitoring...\n", bond->dev->name); bond->params.arp_interval = 0; /* Kill ARP timer, else it brings bond's link down */ if (bond->mii_timer.function) { printk(KERN_INFO DRV_NAME ": %s: Kill ARP timer, else it brings bond's link down...\n", bond->dev->name); del_timer_sync(&bond->arp_timer); } } if (bond->dev->flags & IFF_UP) { /* If the interface is up, we may need to fire off * the MII timer. If the interface is down, the * timer will get fired off when the open function * is called. */ if (bond->mii_timer.function) { /* The timer's already set up, so fire it off */ mod_timer(&bond->mii_timer, jiffies + 1); } else { /* Set up the timer. */ init_timer(&bond->mii_timer); bond->mii_timer.expires = jiffies + 1; bond->mii_timer.data = (unsigned long) bond->dev; bond->mii_timer.function = (void *) &bond_mii_monitor; add_timer(&bond->mii_timer); } } }out: return ret;}static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);/* * Show and set the primary slave. The store function is much * simpler than bonding_store_slaves function because it only needs to * handle one interface name. * The bond must be a mode that supports a primary for this be * set. */static ssize_t bonding_show_primary(struct class_device *cd, char *buf){ int count = 0; struct bonding *bond = to_bond(cd); if (bond->primary_slave) count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1; else count = sprintf(buf, "\n") + 1; return count;}static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count){ int i; struct slave *slave; struct bonding *bond = to_bond(cd); write_lock_bh(&bond->lock); if (!USES_PRIMARY(bond->params.mode)) { printk(KERN_INFO DRV_NAME ": %s: Unable to set primary slave; %s is in mode %d\n", bond->dev->name, bond->dev->name, bond->params.mode); } else { bond_for_each_slave(bond, slave, i) { if (strnicmp (slave->dev->name, buf, strlen(slave->dev->name)) == 0) { printk(KERN_INFO DRV_NAME ": %s: Setting %s as primary slave.\n", bond->dev->name, slave->dev->name); bond->primary_slave = slave; bond_select_active_slave(bond); goto out; } } /* if we got here, then we didn't match the name of any slave */ if (strlen(buf) == 0 || buf[0] == '\n') { printk(KERN_INFO DRV_NAME ": %s: Setting primary slave to None.\n", bond->dev->name); bond->primary_slave = NULL; bond_select_active_slave(bond); } else { printk(KERN_INFO DRV_NAME ": %s: Unable to set %.*s as primary slave as it is not a slave.\n", bond->dev->name, (int)strlen(buf) - 1, buf); } }out: write_unlock_bh(&bond->lock); return count;}static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);/* * Show and set the use_carrier flag. */static ssize_t bonding_show_carrier(struct class_device *cd, char *buf){ struct bonding *bond = to_bond(cd); return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;}static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count){ int new_value, ret = count; struct bonding *bond = to_bond(cd); if (sscanf(buf, "%d", &new_value) != 1) { printk(KERN_ERR DRV_NAME ": %s: no use_carrier value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if ((new_value == 0) || (new_value == 1)) { bond->params.use_carrier = new_value; printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n", bond->dev->name, new_value); } else { printk(KERN_INFO DRV_NAME ": %s: Ignoring invalid use_carrier value %d.\n", bond->dev->name, new_value); }out: return count;}static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);/* * Show and set currently active_slave. */static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf){ struct slave *curr; struct bonding *bond = to_bond(cd); int count; read_lock(&bond->curr_slave_lock); curr = bond->curr_active_slave; read_unlock(&bond->curr_slave_lock); if (USES_PRIMARY(bond->params.mode) && curr) count = sprintf(buf, "%s\n", curr->dev->name) + 1; else count = sprintf(buf, "\n") + 1; return count;}static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count){ int i; struct slave *slave; struct slave *old_active = NULL; struct slave *new_active = NULL; struct bonding *bond = to_bond(cd); write_lock_bh(&bond->lock); if (!USES_PRIMARY(bond->params.mode)) { printk(KERN_INFO DRV_NAME ": %s: Unable to change active slave; %s is in mode %d\n", bond->dev->name, bond->dev->name, bond->params.mode); } else { bond_for_each_slave(bond, slave, i) { if (strnicmp (slave->dev->name, buf, strlen(slave->dev->name)) == 0) { old_active = bond->curr_active_slave; new_active = slave; if (new_active && (new_active == old_active)) { /* do nothing */ printk(KERN_INFO DRV_NAME ": %s: %s is already the current active slave.\n", bond->dev->name, slave->dev->name); goto out; } else { if ((new_active) && (old_active) && (new_active->link == BOND_LINK_UP) && IS_UP(new_active->dev)) { printk(KERN_INFO DRV_NAME ": %s: Setting %s as active slave.\n", bond->dev->name, slave->dev->name); bond_change_active_slave(bond, new_active); } else { printk(KERN_INFO DRV_NAME ": %s: Could not set %s as active slave; " "either %s is down or the link is down.\n", bond->dev->name, slave->dev->name, slave->dev->name); } goto out; } } } /* if we got here, then we didn't match the name of any slave */ if (strlen(buf) == 0 || buf[0] == '\n') { printk(KERN_INFO DRV_NAME ": %s: Setting active slave to None.\n", bond->dev->name); bond->primary_slave = NULL; bond_select_active_slave(bond); } else { printk(KERN_INFO DRV_NAME ": %s: Unable to set %.*s as active slave as it is not a slave.\n", bond->dev->name, (int)strlen(buf) - 1, buf); } }out: write_unlock_bh(&bond->lock); return count;}static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);/* * Show link status of the bond interface. */static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf){ struct slave *curr; struct bonding *bond = to_bond(cd); read_lock(&bond->curr_slave_lock); curr = bond->curr_active_slave; read_unlock(&bond->curr_slave_lock); return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;}static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);/* * Show current 802.3ad aggregator ID. */static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf){ int count = 0; struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id) + 1; } else count = sprintf(buf, "\n") + 1; return count;}static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);/* * Show number of active 802.3ad ports. */static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf){ int count = 0; struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports) + 1; } else count = sprintf(buf, "\n") + 1; return count;}static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);/* * Show current 802.3ad actor key. */static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf){ int count = 0; struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key) + 1; } else count = sprintf(buf, "\n") + 1; return count;}static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);/* * Show current 802.3ad partner key. */static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf){ int count = 0; struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key) + 1; } else count = sprintf(buf, "\n") + 1; return count;}static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);/* * Show current 802.3ad partner mac. */static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf){ int count = 0; struct bonding *bond = to_bond(cd); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; if (!bond_3ad_get_active_agg_info(bond, &ad_info)) { count = sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x\n", ad_info.partner_system[0], ad_info.partner_system[1], ad_info.partner_system[2], ad_info.partner_system[3], ad_info.partner_system[4], ad_info.partner_system[5]) + 1; } } else count = sprintf(buf, "\n") + 1; return count;}static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);static struct attribute *per_bond_attrs[] = { &class_device_attr_slaves.attr, &class_device_attr_mode.attr, &class_device_attr_arp_interval.attr, &class_device_attr_arp_ip_target.attr, &class_device_attr_downdelay.attr, &class_device_attr_updelay.attr, &class_device_attr_lacp_rate.attr, &class_device_attr_xmit_hash_policy.attr, &class_device_attr_miimon.attr, &class_device_attr_primary.attr, &class_device_attr_use_carrier.attr, &class_device_attr_active_slave.attr, &class_device_attr_mii_status.attr, &class_device_attr_ad_aggregator.attr, &class_device_attr_ad_num_ports.attr, &class_device_attr_ad_actor_key.attr, &class_device_attr_ad_partner_key.attr, &class_device_attr_ad_partner_mac.attr, NULL,};static struct attribute_group bonding_group = { .name = "bonding", .attrs = per_bond_attrs,};/* * Initialize sysfs. This sets up the bonding_masters file in * /sys/class/net. */int bond_create_sysfs(void){ int ret = 0; struct bonding *firstbond; init_rwsem(&bonding_rwsem); /* get the netdev class pointer */ firstbond = container_of(bond_dev_list.next, struct bonding, bond_list); if (!firstbond) return -ENODEV; netdev_class = firstbond->dev->class_dev.class; if (!netdev_class) return -ENODEV; ret = class_create_file(netdev_class, &class_attr_bonding_masters); return ret;}/* * Remove /sys/class/net/bonding_masters. */void bond_destroy_sysfs(void){ if (netdev_class) class_remove_file(netdev_class, &class_attr_bonding_masters);}/* * Initialize sysfs for each bond. This sets up and registers * the 'bondctl' directory for each individual bond under /sys/class/net. */int bond_create_sysfs_entry(struct bonding *bond){ struct net_device *dev = bond->dev; int err; err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group); if (err) { printk(KERN_EMERG "eek! didn't create group!\n"); } if (expected_refcount < 1) expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount); return err;}/* * Remove sysfs entries for each bond. */void bond_destroy_sysfs_entry(struct bonding *bond){ struct net_device *dev = bond->dev; sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?