merge: add settings plugin for reading iBFT configuration (bgo #734009) (rh #990480)

This commit is contained in:
Dan Williams 2014-08-29 18:51:34 -05:00
commit fc9c1f1557
33 changed files with 1649 additions and 1215 deletions

1
.gitignore vendored
View file

@ -222,6 +222,7 @@ valgrind-*.log
/src/dhcp-manager/tests/test-dhcp-dhclient
/src/dhcp-manager/tests/test-dhcp-options
/src/dnsmasq-manager/tests/test-dnsmasq-utils
/src/settings/plugins/ibft/tests/test-ibft
/src/settings/plugins/ifcfg-rh/tests/network-scripts/*-Test_Write_*
/src/settings/plugins/ifcfg-rh/tests/network-scripts/Test_Write_*
/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh

View file

@ -843,6 +843,8 @@ src/settings/plugins/ifnet/tests/Makefile
src/settings/plugins/ifcfg-rh/Makefile
src/settings/plugins/ifcfg-rh/tests/Makefile
src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile
src/settings/plugins/ibft/Makefile
src/settings/plugins/ibft/tests/Makefile
src/settings/plugins/ifcfg-suse/Makefile
src/settings/plugins/keyfile/Makefile
src/settings/plugins/keyfile/tests/Makefile

View file

@ -958,5 +958,51 @@ nmtst_assert_connection_unnormalizable (NMConnection *con,
#endif
static inline void
nmtst_assert_ip4_address_equals (guint32 addr, const char *expected, const char *loc)
{
guint32 addr2 = nmtst_inet4_from_string (expected);
if (addr != addr2)
g_error ("assert: %s: ip4 address '%s' expected, but got %s",
loc, expected ? expected : "any", nm_utils_inet4_ntop (addr, NULL));
}
#define nmtst_assert_ip4_address_equals(addr, expected) \
nmtst_assert_ip4_address_equals (addr, expected, G_STRLOC)
#ifdef __NM_UTILS_H__
static inline void
nmtst_assert_hwaddr_equals (gconstpointer hwaddr1, gssize hwaddr1_len, const char *expected, const char *loc)
{
guint8 buf2[NM_UTILS_HWADDR_LEN_MAX];
gsize hwaddr2_len = 1;
const char *p;
gboolean success;
g_assert (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX);
g_assert (expected);
for (p = expected; *p; p++) {
if (*p == ':' || *p == '-')
hwaddr2_len++;
}
g_assert (hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX);
g_assert (nm_utils_hwaddr_aton (expected, buf2, hwaddr2_len));
/* Manually check the entire hardware address instead of using
* nm_utils_hwaddr_matches() because that function doesn't compare
* entire InfiniBand addresses for various (legitimate) reasons.
*/
success = (hwaddr1_len == hwaddr2_len);
if (success)
success = !memcmp (hwaddr1, buf2, hwaddr1_len);
if (!success) {
g_error ("assert: %s: hwaddr '%s' (%zd) expected, but got %s (%zd)",
loc, expected, hwaddr2_len, nm_utils_hwaddr_ntoa (hwaddr1, hwaddr1_len), hwaddr1_len);
}
}
#define nmtst_assert_hwaddr_equals(hwaddr1, hwaddr1_len, expected) \
nmtst_assert_hwaddr_equals (hwaddr1, hwaddr1_len, expected, G_STRLOC)
#endif
#endif /* __NM_TEST_UTILS_H__ */

View file

@ -123,5 +123,6 @@ src/nm-config.c
src/nm-logging.c
src/nm-manager.c
src/nm-sleep-monitor-systemd.c
src/settings/plugins/ibft/plugin.c
src/settings/plugins/ifcfg-rh/reader.c
src/settings/nm-settings-utils.c

View file

@ -1078,6 +1078,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
GSList *iter;
char *iface = NULL;
NMDevice *device = NULL, *parent = NULL;
gboolean nm_owned = FALSE;
iface = get_virtual_iface_name (self, connection, &parent);
if (!iface) {
@ -1101,6 +1102,8 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
*/
priv->ignore_link_added_cb++;
nm_owned = !nm_platform_link_exists (iface);
if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) {
device = nm_device_bond_new_for_connection (connection);
} else if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) {
@ -1127,8 +1130,14 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
}
if (device) {
nm_device_set_nm_owned (device);
add_device (self, device, FALSE);
if (nm_owned)
nm_device_set_nm_owned (device);
/* If it was created by NM there's no connection to assume, but if it
* previously existed there might be one.
*/
add_device (self, device, !nm_owned);
g_object_unref (device);
}
@ -1908,7 +1917,7 @@ factory_device_added_cb (NMDeviceFactory *factory,
NMDevice *device,
gpointer user_data)
{
add_device (NM_MANAGER (user_data), device, FALSE);
add_device (NM_MANAGER (user_data), device, TRUE);
}
static gboolean

View file

@ -1,4 +1,4 @@
SUBDIRS=keyfile example
SUBDIRS=keyfile example ibft
@GNOME_CODE_COVERAGE_RULES@

View file

@ -0,0 +1,40 @@
SUBDIRS = . tests
@GNOME_CODE_COVERAGE_RULES@
pkglib_LTLIBRARIES = libnm-settings-plugin-ibft.la
noinst_LTLIBRARIES = libibft-io.la
libibft_io_la_SOURCES = \
reader.c \
reader.h \
errors.c \
errors.h
AM_CPPFLAGS = \
-I$(top_srcdir)/src/ \
-I$(top_srcdir)/src/platform \
-I$(top_srcdir)/src/settings \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-core \
-I$(top_builddir)/libnm-core \
-DNETWORKMANAGER_COMPILATION \
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \
-DG_LOG_DOMAIN=\""NetworkManager-ibft"\" \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DSBINDIR=\"$(sbindir)\"
libnm_settings_plugin_ibft_la_SOURCES = \
plugin.c \
plugin.h \
nm-ibft-connection.c \
nm-ibft-connection.h
libnm_settings_plugin_ibft_la_LDFLAGS = -module -avoid-version
libnm_settings_plugin_ibft_la_LIBADD = libibft-io.la
CLEANFILES = $(BUILT_SOURCES)

View file

@ -0,0 +1,34 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#include <glib.h>
#include "errors.h"
GQuark
ibft_plugin_error_quark (void)
{
static GQuark error_quark = 0;
if (G_UNLIKELY (error_quark == 0))
error_quark = g_quark_from_static_string ("ibft-plugin-error-quark");
return error_quark;
}

View file

@ -0,0 +1,29 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#ifndef __ERRORS_H__
#define __ERRORS_H__
#define IBFT_PLUGIN_ERROR (ibft_plugin_error_quark ())
GQuark ibft_plugin_error_quark (void);
#endif /* __ERRORS_H__ */

View file

@ -0,0 +1,65 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#include <string.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <glib/gstdio.h>
#include "nm-ibft-connection.h"
#include "errors.h"
#include "reader.h"
G_DEFINE_TYPE (NMIbftConnection, nm_ibft_connection, NM_TYPE_SETTINGS_CONNECTION)
NMIbftConnection *
nm_ibft_connection_new (const GPtrArray *block, GError **error)
{
NMConnection *source;
GObject *object;
source = connection_from_block (block, error);
if (!source)
return NULL;
object = g_object_new (NM_TYPE_IBFT_CONNECTION, NULL);
/* Update settings with what was read from iscsiadm */
if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object),
source,
FALSE,
error))
g_clear_object (&object);
return (NMIbftConnection *) object;
}
/* GObject */
static void
nm_ibft_connection_init (NMIbftConnection *connection)
{
}
static void
nm_ibft_connection_class_init (NMIbftConnectionClass *ibft_connection_class)
{
}

View file

@ -0,0 +1,50 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#ifndef NM_IBFT_CONNECTION_H
#define NM_IBFT_CONNECTION_H
G_BEGIN_DECLS
#include <nm-settings-connection.h>
#define NM_TYPE_IBFT_CONNECTION (nm_ibft_connection_get_type ())
#define NM_IBFT_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IBFT_CONNECTION, NMIbftConnection))
#define NM_IBFT_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IBFT_CONNECTION, NMIbftConnectionClass))
#define NM_IS_IBFT_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IBFT_CONNECTION))
#define NM_IS_IBFT_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IBFT_CONNECTION))
#define NM_IBFT_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IBFT_CONNECTION, NMIbftConnectionClass))
typedef struct {
NMSettingsConnection parent;
} NMIbftConnection;
typedef struct {
NMSettingsConnectionClass parent;
} NMIbftConnectionClass;
GType nm_ibft_connection_get_type (void);
NMIbftConnection *nm_ibft_connection_new (const GPtrArray *block,
GError **error);
G_END_DECLS
#endif /* NM_IBFT_CONNECTION_H */

View file

@ -0,0 +1,211 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#include <config.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <gmodule.h>
#include <glib-object.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <nm-setting-connection.h>
#include "nm-dbus-glib-types.h"
#include "nm-system-config-interface.h"
#include "nm-settings-error.h"
#include "nm-logging.h"
#include "NetworkManagerUtils.h"
#include "plugin.h"
#include "errors.h"
#include "reader.h"
#include "nm-ibft-connection.h"
static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
G_DEFINE_TYPE_EXTENDED (SCPluginIbft, sc_plugin_ibft, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
system_config_interface_init))
#define SC_PLUGIN_IBFT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IBFT, SCPluginIbftPrivate))
typedef struct {
GHashTable *connections; /* uuid::connection */
gboolean initialized;
} SCPluginIbftPrivate;
static void
read_connections (SCPluginIbft *self)
{
SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self);
GSList *blocks, *iter;
GError *error = NULL;
NMIbftConnection *connection;
if (!read_ibft_blocks ("/sbin/iscsiadm", &blocks, &error)) {
nm_log_dbg (LOGD_SETTINGS, _("ibft: failed to read iscsiadm records: %s"), error->message);
g_error_free (error);
return;
}
for (iter = blocks; iter; iter = iter->next) {
connection = nm_ibft_connection_new (iter->data, &error);
if (connection) {
nm_log_info (LOGD_SETTINGS, _("ibft: read connection '%s'"),
nm_connection_get_id (NM_CONNECTION (connection)));
g_hash_table_insert (priv->connections,
g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))),
connection);
} else {
nm_log_warn (LOGD_SETTINGS, _("ibft: failed to read iscsiadm record: %s"), error->message);
g_clear_error (&error);
}
}
g_slist_free_full (blocks, (GDestroyNotify) g_ptr_array_unref);
}
static GSList *
get_connections (NMSystemConfigInterface *config)
{
SCPluginIbft *self = SC_PLUGIN_IBFT (config);
SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self);
GSList *list = NULL;
GHashTableIter iter;
NMIbftConnection *connection;
if (!priv->initialized) {
read_connections (self);
priv->initialized = TRUE;
}
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection))
list = g_slist_prepend (list, connection);
return list;
}
static void
init (NMSystemConfigInterface *config)
{
}
static void
sc_plugin_ibft_init (SCPluginIbft *self)
{
SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self);
priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
static void
dispose (GObject *object)
{
SCPluginIbft *self = SC_PLUGIN_IBFT (object);
SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self);
if (priv->connections) {
g_hash_table_destroy (priv->connections);
priv->connections = NULL;
}
G_OBJECT_CLASS (sc_plugin_ibft_parent_class)->dispose (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
g_value_set_string (value, "iBFT");
break;
case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
g_value_set_string (value, "(c) 2014 Red Hat, Inc. To report bugs please use the NetworkManager mailing list.");
break;
case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
sc_plugin_ibft_class_init (SCPluginIbftClass *req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
g_type_class_add_private (req_class, sizeof (SCPluginIbftPrivate));
object_class->dispose = dispose;
object_class->get_property = get_property;
object_class->set_property = set_property;
g_object_class_override_property (object_class,
NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
NM_SYSTEM_CONFIG_INTERFACE_NAME);
g_object_class_override_property (object_class,
NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
NM_SYSTEM_CONFIG_INTERFACE_INFO);
g_object_class_override_property (object_class,
NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
g_object_class_override_property (object_class,
NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
}
static void
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
{
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
system_config_interface_class->init = init;
}
G_MODULE_EXPORT GObject *
nm_system_config_factory (void)
{
static SCPluginIbft *singleton = NULL;
if (!singleton)
singleton = SC_PLUGIN_IBFT (g_object_new (SC_TYPE_PLUGIN_IBFT, NULL));
else
g_object_ref (singleton);
return G_OBJECT (singleton);
}

View file

@ -0,0 +1,47 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#ifndef _PLUGIN_H_
#define _PLUGIN_H_
#include <glib-object.h>
#define SC_TYPE_PLUGIN_IBFT (sc_plugin_ibft_get_type ())
#define SC_PLUGIN_IBFT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IBFT, SCPluginIbft))
#define SC_PLUGIN_IBFT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IBFT, SCPluginIbftClass))
#define SC_IS_PLUGIN_IBFT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IBFT))
#define SC_IS_PLUGIN_IBFT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_PLUGIN_IBFT))
#define SC_PLUGIN_IBFT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IBFT, SCPluginIbftClass))
typedef struct _SCPluginIbft SCPluginIbft;
typedef struct _SCPluginIbftClass SCPluginIbftClass;
struct _SCPluginIbft {
GObject parent;
};
struct _SCPluginIbftClass {
GObjectClass parent;
};
GType sc_plugin_ibft_get_type (void);
#endif /* _PLUGIN_H_ */

View file

@ -0,0 +1,565 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/inotify.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <nm-connection.h>
#include <nm-setting-connection.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
#include <nm-setting-vlan.h>
#include <nm-setting-wired.h>
#include <nm-utils.h>
#include "nm-platform.h"
#include "nm-posix-signals.h"
#include "NetworkManagerUtils.h"
#include "nm-logging.h"
#include "errors.h"
#include "reader.h"
#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg)
static void
iscsiadm_child_setup (gpointer user_data G_GNUC_UNUSED)
{
/* We are in the child process here; set a different process group to
* ensure signal isolation between child and parent.
*/
pid_t pid = getpid ();
setpgid (pid, pid);
/*
* We blocked signals in main(). We need to restore original signal
* mask for iscsiadm here so that it can receive signals.
*/
nm_unblock_posix_signals (NULL);
}
/* Removes trailing whitespace and whitespace before and immediately after the '=' */
static char *
remove_most_whitespace (const char *src)
{
char *s_new, *s2;
const char *svalue;
while (*src && g_ascii_isspace (*src))
src++;
svalue = strchr (src, '=');
if (!svalue || svalue == src)
return NULL;
s_new = g_new (char, strlen (src) + 1);
memcpy (s_new, src, svalue - src);
s_new[svalue - src] = '\0';
g_strchomp (s_new);
svalue++;
while (*svalue && g_ascii_isspace (*svalue))
svalue++;
s2 = strchr (s_new, '\0');
s2[0] = '=';
strcpy (++s2, svalue);
g_strchomp (s2);
return s_new;
}
#define TAG_BEGIN "# BEGIN RECORD"
#define TAG_END "# END RECORD"
/**
* read_ibft_blocks:
* @iscsiadm_path: path to iscsiadm program
* @out_blocks: on return if successful, a #GSList of #GPtrArray, or %NULL on
* failure
* @error: location for an error on failure
*
* Parses iscsiadm output and returns a #GSList of #GPtrArray in the @out_blocks
* argument on success, otherwise @out_blocks is set to %NULL. Each #GPtrArray
* in @out_blocks contains the lines from an iscsiadm interface block.
*
* Returns: %TRUE on success, %FALSE on errors
*/
gboolean
read_ibft_blocks (const char *iscsiadm_path,
GSList **out_blocks,
GError **error)
{
const char *argv[4] = { iscsiadm_path, "-m", "fw", NULL };
const char *envp[1] = { NULL };
GSList *blocks = NULL;
char *out = NULL, *err = NULL;
gint status = 0;
char **lines = NULL, **iter;
GPtrArray *block_lines = NULL;
gboolean success = FALSE;
g_return_val_if_fail (iscsiadm_path != NULL, FALSE);
g_return_val_if_fail (out_blocks != NULL && *out_blocks == NULL, FALSE);
if (!g_spawn_sync ("/", (char **) argv, (char **) envp, 0,
iscsiadm_child_setup, NULL, &out, &err, &status, error))
goto done;
if (!WIFEXITED (status)) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: %s exited abnormally.", iscsiadm_path);
goto done;
}
if (WEXITSTATUS (status) != 0) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: %s exited with error %d. Message: '%s'",
iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)");
goto done;
}
nm_log_dbg (LOGD_SETTINGS, "iBFT records:\n%s", out);
lines = g_strsplit_set (out, "\n\r", -1);
for (iter = lines; iter && *iter; iter++) {
if (!*iter[0])
continue;
if (!g_ascii_strncasecmp (*iter, TAG_BEGIN, STRLEN (TAG_BEGIN))) {
if (block_lines) {
PARSE_WARNING ("malformed iscsiadm record: missing END RECORD.");
g_ptr_array_unref (block_lines);
}
/* Start new record */
block_lines = g_ptr_array_new_full (15, g_free);
} else if (!g_ascii_strncasecmp (*iter, TAG_END, STRLEN (TAG_END))) {
if (block_lines) {
if (block_lines->len)
blocks = g_slist_prepend (blocks, block_lines);
else
g_ptr_array_unref (block_lines);
block_lines = NULL;
}
} else if (block_lines) {
char *s = remove_most_whitespace (*iter);
if (s)
g_ptr_array_add (block_lines, s);
else {
PARSE_WARNING ("malformed iscsiadm record: no = in '%s'.", *iter);
g_clear_pointer (&block_lines, g_ptr_array_unref);
}
}
}
if (block_lines) {
PARSE_WARNING ("malformed iscsiadm record: missing # END RECORD.");
g_clear_pointer (&block_lines, g_ptr_array_unref);
}
success = TRUE;
done:
if (lines)
g_strfreev (lines);
g_free (out);
if (success)
*out_blocks = blocks;
else
g_slist_free_full (blocks, (GDestroyNotify) g_ptr_array_unref);
return success;
}
#define ISCSI_HWADDR_TAG "iface.hwaddress"
#define ISCSI_BOOTPROTO_TAG "iface.bootproto"
#define ISCSI_IPADDR_TAG "iface.ipaddress"
#define ISCSI_SUBNET_TAG "iface.subnet_mask"
#define ISCSI_GATEWAY_TAG "iface.gateway"
#define ISCSI_DNS1_TAG "iface.primary_dns"
#define ISCSI_DNS2_TAG "iface.secondary_dns"
#define ISCSI_VLAN_ID_TAG "iface.vlan_id"
#define ISCSI_IFACE_TAG "iface.net_ifacename"
static const char *
match_iscsiadm_tag (const char *line, const char *tag)
{
gsize taglen = strlen (tag);
if (g_ascii_strncasecmp (line, tag, taglen) != 0)
return NULL;
if (line[taglen] != '=')
return NULL;
return line + taglen + 1;
}
/**
* parse_ibft_config:
* @data: an array of iscsiadm interface block lines
* @error: return location for errors
* @...: pairs of key (const char *) : location (const char **) indicating the
* key to look for and the location to store the retrieved value in
*
* Parses an iscsiadm interface block into variables requested by the caller.
* Callers should verify the returned data is complete and valid. Returned
* strings are owned by @data and should not be used after @data is freed.
*
* Returns: %TRUE if at least , %FALSE on failure
*/
gboolean
parse_ibft_config (const GPtrArray *data, GError **error, ...)
{
gboolean success = FALSE;
const char **out_value, *p;
va_list ap;
const char *key;
guint i;
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data->len > 0, FALSE);
/* Find requested keys and populate return values */
va_start (ap, error);
while ((key = va_arg (ap, const char *))) {
out_value = va_arg (ap, const char **);
*out_value = NULL;
for (i = 0; i < data->len; i++) {
p = match_iscsiadm_tag (g_ptr_array_index (data, i), key);
if (p) {
*out_value = p;
success = TRUE;
break;
}
}
}
va_end (ap);
if (!success) {
g_set_error_literal (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: failed to match at least one iscsiadm block field");
}
return success;
}
static gboolean
ip4_setting_add_from_block (const GPtrArray *block,
NMConnection *connection,
GError **error)
{
NMSettingIP4Config *s_ip4 = NULL;
NMIP4Address *addr;
const char *s_method = NULL;
const char *s_ipaddr = NULL;
const char *s_gateway = NULL;
const char *s_dns1 = NULL;
const char *s_dns2 = NULL;
const char *s_netmask = NULL;
guint32 ipaddr = 0;
guint32 netmask = 0;
guint32 gateway = 0;
guint32 dns1 = 0;
guint32 dns2 = 0;
guint32 prefix;
g_assert (block);
if (!parse_ibft_config (block, error,
ISCSI_BOOTPROTO_TAG, &s_method,
ISCSI_IPADDR_TAG, &s_ipaddr,
ISCSI_SUBNET_TAG, &s_netmask,
ISCSI_GATEWAY_TAG, &s_gateway,
ISCSI_DNS1_TAG, &s_dns1,
ISCSI_DNS2_TAG, &s_dns2,
NULL))
goto error;
if (!s_method) {
g_set_error_literal (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: missing " ISCSI_BOOTPROTO_TAG);
goto error;
}
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
if (!g_ascii_strcasecmp (s_method, "dhcp")) {
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
goto success;
} else if (g_ascii_strcasecmp (s_method, "static") != 0) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: unknown " ISCSI_BOOTPROTO_TAG " '%s'.",
s_method);
goto error;
}
/* Static configuration stuff */
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
/* IP address */
if (!s_ipaddr || inet_pton (AF_INET, s_ipaddr, &ipaddr) != 1) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: invalid IP address '%s'.",
s_ipaddr);
goto error;
}
/* Subnet/prefix */
if (!s_netmask || inet_pton (AF_INET, s_netmask, &netmask) != 1) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: invalid subnet mask '%s'.",
s_netmask);
goto error;
}
prefix = nm_utils_ip4_netmask_to_prefix (netmask);
if (s_gateway && inet_pton (AF_INET, s_gateway, &gateway) != 1) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: invalid IP gateway '%s'.",
s_gateway);
goto error;
}
if (s_dns1 && inet_pton (AF_INET, s_dns1, &dns1) != 1) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: invalid DNS1 address '%s'.",
s_dns1);
goto error;
}
if (s_dns2 && inet_pton (AF_INET, s_dns2, &dns2) != 1) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: invalid DNS2 address '%s'.",
s_dns2);
goto error;
}
addr = nm_ip4_address_new ();
nm_ip4_address_set_address (addr, ipaddr);
nm_ip4_address_set_prefix (addr, prefix);
nm_ip4_address_set_gateway (addr, gateway);
nm_setting_ip4_config_add_address (s_ip4, addr);
nm_ip4_address_unref (addr);
if (dns1)
nm_setting_ip4_config_add_dns (s_ip4, dns1);
if (dns2)
nm_setting_ip4_config_add_dns (s_ip4, dns2);
success:
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
return TRUE;
error:
g_clear_object (&s_ip4);
return FALSE;
}
static gboolean
connection_setting_add (const GPtrArray *block,
NMConnection *connection,
const char *type,
const char *prefix,
const char *iface,
GError **error)
{
NMSetting *s_con;
char *id, *uuid, *uuid_data;
const char *s_hwaddr = NULL, *s_ip4addr = NULL, *s_vlanid;
if (!parse_ibft_config (block, error,
ISCSI_VLAN_ID_TAG, &s_vlanid,
ISCSI_HWADDR_TAG, &s_hwaddr,
ISCSI_IPADDR_TAG, &s_ip4addr,
NULL))
return FALSE;
if (!s_hwaddr) {
g_set_error_literal (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: missing " ISCSI_HWADDR_TAG);
return FALSE;
}
id = g_strdup_printf ("iBFT%s%s %s",
prefix ? " " : "",
prefix ? prefix : "",
iface);
uuid_data = g_strdup_printf ("%s%s%s",
s_vlanid ? s_vlanid : "0",
s_hwaddr,
s_ip4addr ? s_ip4addr : "DHCP");
uuid = nm_utils_uuid_generate_from_string (uuid_data);
g_free (uuid_data);
s_con = nm_setting_connection_new ();
g_object_set (s_con,
NM_SETTING_CONNECTION_TYPE, type,
NM_SETTING_CONNECTION_UUID, uuid,
NM_SETTING_CONNECTION_ID, id,
NM_SETTING_CONNECTION_READ_ONLY, TRUE,
NULL);
g_free (uuid);
g_free (id);
nm_connection_add_setting (connection, NM_SETTING (s_con));
return TRUE;
}
static gboolean
is_ibft_vlan_device (const GPtrArray *block)
{
char *s_vlan_id = NULL;
if (parse_ibft_config (block, NULL, ISCSI_VLAN_ID_TAG, &s_vlan_id, NULL)) {
g_assert (s_vlan_id);
/* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it
* means "no VLAN".
*/
if (nm_utils_ascii_str_to_int64 (s_vlan_id, 10, 1, 4095, -1) != -1)
return TRUE;
}
return FALSE;
}
static gboolean
vlan_setting_add_from_block (const GPtrArray *block,
NMConnection *connection,
GError **error)
{
NMSetting *s_vlan = NULL;
const char *vlan_id_str = NULL;
gint64 vlan_id = -1;
gboolean success;
g_assert (block);
g_assert (connection);
/* This won't fail since this function shouldn't be called unless the
* iBFT VLAN ID exists and is > 0.
*/
success = parse_ibft_config (block, NULL, ISCSI_VLAN_ID_TAG, &vlan_id_str, NULL);
g_assert (success);
g_assert (vlan_id_str);
/* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it means "no VLAN" */
vlan_id = nm_utils_ascii_str_to_int64 (vlan_id_str, 10, 1, 4095, -1);
if (vlan_id == -1) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0, "Invalid VLAN_ID '%s'", vlan_id_str);
return FALSE;
}
s_vlan = nm_setting_vlan_new ();
g_object_set (s_vlan, NM_SETTING_VLAN_ID, (guint32) vlan_id, NULL);
nm_connection_add_setting (connection, NM_SETTING (s_vlan));
return TRUE;
}
static gboolean
wired_setting_add_from_block (const GPtrArray *block,
NMConnection *connection,
GError **error)
{
NMSetting *s_wired = NULL;
const char *hwaddr_str = NULL;
GByteArray *hwaddr;
g_assert (block);
g_assert (connection);
if (!parse_ibft_config (block, NULL, ISCSI_HWADDR_TAG, &hwaddr_str, NULL)) {
g_set_error_literal (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: missing " ISCSI_HWADDR_TAG);
return FALSE;
}
hwaddr = nm_utils_hwaddr_atoba (hwaddr_str, ETH_ALEN);
if (!hwaddr) {
g_set_error (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: invalid " ISCSI_HWADDR_TAG " '%s'.",
hwaddr_str);
return FALSE;
}
s_wired = nm_setting_wired_new ();
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, hwaddr, NULL);
g_byte_array_unref (hwaddr);
nm_connection_add_setting (connection, s_wired);
return TRUE;
}
NMConnection *
connection_from_block (const GPtrArray *block, GError **error)
{
NMConnection *connection = NULL;
gboolean is_vlan = FALSE;
const char *iface = NULL;
g_assert (block);
if (!parse_ibft_config (block, error, ISCSI_IFACE_TAG, &iface, NULL)) {
g_set_error_literal (error, IBFT_PLUGIN_ERROR, 0,
"iBFT: malformed iscsiadm record: missing " ISCSI_IFACE_TAG);
return NULL;
}
connection = nm_simple_connection_new ();
is_vlan = is_ibft_vlan_device (block);
if (is_vlan && !vlan_setting_add_from_block (block, connection, error))
goto error;
/* Always have a wired setting; for VLAN it defines the parent */
if (!wired_setting_add_from_block (block, connection, error))
goto error;
if (!ip4_setting_add_from_block (block, connection, error))
goto error;
if (!connection_setting_add (block,
connection,
is_vlan ? NM_SETTING_VLAN_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME,
is_vlan ? "VLAN" : NULL,
iface,
error))
goto error;
if (!nm_connection_normalize (connection, NULL, NULL, error))
goto error;
return connection;
error:
g_object_unref (connection);
return NULL;
}

View file

@ -0,0 +1,36 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#ifndef __READER_H__
#define __READER_H__
#include <glib.h>
#include <nm-connection.h>
gboolean read_ibft_blocks (const char *iscsiadm_path,
GSList **out_blocks,
GError **error);
NMConnection *connection_from_block (const GPtrArray *block, GError **error);
/* For testcases */
gboolean parse_ibft_config (const GPtrArray *data, GError **error, ...) G_GNUC_NULL_TERMINATED;
#endif /* __READER_H__ */

View file

@ -0,0 +1,50 @@
if ENABLE_TESTS
@GNOME_CODE_COVERAGE_RULES@
AM_CPPFLAGS = \
$(GLIB_CFLAGS) \
$(CODE_COVERAGE_CFLAGS) \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-core \
-I$(top_builddir)/libnm-core \
-I$(top_srcdir)/src/ \
-I$(top_srcdir)/src/platform \
-I$(top_srcdir)/src/settings \
-I$(srcdir)/../ \
-DG_LOG_DOMAIN=\""NetworkManager-ibft"\" \
-DNETWORKMANAGER_COMPILATION \
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
-DTEST_IBFT_DIR=\"$(abs_srcdir)\" \
-DTEST_SCRATCH_DIR=\"$(abs_builddir)/\"
AM_LDFLAGS = \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(CODE_COVERAGE_LDFLAGS)
noinst_PROGRAMS = test-ibft
test_ibft_SOURCES = \
test-ibft.c \
../errors.c \
../reader.c
test_ibft_LDADD = \
$(top_builddir)/src/libNetworkManager.la
TESTS = test-ibft
EXTRA_DIST = \
iscsiadm-test-dhcp \
iscsiadm-test-static \
iscsiadm-test-bad-ipaddr \
iscsiadm-test-bad-gateway \
iscsiadm-test-bad-dns1 \
iscsiadm-test-bad-dns2 \
iscsiadm-test-bad-entry \
iscsiadm-test-bad-record \
iscsiadm-test-vlan
endif

View file

@ -10,7 +10,7 @@ iface.subnet_mask = 255.255.252.0
iface.gateway = 192.168.35.254
iface.primary_dns = 10000.500.250.1
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16

View file

@ -10,7 +10,7 @@ iface.subnet_mask = 255.255.252.0
iface.gateway = 192.168.35.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = blah.foo.bar.baz
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16

View file

@ -10,26 +10,11 @@ iface.subnet_mask = 255.255.252.0
iface.gateway = 192.168.35.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16
node.conn[0].port = 3260
node.boot_lun = 00000000
# END RECORD
# BEGIN RECORD
iface.initiatorname = iqn.pjones6
iface.hwaddress = 00:33:21:98:b9:f1
iface.bootproto = DHCP
iface.gateway = 10.16.52.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.net_ifacename = eth1
node.name = iqn.1.2008-11.com.blahblah:iscsi1
node.conn[0].address = 10.16.52.16
node.conn[0].port = 3260
node.boot_lun = 00000000
# END RECORD
EOF

View file

@ -5,12 +5,12 @@ cat << EOF
iface.initiatorname = iqn.pjones6
iface.hwaddress = 00:33:21:98:b9:f0
iface.bootproto = STATIC
iface.ipaddress = aa.bb.cc.dd
iface.ipaddress = 192.168.32.72
iface.subnet_mask = 255.255.252.0
iface.gateway = 192.168.35.254
iface.gateway = bb.cc.dd.ee
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16

View file

@ -5,12 +5,12 @@ cat << EOF
iface.initiatorname = iqn.pjones6
iface.hwaddress = 00:33:21:98:b9:f0
iface.bootproto = STATIC
iface.ipaddress = 192.168.32.72
iface.ipaddress = aa.bb.cc.dd
iface.subnet_mask = 255.255.252.0
iface.gateway = bb.cc.dd.ee
iface.gateway = 192.168.35.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16

View file

@ -8,7 +8,7 @@ iface.bootproto = DHCP
iface.gateway = 10.16.52.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16

View file

@ -8,7 +8,7 @@ iface.bootproto = DHCP
iface.gateway = 10.16.52.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16
@ -22,7 +22,7 @@ iface.bootproto = DHCP
iface.gateway = 10.16.52.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth1
node.name = iqn.1.2008-11.com.blahblah:iscsi1
node.conn[0].address = 10.16.52.16

View file

@ -10,7 +10,7 @@ iface.subnet_mask = 255.255.252.0
iface.gateway = 192.168.35.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth0
node.name = iqn.0.2008-11.com.blahblah:iscsi0
node.conn[0].address = 10.16.52.16
@ -24,7 +24,7 @@ iface.bootproto = DHCP
iface.gateway = 10.16.52.254
iface.primary_dns = 10.16.255.2
iface.secondary_dns = 10.16.255.3
iface.vlan = 0
iface.vlan_id = 0
iface.net_ifacename = eth1
node.name = iqn.1.2008-11.com.blahblah:iscsi1
node.conn[0].address = 10.16.52.16

View file

@ -0,0 +1,19 @@
#!/bin/bash
cat << EOF
# BEGIN RECORD 6.2.0.873-21
iface.initiatorname = iqn.2010-04.org.ipxe:d05faa97-c4be-44f6-a723-efde9aa399a0
iface.transport_name = tcp
iface.hwaddress = 00:33:21:98:b9:f0
iface.bootproto = STATIC
iface.ipaddress = 192.168.6.200
iface.subnet_mask = 255.255.255.0
iface.vlan_id = 123
iface.net_ifacename = eth0
node.name = iqn.2003-01.org.x:disk1
node.conn[0].address = 192.168.6.32
node.conn[0].port = 3260
node.boot_lun = 01000000
# END RECORD
EOF

View file

@ -0,0 +1,295 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014 Red Hat, Inc.
*/
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <nm-utils.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-vlan.h>
#include "NetworkManagerUtils.h"
#include "errors.h"
#include "reader.h"
#include "nm-logging.h"
#include "nm-test-utils.h"
static GPtrArray *
read_block (const char *iscsiadm_path, const char *expected_mac)
{
GSList *blocks = NULL, *iter;
GPtrArray *block = NULL;
GError *error = NULL;
gboolean success;
success = read_ibft_blocks (iscsiadm_path, &blocks, &error);
g_assert_no_error (error);
g_assert (success);
g_assert (blocks);
for (iter = blocks; iter; iter = iter->next) {
const char *s_hwaddr = NULL;
if (!parse_ibft_config (iter->data, NULL, "iface.hwaddress", &s_hwaddr, NULL))
continue;
g_assert (s_hwaddr);
if (nm_utils_hwaddr_matches (s_hwaddr, -1, expected_mac, -1)) {
block = g_ptr_array_ref (iter->data);
break;
}
}
g_assert (block);
g_slist_foreach (blocks, (GFunc) g_ptr_array_unref, NULL);
return block;
}
static void
test_read_ibft_dhcp (void)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4;
GError *error = NULL;
const GByteArray *array;
const char *expected_mac_address = "00:33:21:98:b9:f1";
GPtrArray *block;
block = read_block (TEST_IBFT_DIR "/iscsiadm-test-dhcp", expected_mac_address);
connection = connection_from_block (block, &error);
g_assert_no_error (error);
nmtst_assert_connection_verifies_without_normalization (connection);
g_assert (!nm_connection_get_setting_vlan (connection));
/* ===== CONNECTION SETTING ===== */
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME);
g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "iBFT eth1");
g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0);
g_assert (nm_setting_connection_get_autoconnect (s_con));
g_assert (nm_setting_connection_get_read_only (s_con));
/* ===== WIRED SETTING ===== */
s_wired = nm_connection_get_setting_wired (connection);
g_assert (s_wired);
array = nm_setting_wired_get_mac_address (s_wired);
g_assert (array);
nmtst_assert_hwaddr_equals (array->data, array->len, expected_mac_address);
g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0);
/* ===== IPv4 SETTING ===== */
s_ip4 = nm_connection_get_setting_ip4_config (connection);
g_assert (s_ip4);
g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
g_object_unref (connection);
}
static void
test_read_ibft_static (void)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4;
GError *error = NULL;
const GByteArray *array;
const char *expected_mac_address = "00:33:21:98:b9:f0";
NMIP4Address *ip4_addr;
GPtrArray *block;
block = read_block (TEST_IBFT_DIR "/iscsiadm-test-static", expected_mac_address);
connection = connection_from_block (block, &error);
g_assert_no_error (error);
nmtst_assert_connection_verifies_without_normalization (connection);
g_assert (!nm_connection_get_setting_vlan (connection));
/* ===== CONNECTION SETTING ===== */
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME);
g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "iBFT eth0");
g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0);
g_assert (nm_setting_connection_get_autoconnect (s_con));
g_assert (nm_setting_connection_get_read_only (s_con));
/* ===== WIRED SETTING ===== */
s_wired = nm_connection_get_setting_wired (connection);
g_assert (s_wired);
array = nm_setting_wired_get_mac_address (s_wired);
g_assert (array);
nmtst_assert_hwaddr_equals (array->data, array->len, expected_mac_address);
g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0);
/* ===== IPv4 SETTING ===== */
s_ip4 = nm_connection_get_setting_ip4_config (connection);
g_assert (s_ip4);
g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
g_assert_cmpint (nm_setting_ip4_config_get_num_dns (s_ip4), ==, 2);
nmtst_assert_ip4_address_equals (nm_setting_ip4_config_get_dns (s_ip4, 0), "10.16.255.2");
nmtst_assert_ip4_address_equals (nm_setting_ip4_config_get_dns (s_ip4, 1), "10.16.255.3");
g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 1);
ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
g_assert (ip4_addr);
nmtst_assert_ip4_address_equals (nm_ip4_address_get_address (ip4_addr), "192.168.32.72");
g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 22);
nmtst_assert_ip4_address_equals (nm_ip4_address_get_gateway (ip4_addr), "192.168.35.254");
g_object_unref (connection);
g_ptr_array_unref (block);
}
static void
test_read_ibft_malformed (gconstpointer user_data)
{
const char *iscsiadm_path = user_data;
GSList *blocks = NULL;
GError *error = NULL;
gboolean success;
g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS));
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*malformed iscsiadm record*");
success = read_ibft_blocks (iscsiadm_path, &blocks, &error);
g_assert_no_error (error);
g_assert (success);
g_assert (blocks == NULL);
g_test_assert_expected_messages ();
}
static void
test_read_ibft_bad_address (gconstpointer user_data)
{
const char *iscsiadm_path = user_data;
NMConnection *connection;
const char *expected_mac_address = "00:33:21:98:b9:f0";
GPtrArray *block;
GError *error = NULL;
g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS));
block = read_block (iscsiadm_path, expected_mac_address);
connection = connection_from_block (block, &error);
g_assert_error (error, IBFT_PLUGIN_ERROR, 0);
g_assert (strstr (error->message, "iBFT: malformed iscsiadm record: invalid"));
g_clear_error (&error);
g_assert (connection == NULL);
g_ptr_array_unref (block);
}
static void
test_read_ibft_vlan (void)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
NMSettingVlan *s_vlan;
NMSettingIP4Config *s_ip4;
const GByteArray *array;
const char *expected_mac_address = "00:33:21:98:b9:f0";
NMIP4Address *ip4_addr;
GError *error = NULL;
GPtrArray *block;
block = read_block (TEST_IBFT_DIR "/iscsiadm-test-vlan", expected_mac_address);
connection = connection_from_block (block, &error);
g_assert_no_error (error);
nmtst_assert_connection_verifies_without_normalization (connection);
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_VLAN_SETTING_NAME);
/* ===== WIRED SETTING ===== */
s_wired = nm_connection_get_setting_wired (connection);
g_assert (s_wired);
array = nm_setting_wired_get_mac_address (s_wired);
g_assert (array);
nmtst_assert_hwaddr_equals (array->data, array->len, expected_mac_address);
/* ===== VLAN SETTING ===== */
s_vlan = nm_connection_get_setting_vlan (connection);
g_assert (s_vlan);
g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 123);
g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, NULL);
g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, NULL);
/* ===== IPv4 SETTING ===== */
s_ip4 = nm_connection_get_setting_ip4_config (connection);
g_assert (s_ip4);
g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
g_assert_cmpint (nm_setting_ip4_config_get_num_dns (s_ip4), ==, 0);
g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 1);
ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
g_assert (ip4_addr);
nmtst_assert_ip4_address_equals (nm_ip4_address_get_address (ip4_addr), "192.168.6.200");
g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 24);
nmtst_assert_ip4_address_equals (nm_ip4_address_get_gateway (ip4_addr), "0.0.0.0");
g_object_unref (connection);
g_ptr_array_ref (block);
}
NMTST_DEFINE ();
#define TPATH "/settings/plugins/ibft/"
int main (int argc, char **argv)
{
nmtst_init_assert_logging (&argc, &argv);
g_test_add_func (TPATH "ibft/dhcp", test_read_ibft_dhcp);
g_test_add_func (TPATH "ibft/static", test_read_ibft_static);
g_test_add_func (TPATH "ibft/vlan", test_read_ibft_vlan);
g_test_add_data_func (TPATH "ibft/bad-record-read", TEST_IBFT_DIR "/iscsiadm-test-bad-record", test_read_ibft_malformed);
g_test_add_data_func (TPATH "ibft/bad-entry-read", TEST_IBFT_DIR "/iscsiadm-test-bad-entry", test_read_ibft_malformed);
g_test_add_data_func (TPATH "ibft/bad-ipaddr-read", TEST_IBFT_DIR "/iscsiadm-test-bad-ipaddr", test_read_ibft_bad_address);
g_test_add_data_func (TPATH "ibft/bad-gateway-read", TEST_IBFT_DIR "/iscsiadm-test-bad-gateway", test_read_ibft_bad_address);
g_test_add_data_func (TPATH "ibft/bad-dns1-read", TEST_IBFT_DIR "/iscsiadm-test-bad-dns1", test_read_ibft_bad_address);
g_test_add_data_func (TPATH "ibft/bad-dns2-read", TEST_IBFT_DIR "/iscsiadm-test-bad-dns2", test_read_ibft_bad_address);
return g_test_run ();
}

View file

@ -117,7 +117,7 @@ nm_ifcfg_connection_new (NMConnection *source,
else {
char *keyfile = NULL, *routefile = NULL, *route6file = NULL;
tmp = connection_from_file (full_path, NULL, NULL, NULL,
tmp = connection_from_file (full_path, NULL, NULL,
&unhandled_spec,
&keyfile,
&routefile,
@ -269,7 +269,7 @@ commit_changes (NMSettingsConnection *connection,
* it if it's really changed.
*/
if (priv->path) {
reread = connection_from_file (priv->path, NULL, NULL, NULL,
reread = connection_from_file (priv->path, NULL, NULL,
NULL, NULL, NULL, NULL,
&error, NULL);
g_clear_error (&error);

View file

@ -274,251 +274,6 @@ read_mac_address (shvarFile *ifcfg, const char *key, gsize len,
return TRUE;
}
static void
iscsiadm_child_setup (gpointer user_data G_GNUC_UNUSED)
{
/* We are in the child process here; set a different process group to
* ensure signal isolation between child and parent.
*/
pid_t pid = getpid ();
setpgid (pid, pid);
/*
* We blocked signals in main(). We need to restore original signal
* mask for iscsiadm here so that it can receive signals.
*/
nm_unblock_posix_signals (NULL);
}
static char *
match_iscsiadm_tag (const char *line, const char *tag, gboolean *skip)
{
char *p;
if (g_ascii_strncasecmp (line, tag, strlen (tag)))
return NULL;
p = strchr (line, '=');
if (!p) {
PARSE_WARNING ("malformed iscsiadm record: no = in '%s'.", line);
*skip = TRUE;
return NULL;
}
p++; /* advance past = */
return g_strstrip (p);
}
#define ISCSI_HWADDR_TAG "iface.hwaddress"
#define ISCSI_BOOTPROTO_TAG "iface.bootproto"
#define ISCSI_IPADDR_TAG "iface.ipaddress"
#define ISCSI_SUBNET_TAG "iface.subnet_mask"
#define ISCSI_GATEWAY_TAG "iface.gateway"
#define ISCSI_DNS1_TAG "iface.primary_dns"
#define ISCSI_DNS2_TAG "iface.secondary_dns"
static gboolean
fill_ip4_setting_from_ibft (shvarFile *ifcfg,
NMSettingIP4Config *s_ip4,
const char *iscsiadm_path,
GError **error)
{
const char *argv[4] = { iscsiadm_path, "-m", "fw", NULL };
const char *envp[1] = { NULL };
gboolean success = FALSE, in_record = FALSE, hwaddr_matched = FALSE, skip = FALSE;
char *out = NULL, *err = NULL;
gint status = 0;
GByteArray *ifcfg_mac = NULL;
char **lines = NULL, **iter;
const char *method = NULL;
guint32 ipaddr;
guint32 gateway;
guint32 dns1;
guint32 dns2;
guint32 prefix = 0;
g_return_val_if_fail (s_ip4 != NULL, FALSE);
g_return_val_if_fail (iscsiadm_path != NULL, FALSE);
if (!g_spawn_sync ("/", (char **) argv, (char **) envp, 0,
iscsiadm_child_setup, NULL, &out, &err, &status, error))
return FALSE;
if (!WIFEXITED (status)) {
g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
"%s exited abnormally.", iscsiadm_path);
goto done;
}
if (WEXITSTATUS (status) != 0) {
g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
"%s exited with error %d. Message: '%s'",
iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)");
goto done;
}
if (!read_mac_address (ifcfg, "HWADDR", ETH_ALEN, &ifcfg_mac, error))
goto done;
/* Ensure we got a MAC */
if (!ifcfg_mac) {
g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
"Missing device MAC address (no HWADDR tag present).");
goto done;
}
memset (&ipaddr, 0, sizeof (ipaddr));
memset (&gateway, 0, sizeof (gateway));
memset (&dns1, 0, sizeof (dns1));
memset (&dns2, 0, sizeof (dns2));
/* Success, lets parse the output */
lines = g_strsplit_set (out, "\n\r", -1);
for (iter = lines; iter && *iter; iter++) {
char *p;
if (!g_ascii_strcasecmp (*iter, "# BEGIN RECORD")) {
if (in_record) {
PARSE_WARNING ("malformed iscsiadm record: already parsing record.");
skip = TRUE;
}
} else if (!g_ascii_strcasecmp (*iter, "# END RECORD")) {
if (!skip && hwaddr_matched) {
/* Record is good; fill IP4 config with its info */
if (!method) {
PARSE_WARNING ("malformed iscsiadm record: missing BOOTPROTO.");
goto done;
}
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, method, NULL);
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
NMIP4Address *addr;
if (!ipaddr || !prefix) {
PARSE_WARNING ("malformed iscsiadm record: BOOTPROTO=static "
"but missing IP address or prefix.");
goto done;
}
addr = nm_ip4_address_new ();
nm_ip4_address_set_address (addr, ipaddr);
nm_ip4_address_set_prefix (addr, prefix);
nm_ip4_address_set_gateway (addr, gateway);
nm_setting_ip4_config_add_address (s_ip4, addr);
nm_ip4_address_unref (addr);
if (dns1)
nm_setting_ip4_config_add_dns (s_ip4, dns1);
if (dns2)
nm_setting_ip4_config_add_dns (s_ip4, dns2);
// FIXME: DNS search domains?
}
success = TRUE;
goto done;
}
skip = FALSE;
hwaddr_matched = FALSE;
memset (&ipaddr, 0, sizeof (ipaddr));
memset (&gateway, 0, sizeof (gateway));
memset (&dns1, 0, sizeof (dns1));
memset (&dns2, 0, sizeof (dns2));
prefix = 0;
method = NULL;
}
if (skip)
continue;
/* HWADDR */
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_HWADDR_TAG, &skip))) {
guint8 *ibft_mac[ETH_ALEN];
if (!nm_utils_hwaddr_aton (p, ibft_mac, ETH_ALEN)) {
PARSE_WARNING ("malformed iscsiadm record: invalid hwaddress.");
skip = TRUE;
continue;
}
if (!nm_utils_hwaddr_matches (ibft_mac, ETH_ALEN, ifcfg_mac->data, ifcfg_mac->len)) {
/* This record isn't for the current device, ignore it */
skip = TRUE;
continue;
}
/* Success, this record is for this device */
hwaddr_matched = TRUE;
}
/* BOOTPROTO */
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_BOOTPROTO_TAG, &skip))) {
if (!g_ascii_strcasecmp (p, "dhcp"))
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
else if (!g_ascii_strcasecmp (p, "static"))
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
else {
PARSE_WARNING ("malformed iscsiadm record: unknown BOOTPROTO '%s'.", p);
skip = TRUE;
continue;
}
}
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_IPADDR_TAG, &skip))) {
if (inet_pton (AF_INET, p, &ipaddr) < 1) {
PARSE_WARNING ("malformed iscsiadm record: invalid IP address '%s'.", p);
skip = TRUE;
continue;
}
}
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_SUBNET_TAG, &skip))) {
guint32 mask;
if (inet_pton (AF_INET, p, &mask) < 1) {
PARSE_WARNING ("malformed iscsiadm record: invalid subnet mask '%s'.", p);
skip = TRUE;
continue;
}
prefix = nm_utils_ip4_netmask_to_prefix (mask);
}
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_GATEWAY_TAG, &skip))) {
if (inet_pton (AF_INET, p, &gateway) < 1) {
PARSE_WARNING ("malformed iscsiadm record: invalid IP gateway '%s'.", p);
skip = TRUE;
continue;
}
}
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS1_TAG, &skip))) {
if (inet_pton (AF_INET, p, &dns1) < 1) {
PARSE_WARNING ("malformed iscsiadm record: invalid DNS1 address '%s'.", p);
skip = TRUE;
continue;
}
}
if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS2_TAG, &skip))) {
if (inet_pton (AF_INET, p, &dns2) < 1) {
PARSE_WARNING ("malformed iscsiadm record: invalid DNS2 address '%s'.", p);
skip = TRUE;
continue;
}
}
}
success = TRUE;
done:
if (ifcfg_mac)
g_byte_array_free (ifcfg_mac, TRUE);
g_strfreev (lines);
g_free (out);
g_free (err);
return success;
}
/* Returns TRUE on missing address or valid address */
static gboolean
read_ip4_address (shvarFile *ifcfg,
@ -1242,7 +997,6 @@ error:
static NMSetting *
make_ip4_setting (shvarFile *ifcfg,
const char *network_file,
const char *iscsiadm_path,
GError **error)
{
NMSettingIP4Config *s_ip4 = NULL;
@ -1294,16 +1048,6 @@ make_ip4_setting (shvarFile *ifcfg,
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
} else if (!g_ascii_strcasecmp (value, "static")) {
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
} else if (!g_ascii_strcasecmp (value, "ibft")) {
g_free (value);
g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, NULL);
/* iSCSI Boot Firmware Table: need to read values from the iSCSI
* firmware for this device and create the IP4 setting using those.
*/
if (fill_ip4_setting_from_ibft (ifcfg, s_ip4, iscsiadm_path, error))
return NM_SETTING (s_ip4);
g_object_unref (s_ip4);
return NULL;
} else if (!g_ascii_strcasecmp (value, "autoip")) {
g_free (value);
g_object_set (s_ip4,
@ -1600,7 +1344,6 @@ read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *netwo
static NMSetting *
make_ip6_setting (shvarFile *ifcfg,
const char *network_file,
const char *iscsiadm_path,
GError **error)
{
NMSettingIP6Config *s_ip6 = NULL;
@ -4724,7 +4467,6 @@ static NMSetting *
make_vlan_setting (shvarFile *ifcfg,
const char *file,
char **out_master,
NMSetting8021x **s_8021x,
GError **error)
{
NMSettingVlan *s_vlan = NULL;
@ -4866,7 +4608,7 @@ vlan_connection_from_ifcfg (const char *file,
}
nm_connection_add_setting (connection, con_setting);
vlan_setting = make_vlan_setting (ifcfg, file, &master, &s_8021x, error);
vlan_setting = make_vlan_setting (ifcfg, file, &master, error);
if (!vlan_setting) {
g_object_unref (connection);
return NULL;
@ -5006,7 +4748,6 @@ NMConnection *
connection_from_file (const char *filename,
const char *network_file, /* for unit tests only */
const char *test_type, /* for unit tests only */
const char *iscsiadm_path, /* for unit tests only */
char **out_unhandled,
char **out_keyfile,
char **out_routefile,
@ -5034,9 +4775,6 @@ connection_from_file (const char *filename,
if (!network_file)
network_file = SYSCONFDIR "/sysconfig/network";
if (!iscsiadm_path)
iscsiadm_path = "/sbin/iscsiadm";
ifcfg_name = utils_get_ifcfg_name (filename, TRUE);
if (!ifcfg_name) {
g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
@ -5057,6 +4795,17 @@ connection_from_file (const char *filename,
goto done;
}
/* iBFT is handled by the iBFT settings plugin */
bootproto = svGetValue (parsed, "BOOTPROTO", FALSE);
if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) {
if (out_ignore_error)
*out_ignore_error = TRUE;
g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
"Ignoring iBFT configuration");
g_free (bootproto);
goto done;
}
type = NULL;
devtype = svGetValue (parsed, "DEVICETYPE", FALSE);
@ -5151,7 +4900,7 @@ connection_from_file (const char *filename,
if (!connection)
goto done;
s_ip6 = make_ip6_setting (parsed, network_file, iscsiadm_path, error);
s_ip6 = make_ip6_setting (parsed, network_file, error);
if (!s_ip6) {
g_object_unref (connection);
connection = NULL;
@ -5159,7 +4908,7 @@ connection_from_file (const char *filename,
} else
nm_connection_add_setting (connection, s_ip6);
s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, error);
s_ip4 = make_ip4_setting (parsed, network_file, error);
if (!s_ip4) {
g_object_unref (connection);
connection = NULL;
@ -5193,22 +4942,6 @@ connection_from_file (const char *filename,
if (s_dcb)
nm_connection_add_setting (connection, s_dcb);
/* iSCSI / ibft connections are read-only since their settings are
* stored in NVRAM and can only be changed in BIOS.
*/
bootproto = svGetValue (parsed, "BOOTPROTO", FALSE);
if ( bootproto
&& connection
&& !g_ascii_strcasecmp (bootproto, "ibft")) {
NMSettingConnection *s_con;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL);
}
g_free (bootproto);
if (!nm_connection_normalize (connection, NULL, NULL, error)) {
g_object_unref (connection);
connection = NULL;

View file

@ -29,7 +29,6 @@
NMConnection *connection_from_file (const char *filename,
const char *network_file, /* for unit tests only */
const char *test_type, /* for unit tests only */
const char *iscsiadm_path, /* for unit tests only */
char **out_unhandled,
char **out_keyfile,
char **out_routefile,

View file

@ -50,15 +50,5 @@ test_ifcfg_rh_utils_LDADD = \
TESTS = test-ifcfg-rh-utils test-ifcfg-rh
EXTRA_DIST = \
iscsiadm-test-dhcp \
iscsiadm-test-static \
iscsiadm-test-bad-ipaddr \
iscsiadm-test-bad-gateway \
iscsiadm-test-bad-dns1 \
iscsiadm-test-bad-dns2 \
iscsiadm-test-bad-entry \
iscsiadm-test-bad-record
endif

View file

@ -61,8 +61,7 @@ EXTRA_DIST = \
ifcfg-test-wifi-hidden \
test_ca_cert.pem \
test1_key_and_cert.pem \
ifcfg-test-ibft-dhcp \
ifcfg-test-ibft-static \
ifcfg-test-ibft \
ifcfg-test-static-routes-legacy \
route-test-static-routes-legacy \
ifcfg-test-wired-static-routes \

View file

@ -0,0 +1,10 @@
# Generated by dracut initrd
DEVICE="ibft0"
ONBOOT=yes
NETBOOT=yes
UUID="2aa8c19d-9744-4ca4-b74f-c37e73f2918e"
BOOTPROTO=ibft
HWADDR="00:33:21:98:b9:f0"
TYPE=Ethernet
NAME="ibft0"

File diff suppressed because it is too large Load diff