Calling commit with rollback=false to cancel a pending rollback timer can
potentially trigger another commit if no rollback is actually pending.
This introduces a new method "confirm" which cancels the rollback timer
without any other possible side effects.
While being at it, change the return code when trying to commit during
a pending rollback or when trying to rollback without a pending timeout to
UBUS_STATUS_NO_DATA. This is needed to be able to differentiate between a
denied request and an inappropriate state.
Also change the error return code for glob() failures to the more
appropriate UBUS_STATUS_NOT_FOUND.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
snprintf(tmp, sizeof(tmp), RPC_UCI_SAVEDIR_PREFIX "%s/*", sid);
if (glob(tmp, GLOB_PERIOD, NULL, &gl) < 0)
snprintf(tmp, sizeof(tmp), RPC_UCI_SAVEDIR_PREFIX "%s/*", sid);
if (glob(tmp, GLOB_PERIOD, NULL, &gl) < 0)
+ return UBUS_STATUS_NOT_FOUND;
snprintf(tmp, sizeof(tmp), RPC_UCI_SAVEDIR_PREFIX "%s/", sid);
snprintf(tmp, sizeof(tmp), RPC_UCI_SAVEDIR_PREFIX "%s/", sid);
- apply_running = true;
- apply_timer.cb = rpc_uci_apply_timeout;
- uloop_timeout_set(&apply_timer, timeout * 1000);
- apply_ctx = ctx;
+ if (rollback) {
+ apply_running = true;
+ apply_timer.cb = rpc_uci_apply_timeout;
+ uloop_timeout_set(&apply_timer, timeout * 1000);
+ apply_ctx = ctx;
+ }
- if (apply_running && !rollback) {
- rpc_uci_purge_dir(RPC_SNAPSHOT_FILES);
- rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
- uloop_timeout_cancel(&apply_timer);
- apply_running = false;
- apply_ctx = NULL;
- }
+static int
+rpc_uci_confirm(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ if (!apply_running)
+ return UBUS_STATUS_NO_DATA;
+
+ rpc_uci_purge_dir(RPC_SNAPSHOT_FILES);
+ rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
+
+ uloop_timeout_cancel(&apply_timer);
+ apply_running = false;
+ apply_ctx = NULL;
blob_data(msg), blob_len(msg));
if (!apply_running)
blob_data(msg), blob_len(msg));
if (!apply_running)
- return UBUS_STATUS_PERMISSION_DENIED;
+ return UBUS_STATUS_NO_DATA;
if (!tb[RPC_B_SESSION])
return UBUS_STATUS_INVALID_ARGUMENT;
if (!tb[RPC_B_SESSION])
return UBUS_STATUS_INVALID_ARGUMENT;
snprintf(tmp, sizeof(tmp), "%s/*", RPC_SNAPSHOT_FILES);
if (glob(tmp, GLOB_PERIOD, NULL, &gl) < 0)
snprintf(tmp, sizeof(tmp), "%s/*", RPC_SNAPSHOT_FILES);
if (glob(tmp, GLOB_PERIOD, NULL, &gl) < 0)
+ return UBUS_STATUS_NOT_FOUND;
ret = rpc_uci_apply_access(sid, &gl);
if (ret) {
ret = rpc_uci_apply_access(sid, &gl);
if (ret) {
UBUS_METHOD("revert", rpc_uci_revert, rpc_uci_config_policy),
UBUS_METHOD("commit", rpc_uci_commit, rpc_uci_config_policy),
UBUS_METHOD("apply", rpc_uci_apply, rpc_uci_apply_policy),
UBUS_METHOD("revert", rpc_uci_revert, rpc_uci_config_policy),
UBUS_METHOD("commit", rpc_uci_commit, rpc_uci_config_policy),
UBUS_METHOD("apply", rpc_uci_apply, rpc_uci_apply_policy),
+ UBUS_METHOD("confirm", rpc_uci_confirm, rpc_uci_rollback_policy),
UBUS_METHOD("rollback", rpc_uci_rollback, rpc_uci_rollback_policy),
};
UBUS_METHOD("rollback", rpc_uci_rollback, rpc_uci_rollback_policy),
};