From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] netdev - udevdb+dev.d changes
Date: Sun, 28 Mar 2004 18:48:40 +0000 [thread overview]
Message-ID: <20040328184840.GA5877@vrfy.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 1724 bytes --]
Hey, Chris fixed the udevd hole and Treeve found the timestamp bug,
so there was nothing left for me at the weekend :)
Here is a patch to change the netdev handling in the database and for
the dev.d/ calls. I applies on top of the udevd.patch, cause klibc has
no sysinfo().
o netdev's are also put into our database now. I want this for the
udevruler gui to get a list of all handled devices.
All devices in the db are stamped with the system uptime value at
the creation time. 'udevinfo -d' prints it.
o the DEVPATH value is the key for udevdb, but if we rename
a netdev, the name is replaced in the kernel, so we add
the changed name to the db to match with the remove event.
NOTE: The dev.d/ scripts still get the original name from the
hotplug call. Should we replace DEVPATH with the new name too?
o We now only add a device to the db, if we have successfully created
the main node or successfully renamed a netdev. This is the main part
of the patch, cause I needed to clean the retval passing trough all
the functions used for node creation.
o DEVNODE sounds a bit ugly for netdev's so I exported DEVNAME too.
Can we change the name?
o I've added a UDEV_NO_DEVD to possibly skip the script execution
and used it in udev-test.pl.
udevstart is the same horror now, if you have scripts with logging
statements in dev.d/ it takes minutes to finish, can we skip the
scripts here too?
o The get_device_type() function is changed to be more strict, cause
'udevinfo -a -p /block/' gets a class device for it and tries to
print the major/minor values.
o bugfix, the RESULT value has now a working newline removal and a test
for this case.
thanks,
Kay
[-- Attachment #2: 02-netdev-dev_d.patch --]
[-- Type: text/plain, Size: 15588 bytes --]
===== dev_d.c 1.3 vs edited =====
--- 1.3/dev_d.c Thu Mar 25 15:38:22 2004
+++ edited/dev_d.c Sun Mar 28 14:39:40 2004
@@ -64,11 +64,20 @@
void dev_d_send(struct udevice *dev, char *subsystem)
{
char dirname[256];
- char devnode[NAME_SIZE];
+ char devname[NAME_SIZE];
- strfieldcpy(devnode, udev_root);
- strfieldcat(devnode, dev->name);
- setenv("DEVNODE", devnode, 1);
+ if (udev_dev_d == 0)
+ return;
+
+ if (dev->type == 'b' || dev->type == 'c') {
+ strfieldcpy(devname, udev_root);
+ strfieldcat(devname, dev->name);
+ } else if (dev->type == 'n') {
+ strfieldcpy(devname, dev->name);
+ }
+ setenv("DEVNODE", devname, 1); /* FIXME: bad name for netif */
+ setenv("DEVNAME", devname, 1);
+ dbg("DEVNAME='%s'", devname);
strcpy(dirname, DEVD_DIR);
strfieldcat(dirname, dev->name);
@@ -81,4 +90,3 @@
strcpy(dirname, DEVD_DIR "default");
call_foreach_file(run_program, dirname, DEVD_SUFFIX);
}
-
===== namedev.c 1.137 vs edited =====
--- 1.137/namedev.c Thu Mar 25 02:47:08 2004
+++ edited/namedev.c Sun Mar 28 19:35:32 2004
@@ -32,6 +32,9 @@
#include <time.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#ifndef __KLIBC__
+#include <sys/sysinfo.h>
+#endif
#include "libsysfs/sysfs/libsysfs.h"
#include "list.h"
@@ -454,7 +457,7 @@
retval = -1;
}
- if (i > 0 && value[i] == '\n')
+ if (i > 0 && value[i-1] == '\n')
i--;
value[i] = '\0';
dbg("result is '%s'", value);
@@ -776,6 +779,7 @@
struct sysfs_device *sysfs_device = NULL;
struct config_device *dev;
struct perm_device *perm;
+ struct sysinfo info;
char *pos;
udev->mode = 0;
@@ -837,22 +841,18 @@
}
}
}
-
- /* no rule was found for the net device */
- if (udev->type == 'n') {
- dbg("no name for net device '%s' configured", udev->kernel_name);
- return -1;
- }
-
/* no rule was found so we use the kernel name */
strfieldcpy(udev->name, udev->kernel_name);
- goto done;
+ if (udev->type == 'n')
+ goto done;
+ else
+ goto perms;
found:
apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device);
if (udev->type == 'n')
- return 0;
+ goto done;
udev->partitions = dev->partitions;
strfieldcpy(udev->config_file, dev->config_file);
@@ -863,7 +863,7 @@
dev->owner,
dev->group);
-done:
+perms:
/* get permissions given in config file or set defaults */
perm = find_perm(udev->name);
if (perm != NULL) {
@@ -879,8 +879,10 @@
dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o",
udev->name, udev->owner, udev->group, udev->mode);
+done:
/* store time of action */
- udev->config_time = time(NULL);
+ sysinfo(&info);
+ udev->config_uptime = info.uptime;
return 0;
}
===== udev-add.c 1.67 vs edited =====
--- 1.67/udev-add.c Thu Mar 25 14:25:50 2004
+++ edited/udev-add.c Sun Mar 28 20:12:39 2004
@@ -61,21 +61,20 @@
*/
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;
+ goto error;
dbg("dev='%s'", attr->value);
if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2)
- goto exit;
+ goto error;
dbg("found major=%d, minor=%d", udev->major, udev->minor);
- retval = 0;
-exit:
- return retval;
+ return 0;
+error:
+ return -1;
}
static int create_path(char *file)
@@ -114,28 +113,27 @@
if (retval != 0) {
dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
filename, mode, major, minor, strerror(errno));
- return retval;
+ goto exit;
}
dbg("chmod(%s, %#o)", filename, mode);
- retval = chmod(filename, mode);
- if (retval != 0) {
+ if (chmod(filename, mode) != 0) {
dbg("chmod(%s, %#o) failed with error '%s'",
filename, mode, strerror(errno));
- return retval;
+ goto exit;
}
if (uid != 0 || gid != 0) {
dbg("chown(%s, %u, %u)", filename, uid, gid);
- retval = chown(filename, uid, gid);
- if (retval != 0) {
+ if (chown(filename, uid, gid) != 0) {
dbg("chown(%s, %u, %u) failed with error '%s'",
filename, uid, gid, strerror(errno));
- return retval;
+ goto exit;
}
}
- return 0;
+exit:
+ return retval;
}
/* get the local logged in user */
@@ -169,7 +167,6 @@
endutent();
}
-/* Used to unlink existing files to ensure that our new file/symlink is created */
static int unlink_entry(char *filename)
{
struct stat stats;
@@ -193,7 +190,6 @@
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;
@@ -259,14 +255,15 @@
if (!fake) {
unlink_entry(filename);
info("creating device node '%s'", filename);
- make_node(filename, dev->major, dev->minor, dev->mode, uid, gid);
+ if (make_node(filename, dev->major, dev->minor, dev->mode, uid, gid) != 0)
+ goto error;
} 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 */
+ /* create all_partitions if requested */
if (dev->partitions > 0) {
info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions);
if (!fake) {
@@ -280,7 +277,7 @@
}
}
- /* create symlink if requested */
+ /* create symlink(s) if requested */
foreach_strpart(dev->symlink, " ", pos, len) {
strfieldcpymax(linkname, pos, len+1);
strfieldcpy(filename, udev_root);
@@ -312,14 +309,15 @@
dbg("symlink(%s, %s)", linktarget, filename);
if (!fake) {
- retval = symlink(linktarget, filename);
- if (retval != 0)
+ if (symlink(linktarget, filename) != 0)
dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno));
}
}
- return retval;
+ return 0;
+error:
+ return -1;
}
static struct sysfs_class_device *get_class_dev(char *device_name)
@@ -373,12 +371,16 @@
return retval;
}
-static int rename_net_if(struct udevice *dev)
+static int rename_net_if(struct udevice *dev, int fake)
{
int sk;
struct ifreq ifr;
int retval;
+ dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name);
+ if (fake)
+ return 0;
+
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0) {
dbg("error opening socket");
@@ -389,7 +391,6 @@
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");
@@ -400,16 +401,15 @@
int udev_add_device(char *path, char *subsystem, int fake)
{
- struct sysfs_class_device *class_dev = NULL;
+ struct sysfs_class_device *class_dev;
struct udevice dev;
- int retval = -EINVAL;
+ char key[DEVPATH_SIZE];
+ char *pos;
+ int retval;
memset(&dev, 0x00, sizeof(dev));
- /* for now, the block layer is the only place where block devices are */
-
dev.type = get_device_type(path, subsystem);
-
switch (dev.type) {
case 'b':
case 'c':
@@ -422,12 +422,12 @@
default:
dbg("unknown device type '%c'", dev.type);
- retval = -EINVAL;
+ return -1;
}
class_dev = get_class_dev(path);
if (class_dev == NULL)
- goto exit;
+ return -1;
if (dev.type == 'b' || dev.type == 'c') {
retval = get_major_minor(class_dev, &dev);
@@ -437,37 +437,48 @@
}
}
- retval = namedev_name_device(class_dev, &dev);
- if (retval != 0)
+ if (namedev_name_device(class_dev, &dev) != 0)
goto exit;
- 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.");
- }
-
dbg("name='%s'", dev.name);
+
switch (dev.type) {
case 'b':
case 'c':
retval = create_node(&dev, fake);
- if ((retval == 0) && (!fake))
- dev_d_send(&dev, subsystem);
+ if (fake || retval != 0)
+ goto exit;
+ if (udevdb_add_dev(path, &dev) != 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.");
break;
case 'n':
- retval = rename_net_if(&dev);
- if (retval != 0)
- dbg("net device naming failed");
+ strfieldcpy(key, path);
+ if (strcmp(dev.name, dev.kernel_name) != 0) {
+ retval = rename_net_if(&dev, fake);
+ if (fake || retval != 0)
+ goto exit;
+ /* netif's are keyed with the configured name, cause
+ * the original kernel name sleeps with the fishes
+ */
+ pos = strrchr(key, '/');
+ if (pos != NULL) {
+ pos[1] = '\0';
+ strfieldcat(key, dev.name);
+ }
+ }
+ if (udevdb_add_dev(key, &dev) != 0)
+ dbg("udevdb_add_dev failed");
break;
}
+ /* execute programs in dev.d/ with the name in the environment */
+ dev_d_send(&dev, subsystem);
+
exit:
- if (class_dev)
- sysfs_close_class_device(class_dev);
+ sysfs_close_class_device(class_dev);
return retval;
}
===== udev-remove.c 1.29 vs edited =====
--- 1.29/udev-remove.c Thu Mar 25 00:34:31 2004
+++ edited/udev-remove.c Sun Mar 28 05:20:27 2004
@@ -137,36 +137,24 @@
memset(&dev, 0x00, sizeof(dev));
- dev.type = get_device_type(path, subsystem);
-
- switch (dev.type) {
- case 'b':
- case 'c':
- retval = udevdb_get_dev(path, &dev);
- if (retval) {
- dbg("'%s' not found in database, falling back on default name", path);
- temp = strrchr(path, '/');
- if (temp == NULL)
- return -ENODEV;
- strfieldcpy(dev.name, &temp[1]);
- }
-
- dbg("name='%s'", dev.name);
- udevdb_delete_dev(path);
+ retval = udevdb_get_dev(path, &dev);
+ if (retval != 0) {
+ dbg("'%s' not found in database, falling back on default name", path);
+ temp = strrchr(path, '/');
+ if (temp == NULL)
+ return -ENODEV;
+ strfieldcpy(dev.name, &temp[1]);
+ }
+ dbg("name='%s'", dev.name);
- dev_d_send(&dev, subsystem);
+ dev.type = get_device_type(path, subsystem);
+ dev_d_send(&dev, subsystem);
+ udevdb_delete_dev(path);
+ if (dev.type == 'b' || dev.type == 'c')
retval = delete_node(&dev);
- break;
-
- case 'n':
+ else if (dev.type == 'n')
retval = 0;
- break;
-
- default:
- dbg("unknown device type '%c'", dev.type);
- retval = -EINVAL;
- }
return retval;
}
===== udev.h 1.55 vs edited =====
--- 1.55/udev.h Wed Mar 24 21:46:58 2004
+++ edited/udev.h Sun Mar 28 16:34:01 2004
@@ -52,7 +52,7 @@
int partitions;
int config_line;
char config_file[NAME_SIZE];
- time_t config_time;
+ long config_uptime;
/* private data that help us in building strings */
char bus_id[SYSFS_NAME_LEN];
@@ -80,5 +80,6 @@
extern char default_group_str[GROUP_SIZE];
extern int udev_log;
extern int udev_sleep;
+extern int udev_dev_d;
#endif
===== udev_config.c 1.15 vs edited =====
--- 1.15/udev_config.c Wed Mar 17 23:40:12 2004
+++ edited/udev_config.c Sun Mar 28 05:20:28 2004
@@ -51,6 +51,7 @@
char default_group_str[GROUP_SIZE];
int udev_log;
int udev_sleep;
+int udev_dev_d;
static int string_is_true(char *str)
@@ -77,6 +78,10 @@
udev_sleep = 1;
if (getenv("UDEV_NO_SLEEP") != NULL)
udev_sleep = 0;
+
+ udev_dev_d = 1;
+ if (getenv("UDEV_NO_DEVD") != NULL)
+ udev_dev_d = 0;
}
#define set_var(_name, _var) \
===== udev_lib.c 1.4 vs edited =====
--- 1.4/udev_lib.c Thu Mar 25 14:29:50 2004
+++ edited/udev_lib.c Sun Mar 28 05:20:28 2004
@@ -86,17 +86,28 @@
return subsystem;
}
+#define BLOCK_PATH "/block/"
+#define CLASS_PATH "/class/"
+#define NET_PATH "/class/net/"
+
char get_device_type(const char *path, const char *subsystem)
{
- if (strcmp(subsystem, "block") == 0 ||
- strstr(path, "/block/") != NULL)
+ if (strcmp(subsystem, "block") == 0)
+ return 'b';
+
+ if (strcmp(subsystem, "net") == 0)
+ return 'n';
+
+ if (strncmp(path, BLOCK_PATH, strlen(BLOCK_PATH)) == 0 &&
+ strlen(path) > strlen(BLOCK_PATH))
return 'b';
- if (strcmp(subsystem, "net") == 0 ||
- strstr(path, "/class/net/") != NULL)
+ if (strncmp(path, NET_PATH, strlen(NET_PATH)) == 0 &&
+ strlen(path) > strlen(NET_PATH))
return 'n';
- if (strstr(path, "/class/") != NULL)
+ if (strncmp(path, CLASS_PATH, strlen(CLASS_PATH)) == 0 &&
+ strlen(path) > strlen(CLASS_PATH))
return 'c';
return '\0';
===== udevdb.c 1.28 vs edited =====
--- 1.28/udevdb.c Wed Mar 17 23:40:12 2004
+++ edited/udevdb.c Sun Mar 28 16:06:50 2004
@@ -59,6 +59,7 @@
data.dptr = (void *)dev;
data.dsize = UDEVICE_LEN;
+ dbg("store key '%s' for device '%s'", path, dev->name);
return tdb_store(udevdb, key, data, TDB_REPLACE);
}
===== udevinfo.c 1.22 vs edited =====
--- 1.22/udevinfo.c Thu Mar 25 00:28:42 2004
+++ edited/udevinfo.c Sun Mar 28 05:20:28 2004
@@ -108,13 +108,14 @@
{
printf("P: %s\n", path);
printf("N: %s\n", dev->name);
+ printf("T: %c\n", dev->type);
printf("M: %#o\n", dev->mode);
printf("S: %s\n", dev->symlink);
printf("O: %s\n", dev->owner);
printf("G: %s\n", dev->group);
printf("F: %s\n", dev->config_file);
printf("L: %i\n", dev->config_line);
- printf("T: %li\n", dev->config_time);
+ printf("U: %li\n", dev->config_uptime);
printf("\n");
return 0;
}
===== udevruler.c 1.2 vs edited =====
--- 1.2/udevruler.c Thu Mar 25 13:45:16 2004
+++ edited/udevruler.c Sun Mar 28 16:33:33 2004
@@ -77,7 +77,7 @@
char devpath[DEVPATH_SIZE];
int config_line;
char config_file[NAME_SIZE];
- time_t config_time;
+ long config_uptime;
int added;
};
@@ -106,7 +106,7 @@
strfieldcpy(dev->devpath, path);
dev->config_line = udev->config_line;
strfieldcpy(dev->config_file, udev->config_file);
- dev->config_time = udev->config_time;
+ dev->config_uptime = udev->config_uptime;
dev->added = 0;
/* sort in lexical order */
@@ -308,7 +308,7 @@
char roottext[81];
char path[NAME_SIZE];
struct device *dev;
- time_t time_last;
+ long time_last;
int count_last;
newtInit();
@@ -332,13 +332,13 @@
/* look for last discovered device */
time_last = 0;
list_for_each_entry(dev, &device_list, list)
- if (dev->config_time > time_last)
- time_last = dev->config_time;
+ if (dev->config_uptime > time_last)
+ time_last = dev->config_uptime;
/* skip if more than 16 recent devices */
count_last = 0;
list_for_each_entry(dev, &device_list, list) {
- if (dev->config_time < time_last - 10)
+ if (dev->config_uptime < time_last - 10)
continue;
count_last++;
}
@@ -347,7 +347,7 @@
if (count_last < 16) {
newtListboxAppendEntry(lbox, "--- last dicovered ---", NULL);
list_for_each_entry(dev, &device_list, list) {
- if (dev->config_time < time_last - 10)
+ if (dev->config_uptime < time_last - 10)
continue;
dbg("%s %i", dev->name, dev->config_line);
===== test/udev-test.pl 1.53 vs edited =====
--- 1.53/test/udev-test.pl Thu Mar 25 00:50:17 2004
+++ edited/test/udev-test.pl Sun Mar 28 19:48:18 2004
@@ -235,6 +235,15 @@
EOF
},
{
+ desc => "program result substitution (newline removal)",
+ subsys => "block",
+ devpath => "/block/sda/sda3",
+ exp_name => "newline_removed" ,
+ conf => <<EOF
+BUS="scsi", PROGRAM="/bin/echo test", RESULT="test", NAME="newline_removed"
+EOF
+ },
+ {
desc => "program result substitution",
subsys => "block",
devpath => "/block/sda/sda3",
@@ -580,6 +589,8 @@
$ENV{UDEV_TEST} = "yes";
$ENV{SYSFS_PATH} = $sysfs;
$ENV{UDEV_CONFIG_FILE} = $main_conf;
+$ENV{UDEV_NO_SLEEP} = "yes";
+$ENV{UDEV_NO_DEVD} = "yes";
sub udev {
next reply other threads:[~2004-03-28 18:48 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-03-28 18:48 Kay Sievers [this message]
2004-03-31 23:14 ` [PATCH] netdev - udevdb+dev.d changes Greg KH
2004-03-31 23:40 ` Kay Sievers
2004-04-01 0:22 ` Greg KH
2004-04-01 0:41 ` Kay Sievers
2004-04-01 1:02 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040328184840.GA5877@vrfy.org \
--to=kay.sievers@vrfy.org \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.