2003-10-17 12:40:02 +04:00
/*
2004-03-23 09:22:20 +03:00
* udevdb . c - udev database library
2003-10-17 12:40:02 +04:00
*
* Userspace devfs
*
* Copyright ( C ) 2003 Greg Kroah - Hartman < greg @ kroah . com >
* Copyright ( C ) 2003 IBM Corp .
*
* 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 0213 9 , USA .
*
*/
2003-12-17 11:23:28 +03:00
# define _KLIBC_HAS_ARCH_SIG_ATOMIC_T
2003-08-06 10:57:23 +04:00
# include <stdlib.h>
# include <stdio.h>
2004-03-02 10:47:59 +03:00
# include <string.h>
2004-03-23 09:22:20 +03:00
# include <stddef.h>
2003-08-06 10:57:23 +04:00
# include <fcntl.h>
# include <string.h>
# include <sys/stat.h>
# include <errno.h>
2003-08-06 11:03:30 +04:00
# include <signal.h>
2003-08-06 10:57:23 +04:00
2004-02-24 06:07:25 +03:00
# include "libsysfs/sysfs/libsysfs.h"
2003-10-16 10:50:13 +04:00
# include "udev.h"
2004-03-23 09:22:20 +03:00
# include "udev_lib.h"
# include "udev_version.h"
[PATCH] add udev logging to info log
On Thu, Jan 15, 2004 at 05:14:16AM +0100, Kay Sievers wrote:
> On Wed, Jan 14, 2004 at 01:10:43PM -0800, Greg KH wrote:
> > On Wed, Jan 14, 2004 at 02:34:26PM -0600, Clay Haapala wrote:
> > > On Wed, 14 Jan 2004, Chris Friesen spake thusly:
> > > >
> > > > Maybe for ones with a matching rule, you could print something like:
> > > >
> > > >
> > > Is the act of printing/syslogging a rule in an of itself?
> >
> > No, as currently the only way stuff ends up in the syslog is if
> > DEBUG=true is used on the build line.
> >
> > But it's sounding like we might want to change that... :)
>
> How about this in the syslog after connect/disconnect?
>
> Jan 15 05:07:45 pim udev[28007]: configured rule in '/etc/udev/udev.rules' at line 17 applied, 'video*' becomes 'video/webcam%n'
> Jan 15 05:07:45 pim udev[28007]: creating device node '/udev/video/webcam0'
> Jan 15 05:07:47 pim udev[28015]: removing device node '/udev/video/webcam0'
Here is a slightly better version. I've created a logging.h file and
moved the debug macros from udev.h in there.
If you type:
'make' - you will get a binary that prints one or two lines to syslog
if a device node is created or deleted
'make LOG=false' - you get a binary that prints asolutely nothing
'make DEBUG=true' - the same as today, it will print all debug lines
2004-01-16 08:53:20 +03:00
# include "logging.h"
2003-10-16 10:50:13 +04:00
# include "namedev.h"
2003-08-06 10:57:23 +04:00
# include "udevdb.h"
2003-08-06 11:03:30 +04:00
# include "tdb/tdb.h"
2003-08-06 10:57:23 +04:00
2003-10-15 10:20:53 +04:00
static TDB_CONTEXT * udevdb ;
2004-10-14 10:13:26 +04:00
sig_atomic_t gotalarm ;
2003-10-18 10:32:17 +04:00
2003-10-21 09:48:44 +04:00
int udevdb_add_dev ( const char * path , const struct udevice * dev )
2003-10-18 10:32:17 +04:00
{
TDB_DATA key , data ;
2003-10-21 09:48:44 +04:00
char keystr [ SYSFS_PATH_MAX ] ;
2003-10-18 10:32:17 +04:00
2004-10-14 10:13:26 +04:00
if ( udevdb = = NULL )
return - 1 ;
2003-10-21 09:48:44 +04:00
if ( ( path = = NULL ) | | ( dev = = NULL ) )
return - ENODEV ;
2003-10-18 10:32:17 +04:00
2004-07-03 05:59:30 +04:00
memset ( keystr , 0 , SYSFS_PATH_MAX ) ;
2004-02-27 06:37:47 +03:00
strfieldcpy ( keystr , path ) ;
2003-10-21 09:48:44 +04:00
key . dptr = keystr ;
2003-10-18 10:32:17 +04:00
key . dsize = strlen ( keystr ) + 1 ;
2003-11-25 09:27:17 +03:00
2003-10-21 09:48:44 +04:00
data . dptr = ( void * ) dev ;
2004-02-13 09:51:44 +03:00
data . dsize = UDEVICE_LEN ;
[PATCH] netdev - udevdb+dev.d changes
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.
2004-04-01 11:12:57 +04:00
dbg ( " store key '%s' for device '%s' " , path , dev - > name ) ;
2004-02-13 09:51:44 +03:00
2003-10-21 09:48:44 +04:00
return tdb_store ( udevdb , key , data , TDB_REPLACE ) ;
2003-10-18 10:32:17 +04:00
}
2003-12-20 05:29:01 +03:00
int udevdb_get_dev ( const char * path , struct udevice * dev )
2003-08-06 10:57:23 +04:00
{
TDB_DATA key , data ;
2004-10-14 10:13:26 +04:00
if ( udevdb = = NULL )
return - 1 ;
2003-10-21 09:48:44 +04:00
if ( path = = NULL )
2003-12-20 05:29:01 +03:00
return - ENODEV ;
2003-08-06 10:57:23 +04:00
2003-10-21 09:48:44 +04:00
key . dptr = ( void * ) path ;
key . dsize = strlen ( path ) + 1 ;
2003-08-06 10:57:23 +04:00
2003-10-15 10:20:53 +04:00
data = tdb_fetch ( udevdb , key ) ;
2003-08-06 10:57:23 +04:00
if ( data . dptr = = NULL | | data . dsize = = 0 )
2003-12-20 05:29:01 +03:00
return - ENODEV ;
2003-11-25 09:27:17 +03:00
2004-02-13 09:51:44 +03:00
memset ( dev , 0 , sizeof ( struct udevice ) ) ;
memcpy ( dev , data . dptr , UDEVICE_LEN ) ;
2003-12-20 05:29:01 +03:00
return 0 ;
2003-08-06 10:57:23 +04:00
}
2003-10-21 09:48:44 +04:00
int udevdb_delete_dev ( const char * path )
2003-08-06 10:57:23 +04:00
{
TDB_DATA key ;
2003-10-21 09:48:44 +04:00
char keystr [ SYSFS_PATH_MAX ] ;
2003-08-06 10:57:23 +04:00
2004-10-14 10:13:26 +04:00
if ( udevdb = = NULL )
return - 1 ;
2003-10-21 09:48:44 +04:00
if ( path = = NULL )
return - EINVAL ;
2003-10-21 07:28:42 +04:00
memset ( keystr , 0 , sizeof ( keystr ) ) ;
2004-02-27 06:37:47 +03:00
strfieldcpy ( keystr , path ) ;
2003-10-21 07:28:42 +04:00
key . dptr = keystr ;
key . dsize = strlen ( keystr ) + 1 ;
2003-11-25 09:27:17 +03:00
2003-10-21 07:28:42 +04:00
return tdb_delete ( udevdb , key ) ;
}
2003-10-15 10:20:53 +04:00
/**
* udevdb_exit : closes database
*/
void udevdb_exit ( void )
{
2003-10-21 09:48:44 +04:00
if ( udevdb ! = NULL ) {
tdb_close ( udevdb ) ;
udevdb = NULL ;
}
2003-10-15 10:20:53 +04:00
}
/**
* udevdb_init : initializes database
2003-11-25 09:27:17 +03:00
* @ init_flag : UDEVDB_INTERNAL - database stays in memory
* UDEVDB_DEFAULT - database is written to a file
2003-10-15 10:20:53 +04:00
*/
int udevdb_init ( int init_flag )
{
if ( init_flag ! = UDEVDB_DEFAULT & & init_flag ! = UDEVDB_INTERNAL )
2003-10-21 09:48:44 +04:00
return - EINVAL ;
2003-10-15 10:20:53 +04:00
2004-10-14 10:13:26 +04:00
tdb_set_lock_alarm ( & gotalarm ) ;
2003-10-22 07:19:09 +04:00
udevdb = tdb_open ( udev_db_filename , 0 , init_flag , O_RDWR | O_CREAT , 0644 ) ;
2003-10-21 09:48:44 +04:00
if ( udevdb = = NULL ) {
if ( init_flag = = UDEVDB_INTERNAL )
2003-11-25 09:27:17 +03:00
dbg ( " unable to initialize in-memory database " ) ;
2003-10-21 09:48:44 +04:00
else
2003-11-25 09:27:17 +03:00
dbg ( " unable to initialize database at '%s' " , udev_db_filename ) ;
2004-01-13 12:01:19 +03:00
return - EACCES ;
2003-10-21 09:48:44 +04:00
}
return 0 ;
2003-10-15 10:20:53 +04:00
}
2003-12-31 09:31:37 +03:00
/**
2003-12-31 11:34:51 +03:00
* udevdb_open_ro : open database for reading
2003-12-31 09:31:37 +03:00
*/
int udevdb_open_ro ( void )
{
udevdb = tdb_open ( udev_db_filename , 0 , 0 , O_RDONLY , 0 ) ;
if ( udevdb = = NULL ) {
dbg ( " unable to open database at '%s' " , udev_db_filename ) ;
2004-01-13 12:01:19 +03:00
return - EACCES ;
}
return 0 ;
}
2004-01-20 06:40:32 +03:00
static int ( * user_record_callback ) ( char * path , struct udevice * dev ) ;
2004-01-13 12:01:19 +03:00
static int traverse_callback ( TDB_CONTEXT * tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
{
2004-01-20 06:40:32 +03:00
return user_record_callback ( ( char * ) key . dptr , ( struct udevice * ) dbuf . dptr ) ;
2004-01-13 12:01:19 +03:00
}
/**
2004-01-20 06:40:32 +03:00
* udevdb_call_foreach : dumps whole database by passing record data to user function
2004-01-13 12:01:19 +03:00
* @ user_record_handler : user function called for every record in the database
*/
2004-01-20 06:40:32 +03:00
int udevdb_call_foreach ( int ( * user_record_handler ) ( char * path , struct udevice * dev ) )
2004-01-13 12:01:19 +03:00
{
2004-01-20 06:40:32 +03:00
int retval = 0 ;
2004-10-14 10:13:26 +04:00
if ( udevdb = = NULL )
return - 1 ;
2004-01-13 12:01:19 +03:00
if ( user_record_handler = = NULL ) {
dbg ( " invalid user record handling function " ) ;
2003-12-31 09:31:37 +03:00
return - EINVAL ;
}
2004-01-13 12:01:19 +03:00
user_record_callback = user_record_handler ;
2004-01-20 06:40:32 +03:00
retval = tdb_traverse ( udevdb , traverse_callback , NULL ) ;
if ( retval < 0 )
return - ENODEV ;
else
return 0 ;
}
static struct udevice * find_dev ;
static char * find_path ;
static const char * find_name ;
static int find_found ;
static int find_device_by_name ( char * path , struct udevice * dev )
{
[PATCH] better fix for NAME="foo-%c{N}" gets a truncated name
On Wed, Mar 03, 2004 at 04:56:34PM -0800, Greg KH wrote:
> On Wed, Mar 03, 2004 at 03:57:04PM -0800, Patrick Mansfield wrote:
> >
> > Here is a patch for some new tests.
>
> Applied, thanks.
Here is a small improvement, which looks much better.
Hey Pat, thanks a lot for finding the recent bug, hope this one will
not break it again :)
2004-03-05 05:55:34 +03:00
char * pos ;
int len ;
2004-03-04 05:16:35 +03:00
2004-01-20 06:40:32 +03:00
if ( strncmp ( dev - > name , find_name , sizeof ( dev - > name ) ) = = 0 ) {
2004-03-02 10:47:59 +03:00
memcpy ( find_dev , dev , sizeof ( struct udevice ) ) ;
2004-03-10 06:50:15 +03:00
strfieldcpymax ( find_path , path , NAME_SIZE ) ;
2004-01-20 06:40:32 +03:00
find_found = 1 ;
/* stop search */
return 1 ;
}
2004-03-02 10:47:59 +03:00
/* look for matching symlink*/
2004-03-04 05:16:35 +03:00
foreach_strpart ( dev - > symlink , " " , pos , len ) {
[PATCH] better fix for NAME="foo-%c{N}" gets a truncated name
On Wed, Mar 03, 2004 at 04:56:34PM -0800, Greg KH wrote:
> On Wed, Mar 03, 2004 at 03:57:04PM -0800, Patrick Mansfield wrote:
> >
> > Here is a patch for some new tests.
>
> Applied, thanks.
Here is a small improvement, which looks much better.
Hey Pat, thanks a lot for finding the recent bug, hope this one will
not break it again :)
2004-03-05 05:55:34 +03:00
if ( strncmp ( pos , find_name , len ) ! = 0 )
2004-03-04 05:16:35 +03:00
continue ;
if ( len ! = strlen ( find_name ) )
continue ;
memcpy ( find_dev , dev , sizeof ( struct udevice ) ) ;
2004-03-10 06:50:15 +03:00
strfieldcpymax ( find_path , path , NAME_SIZE ) ;
2004-03-04 05:16:35 +03:00
find_found = 1 ;
return 1 ;
}
2003-12-31 09:31:37 +03:00
return 0 ;
}
2004-01-20 06:40:32 +03:00
/**
* udevdb_get_dev_byname : search device with given name by traversing the whole database
*/
int udevdb_get_dev_byname ( const char * name , char * path , struct udevice * dev )
{
find_found = 0 ;
find_path = path ;
find_dev = dev ;
find_name = name ;
udevdb_call_foreach ( find_device_by_name ) ;
if ( find_found = = 1 )
return 0 ;
else
return - 1 ;
}