projects
/
project
/
netifd.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
proto-shell: extend race condition avoidance
[project/netifd.git]
/
proto-shell.c
diff --git
a/proto-shell.c
b/proto-shell.c
index 9fad3a0a581f038c703da42348084084d1110198..98f5e52fd720874620e28f3c6948483ade5507e3 100644
(file)
--- a/
proto-shell.c
+++ b/
proto-shell.c
@@
-71,6
+71,7
@@
struct proto_shell_state {
enum proto_shell_sm sm;
bool proto_task_killed;
enum proto_shell_sm sm;
bool proto_task_killed;
+ bool renew_pending;
int last_error;
int last_error;
@@
-162,11
+163,19
@@
proto_shell_handler(struct interface_proto_state *proto,
} else if (cmd == PROTO_CMD_RENEW) {
if (!(handler->proto.flags & PROTO_FLAG_RENEW_AVAILABLE))
return 0;
} else if (cmd == PROTO_CMD_RENEW) {
if (!(handler->proto.flags & PROTO_FLAG_RENEW_AVAILABLE))
return 0;
+
+ if (state->script_task.uloop.pending) {
+ state->renew_pending = true;
+ return 0;
+ }
+
+ state->renew_pending = false;
action = "renew";
} else {
if (state->sm == S_TEARDOWN)
return 0;
action = "renew";
} else {
if (state->sm == S_TEARDOWN)
return 0;
+ state->renew_pending = false;
if (state->script_task.uloop.pending) {
if (state->sm != S_SETUP_ABORT) {
uloop_timeout_set(&state->teardown_timeout, 1000);
if (state->script_task.uloop.pending) {
if (state->sm != S_SETUP_ABORT) {
uloop_timeout_set(&state->teardown_timeout, 1000);
@@
-187,6
+196,7
@@
proto_shell_handler(struct interface_proto_state *proto,
uloop_timeout_set(&state->teardown_timeout, 5000);
}
uloop_timeout_set(&state->teardown_timeout, 5000);
}
+ D(INTERFACE, "run %s for interface '%s'\n", action, proto->iface->name);
config = blobmsg_format_json(state->config, true);
if (!config)
return -1;
config = blobmsg_format_json(state->config, true);
if (!config)
return -1;
@@
-255,6
+265,9
@@
proto_shell_task_finish(struct proto_shell_state *state,
if (task == &state->proto_task)
proto_shell_handler(&state->proto, PROTO_CMD_TEARDOWN,
false);
if (task == &state->proto_task)
proto_shell_handler(&state->proto, PROTO_CMD_TEARDOWN,
false);
+ if (task == &state->script_task && state->renew_pending)
+ proto_shell_handler(&state->proto, PROTO_CMD_RENEW,
+ false);
break;
case S_SETUP_ABORT:
break;
case S_SETUP_ABORT:
@@
-682,6
+695,9
@@
proto_shell_notify(struct interface_proto_state *proto, struct blob_attr *attr)
if (!tb[NOTIFY_ACTION])
return UBUS_STATUS_INVALID_ARGUMENT;
if (!tb[NOTIFY_ACTION])
return UBUS_STATUS_INVALID_ARGUMENT;
+ if (state->sm == S_TEARDOWN || state->sm == S_SETUP_ABORT)
+ return UBUS_STATUS_PERMISSION_DENIED;
+
switch(blobmsg_get_u32(tb[NOTIFY_ACTION])) {
case 0:
return proto_shell_update_link(state, attr, tb);
switch(blobmsg_get_u32(tb[NOTIFY_ACTION])) {
case 0:
return proto_shell_update_link(state, attr, tb);