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.
192 lines
5.4 KiB
192 lines
5.4 KiB
7 years ago
|
commit ea9c14d9ab10d1070a8d3c032e64bb946a279a02
|
||
|
Author: Chris Leech <cleech@redhat.com>
|
||
|
Date: Thu Nov 30 12:05:28 2017 -0800
|
||
|
|
||
|
vlan setting sync for be2iscsi
|
||
|
|
||
|
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
|
||
|
index b30518a293db..f269fc406a13 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,
|
||
|
@@ -2319,6 +2402,8 @@ static int exec_iface_op(int op, int do_show, int info_level,
|
||
|
struct host_info hinfo;
|
||
|
struct node_rec *rec = NULL;
|
||
|
int rc = 0;
|
||
|
+ LIST_HEAD(vlan_params);
|
||
|
+ struct iscsi_transport *t;
|
||
|
|
||
|
switch (op) {
|
||
|
case OP_NEW:
|
||
|
@@ -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);
|