From: Mateusz Majewski Date: Wed, 27 Jul 2022 06:26:13 +0000 (+0200) Subject: Do not track the full upgrade server-side X-Git-Tag: submit/tizen/20220727.141559^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7ac82e6b428e4c9fc0ea0bf4813618277a1a39e7;p=platform%2Fcore%2Fsystem%2Fupdate-control.git Do not track the full upgrade server-side This realises the asynchrony of do_update in a better way, since now the server does some basic checks, and fades away after spawning the update process. Change-Id: I4d53f3d65eaf6e75a425bf3061f10fd0b5f55d7a --- diff --git a/src/update_control.c b/src/update_control.c index 2b769cd..d87f787 100644 --- a/src/update_control.c +++ b/src/update_control.c @@ -182,47 +182,33 @@ API int update_control_download_package(void) return UPDATE_CONTROL_ERROR_NONE; } -static void do_update_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +API int update_control_do_update(void) { - if (proxy == NULL) { - _E("Not initialized"); - return; - } + CHECK_FEATURE_SUPPORTED(DEVICE_UPDATE_FEATURE); + _I("update_control_do_update called"); gint status = 0; GError *error = NULL; - org_tizen_update_manager_call_install_finish(proxy, &status, res, &error); + if (proxy == NULL) { + _E("Not initialized"); + return UPDATE_CONTROL_ERROR_SYSTEM_ERROR; + } + + org_tizen_update_manager_call_install_sync(proxy, &status, NULL, &error); if (error != NULL) { - _E("Failed to method call to dbus : %s", error->message); + _E("Failed to call DBus method: %s", error->message); g_error_free(error); - return; + return UPDATE_CONTROL_ERROR_SYSTEM_ERROR; } - _I("Success to method call to dbus"); + _I("Successfully called DBus method call"); if (status < 0) { - _E("Failed to do update : %d", status); - return; - } - - // NB: We shouldn't really end up here, since the target should be rebooted by now. - _I("Success to do update : %d", status); -} - -API int update_control_do_update(void) -{ - CHECK_FEATURE_SUPPORTED(DEVICE_UPDATE_FEATURE); - _I("update_control_do_update called"); - - if (proxy == NULL) { - _E("Not initialized"); - return UPDATE_CONTROL_ERROR_SYSTEM_ERROR; + _E("DBus method returned error code: %d", status); + return UPDATE_CONTROL_ERROR_INVALID_OPERATION; } - // TODO: Take the fact that this is now async into account in docs. - // TODO: Consider making this asynchronous server-side instead. - org_tizen_update_manager_call_install(proxy, NULL, do_update_cb, NULL); - _I("Started update"); + _I("Started update: %d", status); return UPDATE_CONTROL_ERROR_NONE; } diff --git a/update-manager/fota/fota-installer.c b/update-manager/fota/fota-installer.c index 1686b56..cb68ec2 100644 --- a/update-manager/fota/fota-installer.c +++ b/update-manager/fota/fota-installer.c @@ -167,12 +167,28 @@ int fota_installer_execute(pid_t sender_pid) } } + /* All basic checks succeeded, following is what happens next: We + * double-fork() the process and run actual upgrade script in the child + * process. We do this so that we can at least inform API client that + * script executed sucessfuly, without requiring him to wait for whole + * upgrade to succeed till returning from dbus call. + * TODO: Take the fact that this is now async into account in docs. */ pid = fork(); if (pid < 0) { _FLOGE("Failed to fork"); status = -1; goto execute_destroy; } else if (pid == 0) { + /* Double fork to avoid zombies */ + switch (fork()) { + case -1: + exit(EXIT_FAILURE); + case 0: + break; + default: + exit(EXIT_SUCCESS); + } + ret = execl(FOTA_TRIGGER_PATH, FOTA_TRIGGER_PATH, client_delta_path, NULL); if (ret == -1) _FLOGE("Failed to execl(%s %s)", FOTA_TRIGGER_PATH, client_delta_path); @@ -180,43 +196,15 @@ int fota_installer_execute(pid_t sender_pid) exit(EXIT_FAILURE); } - ret = wait(&exec_status); + /* Since we double forked, we have to wait for the first child (otherwise + * it will become a zombie), but it should return quickly. */ + ret = waitpid(pid, &exec_status, 0); if (ret == -1) { _FLOGE("Failed to wait child"); status = -1; goto execute_destroy; } - if (WIFEXITED(exec_status) == TRUE) { - exec_status = WEXITSTATUS(exec_status); - if (exec_status != 100) { - _FLOGE("Trigger fota failed, exit code(%d)", exec_status); - status = -4; - goto execute_destroy; - } - } else if (WIFSIGNALED(exec_status) == TRUE) { - _FLOGE("Trigger fota killed, signal(%d)", WTERMSIG(exec_status)); - status = -4; - goto execute_destroy; - } else if (WIFSTOPPED(exec_status) == TRUE) { - _FLOGE("Trigger fota stoped, signal(%d)", WSTOPSIG(exec_status)); - status = -4; - goto execute_destroy; - } else { - _FLOGE("Unexpected wait error"); - status = -1; - goto execute_destroy; - } - - ret = device_power_reboot(FOTA_INSTALL_REBOOT_REASON); - if (ret != DEVICE_ERROR_NONE) { - _FLOGE("Failed to reboot with %s", FOTA_INSTALL_REBOOT_REASON); - status = -1; - goto execute_destroy; - } - - _FLOGI("Success to trigger fota, device will be rebooted"); - execute_destroy: util_file_remove(FOTA_DELTA_BUILD_STRING_PATH);