summaryrefslogtreecommitdiffstats
path: root/watch.cpp
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2017-04-12 06:40:53 -0500
committerDeepak Kodihalli <dkodihal@in.ibm.com>2017-04-18 11:54:17 -0500
commit059e23355e0563ed22661ec2a78ccdc563414a7d (patch)
treebad284e0c2dd7e730cdc291b084be951c064b663 /watch.cpp
parent7f160bc8fa94fbec69a15ab707f10f6d0122ca8b (diff)
downloadphosphor-bmc-code-mgmt-059e23355e0563ed22661ec2a78ccdc563414a7d.tar.gz
phosphor-bmc-code-mgmt-059e23355e0563ed22661ec2a78ccdc563414a7d.zip
image manager: add inotify watch
Add an inotify watch to the known software image location. Hook the inotify fd with sd-event, so that on callback, version d-bus objects can be created based on the newly added software image. Resolves openbmc/openbmc#1444. Change-Id: I5c460f820c8d3a851b8ddc969f26d38870c36991 Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Diffstat (limited to 'watch.cpp')
-rw-r--r--watch.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/watch.cpp b/watch.cpp
new file mode 100644
index 0000000..a520dd2
--- /dev/null
+++ b/watch.cpp
@@ -0,0 +1,104 @@
+#include <stdexcept>
+#include <cstddef>
+#include <cstring>
+#include <string>
+#include <sys/inotify.h>
+#include <unistd.h>
+#include <phosphor-logging/log.hpp>
+#include "config.h"
+#include "watch.hpp"
+
+namespace phosphor
+{
+namespace software
+{
+namespace manager
+{
+
+using namespace std::string_literals;
+
+Watch::Watch(sd_event* loop)
+{
+ fd = inotify_init1(IN_NONBLOCK);
+ if (-1 == fd)
+ {
+ // Store a copy of errno, because the string creation below will
+ // invalidate errno due to one more system calls.
+ auto error = errno;
+ throw std::runtime_error(
+ "inotify_init1 failed, errno="s + std::strerror(error));
+ }
+
+ wd = inotify_add_watch(fd, IMG_UPLOAD_DIR, IN_CREATE);
+ if (-1 == wd)
+ {
+ auto error = errno;
+ close(fd);
+ throw std::runtime_error(
+ "inotify_add_watch failed, errno="s + std::strerror(error));
+ }
+
+ auto rc = sd_event_add_io(loop,
+ nullptr,
+ fd,
+ EPOLLIN,
+ callback,
+ this);
+ if (0 > rc)
+ {
+ throw std::runtime_error(
+ "failed to add to event loop, rc="s + std::strerror(-rc));
+ }
+}
+
+Watch::~Watch()
+{
+ if ((-1 != fd) && (-1 != wd))
+ {
+ inotify_rm_watch(fd, wd);
+ close(fd);
+ }
+}
+
+int Watch::callback(sd_event_source* s,
+ int fd,
+ uint32_t revents,
+ void* userdata)
+{
+ if (!(revents & EPOLLIN))
+ {
+ return 0;
+ }
+
+ constexpr auto maxBytes = 1024;
+ uint8_t buffer[maxBytes];
+ auto bytes = read(fd, buffer, maxBytes);
+ if (0 > bytes)
+ {
+ auto error = errno;
+ throw std::runtime_error(
+ "failed to read inotify event, errno="s + std::strerror(error));
+ }
+
+ auto offset = 0;
+ while (offset < bytes)
+ {
+ auto event = reinterpret_cast<inotify_event*>(&buffer[offset]);
+ if ((event->mask & IN_CREATE) && !(event->mask & IN_ISDIR))
+ {
+ // TODO: openbmc/openbmc#1352 - invoke method (which takes uploaded
+ // filepath) to construct software version d-bus objects.
+ // For now, log the image filename.
+ using namespace phosphor::logging;
+ log<level::INFO>(event->name);
+ }
+
+ offset += offsetof(inotify_event, name) + event->len;
+ }
+
+ return 0;
+}
+
+} // namespace manager
+} // namespace software
+} // namespace phosphor
OpenPOWER on IntegriCloud