Bug fix 61/257861/6 accepted/tizen/6.5/unified/20211028.115403 accepted/tizen/unified/20210505.141432 submit/tizen/20210504.124833 submit/tizen_6.5/20211028.163201 tizen_6.5.m2_release
authorYoungjae Cho <y0.cho@samsung.com>
Tue, 4 May 2021 10:10:13 +0000 (19:10 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Tue, 4 May 2021 12:42:42 +0000 (21:42 +0900)
udev_control_kernel_start() can be invoked multiple times
from multiple hal-backend modules. Therefore do not return
error for duplicate invocation.

Change-Id: Icd3586aec4281ad23b39c26a21d7cff13a8ca80b
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
src/udev/udev.c

index f2a4a3d..291e605 100644 (file)
@@ -35,11 +35,12 @@ struct uevent_info {
        GIOChannel *ch;
        guint eventid;
        GList *event_list;
+       int ref;
+       struct udev *udev;
 };
 
 
 /* Uevent */
-static struct udev *udev;
 static struct uevent_info kevent; /* kernel */
 static struct uevent_info uevent; /* udev */
 
@@ -89,6 +90,9 @@ static int uevent_control_stop(struct uevent_info *info)
        if (!info)
                return -EINVAL;
 
+       if (--info->ref > 0)
+               return 0;
+
        if (info->eventid) {
                g_source_remove(info->eventid);
                info->eventid = 0;
@@ -104,37 +108,34 @@ static int uevent_control_stop(struct uevent_info *info)
                udev_monitor_unref(info->mon);
                info->mon = NULL;
        }
-       if (udev)
-               udev = udev_unref(udev);
+       if (info->udev)
+               info->udev = udev_unref(info->udev);
+
        return 0;
 }
 
 static int uevent_control_start(const char *type,
                struct uevent_info *info)
 {
-       struct uevent_handler *l;
-       GList *elem;
        int fd;
        int ret;
 
        if (!info)
                return -EINVAL;
 
-       if (info->mon) {
-               _E("%s uevent control routine is alreay started", type);
-               return -EINVAL;
-       }
-
-       if (!udev) {
-               udev = udev_new();
-               if (!udev) {
+       if (!info->udev) {
+               info->udev = udev_new();
+               if (!info->udev) {
                        _E("error create udev");
                        return -EINVAL;
                }
-       } else
-               udev = udev_ref(udev);
+               info->ref = 1;
+       } else {
+               ++info->ref;
+               return 0;
+       }
 
-       info->mon = udev_monitor_new_from_netlink(udev, type);
+       info->mon = udev_monitor_new_from_netlink(info->udev, type);
        if (info->mon == NULL) {
                _E("error udev_monitor create");
                goto stop;
@@ -148,21 +149,6 @@ static int uevent_control_start(const char *type,
                goto stop;
        }
 
-       for (elem = info->event_list ; elem ; elem = g_list_next(elem)) {
-               l = elem->data;
-               ret = udev_monitor_filter_add_match_subsystem_devtype(
-                               info->mon,
-                               l->subsystem, NULL);
-               if (ret < 0) {
-                       _E("error apply subsystem filter");
-                       goto stop;
-               }
-       }
-
-       ret = udev_monitor_filter_update(info->mon);
-       if (ret < 0)
-               _E("error udev_monitor_filter_update");
-
        fd = udev_monitor_get_fd(info->mon);
        if (fd == -1) {
                _E("error udev_monitor_get_fd");
@@ -214,34 +200,29 @@ static int register_uevent_control(struct uevent_info *info,
        struct uevent_handler *l;
        GList *elem;
        int r;
-       bool matched = false;
        int len;
 
        if (!info || !uh || !uh->subsystem)
                return -EINVAL;
 
        /* if udev is not initialized, it just will be added list */
-       if (!udev || !info->mon)
+       if (!info->udev || !info->mon)
                goto add_list;
 
        len = strlen(uh->subsystem);
        /* check if the same subsystem is already added */
        for (elem = info->event_list; elem ; elem = g_list_next(elem)) {
                l = elem->data;
-               if (!strncmp(l->subsystem, uh->subsystem, len)) {
-                       matched = true;
-                       break;
-               }
+               if (!strncmp(l->subsystem, uh->subsystem, len))
+                       goto add_list;
        }
 
        /* the first request to add subsystem */
-       if (!matched) {
-               r = udev_monitor_filter_add_match_subsystem_devtype(info->mon,
-                               uh->subsystem, NULL);
-               if (r < 0) {
-                       _E("fail to add %s subsystem : %d", uh->subsystem, r);
-                       return -EPERM;
-               }
+       r = udev_monitor_filter_add_match_subsystem_devtype(info->mon,
+                       uh->subsystem, NULL);
+       if (r < 0) {
+               _E("fail to add %s subsystem : %d", uh->subsystem, r);
+               return -EPERM;
        }
 
        r = udev_monitor_filter_update(info->mon);