Răsfoiți Sursa

ncd/modules/net_backend_waitdevice.c: port to NCDUdevManager

ambrop7 15 ani în urmă
părinte
comite
c4f6ccbe6b
1 a modificat fișierele cu 68 adăugiri și 28 ștergeri
  1. 68 28
      ncd/modules/net_backend_waitdevice.c

+ 68 - 28
ncd/modules/net_backend_waitdevice.c

@@ -24,14 +24,16 @@
  * Module which waits for the presence of a network interface.
  * 
  * Synopsis: net.backend.waitdevice(string ifname)
+ * Description: statement is UP when a network interface named ifname
+ *   exists, and DOWN when it does not.
  */
 
 #include <stdlib.h>
 #include <string.h>
 
+#include <misc/parse_number.h>
 #include <ncd/NCDModule.h>
 #include <ncd/NCDIfConfig.h>
-#include <ncd/NCDInterfaceMonitor.h>
 
 #include <generated/blog_channel_ncd_net_backend_waitdevice.h>
 
@@ -40,24 +42,65 @@
 struct instance {
     NCDModuleInst *i;
     const char *ifname;
-    NCDInterfaceMonitor monitor;
-    int up;
+    NCDUdevClient client;
+    char *devpath;
+    uintmax_t ifindex;
 };
 
-static void monitor_handler (struct instance *o, const char *ifname, int if_flags)
+static void client_handler (struct instance *o, char *devpath, int have_map, BStringMap map)
 {
-    if (strcmp(ifname, o->ifname)) {
-        return;
+    if (o->devpath && !strcmp(devpath, o->devpath) && !NCDUdevManager_Query(o->i->umanager, o->devpath)) {
+        // free devpath
+        free(o->devpath);
+        
+        // set no devpath
+        o->devpath = NULL;
+        
+        // signal down
+        NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_DOWN);
+    } else {
+        const BStringMap *cache_map = NCDUdevManager_Query(o->i->umanager, devpath);
+        if (!cache_map) {
+            goto out;
+        }
+        
+        const char *subsystem = BStringMap_Get(cache_map, "SUBSYSTEM");
+        const char *interface = BStringMap_Get(cache_map, "INTERFACE");
+        const char *ifindex_str = BStringMap_Get(cache_map, "IFINDEX");
+        
+        uintmax_t ifindex;
+        if (!(subsystem && !strcmp(subsystem, "net") && interface && !strcmp(interface, o->ifname) && ifindex_str && parse_unsigned_integer(ifindex_str, &ifindex))) {
+            goto out;
+        }
+        
+        if (o->devpath && (strcmp(o->devpath, devpath) || o->ifindex != ifindex)) {
+            // free devpath
+            free(o->devpath);
+            
+            // set no devpath
+            o->devpath = NULL;
+            
+            // signal down
+            NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_DOWN);
+        }
+        
+        if (!o->devpath) {
+            // grab devpath
+            o->devpath = devpath;
+            devpath = NULL;
+            
+            // remember ifindex
+            o->ifindex = ifindex;
+            
+            // signal up
+            NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
+        }
     }
     
-    int was_up = o->up;
-    o->up = !!(if_flags & NCDIFCONFIG_FLAG_EXISTS);
-    
-    if (o->up && !was_up) {
-        NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
-    }
-    else if (!o->up && was_up) {
-        NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_DOWN);
+out:
+    free(devpath);
+    if (have_map) {
+        BStringMap_Free(&map);
     }
 }
 
@@ -86,19 +129,11 @@ static void func_new (NCDModuleInst *i)
     }
     o->ifname = NCDValue_StringValue(arg);
     
-    // init monitor
-    if (!NCDInterfaceMonitor_Init(&o->monitor, o->i->reactor, (NCDInterfaceMonitor_handler)monitor_handler, o)) {
-        ModuleLog(o->i, BLOG_ERROR, "NCDInterfaceMonitor_Init failed");
-        goto fail1;
-    }
-    
-    // query initial state
-    o->up = !!(NCDIfConfig_query(o->ifname) & NCDIFCONFIG_FLAG_EXISTS);
+    // init client
+    NCDUdevClient_Init(&o->client, o->i->umanager, o, (NCDUdevClient_handler)client_handler);
     
-    // signal up if needed
-    if (o->up) {
-        NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
-    }
+    // set no devpath
+    o->devpath = NULL;
     
     return;
     
@@ -114,8 +149,13 @@ static void func_die (void *vo)
     struct instance *o = vo;
     NCDModuleInst *i = o->i;
     
-    // free monitor
-    NCDInterfaceMonitor_Free(&o->monitor);
+    // free devpath
+    if (o->devpath) {
+        free(o->devpath);
+    }
+    
+    // free client
+    NCDUdevClient_Free(&o->client);
     
     // free instance
     free(o);