From e22346b9d095783975b10cb18d78277fe3aae81e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 17:35:57 -0700 Subject: [PATCH] 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;