2003-10-17 12:40:02 +04:00
/*
* udevdb . c
*
* 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-08-06 10:57:23 +04:00
/*
* udev database library
*/
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>
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_version.h"
# include "udev.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 ;
2003-08-06 10:57:23 +04:00
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
2003-10-21 09:48:44 +04:00
if ( ( path = = NULL ) | | ( dev = = NULL ) )
return - ENODEV ;
2003-10-18 10:32:17 +04:00
2003-10-21 09:48:44 +04:00
memset ( keystr , 0 , NAME_SIZE ) ;
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 ;
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 ;
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
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
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-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 )
{
2004-03-02 10:47:59 +03:00
int l , i , j ;
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 ) ) ;
strnfieldcpy ( 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*/
l = strlen ( dev - > symlink ) ;
if ( ! l )
return 0 ;
i = j = 0 ;
do {
j = strcspn ( & dev - > symlink [ i ] , " " ) ;
if ( j & & strncmp ( & dev - > symlink [ i ] , find_name , j ) = = 0 ) {
memcpy ( find_dev , dev , sizeof ( struct udevice ) ) ;
strnfieldcpy ( find_path , path , NAME_SIZE ) ;
find_found = 1 ;
return 1 ;
}
i = i + j + 1 ;
} while ( i < l ) ;
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 ;
}