[PATCH phosphor-settingsd] Move settings to c code
OpenBMC Patches
openbmc-patches at stwcx.xyz
Sat Jan 30 09:50:31 AEDT 2016
From: Chris Austen <austenc at us.ibm.com>
This gets the boot_list and PowerCap settings exposed
on the dbus.
Examples of how to now interact...
$ curl -c cjar -b cjar -k https://x.x.x.x/org/openbmc/settings/host0
{
"data": {
"boot_mode_list": [
"Default",
"Network",
"Disk",
"Safe",
"CDROM",
"Setup"
],
"current_boot_mode": "Default",
"power_cap_default": 999,
"power_cap_max": 1000,
"power_cap_min": 1,
"power_cap_now": 998
},
"message": "200 OK",
"status": "ok"
}
View a single property
curl -c cjar -b cjar -k https://192.168.7.2/org/openbmc/settings/host0/attr/Current_boot_mode
Make the Network the current boot device
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X POST -d "{\"data\": [\"CDROM\"]}" https://x.x.x.x/org/openbmc/settings/host0/action/setBootMode
Set the powercap to 42
curl -c cjar -b cjar -k -H "Content-Type: application/json" -X POST -d "{\"data\": [42]}" https://x.x.x.x/org/openbmc/settings/host0/action/setPowerCap
---
Makefile | 22 ++++++
settings_file.py | 2 -
settings_manager.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++
settings_manager.py | 87 ----------------------
settings_parser.py | 20 -----
5 files changed, 228 insertions(+), 109 deletions(-)
create mode 100644 Makefile
delete mode 100644 settings_file.py
create mode 100644 settings_manager.c
delete mode 100755 settings_manager.py
delete mode 100755 settings_parser.py
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5d00300
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+
+EXE = settings_manager
+
+OBJS = $(EXE).o \
+
+
+DEPPKGS = libsystemd
+CC ?= $(CROSS_COMPILE)gcc
+INCLUDES += $(shell pkg-config --cflags $(DEPPKGS))
+LIBS += $(shell pkg-config --libs $(DEPPKGS))
+CFLAGS += -Wall
+
+all: $(EXE)
+
+%.o : %.c
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@
+
+$(EXE): $(OBJS)
+ $(CC) $^ $(LDFLAGS) $(LIBS) -o $@
+
+clean:
+ rm -f $(OBJS) $(EXE) *.o
diff --git a/settings_file.py b/settings_file.py
deleted file mode 100644
index e05bc31..0000000
--- a/settings_file.py
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/python -u
-SETTINGS={'host': {'bootflags': {'default': '0000000000', 'type': 's', 'name': 'boot_flags'}, 'powercap': {'name': 'power_cap', 'min': 0, 'default': 0, 'max': 1000, 'type': 'i', 'unit': 'watts'}, 'sysstate': {'default': '', 'type': 's', 'name': 'system_state'}}}
\ No newline at end of file
diff --git a/settings_manager.c b/settings_manager.c
new file mode 100644
index 0000000..7125cb8
--- /dev/null
+++ b/settings_manager.c
@@ -0,0 +1,206 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h>
+#include <systemd/sd-bus.h>
+
+const char *gService = "org.openbmc.settings.Host";
+const char *gObjPath = "/org/openbmc/settings/host0";
+const char *gIntPath = "org.openbmc.Settings";
+
+
+typedef struct _settings_t {
+ char* currentBootMode;
+ int32_t powercap;
+ int32_t powercap_min;
+ int32_t powercap_max;
+ int32_t powercap_default;
+} settings_t;
+
+#define MAX_BOOT_MODES 6
+char gPossibleBootModes[MAX_BOOT_MODES][10] = {
+ "Default",
+ "Network",
+ "Disk",
+ "Safe",
+ "CDROM",
+ "Setup"
+};
+
+static int method_boot_mode_list(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ int r, i=0;
+
+ printf("Building boot mode list\n");
+
+ r = sd_bus_message_open_container(reply, 'a', "s");
+ if (r < 0)
+ return r;
+
+ for (i=0;i<MAX_BOOT_MODES;i++) {
+ r = sd_bus_message_append(reply, "s", gPossibleBootModes[i]);
+ if (r < 0) {
+ fprintf(stderr, "Failed to build the list of failed boot modes: %s", strerror(-r));
+ return r;
+ }
+ }
+
+ return sd_bus_message_close_container(reply);
+}
+
+static int method_setBootMode(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+
+ int i, r=-1;
+ char *str;
+ settings_t *settings = (settings_t *) userdata;
+
+ printf("Setting boot mode list\n");
+
+ r = sd_bus_message_read(m, "s", &str);
+ if (r < 0) {
+ fprintf(stderr, "Failed to extract string: %s", strerror(-r));
+ goto final;
+ }
+
+ for (i=0;i<MAX_BOOT_MODES;i++) {
+ if(!strcmp(gPossibleBootModes[i], str)) {
+ settings->currentBootMode = &gPossibleBootModes[i][0];
+ break;
+ }
+ }
+
+ if (i == MAX_BOOT_MODES) {
+ // Getting here means string of what
+ // they wanted did not map to anything
+ r = -1;
+ }
+
+ final:
+ return sd_bus_reply_method_return(m, "i", r);
+}
+
+
+static int method_setPowerCap(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+
+ int r;
+ int32_t pcap;
+ settings_t *settings = (settings_t *) userdata;
+
+ printf("Setting Power Cap\n");
+
+ r = sd_bus_message_read(m, "i", &pcap);
+ if (r < 0) {
+ fprintf(stderr, "Failed to extract data: %s", strerror(-r));
+ } else {
+
+ if ((pcap <= settings->powercap_max) &&
+ (pcap >= settings->powercap_min)) {
+ settings->powercap = pcap;
+ } else {
+ return sd_bus_reply_method_error(m,&SD_BUS_ERROR_MAKE_CONST( \
+ SD_BUS_ERROR_INVALID_ARGS, \
+ "value not supported"));
+ }
+ }
+
+ return sd_bus_reply_method_return(m, "i", r);
+}
+
+static const sd_bus_vtable vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("setBootMode", "s", "i", method_setBootMode, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("setPowerCap", "i", "i", method_setPowerCap, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_PROPERTY("current_boot_mode", "s", NULL, offsetof(settings_t, currentBootMode), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("boot_mode_list", "as", method_boot_mode_list, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("power_cap_now", "i", NULL, offsetof(settings_t, powercap), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("power_cap_min", "i", NULL, offsetof(settings_t, powercap_min), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("power_cap_max", "i", NULL, offsetof(settings_t, powercap_max), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("power_cap_default", "i", NULL, offsetof(settings_t, powercap_default), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_VTABLE_END
+};
+
+
+void init_settings(settings_t *p) {
+
+ // Someday there will be a file that the defaults can come from
+ // This stuff for now is completely fake and doesn't do anything.
+ // Simply the place holder to make it easier for the pcap to be
+ // set
+ settings_t t = {
+ gPossibleBootModes[0],
+ 998, 1, 1000, 999
+ };
+
+ memcpy(p,&t,sizeof(settings_t));
+
+ return;
+}
+
+int start_HostSettingsService(void) {
+
+ sd_bus *bus;
+ sd_bus_slot *slot;
+ int r;
+ settings_t settings;
+
+ init_settings(&settings);
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0) {
+ fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
+ goto finish;
+ }
+
+ /* Install the object */
+ r = sd_bus_add_object_vtable(bus,
+ &slot,
+ gObjPath,
+ gIntPath,
+ vtable,
+ &settings);
+ if (r < 0) {
+ fprintf(stderr, "Failed to issue method call: %s\n", strerror(-r));
+ goto finish;
+ }
+
+ /* Take a well-known service name so that clients can find us */
+ r = sd_bus_request_name(bus, gService, 0);
+ if (r < 0) {
+ fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r));
+ goto finish;
+ }
+
+
+ for (;;) {
+ r = sd_bus_process(bus, NULL);
+ if (r < 0) {
+ fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
+ goto finish;
+ }
+
+ if (r > 0)
+ continue;
+
+ r = sd_bus_wait(bus, (uint64_t) -1);
+ if (r < 0) {
+ fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r));
+ goto finish;
+ }
+ }
+ finish:
+ sd_bus_unref(bus);
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+
+int main(int argc, char *argv[]) {
+
+ return start_HostSettingsService();
+}
\ No newline at end of file
diff --git a/settings_manager.py b/settings_manager.py
deleted file mode 100755
index e49b466..0000000
--- a/settings_manager.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/python -u
-
-import gobject
-import dbus
-import dbus.service
-import dbus.mainloop.glib
-import os
-import os.path as path
-import Openbmc
-import settings_file as s
-
-DBUS_NAME = 'org.openbmc.settings.Host'
-OBJ_NAME = '/org/openbmc/settings/host0'
-CONTROL_INTF = 'org.openbmc.Settings'
-
-class HostSettingsObject(Openbmc.DbusProperties):
- def __init__(self, bus, name, settings, path):
- Openbmc.DbusProperties.__init__(self)
- dbus.service.Object.__init__(self, bus, name)
-
- self.path = path
- if not os.path.exists(path):
- os.mkdir(path)
-
- # Listen to changes in the property values and sync them to the BMC
- bus.add_signal_receiver(self.settings_signal_handler,
- dbus_interface = "org.freedesktop.DBus.Properties",
- signal_name = "PropertiesChanged",
- path = "/org/openbmc/settings/host0")
-
- # Create the dbus properties
- for i in settings['host'].iterkeys():
- shk = settings['host'][i]
- self.set_settings_property(shk['name'],
- shk['type'],
- shk['default'])
-
- def get_bmc_value(self, name):
- try:
- with open(path.join(self.path, name), 'r') as f:
- return f.read()
- except (IOError):
- pass
- return None
-
- # Create dbus properties based on bmc value. This will be either a value
- # previously set, or the default file value if the BMC value does not exist.
- def set_settings_property(self, name, type, value):
- bmcv = self.get_bmc_value(name)
- if bmcv:
- value = bmcv
- if type=="i":
- self.Set(DBUS_NAME, name, value)
- elif type=="s":
- self.Set(DBUS_NAME, name, str(value))
-
- # Save the settings to the BMC. This will write the settings value in
- # individual files named by the property name to the BMC.
- def set_system_settings(self, name, value):
- bmcv = self.get_bmc_value(name)
- if bmcv != value:
- filepath = path.join(self.path, name)
- with open(filepath, 'w') as f:
- f.write(str(value))
-
- # Signal handler for when one ore more settings properties were updated.
- # This will sync the changes to the BMC.
- def settings_signal_handler(self, interface_name, changed_properties, invalidated_properties):
- for name, value in changed_properties.items():
- self.set_system_settings(name, value)
-
- # Placeholder signal. Needed to register the settings interface.
- @dbus.service.signal(DBUS_NAME, signature='s')
- def SettingsUpdated(self, sname):
- pass
-
-if __name__ == '__main__':
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
- bus = Openbmc.getDBus()
- name = dbus.service.BusName(DBUS_NAME, bus)
- obj = HostSettingsObject(bus, OBJ_NAME, s.SETTINGS, "/var/lib/obmc/")
- mainloop = gobject.MainLoop()
-
- print "Running HostSettingsService"
- mainloop.run()
-
diff --git a/settings_parser.py b/settings_parser.py
deleted file mode 100755
index 46bb474..0000000
--- a/settings_parser.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python -u
-
-# Simple parser to create a python dictionary from a yaml file.
-# It saves the applications from doing the parsing and
-# adding dependencies to additional modules like yaml
-
-import yaml
-
-SETTINGS_FILE = 'settings.yaml'
-OUTPUT_FILE = 'settings_file.py'
-FILE_HEADER = '#!/usr/bin/python -u'
-
-with open(SETTINGS_FILE) as s:
- data = yaml.safe_load(s)
-
-with open(OUTPUT_FILE, 'w') as f:
- f.write(FILE_HEADER)
- f.write('\n')
- f.write('SETTINGS=')
- f.write(str(data))
--
2.6.4
More information about the openbmc
mailing list