diff options
author | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-04-12 06:40:53 -0500 |
---|---|---|
committer | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-04-18 11:54:17 -0500 |
commit | 059e23355e0563ed22661ec2a78ccdc563414a7d (patch) | |
tree | bad284e0c2dd7e730cdc291b084be951c064b663 /watch.cpp | |
parent | 7f160bc8fa94fbec69a15ab707f10f6d0122ca8b (diff) | |
download | phosphor-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.cpp | 104 |
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 |