From 327bfe7416c8092c799e03307353899e65f17b8d Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 11 Oct 2023 14:09:24 +0900 Subject: [PATCH 01/16] Release version 0.38.8 Changes: - Fix external package activation Change-Id: I9e140fd972ddc010adaf7ed404b7bfae7d818dfc Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index a2d4439..22fb2a1 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.7 +Version: 0.38.8 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From d9aa291d89572b20e73004dfd0e8ec2be50264a4 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 12 Oct 2023 10:03:39 +0900 Subject: [PATCH 02/16] Exclude dlog fds from closing fds To print dlogs, the process pool checks whether the file descriptor is dlog fd or not. And then, the dlog fds will be excluded from closing fds. Change-Id: I86aee6554ec3ba7ad8cfbac395a84e75b629b52b Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/process_pool.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/launchpad-process-pool/process_pool.cc b/src/launchpad-process-pool/process_pool.cc index c7bb40f..d91bc58 100644 --- a/src/launchpad-process-pool/process_pool.cc +++ b/src/launchpad-process-pool/process_pool.cc @@ -16,6 +16,7 @@ #include "launchpad-process-pool/process_pool.hh" +#include #include #include #include @@ -23,18 +24,41 @@ #include #include +#include #include +#include #include #include "launchpad-process-pool/launchpad_args.hh" #include "launchpad-process-pool/log_private.hh" +namespace fs = std::filesystem; + namespace launchpad { namespace { constexpr const char kProcessPool[] = "process-pool"; +std::vector GetDlogFds() { + std::vector fds; + try { + fs::path proc_path("/proc/self/fd"); + for (const auto& entry : fs::directory_iterator(proc_path)) { + if (!isdigit(entry.path().filename().string()[0])) + continue; + + int fd = std::stoi(entry.path().filename().string()); + if (dlog_is_log_fd(fd)) + fds.push_back(fd); + } + } catch (const fs::filesystem_error& e) { + _E("Exception occurs. error(%s)", e.what()); + } + + return fds; +} + } // namespace ProcessPool::ProcessPool(std::string name, int num_processes, @@ -112,7 +136,8 @@ void ProcessPool::OnExecution() { snprintf(args[0], length, "/usr/bin/%s <%s>", kProcessPool, name_.c_str()); close(pipe_fd_[1]); - std::vector except_fds { pipe_fd_[0] }; + std::vector except_fds = GetDlogFds(); + except_fds.push_back(pipe_fd_[0]); Util::CloseAllFds(except_fds); int ret = WaitForRequest(std::make_unique(pipe_fd_[0])); exit(ret); -- 2.7.4 From 7d8aafce794bdd0473a6dc526e923ee7499e29df Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 12 Oct 2023 11:16:27 +0900 Subject: [PATCH 03/16] Release version 0.38.9 Changes: - Exclude dlog fds from closing fds Change-Id: I3c215acf48c32d6d186409f9e2c0d1b32e0f3b0a Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 22fb2a1..a677116 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.8 +Version: 0.38.9 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From d2f6f2bbf8e13461ad1bf6156df1e8b1287eb4c9 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 12 Oct 2023 16:43:37 +0900 Subject: [PATCH 04/16] Remove previous files at fork This patch uses pthread_atfork() to register a fork handler. While creating a children process, we should remove previous files related to the process ID. Change-Id: I04a646feefeb7dd21cc102c4ab2bb43f10a259b5 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/signal_manager.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/launchpad-process-pool/signal_manager.cc b/src/launchpad-process-pool/signal_manager.cc index de8b624..493a75e 100644 --- a/src/launchpad-process-pool/signal_manager.cc +++ b/src/launchpad-process-pool/signal_manager.cc @@ -16,6 +16,7 @@ #include "launchpad-process-pool/signal_manager.hh" +#include #include #include @@ -49,6 +50,18 @@ class GarbageCollector : public launchpad::Worker::Job { } } + void DoAtFork() { + _W("pid: %d", pid_); + try { + std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" + + std::to_string(pid_); + DeleteSocketPath(fs::path(path)); + DeleteUnusedFiles(); + } catch (const std::filesystem::filesystem_error& e) { + _E("Exception occurs. error(%s:%d)", e.what(), e.code().value()); + } + } + private: void DeleteSocketPath(const fs::path& path) { try { @@ -121,6 +134,7 @@ void SignalManager::Dispose() { recycle_bin_.reset(); hydra_sigchld_event_.reset(); sigchld_event_.reset(); + pthread_atfork(nullptr, nullptr, nullptr); disposed_ = true; _W("END"); } @@ -154,6 +168,12 @@ void SignalManager::Init() { signal(signo, SIG_DFL); } + pthread_atfork(nullptr, nullptr, + []() { + GarbageCollector gc(getpid()); + gc.DoAtFork(); + }); + disposed_ = false; _W("END"); } -- 2.7.4 From 997cc951cbe954bd7fc264edea1f78e2fc0bd39c Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 12 Oct 2023 17:00:00 +0900 Subject: [PATCH 05/16] Release version 0.38.10 Changes: - Remove previous files at fork Change-Id: I6bcd8cec89a1f332474bdad3285e73916041a4c3 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index a677116..4805d7b 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.9 +Version: 0.38.10 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From b880098d392930039c6f4cb076ef9750d5868791 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 18 Oct 2023 09:03:48 +0900 Subject: [PATCH 06/16] Add SIGUSR1 signal handler Currently, the launchpad-process-pool suddenly gets the SIGUSR1 signal. To debug the reason, the SIGUSR1 signal handler is added. While getting the signal, the launchpad-process-pool prints the sender pid and the backtrace. Change-Id: I842e374b836b83a635722baafa628bea10f072d0 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/signal_manager.cc | 70 ++++++++++++++++++++++++++++ src/launchpad-process-pool/signal_manager.hh | 19 ++++++++ 2 files changed, 89 insertions(+) diff --git a/src/launchpad-process-pool/signal_manager.cc b/src/launchpad-process-pool/signal_manager.cc index 493a75e..51fb638 100644 --- a/src/launchpad-process-pool/signal_manager.cc +++ b/src/launchpad-process-pool/signal_manager.cc @@ -16,10 +16,13 @@ #include "launchpad-process-pool/signal_manager.hh" +#include #include +#include #include #include +#include #include #include #include @@ -126,6 +129,8 @@ void SignalManager::Dispose() { return; _W("BEGIN"); + RestoreSignalAction(SIGUSR2); + RestoreSignalAction(SIGUSR1); #ifndef PRELOAD_ACTIVATE for (int signo = 0; signo < _NSIG; ++signo) signal(signo, SIG_DFL); @@ -174,6 +179,9 @@ void SignalManager::Init() { gc.DoAtFork(); }); + ChangeSignalAction(SIGUSR1); + ChangeSignalAction(SIGUSR2); + disposed_ = false; _W("END"); } @@ -231,4 +239,66 @@ void SignalManager::OnHydraSigchld(pid_t pid, int status) { HandleSigchld(pid, status); } +void SignalManager::ChangeSignalAction(int signo) { + struct sigaction old_action = { 0, }; + struct sigaction action = { 0, }; + sigemptyset(&action.sa_mask); + action.sa_sigaction = UnixSignalHandler; + action.sa_flags = SA_RESTART | SA_SIGINFO; + + int ret = sigaction(signo, &action, &old_action); + if (ret != 0) { + _W("sigaction() is failed. errno(%d)", errno); + return; + } + + sigaction_map_[signo] = std::make_unique(signo, old_action); +} + +void SignalManager::RestoreSignalAction(int signo) { + auto found = sigaction_map_.find(signo); + if (found == sigaction_map_.end()) { + _W("Failed to find signal action. signo(%d)", signo); + return; + } + + auto& signal_action = found->second; + auto old_action = signal_action->GetSigaction(); + sigaction(signo, &old_action, nullptr); + sigaction_map_.erase(found); +} + +void SignalManager::UnixSignalHandler(int signo, siginfo_t* info, void* arg) { +#define BT_BUF_SIZE 128 + sigset_t old_mask; + sigset_t mask; + sigfillset(&mask); + sigprocmask(SIG_BLOCK, &mask, &old_mask); + + _W("[UNIX_SIGNAL_HANDLER] signo: %d", signo); + if (info != nullptr) { + _W("[UNIX_SIGNAL_HANDLER] pid: %d, uid: %u", info->si_pid, info->si_uid); + if (info->si_pid > 0) { + std::ifstream stream("/proc/" + std::to_string(info->si_pid) + + "/cmdline"); + if (stream.is_open()) { + std::string cmdline; + std::getline(stream, cmdline); + stream.close(); + _W("[UNIX_SIGNAL_HANDLER] cmdline: %s", cmdline.c_str()); + } + } + } + + void* buffer[BT_BUF_SIZE]; + int nptrs = backtrace(buffer, BT_BUF_SIZE); + backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO); + + sigprocmask(SIG_SETMASK, &old_mask, nullptr); + raise(signo); + + _W("Raise SIGABRT to make coredump"); + abort(); +} + } // namespace launchpad diff --git a/src/launchpad-process-pool/signal_manager.hh b/src/launchpad-process-pool/signal_manager.hh index 8cd8ffc..66acf22 100644 --- a/src/launchpad-process-pool/signal_manager.hh +++ b/src/launchpad-process-pool/signal_manager.hh @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -54,6 +55,19 @@ class SignalManager : public SigchldEvent::IEvent, void UnblockSigchld(); private: + class SignalAction { + public: + SignalAction(int signo, struct sigaction action) + : signo_(signo), action_(action) {} + + int GetSigno() const { return signo_; }; + struct sigaction GetSigaction() const { return action_; }; + + private: + int signo_; + struct sigaction action_; + }; + SignalManager() = default; ~SignalManager(); @@ -65,6 +79,10 @@ class SignalManager : public SigchldEvent::IEvent, void OnSigchld(pid_t pid, int status) override; void OnHydraSigchld(pid_t pid, int status) override; + void ChangeSignalAction(int signo); + void RestoreSignalAction(int signo); + static void UnixSignalHandler(int signo, siginfo_t* info, void* arg); + private: bool disposed_ = true; IEvent* listener_ = nullptr; @@ -73,6 +91,7 @@ class SignalManager : public SigchldEvent::IEvent, std::unique_ptr sigchld_event_; std::unique_ptr hydra_sigchld_event_; std::unique_ptr recycle_bin_; + std::unordered_map> sigaction_map_; }; } // namespace launchpad -- 2.7.4 From f8c5b5742c8bedfd0bace92916cc7f1b496feda7 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 18 Oct 2023 09:46:47 +0900 Subject: [PATCH 07/16] Fix double close This patch removes input_file.close() call from debugger info parser. Change-Id: Ib430ee0f6f715f55aa6f23a28b65634700e98ade Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/debugger_info.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/launchpad-process-pool/debugger_info.cc b/src/launchpad-process-pool/debugger_info.cc index c9618b1..c611931 100644 --- a/src/launchpad-process-pool/debugger_info.cc +++ b/src/launchpad-process-pool/debugger_info.cc @@ -305,8 +305,6 @@ void DebuggerInfoInflator::Parse(const fs::path& path) { parser(std::move(token2)); } - input_file.close(); - if (parsing) InsertDebuggerInfo(std::shared_ptr(builder_.Build())); -- 2.7.4 From 7129cbe7fb6bc5f384c00ecdce2c2287e3eb9018 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 18 Oct 2023 09:51:49 +0900 Subject: [PATCH 08/16] Release version 0.38.11 Changes: - Add SIGUSR1 signal handler - Fix double close Change-Id: I539d5645dcbeb9ae00474fcbbd5a15ac0fce10a3 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 4805d7b..f40dbe0 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.10 +Version: 0.38.11 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From b2a65eb5b68d7e3bcea195536214301d6a4b5143 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 19 Oct 2023 13:08:55 +0900 Subject: [PATCH 09/16] Change log messages of executing echo The error message is added. Change-Id: I18518c4806e2de0bdd9d6515940798fda8b7849a Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/app_executor.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/launchpad-process-pool/app_executor.cc b/src/launchpad-process-pool/app_executor.cc index f534aef..d2e17f8 100644 --- a/src/launchpad-process-pool/app_executor.cc +++ b/src/launchpad-process-pool/app_executor.cc @@ -44,11 +44,13 @@ namespace launchpad { namespace fs = std::filesystem; namespace { -void ExecuteEcho(const std::string& app_path) { +void ExecuteEcho(const std::string& app_path, const std::string& error) { char *argv[] = { const_cast("/usr/bin/echo"), - const_cast("Failed to execute a file. path: "), + const_cast("Failed to execute a file. path:"), const_cast(app_path.c_str()), + const_cast("error:"), + const_cast(error.c_str()), nullptr, }; @@ -120,7 +122,7 @@ void AppExecutor::OnExecution() { if (ret < 0) { _E("Failed to prepare executing application(%s)", app_info_->GetAppId().c_str()); - ExecuteEcho(app_info_->GetAppPath()); + ExecuteEcho(app_info_->GetAppPath(), std::to_string(ret)); exit(ret); } @@ -129,7 +131,7 @@ void AppExecutor::OnExecution() { char** app_argv = static_cast(calloc(argv.size() + 1, sizeof(char*))); if (app_argv == nullptr) { _E("Out of memory"); - ExecuteEcho(app_info_->GetAppPath()); + ExecuteEcho(app_info_->GetAppPath(), std::to_string(-ENOMEM)); exit(-1); } @@ -149,7 +151,7 @@ void AppExecutor::OnExecution() { fprintf(stderr, "Failed to exeucte a file. path: %s, errno: %d(%s)\n", app_info_->GetAppPath().c_str(), errno, strerror_r(errno, err_buf, sizeof(err_buf))); - ExecuteEcho(app_info_->GetAppPath()); + ExecuteEcho(app_info_->GetAppPath(), err_buf); exit(EXIT_FAILURE); } } -- 2.7.4 From 0958ad257b14124da03eb922acf66441b094c95f Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 19 Oct 2023 13:32:26 +0900 Subject: [PATCH 10/16] Release version 0.38.12 Changes: - Change log messages of executing echo Change-Id: I0df749a6230971b88dead3c2ada3aec14bdeaa77 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index f40dbe0..192690f 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.11 +Version: 0.38.12 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From f683060c8a2b80db6833b5d5da17165b5c10dfe6 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 31 Oct 2023 16:42:20 +0900 Subject: [PATCH 11/16] Fix typo Change-Id: I4c17ea4c8253e46b26237c63326bf8ded5f136f6 Signed-off-by: Changgyu Choi --- src/launchpad-process-pool/app_executor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad-process-pool/app_executor.cc b/src/launchpad-process-pool/app_executor.cc index d2e17f8..06dda58 100644 --- a/src/launchpad-process-pool/app_executor.cc +++ b/src/launchpad-process-pool/app_executor.cc @@ -148,7 +148,7 @@ void AppExecutor::OnExecution() { Util::CloseAllFds(); if (execv(app_argv[LoaderArg::Path], app_argv) < 0) { char err_buf[1024]; - fprintf(stderr, "Failed to exeucte a file. path: %s, errno: %d(%s)\n", + fprintf(stderr, "Failed to execute a file. path: %s, errno: %d(%s)\n", app_info_->GetAppPath().c_str(), errno, strerror_r(errno, err_buf, sizeof(err_buf))); ExecuteEcho(app_info_->GetAppPath(), err_buf); -- 2.7.4 From 70ff4120c70bceeb4d79efed9ceb08432daf2879 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 31 Oct 2023 16:51:06 +0900 Subject: [PATCH 12/16] Release version 0.38.13 Changes: - Fix typo Change-Id: I6966a0e3f7b48269aed5ffd6c21c3ba8f77259e9 Signed-off-by: Changgyu Choi --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 192690f..eddf435 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.12 +Version: 0.38.13 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From dd7bda875abfd24393d78e394072515f70daf040 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 3 Nov 2023 17:15:11 +0900 Subject: [PATCH 13/16] Remove CPU boosting of loader process Recently, the launchpad-process-pool sends a boosting request when the loader process is not prepared. This patch removes that. In the product model, the module of amd sends a boosting request for executing the process. Change-Id: Iebf96954919be250447f19ee0d37f4274db39bf2 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/launchpad.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/launchpad-process-pool/launchpad.cc b/src/launchpad-process-pool/launchpad.cc index 90663d6..bfbe8ad 100644 --- a/src/launchpad-process-pool/launchpad.cc +++ b/src/launchpad-process-pool/launchpad.cc @@ -511,8 +511,6 @@ Launchpad::LaunchResult Launchpad::LaunchRequestPend( loader_context->Prepare(); if (loader_context->GetPid() > 0) { - CPUBoostController::DoBoost(loader_context->GetPid(), - CPUBoostController::Level::Strong, 10000); _W("Send result: %d", loader_context->GetPid()); request->SetPid(loader_context->GetPid()); request->SendResult(loader_context->GetPid()); -- 2.7.4 From d4c458125861f3193c5ad154ea428b2516ec3a94 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 6 Nov 2023 08:37:18 +0900 Subject: [PATCH 14/16] Release version 0.38.14 Changes: - Remove CPU boosting of loader process Change-Id: Ib17f02eeed22cd740047589f1f8061b55f747e4f Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index eddf435..8378a80 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.13 +Version: 0.38.14 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 182e6ba867f16e5ba2e6fc75092f5a772351b006 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 6 Nov 2023 16:18:15 +0900 Subject: [PATCH 15/16] Modify thread control This patch uses std::condition_variable::wait_for() instead of std::condition_variable::wait(). The timeout is 5 seconds. Change-Id: I6a5f89bbf4450679c8527121f76966c6451eab52 Signed-off-by: Hwankyu Jhun --- src/lib/launchpad/thread_control.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib/launchpad/thread_control.cc b/src/lib/launchpad/thread_control.cc index 41b2ed1..680b305 100644 --- a/src/lib/launchpad/thread_control.cc +++ b/src/lib/launchpad/thread_control.cc @@ -177,9 +177,12 @@ void ThreadControl::SignalHandler(int signo) { auto& inst = ThreadControl::GetInst(); std::unique_lock lock(inst.mutex_); inst.count_--; - inst.cond_.wait(lock, [&] { return inst.done_; }); + if (inst.cond_.wait_for(lock, std::chrono::seconds(5), + [&] { return inst.done_; })) + _D("Unblock"); + else + _E("Timed out"); inst.count_--; - _D("Unblock"); } } // namespace launchpad -- 2.7.4 From c1c15379213de7859ab84db16074fdef13d88c12 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 6 Nov 2023 16:39:46 +0900 Subject: [PATCH 16/16] Release version 0.38.15 Changes: - Modify thread control Change-Id: I94a8a7e1b27a922714a51154817e19fcd8593047 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 8378a80..0c1e774 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.14 +Version: 0.38.15 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4