Cleaning Up Resources on Module Removal
When you remove a kernel module, it is essential to clean up all resources that were allocated during the module's operation. This process, commonly called resource cleanup, ensures that memory, device registrations, and other kernel resources do not remain allocated after the module is unloaded. Failing to release these resources can lead to memory leaks, dangling device nodes, or even system instability. The kernel expects each module to provide an exit function responsible for undoing everything performed in the initialization phase.
cleanup_module_example.c
12345678910111213141516171819202122232425262728293031323334#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> #define DEVICE_NAME "cleanup_demo" static int major; static char *buffer; static int __init cleanup_demo_init(void) { major = register_chrdev(0, DEVICE_NAME, NULL); if (major < 0) return major; buffer = kmalloc(1024, GFP_KERNEL); if (!buffer) { unregister_chrdev(major, DEVICE_NAME); return -ENOMEM; } return 0; } static void __exit cleanup_demo_exit(void) { if (buffer) { kfree(buffer); buffer = NULL; } if (major >= 0) unregister_chrdev(major, DEVICE_NAME); } module_init(cleanup_demo_init); module_exit(cleanup_demo_exit); MODULE_LICENSE("GPL");
Proper cleanup in the module's exit function is critical for system stability. In the code above, the cleanup_demo_exit function frees the memory previously allocated with kmalloc and unregisters the character device from the kernel. This ensures that no memory is leaked and the major number is released, so it can be reused by other drivers or modules. If these steps are skipped, the system may run out of memory over time, or device nodes may remain in /dev, causing confusion and potential conflicts.
remove_device_node_example.c
1234567891011121314151617181920212223242526272829303132333435363738394041#include <linux/module.h> #include <linux/init.h> #include <linux/device.h> #include <linux/fs.h> #define DEVICE_NAME "node_cleanup" static int major; static struct class *cls; static struct device *dev; static int __init node_cleanup_init(void) { major = register_chrdev(0, DEVICE_NAME, NULL); if (major < 0) return major; cls = class_create(THIS_MODULE, "node_cleanup_class"); if (IS_ERR(cls)) { unregister_chrdev(major, DEVICE_NAME); return PTR_ERR(cls); } dev = device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); if (IS_ERR(dev)) { class_destroy(cls); unregister_chrdev(major, DEVICE_NAME); return PTR_ERR(dev); } return 0; } static void __exit node_cleanup_exit(void) { if (!IS_ERR_OR_NULL(dev)) device_destroy(cls, MKDEV(major, 0)); if (!IS_ERR_OR_NULL(cls)) class_destroy(cls); if (major >= 0) unregister_chrdev(major, DEVICE_NAME); } module_init(node_cleanup_init); module_exit(node_cleanup_exit); MODULE_LICENSE("GPL");
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Incrível!
Completion taxa melhorada para 3.85
Cleaning Up Resources on Module Removal
Deslize para mostrar o menu
When you remove a kernel module, it is essential to clean up all resources that were allocated during the module's operation. This process, commonly called resource cleanup, ensures that memory, device registrations, and other kernel resources do not remain allocated after the module is unloaded. Failing to release these resources can lead to memory leaks, dangling device nodes, or even system instability. The kernel expects each module to provide an exit function responsible for undoing everything performed in the initialization phase.
cleanup_module_example.c
12345678910111213141516171819202122232425262728293031323334#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> #define DEVICE_NAME "cleanup_demo" static int major; static char *buffer; static int __init cleanup_demo_init(void) { major = register_chrdev(0, DEVICE_NAME, NULL); if (major < 0) return major; buffer = kmalloc(1024, GFP_KERNEL); if (!buffer) { unregister_chrdev(major, DEVICE_NAME); return -ENOMEM; } return 0; } static void __exit cleanup_demo_exit(void) { if (buffer) { kfree(buffer); buffer = NULL; } if (major >= 0) unregister_chrdev(major, DEVICE_NAME); } module_init(cleanup_demo_init); module_exit(cleanup_demo_exit); MODULE_LICENSE("GPL");
Proper cleanup in the module's exit function is critical for system stability. In the code above, the cleanup_demo_exit function frees the memory previously allocated with kmalloc and unregisters the character device from the kernel. This ensures that no memory is leaked and the major number is released, so it can be reused by other drivers or modules. If these steps are skipped, the system may run out of memory over time, or device nodes may remain in /dev, causing confusion and potential conflicts.
remove_device_node_example.c
1234567891011121314151617181920212223242526272829303132333435363738394041#include <linux/module.h> #include <linux/init.h> #include <linux/device.h> #include <linux/fs.h> #define DEVICE_NAME "node_cleanup" static int major; static struct class *cls; static struct device *dev; static int __init node_cleanup_init(void) { major = register_chrdev(0, DEVICE_NAME, NULL); if (major < 0) return major; cls = class_create(THIS_MODULE, "node_cleanup_class"); if (IS_ERR(cls)) { unregister_chrdev(major, DEVICE_NAME); return PTR_ERR(cls); } dev = device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); if (IS_ERR(dev)) { class_destroy(cls); unregister_chrdev(major, DEVICE_NAME); return PTR_ERR(dev); } return 0; } static void __exit node_cleanup_exit(void) { if (!IS_ERR_OR_NULL(dev)) device_destroy(cls, MKDEV(major, 0)); if (!IS_ERR_OR_NULL(cls)) class_destroy(cls); if (major >= 0) unregister_chrdev(major, DEVICE_NAME); } module_init(node_cleanup_init); module_exit(node_cleanup_exit); MODULE_LICENSE("GPL");
Obrigado pelo seu feedback!