ifcfg: merge branch 'th/ifcfg-simple-dbus'

https://github.com/NetworkManager/NetworkManager/pull/63
This commit is contained in:
Thomas Haller 2018-02-12 13:29:27 +01:00
commit be1d8c842f
5 changed files with 184 additions and 76 deletions

View file

@ -2081,8 +2081,7 @@ src_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = \
-Wl,--version-script="$(srcdir)/linker-script-settings.ver"
src_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_LIBADD = \
src/settings/plugins/ifcfg-rh/libnms-ifcfg-rh-core.la \
src/settings/plugins/ifcfg-rh/libnmdbus-ifcfg-rh.la
src/settings/plugins/ifcfg-rh/libnms-ifcfg-rh-core.la
$(src_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): src/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h
$(src_settings_plugins_ifcfg_rh_libnm_settings_plugin_ifcfg_rh_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums)

View file

@ -389,6 +389,28 @@ NM_G_ERROR_MSG (GError *error)
#define NM_CONSTCAST(type, obj, ...) \
NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__)
#if _NM_CC_SUPPORT_GENERIC
#define NM_UNCONST_PTR(type, arg) \
_Generic ((arg), \
const type *: ((type *) (arg)), \
type *: ((type *) (arg)))
#else
#define NM_UNCONST_PTR(type, arg) \
((type *) (arg))
#endif
#if _NM_CC_SUPPORT_GENERIC
#define NM_UNCONST_PPTR(type, arg) \
_Generic ((arg), \
const type * *: ((type **) (arg)), \
type * *: ((type **) (arg)), \
const type *const*: ((type **) (arg)), \
type *const*: ((type **) (arg)))
#else
#define NM_UNCONST_PPTR(type, arg) \
((type **) (arg))
#endif
#define NM_GOBJECT_CAST(type, obj, is_check, ...) \
({ \
const void *_obj = (obj); \
@ -1296,6 +1318,25 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro)
/*****************************************************************************/
/**
* nm_steal_int:
* @p_val: pointer to an int type.
*
* Returns: *p_val and sets *p_val to zero the same time.
* Accepts %NULL, in which case also numeric 0 will be returned.
*/
#define nm_steal_int(p_val) \
({ \
typeof (p_val) const _p_val = (p_val); \
typeof (*_p_val) _val = 0; \
\
if ( _p_val \
&& (_val = *_p_val)) { \
*_p_val = 0; \
} \
_val; \
})
static inline int
nm_steal_fd (int *p_fd)
{

View file

@ -469,4 +469,39 @@ int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
/*****************************************************************************/
#define NM_DEFINE_GDBUS_ARG_INFO(a_name, ...) \
((GDBusArgInfo *) (&((const GDBusArgInfo) { \
.ref_count = -1, \
.name = a_name, \
__VA_ARGS__ \
})))
#define NM_DEFINE_GDBUS_ARG_INFOS(...) \
((GDBusArgInfo **) ((const GDBusArgInfo *[]) { \
__VA_ARGS__ \
NULL, \
}))
#define NM_DEFINE_GDBUS_METHOD_INFO(m_name, ...) \
((GDBusMethodInfo *) (&((const GDBusMethodInfo) { \
.ref_count = -1, \
.name = m_name, \
__VA_ARGS__ \
})))
#define NM_DEFINE_GDBUS_METHOD_INFOS(...) \
((GDBusMethodInfo **) ((const GDBusMethodInfo *[]) { \
__VA_ARGS__ \
NULL, \
}))
#define NM_DEFINE_GDBUS_INTERFACE_INFO(variable, i_name, ...) \
static GDBusInterfaceInfo *const variable = ((GDBusInterfaceInfo *) (&((const GDBusInterfaceInfo) { \
.ref_count = -1, \
.name = i_name, \
__VA_ARGS__ \
})))
/*****************************************************************************/
#endif /* __NM_SHARED_UTILS_H__ */

View file

@ -204,51 +204,35 @@ _method_call (GDBusConnection *connection,
g_dbus_method_invocation_return_value (invocation, NULL);
}
NM_DEFINE_GDBUS_INTERFACE_INFO (
interface_info,
NM_DHCP_HELPER_SERVER_INTERFACE_NAME,
.methods = NM_DEFINE_GDBUS_METHOD_INFOS (
NM_DEFINE_GDBUS_METHOD_INFO (
NM_DHCP_HELPER_SERVER_METHOD_NOTIFY,
.in_args = NM_DEFINE_GDBUS_ARG_INFOS (
NM_DEFINE_GDBUS_ARG_INFO (
"data",
.signature = "a{sv}",
),
),
),
),
);
static guint
_dbus_connection_register_object (NMDhcpListener *self,
GDBusConnection *connection,
GError **error)
{
static GDBusArgInfo arg_info_notify_in = {
.ref_count = -1,
.name = "data",
.signature = "a{sv}",
.annotations = NULL,
};
static GDBusArgInfo *arg_infos_notify[] = {
&arg_info_notify_in,
NULL,
};
static GDBusMethodInfo method_info_notify = {
.ref_count = -1,
.name = NM_DHCP_HELPER_SERVER_METHOD_NOTIFY,
.in_args = arg_infos_notify,
.out_args = NULL,
.annotations = NULL,
};
static GDBusMethodInfo *method_infos[] = {
&method_info_notify,
NULL,
};
static GDBusInterfaceInfo interface_info = {
.ref_count = -1,
.name = NM_DHCP_HELPER_SERVER_INTERFACE_NAME,
.methods = method_infos,
.signals = NULL,
.properties = NULL,
.annotations = NULL,
};
static GDBusInterfaceVTable interface_vtable = {
static const GDBusInterfaceVTable interface_vtable = {
.method_call = _method_call,
.get_property = NULL,
.set_property = NULL,
};
return g_dbus_connection_register_object (connection,
NM_DHCP_HELPER_SERVER_OBJECT_PATH,
&interface_info,
&interface_vtable,
interface_info,
NM_UNCONST_PTR (GDBusInterfaceVTable, &interface_vtable),
self,
NULL,
error);

View file

@ -46,10 +46,10 @@
#include "nms-ifcfg-rh-utils.h"
#include "shvar.h"
#include "settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.h"
#define IFCFGRH1_DBUS_SERVICE_NAME "com.redhat.ifcfgrh1"
#define IFCFGRH1_DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1"
#define IFCFGRH1_BUS_NAME "com.redhat.ifcfgrh1"
#define IFCFGRH1_OBJECT_PATH "/com/redhat/ifcfgrh1"
#define IFCFGRH1_IFACE1_NAME "com.redhat.ifcfgrh1"
#define IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS "GetIfcfgDetails"
/*****************************************************************************/
@ -58,9 +58,9 @@ typedef struct {
struct {
GDBusConnection *connection;
GDBusInterfaceSkeleton *interface;
GCancellable *cancellable;
gulong signal_id;
guint regist_id;
} dbus;
GHashTable *connections; /* uuid::connection */
@ -768,15 +768,15 @@ static void
_dbus_clear (SettingsPluginIfcfg *self)
{
SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self);
guint id;
nm_clear_g_signal_handler (priv->dbus.connection, &priv->dbus.signal_id);
nm_clear_g_cancellable (&priv->dbus.cancellable);
if (priv->dbus.interface) {
g_dbus_interface_skeleton_unexport (priv->dbus.interface);
nm_exported_object_skeleton_release (priv->dbus.interface);
priv->dbus.interface = NULL;
if ((id = nm_steal_int (&priv->dbus.regist_id))) {
if (!g_dbus_connection_unregister_object (priv->dbus.connection, id))
_LOGW ("dbus: unexpected failure to unregister object");
}
g_clear_object (&priv->dbus.connection);
@ -788,12 +788,65 @@ _dbus_connection_closed (GDBusConnection *connection,
GError *error,
gpointer user_data)
{
_LOGW ("dbus: %s bus closed", IFCFGRH1_DBUS_SERVICE_NAME);
_LOGW ("dbus: %s bus closed", IFCFGRH1_BUS_NAME);
_dbus_clear (SETTINGS_PLUGIN_IFCFG (user_data));
/* Retry or recover? */
}
static void
_method_call (GDBusConnection *connection,
const char *sender,
const char *object_path,
const char *interface_name,
const char *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
SettingsPluginIfcfg *self = SETTINGS_PLUGIN_IFCFG (user_data);
const char *ifcfg;
if (nm_streq0 (interface_name, IFCFGRH1_IFACE1_NAME)) {
if (nm_streq0 (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) {
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)")))
g_return_if_reached ();
g_variant_get (parameters, "(&s)", &ifcfg);
impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg);
return;
}
}
g_return_if_reached ();
}
NM_DEFINE_GDBUS_INTERFACE_INFO (
interface_info,
IFCFGRH1_BUS_NAME,
.methods = NM_DEFINE_GDBUS_METHOD_INFOS (
NM_DEFINE_GDBUS_METHOD_INFO (
IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS,
.in_args = NM_DEFINE_GDBUS_ARG_INFOS (
NM_DEFINE_GDBUS_ARG_INFO (
"ifcfg",
.signature = "s",
),
),
.out_args = NM_DEFINE_GDBUS_ARG_INFOS (
NM_DEFINE_GDBUS_ARG_INFO (
"uuid",
.signature = "s",
),
NM_DEFINE_GDBUS_ARG_INFO (
"path",
.signature = "o",
),
),
),
),
);
static void
_dbus_request_name_done (GObject *source_object,
GAsyncResult *res,
@ -830,36 +883,27 @@ _dbus_request_name_done (GObject *source_object,
}
{
GType skeleton_type = NMDBUS_TYPE_IFCFGRH1_SKELETON;
gs_free char *method_name_get_ifcfg_details = NULL;
NMExportedObjectDBusMethodImpl methods[] = {
{
.method_name = (method_name_get_ifcfg_details = nm_exported_object_skeletonify_method_name ("GetIfcfgDetails")),
.impl = G_CALLBACK (impl_ifcfgrh_get_ifcfg_details),
},
static const GDBusInterfaceVTable interface_vtable = {
.method_call = _method_call,
};
priv->dbus.interface = nm_exported_object_skeleton_create (skeleton_type,
g_type_class_peek (SETTINGS_TYPE_PLUGIN_IFCFG),
methods,
G_N_ELEMENTS (methods),
(GObject *) self);
if (!g_dbus_interface_skeleton_export (priv->dbus.interface,
priv->dbus.connection,
IFCFGRH1_DBUS_OBJECT_PATH,
&error)) {
nm_exported_object_skeleton_release (priv->dbus.interface);
priv->dbus.interface = NULL;
_LOGW ("dbus: failed exporting interface: %s", error->message);
priv->dbus.regist_id = g_dbus_connection_register_object (connection,
IFCFGRH1_OBJECT_PATH,
interface_info,
NM_UNCONST_PTR (GDBusInterfaceVTable, &interface_vtable),
self,
NULL,
&error);
if (!priv->dbus.regist_id) {
_LOGW ("dbus: couldn't register D-Bus service: %s", error->message);
_dbus_clear (self);
return;
}
}
_LOGD ("dbus: aquired D-Bus service %s and exported %s object",
IFCFGRH1_DBUS_SERVICE_NAME,
IFCFGRH1_DBUS_OBJECT_PATH);
IFCFGRH1_BUS_NAME,
IFCFGRH1_OBJECT_PATH);
}
static void
@ -900,7 +944,7 @@ _dbus_create_done (GObject *source_object,
DBUS_INTERFACE_DBUS,
"RequestName",
g_variant_new ("(su)",
IFCFGRH1_DBUS_SERVICE_NAME,
IFCFGRH1_BUS_NAME,
DBUS_NAME_FLAG_DO_NOT_QUEUE),
G_VARIANT_TYPE ("(u)"),
G_DBUS_CALL_FLAGS_NONE,
@ -917,7 +961,7 @@ _dbus_setup (SettingsPluginIfcfg *self)
gs_free char *address = NULL;
gs_free_error GError *error = NULL;
g_return_if_fail (!priv->dbus.connection);
_dbus_clear (self);
address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (address == NULL) {
@ -943,17 +987,22 @@ config_changed_cb (NMConfig *config,
NMConfigData *old_data,
SettingsPluginIfcfg *self)
{
SettingsPluginIfcfgPrivate *priv;
/* If the dbus connection for some reason is borked the D-Bus service
* won't be offered.
*
* On SIGHUP and SIGUSR1 try to re-connect to D-Bus. So in the unlikely
* event that the D-Bus conneciton is broken, that allows for recovery
* without need for restarting NetworkManager. */
if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP
| NM_CONFIG_CHANGE_CAUSE_SIGUSR1)) {
if (!SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self)->dbus.connection)
_dbus_setup (self);
}
if (!NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP
| NM_CONFIG_CHANGE_CAUSE_SIGUSR1))
return;
priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (self);
if ( !priv->dbus.connection
&& !priv->dbus.cancellable)
_dbus_setup (self);
}
/*****************************************************************************/