diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-08-23 10:47:19 -0400 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2016-08-30 16:06:39 +0000 |
commit | 059cffb8749a6f95cbc422840adce67de7674401 (patch) | |
tree | 849a3fb076acfec55ed83e7c0d8edafbc731accd /op-pwrctl | |
parent | ed1368dab8568edabb6aa8baacfb90e661997cbd (diff) | |
download | talos-skeleton-059cffb8749a6f95cbc422840adce67de7674401.tar.gz talos-skeleton-059cffb8749a6f95cbc422840adce67de7674401.zip |
pwrctl: add pgood state switching application
pgood_wait simply blocks until the power state changes to
the requested state.
The intent is for use from a systemd unit similar to nm-online.
Change-Id: Icf1e18f5d47d6eb2fc424b4614fd196ef3dfd6ee
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'op-pwrctl')
-rw-r--r-- | op-pwrctl/Makefile | 1 | ||||
-rw-r--r-- | op-pwrctl/pgood_wait/.gitignore | 1 | ||||
-rw-r--r-- | op-pwrctl/pgood_wait/Makefile | 5 | ||||
-rw-r--r-- | op-pwrctl/pgood_wait/pgood_wait.c | 183 |
4 files changed, 190 insertions, 0 deletions
diff --git a/op-pwrctl/Makefile b/op-pwrctl/Makefile index b1188ae..dd11965 100644 --- a/op-pwrctl/Makefile +++ b/op-pwrctl/Makefile @@ -1,3 +1,4 @@ BINS=power_control +SUBDIRS=pgood_wait include ../gdbus.mk include ../rules.mk diff --git a/op-pwrctl/pgood_wait/.gitignore b/op-pwrctl/pgood_wait/.gitignore new file mode 100644 index 0000000..fbc938c --- /dev/null +++ b/op-pwrctl/pgood_wait/.gitignore @@ -0,0 +1 @@ +pgood_wait diff --git a/op-pwrctl/pgood_wait/Makefile b/op-pwrctl/pgood_wait/Makefile new file mode 100644 index 0000000..c54382e --- /dev/null +++ b/op-pwrctl/pgood_wait/Makefile @@ -0,0 +1,5 @@ +BINS=pgood_wait +BIN_SUFFIX="" +LDLIBS=-lmapper +include ../../sdbus.mk +include ../../rules.mk diff --git a/op-pwrctl/pgood_wait/pgood_wait.c b/op-pwrctl/pgood_wait/pgood_wait.c new file mode 100644 index 0000000..949776d --- /dev/null +++ b/op-pwrctl/pgood_wait/pgood_wait.c @@ -0,0 +1,183 @@ +/** + * Copyright © 2016 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <systemd/sd-bus.h> +#include <systemd/sd-event.h> +#include <mapper.h> + +static void quit(int r, void *loop) +{ + sd_event_exit((sd_event *)loop, r); +} + +static int callback(sd_bus_message *m, void *user, sd_bus_error *error) +{ + sd_event *loop = user; + int r; + char *property = NULL; + + r = sd_bus_message_skip(m, "s"); + if (r < 0) { + fprintf(stderr, "Error skipping message fields: %s\n", + strerror(-r)); + quit(r, loop); + return r; + } + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); + if (r < 0) { + fprintf(stderr, "Error entering container: %s\n", + strerror(-r)); + quit(r, loop); + return r; + } + + while((r = sd_bus_message_enter_container( + m, + SD_BUS_TYPE_DICT_ENTRY, + "sv")) > 0) { + r = sd_bus_message_read(m, "s", &property); + if (r < 0) { + fprintf(stderr, "Error reading message: %s\n", + strerror(-r)); + quit(r, loop); + return r; + } + + if(strcmp(property, "pgood")) + continue; + + quit(0, loop); + break; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + static const char *matchfmt = + "type='signal'," + "interface='org.freedesktop.DBus.Properties'," + "member='PropertiesChanged'," + "arg0='org.openbmc.control.Power'," + "path='%s'," + "sender='%s'"; + static const char *usage = + "Usage: %s OBJECTPATH on|off\n"; + static const size_t LEN = 256; + + sd_bus *conn = NULL; + sd_event *loop = NULL; + sd_bus_slot *slot = NULL; + sd_bus_error error = SD_BUS_ERROR_NULL; + char *service = NULL; + int r, dest = -1, state; + char match[LEN]; + + if(argc < 3) { + fprintf(stderr, usage, argv[0]); + exit(EXIT_FAILURE); + } + + if(!strcmp(argv[2], "on")) + dest = 1; + if(!strcmp(argv[2], "off")) + dest = 0; + + if(dest != 0 && dest != 1) { + fprintf(stderr, usage, argv[0]); + exit(EXIT_FAILURE); + } + + r = sd_bus_default_system(&conn); + if(r < 0) { + fprintf(stderr, "Error connecting to system bus: %s\n", + strerror(-r)); + goto finish; + } + + r = mapper_get_service(conn, argv[1], &service); + if (r < 0) { + fprintf(stderr, "Error obtaining host service: %s\n", + strerror(-r)); + goto finish; + } + + r = sd_event_default(&loop); + if (r < 0) { + fprintf(stderr, "Error obtaining event loop: %s\n", + strerror(-r)); + goto finish; + } + + r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL); + if (r < 0) { + fprintf(stderr, "Failed to attach system " + "bus to event loop: %s\n", + strerror(-r)); + goto finish; + } + + if(strlen(matchfmt) + strnlen(argv[1], LEN) > LEN) { + r = -E2BIG; + fprintf(stderr, "Error adding match rule: %s\n", + strerror(-r)); + goto finish; + } + + sprintf(match, matchfmt, argv[1], service); + + r = sd_bus_add_match(conn, + &slot, + match, + callback, + loop); + if(r < 0) { + fprintf(stderr, "Error adding match rule: %s\n", + strerror(-r)); + goto finish; + } + + r = sd_bus_get_property_trivial(conn, + service, + argv[1], + "org.openbmc.control.Power", + "pgood", + &error, + 'i', + &state); + if(r < 0) { + fprintf(stderr, "Error getting property: %s\n", + strerror(-r)); + goto finish; + } + + if(dest == state) + goto finish; + + r = sd_event_loop(loop); + if(r < 0) { + fprintf(stderr, "Error starting event loop: %s\n", + strerror(-r)); + goto finish; + } + +finish: + exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); +} |