chiark / gitweb /
link-config: support --enable-split-usr
[elogind.git] / src / udev / udev-event.c
index 8c8b058df78954fb19b47d0633578f16179474dc..0d1049cf1cc13ceb725e072a277754bdc8abb88b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <string.h>
 #include <time.h>
 #include <net/if.h>
-#include <sys/ioctl.h>
 #include <sys/prctl.h>
 #include <sys/poll.h>
 #include <sys/epoll.h>
 #include <sys/wait.h>
-#include <sys/socket.h>
 #include <sys/signalfd.h>
-#include <linux/sockios.h>
 
 #include "udev.h"
+#include "rtnl-util.h"
 
 struct udev_event *udev_event_new(struct udev_device *dev)
 {
@@ -47,6 +45,7 @@ struct udev_event *udev_event_new(struct udev_device *dev)
         event->dev = dev;
         event->udev = udev;
         udev_list_init(udev, &event->run_list, false);
+        udev_list_init(udev, &event->seclabel_list, false);
         event->fd_signal = -1;
         event->birth_usec = now(CLOCK_MONOTONIC);
         event->timeout_usec = 30 * 1000 * 1000;
@@ -58,6 +57,7 @@ void udev_event_unref(struct udev_event *event)
         if (event == NULL)
                 return;
         udev_list_cleanup(&event->run_list);
+        udev_list_cleanup(&event->seclabel_list);
         free(event->program_result);
         free(event->name);
         free(event);
@@ -748,32 +748,30 @@ out:
 static int rename_netif(struct udev_event *event)
 {
         struct udev_device *dev = event->dev;
-        int sk;
-        struct ifreq ifr;
-        int err;
+        _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        char name[IFNAMSIZ];
+        const char *oldname;
+        int r;
+
+        oldname = udev_device_get_sysname(dev);
 
         log_debug("changing net interface name from '%s' to '%s'\n",
-                  udev_device_get_sysname(dev), event->name);
+                  oldname, event->name);
 
-        sk = socket(PF_INET, SOCK_DGRAM, 0);
-        if (sk < 0) {
-                err = -errno;
-                log_error("error opening socket: %m\n");
-                return err;
-        }
+        strscpy(name, IFNAMSIZ, event->name);
 
-        memset(&ifr, 0x00, sizeof(struct ifreq));
-        strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev));
-        strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
-        err = ioctl(sk, SIOCSIFNAME, &ifr);
-        if (err >= 0) {
-                print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
-        } else {
-                err = -errno;
-                log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname);
-        }
-        close(sk);
-        return err;
+        r = sd_rtnl_open(0, &rtnl);
+        if (r < 0)
+                return r;
+
+        r = rtnl_set_link_name(rtnl, udev_device_get_ifindex(dev), name);
+        if (r < 0)
+                log_error("error changing net interface name %s to %s: %s",
+                          oldname, name, strerror(-r));
+        else
+                print_kmsg("renamed network interface %s to %s", oldname, name);
+
+        return r;
 }
 
 int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask)
@@ -784,7 +782,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
         if (udev_device_get_subsystem(dev) == NULL)
                 return -1;
 
-        if (strcmp(udev_device_get_action(dev), "remove") == 0) {
+        if (streq(udev_device_get_action(dev), "remove")) {
                 udev_device_read_db(dev, NULL);
                 udev_device_delete_db(dev);
                 udev_device_tag_index(dev, NULL, false);
@@ -812,8 +810,8 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                 udev_rules_apply_to_event(rules, event, sigmask);
 
                 /* rename a new network interface, if needed */
-                if (udev_device_get_ifindex(dev) > 0 && strcmp(udev_device_get_action(dev), "add") == 0 &&
-                    event->name != NULL && strcmp(event->name, udev_device_get_sysname(dev)) != 0) {
+                if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
+                    event->name != NULL && !streq(event->name, udev_device_get_sysname(dev))) {
                         char syspath[UTIL_PATH_SIZE];
                         char *pos;
 
@@ -838,6 +836,8 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                 }
 
                 if (major(udev_device_get_devnum(dev)) > 0) {
+                        bool apply;
+
                         /* remove/update possible left-over symlinks from old database entry */
                         if (event->dev_db != NULL)
                                 udev_node_update_old_links(dev, event->dev_db);
@@ -861,7 +861,8 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                                 }
                         }
 
-                        udev_node_add(dev, event->mode, event->uid, event->gid);
+                        apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set;
+                        udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list);
                 }
 
                 /* preserve old, or get new initialization timestamp */