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