Enable user initiated dump child directory level file watch

Change-Id: I38b1f0a06e96a465526ea1ac497e49dc5f778dd8
Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
diff --git a/dump_manager.cpp b/dump_manager.cpp
index 3b00119..3d8bdc2 100644
--- a/dump_manager.cpp
+++ b/dump_manager.cpp
@@ -117,13 +117,39 @@
 {
     for (const auto& i : fileInfo)
     {
-        // For any new dump file create dump entry object.
+        // For any new dump file create dump entry object
+        // and associated inotify watch.
         if (IN_CLOSE_WRITE == i.second)
         {
+            removeWatch(i.first);
+
             createEntry(i.first);
         }
+        // Start inotify watch on newly created directory.
+        else if ((IN_CREATE == i.second) && fs::is_directory(i.first))
+        {
+            auto watchObj = std::make_unique<Watch>(
+                                    eventLoop,
+                                    IN_NONBLOCK,
+                                    IN_CLOSE_WRITE,
+                                    EPOLLIN,
+                                    i.first,
+                                    std::bind(
+                                         std::mem_fn(
+                                      &phosphor::dump::Manager::watchCallback),
+                                         this, std::placeholders::_1));
+
+           childWatchMap.emplace(i.first, std::move(watchObj));
+        }
+
     }
 }
 
+void Manager::removeWatch(const fs::path& path)
+{
+    //Delete Watch entry from map.
+    childWatchMap.erase(path);
+}
+
 } //namespace dump
 } //namespace phosphor
diff --git a/dump_manager.hpp b/dump_manager.hpp
index 4e6715b..003d9e4 100644
--- a/dump_manager.hpp
+++ b/dump_manager.hpp
@@ -33,6 +33,8 @@
 
 namespace fs = std::experimental::filesystem;
 
+using Watch = phosphor::dump::inotify::Watch;
+
 /** @class Manager
  *  @brief OpenBMC Dump  manager implementation.
  *  @details A concrete implementation for the
@@ -123,6 +125,11 @@
             //the sd_event_add_child callback.
             return 0;
         }
+        /** @brief Remove specified watch object pointer from the
+          *        watch map and associated entry from the map.
+          *        @param[in] path - unique identifier of the map
+          */
+        void removeWatch(const fs::path& path);
 
         /** @brief sdbusplus DBus bus connection. */
         sdbusplus::bus::bus& bus;
@@ -136,8 +143,13 @@
         /** @brief Id of the last Dump entry */
         uint32_t lastEntryId;
 
-        /** @brief Dump watch object */
-        phosphor::dump::inotify::Watch dumpWatch;
+        /** @brief Dump main watch object */
+        Watch dumpWatch;
+
+        /** @brief Child directory path and its associated watch object map
+          *        [path:watch object]
+          */
+        std::map<fs::path, std::unique_ptr<Watch>> childWatchMap;
 };
 
 } // namespace dump
diff --git a/watch.cpp b/watch.cpp
index bc7fb1f..cec97af 100644
--- a/watch.cpp
+++ b/watch.cpp
@@ -87,7 +87,9 @@
                     uint32_t revents,
                     void* userdata)
 {
-    if (!(revents & static_cast<Watch*>(userdata)->events))
+    auto userData = static_cast<Watch*>(userdata);
+
+    if (!(revents & userData->events))
     {
         return 0;
     }
@@ -115,12 +117,12 @@
     while (offset < bytes)
     {
         auto event = reinterpret_cast<inotify_event*>(&buffer[offset]);
-        auto mask = event->mask & static_cast<Watch*>(userdata)->mask;
+        auto mask = event->mask & userData->mask;
 
-        if (mask && !(event->mask & IN_ISDIR))
+        if (mask)
         {
             userMap.emplace(
-                    (static_cast<Watch*>(userdata)->path / event->name), mask);
+                    (userData->path / event->name), mask);
         }
 
         offset += offsetof(inotify_event, name) + event->len;
@@ -129,7 +131,7 @@
     //Call user call back function incase valid data in the map
     if (!userMap.empty())
     {
-        static_cast<Watch*>(userdata)->userFunc(userMap);
+        userData->userFunc(userMap);
     }
 
     return 0;