|
@@ -1235,81 +1235,33 @@ static ssize_t bonding_store_active_slave(struct device *d,
|
|
|
struct device_attribute *attr,
|
|
|
const char *buf, size_t count)
|
|
|
{
|
|
|
- struct slave *slave, *old_active, *new_active;
|
|
|
+ int ret;
|
|
|
struct bonding *bond = to_bond(d);
|
|
|
- struct list_head *iter;
|
|
|
char ifname[IFNAMSIZ];
|
|
|
+ struct net_device *dev;
|
|
|
|
|
|
if (!rtnl_trylock())
|
|
|
return restart_syscall();
|
|
|
|
|
|
- old_active = new_active = NULL;
|
|
|
- block_netpoll_tx();
|
|
|
- read_lock(&bond->lock);
|
|
|
- write_lock_bh(&bond->curr_slave_lock);
|
|
|
-
|
|
|
- if (!USES_PRIMARY(bond->params.mode)) {
|
|
|
- pr_info("%s: Unable to change active slave; %s is in mode %d\n",
|
|
|
- bond->dev->name, bond->dev->name, bond->params.mode);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
|
|
|
-
|
|
|
- /* check to see if we are clearing active */
|
|
|
if (!strlen(ifname) || buf[0] == '\n') {
|
|
|
- pr_info("%s: Clearing current active slave.\n",
|
|
|
- bond->dev->name);
|
|
|
- rcu_assign_pointer(bond->curr_active_slave, NULL);
|
|
|
- bond_select_active_slave(bond);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- bond_for_each_slave(bond, slave, iter) {
|
|
|
- if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
|
|
|
- old_active = bond->curr_active_slave;
|
|
|
- new_active = slave;
|
|
|
- if (new_active == old_active) {
|
|
|
- /* do nothing */
|
|
|
- pr_info("%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)) {
|
|
|
- pr_info("%s: Setting %s as active"
|
|
|
- " slave.\n",
|
|
|
- bond->dev->name,
|
|
|
- slave->dev->name);
|
|
|
- bond_change_active_slave(bond,
|
|
|
- new_active);
|
|
|
- } else {
|
|
|
- pr_info("%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;
|
|
|
- }
|
|
|
+ dev = NULL;
|
|
|
+ } else {
|
|
|
+ dev = __dev_get_by_name(dev_net(bond->dev), ifname);
|
|
|
+ if (!dev) {
|
|
|
+ ret = -ENODEV;
|
|
|
+ goto out;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pr_info("%s: Unable to set %.*s as active slave.\n",
|
|
|
- bond->dev->name, (int)strlen(buf) - 1, buf);
|
|
|
- out:
|
|
|
- write_unlock_bh(&bond->curr_slave_lock);
|
|
|
- read_unlock(&bond->lock);
|
|
|
- unblock_netpoll_tx();
|
|
|
+ ret = bond_option_active_slave_set(bond, dev);
|
|
|
+ if (!ret)
|
|
|
+ ret = count;
|
|
|
|
|
|
+ out:
|
|
|
rtnl_unlock();
|
|
|
|
|
|
- return count;
|
|
|
+ return ret;
|
|
|
|
|
|
}
|
|
|
static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
|