Support to fork a task

This commit is contained in:
Vivek Kumar Dutta 2024-10-07 11:53:24 +05:30
parent 5ea49eb360
commit 2d9c87e5c6
5 changed files with 98 additions and 17 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -26,4 +26,5 @@ extern DMLEAF tDeviceInfoProcessorParams[];
extern DMLEAF tDeviceInfoSupportedDataModelParams[];
extern DMLEAF tDeviceInfoFirmwareImageParams[];
void _exec_reboot(const void *arg1, const void *arg2);
#endif