Commit 64bf0b1a authored by NeilBrown's avatar NeilBrown Committed by Greg Kroah-Hartman

staging: lustre: refactor libcfs initialization.

Many lustre modules depend on libcfs having initialized
properly, but do not explicit check that it did.
When lustre is built as discrete modules, this does not
cause a problem because if the libcfs module fails
initialization, the other modules don't even get loaded.

When lustre is compiled into the kernel, all module_init()
routines get run, so they need to check the required initialization
succeeded.

This patch splits out the initialization of libcfs into a new
libcfs_setup(), and has all modules call that.

The misc_register() call is kept separate as it does not allocate any
resources and if it fails, it fails hard - no point in retrying.
Other set-up allocates resources and so is best delayed until they
are needed, and can be worth retrying.

Ideally, the initialization would happen at mount time (or similar)
rather than at load time.  Doing this requires each module to
check dependencies when they are activated rather than when
they are loaded.  Achieving that is a much larger job that would
have to progress in stages.

For now, this change ensures that if some initialization in libcfs
fails, other modules will fail-safe.
Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e67f133d
...@@ -137,6 +137,7 @@ struct libcfs_ioctl_handler { ...@@ -137,6 +137,7 @@ struct libcfs_ioctl_handler {
int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
int libcfs_setup(void);
#define _LIBCFS_H #define _LIBCFS_H
......
...@@ -2928,6 +2928,8 @@ static void __exit ko2iblnd_exit(void) ...@@ -2928,6 +2928,8 @@ static void __exit ko2iblnd_exit(void)
static int __init ko2iblnd_init(void) static int __init ko2iblnd_init(void)
{ {
int rc;
BUILD_BUG_ON(sizeof(struct kib_msg) > IBLND_MSG_SIZE); BUILD_BUG_ON(sizeof(struct kib_msg) > IBLND_MSG_SIZE);
BUILD_BUG_ON(offsetof(struct kib_msg, BUILD_BUG_ON(offsetof(struct kib_msg,
ibm_u.get.ibgm_rd.rd_frags[IBLND_MAX_RDMA_FRAGS]) ibm_u.get.ibgm_rd.rd_frags[IBLND_MAX_RDMA_FRAGS])
...@@ -2938,6 +2940,10 @@ static int __init ko2iblnd_init(void) ...@@ -2938,6 +2940,10 @@ static int __init ko2iblnd_init(void)
kiblnd_tunables_init(); kiblnd_tunables_init();
rc = libcfs_setup();
if (rc)
return rc;
lnet_register_lnd(&the_o2iblnd); lnet_register_lnd(&the_o2iblnd);
return 0; return 0;
......
...@@ -2903,6 +2903,10 @@ static int __init ksocklnd_init(void) ...@@ -2903,6 +2903,10 @@ static int __init ksocklnd_init(void)
if (rc) if (rc)
return rc; return rc;
rc = libcfs_setup();
if (rc)
return rc;
lnet_register_lnd(&the_ksocklnd); lnet_register_lnd(&the_ksocklnd);
return 0; return 0;
......
...@@ -426,7 +426,8 @@ int cfs_crypto_register(void) ...@@ -426,7 +426,8 @@ int cfs_crypto_register(void)
{ {
request_module("crc32c"); request_module("crc32c");
adler32 = cfs_crypto_adler32_register(); if (cfs_crypto_adler32_register() == 0)
adler32 = 1;
/* check all algorithms and do performance test */ /* check all algorithms and do performance test */
cfs_crypto_test_hashes(); cfs_crypto_test_hashes();
...@@ -438,6 +439,7 @@ int cfs_crypto_register(void) ...@@ -438,6 +439,7 @@ int cfs_crypto_register(void)
*/ */
void cfs_crypto_unregister(void) void cfs_crypto_unregister(void)
{ {
if (!adler32) if (adler32)
cfs_crypto_adler32_unregister(); cfs_crypto_adler32_unregister();
adler32 = 0;
} }
...@@ -320,6 +320,8 @@ static struct miscdevice libcfs_dev = { ...@@ -320,6 +320,8 @@ static struct miscdevice libcfs_dev = {
.fops = &libcfs_fops, .fops = &libcfs_fops,
}; };
static int libcfs_dev_registered;
int lprocfs_call_handler(void *data, int write, loff_t *ppos, int lprocfs_call_handler(void *data, int write, loff_t *ppos,
void __user *buffer, size_t *lenp, void __user *buffer, size_t *lenp,
int (*handler)(void *data, int write, loff_t pos, int (*handler)(void *data, int write, loff_t pos,
...@@ -687,49 +689,70 @@ static void lustre_remove_debugfs(void) ...@@ -687,49 +689,70 @@ static void lustre_remove_debugfs(void)
lnet_debugfs_root = NULL; lnet_debugfs_root = NULL;
} }
static int libcfs_init(void) static DEFINE_MUTEX(libcfs_startup);
static int libcfs_active;
int libcfs_setup(void)
{ {
int rc; int rc = -EINVAL;
mutex_lock(&libcfs_startup);
if (libcfs_active)
goto out;
if (!libcfs_dev_registered)
goto err;
rc = libcfs_debug_init(5 * 1024 * 1024); rc = libcfs_debug_init(5 * 1024 * 1024);
if (rc < 0) { if (rc < 0) {
pr_err("LustreError: libcfs_debug_init: %d\n", rc); pr_err("LustreError: libcfs_debug_init: %d\n", rc);
return rc; goto err;
} }
rc = cfs_cpu_init(); rc = cfs_cpu_init();
if (rc) if (rc)
goto cleanup_debug; goto err;
rc = misc_register(&libcfs_dev);
if (rc) {
CERROR("misc_register: error %d\n", rc);
goto cleanup_cpu;
}
cfs_rehash_wq = alloc_workqueue("cfs_rh", WQ_SYSFS, 4); cfs_rehash_wq = alloc_workqueue("cfs_rh", WQ_SYSFS, 4);
if (!cfs_rehash_wq) { if (!cfs_rehash_wq) {
CERROR("Failed to start rehash workqueue.\n"); CERROR("Failed to start rehash workqueue.\n");
rc = -ENOMEM; rc = -ENOMEM;
goto cleanup_deregister; goto err;
} }
rc = cfs_crypto_register(); rc = cfs_crypto_register();
if (rc) { if (rc) {
CERROR("cfs_crypto_register: error %d\n", rc); CERROR("cfs_crypto_register: error %d\n", rc);
goto cleanup_deregister; goto err;
} }
lustre_insert_debugfs(lnet_table, lnet_debugfs_symlinks); lustre_insert_debugfs(lnet_table, lnet_debugfs_symlinks);
CDEBUG(D_OTHER, "portals setup OK\n"); CDEBUG(D_OTHER, "portals setup OK\n");
out:
libcfs_active = 1;
mutex_unlock(&libcfs_startup);
return 0; return 0;
cleanup_deregister: err:
misc_deregister(&libcfs_dev); cfs_crypto_unregister();
cleanup_cpu: if (cfs_rehash_wq)
destroy_workqueue(cfs_rehash_wq);
cfs_cpu_fini(); cfs_cpu_fini();
cleanup_debug:
libcfs_debug_cleanup(); libcfs_debug_cleanup();
mutex_unlock(&libcfs_startup);
return rc;
}
EXPORT_SYMBOL(libcfs_setup);
static int libcfs_init(void)
{
int rc;
rc = misc_register(&libcfs_dev);
if (rc)
CERROR("misc_register: error %d\n", rc);
else
libcfs_dev_registered = 1;
return rc; return rc;
} }
...@@ -739,14 +762,13 @@ static void libcfs_exit(void) ...@@ -739,14 +762,13 @@ static void libcfs_exit(void)
lustre_remove_debugfs(); lustre_remove_debugfs();
if (cfs_rehash_wq) { if (cfs_rehash_wq)
destroy_workqueue(cfs_rehash_wq); destroy_workqueue(cfs_rehash_wq);
cfs_rehash_wq = NULL;
}
cfs_crypto_unregister(); cfs_crypto_unregister();
misc_deregister(&libcfs_dev); if (libcfs_dev_registered)
misc_deregister(&libcfs_dev);
cfs_cpu_fini(); cfs_cpu_fini();
......
...@@ -184,6 +184,10 @@ static int __init lnet_init(void) ...@@ -184,6 +184,10 @@ static int __init lnet_init(void)
mutex_init(&lnet_config_mutex); mutex_init(&lnet_config_mutex);
rc = libcfs_setup();
if (rc)
return rc;
rc = lnet_lib_init(); rc = lnet_lib_init();
if (rc) { if (rc) {
CERROR("lnet_lib_init: error %d\n", rc); CERROR("lnet_lib_init: error %d\n", rc);
......
...@@ -89,9 +89,13 @@ static int ...@@ -89,9 +89,13 @@ static int
lnet_selftest_init(void) lnet_selftest_init(void)
{ {
int nscheds; int nscheds;
int rc = -ENOMEM; int rc;
int i; int i;
rc = libcfs_setup();
if (rc)
return rc;
lst_serial_wq = alloc_ordered_workqueue("lst_s", 0); lst_serial_wq = alloc_ordered_workqueue("lst_s", 0);
if (!lst_serial_wq) { if (!lst_serial_wq) {
CERROR("Failed to create serial WI scheduler for LST\n"); CERROR("Failed to create serial WI scheduler for LST\n");
......
...@@ -419,6 +419,12 @@ EXPORT_SYMBOL(client_fid_fini); ...@@ -419,6 +419,12 @@ EXPORT_SYMBOL(client_fid_fini);
static int __init fid_init(void) static int __init fid_init(void)
{ {
int rc;
rc = libcfs_setup();
if (rc)
return rc;
seq_debugfs_dir = ldebugfs_register(LUSTRE_SEQ_NAME, seq_debugfs_dir = ldebugfs_register(LUSTRE_SEQ_NAME,
debugfs_lustre_root, debugfs_lustre_root,
NULL, NULL); NULL, NULL);
......
...@@ -450,6 +450,12 @@ void fld_client_flush(struct lu_client_fld *fld) ...@@ -450,6 +450,12 @@ void fld_client_flush(struct lu_client_fld *fld)
static int __init fld_init(void) static int __init fld_init(void)
{ {
int rc;
rc = libcfs_setup();
if (rc)
return rc;
fld_debugfs_dir = ldebugfs_register(LUSTRE_FLD_NAME, fld_debugfs_dir = ldebugfs_register(LUSTRE_FLD_NAME,
debugfs_lustre_root, debugfs_lustre_root,
NULL, NULL); NULL, NULL);
......
...@@ -90,6 +90,10 @@ static int __init lustre_init(void) ...@@ -90,6 +90,10 @@ static int __init lustre_init(void)
BUILD_BUG_ON(sizeof(LUSTRE_VOLATILE_HDR) != BUILD_BUG_ON(sizeof(LUSTRE_VOLATILE_HDR) !=
LUSTRE_VOLATILE_HDR_LEN + 1); LUSTRE_VOLATILE_HDR_LEN + 1);
rc = libcfs_setup();
if (rc)
return rc;
/* print an address of _any_ initialized kernel symbol from this /* print an address of _any_ initialized kernel symbol from this
* module, to allow debugging with gdb that doesn't support data * module, to allow debugging with gdb that doesn't support data
* symbols from modules. * symbols from modules.
......
...@@ -3108,9 +3108,14 @@ static struct md_ops lmv_md_ops = { ...@@ -3108,9 +3108,14 @@ static struct md_ops lmv_md_ops = {
static int __init lmv_init(void) static int __init lmv_init(void)
{ {
struct lprocfs_static_vars lvars; struct lprocfs_static_vars lvars;
int rc;
lprocfs_lmv_init_vars(&lvars); lprocfs_lmv_init_vars(&lvars);
rc = libcfs_setup();
if (rc)
return rc;
return class_register_type(&lmv_obd_ops, &lmv_md_ops, return class_register_type(&lmv_obd_ops, &lmv_md_ops,
LUSTRE_LMV_NAME, NULL); LUSTRE_LMV_NAME, NULL);
} }
......
...@@ -1403,6 +1403,10 @@ static int __init lov_init(void) ...@@ -1403,6 +1403,10 @@ static int __init lov_init(void)
*/ */
CDEBUG(D_INFO, "Lustre LOV module (%p).\n", &lov_caches); CDEBUG(D_INFO, "Lustre LOV module (%p).\n", &lov_caches);
rc = libcfs_setup();
if (rc)
return rc;
rc = lu_kmem_init(lov_caches); rc = lu_kmem_init(lov_caches);
if (rc) if (rc)
return rc; return rc;
......
...@@ -2733,6 +2733,11 @@ static struct md_ops mdc_md_ops = { ...@@ -2733,6 +2733,11 @@ static struct md_ops mdc_md_ops = {
static int __init mdc_init(void) static int __init mdc_init(void)
{ {
struct lprocfs_static_vars lvars = { NULL }; struct lprocfs_static_vars lvars = { NULL };
int rc;
rc = libcfs_setup();
if (rc)
return rc;
lprocfs_mdc_init_vars(&lvars); lprocfs_mdc_init_vars(&lvars);
......
...@@ -1826,6 +1826,12 @@ static struct obd_ops mgc_obd_ops = { ...@@ -1826,6 +1826,12 @@ static struct obd_ops mgc_obd_ops = {
static int __init mgc_init(void) static int __init mgc_init(void)
{ {
int rc;
rc = libcfs_setup();
if (rc)
return rc;
return class_register_type(&mgc_obd_ops, NULL, return class_register_type(&mgc_obd_ops, NULL,
LUSTRE_MGC_NAME, NULL); LUSTRE_MGC_NAME, NULL);
} }
......
...@@ -449,6 +449,11 @@ static int __init obdclass_init(void) ...@@ -449,6 +449,11 @@ static int __init obdclass_init(void)
LCONSOLE_INFO("Lustre: Build Version: " LUSTRE_VERSION_STRING "\n"); LCONSOLE_INFO("Lustre: Build Version: " LUSTRE_VERSION_STRING "\n");
spin_lock_init(&obd_types_lock); spin_lock_init(&obd_types_lock);
err = libcfs_setup();
if (err)
return err;
obd_zombie_impexp_init(); obd_zombie_impexp_init();
err = obd_init_checks(); err = obd_init_checks();
......
...@@ -1701,10 +1701,16 @@ static void echo_client_exit(void) ...@@ -1701,10 +1701,16 @@ static void echo_client_exit(void)
static int __init obdecho_init(void) static int __init obdecho_init(void)
{ {
int rc;
LCONSOLE_INFO("Echo OBD driver; http://www.lustre.org/\n"); LCONSOLE_INFO("Echo OBD driver; http://www.lustre.org/\n");
LASSERT(PAGE_SIZE % OBD_ECHO_BLOCK_SIZE == 0); LASSERT(PAGE_SIZE % OBD_ECHO_BLOCK_SIZE == 0);
rc = libcfs_setup();
if (rc)
return rc;
return echo_client_init(); return echo_client_init();
} }
......
...@@ -2831,6 +2831,10 @@ static int __init osc_init(void) ...@@ -2831,6 +2831,10 @@ static int __init osc_init(void)
*/ */
CDEBUG(D_INFO, "Lustre OSC module (%p).\n", &osc_caches); CDEBUG(D_INFO, "Lustre OSC module (%p).\n", &osc_caches);
rc = libcfs_setup();
if (rc)
return rc;
rc = lu_kmem_init(osc_caches); rc = lu_kmem_init(osc_caches);
if (rc) if (rc)
return rc; return rc;
......
...@@ -94,6 +94,10 @@ static int __init ptlrpc_init(void) ...@@ -94,6 +94,10 @@ static int __init ptlrpc_init(void)
mutex_init(&ptlrpcd_mutex); mutex_init(&ptlrpcd_mutex);
ptlrpc_init_xid(); ptlrpc_init_xid();
rc = libcfs_setup();
if (rc)
return rc;
rc = req_layout_init(); rc = req_layout_init();
if (rc) if (rc)
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment