1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-28 20:25:38 +03:00
systemd/udev-add.c

474 lines
10 KiB
C
Raw Normal View History

/*
* udev-add.c
*
* Userspace devfs
*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
*
*
* 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 the
* Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <grp.h>
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#ifndef __KLIBC__
#include <pwd.h>
#include <utmp.h>
#endif
#include "libsysfs/sysfs/libsysfs.h"
#include "udev.h"
#include "udev_lib.h"
#include "udev_version.h"
#include "logging.h"
#include "namedev.h"
[PATCH] udevdb prototype Here's an "idea" of what I had in mind for udevdb. Let me preface the code with a few remarks: 1) I was expecting to write this udevdb for udev to keep track of devices. I was planning an external package that depends upon udev to provide an external API to the udevdb database. The calls for the interface would be read only access. Not sure how you want to do packaging, if having a separate package is ok or having it included in udev. 2) I created it as it is because udev isn't a daemon. So, the open database call doesn't take any parameters. My plan was to create a udevdb_init function that took arguments for initializing the db to start, where you could specify in memory only or a file location. This can all be filled in. 3) I hacked the Makefile to get it to work. Not sure how you'd want that in the future. 4) This assumes TDB has been installed elsewhere, you would need to edit your Makefile and point it to the header and library locations. How do you want to do TDB in udev? Do you want to just reference it and make udev dependent on that package being installed. Or should we do what samba does and include a limited tdb version in udev? 5) Again, I hacked udev into your existing code. In the future, I'd probably make a function around the filling out the udevice before calling the store command. Didn't know if you wanted to change your add device function to use struct udevice rather than having everything separate. 6) Not sure what we should include in the udevice structure that's stored by udev. I made a stab at a first shot - we can add and remove of course, this was a first pass. I've come to realize - with you including libsysfs in udev, the "external" interface that references udevdb could make use of getting information from through libsysfs from sysfs and doesn't need to be in udevdb. 7) I could write a namedevdb for namedev's device management if you wanted.
2003-08-06 10:57:23 +04:00
#include "udevdb.h"
#include "klibc_fixups.h"
#define LOCAL_USER "$local"
/*
* Right now the major/minor of a device is stored in a file called
* "dev" in sysfs.
* The number is stored as:
* MM:mm
* MM is the major
* mm is the minor
* The value is in decimal.
*/
static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev)
{
int retval = -ENODEV;
struct sysfs_attribute *attr = NULL;
attr = sysfs_get_classdev_attr(class_dev, "dev");
if (attr == NULL)
goto exit;
dbg("dev='%s'", attr->value);
if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2)
goto exit;
dbg("found major=%d, minor=%d", udev->major, udev->minor);
retval = 0;
exit:
return retval;
}
static int create_path(char *file)
{
char p[NAME_SIZE];
char *pos;
int retval;
struct stat stats;
strfieldcpy(p, file);
pos = strchr(p+1, '/');
while (1) {
pos = strchr(pos+1, '/');
if (pos == NULL)
break;
*pos = 0x00;
if (stat(p, &stats)) {
retval = mkdir(p, 0755);
if (retval != 0) {
dbg("mkdir(%s) failed with error '%s'",
p, strerror(errno));
return retval;
}
dbg("created '%s'", p);
}
*pos = '/';
}
return 0;
}
static int make_node(char *filename, int major, int minor, unsigned int mode, uid_t uid, gid_t gid)
{
int retval;
retval = mknod(filename, mode, makedev(major, minor));
if (retval != 0) {
dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
filename, mode, major, minor, strerror(errno));
return retval;
}
dbg("chmod(%s, %#o)", filename, mode);
retval = chmod(filename, mode);
if (retval != 0) {
dbg("chmod(%s, %#o) failed with error '%s'",
filename, mode, strerror(errno));
return retval;
}
if (uid != 0 || gid != 0) {
dbg("chown(%s, %u, %u)", filename, uid, gid);
retval = chown(filename, uid, gid);
if (retval != 0) {
dbg("chown(%s, %u, %u) failed with error '%s'",
filename, uid, gid, strerror(errno));
return retval;
}
}
return 0;
}
/* get the local logged in user */
static void set_to_local_user(char *user)
{
struct utmp *u;
time_t recent = 0;
strfieldcpymax(user, default_owner_str, OWNER_SIZE);
setutent();
while (1) {
u = getutent();
if (u == NULL)
break;
/* is this a user login ? */
if (u->ut_type != USER_PROCESS)
continue;
/* is this a local login ? */
if (strcmp(u->ut_host, ""))
continue;
if (u->ut_time > recent) {
recent = u->ut_time;
strfieldcpymax(user, u->ut_user, OWNER_SIZE);
dbg("local user is '%s'", user);
break;
}
}
endutent();
}
/* Used to unlink existing files to ensure that our new file/symlink is created */
static int unlink_entry(char *filename)
{
struct stat stats;
int retval = 0;
if (lstat(filename, &stats) == 0) {
if ((stats.st_mode & S_IFMT) != S_IFDIR) {
retval = unlink(filename);
if (retval) {
dbg("unlink(%s) failed with error '%s'",
filename, strerror(errno));
}
}
}
return retval;
}
static int create_node(struct udevice *dev, int fake)
{
char filename[NAME_SIZE];
char linkname[NAME_SIZE];
char linktarget[NAME_SIZE];
char partitionname[NAME_SIZE];
int retval = 0;
uid_t uid = 0;
gid_t gid = 0;
int i;
int tail;
char *pos;
int len;
strfieldcpy(filename, udev_root);
strfieldcat(filename, dev->name);
switch (dev->type) {
2003-08-05 08:59:50 +04:00
case 'b':
dev->mode |= S_IFBLK;
2003-08-05 08:59:50 +04:00
break;
case 'c':
case 'u':
dev->mode |= S_IFCHR;
2003-08-05 08:59:50 +04:00
break;
case 'p':
dev->mode |= S_IFIFO;
2003-08-05 08:59:50 +04:00
break;
default:
dbg("unknown node type %c\n", dev->type);
2003-08-05 08:59:50 +04:00
return -EINVAL;
}
/* create parent directories if needed */
if (strrchr(dev->name, '/'))
create_path(filename);
if (dev->owner[0] != '\0') {
char *endptr;
unsigned long id = strtoul(dev->owner, &endptr, 10);
if (endptr[0] == '\0')
uid = (uid_t) id;
else {
struct passwd *pw;
if (strncmp(dev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0)
set_to_local_user(dev->owner);
pw = getpwnam(dev->owner);
if (pw == NULL)
dbg("specified user unknown '%s'", dev->owner);
else
uid = pw->pw_uid;
}
}
if (dev->group[0] != '\0') {
char *endptr;
unsigned long id = strtoul(dev->group, &endptr, 10);
if (endptr[0] == '\0')
gid = (gid_t) id;
else {
struct group *gr = getgrnam(dev->group);
if (gr == NULL)
dbg("specified group unknown '%s'", dev->group);
else
gid = gr->gr_gid;
}
}
if (!fake) {
unlink_entry(filename);
info("creating device node '%s'", filename);
make_node(filename, dev->major, dev->minor, dev->mode, uid, gid);
} else {
info("creating device node '%s', major = '%d', minor = '%d', "
"mode = '%#o', uid = '%d', gid = '%d'", filename,
dev->major, dev->minor, (mode_t)dev->mode, uid, gid);
}
/* create partitions if requested */
if (dev->partitions > 0) {
info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions);
if (!fake) {
for (i = 1; i <= dev->partitions; i++) {
strfieldcpy(partitionname, filename);
strintcat(partitionname, i);
unlink_entry(partitionname);
make_node(partitionname, dev->major,
dev->minor + i, dev->mode, uid, gid);
}
}
}
/* create symlink if requested */
foreach_strpart(dev->symlink, " ", pos, len) {
strfieldcpymax(linkname, pos, len+1);
strfieldcpy(filename, udev_root);
strfieldcat(filename, linkname);
dbg("symlink '%s' to node '%s' requested", filename, dev->name);
if (!fake)
if (strrchr(linkname, '/'))
create_path(filename);
/* optimize relative link */
linktarget[0] = '\0';
i = 0;
tail = 0;
while ((dev->name[i] == linkname[i]) && dev->name[i]) {
if (dev->name[i] == '/')
tail = i+1;
i++;
}
while (linkname[i] != '\0') {
if (linkname[i] == '/')
strfieldcat(linktarget, "../");
i++;
}
strfieldcat(linktarget, &dev->name[tail]);
if (!fake)
unlink_entry(filename);
dbg("symlink(%s, %s)", linktarget, filename);
if (!fake) {
retval = symlink(linktarget, filename);
if (retval != 0)
dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno));
}
}
return retval;
}
static struct sysfs_class_device *get_class_dev(char *device_name)
{
char dev_path[SYSFS_PATH_MAX];
2003-08-05 09:13:35 +04:00
struct sysfs_class_device *class_dev = NULL;
strfieldcpy(dev_path, sysfs_path);
strfieldcat(dev_path, device_name);
dbg("looking at '%s'", dev_path);
/* open up the sysfs class device for this thing... */
class_dev = sysfs_open_class_device_path(dev_path);
if (class_dev == NULL) {
dbg ("sysfs_open_class_device_path failed");
2003-08-05 09:13:35 +04:00
goto exit;
}
dbg("class_dev->name='%s'", class_dev->name);
2003-08-05 09:13:35 +04:00
exit:
return class_dev;
}
/* wait for the "dev" file to show up in the directory in sysfs.
* If it doesn't happen in about 10 seconds, give up.
*/
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
#define SECONDS_TO_WAIT_FOR_FILE 10
static int sleep_for_file(char *path, char* file)
{
char filename[SYSFS_PATH_MAX + 6];
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
int loop = SECONDS_TO_WAIT_FOR_FILE;
int retval;
strfieldcpy(filename, sysfs_path);
strfieldcat(filename, path);
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
strfieldcat(filename, file);
while (loop--) {
struct stat buf;
dbg("looking for '%s'", filename);
retval = stat(filename, &buf);
if (retval == 0)
goto exit;
/* sleep to give the kernel a chance to create the dev file */
sleep(1);
}
retval = -ENODEV;
exit:
return retval;
}
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
static int rename_net_if(struct udevice *dev)
{
int sk;
struct ifreq ifr;
int retval;
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0) {
dbg("error opening socket");
return -1;
}
memset(&ifr, 0x00, sizeof(struct ifreq));
strfieldcpy(ifr.ifr_name, dev->kernel_name);
strfieldcpy(ifr.ifr_newname, dev->name);
dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name);
retval = ioctl(sk, SIOCSIFNAME, &ifr);
if (retval != 0)
dbg("error changing net interface name");
close(sk);
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
return retval;
}
int udev_add_device(char *path, char *subsystem, int fake)
{
struct sysfs_class_device *class_dev = NULL;
struct udevice dev;
int retval = -EINVAL;
memset(&dev, 0x00, sizeof(dev));
/* for now, the block layer is the only place where block devices are */
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
dev.type = get_device_type(path, subsystem);
switch (dev.type) {
case 'b':
case 'c':
retval = sleep_for_file(path, "/dev");
break;
case 'n':
retval = sleep_for_file(path, "/address");
break;
default:
dbg("unknown device type '%c'", dev.type);
retval = -EINVAL;
}
2003-08-05 09:13:35 +04:00
class_dev = get_class_dev(path);
if (class_dev == NULL)
goto exit;
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
if (dev.type == 'b' || dev.type == 'c') {
retval = get_major_minor(class_dev, &dev);
if (retval != 0) {
dbg("get_major_minor failed");
goto exit;
}
}
retval = namedev_name_device(class_dev, &dev);
if (retval != 0)
goto exit;
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
if (!fake && (dev.type == 'b' || dev.type == 'c')) {
retval = udevdb_add_dev(path, &dev);
if (retval != 0)
dbg("udevdb_add_dev failed, but we are going to try "
"to create the node anyway. But remove might not "
"work properly for this device.");
}
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
dbg("name='%s'", dev.name);
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
switch (dev.type) {
case 'b':
case 'c':
retval = create_node(&dev, fake);
if ((retval == 0) && (!fake))
dev_d_send(&dev, subsystem);
[PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :)
2004-03-25 10:19:39 +03:00
break;
case 'n':
retval = rename_net_if(&dev);
if (retval != 0)
dbg("net device naming failed");
break;
}
exit:
if (class_dev)
sysfs_close_class_device(class_dev);
return retval;
}