Message ID | 1468428381-30363-1-git-send-email-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
On 2016-07-14 12:46 AM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > The name of the efi module and the device is going to change once > the driver lands upstream in the kernel. So make the module loading > more flexible to cater for legacy and the new upstream'd kernel driver. > > Also abstract out the efi test device driver name and provide a thin > open/close device abstraction layer so we can keep the device name > out of the tests. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts_efi_module.h | 2 + > src/lib/src/fwts_efi_module.c | 202 ++++++++++++++++++++++++------- > src/uefi/uefirtauthvar/uefirtauthvar.c | 6 +- > src/uefi/uefirtmisc/uefirtmisc.c | 6 +- > src/uefi/uefirttime/uefirttime.c | 6 +- > src/uefi/uefirtvariable/uefirtvariable.c | 6 +- > src/uefi/uefivarinfo/uefivarinfo.c | 6 +- > 7 files changed, 176 insertions(+), 58 deletions(-) > > diff --git a/src/lib/include/fwts_efi_module.h b/src/lib/include/fwts_efi_module.h > index ec8eceb..73c4ba6 100644 > --- a/src/lib/include/fwts_efi_module.h > +++ b/src/lib/include/fwts_efi_module.h > @@ -22,5 +22,7 @@ > > int fwts_lib_efi_runtime_load_module(fwts_framework *fw); > int fwts_lib_efi_runtime_unload_module(fwts_framework *fw); > +int fwts_lib_efi_runtime_open(void); > +int fwts_lib_efi_runtime_close(int fd); > > #endif > diff --git a/src/lib/src/fwts_efi_module.c b/src/lib/src/fwts_efi_module.c > index b3e0bdb..f95ee63 100644 > --- a/src/lib/src/fwts_efi_module.c > +++ b/src/lib/src/fwts_efi_module.c > @@ -21,90 +21,206 @@ > #include <string.h> > #include <sys/types.h> > #include <sys/stat.h> > +#include <fcntl.h> > #include <unistd.h> > > #include "fwts_pipeio.h" > > -static bool module_already_loaded = false; > +static char *efi_dev_name = NULL; > +static char *module_name = NULL; > > -static int check_module_loaded(void) > +/* > + * check_module_loaded() > + * check if a given module is loaded > + */ > +static int check_module_loaded( > + fwts_framework *fw, > + char *module, > + bool *loaded) > { > FILE *fp; > > - module_already_loaded = false; > + *loaded = false; > + > if ((fp = fopen("/proc/modules", "r")) != NULL) { > char buffer[1024]; > > while (fgets(buffer, sizeof(buffer), fp) != NULL) { > - if (strstr(buffer, "efi_runtime") != NULL) { > - module_already_loaded = true; > + if (strstr(buffer, module)) { > + *loaded = true; > break; > } > } > fclose(fp); > return FWTS_OK; > } > + fwts_log_error(fw, "Could not open /proc/modules to check if efi module '%s' is loaded.", module); > + > return FWTS_ERROR; > } > > -int fwts_lib_efi_runtime_load_module(fwts_framework *fw) > +/* > + * check_module_loaded_no_dev() > + * sanity check - we don't have a device so we definitely should > + * not have the module loaded either > + */ > +static int check_module_loaded_no_dev( > + fwts_framework *fw, > + char *module) > { > - struct stat statbuf; > + bool loaded; > > - if (check_module_loaded() != FWTS_OK) { > - fwts_log_error(fw, "Could not open /proc/modules for checking module loaded."); > + if (check_module_loaded(fw, module, &loaded) != FWTS_OK) > + return FWTS_ERROR; > + if (loaded) { > + fwts_log_error(fw, "Module '%s' is already loaded, but device not available.", module); > return FWTS_ERROR; > } > + return FWTS_OK; > +} > > - if (!module_already_loaded) { > - int status; > - > - if (fwts_exec("modprobe efi_runtime", &status) != FWTS_OK) { > - fwts_log_error(fw, "Load efi_runtime module error."); > - return FWTS_ERROR; > - } else { > - (void)check_module_loaded(); > - if (!module_already_loaded) { > - fwts_log_error(fw, "Could not load efi_runtime module."); > - return FWTS_ERROR; > - } > - } > - } > +/* > + * check_device() > + * check if the device exists and is a char dev > + */ > +static int check_device(char *devname) > +{ > + struct stat statbuf; > > - if (stat("/dev/efi_runtime", &statbuf)) { > - fwts_log_error(fw, "Loaded efi_runtime module but /dev/efi_runtime is not present."); > + if (stat(devname, &statbuf)) > return FWTS_ERROR; > + > + if (S_ISCHR(statbuf.st_mode)) { > + efi_dev_name = devname; > + return FWTS_OK; > } > + return FWTS_ERROR; > +} > + > +/* > + * load_module() > + * load the module and check if the device appears > + */ > +static int load_module( > + fwts_framework *fw, > + char *module, > + char *devname) > +{ > + int status; > + char cmd[80]; > + bool loaded; > + > + snprintf(cmd, sizeof(cmd), "modprobe %s", module); > > - if (!S_ISCHR(statbuf.st_mode)) { > - fwts_log_error(fw, "Loaded efi_runtime module but /dev/efi_runtime is not a char device."); > + if (fwts_exec(cmd, &status) != FWTS_OK) > + return FWTS_ERROR; > + > + if (check_module_loaded(fw, module, &loaded) != FWTS_OK) > return FWTS_ERROR; > - } > + > + if (!loaded) > + return FWTS_ERROR; > + > + if (check_device(devname) != FWTS_OK) > + return FWTS_ERROR; > + > + module_name = module; > > return FWTS_OK; > } > > +/* > + * fwts_lib_efi_runtime_load_module() > + * load the runtime module, for historical reasons > + * we have two names for the module and the device > + * it creates > + */ > +int fwts_lib_efi_runtime_load_module(fwts_framework *fw) > +{ > + efi_dev_name = NULL; > + module_name = NULL; > + > + /* Check if dev is already available */ > + if (check_device("/dev/efi_test") == FWTS_OK) > + return FWTS_OK; > + if (check_device("/dev/efi_runtime") == FWTS_OK) > + return FWTS_OK; > + > + /* Since the devices can't be found, the module should be not loaded */ > + if (check_module_loaded_no_dev(fw, "efi_test") != FWTS_OK) > + return FWTS_ERROR; > + if (check_module_loaded_no_dev(fw, "efi_runtime") != FWTS_OK) > + return FWTS_ERROR; > + > + /* Now try to load the module */ > + > + if (load_module(fw, "efi_test", "/dev/efi_test") == FWTS_OK) > + return FWTS_OK; > + if (load_module(fw, "efi_runtime", "/dev/efi_runtime") == FWTS_OK) > + return FWTS_OK; > + > + fwts_log_error(fw, "Failed to load efi test module."); > + return FWTS_ERROR; > +} > > +/* > + * fwts_lib_efi_runtime_unload_module() > + * unload the runtile module > + */ > int fwts_lib_efi_runtime_unload_module(fwts_framework *fw) > { > - if (check_module_loaded() != FWTS_OK) { > - fwts_log_error(fw, "Could not open /proc/modules for checking module loaded."); > + bool loaded; > + int status; > + char cmd[80], *tmp_name = module_name; > + > + efi_dev_name = NULL; > + > + /* No module, not much to do */ > + if (!module_name) > + return FWTS_OK; > + > + module_name = NULL; > + > + /* If it is not loaded, no need to unload it */ > + if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) > + return FWTS_ERROR; > + if (!loaded) > + return FWTS_OK; > + > + snprintf(cmd, sizeof(cmd), "modprobe -r %s", tmp_name); > + if (fwts_exec(cmd, &status) != FWTS_OK) { > + fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); > return FWTS_ERROR; > } > - if (module_already_loaded) { > - int status; > - > - if (fwts_exec("modprobe -r efi_runtime", &status) != FWTS_OK) { > - fwts_log_error(fw, "Unload efi_runtime module error."); > - return FWTS_ERROR; > - } else { > - (void)check_module_loaded(); > - if (module_already_loaded) { > - fwts_log_error(fw, "Could not unload efi_runtime module."); > - return FWTS_ERROR; > - } > - } > + > + /* Module should not be loaded at this point */ > + if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) > + return FWTS_ERROR; > + if (loaded) { > + fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); > + return FWTS_ERROR; > } > > return FWTS_OK; > } > + > +/* > + * fwts_lib_efi_runtime_open() > + * open the device > + */ > +int fwts_lib_efi_runtime_open(void) > +{ > + if (!efi_dev_name) > + return -1; > + > + return open(efi_dev_name, O_WRONLY | O_RDWR); > +} > + > +/* > + * fwts_lib_efi_runtime_close() > + * close the device > + */ > +int fwts_lib_efi_runtime_close(int fd) > +{ > + return close(fd); > +} > diff --git a/src/uefi/uefirtauthvar/uefirtauthvar.c b/src/uefi/uefirtauthvar/uefirtauthvar.c > index ed23a8e..cdfd7aa 100644 > --- a/src/uefi/uefirtauthvar/uefirtauthvar.c > +++ b/src/uefi/uefirtauthvar/uefirtauthvar.c > @@ -123,9 +123,9 @@ static int uefirtauthvar_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -136,7 +136,7 @@ static int uefirtauthvar_init(fwts_framework *fw) > > static int uefirtauthvar_deinit(fwts_framework *fw) > { > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefirtmisc/uefirtmisc.c b/src/uefi/uefirtmisc/uefirtmisc.c > index 347b2b1..d06e2a1 100644 > --- a/src/uefi/uefirtmisc/uefirtmisc.c > +++ b/src/uefi/uefirtmisc/uefirtmisc.c > @@ -55,9 +55,9 @@ static int uefirtmisc_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -68,7 +68,7 @@ static int uefirtmisc_deinit(fwts_framework *fw) > { > FWTS_UNUSED(fw); > > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefirttime/uefirttime.c b/src/uefi/uefirttime/uefirttime.c > index f79e2da..55e9d19 100644 > --- a/src/uefi/uefirttime/uefirttime.c > +++ b/src/uefi/uefirttime/uefirttime.c > @@ -179,9 +179,9 @@ static int uefirttime_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -192,7 +192,7 @@ static int uefirttime_deinit(fwts_framework *fw) > { > FWTS_UNUSED(fw); > > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefirtvariable/uefirtvariable.c b/src/uefi/uefirtvariable/uefirtvariable.c > index f60dbad..2adc064 100644 > --- a/src/uefi/uefirtvariable/uefirtvariable.c > +++ b/src/uefi/uefirtvariable/uefirtvariable.c > @@ -101,9 +101,9 @@ static int uefirtvariable_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -114,7 +114,7 @@ static int uefirtvariable_init(fwts_framework *fw) > > static int uefirtvariable_deinit(fwts_framework *fw) > { > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefivarinfo/uefivarinfo.c b/src/uefi/uefivarinfo/uefivarinfo.c > index 22afe53..24798a9 100644 > --- a/src/uefi/uefivarinfo/uefivarinfo.c > +++ b/src/uefi/uefivarinfo/uefivarinfo.c > @@ -46,9 +46,9 @@ static int uefivarinfo_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -57,7 +57,7 @@ static int uefivarinfo_init(fwts_framework *fw) > > static int uefivarinfo_deinit(fwts_framework *fw) > { > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > Acked-by: Alex Hung <alex.hung@canonical.com>
On 2016年07月14日 00:46, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > The name of the efi module and the device is going to change once > the driver lands upstream in the kernel. So make the module loading > more flexible to cater for legacy and the new upstream'd kernel driver. > > Also abstract out the efi test device driver name and provide a thin > open/close device abstraction layer so we can keep the device name > out of the tests. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/lib/include/fwts_efi_module.h | 2 + > src/lib/src/fwts_efi_module.c | 202 ++++++++++++++++++++++++------- > src/uefi/uefirtauthvar/uefirtauthvar.c | 6 +- > src/uefi/uefirtmisc/uefirtmisc.c | 6 +- > src/uefi/uefirttime/uefirttime.c | 6 +- > src/uefi/uefirtvariable/uefirtvariable.c | 6 +- > src/uefi/uefivarinfo/uefivarinfo.c | 6 +- > 7 files changed, 176 insertions(+), 58 deletions(-) > > diff --git a/src/lib/include/fwts_efi_module.h b/src/lib/include/fwts_efi_module.h > index ec8eceb..73c4ba6 100644 > --- a/src/lib/include/fwts_efi_module.h > +++ b/src/lib/include/fwts_efi_module.h > @@ -22,5 +22,7 @@ > > int fwts_lib_efi_runtime_load_module(fwts_framework *fw); > int fwts_lib_efi_runtime_unload_module(fwts_framework *fw); > +int fwts_lib_efi_runtime_open(void); > +int fwts_lib_efi_runtime_close(int fd); > > #endif > diff --git a/src/lib/src/fwts_efi_module.c b/src/lib/src/fwts_efi_module.c > index b3e0bdb..f95ee63 100644 > --- a/src/lib/src/fwts_efi_module.c > +++ b/src/lib/src/fwts_efi_module.c > @@ -21,90 +21,206 @@ > #include <string.h> > #include <sys/types.h> > #include <sys/stat.h> > +#include <fcntl.h> > #include <unistd.h> > > #include "fwts_pipeio.h" > > -static bool module_already_loaded = false; > +static char *efi_dev_name = NULL; > +static char *module_name = NULL; > > -static int check_module_loaded(void) > +/* > + * check_module_loaded() > + * check if a given module is loaded > + */ > +static int check_module_loaded( > + fwts_framework *fw, > + char *module, > + bool *loaded) > { > FILE *fp; > > - module_already_loaded = false; > + *loaded = false; > + > if ((fp = fopen("/proc/modules", "r")) != NULL) { > char buffer[1024]; > > while (fgets(buffer, sizeof(buffer), fp) != NULL) { > - if (strstr(buffer, "efi_runtime") != NULL) { > - module_already_loaded = true; > + if (strstr(buffer, module)) { > + *loaded = true; > break; > } > } > fclose(fp); > return FWTS_OK; > } > + fwts_log_error(fw, "Could not open /proc/modules to check if efi module '%s' is loaded.", module); > + > return FWTS_ERROR; > } > > -int fwts_lib_efi_runtime_load_module(fwts_framework *fw) > +/* > + * check_module_loaded_no_dev() > + * sanity check - we don't have a device so we definitely should > + * not have the module loaded either > + */ > +static int check_module_loaded_no_dev( > + fwts_framework *fw, > + char *module) > { > - struct stat statbuf; > + bool loaded; > > - if (check_module_loaded() != FWTS_OK) { > - fwts_log_error(fw, "Could not open /proc/modules for checking module loaded."); > + if (check_module_loaded(fw, module, &loaded) != FWTS_OK) > + return FWTS_ERROR; > + if (loaded) { > + fwts_log_error(fw, "Module '%s' is already loaded, but device not available.", module); > return FWTS_ERROR; > } > + return FWTS_OK; > +} > > - if (!module_already_loaded) { > - int status; > - > - if (fwts_exec("modprobe efi_runtime", &status) != FWTS_OK) { > - fwts_log_error(fw, "Load efi_runtime module error."); > - return FWTS_ERROR; > - } else { > - (void)check_module_loaded(); > - if (!module_already_loaded) { > - fwts_log_error(fw, "Could not load efi_runtime module."); > - return FWTS_ERROR; > - } > - } > - } > +/* > + * check_device() > + * check if the device exists and is a char dev > + */ > +static int check_device(char *devname) > +{ > + struct stat statbuf; > > - if (stat("/dev/efi_runtime", &statbuf)) { > - fwts_log_error(fw, "Loaded efi_runtime module but /dev/efi_runtime is not present."); > + if (stat(devname, &statbuf)) > return FWTS_ERROR; > + > + if (S_ISCHR(statbuf.st_mode)) { > + efi_dev_name = devname; > + return FWTS_OK; > } > + return FWTS_ERROR; > +} > + > +/* > + * load_module() > + * load the module and check if the device appears > + */ > +static int load_module( > + fwts_framework *fw, > + char *module, > + char *devname) > +{ > + int status; > + char cmd[80]; > + bool loaded; > + > + snprintf(cmd, sizeof(cmd), "modprobe %s", module); > > - if (!S_ISCHR(statbuf.st_mode)) { > - fwts_log_error(fw, "Loaded efi_runtime module but /dev/efi_runtime is not a char device."); > + if (fwts_exec(cmd, &status) != FWTS_OK) > + return FWTS_ERROR; > + > + if (check_module_loaded(fw, module, &loaded) != FWTS_OK) > return FWTS_ERROR; > - } > + > + if (!loaded) > + return FWTS_ERROR; > + > + if (check_device(devname) != FWTS_OK) > + return FWTS_ERROR; > + > + module_name = module; > > return FWTS_OK; > } > > +/* > + * fwts_lib_efi_runtime_load_module() > + * load the runtime module, for historical reasons > + * we have two names for the module and the device > + * it creates > + */ > +int fwts_lib_efi_runtime_load_module(fwts_framework *fw) > +{ > + efi_dev_name = NULL; > + module_name = NULL; > + > + /* Check if dev is already available */ > + if (check_device("/dev/efi_test") == FWTS_OK) > + return FWTS_OK; > + if (check_device("/dev/efi_runtime") == FWTS_OK) > + return FWTS_OK; > + > + /* Since the devices can't be found, the module should be not loaded */ > + if (check_module_loaded_no_dev(fw, "efi_test") != FWTS_OK) > + return FWTS_ERROR; > + if (check_module_loaded_no_dev(fw, "efi_runtime") != FWTS_OK) > + return FWTS_ERROR; > + > + /* Now try to load the module */ > + > + if (load_module(fw, "efi_test", "/dev/efi_test") == FWTS_OK) > + return FWTS_OK; > + if (load_module(fw, "efi_runtime", "/dev/efi_runtime") == FWTS_OK) > + return FWTS_OK; > + > + fwts_log_error(fw, "Failed to load efi test module."); > + return FWTS_ERROR; > +} > > +/* > + * fwts_lib_efi_runtime_unload_module() > + * unload the runtile module > + */ > int fwts_lib_efi_runtime_unload_module(fwts_framework *fw) > { > - if (check_module_loaded() != FWTS_OK) { > - fwts_log_error(fw, "Could not open /proc/modules for checking module loaded."); > + bool loaded; > + int status; > + char cmd[80], *tmp_name = module_name; > + > + efi_dev_name = NULL; > + > + /* No module, not much to do */ > + if (!module_name) > + return FWTS_OK; > + > + module_name = NULL; > + > + /* If it is not loaded, no need to unload it */ > + if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) > + return FWTS_ERROR; > + if (!loaded) > + return FWTS_OK; > + > + snprintf(cmd, sizeof(cmd), "modprobe -r %s", tmp_name); > + if (fwts_exec(cmd, &status) != FWTS_OK) { > + fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); > return FWTS_ERROR; > } > - if (module_already_loaded) { > - int status; > - > - if (fwts_exec("modprobe -r efi_runtime", &status) != FWTS_OK) { > - fwts_log_error(fw, "Unload efi_runtime module error."); > - return FWTS_ERROR; > - } else { > - (void)check_module_loaded(); > - if (module_already_loaded) { > - fwts_log_error(fw, "Could not unload efi_runtime module."); > - return FWTS_ERROR; > - } > - } > + > + /* Module should not be loaded at this point */ > + if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) > + return FWTS_ERROR; > + if (loaded) { > + fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); > + return FWTS_ERROR; > } > > return FWTS_OK; > } > + > +/* > + * fwts_lib_efi_runtime_open() > + * open the device > + */ > +int fwts_lib_efi_runtime_open(void) > +{ > + if (!efi_dev_name) > + return -1; > + > + return open(efi_dev_name, O_WRONLY | O_RDWR); > +} > + > +/* > + * fwts_lib_efi_runtime_close() > + * close the device > + */ > +int fwts_lib_efi_runtime_close(int fd) > +{ > + return close(fd); > +} > diff --git a/src/uefi/uefirtauthvar/uefirtauthvar.c b/src/uefi/uefirtauthvar/uefirtauthvar.c > index ed23a8e..cdfd7aa 100644 > --- a/src/uefi/uefirtauthvar/uefirtauthvar.c > +++ b/src/uefi/uefirtauthvar/uefirtauthvar.c > @@ -123,9 +123,9 @@ static int uefirtauthvar_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -136,7 +136,7 @@ static int uefirtauthvar_init(fwts_framework *fw) > > static int uefirtauthvar_deinit(fwts_framework *fw) > { > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefirtmisc/uefirtmisc.c b/src/uefi/uefirtmisc/uefirtmisc.c > index 347b2b1..d06e2a1 100644 > --- a/src/uefi/uefirtmisc/uefirtmisc.c > +++ b/src/uefi/uefirtmisc/uefirtmisc.c > @@ -55,9 +55,9 @@ static int uefirtmisc_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -68,7 +68,7 @@ static int uefirtmisc_deinit(fwts_framework *fw) > { > FWTS_UNUSED(fw); > > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefirttime/uefirttime.c b/src/uefi/uefirttime/uefirttime.c > index f79e2da..55e9d19 100644 > --- a/src/uefi/uefirttime/uefirttime.c > +++ b/src/uefi/uefirttime/uefirttime.c > @@ -179,9 +179,9 @@ static int uefirttime_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -192,7 +192,7 @@ static int uefirttime_deinit(fwts_framework *fw) > { > FWTS_UNUSED(fw); > > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefirtvariable/uefirtvariable.c b/src/uefi/uefirtvariable/uefirtvariable.c > index f60dbad..2adc064 100644 > --- a/src/uefi/uefirtvariable/uefirtvariable.c > +++ b/src/uefi/uefirtvariable/uefirtvariable.c > @@ -101,9 +101,9 @@ static int uefirtvariable_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -114,7 +114,7 @@ static int uefirtvariable_init(fwts_framework *fw) > > static int uefirtvariable_deinit(fwts_framework *fw) > { > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > diff --git a/src/uefi/uefivarinfo/uefivarinfo.c b/src/uefi/uefivarinfo/uefivarinfo.c > index 22afe53..24798a9 100644 > --- a/src/uefi/uefivarinfo/uefivarinfo.c > +++ b/src/uefi/uefivarinfo/uefivarinfo.c > @@ -46,9 +46,9 @@ static int uefivarinfo_init(fwts_framework *fw) > return FWTS_ABORTED; > } > > - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); > + fd = fwts_lib_efi_runtime_open(); > if (fd == -1) { > - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); > + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); > return FWTS_ABORTED; > } > > @@ -57,7 +57,7 @@ static int uefivarinfo_init(fwts_framework *fw) > > static int uefivarinfo_deinit(fwts_framework *fw) > { > - close(fd); > + fwts_lib_efi_runtime_close(fd); > fwts_lib_efi_runtime_unload_module(fw); > > return FWTS_OK; > Build and test with efi_test driver and efi_runtime driver, both work fine. Thanks Colin. Acked-by: Ivan Hu <ivan.hu@canonical.com>
diff --git a/src/lib/include/fwts_efi_module.h b/src/lib/include/fwts_efi_module.h index ec8eceb..73c4ba6 100644 --- a/src/lib/include/fwts_efi_module.h +++ b/src/lib/include/fwts_efi_module.h @@ -22,5 +22,7 @@ int fwts_lib_efi_runtime_load_module(fwts_framework *fw); int fwts_lib_efi_runtime_unload_module(fwts_framework *fw); +int fwts_lib_efi_runtime_open(void); +int fwts_lib_efi_runtime_close(int fd); #endif diff --git a/src/lib/src/fwts_efi_module.c b/src/lib/src/fwts_efi_module.c index b3e0bdb..f95ee63 100644 --- a/src/lib/src/fwts_efi_module.c +++ b/src/lib/src/fwts_efi_module.c @@ -21,90 +21,206 @@ #include <string.h> #include <sys/types.h> #include <sys/stat.h> +#include <fcntl.h> #include <unistd.h> #include "fwts_pipeio.h" -static bool module_already_loaded = false; +static char *efi_dev_name = NULL; +static char *module_name = NULL; -static int check_module_loaded(void) +/* + * check_module_loaded() + * check if a given module is loaded + */ +static int check_module_loaded( + fwts_framework *fw, + char *module, + bool *loaded) { FILE *fp; - module_already_loaded = false; + *loaded = false; + if ((fp = fopen("/proc/modules", "r")) != NULL) { char buffer[1024]; while (fgets(buffer, sizeof(buffer), fp) != NULL) { - if (strstr(buffer, "efi_runtime") != NULL) { - module_already_loaded = true; + if (strstr(buffer, module)) { + *loaded = true; break; } } fclose(fp); return FWTS_OK; } + fwts_log_error(fw, "Could not open /proc/modules to check if efi module '%s' is loaded.", module); + return FWTS_ERROR; } -int fwts_lib_efi_runtime_load_module(fwts_framework *fw) +/* + * check_module_loaded_no_dev() + * sanity check - we don't have a device so we definitely should + * not have the module loaded either + */ +static int check_module_loaded_no_dev( + fwts_framework *fw, + char *module) { - struct stat statbuf; + bool loaded; - if (check_module_loaded() != FWTS_OK) { - fwts_log_error(fw, "Could not open /proc/modules for checking module loaded."); + if (check_module_loaded(fw, module, &loaded) != FWTS_OK) + return FWTS_ERROR; + if (loaded) { + fwts_log_error(fw, "Module '%s' is already loaded, but device not available.", module); return FWTS_ERROR; } + return FWTS_OK; +} - if (!module_already_loaded) { - int status; - - if (fwts_exec("modprobe efi_runtime", &status) != FWTS_OK) { - fwts_log_error(fw, "Load efi_runtime module error."); - return FWTS_ERROR; - } else { - (void)check_module_loaded(); - if (!module_already_loaded) { - fwts_log_error(fw, "Could not load efi_runtime module."); - return FWTS_ERROR; - } - } - } +/* + * check_device() + * check if the device exists and is a char dev + */ +static int check_device(char *devname) +{ + struct stat statbuf; - if (stat("/dev/efi_runtime", &statbuf)) { - fwts_log_error(fw, "Loaded efi_runtime module but /dev/efi_runtime is not present."); + if (stat(devname, &statbuf)) return FWTS_ERROR; + + if (S_ISCHR(statbuf.st_mode)) { + efi_dev_name = devname; + return FWTS_OK; } + return FWTS_ERROR; +} + +/* + * load_module() + * load the module and check if the device appears + */ +static int load_module( + fwts_framework *fw, + char *module, + char *devname) +{ + int status; + char cmd[80]; + bool loaded; + + snprintf(cmd, sizeof(cmd), "modprobe %s", module); - if (!S_ISCHR(statbuf.st_mode)) { - fwts_log_error(fw, "Loaded efi_runtime module but /dev/efi_runtime is not a char device."); + if (fwts_exec(cmd, &status) != FWTS_OK) + return FWTS_ERROR; + + if (check_module_loaded(fw, module, &loaded) != FWTS_OK) return FWTS_ERROR; - } + + if (!loaded) + return FWTS_ERROR; + + if (check_device(devname) != FWTS_OK) + return FWTS_ERROR; + + module_name = module; return FWTS_OK; } +/* + * fwts_lib_efi_runtime_load_module() + * load the runtime module, for historical reasons + * we have two names for the module and the device + * it creates + */ +int fwts_lib_efi_runtime_load_module(fwts_framework *fw) +{ + efi_dev_name = NULL; + module_name = NULL; + + /* Check if dev is already available */ + if (check_device("/dev/efi_test") == FWTS_OK) + return FWTS_OK; + if (check_device("/dev/efi_runtime") == FWTS_OK) + return FWTS_OK; + + /* Since the devices can't be found, the module should be not loaded */ + if (check_module_loaded_no_dev(fw, "efi_test") != FWTS_OK) + return FWTS_ERROR; + if (check_module_loaded_no_dev(fw, "efi_runtime") != FWTS_OK) + return FWTS_ERROR; + + /* Now try to load the module */ + + if (load_module(fw, "efi_test", "/dev/efi_test") == FWTS_OK) + return FWTS_OK; + if (load_module(fw, "efi_runtime", "/dev/efi_runtime") == FWTS_OK) + return FWTS_OK; + + fwts_log_error(fw, "Failed to load efi test module."); + return FWTS_ERROR; +} +/* + * fwts_lib_efi_runtime_unload_module() + * unload the runtile module + */ int fwts_lib_efi_runtime_unload_module(fwts_framework *fw) { - if (check_module_loaded() != FWTS_OK) { - fwts_log_error(fw, "Could not open /proc/modules for checking module loaded."); + bool loaded; + int status; + char cmd[80], *tmp_name = module_name; + + efi_dev_name = NULL; + + /* No module, not much to do */ + if (!module_name) + return FWTS_OK; + + module_name = NULL; + + /* If it is not loaded, no need to unload it */ + if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) + return FWTS_ERROR; + if (!loaded) + return FWTS_OK; + + snprintf(cmd, sizeof(cmd), "modprobe -r %s", tmp_name); + if (fwts_exec(cmd, &status) != FWTS_OK) { + fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); return FWTS_ERROR; } - if (module_already_loaded) { - int status; - - if (fwts_exec("modprobe -r efi_runtime", &status) != FWTS_OK) { - fwts_log_error(fw, "Unload efi_runtime module error."); - return FWTS_ERROR; - } else { - (void)check_module_loaded(); - if (module_already_loaded) { - fwts_log_error(fw, "Could not unload efi_runtime module."); - return FWTS_ERROR; - } - } + + /* Module should not be loaded at this point */ + if (check_module_loaded(fw, tmp_name, &loaded) != FWTS_OK) + return FWTS_ERROR; + if (loaded) { + fwts_log_error(fw, "Failed to unload module '%s'.", tmp_name); + return FWTS_ERROR; } return FWTS_OK; } + +/* + * fwts_lib_efi_runtime_open() + * open the device + */ +int fwts_lib_efi_runtime_open(void) +{ + if (!efi_dev_name) + return -1; + + return open(efi_dev_name, O_WRONLY | O_RDWR); +} + +/* + * fwts_lib_efi_runtime_close() + * close the device + */ +int fwts_lib_efi_runtime_close(int fd) +{ + return close(fd); +} diff --git a/src/uefi/uefirtauthvar/uefirtauthvar.c b/src/uefi/uefirtauthvar/uefirtauthvar.c index ed23a8e..cdfd7aa 100644 --- a/src/uefi/uefirtauthvar/uefirtauthvar.c +++ b/src/uefi/uefirtauthvar/uefirtauthvar.c @@ -123,9 +123,9 @@ static int uefirtauthvar_init(fwts_framework *fw) return FWTS_ABORTED; } - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); + fd = fwts_lib_efi_runtime_open(); if (fd == -1) { - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); return FWTS_ABORTED; } @@ -136,7 +136,7 @@ static int uefirtauthvar_init(fwts_framework *fw) static int uefirtauthvar_deinit(fwts_framework *fw) { - close(fd); + fwts_lib_efi_runtime_close(fd); fwts_lib_efi_runtime_unload_module(fw); return FWTS_OK; diff --git a/src/uefi/uefirtmisc/uefirtmisc.c b/src/uefi/uefirtmisc/uefirtmisc.c index 347b2b1..d06e2a1 100644 --- a/src/uefi/uefirtmisc/uefirtmisc.c +++ b/src/uefi/uefirtmisc/uefirtmisc.c @@ -55,9 +55,9 @@ static int uefirtmisc_init(fwts_framework *fw) return FWTS_ABORTED; } - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); + fd = fwts_lib_efi_runtime_open(); if (fd == -1) { - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); return FWTS_ABORTED; } @@ -68,7 +68,7 @@ static int uefirtmisc_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); - close(fd); + fwts_lib_efi_runtime_close(fd); fwts_lib_efi_runtime_unload_module(fw); return FWTS_OK; diff --git a/src/uefi/uefirttime/uefirttime.c b/src/uefi/uefirttime/uefirttime.c index f79e2da..55e9d19 100644 --- a/src/uefi/uefirttime/uefirttime.c +++ b/src/uefi/uefirttime/uefirttime.c @@ -179,9 +179,9 @@ static int uefirttime_init(fwts_framework *fw) return FWTS_ABORTED; } - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); + fd = fwts_lib_efi_runtime_open(); if (fd == -1) { - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); return FWTS_ABORTED; } @@ -192,7 +192,7 @@ static int uefirttime_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); - close(fd); + fwts_lib_efi_runtime_close(fd); fwts_lib_efi_runtime_unload_module(fw); return FWTS_OK; diff --git a/src/uefi/uefirtvariable/uefirtvariable.c b/src/uefi/uefirtvariable/uefirtvariable.c index f60dbad..2adc064 100644 --- a/src/uefi/uefirtvariable/uefirtvariable.c +++ b/src/uefi/uefirtvariable/uefirtvariable.c @@ -101,9 +101,9 @@ static int uefirtvariable_init(fwts_framework *fw) return FWTS_ABORTED; } - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); + fd = fwts_lib_efi_runtime_open(); if (fd == -1) { - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); return FWTS_ABORTED; } @@ -114,7 +114,7 @@ static int uefirtvariable_init(fwts_framework *fw) static int uefirtvariable_deinit(fwts_framework *fw) { - close(fd); + fwts_lib_efi_runtime_close(fd); fwts_lib_efi_runtime_unload_module(fw); return FWTS_OK; diff --git a/src/uefi/uefivarinfo/uefivarinfo.c b/src/uefi/uefivarinfo/uefivarinfo.c index 22afe53..24798a9 100644 --- a/src/uefi/uefivarinfo/uefivarinfo.c +++ b/src/uefi/uefivarinfo/uefivarinfo.c @@ -46,9 +46,9 @@ static int uefivarinfo_init(fwts_framework *fw) return FWTS_ABORTED; } - fd = open("/dev/efi_runtime", O_WRONLY | O_RDWR); + fd = fwts_lib_efi_runtime_open(); if (fd == -1) { - fwts_log_info(fw, "Cannot open efi_runtime driver. Aborted."); + fwts_log_info(fw, "Cannot open EFI test driver. Aborted."); return FWTS_ABORTED; } @@ -57,7 +57,7 @@ static int uefivarinfo_init(fwts_framework *fw) static int uefivarinfo_deinit(fwts_framework *fw) { - close(fd); + fwts_lib_efi_runtime_close(fd); fwts_lib_efi_runtime_unload_module(fw); return FWTS_OK;