mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Support to fork a task
This commit is contained in:
parent
5ea49eb360
commit
2d9c87e5c6
5 changed files with 98 additions and 17 deletions
|
|
@ -161,11 +161,11 @@ static void _bbfdm_task_callback(struct uloop_timeout *t)
|
|||
BBF_ERR("Failed to decode task");
|
||||
return;
|
||||
}
|
||||
task->callback(task->arg1, task->arg2);
|
||||
task->taskcb(task->arg1, task->arg2);
|
||||
free(task);
|
||||
}
|
||||
|
||||
int bbfdm_task_add(bbfdm_task_callback_t callback, const void *arg1, const void *arg2, int timeout_sec) {
|
||||
int bbfdm_task_schedule(bbfdm_task_callback_t callback, const void *arg1, const void *arg2, int timeout_sec) {
|
||||
|
||||
bbfdm_task_data_t *task;
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ int bbfdm_task_add(bbfdm_task_callback_t callback, const void *arg1, const void
|
|||
}
|
||||
|
||||
|
||||
task->callback = callback;
|
||||
task->taskcb = callback;
|
||||
task->arg1 = arg1;
|
||||
task->arg2 = arg2;
|
||||
|
||||
|
|
@ -194,7 +194,68 @@ int bbfdm_task_add(bbfdm_task_callback_t callback, const void *arg1, const void
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void _bbfdm_task_finish_callback(struct uloop_process *p, int ret)
|
||||
{
|
||||
struct bbfdm_task_data *task = container_of(p, struct bbfdm_task_data, process);
|
||||
|
||||
if (task == NULL) {
|
||||
BBF_ERR("Failed to decode forked task");
|
||||
return;
|
||||
}
|
||||
if (task->finishcb) {
|
||||
task->finishcb(task->arg1, task->arg2);
|
||||
}
|
||||
free(task);
|
||||
}
|
||||
|
||||
|
||||
int bbfdm_task_fork(bbfdm_task_callback_t taskcb, bbfdm_task_callback_t finishcb, const void *arg1, const void *arg2)
|
||||
{
|
||||
pid_t child;
|
||||
bbfdm_task_data_t *task;
|
||||
|
||||
// do not use dmalloc here, as this needs to persists beyond session
|
||||
task = (bbfdm_task_data_t *)calloc(sizeof(bbfdm_task_data_t), 1);
|
||||
if (task == NULL) {
|
||||
BBF_ERR("Failed to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
task->arg1 = arg1;
|
||||
task->arg2 = arg2;
|
||||
|
||||
child = fork();
|
||||
if (child == -1) {
|
||||
BBF_ERR("Failed to fork a child for task");
|
||||
goto err_out;
|
||||
} else if (child == 0) {
|
||||
/* free fd's and memory inherited from parent */
|
||||
uloop_done();
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
BBF_INFO("{fork} Calling from subprocess");
|
||||
taskcb(task->arg1, task->arg2);
|
||||
|
||||
/* write result and exit */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// monitor the process if finish callback is defined
|
||||
if (finishcb) {
|
||||
task->finishcb = finishcb;
|
||||
task->process.pid = child;
|
||||
task->process.cb = _bbfdm_task_finish_callback;
|
||||
uloop_process_add(&task->process);
|
||||
} else {
|
||||
FREE(task);
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
return -1;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** dmubus_wait_for_event
|
||||
|
|
|
|||
|
|
@ -34,13 +34,17 @@ struct dmubus_ev_subtask {
|
|||
typedef void (*bbfdm_task_callback_t)(const void *arg1, const void *arg2);
|
||||
|
||||
typedef struct bbfdm_task_data {
|
||||
struct uloop_process process; // Used for forked task
|
||||
struct uloop_timeout timeout;
|
||||
bbfdm_task_callback_t callback;
|
||||
bbfdm_task_callback_t taskcb;
|
||||
bbfdm_task_callback_t finishcb; // Used for forked task
|
||||
const void *arg1;
|
||||
const void *arg2;
|
||||
} bbfdm_task_data_t;
|
||||
|
||||
int bbfdm_task_add(bbfdm_task_callback_t callback, const void *arg1, const void *arg2, int timeout);
|
||||
int bbfdm_task_schedule(bbfdm_task_callback_t callback, const void *arg1, const void *arg2, int timeout);
|
||||
|
||||
int bbfdm_task_fork(bbfdm_task_callback_t taskcb, bbfdm_task_callback_t finishcb, const void *arg1, const void *arg2);
|
||||
|
||||
typedef void (*CB_FUNC_PTR)(struct ubus_context *ctx, struct ubus_event_handler *ev,
|
||||
const char *type, struct blob_attr *msg);
|
||||
|
|
|
|||
|
|
@ -26,19 +26,30 @@ static int get_Device_RootDataModelVersion(char *refparam, struct dmctx *ctx, vo
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void _exec_factoryreset(const void *arg1, const void *arg2)
|
||||
{
|
||||
sleep(2);
|
||||
dmubus_call_set("rpc-sys", "factory", UBUS_ARGS{0}, 0);
|
||||
sleep(5); // Wait for reboot to happen
|
||||
BBF_ERR("FactoryReset via rpc-sys failed, trying defaultreset");
|
||||
dmcmd_no_wait("/sbin/defaultreset", 0);
|
||||
sleep(5); // Wait for reboot to happen
|
||||
BBF_ERR("FactoryReset call failed!!!");
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* OPERATE COMMANDS
|
||||
*************************************************************/
|
||||
static int operate_Device_Reboot(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
int res = dmubus_call_set("system", "reboot", UBUS_ARGS{0}, 0);
|
||||
int res = bbfdm_task_fork(_exec_reboot, NULL, NULL, NULL);
|
||||
if (res) bbfdm_set_fault_message(ctx, "Reboot: ubus 'system reboot' method doesn't exist");
|
||||
return !res ? 0 : USP_FAULT_COMMAND_FAILURE;
|
||||
}
|
||||
|
||||
static int operate_Device_FactoryReset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
int res = dmcmd_no_wait("/sbin/defaultreset", 0);
|
||||
int res = bbfdm_task_fork(_exec_factoryreset, NULL, NULL, NULL);
|
||||
if (res) bbfdm_set_fault_message(ctx, "FactoryReset: '/sbin/defaultreset' command doesn't exist");
|
||||
return !res ? 0 : USP_FAULT_COMMAND_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -731,15 +731,9 @@ static int bbf_fw_image_download(const char *url, const char *auto_activate, con
|
|||
goto end;
|
||||
}
|
||||
|
||||
// Reboot the device if auto activation is true
|
||||
// Schedule a device Reboot, if auto activation is true
|
||||
if (activate) {
|
||||
// Send the transfer complete after image applied
|
||||
send_transfer_complete_event(command, obj_path, url, fault_msg, start_time, complete_time, commandKey, "Download");
|
||||
|
||||
sleep(5); // added additional buffer for TransferComplete! event
|
||||
if (dmubus_call_set("system", "reboot", UBUS_ARGS{0}, 0) != 0)
|
||||
res = -1;
|
||||
sleep(10); // Wait for reboot to take action
|
||||
bbfdm_task_fork(_exec_reboot, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
end:
|
||||
|
|
@ -1698,6 +1692,17 @@ static int get_operate_args_DeviceInfoFirmwareImage_Activate(char *refparam, str
|
|||
return 0;
|
||||
}
|
||||
|
||||
void _exec_reboot(const void *arg1, const void *arg2)
|
||||
{
|
||||
sleep(3); // Wait for reboot to happen
|
||||
dmubus_call_set("rpc-sys", "reboot", UBUS_ARGS{0}, 0);
|
||||
sleep(5); // Wait for reboot to happen
|
||||
BBF_ERR("Reboot call failed with rpc-sys, trying again with system");
|
||||
dmubus_call_set("system", "reboot", UBUS_ARGS{0}, 0);
|
||||
sleep(5); // Wait for reboot
|
||||
BBF_ERR("Reboot call failed!!!");
|
||||
}
|
||||
|
||||
static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
#define CRONTABS_ROOT "/etc/crontabs/root"
|
||||
|
|
@ -1799,8 +1804,7 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
|
|||
if (strcasecmp(status, "true") != 0)
|
||||
return USP_FAULT_COMMAND_FAILURE;
|
||||
|
||||
res = dmubus_call_set("rpc-sys", "reboot", UBUS_ARGS{0}, 0);
|
||||
sleep(10); // Wait for reboot to happen
|
||||
bbfdm_task_fork(_exec_reboot, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
return res ? USP_FAULT_COMMAND_FAILURE : 0;
|
||||
|
|
|
|||
|
|
@ -26,4 +26,5 @@ extern DMLEAF tDeviceInfoProcessorParams[];
|
|||
extern DMLEAF tDeviceInfoSupportedDataModelParams[];
|
||||
extern DMLEAF tDeviceInfoFirmwareImageParams[];
|
||||
|
||||
void _exec_reboot(const void *arg1, const void *arg2);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue