From 4b1abce9f5c20e298ddaa3368b3fb6a529c71459 Mon Sep 17 00:00:00 2001 From: Ned Bass Date: Wed, 6 Oct 2010 18:00:55 -0700 Subject: [PATCH] Make commands load zfs module on demand This commit modifies libzfs_init() to attempt to load the zfs kernel module if it is not already loaded. This is done to simplify initialization by letting users simply import their zpools without having to first load the module. Signed-off-by: Brian Behlendorf --- lib/libzfs/libzfs_util.c | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 3c4fae5aa..d72b7c0fc 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -604,11 +605,80 @@ libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr) hdl->libzfs_printerr = printerr; } +static int +libzfs_module_loaded(const char *module) +{ + FILE *f; + int result = 0; + char name[256]; + + f = fopen("/proc/modules", "r"); + if (f == NULL) + return -1; + + while (fgets(name, sizeof(name), f)) { + char *c = strchr(name, ' '); + if (!c) + continue; + *c = 0; + if (strcmp(module, name) == 0) { + result = 1; + break; + } + } + fclose(f); + + return result; +} + +static int +libzfs_run_process(const char *path, char *argv[]) +{ + pid_t pid; + int rc; + + pid = vfork(); + if (pid == 0) { + close(1); + close(2); + (void) execvp(path, argv); + _exit(-1); + } else if (pid > 0) { + int status; + + while ((rc = waitpid(pid, &status, 0)) == -1 && + errno == EINTR); + if (rc < 0 || !WIFEXITED(status)) + return -1; + + return WEXITSTATUS(status); + } + + return -1; +} + +static int +libzfs_load_module(const char *module) +{ + char *argv[4] = {"/sbin/modprobe", "-q", (char *)module, (char *)0}; + + if (libzfs_module_loaded(module)) + return 0; + return libzfs_run_process("modprobe", argv); +} + libzfs_handle_t * libzfs_init(void) { libzfs_handle_t *hdl; + if (libzfs_load_module("zfs") != 0) { + (void) fprintf(stderr, gettext("Failed to load ZFS module " + "stack.\nLoad the module manually by running " + "'insmod /zfs.ko' as root.\n")); + return (NULL); + } + if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) { return (NULL); } -- 2.40.0