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.
Linux-commit:
64bf0b1a079d61e9e059b9dc7a58e064c7d994ae
Change-Id: I6b5ecdba0defc6e033f78d8fc2b9be9e26c7f720
Signed-off-by: Mr. NeilBrown <neilb@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52700
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Timothy Day <timday@amazon.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
typedef s32 timeout_t;
+int libcfs_setup(void);
int libcfs_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data);
extern struct workqueue_struct *cfs_rehash_wq;
}
#endif /* HAVE_KREF_READ */
-void cfs_arch_init(void);
+int cfs_arch_init(void);
void cfs_arch_exit(void);
#ifndef container_of_safe
#endif
#include <lustre_compat.h>
+#include <libcfs/crypto/llcrypt.h>
#include <libcfs/linux/linux-time.h>
#include <libcfs/linux/linux-wait.h>
#include <libcfs/linux/linux-misc.h>
}
}
-void __init cfs_arch_init(void)
+int __init cfs_arch_init(void)
{
init_libcfs_vfree_atomic();
SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
xarray_node_ctor);
#endif
+ return llcrypt_init();
}
void __exit cfs_arch_exit(void)
{
/* exit_libcfs_vfree_atomic */
flush_scheduled_work();
+
+ llcrypt_exit();
}
int cfs_kernel_write(struct file *filp, const void *buf, size_t count,
}
EXPORT_SYMBOL_GPL(lnet_remove_debugfs);
+static DEFINE_MUTEX(libcfs_startup);
+static int libcfs_active;
+
static void *debugfs_state;
-static int __init libcfs_init(void)
+
+int libcfs_setup(void)
{
- int rc;
+ int rc = -EINVAL;
- cfs_arch_init();
+ mutex_lock(&libcfs_startup);
+ if (libcfs_active)
+ goto out;
rc = libcfs_debug_init(5 * 1024 * 1024);
if (rc < 0) {
pr_err("LustreError: libcfs_debug_init: rc = %d\n", rc);
- return (rc);
+ goto cleanup_lock;
}
rc = cfs_cpu_init();
rc = cfs_crypto_register();
if (rc) {
- CERROR("cfs_crypto_regster: error %d\n", rc);
+ CERROR("cfs_crypto_register: error %d\n", rc);
goto cleanup_wq;
}
- lnet_insert_debugfs(lnet_table, THIS_MODULE, &debugfs_state);
- if (!IS_ERR_OR_NULL(lnet_debugfs_root))
- lnet_insert_debugfs_links(lnet_debugfs_symlinks);
-
- rc = llcrypt_init();
- if (rc) {
- CERROR("llcrypt_init: error %d\n", rc);
- goto cleanup_lnet;
- }
-
- CDEBUG(D_OTHER, "portals setup OK\n");
+ CDEBUG(D_OTHER, "libcfs setup OK\n");
+out:
+ libcfs_active = 1;
+ mutex_unlock(&libcfs_startup);
return 0;
-cleanup_lnet:
- if (!IS_ERR_OR_NULL(lnet_debugfs_root)) {
- debugfs_remove_recursive(lnet_debugfs_root);
- lnet_debugfs_root = NULL;
- lnet_debugfs_fini(&debugfs_state);
- }
- cfs_crypto_unregister();
cleanup_wq:
destroy_workqueue(cfs_rehash_wq);
cfs_rehash_wq = NULL;
cfs_cpu_fini();
cleanup_debug:
libcfs_debug_cleanup();
+cleanup_lock:
+ mutex_unlock(&libcfs_startup);
+ return rc;
+}
+EXPORT_SYMBOL(libcfs_setup);
+
+static int __init libcfs_init(void)
+{
+ int rc;
+
+ rc = cfs_arch_init();
+ if (rc < 0) {
+ CERROR("cfs_arch_init: error %d\n", rc);
+ return rc;
+ }
+
+ lnet_insert_debugfs(lnet_table, THIS_MODULE, &debugfs_state);
+ if (!IS_ERR_OR_NULL(lnet_debugfs_root))
+ lnet_insert_debugfs_links(lnet_debugfs_symlinks);
+
return rc;
}
CDEBUG(D_MALLOC, "before Portals cleanup: kmem %lld\n",
libcfs_kmem_read());
- llcrypt_exit();
-
- if (cfs_rehash_wq) {
+ if (cfs_rehash_wq)
destroy_workqueue(cfs_rehash_wq);
- cfs_rehash_wq = NULL;
- }
cfs_crypto_unregister();
rc = libcfs_debug_cleanup();
if (rc)
pr_err("LustreError: libcfs_debug_cleanup: rc = %d\n", rc);
+
+ cfs_arch_exit();
}
MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
kgnilnd_insert_sysctl();
kgnilnd_proc_init();
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
lnet_register_lnd(&the_kgnilnd);
return 0;
if (rc)
goto err;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
/* Do any initialization of the transaction system */
rc = kfilnd_tn_init();
if (rc) {
if (rc != 0)
return rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
lnet_register_lnd(&the_o2iblnd);
return 0;
if (rc != 0)
return rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
lnet_register_lnd(&the_ksocklnd);
return 0;
static int __init lnet_init(void)
{
int rc;
+
ENTRY;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
rc = lnet_lib_init();
if (rc != 0) {
int rc = -ENOMEM;
int i;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
lst_serial_wq = alloc_ordered_workqueue("lst_s", 0);
if (!lst_serial_wq) {
CERROR("Failed to create serial WI scheduler for LST\n");
static int __init fid_init(void)
{
struct dentry *de;
+ int rc;
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
#ifdef HAVE_SERVER_SUPPORT
- int rc = fid_server_mod_init();
+ rc = fid_server_mod_init();
if (rc)
return rc;
static int __init fld_init(void)
{
-#ifdef HAVE_SERVER_SUPPORT
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
+#ifdef HAVE_SERVER_SUPPORT
rc = fld_server_mod_init();
if (rc)
return rc;
{
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
lfsck_key_init_generic(&lfsck_thread_key, NULL);
rc = lu_context_key_register(&lfsck_thread_key);
if (!rc) {
BUILD_BUG_ON(sizeof(LUSTRE_VOLATILE_HDR) !=
LUSTRE_VOLATILE_HDR_LEN + 1);
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
/* print an address of _any_ initialized kernel symbol from this
* module, to allow debugging with gdb that doesn't support data
* symbols from modules.*/
static int __init lmv_init(void)
{
+ int rc;
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
return class_register_type(&lmv_obd_ops, &lmv_md_ops, true,
LUSTRE_LMV_NAME, NULL);
}
struct obd_type *sym;
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(lod_caches);
if (rc)
return rc;
* symbols from modules.*/
CDEBUG(D_INFO, "Lustre LOV module (%p).\n", &lov_caches);
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(lov_caches);
if (rc)
return rc;
static int __init mdc_init(void)
{
int rc = 0;
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = alloc_chrdev_region(&mdc_changelog_dev, 0,
MDC_CHANGELOG_DEV_COUNT,
MDC_CHANGELOG_DEV_NAME);
{
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(mdd_caches);
if (rc)
return rc;
FID_NOBRACE_LEN + 1);
BUILD_BUG_ON(sizeof("[0x0123456789ABCDEF:0x01234567:0x01234567]") !=
FID_LEN + 1);
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(mdt_caches);
if (rc)
return rc;
static int __init mgc_init(void)
{
+ int rc;
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
return class_register_type(&mgc_obd_ops, NULL, false,
LUSTRE_MGC_NAME, NULL);
}
static int __init mgs_init(void)
{
+ int rc;
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
return class_register_type(&mgs_obd_device_ops, NULL, true,
LUSTRE_MGS_NAME, &mgs_device_type);
}
register_oom_notifier(&obdclass_oom);
+ err = libcfs_setup();
+ if (err)
+ return err;
+
err = obd_init_checks();
if (err)
return err;
LASSERT(PAGE_SIZE % OBD_ECHO_BLOCK_SIZE == 0);
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
# ifdef HAVE_SERVER_SUPPORT
rc = echo_persistent_pages_init();
if (rc != 0)
{
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(ofd_caches);
if (rc)
return rc;
* symbols from modules.*/
CDEBUG(D_INFO, "Lustre OSC module (%p).\n", &osc_caches);
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(osc_caches);
if (rc)
RETURN(rc);
BUILD_BUG_ON(sizeof(struct osd_thread_info) > PAGE_SIZE);
#endif
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
osd_oi_mod_init();
rc = lu_kmem_init(ldiskfs_caches);
{
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = osd_options_init();
if (rc)
return rc;
struct obd_type *sym;
int rc;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
rc = lu_kmem_init(osp_caches);
if (rc)
return rc;
int rc;
ENTRY;
+ rc = libcfs_setup();
+ if (rc)
+ RETURN(rc);
rc = class_register_type(&ost_obd_ops, NULL, false,
LUSTRE_OSS_NAME, NULL);
ptlrpc_init_xid();
lustre_msg_early_size_init();
+ rc = libcfs_setup();
+ if (rc)
+ RETURN(rc);
+
rc = req_layout_init();
if (rc)
RETURN(rc);
int rc;
ENTRY;
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
+
lquota_key_init_generic(&lquota_thread_key, NULL);
lu_context_key_register(&lquota_thread_key);