Joe Eykholt wrote:
> Vasu Dev wrote:
>> The user could temporarily disable a fcoe interface
>> and then enable it again with this added interface,
>> the fcoemon util can use this to temporarily disable
>> fcoe when its DCB state is not operational.
> 
> We could add an 'enable' attribute at the fc_host level, and
> just write 0 or 1 to that.
> 
> Perhaps fcoemon should have its own /sys interface so as not to
> interfere with any user-specified enable/disable.  For example,
> if the user disables it and then the link flaps, fcoemod might
> enable it after DCB is up, conflicting with the user's wishes.
> 
> I'll look at the rest of this patch later.
> 
>       Joe
> 
>> The fcoe enable/disable is tracked by added enabled
>> field to lport and then current lport reset functionality
>> is used to enable and disable all VN_PORTs on a eth
>> interface.
>>
>> Adds sysfs module param enable and disable for this and
>> updates adjacent other module param description to be
>> consistent and more accurate. The older description had
>> double "fcoe" word with less meaningful netdev reference
>> to user/admin.
>>
>> Signed-off-by: Vasu Dev <[email protected]>
>> ---
>>
>>  drivers/scsi/fcoe/fcoe.c      |  122 
>> ++++++++++++++++++++++++++++++++++++++++-
>>  drivers/scsi/libfc/fc_lport.c |    2 -
>>  include/scsi/libfc.h          |    4 +
>>  3 files changed, 124 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
>> index a30ffaa..6e314d8 100644
>> --- a/drivers/scsi/fcoe/fcoe.c
>> +++ b/drivers/scsi/fcoe/fcoe.c
>> @@ -101,6 +101,8 @@ static int fcoe_cpu_callback(struct notifier_block *, 
>> unsigned long, void *);
>>  
>>  static int fcoe_create(const char *, struct kernel_param *);
>>  static int fcoe_destroy(const char *, struct kernel_param *);
>> +static int fcoe_enable(const char *, struct kernel_param *);
>> +static int fcoe_disable(const char *, struct kernel_param *);
>>  
>>  static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
>>                                    u32 did, struct fc_frame *,
>> @@ -115,10 +117,16 @@ static void fcoe_get_lesb(struct fc_lport *, struct 
>> fc_els_lesb *);
>>  
>>  module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
>>  __MODULE_PARM_TYPE(create, "string");
>> -MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
>> +MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface");
>>  module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
>>  __MODULE_PARM_TYPE(destroy, "string");
>> -MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe");
>> +MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet 
>> interface");
>> +module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR);
>> +__MODULE_PARM_TYPE(enable, "string");
>> +MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface.");
>> +module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR);
>> +__MODULE_PARM_TYPE(disable, "string");
>> +MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface.");
>>  
>>  /* notification function for packets from net device */
>>  static struct notifier_block fcoe_notifier = {
>> @@ -509,6 +517,7 @@ static u8 *fcoe_get_src_mac(struct fc_lport *lport)
>>  static int fcoe_lport_config(struct fc_lport *lport)
>>  {
>>      lport->link_up = 0;
>> +    lport->enabled = 1;

The LPORT_ST_DISABLED state takes care of this if you call 
fc_fabric_logoff()/login()
instead of doing fc_fabric_reset().  However, if we have more than one 
enable/disable
mechanism, a flag may be better.  If we add a flag, we might remove the 
DISABLED state.

>>      lport->qfull = 0;
>>      lport->max_retry_count = 3;
>>      lport->max_rport_retry_count = 3;
>> @@ -1838,6 +1847,115 @@ static struct net_device *fcoe_if_to_netdev(const 
>> char *buffer)
>>  }
>>  
>>  /**
>> + * fcoe_disable() - Disables a FCoE interface
>> + * @buffer: The name of the Ethernet interface to be disabled
>> + * @kp:         The associated kernel parameter
>> + *
>> + * Called from sysfs.
>> + *
>> + * Returns: 0 for success
>> + */
>> +static int fcoe_disable(const char *buffer, struct kernel_param *kp)
>> +{
>> +    struct fcoe_interface *fcoe;
>> +    struct net_device *netdev;
>> +    int rc = 0;
>> +
>> +    mutex_lock(&fcoe_config_mutex);
>> +#ifdef CONFIG_FCOE_MODULE
>> +    /*
>> +     * Make sure the module has been initialized, and is not about to be
>> +     * removed.  Module paramter sysfs files are writable before the
>> +     * module_init function is called and after module_exit.
>> +     */
>> +    if (THIS_MODULE->state != MODULE_STATE_LIVE) {
>> +            rc = -ENODEV;
>> +            goto out_nodev;
>> +    }
>> +#endif
>> +
>> +    netdev = fcoe_if_to_netdev(buffer);
>> +    if (!netdev) {
>> +            rc = -ENODEV;
>> +            goto out_nodev;
>> +    }
>> +
>> +    rtnl_lock();
>> +    fcoe = fcoe_hostlist_lookup_port(netdev);
>> +    if (!fcoe) {
>> +            rtnl_unlock();
>> +            rc = -ENODEV;
>> +            goto out_putdev;
>> +    }
>> +    rtnl_unlock();

You could drop rtnl_lock() before the if-statement.
Actually, the list can't change because fcoe_config_mutex is held,
so rtnl_lock isn't needed.

>> +    if (fcoe->ctlr.lp->enabled) {
>> +            fcoe->ctlr.lp->enabled = 0;
>> +            fc_lport_reset(fcoe->ctlr.lp);
>> +    } else
>> +            FCOE_NETDEV_DBG(netdev, "Interface is already disabled\n");
>> +
>> +out_putdev:
>> +    dev_put(netdev);
>> +out_nodev:
>> +    mutex_unlock(&fcoe_config_mutex);
>> +    return rc;
>> +}
>> +
>> +/**
>> + * fcoe_enable() - Enables a FCoE interface
>> + * @buffer: The name of the Ethernet interface to be enabled
>> + * @kp:     The associated kernel parameter
>> + *
>> + * Called from sysfs.
>> + *
>> + * Returns: 0 for success
>> + */
>> +static int fcoe_enable(const char *buffer, struct kernel_param *kp)
>> +{
>> +    struct fcoe_interface *fcoe;
>> +    struct net_device *netdev;
>> +    int rc = 0;
>> +
>> +    mutex_lock(&fcoe_config_mutex);
>> +#ifdef CONFIG_FCOE_MODULE
>> +    /*
>> +     * Make sure the module has been initialized, and is not about to be
>> +     * removed.  Module paramter sysfs files are writable before the
>> +     * module_init function is called and after module_exit.
>> +     */
>> +    if (THIS_MODULE->state != MODULE_STATE_LIVE) {
>> +            rc = -ENODEV;
>> +            goto out_nodev;
>> +    }
>> +#endif
>> +
>> +    netdev = fcoe_if_to_netdev(buffer);
>> +    if (!netdev) {
>> +            rc = -ENODEV;
>> +            goto out_nodev;
>> +    }
>> +
>> +    rtnl_lock();
>> +    fcoe = fcoe_hostlist_lookup_port(netdev);
>> +    if (!fcoe) {
>> +            rtnl_unlock();
>> +            rc = -ENODEV;
>> +            goto out_putdev;
>> +    }
>> +    rtnl_unlock();

Same here.

>> +    if (!fcoe->ctlr.lp->enabled) {
>> +            fcoe->ctlr.lp->enabled = 1;
>> +            fc_lport_reset(fcoe->ctlr.lp);
>> +    } else
>> +            FCOE_NETDEV_DBG(netdev, "Interface is already enabled\n");
>> +out_putdev:
>> +    dev_put(netdev);
>> +out_nodev:
>> +    mutex_unlock(&fcoe_config_mutex);
>> +    return rc;
>> +}
>> +
>> +/**
>>   * fcoe_destroy() - Destroy a FCoE interface
>>   * @buffer: The name of the Ethernet interface to be destroyed
>>   * @kp:         The associated kernel parameter
>> diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
>> index bbf4152..5276ed6 100644
>> --- a/drivers/scsi/libfc/fc_lport.c
>> +++ b/drivers/scsi/libfc/fc_lport.c
>> @@ -976,7 +976,7 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
>>      fc_lport_state_enter(lport, LPORT_ST_RESET);
>>      fc_vports_linkchange(lport);
>>      fc_lport_reset_locked(lport);
>> -    if (lport->link_up)
>> +    if (lport->link_up && lport->enabled)
>>              fc_lport_enter_flogi(lport);
>>  }
>>  
>> diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
>> index 4b912ee..6baa003 100644
>> --- a/include/scsi/libfc.h
>> +++ b/include/scsi/libfc.h
>> @@ -768,6 +768,7 @@ struct fc_disc {
>>   * @vport:                 Parent vport if VN_Port
>>   * @tt:                    Libfc function template
>>   * @link_up:               Link state (1 = link up, 0 = link down)
>> + * @enabled:               enabled (1 = enabled, 0 = disabled)
>>   * @qfull:                 Queue state (1 queue is full, 0 queue is not 
>> full)
>>   * @state:                 Identifies the state
>>   * @boot_time:             Timestamp indicating when the local port came 
>> online
>> @@ -813,12 +814,13 @@ struct fc_lport {
>>      /* Operational Information */
>>      struct libfc_function_template tt;
>>      u8                             link_up;
>> +    u8                             enabled;
>>      u8                             qfull;
>> +    u8                             retry_count;
>>      enum fc_lport_state            state;
>>      unsigned long                  boot_time;
>>      struct fc_host_statistics      host_stats;
>>      struct fcoe_dev_stats          *dev_stats;
>> -    u8                             retry_count;
>>  
>>      /* Fabric information */
>>      u64                            wwpn;
>>
>> _______________________________________________
>> devel mailing list
>> [email protected]
>> http://www.open-fcoe.org/mailman/listinfo/devel
> 
> _______________________________________________
> devel mailing list
> [email protected]
> http://www.open-fcoe.org/mailman/listinfo/devel

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to