Async request to create PEL

To avoid any deadlocks between phosphor-logging and vpd-manager
service a wrapper around request to create PEL is created
which enables vpd-manager to make async requests to create PEL.

It also implements a new exception type to throw any GPIO
related exception. This was required to throw specific
exception.

Test:
Scenario 1:
While vpd-manager logs a pel with call out to an inventory
item.
It should be checked that both the services do not enter into
a deadlock situation.

Scenario 2:
Any third process is requesting to log PEL with call out
to an inventory item in a loop.
In the mean time vpd-manager also requests to log a PEL
with or without call out to inventory item.
All the pels should be logged correctly in the system.
No deadlock should appear.

Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
Change-Id: I0efaf6918e679ca94808fc70d747c843a50eaf78
diff --git a/vpd-manager/manager.cpp b/vpd-manager/manager.cpp
index 7fa09ee..35d9ddf 100644
--- a/vpd-manager/manager.cpp
+++ b/vpd-manager/manager.cpp
@@ -449,15 +449,28 @@
         if ((jsonFile["frus"][item].at(0)).find("preAction") !=
             jsonFile["frus"][item].at(0).end())
         {
-            if (!executePreAction(jsonFile, item))
+            try
             {
-                // if the FRU has preAction defined then its execution should
-                // pass to ensure bind/unbind of data.
-                // preAction execution failed. should not call bind/unbind.
-                log<level::ERR>(
-                    "Pre-Action execution failed for the FRU",
-                    entry("ERROR=%s",
-                          ("Inventory path: " + inventoryPath).c_str()));
+                if (!executePreAction(jsonFile, item))
+                {
+                    // if the FRU has preAction defined then its execution
+                    // should pass to ensure bind/unbind of data.
+                    // preAction execution failed. should not call
+                    // bind/unbind.
+                    log<level::ERR>(
+                        "Pre-Action execution failed for the FRU",
+                        entry("ERROR=%s",
+                              ("Inventory path: " + inventoryPath).c_str()));
+                    continue;
+                }
+            }
+            catch (const GpioException& e)
+            {
+                log<level::ERR>(e.what());
+                PelAdditionalData additionalData{};
+                additionalData.emplace("DESCRIPTION", e.what());
+                createPEL(additionalData, PelSeverity::WARNING,
+                          errIntfForGpioError, sdBus);
                 continue;
             }
             prePostActionRequired = true;
@@ -529,8 +542,18 @@
             // Check if device showed up (test for file)
             if (!filesystem::exists(item))
             {
-                // If not, then take failure postAction
-                executePostFailAction(jsonFile, item);
+                try
+                {
+                    // If not, then take failure postAction
+                    executePostFailAction(jsonFile, item);
+                }
+                catch (const GpioException& e)
+                {
+                    PelAdditionalData additionalData{};
+                    additionalData.emplace("DESCRIPTION", e.what());
+                    createPEL(additionalData, PelSeverity::WARNING,
+                              errIntfForGpioError, sdBus);
+                }
             }
         }
     }