You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.2 KiB
208 lines
6.2 KiB
From 2cee7f4a011619480c83d8279fe5d15de6e37ea8 Mon Sep 17 00:00:00 2001 |
|
From: Chris Leech <cleech@redhat.com> |
|
Date: Fri, 22 Jun 2018 12:25:05 -0700 |
|
Subject: [PATCH 1/1] vlan setting sync across ipv4/ipv6 for be2iscsi |
|
|
|
be2iscsi exports two ifaces per host port for ipv4 and ipv6 network |
|
configurations. But, they need to have the same link level configuration |
|
including vlan settings. If vlan setting are modified in only one iface |
|
record, then whichever record is applied last (filesystem dependant I |
|
think) will take effect and things may not work. |
|
|
|
This change to iscsiadm applies vlan updates to all records with |
|
matching MAC addresses if a flag is set on the transport. |
|
The new transport flag is only set for be2iscsi. |
|
--- |
|
usr/iscsiadm.c | 132 ++++++++++++++++++++++++++++++++++++++++++++------------ |
|
usr/transport.c | 1 + |
|
usr/transport.h | 3 ++ |
|
3 files changed, 108 insertions(+), 28 deletions(-) |
|
|
|
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c |
|
index 6245e89d46cb..9083132942e2 100644 |
|
--- a/usr/iscsiadm.c |
|
+++ b/usr/iscsiadm.c |
|
@@ -2311,6 +2311,89 @@ static int verify_iface_params(struct list_head *params, struct node_rec *rec) |
|
return 0; |
|
} |
|
|
|
+static int iface_param_update(struct iface_rec *iface, struct list_head *params) |
|
+{ |
|
+ struct node_rec *rec; |
|
+ int rc = 0; |
|
+ |
|
+ rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1); |
|
+ if (!rec) { |
|
+ rc = ISCSI_ERR_INVAL; |
|
+ goto update_fail; |
|
+ } |
|
+ |
|
+ if (iscsi_check_for_running_session(rec)) |
|
+ log_warning("Updating iface while iscsi sessions " |
|
+ "are using it. You must logout the running " |
|
+ "sessions then log back in for the " |
|
+ "new settings to take affect."); |
|
+ |
|
+ rc = verify_iface_params(params, rec); |
|
+ if (rc) |
|
+ goto update_fail; |
|
+ |
|
+ rc = iface_conf_update(params, &rec->iface); |
|
+ if (rc) |
|
+ goto update_fail; |
|
+ |
|
+ rc = __for_each_matched_rec(0, rec, params, idbm_node_set_param); |
|
+ if (rc == ISCSI_ERR_NO_OBJS_FOUND) |
|
+ rc = 0; |
|
+ else if (rc) |
|
+ goto update_fail; |
|
+ |
|
+ printf("%s updated.\n", iface->name); |
|
+ free(rec); |
|
+ return rc; |
|
+ |
|
+update_fail: |
|
+ log_error("Could not update iface %s: %s", |
|
+ iface->name, iscsi_err_to_str(rc)); |
|
+ free(rec); |
|
+ return rc; |
|
+} |
|
+ |
|
+struct iface_param_sync { |
|
+ struct iface_rec *primary; |
|
+ struct list_head *params; |
|
+ int count; |
|
+}; |
|
+ |
|
+static int update_sync_params(void *data, struct iface_rec *iface) |
|
+{ |
|
+ struct iface_param_sync *iface_params = data; |
|
+ struct iface_rec *primary = iface_params->primary; |
|
+ struct list_head *params = iface_params->params; |
|
+ |
|
+ if ((strcmp(primary->transport_name, iface->transport_name)) || |
|
+ (strcmp(primary->hwaddress, iface->hwaddress)) || |
|
+ (primary->iface_num != iface->iface_num)) |
|
+ return 0; |
|
+ |
|
+ return iface_param_update(iface, params); |
|
+} |
|
+ |
|
+static int split_vlan_params(struct list_head *params, struct list_head *vlan_params) |
|
+{ |
|
+ struct user_param *param, *tmp; |
|
+ |
|
+ list_for_each_entry_safe(param, tmp, params, list) { |
|
+ if (!strncmp(param->name, "iface.vlan", 10)) { |
|
+ list_move_tail(¶m->list, vlan_params); |
|
+ } |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
+static inline void list_splice_tail(struct list_head *list, struct list_head *head) |
|
+{ |
|
+ list->prev->next = head; |
|
+ list->next->prev = head->prev; |
|
+ head->prev->next = list->next; |
|
+ head->prev = list->prev; |
|
+ INIT_LIST_HEAD(list); |
|
+} |
|
+ |
|
/* TODO: merge iter helpers and clean them up, so we can use them here */ |
|
static int exec_iface_op(int op, int do_show, int info_level, |
|
struct iface_rec *iface, uint64_t host_no, |
|
@@ -2320,6 +2403,8 @@ static int exec_iface_op(int op, int do_show, int info_level, |
|
struct node_rec *rec = NULL; |
|
int rc = 0; |
|
|
|
+ LIST_HEAD(vlan_params); |
|
+ struct iscsi_transport *t; |
|
switch (op) { |
|
case OP_NEW: |
|
if (!iface) { |
|
@@ -2381,36 +2466,27 @@ delete_fail: |
|
rec = idbm_create_rec(NULL, -1, NULL, -1, iface, 1); |
|
if (!rec) { |
|
rc = ISCSI_ERR_INVAL; |
|
- goto update_fail; |
|
+ break; |
|
} |
|
- |
|
- if (iscsi_check_for_running_session(rec)) |
|
- log_warning("Updating iface while iscsi sessions " |
|
- "are using it. You must logout the running " |
|
- "sessions then log back in for the " |
|
- "new settings to take affect."); |
|
- |
|
- rc = verify_iface_params(params, rec); |
|
- if (rc) |
|
+ t = iscsi_sysfs_get_transport_by_name(rec->iface.transport_name); |
|
+ if (!t) { |
|
+ log_error("Cound not locate transport for iface %s", iface->name); |
|
+ rc = ISCSI_ERR_INVAL; |
|
break; |
|
- |
|
- /* pass rec's iface because it has the db values */ |
|
- rc = iface_conf_update(params, &rec->iface); |
|
- if (rc) |
|
- goto update_fail; |
|
- |
|
- rc = __for_each_matched_rec(0, rec, params, |
|
- idbm_node_set_param); |
|
- if (rc == ISCSI_ERR_NO_OBJS_FOUND) |
|
- rc = 0; |
|
- else if (rc) |
|
- goto update_fail; |
|
- |
|
- printf("%s updated.\n", iface->name); |
|
- break; |
|
-update_fail: |
|
- log_error("Could not update iface %s: %s", |
|
- iface->name, iscsi_err_to_str(rc)); |
|
+ } |
|
+ if (t->template->sync_vlan_settings) { |
|
+ /* sync shared vlan settings across ifaces */ |
|
+ int nr_found = 0; |
|
+ struct iface_param_sync sync_params = { |
|
+ .primary = &rec->iface, |
|
+ .params = &vlan_params, |
|
+ .count = 0, |
|
+ }; |
|
+ split_vlan_params(params, &vlan_params); |
|
+ iface_for_each_iface(&sync_params, 1, &nr_found, update_sync_params); |
|
+ } |
|
+ iface_param_update(&rec->iface, params); |
|
+ list_splice_tail(&vlan_params, params); |
|
break; |
|
case OP_APPLY: |
|
if (!iface) { |
|
diff --git a/usr/transport.c b/usr/transport.c |
|
index 3b7a00a2245e..35a8ccd4a400 100644 |
|
--- a/usr/transport.c |
|
+++ b/usr/transport.c |
|
@@ -91,6 +91,7 @@ struct iscsi_transport_template bnx2i = { |
|
struct iscsi_transport_template be2iscsi = { |
|
.name = "be2iscsi", |
|
.bind_ep_required = 1, |
|
+ .sync_vlan_settings = 1, |
|
.create_conn = be2iscsi_create_conn, |
|
.ep_connect = ktransport_ep_connect, |
|
.ep_poll = ktransport_ep_poll, |
|
diff --git a/usr/transport.h b/usr/transport.h |
|
index b67776b47288..07027564e46b 100644 |
|
--- a/usr/transport.h |
|
+++ b/usr/transport.h |
|
@@ -40,6 +40,9 @@ struct iscsi_transport_template { |
|
uint8_t use_boot_info; |
|
uint8_t bind_ep_required; |
|
uint8_t no_netdev; |
|
+ /* be2iscsi has a single host vlan setting, |
|
+ * but uses 2 ifaces for ipv4 and ipv6 settings; keep them in sync */ |
|
+ uint8_t sync_vlan_settings; |
|
int (*ep_connect) (struct iscsi_conn *conn, int non_blocking); |
|
int (*ep_poll) (struct iscsi_conn *conn, int timeout_ms); |
|
void (*ep_disconnect) (struct iscsi_conn *conn); |
|
-- |
|
2.14.4 |
|
|
|
|