/* * Property link_watch */ static dbus_bool_t __ni_objectmodel_team_get_link_watch(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_team_t *team; unsigned int i; if (!(team = __ni_objectmodel_team_read_handle(object, error))) return FALSE; if (!team->link_watch.count) return FALSE; ni_dbus_variant_init_dict(result); for (i = 0; i < team->link_watch.count; i++) { ni_team_link_watch_t *lw = team->link_watch.data[i]; ni_dbus_variant_t *entry; ni_dbus_variant_t *dict; const char *name; if (!(name = ni_team_link_watch_type_to_name(lw->type))) continue; entry = ni_dbus_dict_add(result, "watch"); ni_dbus_variant_init_struct(entry); ni_dbus_struct_add_string(entry, name); dict = ni_dbus_struct_add(entry); ni_dbus_variant_init_dict(dict); __ni_objectmodel_team_link_watch_to_dict(lw, dict, error, object, property); } return TRUE; }
/* * Filesystem.getInfo(path) * */ static dbus_bool_t __ni_Testbus_Agent_Filesystem_getInfo(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_dbus_variant_t res = NI_DBUS_VARIANT_INIT; struct stat stb; const char *path; dbus_bool_t rv; if (argc != 1 || !ni_dbus_variant_get_string(&argv[0], &path) || path[0] != '/') return ni_dbus_error_invalid_args(error, object->path, method->name); if (stat(path, &stb) < 0) { ni_dbus_set_error_from_errno(error, errno, "unable to stat file \"%s\"", path); return FALSE; } if (!S_ISREG(stb.st_mode)) { dbus_set_error(error, DBUS_ERROR_FAILED, "not a regular file"); return FALSE; } ni_dbus_variant_init_dict(&res); ni_dbus_dict_add_uint64(&res, "size", stb.st_size); rv = ni_dbus_message_serialize_variants(reply, 1, &res, error); ni_dbus_variant_destroy(&res); return rv; }
/* * get/set ethtool.wake-on-lan */ static dbus_bool_t ni_objectmodel_ethtool_get_wake_on_lan(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_ethtool_wake_on_lan_t *wol; const ni_ethtool_t *ethtool; if (!(ethtool = ni_objectmodel_ethtool_read_handle(object, error))) return FALSE; if (!(wol = ethtool->wake_on_lan)) return FALSE; if (wol->support == NI_ETHTOOL_WOL_DEFAULT || wol->support == NI_ETHTOOL_WOL_DISABLE) return FALSE; ni_dbus_variant_init_dict(result); ni_dbus_dict_add_uint32(result, "support", wol->support); if (wol->options != NI_ETHTOOL_WOL_DEFAULT) ni_dbus_dict_add_uint32(result, "options", wol->options); /* from config it is VOID, hide sopass from kernel with type ETHER */ if (wol->sopass.len && wol->sopass.type == ARPHRD_VOID && wol->sopass.len == ni_link_address_length(ARPHRD_ETHER)) __ni_objectmodel_dict_add_hwaddr(result, "sopass", &wol->sopass); return TRUE; }
static dbus_bool_t ni_objectmodel_ppp_config_get_ipv6(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_ppp_config_t *conf; ni_dbus_variant_t *ipcp; if (!(conf = ni_objectmodel_get_ppp_config(object, FALSE, error))) return FALSE; ni_dbus_dict_add_bool(result, "enabled", conf->ipv6.enabled); if (!conf->ipv6.enabled) return TRUE; if (ni_sockaddr_is_specified(&conf->ipv6.local_ip)) { if (!__ni_objectmodel_dict_add_sockaddr(result, "local-ip", &conf->ipv6.local_ip)) return FALSE; } if (ni_sockaddr_is_specified(&conf->ipv6.remote_ip)) { if (!__ni_objectmodel_dict_add_sockaddr(result, "remote-ip", &conf->ipv6.remote_ip)) return FALSE; } if (!(ipcp = ni_dbus_dict_add(result, "ipcp"))) return FALSE; ni_dbus_variant_init_dict(ipcp); ni_dbus_dict_add_bool(ipcp, "accept-local", conf->ipv6.ipcp.accept_local); return TRUE; }
static dbus_bool_t __ni_objectmodel_ovs_bridge_get_ports(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { ni_dbus_variant_t *dict; const ni_ovs_bridge_t *ovsbr; unsigned int i; ni_dbus_dict_array_init(result); if (!(ovsbr = __ni_objectmodel_ovs_bridge_read_handle(object, error))) return ni_dbus_error_property_not_present(error, object->path, property->name); for (i = 0; i < ovsbr->ports.count; ++i) { const ni_ovs_bridge_port_t *port = ovsbr->ports.data[i]; if (!port || ni_string_empty(port->device.name)) continue; if (!(dict = ni_dbus_dict_array_add(result))) return FALSE; ni_dbus_variant_init_dict(dict); if (!__ni_objectmodel_ovs_bridge_port_to_dict(port, dict, error)) return FALSE; } return TRUE; }
/* * Property ports */ static dbus_bool_t __ni_objectmodel_bridge_get_ports(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_bridge_t *bridge; unsigned int i; if (!(bridge = __ni_objectmodel_bridge_read_handle(object, error))) return FALSE; ni_dbus_dict_array_init(result); for (i = 0; i < bridge->ports.count; ++i) { const ni_bridge_port_t *port = bridge->ports.data[i]; ni_dbus_variant_t *dict; /* Append a new element to the array */ if (!(dict = ni_dbus_dict_array_add(result))) return FALSE; ni_dbus_variant_init_dict(dict); if (!__ni_objectmodel_bridge_port_to_dict(port, dict, object, 0)) return FALSE; } return TRUE; }
/* * Get the state of a dbus object as XML. * We do this by going via the dbus representation, which is a bit of a waste of * time but at least that saves me from writing lots of code, and it makes sure * that we have one canonical mapping. * In fact, this is a lot like doing a Properties.GetAll call... */ static ni_bool_t ni_objectmodel_save_object_state_xml(const ni_dbus_object_t *object, xml_node_t *parent) { const ni_dbus_service_t *service; xml_node_t *object_node; unsigned int i; int rv = TRUE; object_node = xml_node_new("object", parent); xml_node_add_attr(object_node, "path", object->path); for (i = 0; rv && (service = object->interfaces[i]) != NULL; ++i) { ni_dbus_variant_t dict = NI_DBUS_VARIANT_INIT; xml_node_t *prop_node; ni_dbus_variant_init_dict(&dict); rv = ni_dbus_object_get_properties_as_dict(object, service, &dict, NULL); if (rv && dict.array.len != 0) { /* serialize as XML */ prop_node = ni_dbus_xml_deserialize_properties(__ni_objectmodel_schema, service->name, &dict, object_node); if (!prop_node) rv = FALSE; } ni_dbus_variant_destroy(&dict); } return rv; }
/* * Filesystem.download(path, offset, count) * */ static dbus_bool_t __ni_Testbus_Agent_Filesystem_download(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_dbus_variant_t res = NI_DBUS_VARIANT_INIT; const char *path; uint64_t offset; uint32_t count; dbus_bool_t rv; ni_buffer_t *bp = NULL; int fd = -1; if (argc != 3 || !ni_dbus_variant_get_string(&argv[0], &path) || path[0] != '/' || !ni_dbus_variant_get_uint64(&argv[1], &offset) || !ni_dbus_variant_get_uint32(&argv[2], &count) || count > 1024 * 1024 || offset + count < offset) return ni_dbus_error_invalid_args(error, object->path, method->name); if ((fd = open(path, O_RDONLY)) < 0) { ni_dbus_set_error_from_errno(error, errno, "unable to open file \"%s\"", path); return FALSE; } if (lseek(fd, offset, SEEK_SET) < 0) { ni_dbus_set_error_from_errno(error, errno, "seek faile"); goto out_fail; } bp = ni_buffer_new(count); while (count) { int n; n = read(fd, ni_buffer_tail(bp), ni_buffer_tailroom(bp)); if (n < 0) { ni_dbus_set_error_from_errno(error, errno, "read failed"); goto out_fail; } if (n == 0) break; ni_buffer_push_tail(bp, n); } ni_dbus_variant_init_dict(&res); ni_dbus_variant_set_byte_array(&res, ni_buffer_head(bp), ni_buffer_count(bp)); rv = ni_dbus_message_serialize_variants(reply, 1, &res, error); ni_dbus_variant_destroy(&res); ni_buffer_free(bp); close(fd); return rv; out_fail: if (fd >= 0) close(fd); return FALSE; }
/* * This works a lot like the serialization code in xml-dbus, except we're not defining a * schema for this. * Used by the device identification code below. */ static void __ni_call_build_dict(ni_dbus_variant_t *var, const xml_node_t *query) { if (query->cdata) { ni_dbus_variant_set_string(var, query->cdata); } else if (query->children) { const xml_node_t *attr; ni_dbus_variant_init_dict(var); for (attr = query->children; attr; attr = attr->next) __ni_call_build_dict(ni_dbus_dict_add(var, attr->name), attr); } else { ni_warn("ni_call_identify_device: empty query attribute %s (%s)", query->name, xml_node_location(query)); } }
/* * OVS Bridge vlan */ static dbus_bool_t __ni_objectmodel_ovs_bridge_get_vlan(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_ovs_bridge_t *ovsbr; if (!(ovsbr = __ni_objectmodel_ovs_bridge_read_handle(object, error))) return ni_dbus_error_property_not_present(error, object->path, property->name); if (ni_string_empty(ovsbr->config.vlan.parent.name)) return ni_dbus_error_property_not_present(error, object->path, property->name); ni_dbus_variant_init_dict(result); ni_dbus_dict_add_string(result, "parent", ovsbr->config.vlan.parent.name); ni_dbus_dict_add_uint16(result, "tag", ovsbr->config.vlan.tag); return TRUE; }
static dbus_bool_t ni_objectmodel_ppp_get_mode(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { ni_dbus_variant_t *dict; const ni_ppp_t *ppp; const char *mode; if (!(ppp = ni_objectmodel_ppp_handle(object, FALSE, error))) return FALSE; if (NI_PPP_MODE_UNKNOWN == ppp->mode.type) return ni_dbus_error_property_not_present(error, object->path, property->name); if (!(mode = ni_ppp_mode_type_to_name(ppp->mode.type))) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "bad property %s; unsupported mode type %u", property->name, ppp->mode.type); return FALSE; } ni_dbus_variant_init_struct(result); ni_dbus_struct_add_string(result, mode); dict = ni_dbus_struct_add(result); ni_dbus_variant_init_dict(dict); switch (ppp->mode.type) { case NI_PPP_MODE_PPPOE: { const ni_ppp_mode_pppoe_t *pppoe = &ppp->mode.pppoe; if (!ni_string_empty(pppoe->device.name)) ni_dbus_dict_add_string(dict, "device", pppoe->device.name); } break; default: return FALSE; } return TRUE; }
static dbus_bool_t ni_objectmodel_ethtool_get_link_settings(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_ethtool_link_settings_t *link; if (!(link = ni_objectmodel_ethtool_link_settings_read_handle(object, error))) return FALSE; ni_dbus_variant_init_dict(result); if (ni_tristate_is_set(link->autoneg)) ni_dbus_dict_add_int32(result, "autoneg", link->autoneg); if (link->speed != NI_ETHTOOL_SPEED_UNKNOWN) ni_dbus_dict_add_uint32(result, "speed", link->speed); if (link->duplex != NI_ETHTOOL_DUPLEX_UNKNOWN) ni_dbus_dict_add_uint32(result, "duplex", link->duplex); if (link->port != NI_ETHTOOL_PORT_DEFAULT) ni_dbus_dict_add_uint32(result, "port", link->port); if (link->port == NI_ETHTOOL_PORT_TP && link->tp_mdix) ni_dbus_dict_add_uint32(result, "mdix", link->tp_mdix); if (link->mdio_support != NI_ETHTOOL_MDI_INVALID) ni_dbus_dict_add_uint32(result, "mdio", link->mdio_support); if (link->phy_address != NI_ETHTOOL_PHYAD_UNKNOWN) ni_dbus_dict_add_uint32(result, "phy-address", link->phy_address); if (link->transceiver != NI_ETHTOOL_XCVR_UNKNOWN) ni_dbus_dict_add_uint32(result, "transceiver", link->transceiver); ni_objectmodel_ethtool_link_adv_into_dict(result, "supported", &link->supported); ni_objectmodel_ethtool_link_adv_into_dict(result, "advertising", &link->advertising); ni_objectmodel_ethtool_link_adv_into_dict(result, "lp-advertising", &link->lp_advertising); return TRUE; }
static dbus_bool_t ni_objectmodel_ethtool_link_adv_into_dict(ni_dbus_variant_t *dict, const char *name, const ni_bitfield_t *bitfield) { ni_bitfield_t tmpfield = NI_BITFIELD_INIT; ni_dbus_variant_t *child; if (!dict || ni_string_empty(name) || !ni_bitfield_bits(bitfield)) return FALSE; if (!(child = ni_dbus_dict_add(dict, name))) return FALSE; ni_dbus_variant_init_dict(child); ni_bitfield_set_data(&tmpfield, ni_bitfield_get_data(bitfield), ni_bitfield_bytes(bitfield)); ni_objectmodel_ethtool_link_adv_autoneg_into_dict(child, &tmpfield); ni_objectmodel_ethtool_link_adv_ports_into_dict(child, &tmpfield); ni_objectmodel_ethtool_link_adv_speed_into_dict(child, &tmpfield); ni_objectmodel_ethtool_link_adv_pause_into_dict(child, &tmpfield); ni_objectmodel_ethtool_link_adv_fec_modes_into_dict(child, &tmpfield); ni_objectmodel_ethtool_link_adv_unknown_into_dict(child, &tmpfield); ni_bitfield_destroy(&tmpfield); return TRUE; }
/* * Property ports (array) */ static dbus_bool_t __ni_objectmodel_team_get_ports(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { ni_dbus_variant_t *dict; const ni_team_t *team; unsigned int i; if (!(team = __ni_objectmodel_team_read_handle(object, error))) return FALSE; ni_dbus_dict_array_init(result); for (i = 0; i < team->ports.count; ++i) { const ni_team_port_t *port = team->ports.data[i]; if (!(dict = ni_dbus_dict_array_add(result))) return FALSE; ni_dbus_variant_init_dict(dict); if (!__ni_objectmodel_team_port_to_dict(port, dict, error)) return FALSE; } return TRUE; }
static dbus_bool_t __ni_objectmodel_team_get_runner(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { ni_dbus_variant_t *dict; const ni_team_t *team; const char *name; if (!(team = __ni_objectmodel_team_read_handle(object, error))) return FALSE; if (!team->runner.type) return ni_dbus_error_property_not_present(error, object->path, property->name); if (!(name = ni_team_runner_type_to_name(team->runner.type))) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "bad property %s; unsupported runner name type %u", property->name, team->runner.type); return FALSE; } ni_dbus_variant_init_struct(result); ni_dbus_struct_add_string(result, name); dict = ni_dbus_struct_add(result); ni_dbus_variant_init_dict(dict); switch (team->runner.type) { case NI_TEAM_RUNNER_ACTIVE_BACKUP: { const ni_team_runner_active_backup_t *ab = &team->runner.ab; ni_dbus_dict_add_uint32(dict, "hwaddr_policy", ab->config.hwaddr_policy); } break; case NI_TEAM_RUNNER_LOAD_BALANCE: { const ni_team_runner_load_balance_t *lb = &team->runner.lb; ni_dbus_variant_t *txb; ni_dbus_dict_add_uint32(dict, "tx_hash", lb->config.tx_hash); txb = ni_dbus_dict_add(dict, "tx_balancer"); ni_dbus_variant_init_dict(txb); ni_dbus_dict_add_uint32(txb, "name", lb->config.tx_balancer.type); ni_dbus_dict_add_uint32(txb, "balancing_interval", lb->config.tx_balancer.interval); } break; case NI_TEAM_RUNNER_ROUND_ROBIN: break; case NI_TEAM_RUNNER_BROADCAST: break; case NI_TEAM_RUNNER_RANDOM: break; case NI_TEAM_RUNNER_LACP: { const ni_team_runner_lacp_t *lacp = &team->runner.lacp; ni_dbus_variant_t *txb; ni_dbus_dict_add_bool(dict, "active", lacp->config.active); ni_dbus_dict_add_bool(dict, "fast_rate", lacp->config.fast_rate); ni_dbus_dict_add_uint16(dict, "sys_prio", lacp->config.sys_prio); ni_dbus_dict_add_uint16(dict, "min_ports", lacp->config.min_ports); ni_dbus_dict_add_uint32(dict, "select_policy", lacp->config.select_policy); ni_dbus_dict_add_uint32(dict, "tx_hash", lacp->config.tx_hash); txb = ni_dbus_dict_add(dict, "tx_balancer"); ni_dbus_variant_init_dict(txb); ni_dbus_dict_add_uint32(txb, "name", lacp->config.tx_balancer.type); ni_dbus_dict_add_uint32(txb, "balancing_interval", lacp->config.tx_balancer.interval); } break; default: return FALSE; } return TRUE; }