Subject: zdev: qeth BridgePort and VNICC attribute conflict From: Hans Wippel Description: zdev: qeth BridgePort and VNICC attribute conflict Symptom: chzdev cannot set VNICC attributes due to a conflict with BridgePort attributes. Problem: Existing conflict checking always assumes a BridgePort and a VNICC attribute are active. Solution: Introduce a function that determines if BridgePort or VNICC attributes are active and use only active attributes for conflict checking. Reproduction: Set VNICC attribute with chzdev w/o active BridgePort attributes. Upstream-ID: df01c470c2a680a924ccdba3b6657af4669002b2 Problem-ID: 172409 Signed-off-by: Hans Wippel --- zdev/src/qeth.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) --- a/zdev/src/qeth.c +++ b/zdev/src/qeth.c @@ -1171,6 +1171,37 @@ static exit_code_t check_ineffective_set return rc; } +/* Check if a possibly conflicting setting is active in the configuration */ +static bool conflict_setting_active(struct setting *s) +{ + enum qeth_attr_group_type t; + + t = get_attr_group_type(s); + if (t != group_bridge && t != group_vnicc) { + /* Check BridgePort and VNICC attributes only */ + return false; + } + if (s->specified) { + /* Specified on the command line: We are strict here and do not + * allow to specify VNICC and BridgePort attributes in the same + * command to avoid issues when attributes are enabled/disabled + * in the wrong order. Example: disable VNICC and enable + * BridgePort in the same command would result in an error + * because BridgePort attributes are set first. + */ + return true; + } + if (attrib_match_default(s->attrib, s->value)) { + /* Not active if set to default value */ + return false; + } + if (s->actual_value && strncmp(s->actual_value, "n/a", 3) == 0) { + /* Not active if in n/a state (conflicting attribute set) */ + return false; + } + return true; +} + /* Check if there are conflicting attribute settings */ static exit_code_t check_conflicting_settings(struct setting_list *list) { @@ -1182,6 +1213,8 @@ static exit_code_t check_conflicting_set util_list_iterate(&list->list, s) { if (s->removed) continue; + if (!conflict_setting_active(s)) + continue; t = get_attr_group_type(s); if (t == group_bridge && (!bridge || !bridge->specified)) bridge = s;