usb: Copy image file to /tmp/images via USB
Traverse the USB mount directory, and copy the first file with
a `.tar` extension under the directory to the `/tmp/images`
directory.
Tested: Manually call the fs::copy_file app locally, test passed.
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I8e03b9c3305f5e9d9a1535dd176ecd40dbea8903
diff --git a/usb/meson.build b/usb/meson.build
index f0ac2d0..0de8e33 100644
--- a/usb/meson.build
+++ b/usb/meson.build
@@ -9,13 +9,21 @@
source = [
'usb_manager_main.cpp',
+ 'usb_manager.cpp',
]
+phosphor_logging_dep = dependency(
+ 'phosphor-logging',
+ fallback: ['phosphor-logging', 'phosphor_logging_dep'],
+)
+
executable(
'phosphor-usb-code-update',
source,
+ include_directories: ['..'],
dependencies: [
CLI11_dep,
+ phosphor_logging_dep,
],
install: true,
install_dir: get_option('bindir')
diff --git a/usb/usb_manager.cpp b/usb/usb_manager.cpp
new file mode 100644
index 0000000..b002dbd
--- /dev/null
+++ b/usb/usb_manager.cpp
@@ -0,0 +1,50 @@
+#include "config.h"
+
+#include "usb_manager.hpp"
+
+namespace phosphor
+{
+namespace usb
+{
+
+bool USBManager::run()
+{
+ fs::path dir(usbPath);
+ if (!fs::exists(dir))
+ {
+ return false;
+ }
+
+ for (const auto& p : std::filesystem::directory_iterator(dir))
+ {
+ if (p.path().extension() == ".tar")
+ {
+ fs::path dstPath{IMG_UPLOAD_DIR / p.path().filename()};
+ if (fs::exists(dstPath))
+ {
+ lg2::info(
+ "{DSTPATH} already exists in the /tmp/images directory, exit the upgrade",
+ "DSTPATH", p.path().filename());
+
+ break;
+ }
+
+ try
+ {
+ return fs::copy_file(fs::absolute(p.path()), dstPath);
+ }
+ catch (const std::exception& e)
+ {
+ lg2::error("Error when copying {SRC} to /tmp/images: {ERROR}",
+ "SRC", p.path(), "ERROR", e.what());
+ }
+
+ break;
+ }
+ }
+
+ return false;
+}
+
+} // namespace usb
+} // namespace phosphor
\ No newline at end of file
diff --git a/usb/usb_manager.hpp b/usb/usb_manager.hpp
new file mode 100644
index 0000000..f3323a8
--- /dev/null
+++ b/usb/usb_manager.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <filesystem>
+
+namespace phosphor
+{
+namespace usb
+{
+namespace fs = std::filesystem;
+
+class USBManager
+{
+ public:
+ ~USBManager() = default;
+ USBManager() = delete;
+ USBManager(const USBManager&) = delete;
+ USBManager(USBManager&&) = default;
+ USBManager& operator=(const USBManager&) = delete;
+ USBManager& operator=(USBManager&&) = default;
+
+ explicit USBManager(const fs::path& path) : usbPath(path)
+ {}
+
+ /** @brief Find the first file with a .tar extension according to the USB
+ * file path.
+ *
+ * @return Success or Fail
+ */
+ bool run();
+
+ private:
+ /** The USB path detected. */
+ const fs::path& usbPath;
+};
+
+} // namespace usb
+} // namespace phosphor
diff --git a/usb/usb_manager_main.cpp b/usb/usb_manager_main.cpp
index b5a538d..143125d 100644
--- a/usb/usb_manager_main.cpp
+++ b/usb/usb_manager_main.cpp
@@ -1,14 +1,35 @@
+#include "usb_manager.hpp"
+
#include <CLI/CLI.hpp>
+#include <phosphor-logging/lg2.hpp>
int main(int argc, char** argv)
{
+ namespace fs = std::filesystem;
+
std::string fileName{};
CLI::App app{"Update the firmware of OpenBMC via USB app"};
app.add_option("-f,--fileName", fileName,
- "Get the name of the USB mount folder");
+ "Get the name of the USB mount folder, eg: sda1, sdb1");
CLI11_PARSE(app, argc, argv);
+ if (fileName.empty())
+ {
+ lg2::error("The file name passed in is empty.");
+ return -1;
+ }
+
+ fs::path usbPath = fs::path{"/run/media/usb"} / fileName;
+ phosphor::usb::USBManager manager(usbPath);
+
+ if (!manager.run())
+ {
+ lg2::error("Failed to FW Update via USB, usbPath:{USBPATH}", "USBPATH",
+ usbPath);
+ return -1;
+ }
+
return 0;
}