2010-08-14 21:59:25 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2010-05-22 02:29:53 +04:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-05-22 02:29:53 +04:00
( at your option ) any later version .
systemd 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
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-05-22 02:29:53 +04:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-05-22 02:29:53 +04:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <unistd.h>
# include <string.h>
2014-11-14 19:58:32 +03:00
# ifdef HAVE_KMOD
2012-02-09 00:52:18 +04:00
# include <libkmod.h>
2014-11-14 19:58:32 +03:00
# endif
2010-05-22 02:29:53 +04:00
# include "macro.h"
2014-06-17 05:23:23 +04:00
# include "capability.h"
2010-05-22 02:29:53 +04:00
# include "kmod-setup.h"
2014-11-14 19:58:32 +03:00
# ifdef HAVE_KMOD
2013-05-07 19:48:25 +04:00
static void systemd_kmod_log (
void * data ,
int priority ,
const char * file , int line ,
const char * fn ,
const char * format ,
va_list args ) {
2012-11-04 19:54:19 +04:00
/* library logging is enabled at debug only */
2014-02-20 21:18:32 +04:00
DISABLE_WARNING_FORMAT_NONLITERAL ;
2014-11-27 22:20:23 +03:00
log_internalv ( LOG_DEBUG , 0 , file , line , fn , format , args ) ;
2014-02-20 21:18:32 +04:00
REENABLE_WARNING ;
2012-02-09 00:52:18 +04:00
}
2013-05-07 19:48:25 +04:00
2013-12-19 04:32:55 +04:00
static bool cmdline_check_kdbus ( void ) {
2014-11-27 23:56:39 +03:00
return get_proc_cmdline_key ( " kdbus " , NULL ) > 0 ;
2013-12-19 02:56:35 +04:00
}
2014-11-14 19:58:32 +03:00
# endif
2013-05-07 19:48:25 +04:00
2013-12-19 02:56:35 +04:00
int kmod_setup ( void ) {
2014-11-14 19:58:32 +03:00
# ifdef HAVE_KMOD
2014-06-17 05:23:23 +04:00
2013-12-19 02:56:35 +04:00
static const struct {
const char * module ;
const char * path ;
bool warn ;
bool ( * condition_fn ) ( void ) ;
} kmod_table [ ] = {
/* auto-loading on use doesn't work before udev is up */
2014-11-26 17:43:20 +03:00
{ " autofs4 " , " /sys/class/misc/autofs " , true , NULL } ,
2013-12-19 02:56:35 +04:00
/* early configure of ::1 on the loopback device */
2014-11-26 17:43:20 +03:00
{ " ipv6 " , " /sys/module/ipv6 " , true , NULL } ,
2013-12-19 02:56:35 +04:00
/* this should never be a module */
2014-11-26 17:43:20 +03:00
{ " unix " , " /proc/net/unix " , true , NULL } ,
2013-12-19 02:56:35 +04:00
/* IPC is needed before we bring up any other services */
sd-bus: sync with kdbus upstream (ABI break)
kdbus has seen a larger update than expected lately, most notably with
kdbusfs, a file system to expose the kdbus control files:
* Each time a file system of this type is mounted, a new kdbus
domain is created.
* The layout inside each mount point is the same as before, except
that domains are not hierarchically nested anymore.
* Domains are therefore also unnamed now.
* Unmounting a kdbusfs will automatically also detroy the
associated domain.
* Hence, the action of creating a kdbus domain is now as
privileged as mounting a filesystem.
* This way, we can get around creating dev nodes for everything,
which is last but not least something that is not limited by
20-bit minor numbers.
The kdbus specific bits in nspawn have all been dropped now, as nspawn
can rely on the container OS to set up its own kdbus domain, simply by
mounting a new instance.
A new set of mounts has been added to mount things *after* the kernel
modules have been loaded. For now, only kdbus is in this set, which is
invoked with mount_setup_late().
2014-11-13 22:33:03 +03:00
{ " kdbus " , " /sys/fs/kdbus " , false , cmdline_check_kdbus } ,
2013-12-19 02:56:35 +04:00
} ;
2012-02-09 00:52:18 +04:00
struct kmod_ctx * ctx = NULL ;
2013-12-19 02:56:35 +04:00
unsigned int i ;
2013-05-07 19:48:25 +04:00
int r ;
2010-05-22 02:29:53 +04:00
2014-06-17 05:23:23 +04:00
if ( have_effective_cap ( CAP_SYS_MODULE ) = = 0 )
return 0 ;
2013-12-19 02:56:35 +04:00
for ( i = 0 ; i < ELEMENTSOF ( kmod_table ) ; i + + ) {
2013-05-07 19:48:25 +04:00
struct kmod_module * mod ;
2010-05-22 02:29:53 +04:00
2013-12-19 04:32:55 +04:00
if ( kmod_table [ i ] . path & & access ( kmod_table [ i ] . path , F_OK ) > = 0 )
2013-12-19 02:56:35 +04:00
continue ;
2013-12-19 04:32:55 +04:00
if ( kmod_table [ i ] . condition_fn & & ! kmod_table [ i ] . condition_fn ( ) )
2010-05-22 02:29:53 +04:00
continue ;
2013-12-19 02:56:35 +04:00
if ( kmod_table [ i ] . warn )
log_debug ( " Your kernel apparently lacks built-in %s support. Might be "
" a good idea to compile it in. We'll now try to work around "
" this by loading the module... " , kmod_table [ i ] . module ) ;
2010-05-22 02:29:53 +04:00
2012-02-09 00:52:18 +04:00
if ( ! ctx ) {
ctx = kmod_new ( NULL , NULL ) ;
2013-05-07 19:48:25 +04:00
if ( ! ctx )
return log_oom ( ) ;
2010-05-22 02:29:53 +04:00
2012-02-09 00:52:18 +04:00
kmod_set_log_fn ( ctx , systemd_kmod_log , NULL ) ;
kmod_load_resources ( ctx ) ;
}
2010-05-22 02:29:53 +04:00
2013-12-19 02:56:35 +04:00
r = kmod_module_new_from_name ( ctx , kmod_table [ i ] . module , & mod ) ;
2013-05-07 19:48:25 +04:00
if ( r < 0 ) {
2013-12-19 02:56:35 +04:00
log_error ( " Failed to lookup module '%s' " , kmod_table [ i ] . module ) ;
2012-02-09 00:52:18 +04:00
continue ;
}
2010-05-22 02:29:53 +04:00
2013-05-07 19:48:25 +04:00
r = kmod_module_probe_insert_module ( mod , KMOD_PROBE_APPLY_BLACKLIST , NULL , NULL , NULL , NULL ) ;
if ( r = = 0 )
2012-02-09 00:52:18 +04:00
log_info ( " Inserted module '%s' " , kmod_module_get_name ( mod ) ) ;
2013-05-07 19:48:25 +04:00
else if ( r = = KMOD_PROBE_APPLY_BLACKLIST )
2012-02-09 00:52:18 +04:00
log_info ( " Module '%s' is blacklisted " , kmod_module_get_name ( mod ) ) ;
2013-12-19 04:32:55 +04:00
else if ( kmod_table [ i ] . warn )
2012-11-04 19:54:19 +04:00
log_error ( " Failed to insert module '%s' " , kmod_module_get_name ( mod ) ) ;
2010-05-22 02:29:53 +04:00
2012-02-09 00:52:18 +04:00
kmod_module_unref ( mod ) ;
2010-05-22 02:29:53 +04:00
}
2012-02-09 00:52:18 +04:00
if ( ctx )
2012-03-15 23:49:25 +04:00
kmod_unref ( ctx ) ;
2012-02-09 00:52:18 +04:00
2014-11-14 19:58:32 +03:00
# endif
2012-02-09 00:52:18 +04:00
return 0 ;
2010-05-22 02:29:53 +04:00
}