From d0ff1fd2ec51dc33a19aa2e037b755213b07ee7a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 15:30:37 -0700 Subject: [PATCH 01/16] system-settings: add unmanaged spec for z/VM subchannels (rh #591533) --- src/system-settings/nm-system-config-interface.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/system-settings/nm-system-config-interface.h b/src/system-settings/nm-system-config-interface.h index c5bbaaa917..5d59cd3ceb 100644 --- a/src/system-settings/nm-system-config-interface.h +++ b/src/system-settings/nm-system-config-interface.h @@ -107,6 +107,12 @@ struct _NMSystemConfigInterface { * * Method: mac Data: device MAC address formatted with leading zeros and * lowercase letters, like 00:0a:0b:0c:0d:0e + * + * Method: zvm-subchannels Data: string of 3 z/VM subchannels separated by + * commas (,) that identify the device, + * like "0.0.09a0,0.0.09a1,0.0.09a2". The + * string may contain only the following + * characters: [a-fA-F0-9,.] */ GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config); From 9c45b52f38b22927ba6a2d79f0666350fa0b7d6b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 15:31:01 -0700 Subject: [PATCH 02/16] libnm-util: add wired setting property for z/VM subchannel (rh #591533) On s390 and z-Series, the hypervisor assigns the MAC address, so we need to use subchannels to uniquely identify the device instead of using the MAC address. --- libnm-util/libnm-util.ver | 1 + libnm-util/nm-setting-wired.c | 57 ++++++++++++++++++++++++++++++++++- libnm-util/nm-setting-wired.h | 18 ++++++----- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index ed1d8a484f..f3d4344ca6 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -289,6 +289,7 @@ global: nm_setting_wired_get_auto_negotiate; nm_setting_wired_get_mac_address; nm_setting_wired_get_mtu; + nm_setting_wired_get_zvm_subchannels; nm_setting_wireless_ap_security_compatible; nm_setting_wireless_error_get_type; nm_setting_wireless_error_quark; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 2f25243318..738302a378 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -29,6 +29,7 @@ #include "nm-param-spec-specialized.h" #include "nm-utils.h" #include "nm-utils-private.h" +#include "nm-dbus-glib-types.h" GQuark nm_setting_wired_error_quark (void) @@ -75,6 +76,7 @@ typedef struct { gboolean auto_negotiate; GByteArray *mac_address; guint32 mtu; + GPtrArray *zvm_subchannels; } NMSettingWiredPrivate; enum { @@ -85,6 +87,7 @@ enum { PROP_AUTO_NEGOTIATE, PROP_MAC_ADDRESS, PROP_MTU, + PROP_ZVM_SUBCHANNELS, LAST_PROP }; @@ -143,6 +146,14 @@ nm_setting_wired_get_mtu (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->mtu; } +const GPtrArray * +nm_setting_wired_get_zvm_subchannels (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->zvm_subchannels; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -174,6 +185,14 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->zvm_subchannels && priv->zvm_subchannels->len != 3) { + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_ZVM_SUBCHANNELS); + return FALSE; + } + return TRUE; } @@ -226,6 +245,13 @@ set_property (GObject *object, guint prop_id, case PROP_MTU: priv->mtu = g_value_get_uint (value); break; + case PROP_ZVM_SUBCHANNELS: + if (priv->zvm_subchannels) { + g_ptr_array_foreach (priv->zvm_subchannels, (GFunc) g_free, NULL); + g_ptr_array_free (priv->zvm_subchannels, TRUE); + } + priv->zvm_subchannels = g_value_dup_boxed (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -257,6 +283,9 @@ get_property (GObject *object, guint prop_id, case PROP_MTU: g_value_set_uint (value, nm_setting_wired_get_mtu (setting)); break; + case PROP_ZVM_SUBCHANNELS: + g_value_set_boxed (value, nm_setting_wired_get_zvm_subchannels (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -380,5 +409,31 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "multiple Ethernet frames.", 0, G_MAXUINT32, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); + + /** + * NMSettingWired:zvm-subchannels: + * + * Identifies specific subchannels that this network device uses for + * communcation with z/VM or s390 host. Like #NMSettingWired:mac-address + * for non-z/VM devices, this property can be used to ensure this connection + * only applies to the network device that uses these subchannels. The + * list should contain exactly 3 strings, and each string may only only be + * composed of hexadecimal characters and the period (.) character. + **/ + g_object_class_install_property + (object_class, PROP_ZVM_SUBCHANNELS, + _nm_param_spec_specialized (NM_SETTING_WIRED_ZVM_SUBCHANNELS, + "z/VM Subchannels", + "Identifies specific subchannels that this " + "network device uses for communcation with z/VM " + "or s390 host. Like the 'mac-address' property " + "for non-z/VM devices, this property can be used " + "to ensure this connection only applies to the " + "network device that uses these subchannels. The " + "list should contain exactly 3 strings, and each " + "string may only only be composed of hexadecimal " + "characters and the period (.) character.", + DBUS_TYPE_G_ARRAY_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index 44127347f2..9bb8877127 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -58,6 +58,7 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate" #define NM_SETTING_WIRED_MAC_ADDRESS "mac-address" #define NM_SETTING_WIRED_MTU "mtu" +#define NM_SETTING_WIRED_ZVM_SUBCHANNELS "zvm-subchannels" typedef struct { NMSetting parent; @@ -75,13 +76,14 @@ typedef struct { GType nm_setting_wired_get_type (void); -NMSetting *nm_setting_wired_new (void); -const char *nm_setting_wired_get_port (NMSettingWired *setting); -guint32 nm_setting_wired_get_speed (NMSettingWired *setting); -const char *nm_setting_wired_get_duplex (NMSettingWired *setting); -gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting); -const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); -guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); +NMSetting * nm_setting_wired_new (void); +const char * nm_setting_wired_get_port (NMSettingWired *setting); +guint32 nm_setting_wired_get_speed (NMSettingWired *setting); +const char * nm_setting_wired_get_duplex (NMSettingWired *setting); +gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting); +const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); +guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); +const GPtrArray * nm_setting_wired_get_zvm_subchannels (NMSettingWired *setting); G_END_DECLS From 5f03706a6b1ad3db3b9bce5852b1ed885039d719 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 16:28:51 -0700 Subject: [PATCH 03/16] ethernet: handle zvm-subchannels unmanaged spec (rh #591533) --- src/NetworkManagerUtils.c | 96 +++++++++++++++++++++++++++++++++++++++ src/NetworkManagerUtils.h | 3 +- src/nm-device-ethernet.c | 5 ++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 22cf2fa0d8..86f66f76d2 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "NetworkManagerUtils.h" #include "nm-utils.h" @@ -487,6 +488,101 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) return FALSE; } +#define BUFSIZE 10 + +static gboolean +parse_subchannels (const char *subchannels, guint32 *a, guint32 *b, guint32 *c) +{ + long unsigned int tmp; + char buf[BUFSIZE + 1]; + const char *p = subchannels; + int i = 0; + char *pa = NULL, *pb = NULL, *pc = NULL; + + g_return_val_if_fail (subchannels != NULL, FALSE); + g_return_val_if_fail (a != NULL, FALSE); + g_return_val_if_fail (*a == 0, FALSE); + g_return_val_if_fail (b != NULL, FALSE); + g_return_val_if_fail (*b == 0, FALSE); + g_return_val_if_fail (c != NULL, FALSE); + g_return_val_if_fail (*c == 0, FALSE); + + /* sanity check */ + if (!isxdigit (subchannels[0])) + return FALSE; + + /* Get the first channel */ + while (*p && (*p != ',')) { + if (!isxdigit (*p) && (*p != '.')) + return FALSE; /* Invalid chars */ + if (i >= BUFSIZE) + return FALSE; /* Too long to be a subchannel */ + buf[i++] = *p++; + } + buf[i] = '\0'; + + /* and grab each of its elements, there should be 3 */ + pa = &buf[0]; + pb = strchr (buf, '.'); + if (pb) + pc = strchr (pb + 1, '.'); + if (!pa || !pb || !pc) + return FALSE; + + /* Split the string */ + *pb++ = '\0'; + *pc++ = '\0'; + + errno = 0; + tmp = strtoul (pa, NULL, 16); + if (errno) + return FALSE; + *a = (guint32) tmp; + + errno = 0; + tmp = strtoul (pb, NULL, 16); + if (errno) + return FALSE; + *b = (guint32) tmp; + + errno = 0; + tmp = strtoul (pc, NULL, 16); + if (errno) + return FALSE; + *c = (guint32) tmp; + + return TRUE; +} + +#define SUBCHAN_TAG "zvm-subchannels:" + +gboolean +nm_match_spec_zvm_subchannels (const GSList *specs, const char *subchannels) +{ + const GSList *iter; + guint32 a = 0, b = 0, c = 0; + guint32 spec_a = 0, spec_b = 0, spec_c = 0; + + g_return_val_if_fail (subchannels != NULL, FALSE); + + if (!parse_subchannels (subchannels, &a, &b, &c)) + return FALSE; + + for (iter = specs; iter; iter = g_slist_next (iter)) { + const char *spec = iter->data; + + if (!strncmp (spec, SUBCHAN_TAG, strlen (SUBCHAN_TAG))) { + spec += strlen (SUBCHAN_TAG); + if (parse_subchannels (spec, &spec_a, &spec_b, &spec_c)) { + if (a == spec_a && b == spec_b && c == spec_c) + return TRUE; + } + } + } + + return FALSE; +} + /*********************************/ static void diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index e3d1793b4d..93a11c31cb 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2008 Red Hat, Inc. + * Copyright (C) 2004 - 2010 Red Hat, Inc. * Copyright (C) 2005 - 2008 Novell, Inc. */ @@ -48,6 +48,7 @@ void nm_utils_call_dispatcher (const char *action, const char *vpn_iface); gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr); +gboolean nm_match_spec_zvm_subchannels (const GSList *specs, const char *subchannels); GHashTable *value_hash_create (void); diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index be6d4e2f3c..5af9ec5f50 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -105,6 +105,7 @@ typedef struct { gboolean disposed; struct ether_addr hw_addr; + char * zvm_subchannels; gboolean carrier; NMNetlinkMonitor * monitor; @@ -1519,6 +1520,7 @@ real_check_connection_compatible (NMDevice *device, static gboolean spec_match_list (NMDevice *device, const GSList *specs) { + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); struct ether_addr ether; char *hwaddr; gboolean matched; @@ -1528,6 +1530,9 @@ spec_match_list (NMDevice *device, const GSList *specs) matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); + if (!matched && priv->zvm_subchannels) + matched = nm_match_spec_zvm_subchannels (specs, priv->zvm_subchannels); + return matched; } From 04370354f0708c7c3355f4091bbc38d1386a0de8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 17:04:32 -0700 Subject: [PATCH 04/16] libnm-util: pretty-print DBUS_TYPE_G_ARRAY_OF_STRING --- libnm-util/nm-utils.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index ddb02a220e..b8d2bc33ea 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -593,6 +593,32 @@ nm_utils_convert_strv_to_string (const GValue *src_value, GValue *dest_value) g_string_free (printable, FALSE); } +static void +nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GPtrArray *strings; + GString *printable; + int i; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_STRING)); + + strings = (GPtrArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + for (i = 0; strings && i < strings->len; i++) { + if (i > 0) + g_string_append (printable, ", '"); + else + g_string_append_c (printable, '\''); + g_string_append (printable, g_ptr_array_index (strings, i)); + g_string_append_c (printable, '\''); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + static void nm_utils_convert_uint_array_to_string (const GValue *src_value, GValue *dest_value) { @@ -1058,6 +1084,9 @@ _nm_utils_register_value_transformations (void) g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING, G_TYPE_STRING, nm_utils_convert_strv_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_STRING, + G_TYPE_STRING, + nm_utils_convert_string_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_UINT_ARRAY, G_TYPE_STRING, nm_utils_convert_uint_array_to_string); From 860e8a13eb59874a8171faa766baefd9c1580a65 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 17:27:37 -0700 Subject: [PATCH 05/16] system-settings: some s390 device types only use 2 channels --- src/system-settings/nm-system-config-interface.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/system-settings/nm-system-config-interface.h b/src/system-settings/nm-system-config-interface.h index 5d59cd3ceb..2cbe2095ff 100644 --- a/src/system-settings/nm-system-config-interface.h +++ b/src/system-settings/nm-system-config-interface.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ @@ -108,10 +108,10 @@ struct _NMSystemConfigInterface { * Method: mac Data: device MAC address formatted with leading zeros and * lowercase letters, like 00:0a:0b:0c:0d:0e * - * Method: zvm-subchannels Data: string of 3 z/VM subchannels separated by - * commas (,) that identify the device, - * like "0.0.09a0,0.0.09a1,0.0.09a2". The - * string may contain only the following + * Method: zvm-subchannels Data: string of 2 or 3 z/VM subchannels + * separated by commas (,) that identify the + * device, like "0.0.09a0,0.0.09a1,0.0.09a2". + * The string may contain only the following * characters: [a-fA-F0-9,.] */ GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config); From e22346b9d095783975b10cb18d78277fe3aae81e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 17:35:57 -0700 Subject: [PATCH 06/16] ifcfg-rh: handle z/VM subchannels (rh #591533) --- system-settings/plugins/ifcfg-rh/reader.c | 58 +++- .../tests/network-scripts/Makefile.am | 3 +- .../ifcfg-test-wired-qeth-static | 10 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 256 ++++++++++++++++++ system-settings/plugins/ifcfg-rh/writer.c | 19 ++ 5 files changed, 339 insertions(+), 7 deletions(-) create mode 100644 system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index a084d30b16..5ff70c7c84 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -2951,15 +2951,61 @@ make_wired_setting (shvarFile *ifcfg, } g_byte_array_free (mac, TRUE); - } else if (!nm_controlled) { - /* If NM_CONTROLLED=no but there wasn't a MAC address, notify - * the user that the device cannot be unmanaged. - */ - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR was missing; device will be managed"); } } else { g_object_unref (s_wired); - s_wired = NULL; + return NULL; + } + + value = svGetValue (ifcfg, "SUBCHANNELS", FALSE); + if (value) { + const char *p = value; + gboolean success = TRUE; + char **chans = NULL; + + /* basic sanity checks */ + while (*p) { + if (!isxdigit (*p) && (*p != ',') && (*p != '.')) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid SUBCHANNELS '%s'", value); + success = FALSE; + break; + } + p++; + } + + if (success) { + guint32 num_chans; + + chans = g_strsplit_set (value, ",", 0); + num_chans = g_strv_length (chans); + if (num_chans < 2 || num_chans > 3) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid SUBCHANNELS '%s' (%d channels, 2 or 3 expected)", + value, g_strv_length (chans)); + } else { + GPtrArray *array = g_ptr_array_sized_new (num_chans); + + g_ptr_array_add (array, chans[0]); + g_ptr_array_add (array, chans[1]); + if (num_chans == 3) + g_ptr_array_add (array, chans[2]); + + g_object_set (s_wired, NM_SETTING_WIRED_ZVM_SUBCHANNELS, array, NULL); + g_ptr_array_free (array, TRUE); + + /* set the unmanaged spec too */ + if (!nm_controlled && !*unmanaged) + *unmanaged = g_strdup_printf ("zvm-subchannels:%s", value); + } + g_strfreev (chans); + } + g_free (value); + } + + if (!nm_controlled && !*unmanaged) { + /* If NM_CONTROLLED=no but there wasn't a MAC address or z/VM + * subchannels, notify the user that the device cannot be unmanaged. + */ + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR or SUBCHANNELS was missing; device will be managed"); } value = svGetValue (ifcfg, "KEY_MGMT", FALSE); diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 66435acbcb..8a93c9deea 100644 --- a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -60,7 +60,8 @@ EXTRA_DIST = \ ifcfg-test-wired-static-no-prefix-24 \ ifcfg-test-wired-ipv6-only \ ifcfg-test-wifi-wep-passphrase \ - keys-test-wifi-wep-passphrase + keys-test-wifi-wep-passphrase \ + ifcfg-test-wired-qeth-static check-local: @for f in $(EXTRA_DIST); do \ diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static new file mode 100644 index 0000000000..b0ec2a9a56 --- /dev/null +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static @@ -0,0 +1,10 @@ +# IBM QETH +DEVICE=eth1 +BOOTPROTO=static +IPADDR=192.168.70.87 +NETMASK=255.255.255.0 +ONBOOT=yes +NETTYPE=qeth +SUBCHANNELS=0.0.0600,0.0.0601,0.0.0602 +TYPE=Ethernet + diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 35cea36cf5..b4aa60a86e 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5080,6 +5080,132 @@ test_read_wifi_wep_eap_ttls_chap (void) g_object_unref (connection); } +#define TEST_IFCFG_WIRED_QETH_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-qeth-static" + +static void +test_read_wired_qeth_static (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System test-wired-qeth-static"; + const GByteArray *array; + const char *expected_channel0 = "0.0.0600"; + const char *expected_channel1 = "0.0.0601"; + const char *expected_channel2 = "0.0.0602"; + const GPtrArray *subchannels; + + connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wired-qeth-static-read", "failed to read %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wired-qeth-static-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message); + + ASSERT (unmanaged == FALSE, + "wired-qeth-static-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_QETH_STATIC); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wired-qeth-static-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wired-qeth-static-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* ===== WIRED SETTING ===== */ + + s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED)); + ASSERT (s_wired != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + ASSERT (array == NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + + /* Subchannels */ + subchannels = nm_setting_wired_get_zvm_subchannels (s_wired); + ASSERT (subchannels != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_ZVM_SUBCHANNELS); + ASSERT (subchannels->len == 3, + "wired-qeth-static-verify-wired", "failed to verify %s: invalid %s / %s key (not 3 elements)", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_ZVM_SUBCHANNELS); + + tmp = (const char *) g_ptr_array_index (subchannels, 0); + ASSERT (strcmp (tmp, expected_channel0) == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #0", + TEST_IFCFG_WIRED_QETH_STATIC); + + tmp = (const char *) g_ptr_array_index (subchannels, 1); + ASSERT (strcmp (tmp, expected_channel1) == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #1", + TEST_IFCFG_WIRED_QETH_STATIC); + + tmp = (const char *) g_ptr_array_index (subchannels, 2); + ASSERT (strcmp (tmp, expected_channel2) == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #2", + TEST_IFCFG_WIRED_QETH_STATIC); + + /* ===== IPv4 SETTING ===== */ + + s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); + ASSERT (s_ip4 != NULL, + "wired-qeth-static-verify-ip4", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* Method */ + tmp = nm_setting_ip4_config_get_method (s_ip4); + ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, + "wired-qeth-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_METHOD); + + g_object_unref (connection); +} + static void test_write_wired_static (void) { @@ -8128,6 +8254,134 @@ test_read_ibft_malformed (const char *name, const char *iscsiadm_path) name, "unexpectedly able to read %s", TEST_IFCFG_IBFT_STATIC); } +static void +test_write_wired_qeth_dhcp (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + GPtrArray *subchans; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "wired-qeth-dhcp-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired qeth Static", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + subchans = g_ptr_array_sized_new (3); + g_ptr_array_add (subchans, "0.0.600"); + g_ptr_array_add (subchans, "0.0.601"); + g_ptr_array_add (subchans, "0.0.602"); + g_object_set (s_wired, + NM_SETTING_WIRED_ZVM_SUBCHANNELS, subchans, + NULL); + g_ptr_array_free (subchans, TRUE); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + /* Verify */ + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "wired-qeth-dhcp-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "wired-qeth-dhcp-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "wired-qeth-dhcp-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "wired-qeth-dhcp-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "wired-qeth-dhcp-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "wired-qeth-dhcp-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + static void test_write_wired_pppoe (void) { @@ -8450,6 +8704,7 @@ int main (int argc, char **argv) test_read_wifi_wpa_eap_tls (); test_read_wifi_wpa_eap_ttls_tls (); test_read_wifi_wep_eap_ttls_chap (); + test_read_wired_qeth_static (); test_write_wired_static (); test_write_wired_static_ip6_only (); @@ -8497,6 +8752,7 @@ int main (int argc, char **argv) test_write_wifi_wpa_eap_tls (); test_write_wifi_wpa_eap_ttls_tls (); test_write_wifi_wpa_eap_ttls_mschapv2 (); + test_write_wired_qeth_dhcp (); /* iSCSI / ibft */ test_read_ibft_dhcp (); diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index de69e0039e..04dac8ec4f 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -816,6 +816,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) const GByteArray *mac; char *tmp; guint32 mtu; + const GPtrArray *zvm_subchannels; s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); if (!s_wired) { @@ -824,6 +825,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return FALSE; } + svSetValue (ifcfg, "HWADDR", NULL, FALSE); mac = nm_setting_wired_get_mac_address (s_wired); if (mac) { tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", @@ -841,6 +843,23 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) g_free (tmp); } + svSetValue (ifcfg, "SUBCHANNELS", NULL, FALSE); + zvm_subchannels = nm_setting_wired_get_zvm_subchannels (s_wired); + if (zvm_subchannels) { + if (zvm_subchannels->len == 2) { + tmp = g_strdup_printf ("%s,%s", + (const char *) g_ptr_array_index (zvm_subchannels, 0), + (const char *) g_ptr_array_index (zvm_subchannels, 1)); + } else if (zvm_subchannels->len == 3) { + tmp = g_strdup_printf ("%s,%s,%s", + (const char *) g_ptr_array_index (zvm_subchannels, 0), + (const char *) g_ptr_array_index (zvm_subchannels, 1), + (const char *) g_ptr_array_index (zvm_subchannels, 2)); + } + svSetValue (ifcfg, "SUBCHANNELS", tmp, FALSE); + g_free (tmp); + } + svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE); return TRUE; From 0b41797b49ae46e1b61d1c94f6706cfa497cdfba Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 17 Jun 2010 21:24:14 -0700 Subject: [PATCH 07/16] s390: replace 'zvm' with s390 ZVM isn't the right terminology here. s390 is. --- libnm-util/libnm-util.ver | 2 +- libnm-util/nm-setting-wired.c | 32 +++++++++---------- libnm-util/nm-setting-wired.h | 18 +++++------ src/NetworkManagerUtils.c | 4 +-- src/NetworkManagerUtils.h | 2 +- src/nm-device-ethernet.c | 6 ++-- .../nm-system-config-interface.h | 10 +++--- system-settings/plugins/ifcfg-rh/reader.c | 4 +-- .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 8 ++--- system-settings/plugins/ifcfg-rh/writer.c | 20 ++++++------ 10 files changed, 53 insertions(+), 53 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index e630b00ec8..508ac6de4e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -289,7 +289,7 @@ global: nm_setting_wired_get_auto_negotiate; nm_setting_wired_get_mac_address; nm_setting_wired_get_mtu; - nm_setting_wired_get_zvm_subchannels; + nm_setting_wired_get_s390_subchannels; nm_setting_wireless_ap_security_compatible; nm_setting_wireless_error_get_type; nm_setting_wireless_error_quark; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 738302a378..8d562cd59d 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -76,7 +76,7 @@ typedef struct { gboolean auto_negotiate; GByteArray *mac_address; guint32 mtu; - GPtrArray *zvm_subchannels; + GPtrArray *s390_subchannels; } NMSettingWiredPrivate; enum { @@ -87,7 +87,7 @@ enum { PROP_AUTO_NEGOTIATE, PROP_MAC_ADDRESS, PROP_MTU, - PROP_ZVM_SUBCHANNELS, + PROP_S390_SUBCHANNELS, LAST_PROP }; @@ -147,11 +147,11 @@ nm_setting_wired_get_mtu (NMSettingWired *setting) } const GPtrArray * -nm_setting_wired_get_zvm_subchannels (NMSettingWired *setting) +nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) { g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); - return NM_SETTING_WIRED_GET_PRIVATE (setting)->zvm_subchannels; + return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_subchannels; } static gboolean @@ -185,11 +185,11 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (priv->zvm_subchannels && priv->zvm_subchannels->len != 3) { + if (priv->s390_subchannels && priv->s390_subchannels->len != 3) { g_set_error (error, NM_SETTING_WIRED_ERROR, NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_ZVM_SUBCHANNELS); + NM_SETTING_WIRED_S390_SUBCHANNELS); return FALSE; } @@ -245,12 +245,12 @@ set_property (GObject *object, guint prop_id, case PROP_MTU: priv->mtu = g_value_get_uint (value); break; - case PROP_ZVM_SUBCHANNELS: - if (priv->zvm_subchannels) { - g_ptr_array_foreach (priv->zvm_subchannels, (GFunc) g_free, NULL); - g_ptr_array_free (priv->zvm_subchannels, TRUE); + case PROP_S390_SUBCHANNELS: + if (priv->s390_subchannels) { + g_ptr_array_foreach (priv->s390_subchannels, (GFunc) g_free, NULL); + g_ptr_array_free (priv->s390_subchannels, TRUE); } - priv->zvm_subchannels = g_value_dup_boxed (value); + priv->s390_subchannels = g_value_dup_boxed (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -283,8 +283,8 @@ get_property (GObject *object, guint prop_id, case PROP_MTU: g_value_set_uint (value, nm_setting_wired_get_mtu (setting)); break; - case PROP_ZVM_SUBCHANNELS: - g_value_set_boxed (value, nm_setting_wired_get_zvm_subchannels (setting)); + case PROP_S390_SUBCHANNELS: + g_value_set_boxed (value, nm_setting_wired_get_s390_subchannels (setting)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -411,7 +411,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); /** - * NMSettingWired:zvm-subchannels: + * NMSettingWired:s390-subchannels: * * Identifies specific subchannels that this network device uses for * communcation with z/VM or s390 host. Like #NMSettingWired:mac-address @@ -421,8 +421,8 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) * composed of hexadecimal characters and the period (.) character. **/ g_object_class_install_property - (object_class, PROP_ZVM_SUBCHANNELS, - _nm_param_spec_specialized (NM_SETTING_WIRED_ZVM_SUBCHANNELS, + (object_class, PROP_S390_SUBCHANNELS, + _nm_param_spec_specialized (NM_SETTING_WIRED_S390_SUBCHANNELS, "z/VM Subchannels", "Identifies specific subchannels that this " "network device uses for communcation with z/VM " diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index 9bb8877127..ee2c4da1a0 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -58,7 +58,7 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate" #define NM_SETTING_WIRED_MAC_ADDRESS "mac-address" #define NM_SETTING_WIRED_MTU "mtu" -#define NM_SETTING_WIRED_ZVM_SUBCHANNELS "zvm-subchannels" +#define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" typedef struct { NMSetting parent; @@ -76,14 +76,14 @@ typedef struct { GType nm_setting_wired_get_type (void); -NMSetting * nm_setting_wired_new (void); -const char * nm_setting_wired_get_port (NMSettingWired *setting); -guint32 nm_setting_wired_get_speed (NMSettingWired *setting); -const char * nm_setting_wired_get_duplex (NMSettingWired *setting); -gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting); -const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); -guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); -const GPtrArray * nm_setting_wired_get_zvm_subchannels (NMSettingWired *setting); +NMSetting * nm_setting_wired_new (void); +const char * nm_setting_wired_get_port (NMSettingWired *setting); +guint32 nm_setting_wired_get_speed (NMSettingWired *setting); +const char * nm_setting_wired_get_duplex (NMSettingWired *setting); +gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting); +const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); +guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); +const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting); G_END_DECLS diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 86f66f76d2..10240960b0 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -554,10 +554,10 @@ parse_subchannels (const char *subchannels, guint32 *a, guint32 *b, guint32 *c) return TRUE; } -#define SUBCHAN_TAG "zvm-subchannels:" +#define SUBCHAN_TAG "s390-subchannels:" gboolean -nm_match_spec_zvm_subchannels (const GSList *specs, const char *subchannels) +nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels) { const GSList *iter; guint32 a = 0, b = 0, c = 0; diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 93a11c31cb..72c0e532b8 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -48,7 +48,7 @@ void nm_utils_call_dispatcher (const char *action, const char *vpn_iface); gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr); -gboolean nm_match_spec_zvm_subchannels (const GSList *specs, const char *subchannels); +gboolean nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels); GHashTable *value_hash_create (void); diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index ce79664a8e..05d79de052 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -105,7 +105,7 @@ typedef struct { gboolean disposed; struct ether_addr hw_addr; - char * zvm_subchannels; + char * s390_subchannels; gboolean carrier; NMNetlinkMonitor * monitor; @@ -1528,8 +1528,8 @@ spec_match_list (NMDevice *device, const GSList *specs) matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); - if (!matched && priv->zvm_subchannels) - matched = nm_match_spec_zvm_subchannels (specs, priv->zvm_subchannels); + if (!matched && priv->s390_subchannels) + matched = nm_match_spec_s390_subchannels (specs, priv->s390_subchannels); return matched; } diff --git a/src/system-settings/nm-system-config-interface.h b/src/system-settings/nm-system-config-interface.h index 2cbe2095ff..3daceb89bd 100644 --- a/src/system-settings/nm-system-config-interface.h +++ b/src/system-settings/nm-system-config-interface.h @@ -108,11 +108,11 @@ struct _NMSystemConfigInterface { * Method: mac Data: device MAC address formatted with leading zeros and * lowercase letters, like 00:0a:0b:0c:0d:0e * - * Method: zvm-subchannels Data: string of 2 or 3 z/VM subchannels - * separated by commas (,) that identify the - * device, like "0.0.09a0,0.0.09a1,0.0.09a2". - * The string may contain only the following - * characters: [a-fA-F0-9,.] + * Method: s390-subchannels Data: string of 2 or 3 s390 subchannels + * separated by commas (,) that identify the + * device, like "0.0.09a0,0.0.09a1,0.0.09a2". + * The string may contain only the following + * characters: [a-fA-F0-9,.] */ GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config); diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index edccd1efbd..2bac57940c 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -2995,12 +2995,12 @@ make_wired_setting (shvarFile *ifcfg, if (num_chans == 3) g_ptr_array_add (array, chans[2]); - g_object_set (s_wired, NM_SETTING_WIRED_ZVM_SUBCHANNELS, array, NULL); + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, array, NULL); g_ptr_array_free (array, TRUE); /* set the unmanaged spec too */ if (!nm_controlled && !*unmanaged) - *unmanaged = g_strdup_printf ("zvm-subchannels:%s", value); + *unmanaged = g_strdup_printf ("s390-subchannels:%s", value); } g_strfreev (chans); } diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index b4aa60a86e..a97effbf88 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5160,17 +5160,17 @@ test_read_wired_qeth_static (void) NM_SETTING_WIRED_MAC_ADDRESS); /* Subchannels */ - subchannels = nm_setting_wired_get_zvm_subchannels (s_wired); + subchannels = nm_setting_wired_get_s390_subchannels (s_wired); ASSERT (subchannels != NULL, "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIRED_QETH_STATIC, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_ZVM_SUBCHANNELS); + NM_SETTING_WIRED_S390_SUBCHANNELS); ASSERT (subchannels->len == 3, "wired-qeth-static-verify-wired", "failed to verify %s: invalid %s / %s key (not 3 elements)", TEST_IFCFG_WIRED_QETH_STATIC, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_ZVM_SUBCHANNELS); + NM_SETTING_WIRED_S390_SUBCHANNELS); tmp = (const char *) g_ptr_array_index (subchannels, 0); ASSERT (strcmp (tmp, expected_channel0) == 0, @@ -8306,7 +8306,7 @@ test_write_wired_qeth_dhcp (void) g_ptr_array_add (subchans, "0.0.601"); g_ptr_array_add (subchans, "0.0.602"); g_object_set (s_wired, - NM_SETTING_WIRED_ZVM_SUBCHANNELS, subchans, + NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, NULL); g_ptr_array_free (subchans, TRUE); diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index a9caf90a1e..a27c49961e 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -826,7 +826,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) const GByteArray *mac; char *tmp; guint32 mtu; - const GPtrArray *zvm_subchannels; + const GPtrArray *s390_subchannels; s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); if (!s_wired) { @@ -854,17 +854,17 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) } svSetValue (ifcfg, "SUBCHANNELS", NULL, FALSE); - zvm_subchannels = nm_setting_wired_get_zvm_subchannels (s_wired); - if (zvm_subchannels) { - if (zvm_subchannels->len == 2) { + s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); + if (s390_subchannels) { + if (s390_subchannels->len == 2) { tmp = g_strdup_printf ("%s,%s", - (const char *) g_ptr_array_index (zvm_subchannels, 0), - (const char *) g_ptr_array_index (zvm_subchannels, 1)); - } else if (zvm_subchannels->len == 3) { + (const char *) g_ptr_array_index (s390_subchannels, 0), + (const char *) g_ptr_array_index (s390_subchannels, 1)); + } else if (s390_subchannels->len == 3) { tmp = g_strdup_printf ("%s,%s,%s", - (const char *) g_ptr_array_index (zvm_subchannels, 0), - (const char *) g_ptr_array_index (zvm_subchannels, 1), - (const char *) g_ptr_array_index (zvm_subchannels, 2)); + (const char *) g_ptr_array_index (s390_subchannels, 0), + (const char *) g_ptr_array_index (s390_subchannels, 1), + (const char *) g_ptr_array_index (s390_subchannels, 2)); } svSetValue (ifcfg, "SUBCHANNELS", tmp, FALSE); g_free (tmp); From 66319f616caa9c716d3226832f45435f689b9911 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 24 Jun 2010 11:59:40 -0700 Subject: [PATCH 08/16] libnm-util: add more necessary s390 properties --- libnm-util/libnm-util.ver | 4 + libnm-util/nm-setting-wired.c | 147 ++++++++++++++++++++++++++++++++++ libnm-util/nm-setting-wired.h | 8 ++ 3 files changed, 159 insertions(+) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 508ac6de4e..000542ca8d 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -290,6 +290,10 @@ global: nm_setting_wired_get_mac_address; nm_setting_wired_get_mtu; nm_setting_wired_get_s390_subchannels; + nm_setting_wired_get_s390_port_name; + nm_setting_wired_get_s390_port_number; + nm_setting_wired_get_s390_qeth_layer; + nm_setting_wired_get_s390_nettype; nm_setting_wireless_ap_security_compatible; nm_setting_wireless_error_get_type; nm_setting_wireless_error_quark; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 8d562cd59d..4b163199a3 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -23,6 +23,7 @@ * (C) Copyright 2007 - 2008 Novell, Inc. */ +#include #include #include #include "nm-setting-wired.h" @@ -77,6 +78,10 @@ typedef struct { GByteArray *mac_address; guint32 mtu; GPtrArray *s390_subchannels; + char *s390_port_name; + guint32 s390_port_number; + guint32 s390_qeth_layer; + char *s390_nettype; } NMSettingWiredPrivate; enum { @@ -88,6 +93,10 @@ enum { PROP_MAC_ADDRESS, PROP_MTU, PROP_S390_SUBCHANNELS, + PROP_S390_PORT_NAME, + PROP_S390_PORT_NUMBER, + PROP_S390_QETH_LAYER, + PROP_S390_NETTYPE, LAST_PROP }; @@ -154,6 +163,38 @@ nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_subchannels; } +const char * +nm_setting_wired_get_s390_port_name (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_port_name; +} + +guint32 +nm_setting_wired_get_s390_port_number (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_port_number; +} + +guint32 +nm_setting_wired_get_s390_qeth_layer (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 2); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_qeth_layer; +} + +const char * +nm_setting_wired_get_s390_nettype (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_nettype; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -193,6 +234,26 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->s390_nettype) { + if ( strcmp (priv->s390_nettype, "qeth") + && strcmp (priv->s390_nettype, "lcs") + && strcmp (priv->s390_nettype, "ctc")) { + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_S390_NETTYPE); + return FALSE; + } + } + + if (priv->s390_port_name && strlen (priv->s390_port_name) > 8) { + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_S390_PORT_NAME); + return FALSE; + } + return TRUE; } @@ -209,6 +270,8 @@ finalize (GObject *object) g_free (priv->port); g_free (priv->duplex); + g_free (priv->s390_port_name); + g_free (priv->s390_nettype); if (priv->mac_address) g_byte_array_free (priv->mac_address, TRUE); @@ -252,6 +315,20 @@ set_property (GObject *object, guint prop_id, } priv->s390_subchannels = g_value_dup_boxed (value); break; + case PROP_S390_PORT_NAME: + g_free (priv->s390_port_name); + priv->s390_port_name = g_value_dup_string (value); + break; + case PROP_S390_PORT_NUMBER: + priv->s390_port_number = g_value_get_uint (value); + break; + case PROP_S390_QETH_LAYER: + priv->s390_qeth_layer = g_value_get_uint (value); + break; + case PROP_S390_NETTYPE: + g_free (priv->s390_nettype); + priv->s390_nettype = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -286,6 +363,18 @@ get_property (GObject *object, guint prop_id, case PROP_S390_SUBCHANNELS: g_value_set_boxed (value, nm_setting_wired_get_s390_subchannels (setting)); break; + case PROP_S390_PORT_NAME: + g_value_set_string (value, nm_setting_wired_get_s390_port_name (setting)); + break; + case PROP_S390_PORT_NUMBER: + g_value_set_uint (value, nm_setting_wired_get_s390_port_number (setting)); + break; + case PROP_S390_QETH_LAYER: + g_value_set_uint (value, nm_setting_wired_get_s390_qeth_layer (setting)); + break; + case PROP_S390_NETTYPE: + g_value_set_string (value, nm_setting_wired_get_s390_nettype (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -435,5 +524,63 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "characters and the period (.) character.", DBUS_TYPE_G_ARRAY_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:s390-port-name: + * + * s390 device port name, if required by your configuration. + **/ + g_object_class_install_property + (object_class, PROP_S390_PORT_NAME, + g_param_spec_string (NM_SETTING_WIRED_S390_PORT_NAME, + "s390 Port Name", + "s390 device port name, if required by your configuration.", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:s390-port-number: + * + * s390 device port number, if required by your configuration. For 'qeth' + * devices, this is the "relative port number". + **/ + g_object_class_install_property + (object_class, PROP_S390_PORT_NUMBER, + g_param_spec_uint (NM_SETTING_WIRED_S390_PORT_NUMBER, + "s390 Port Number", + "s390 device port number, if required by your " + "configuration. For 'qeth' devices, this is the " + "'relative port number'.", + 0, 100, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:s390-qeth-layer: + * + * s390 'qeth' device layer, either '2' or '3'. + **/ + g_object_class_install_property + (object_class, PROP_S390_QETH_LAYER, + g_param_spec_uint (NM_SETTING_WIRED_S390_QETH_LAYER, + "s390 'qeth' layer", + "s390 'qeth' device layer, either '2' or '3'.", + 2, 3, 2, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:s390-nettype: + * + * s390 network device type; one of 'qeth', 'lcs', or 'ctc', representing + * the different types of virtual network devices available on s390 systems. + **/ + g_object_class_install_property + (object_class, PROP_S390_NETTYPE, + g_param_spec_string (NM_SETTING_WIRED_S390_NETTYPE, + "s390 Net Type", + "s390 network device type; one of 'qeth', 'lcs', or " + "'ctc', representing the different types of virtual " + "network devices available on s390 systems.", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index ee2c4da1a0..3efb8d48d3 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -59,6 +59,10 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_MAC_ADDRESS "mac-address" #define NM_SETTING_WIRED_MTU "mtu" #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" +#define NM_SETTING_WIRED_S390_PORT_NAME "s390-port-name" +#define NM_SETTING_WIRED_S390_PORT_NUMBER "s390-port-number" +#define NM_SETTING_WIRED_S390_QETH_LAYER "s390-qeth-layer" +#define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" typedef struct { NMSetting parent; @@ -84,6 +88,10 @@ gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting); +const char * nm_setting_wired_get_s390_port_name (NMSettingWired *setting); +guint32 nm_setting_wired_get_s390_port_number (NMSettingWired *setting); +guint32 nm_setting_wired_get_s390_qeth_layer (NMSettingWired *setting); +const char * nm_setting_wired_get_s390_nettype (NMSettingWired *setting); G_END_DECLS From 3f089fe41d779313dee4e91a6b48f3269f4d81b6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 25 Jun 2010 19:49:39 -0700 Subject: [PATCH 09/16] core: grab s390 subchannels when available --- src/nm-device-ethernet.c | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 05d79de052..c888f9c6af 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -34,6 +34,9 @@ #include #include +#define G_UDEV_API_IS_SUBJECT_TO_CHANGE +#include + #include #include "nm-glib-compat.h" @@ -116,6 +119,11 @@ typedef struct { Supplicant supplicant; guint supplicant_timeout_id; + /* s390 */ + char * subchan1; + char * subchan2; + char * subchan3; + /* PPPoE */ NMPPPManager *ppp_manager; NMIP4Config *pending_ip4_config; @@ -290,6 +298,101 @@ carrier_off (NMNetlinkMonitor *monitor, } } +static void +_update_s390_subchannels (NMDeviceEthernet *self) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const char *iface; + GUdevClient *client; + GUdevDevice *dev; + GUdevDevice *parent; + const char *parent_path, *item, *driver; + const char *subsystems[] = { "net", NULL }; + GDir *dir; + GError *error = NULL; + + iface = nm_device_get_iface (NM_DEVICE (self)); + + client = g_udev_client_new (subsystems); + if (!client) { + nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to initialize GUdev client", iface); + return; + } + + dev = g_udev_client_query_by_subsystem_and_name (client, "net", iface); + if (!dev) { + nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to find device with udev", iface); + goto out; + } + + /* Try for the "ccwgroup" parent */ + parent = g_udev_device_get_parent_with_subsystem (dev, "ccwgroup", NULL); + if (!parent) { + /* FIXME: whatever 'lcs' devices' subsystem is here... */ + if (!parent) { + /* Not an s390 device */ + goto out; + } + } + + parent_path = g_udev_device_get_sysfs_path (parent); + dir = g_dir_open (parent_path, 0, &error); + if (!dir) { + nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to open directory '%s': %s", + iface, parent_path, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + goto out; + } + + /* FIXME: we probably care about ordering here to ensure that we map + * cdev0 -> subchan1, cdev1 -> subchan2, etc. + */ + while ((item = g_dir_read_name (dir))) { + char buf[50]; + char *cdev_path; + + if (strncmp (item, "cdev", 4)) + continue; /* Not a subchannel link */ + + cdev_path = g_strdup_printf ("%s/%s", parent_path, item); + + memset (buf, 0, sizeof (buf)); + errno = 0; + if (readlink (cdev_path, &buf[0], sizeof (buf) - 1) >= 0) { + if (!priv->subchan1) + priv->subchan1 = g_path_get_basename (buf); + else if (!priv->subchan2) + priv->subchan2 = g_path_get_basename (buf); + else if (!priv->subchan3) + priv->subchan3 = g_path_get_basename (buf); + } else { + nm_log_warn (LOGD_DEVICE | LOGD_HW, + "(%s): failed to read cdev link '%s': %s", + iface, cdev_path, errno); + } + g_free (cdev_path); + }; + + driver = nm_device_get_driver (NM_DEVICE (self)); + nm_log_info (LOGD_DEVICE | LOGD_HW, + "(%s): found s390 '%s' subchannels [%s, %s, %s]", + iface, + driver ? driver : "(unknown driver)", + priv->subchan1 ? priv->subchan1 : "(none)", + priv->subchan2 ? priv->subchan2 : "(none)", + priv->subchan3 ? priv->subchan3 : "(none)"); + + g_dir_close (dir); + +out: + if (parent) + g_object_unref (parent); + if (dev) + g_object_unref (dev); + g_object_unref (client); +} + static GObject* constructor (GType type, guint n_construct_params, @@ -313,6 +416,9 @@ constructor (GType type, nm_device_get_iface (NM_DEVICE (self)), nm_device_get_ifindex (NM_DEVICE (self))); + /* s390 stuff */ + _update_s390_subchannels (NM_DEVICE_ETHERNET (self)); + caps = nm_device_get_capabilities (self); if (caps & NM_DEVICE_CAP_CARRIER_DETECT) { GError *error = NULL; @@ -1759,6 +1865,10 @@ dispose (GObject *object) priv->monitor = NULL; } + g_free (priv->subchan1); + g_free (priv->subchan2); + g_free (priv->subchan3); + G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object); } From fd10f97d98b95a205ffe3370a39c50a5afe713d1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 25 Jun 2010 20:08:09 -0700 Subject: [PATCH 10/16] libnm-util: fix default s390 property values --- libnm-util/nm-setting-wired.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 77b210cfaf..90f0a1ad12 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -597,7 +597,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "configuration. For 'qeth' devices, this is the " "'relative port number'.", 0, 100, 0, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); /** * NMSettingWired:s390-qeth-layer: @@ -610,7 +610,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "s390 'qeth' layer", "s390 'qeth' device layer, either '2' or '3'.", 2, 3, 2, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); /** * NMSettingWired:s390-nettype: From d08b7895fbe11d8b535b2bbfd17b4e3deb3411a3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 25 Jun 2010 21:44:01 -0700 Subject: [PATCH 11/16] core: build composite subchannels for unmanaged spec matching --- src/nm-device-ethernet.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 80c4795dac..099af34e8a 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -109,7 +109,6 @@ typedef struct { guint8 hw_addr[ETH_ALEN]; /* Currently set MAC address */ guint8 perm_hw_addr[ETH_ALEN]; /* Currently set MAC address */ - char * s390_subchannels; gboolean carrier; NMNetlinkMonitor * monitor; @@ -124,6 +123,7 @@ typedef struct { char * subchan1; char * subchan2; char * subchan3; + char * subchannels; /* Composite used for checking unmanaged specs */ /* PPPoE */ NMPPPManager *ppp_manager; @@ -387,6 +387,18 @@ _update_s390_subchannels (NMDeviceEthernet *self) g_dir_close (dir); + if (priv->subchan3) { + priv->subchannels = g_strdup_printf ("%s,%s,%s", + priv->subchan1, + priv->subchan2, + priv->subchan3); + } else if (priv->subchan2) { + priv->subchannels = g_strdup_printf ("%s,%s", + priv->subchan1, + priv->subchan2); + } else + priv->subchannels = g_strdup (priv->subchan1); + out: if (parent) g_object_unref (parent); @@ -1758,8 +1770,8 @@ spec_match_list (NMDevice *device, const GSList *specs) matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); - if (!matched && priv->s390_subchannels) - matched = nm_match_spec_s390_subchannels (specs, priv->s390_subchannels); + if (!matched && priv->subchannels) + matched = nm_match_spec_s390_subchannels (specs, priv->subchannels); return matched; } @@ -1988,6 +2000,7 @@ dispose (GObject *object) g_free (priv->subchan1); g_free (priv->subchan2); g_free (priv->subchan3); + g_free (priv->subchannels); G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object); } From 79752954427ed460d530c1551be25fd5819d4dc0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 25 Jun 2010 21:46:57 -0700 Subject: [PATCH 12/16] core: trivial subchannels logging cleanup --- src/nm-device-ethernet.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 099af34e8a..3a296988f5 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -376,15 +376,6 @@ _update_s390_subchannels (NMDeviceEthernet *self) g_free (cdev_path); }; - driver = nm_device_get_driver (NM_DEVICE (self)); - nm_log_info (LOGD_DEVICE | LOGD_HW, - "(%s): found s390 '%s' subchannels [%s, %s, %s]", - iface, - driver ? driver : "(unknown driver)", - priv->subchan1 ? priv->subchan1 : "(none)", - priv->subchan2 ? priv->subchan2 : "(none)", - priv->subchan3 ? priv->subchan3 : "(none)"); - g_dir_close (dir); if (priv->subchan3) { @@ -399,6 +390,11 @@ _update_s390_subchannels (NMDeviceEthernet *self) } else priv->subchannels = g_strdup (priv->subchan1); + driver = nm_device_get_driver (NM_DEVICE (self)); + nm_log_info (LOGD_DEVICE | LOGD_HW, + "(%s): found s390 '%s' subchannels [%s]", + iface, driver ? driver : "(unknown driver)", priv->subchannels); + out: if (parent) g_object_unref (parent); From cdf8c079ef7f849184a0860cb3856510e9b1c188 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 25 Jun 2010 23:46:47 -0700 Subject: [PATCH 13/16] ifcfg-rh: read and write various s390 settings --- system-settings/plugins/ifcfg-rh/reader.c | 70 ++++++++++++++++++- .../ifcfg-test-wired-qeth-static | 3 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 47 +++++++++++++ system-settings/plugins/ifcfg-rh/writer.c | 28 +++++++- 4 files changed, 146 insertions(+), 2 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 5a7d18931e..57eaae9206 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -2926,6 +2926,35 @@ wireless_connection_from_ifcfg (const char *file, return connection; } +#define LAYER2_TAG "layer2=" +#define PORTNO_TAG "portno=" + +static gboolean +get_s390_option (const char *tag, + guint32 min, + guint32 max, + const char *value, + int *out_int_val) +{ + g_return_val_if_fail (tag != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if (strncmp (value, tag, strlen (tag))) + return FALSE; + + if (get_int (value + strlen (tag), out_int_val)) { + if (*out_int_val < min || *out_int_val > max) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 %s value '%d'", tag, *out_int_val); + return FALSE; + } + } else { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 %s '%s'", tag, value); + return FALSE; + } + + return TRUE; +} + static NMSetting * make_wired_setting (shvarFile *ifcfg, const char *file, @@ -2936,8 +2965,9 @@ make_wired_setting (shvarFile *ifcfg, { NMSettingWired *s_wired; char *value = NULL; - int mtu; + int mtu, portno, layer2; GByteArray *mac = NULL; + char *nettype; s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); @@ -3015,6 +3045,44 @@ make_wired_setting (shvarFile *ifcfg, g_free (value); } + value = svGetValue (ifcfg, "PORTNAME", FALSE); + if (value && strlen (value)) + g_object_set (s_wired, NM_SETTING_WIRED_S390_PORT_NAME, value, NULL); + g_free (value); + + nettype = svGetValue (ifcfg, "NETTYPE", FALSE); + if (nettype && strlen (nettype)) { + if (!strcmp (nettype, "qeth") || !strcmp (nettype, "lcs") || !strcmp (nettype, "ctc")) + g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, nettype, NULL); + else + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unknown s390 NETTYPE '%s'", nettype); + } + + value = svGetValue (ifcfg, "OPTIONS", FALSE); + if (value && strlen (value)) { + char **options, **iter; + + iter = options = g_strsplit_set (value, " ", 0); + while (iter && *iter) { + if (get_s390_option (LAYER2_TAG, 0, 1, *iter, &layer2)) { + if (!nettype || strcmp (nettype, "qeth")) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: s390 layer2 set but NETTYPE not 'qeth'"); + } else { + if (layer2 == 0) + g_object_set (s_wired, NM_SETTING_WIRED_S390_QETH_LAYER, 3, NULL); + else if (layer2 == 1) + g_object_set (s_wired, NM_SETTING_WIRED_S390_QETH_LAYER, 2, NULL); + } + } else if (get_s390_option (PORTNO_TAG, 0, 100, *iter, &portno)) + g_object_set (s_wired, NM_SETTING_WIRED_S390_PORT_NUMBER, portno, NULL); + iter++; + } + g_strfreev (options); + } + g_free (value); + + g_free (nettype); + if (!nm_controlled && !*unmanaged) { /* If NM_CONTROLLED=no but there wasn't a MAC address or z/VM * subchannels, notify the user that the device cannot be unmanaged. diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static index b0ec2a9a56..4719de2175 100644 --- a/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static @@ -7,4 +7,7 @@ ONBOOT=yes NETTYPE=qeth SUBCHANNELS=0.0.0600,0.0.0601,0.0.0602 TYPE=Ethernet +PORTNAME=OSAPORT +OPTIONS='layer2=1 portno=0' +MACADDR=02:00:00:23:65:1a diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 4cf663f263..829727d82d 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5368,6 +5368,7 @@ test_read_wired_qeth_static (void) const char *expected_channel1 = "0.0.0601"; const char *expected_channel2 = "0.0.0602"; const GPtrArray *subchannels; + guint32 num; connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, NULL, @@ -5453,6 +5454,48 @@ test_read_wired_qeth_static (void) "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #2", TEST_IFCFG_WIRED_QETH_STATIC); + /* Nettype */ + tmp = nm_setting_wired_get_s390_nettype (s_wired); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_NETTYPE); + ASSERT (strcmp (tmp, "qeth") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_NETTYPE); + + /* port name */ + tmp = nm_setting_wired_get_s390_port_name (s_wired); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_PORT_NAME); + ASSERT (strcmp (tmp, "OSAPORT") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_PORT_NAME); + + /* port number */ + num = nm_setting_wired_get_s390_port_number (s_wired); + ASSERT (num == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_PORT_NUMBER); + + /* layer */ + num = nm_setting_wired_get_s390_qeth_layer (s_wired); + ASSERT (num == 2, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_S390_QETH_LAYER); + /* ===== IPv4 SETTING ===== */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG)); @@ -8893,6 +8936,10 @@ test_write_wired_qeth_dhcp (void) g_ptr_array_add (subchans, "0.0.602"); g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, + NM_SETTING_WIRED_S390_NETTYPE, "qeth", + NM_SETTING_WIRED_S390_PORT_NAME, "OSAPORT", + NM_SETTING_WIRED_S390_PORT_NUMBER, 5, + NM_SETTING_WIRED_S390_QETH_LAYER, 3, NULL); g_ptr_array_free (subchans, TRUE); diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index 511796bf9b..7a64700ab2 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -842,8 +842,10 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) NMSettingWired *s_wired; const GByteArray *device_mac, *cloned_mac; char *tmp; - guint32 mtu; + const char *nettype, *portname; + guint32 mtu, layer, portno; const GPtrArray *s390_subchannels; + GString *str; s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); if (!s_wired) { @@ -896,6 +898,30 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) g_free (tmp); } + svSetValue (ifcfg, "NETTYPE", NULL, FALSE); + nettype = nm_setting_wired_get_s390_nettype (s_wired); + if (nettype) + svSetValue (ifcfg, "NETTYPE", nettype, FALSE); + + svSetValue (ifcfg, "PORTNAME", NULL, FALSE); + portname = nm_setting_wired_get_s390_port_name (s_wired); + if (portname) + svSetValue (ifcfg, "PORTNAME", portname, FALSE); + + svSetValue (ifcfg, "OPTIONS", NULL, FALSE); + if (s390_subchannels && nettype) { + str = g_string_sized_new (20); + if (!strcmp (nettype, "qeth")) { + layer = nm_setting_wired_get_s390_qeth_layer (s_wired); + g_string_append_printf (str, "layer2=%d ", layer == 2 ? 1 : 0); + } + portno = nm_setting_wired_get_s390_port_number (s_wired); + g_string_append_printf (str, "portno=%d", portno); + + svSetValue (ifcfg, "OPTIONS", str->str, FALSE); + g_string_free (str, TRUE); + } + svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE); return TRUE; From 74a221ab36038361dc02b01986ce15fe69f2e9bf Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 26 Jun 2010 00:14:50 -0700 Subject: [PATCH 14/16] core: respect s390 subchannels for auto-activation and config matching --- src/nm-device-ethernet.c | 52 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 3a296988f5..b851ea12d5 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1702,6 +1702,41 @@ real_deactivate_quickly (NMDevice *device) _set_hw_addr (self, priv->perm_hw_addr, "reset"); } +static gboolean +match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + const GPtrArray *subchans; + int i; + + *try_mac = TRUE; + + subchans = nm_setting_wired_get_s390_subchannels (s_wired); + if (!subchans) + return TRUE; + + /* connection requires subchannels but the device has none */ + if (!priv->subchannels) + return FALSE; + + /* Make sure each subchannel in the connection is a subchannel of this device */ + for (i = 0; i < subchans->len; i++) { + const char *candidate = g_ptr_array_index (subchans, i); + gboolean found = FALSE; + + if ( (priv->subchan1 && !strcmp (priv->subchan1, candidate)) + || (priv->subchan2 && !strcmp (priv->subchan2, candidate)) + || (priv->subchan3 && !strcmp (priv->subchan3, candidate))) + found = TRUE; + + if (!found) + return FALSE; + } + + *try_mac = FALSE; + return TRUE; +} + static gboolean real_check_connection_compatible (NMDevice *device, NMConnection *connection, @@ -1713,6 +1748,8 @@ real_check_connection_compatible (NMDevice *device, NMSettingWired *s_wired; const char *connection_type; gboolean is_pppoe = FALSE; + const GByteArray *mac; + gboolean try_mac = TRUE; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); @@ -1739,10 +1776,15 @@ real_check_connection_compatible (NMDevice *device, } if (s_wired) { - const GByteArray *mac; + if (!match_subchans (self, s_wired, &try_mac)) { + g_set_error (error, + NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, + "The connection's s390 subchannels did not match this device."); + return FALSE; + } mac = nm_setting_wired_get_mac_address (s_wired); - if (mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) { + if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) { g_set_error (error, NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "The connection's MAC address did not match this device."); @@ -1778,14 +1820,18 @@ wired_match_config (NMDevice *self, NMConnection *connection) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMSettingWired *s_wired; const GByteArray *s_ether; + gboolean try_mac = TRUE; s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); if (!s_wired) return FALSE; + if (!match_subchans (NM_DEVICE_ETHERNET (self), s_wired, &try_mac)) + return FALSE; + /* MAC address check */ s_ether = nm_setting_wired_get_mac_address (s_wired); - if (s_ether && memcmp (s_ether->data, priv->perm_hw_addr, ETH_ALEN)) + if (try_mac && s_ether && memcmp (s_ether->data, priv->perm_hw_addr, ETH_ALEN)) return FALSE; return TRUE; From 16bccfd672e7584ce52f191bfbcec6dc2b1893b9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 29 Jun 2010 00:37:14 -0700 Subject: [PATCH 15/16] core: handle s390 options more cleanly There are so many... so handle them as a table of key/value pairs instead of having separate functions for each one. At the moment nothing but subchannels is used internally, but this allows plugins to preserve options that NM doesn't care about when reading/writing system configuration. --- libnm-util/libnm-util.ver | 10 +- libnm-util/nm-setting-wired.c | 353 ++++++++++++------ libnm-util/nm-setting-wired.h | 21 +- system-settings/plugins/ifcfg-rh/reader.c | 56 +-- .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 47 +-- system-settings/plugins/ifcfg-rh/writer.c | 30 +- 6 files changed, 322 insertions(+), 195 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 7afab54ddc..6c2b9fc71e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -290,11 +290,13 @@ global: nm_setting_wired_get_mac_address; nm_setting_wired_get_cloned_mac_address; nm_setting_wired_get_mtu; - nm_setting_wired_get_s390_subchannels; - nm_setting_wired_get_s390_port_name; - nm_setting_wired_get_s390_port_number; - nm_setting_wired_get_s390_qeth_layer; + nm_setting_wired_get_num_s390_options; nm_setting_wired_get_s390_nettype; + nm_setting_wired_get_s390_option; + nm_setting_wired_get_s390_option_by_key; + nm_setting_wired_add_s390_option; + nm_setting_wired_get_s390_subchannels; + nm_setting_wired_remove_s390_option; nm_setting_wireless_ap_security_compatible; nm_setting_wireless_error_get_type; nm_setting_wireless_error_quark; diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index 90f0a1ad12..b18f691f21 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -24,8 +24,10 @@ */ #include +#include #include #include + #include "nm-setting-wired.h" #include "nm-param-spec-specialized.h" #include "nm-utils.h" @@ -79,10 +81,8 @@ typedef struct { GByteArray *cloned_mac_address; guint32 mtu; GPtrArray *s390_subchannels; - char *s390_port_name; - guint32 s390_port_number; - guint32 s390_qeth_layer; char *s390_nettype; + GHashTable *s390_options; } NMSettingWiredPrivate; enum { @@ -95,14 +95,22 @@ enum { PROP_CLONED_MAC_ADDRESS, PROP_MTU, PROP_S390_SUBCHANNELS, - PROP_S390_PORT_NAME, - PROP_S390_PORT_NUMBER, - PROP_S390_QETH_LAYER, PROP_S390_NETTYPE, + PROP_S390_OPTIONS, LAST_PROP }; +static const char *valid_s390_opts[] = { + "portno", "layer2", "portname", "protocol", "priority_queueing", + "buffer_count", "isolation", "total", "inter", "inter_jumbo", "route4", + "route6", "fake_broadcast", "broadcast_mode", "canonical_macaddr", + "checksumming", "sniffer", "large_send", "ipato_enable", "ipato_invert4", + "ipato_add4", "ipato_invert6", "ipato_add6", "vipa_add4", "vipa_add6", + "rxip_add4", "rxip_add6", "lancmd_timeout", + NULL +}; + NMSetting * nm_setting_wired_new (void) { @@ -165,6 +173,17 @@ nm_setting_wired_get_mtu (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->mtu; } +/** + * nm_setting_wired_get_s390_subchannels: + * @setting: the #NMSettingWired + * + * Return the list of s390 subchannels that identify the device that this + * connection is applicable to. The connection should only be used in + * conjunction with that device. + * + * Returns: a #GPtrArray of strings, each specifying one subchannel the + * s390 device uses to communicate to the host. + **/ const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) { @@ -173,30 +192,15 @@ nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_subchannels; } -const char * -nm_setting_wired_get_s390_port_name (NMSettingWired *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); - - return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_port_name; -} - -guint32 -nm_setting_wired_get_s390_port_number (NMSettingWired *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); - - return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_port_number; -} - -guint32 -nm_setting_wired_get_s390_qeth_layer (NMSettingWired *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 2); - - return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_qeth_layer; -} - +/** + * nm_setting_wired_get_s390_nettype: + * @setting: the #NMSettingWired + * + * Returns the s390 device type this connection should apply to. Will be one + * of 'qeth', 'lcs', or 'ctcm'. + * + * Returns: the s390 device type + **/ const char * nm_setting_wired_get_s390_nettype (NMSettingWired *setting) { @@ -205,12 +209,161 @@ nm_setting_wired_get_s390_nettype (NMSettingWired *setting) return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_nettype; } +/** + * nm_setting_wired_get_num_s390_options: + * @setting: the #NMSettingWired + * + * Returns the number of s390-specific options that should be set for this + * device when it is activated. This can be used to retrieve each s390 + * option individually using nm_setting_wired_get_s390_option(). + * + * Returns: the number of s390-specific device options + **/ +guint32 +nm_setting_wired_get_num_s390_options (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return g_hash_table_size (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options); +} + +/** + * nm_setting_wired_get_s390_option: + * @setting: the #NMSettingWired + * @idx: index of the desired option, from 0 to + * nm_setting_wired_get_num_s390_options() - 1 + * @out_key: on return, the key name of the s390 specific option; this value is + * owned by the setting and should not be modified + * @out_value: on return, the value of the key of the s390 specific option; this + * value is owned by the setting and should not be modified + * + * Given an index, return the value of the s390 option at that index. indexes + * are *not* guaranteed to be static across modifications to options done by + * nm_setting_wired_add_s390_option() and nm_setting_wired_remove_s390_option(), + * and should not be used to refer to options except for short periods of time + * such as during option iteration. + * + * Returns: %TRUE on success if the index was valid and an option was found, + * %FALSE if the index was invalid (ie, greater than the number of options + * currently held by the setting) + **/ +gboolean +nm_setting_wired_get_s390_option (NMSettingWired *setting, + guint32 idx, + const char **out_key, + const char **out_value) +{ + NMSettingWiredPrivate *priv; + guint32 num_keys; + GList *keys; + const char *_key = NULL, *_value = NULL; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + + num_keys = nm_setting_wired_get_num_s390_options (setting); + g_return_val_if_fail (idx < num_keys, FALSE); + + keys = g_hash_table_get_keys (priv->s390_options); + _key = g_list_nth_data (keys, idx); + _value = g_hash_table_lookup (priv->s390_options, _key); + + if (out_key) + *out_key = _key; + if (out_value) + *out_value = _value; + return TRUE; +} + +/** + * nm_setting_wired_get_s390_option_by_key: + * @setting: the #NMSettingWired + * @key: the key for which to retrieve the value + * + * Returns the value associated with the s390-specific option specified by + * @key, if it exists. + * + * Returns: the value, or NULL if the key/value pair was never added to the + * setting; the value is owned by the setting and must not be modified + **/ +const char * +nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting, + const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + g_return_val_if_fail (key != NULL, NULL); + g_return_val_if_fail (strlen (key), NULL); + + return g_hash_table_lookup (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); +} + +/** + * nm_setting_wired_add_s390_options: + * @setting: the #NMSettingWired + * @key: key name for the option + * @value: value for the option + * + * Add an option to the table. The option is compared to an internal list + * of allowed options. Key names may contain only alphanumeric characters + * (ie [a-zA-Z0-9]). Adding a new key replaces any existing key/value pair that + * may already exist. + * + * Returns: %TRUE if the option was valid and was added to the internal option + * list, %FALSE if it was not. + **/ +gboolean nm_setting_wired_add_s390_option (NMSettingWired *setting, + const char *key, + const char *value) +{ + size_t value_len; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (strlen (key), FALSE); + g_return_val_if_fail (_nm_utils_string_in_list (key, valid_s390_opts), FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + value_len = strlen (value); + g_return_val_if_fail (value_len > 0 && value_len < 200, FALSE); + + g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, + g_strdup (key), + g_strdup (value)); + return TRUE; +} + +/** + * nm_setting_wired_remove_s390_options: + * @setting: the #NMSettingWired + * @key: key name for the option to remove + * + * Remove the s390-specific option referenced by @key from the internal option + * list. + * + * Returns: %TRUE if the option was found and removed from the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_wired_remove_s390_option (NMSettingWired *setting, + const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (strlen (key), FALSE); + + return g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); const char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL }; const char *valid_duplex[] = { "half", "full", NULL }; + const char *valid_nettype[] = { "qeth", "lcs", "ctcm", NULL }; + GHashTableIter iter; + const char *key, *value; if (priv->port && !_nm_utils_string_in_list (priv->port, valid_ports)) { g_set_error (error, @@ -236,7 +389,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (priv->s390_subchannels && priv->s390_subchannels->len != 3) { + if ( priv->s390_subchannels + && !(priv->s390_subchannels->len == 3 || priv->s390_subchannels->len == 2)) { g_set_error (error, NM_SETTING_WIRED_ERROR, NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, @@ -244,26 +398,27 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (priv->s390_nettype) { - if ( strcmp (priv->s390_nettype, "qeth") - && strcmp (priv->s390_nettype, "lcs") - && strcmp (priv->s390_nettype, "ctc")) { - g_set_error (error, - NM_SETTING_WIRED_ERROR, - NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_S390_NETTYPE); - return FALSE; - } - } - - if (priv->s390_port_name && strlen (priv->s390_port_name) > 8) { + if (priv->s390_nettype && !_nm_utils_string_in_list (priv->s390_nettype, valid_nettype)) { g_set_error (error, NM_SETTING_WIRED_ERROR, NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_S390_PORT_NAME); + NM_SETTING_WIRED_S390_NETTYPE); return FALSE; } + g_hash_table_iter_init (&iter, priv->s390_options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + if ( !_nm_utils_string_in_list (key, valid_s390_opts) + || !strlen (value) + || (strlen (value) > 200)) { + g_set_error (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_S390_OPTIONS); + return FALSE; + } + } + if (priv->cloned_mac_address && priv->cloned_mac_address->len != ETH_ALEN) { g_set_error (error, NM_SETTING_WIRED_ERROR, @@ -278,7 +433,10 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) static void nm_setting_wired_init (NMSettingWired *setting) { + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + g_object_set (setting, NM_SETTING_NAME, NM_SETTING_WIRED_SETTING_NAME, NULL); + priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } static void @@ -288,9 +446,10 @@ finalize (GObject *object) g_free (priv->port); g_free (priv->duplex); - g_free (priv->s390_port_name); g_free (priv->s390_nettype); + g_hash_table_destroy (priv->s390_options); + if (priv->device_mac_address) g_byte_array_free (priv->device_mac_address, TRUE); @@ -300,11 +459,18 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object); } +static void +copy_hash (gpointer key, gpointer value, gpointer user_data) +{ + g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value)); +} + static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (object); + GHashTable *new_hash; switch (prop_id) { case PROP_PORT: @@ -341,20 +507,17 @@ set_property (GObject *object, guint prop_id, } priv->s390_subchannels = g_value_dup_boxed (value); break; - case PROP_S390_PORT_NAME: - g_free (priv->s390_port_name); - priv->s390_port_name = g_value_dup_string (value); - break; - case PROP_S390_PORT_NUMBER: - priv->s390_port_number = g_value_get_uint (value); - break; - case PROP_S390_QETH_LAYER: - priv->s390_qeth_layer = g_value_get_uint (value); - break; case PROP_S390_NETTYPE: g_free (priv->s390_nettype); priv->s390_nettype = g_value_dup_string (value); break; + case PROP_S390_OPTIONS: + /* Must make a deep copy of the hash table here... */ + g_hash_table_remove_all (priv->s390_options); + new_hash = g_value_get_boxed (value); + if (new_hash) + g_hash_table_foreach (new_hash, copy_hash, priv->s390_options); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -363,9 +526,10 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingWired *setting = NM_SETTING_WIRED (object); + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); switch (prop_id) { case PROP_PORT: @@ -392,18 +556,12 @@ get_property (GObject *object, guint prop_id, case PROP_S390_SUBCHANNELS: g_value_set_boxed (value, nm_setting_wired_get_s390_subchannels (setting)); break; - case PROP_S390_PORT_NAME: - g_value_set_string (value, nm_setting_wired_get_s390_port_name (setting)); - break; - case PROP_S390_PORT_NUMBER: - g_value_set_uint (value, nm_setting_wired_get_s390_port_number (setting)); - break; - case PROP_S390_QETH_LAYER: - g_value_set_uint (value, nm_setting_wired_get_s390_qeth_layer (setting)); - break; case PROP_S390_NETTYPE: g_value_set_string (value, nm_setting_wired_get_s390_nettype (setting)); break; + case PROP_S390_OPTIONS: + g_value_set_boxed (value, priv->s390_options); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -570,48 +728,6 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) DBUS_TYPE_G_ARRAY_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); - /** - * NMSettingWired:s390-port-name: - * - * s390 device port name, if required by your configuration. - **/ - g_object_class_install_property - (object_class, PROP_S390_PORT_NAME, - g_param_spec_string (NM_SETTING_WIRED_S390_PORT_NAME, - "s390 Port Name", - "s390 device port name, if required by your configuration.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); - - /** - * NMSettingWired:s390-port-number: - * - * s390 device port number, if required by your configuration. For 'qeth' - * devices, this is the "relative port number". - **/ - g_object_class_install_property - (object_class, PROP_S390_PORT_NUMBER, - g_param_spec_uint (NM_SETTING_WIRED_S390_PORT_NUMBER, - "s390 Port Number", - "s390 device port number, if required by your " - "configuration. For 'qeth' devices, this is the " - "'relative port number'.", - 0, 100, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); - - /** - * NMSettingWired:s390-qeth-layer: - * - * s390 'qeth' device layer, either '2' or '3'. - **/ - g_object_class_install_property - (object_class, PROP_S390_QETH_LAYER, - g_param_spec_uint (NM_SETTING_WIRED_S390_QETH_LAYER, - "s390 'qeth' layer", - "s390 'qeth' device layer, either '2' or '3'.", - 2, 3, 2, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); - /** * NMSettingWired:s390-nettype: * @@ -627,5 +743,24 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) "network devices available on s390 systems.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /** + * NMSettingWired:s390-options: + * + * Dictionary of key/value pairs of s390-specific device options. Both keys + * and values must be strings. Allowed keys include 'portno', 'layer2', + * 'portname', 'protocol', among others. Key names must contain only + * alphanumeric characters (ie, [a-zA-Z0-9]). + **/ + g_object_class_install_property + (object_class, PROP_S390_OPTIONS, + _nm_param_spec_specialized (NM_SETTING_WIRED_S390_OPTIONS, + "s390 Options", + "Dictionary of key/value pairs of s390-specific " + "device options. Both keys and values must be " + "strings. Allowed keys include 'portno', " + "'layer2', 'portname', 'protocol', among others.", + DBUS_TYPE_G_MAP_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index ad89b3b229..32361b4bca 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -60,10 +60,8 @@ GQuark nm_setting_wired_error_quark (void); #define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address" #define NM_SETTING_WIRED_MTU "mtu" #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" -#define NM_SETTING_WIRED_S390_PORT_NAME "s390-port-name" -#define NM_SETTING_WIRED_S390_PORT_NUMBER "s390-port-number" -#define NM_SETTING_WIRED_S390_QETH_LAYER "s390-qeth-layer" #define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" +#define NM_SETTING_WIRED_S390_OPTIONS "s390-options" typedef struct { NMSetting parent; @@ -89,12 +87,23 @@ gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting); const GByteArray *nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting); guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); + const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting); -const char * nm_setting_wired_get_s390_port_name (NMSettingWired *setting); -guint32 nm_setting_wired_get_s390_port_number (NMSettingWired *setting); -guint32 nm_setting_wired_get_s390_qeth_layer (NMSettingWired *setting); const char * nm_setting_wired_get_s390_nettype (NMSettingWired *setting); +guint32 nm_setting_wired_get_num_s390_options (NMSettingWired *setting); +gboolean nm_setting_wired_get_s390_option (NMSettingWired *setting, + guint32 idx, + const char **out_key, + const char **out_value); +const char * nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting, + const char *key); +gboolean nm_setting_wired_add_s390_option (NMSettingWired *setting, + const char *key, + const char *item); +gboolean nm_setting_wired_remove_s390_option (NMSettingWired *setting, + const char *key); + G_END_DECLS #endif /* NM_SETTING_WIRED_H */ diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 57eaae9206..e1b2b98bdc 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -2926,35 +2926,6 @@ wireless_connection_from_ifcfg (const char *file, return connection; } -#define LAYER2_TAG "layer2=" -#define PORTNO_TAG "portno=" - -static gboolean -get_s390_option (const char *tag, - guint32 min, - guint32 max, - const char *value, - int *out_int_val) -{ - g_return_val_if_fail (tag != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - - if (strncmp (value, tag, strlen (tag))) - return FALSE; - - if (get_int (value + strlen (tag), out_int_val)) { - if (*out_int_val < min || *out_int_val > max) { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 %s value '%d'", tag, *out_int_val); - return FALSE; - } - } else { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 %s '%s'", tag, value); - return FALSE; - } - - return TRUE; -} - static NMSetting * make_wired_setting (shvarFile *ifcfg, const char *file, @@ -2965,7 +2936,7 @@ make_wired_setting (shvarFile *ifcfg, { NMSettingWired *s_wired; char *value = NULL; - int mtu, portno, layer2; + int mtu; GByteArray *mac = NULL; char *nettype; @@ -3046,8 +3017,9 @@ make_wired_setting (shvarFile *ifcfg, } value = svGetValue (ifcfg, "PORTNAME", FALSE); - if (value && strlen (value)) - g_object_set (s_wired, NM_SETTING_WIRED_S390_PORT_NAME, value, NULL); + if (value && strlen (value)) { + nm_setting_wired_add_s390_option (s_wired, "portname", value); + } g_free (value); nettype = svGetValue (ifcfg, "NETTYPE", FALSE); @@ -3064,17 +3036,15 @@ make_wired_setting (shvarFile *ifcfg, iter = options = g_strsplit_set (value, " ", 0); while (iter && *iter) { - if (get_s390_option (LAYER2_TAG, 0, 1, *iter, &layer2)) { - if (!nettype || strcmp (nettype, "qeth")) { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: s390 layer2 set but NETTYPE not 'qeth'"); - } else { - if (layer2 == 0) - g_object_set (s_wired, NM_SETTING_WIRED_S390_QETH_LAYER, 3, NULL); - else if (layer2 == 1) - g_object_set (s_wired, NM_SETTING_WIRED_S390_QETH_LAYER, 2, NULL); - } - } else if (get_s390_option (PORTNO_TAG, 0, 100, *iter, &portno)) - g_object_set (s_wired, NM_SETTING_WIRED_S390_PORT_NUMBER, portno, NULL); + char *equals = strchr (*iter, '='); + gboolean valid = FALSE; + + if (equals) { + *equals = '\0'; + valid = nm_setting_wired_add_s390_option (s_wired, *iter, equals + 1); + } + if (!valid) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 OPTION '%s'", *iter); iter++; } g_strfreev (options); diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 829727d82d..0aafcf9d68 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5368,7 +5368,6 @@ test_read_wired_qeth_static (void) const char *expected_channel1 = "0.0.0601"; const char *expected_channel2 = "0.0.0602"; const GPtrArray *subchannels; - guint32 num; connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, NULL, @@ -5468,33 +5467,37 @@ test_read_wired_qeth_static (void) NM_SETTING_WIRED_S390_NETTYPE); /* port name */ - tmp = nm_setting_wired_get_s390_port_name (s_wired); + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); ASSERT (tmp != NULL, - "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key", + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portname'", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_PORT_NAME); + NM_SETTING_WIRED_SETTING_NAME); ASSERT (strcmp (tmp, "OSAPORT") == 0, - "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portname' value", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_PORT_NAME); + NM_SETTING_WIRED_SETTING_NAME); /* port number */ - num = nm_setting_wired_get_s390_port_number (s_wired); - ASSERT (num == 0, - "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portno"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portno'", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_PORT_NUMBER); + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "0") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portno' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); /* layer */ - num = nm_setting_wired_get_s390_qeth_layer (s_wired); - ASSERT (num == 2, - "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", + tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "layer2"); + ASSERT (tmp != NULL, + "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'layer2'", TEST_IFCFG_WIRED_QETH_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_S390_QETH_LAYER); + NM_SETTING_WIRED_SETTING_NAME); + ASSERT (strcmp (tmp, "1") == 0, + "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'layer2' value", + TEST_IFCFG_WIRED_QETH_STATIC, + NM_SETTING_WIRED_SETTING_NAME); /* ===== IPv4 SETTING ===== */ @@ -8937,12 +8940,14 @@ test_write_wired_qeth_dhcp (void) g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, NM_SETTING_WIRED_S390_NETTYPE, "qeth", - NM_SETTING_WIRED_S390_PORT_NAME, "OSAPORT", - NM_SETTING_WIRED_S390_PORT_NUMBER, 5, - NM_SETTING_WIRED_S390_QETH_LAYER, 3, NULL); g_ptr_array_free (subchans, TRUE); + nm_setting_wired_add_s390_option (s_wired, "portname", "FOOBAR"); + nm_setting_wired_add_s390_option (s_wired, "portno", "1"); + nm_setting_wired_add_s390_option (s_wired, "layer2", "0"); + nm_setting_wired_add_s390_option (s_wired, "protocol", "blahbalh"); + /* IP4 setting */ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); ASSERT (s_ip4 != NULL, diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index 7a64700ab2..cc7577860d 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -842,8 +842,8 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) NMSettingWired *s_wired; const GByteArray *device_mac, *cloned_mac; char *tmp; - const char *nettype, *portname; - guint32 mtu, layer, portno; + const char *nettype, *portname, *s390_key, *s390_val; + guint32 mtu, num_opts, i; const GPtrArray *s390_subchannels; GString *str; @@ -904,21 +904,27 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "NETTYPE", nettype, FALSE); svSetValue (ifcfg, "PORTNAME", NULL, FALSE); - portname = nm_setting_wired_get_s390_port_name (s_wired); + portname = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); if (portname) svSetValue (ifcfg, "PORTNAME", portname, FALSE); svSetValue (ifcfg, "OPTIONS", NULL, FALSE); - if (s390_subchannels && nettype) { - str = g_string_sized_new (20); - if (!strcmp (nettype, "qeth")) { - layer = nm_setting_wired_get_s390_qeth_layer (s_wired); - g_string_append_printf (str, "layer2=%d ", layer == 2 ? 1 : 0); - } - portno = nm_setting_wired_get_s390_port_number (s_wired); - g_string_append_printf (str, "portno=%d", portno); + num_opts = nm_setting_wired_get_num_s390_options (s_wired); + if (s390_subchannels && num_opts) { + str = g_string_sized_new (30); + for (i = 0; i < num_opts; i++) { + nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val); - svSetValue (ifcfg, "OPTIONS", str->str, FALSE); + /* portname is handled separately */ + if (!strcmp (s390_key, "portname")) + continue; + + if (str->len) + g_string_append_c (str, ' '); + g_string_append_printf (str, "%s=%s", s390_key, s390_val); + } + if (str->len) + svSetValue (ifcfg, "OPTIONS", str->str, FALSE); g_string_free (str, TRUE); } From f257c98193016b8802107857aeff9298907e6e18 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 28 Jul 2010 10:05:22 -0700 Subject: [PATCH 16/16] libnm-util: register transform func for G_TYPE_STRV to GPtrArray Needed for S390 subchannels property of the wired setting. --- libnm-util/nm-utils.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 1f587297e0..ce13da3c86 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -567,6 +567,24 @@ nm_utils_convert_strv_to_slist (const GValue *src_value, GValue *dest_value) g_value_take_boxed (dest_value, g_slist_reverse (list)); } +static void +nm_utils_convert_strv_to_ptrarray (const GValue *src_value, GValue *dest_value) +{ + char **str; + GPtrArray *array = NULL; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV)); + + str = (char **) g_value_get_boxed (src_value); + + array = g_ptr_array_sized_new (3); + while (str && str[i]) + g_ptr_array_add (array, g_strdup (str[i++])); + + g_value_take_boxed (dest_value, array); +} + static void nm_utils_convert_strv_to_string (const GValue *src_value, GValue *dest_value) { @@ -1081,6 +1099,9 @@ _nm_utils_register_value_transformations (void) g_value_register_transform_func (G_TYPE_STRV, DBUS_TYPE_G_LIST_OF_STRING, nm_utils_convert_strv_to_slist); + g_value_register_transform_func (G_TYPE_STRV, + DBUS_TYPE_G_ARRAY_OF_STRING, + nm_utils_convert_strv_to_ptrarray); g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING, G_TYPE_STRING, nm_utils_convert_strv_to_string);