Skip to content

Commit 059cffb

Browse files
bradbishopwilliamspatrick
authored andcommitted
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 <[email protected]>
1 parent ed1368d commit 059cffb

File tree

5 files changed

+201
-1
lines changed

5 files changed

+201
-1
lines changed

op-pwrctl/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
BINS=power_control
2+
SUBDIRS=pgood_wait
23
include ../gdbus.mk
34
include ../rules.mk

op-pwrctl/pgood_wait/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pgood_wait

op-pwrctl/pgood_wait/Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
BINS=pgood_wait
2+
BIN_SUFFIX=""
3+
LDLIBS=-lmapper
4+
include ../../sdbus.mk
5+
include ../../rules.mk

op-pwrctl/pgood_wait/pgood_wait.c

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/**
2+
* Copyright © 2016 IBM Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include <stdlib.h>
17+
#include <stdio.h>
18+
#include <errno.h>
19+
#include <systemd/sd-bus.h>
20+
#include <systemd/sd-event.h>
21+
#include <mapper.h>
22+
23+
static void quit(int r, void *loop)
24+
{
25+
sd_event_exit((sd_event *)loop, r);
26+
}
27+
28+
static int callback(sd_bus_message *m, void *user, sd_bus_error *error)
29+
{
30+
sd_event *loop = user;
31+
int r;
32+
char *property = NULL;
33+
34+
r = sd_bus_message_skip(m, "s");
35+
if (r < 0) {
36+
fprintf(stderr, "Error skipping message fields: %s\n",
37+
strerror(-r));
38+
quit(r, loop);
39+
return r;
40+
}
41+
42+
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
43+
if (r < 0) {
44+
fprintf(stderr, "Error entering container: %s\n",
45+
strerror(-r));
46+
quit(r, loop);
47+
return r;
48+
}
49+
50+
while((r = sd_bus_message_enter_container(
51+
m,
52+
SD_BUS_TYPE_DICT_ENTRY,
53+
"sv")) > 0) {
54+
r = sd_bus_message_read(m, "s", &property);
55+
if (r < 0) {
56+
fprintf(stderr, "Error reading message: %s\n",
57+
strerror(-r));
58+
quit(r, loop);
59+
return r;
60+
}
61+
62+
if(strcmp(property, "pgood"))
63+
continue;
64+
65+
quit(0, loop);
66+
break;
67+
}
68+
69+
return 0;
70+
}
71+
72+
int main(int argc, char *argv[])
73+
{
74+
static const char *matchfmt =
75+
"type='signal',"
76+
"interface='org.freedesktop.DBus.Properties',"
77+
"member='PropertiesChanged',"
78+
"arg0='org.openbmc.control.Power',"
79+
"path='%s',"
80+
"sender='%s'";
81+
static const char *usage =
82+
"Usage: %s OBJECTPATH on|off\n";
83+
static const size_t LEN = 256;
84+
85+
sd_bus *conn = NULL;
86+
sd_event *loop = NULL;
87+
sd_bus_slot *slot = NULL;
88+
sd_bus_error error = SD_BUS_ERROR_NULL;
89+
char *service = NULL;
90+
int r, dest = -1, state;
91+
char match[LEN];
92+
93+
if(argc < 3) {
94+
fprintf(stderr, usage, argv[0]);
95+
exit(EXIT_FAILURE);
96+
}
97+
98+
if(!strcmp(argv[2], "on"))
99+
dest = 1;
100+
if(!strcmp(argv[2], "off"))
101+
dest = 0;
102+
103+
if(dest != 0 && dest != 1) {
104+
fprintf(stderr, usage, argv[0]);
105+
exit(EXIT_FAILURE);
106+
}
107+
108+
r = sd_bus_default_system(&conn);
109+
if(r < 0) {
110+
fprintf(stderr, "Error connecting to system bus: %s\n",
111+
strerror(-r));
112+
goto finish;
113+
}
114+
115+
r = mapper_get_service(conn, argv[1], &service);
116+
if (r < 0) {
117+
fprintf(stderr, "Error obtaining host service: %s\n",
118+
strerror(-r));
119+
goto finish;
120+
}
121+
122+
r = sd_event_default(&loop);
123+
if (r < 0) {
124+
fprintf(stderr, "Error obtaining event loop: %s\n",
125+
strerror(-r));
126+
goto finish;
127+
}
128+
129+
r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
130+
if (r < 0) {
131+
fprintf(stderr, "Failed to attach system "
132+
"bus to event loop: %s\n",
133+
strerror(-r));
134+
goto finish;
135+
}
136+
137+
if(strlen(matchfmt) + strnlen(argv[1], LEN) > LEN) {
138+
r = -E2BIG;
139+
fprintf(stderr, "Error adding match rule: %s\n",
140+
strerror(-r));
141+
goto finish;
142+
}
143+
144+
sprintf(match, matchfmt, argv[1], service);
145+
146+
r = sd_bus_add_match(conn,
147+
&slot,
148+
match,
149+
callback,
150+
loop);
151+
if(r < 0) {
152+
fprintf(stderr, "Error adding match rule: %s\n",
153+
strerror(-r));
154+
goto finish;
155+
}
156+
157+
r = sd_bus_get_property_trivial(conn,
158+
service,
159+
argv[1],
160+
"org.openbmc.control.Power",
161+
"pgood",
162+
&error,
163+
'i',
164+
&state);
165+
if(r < 0) {
166+
fprintf(stderr, "Error getting property: %s\n",
167+
strerror(-r));
168+
goto finish;
169+
}
170+
171+
if(dest == state)
172+
goto finish;
173+
174+
r = sd_event_loop(loop);
175+
if(r < 0) {
176+
fprintf(stderr, "Error starting event loop: %s\n",
177+
strerror(-r));
178+
goto finish;
179+
}
180+
181+
finish:
182+
exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
183+
}

rules.mk

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ LDLIBS+=$(shell pkg-config --libs $(PACKAGE_DEPS))
55
ALL_CFLAGS+=$(shell pkg-config --cflags $(PACKAGE_DEPS)) -fPIC -Werror $(CFLAGS)
66

77
BIN_SUFFIX?=.exe
8+
.PHONY: $(SUBDIRS)
89

9-
all: $(BINS:=$(BIN_SUFFIX))
10+
all: $(BINS:=$(BIN_SUFFIX)) $(SUBDIRS)
1011

1112
%.o: %.c
1213
$(CC) -c $(ALL_CFLAGS) -o $@ $<
1314

15+
$(SUBDIRS):
16+
$(MAKE) -C $@
17+
1418
$(BINS:=$(BIN_SUFFIX)): %$(BIN_SUFFIX): %.o $(EXTRA_OBJS)
1519
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
1620

@@ -19,6 +23,12 @@ install: $(BINS:=$(BIN_SUFFIX))
1923
@for b in $(BINS:=$(BIN_SUFFIX)); do \
2024
install $$b $(DESTDIR)$(sbindir) || exit 1; \
2125
done
26+
@for d in $(SUBDIRS); do \
27+
$(MAKE) -C $$d $@ || exit 1; \
28+
done
2229

2330
clean:
2431
rm -rf *.o $(BINS:=$(BIN_SUFFIX))
32+
@for d in $(SUBDIRS); do \
33+
$(MAKE) -C $$d $@ || exit 1; \
34+
done

0 commit comments

Comments
 (0)