X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=lib%2Fefi%2Fefivar.c;h=37bb6d9468440d6d95ca56b88b87ed675b328007;hb=f583f0cf35fc227db5f73ecd04daf7702735b740;hp=a0c21b5b5d345f3717981a9a8dba67b78382e8e8;hpb=6f157d5e4154069174c6b6268a7f13bb48a74593;p=petitboot diff --git a/lib/efi/efivar.c b/lib/efi/efivar.c index a0c21b5..37bb6d9 100644 --- a/lib/efi/efivar.c +++ b/lib/efi/efivar.c @@ -17,43 +17,82 @@ * Author: Ge Song */ +#include #include #include #include #include #include +#include #include #include +#include #include "efivar.h" #include "log/log.h" #include "talloc/talloc.h" -static const char *efivarfs_path; +#ifndef EFIVARFS_MAGIC +#define EFIVARFS_MAGIC 0xde5e81e4 +#endif -inline void set_efivarfs_path(const char *path) +void efi_init_mount(struct efi_mount *efi_mount, const char *path, + const char *guid) { - efivarfs_path = path; + assert(efi_mount); + + efi_mount->path = path; + efi_mount->guid = guid; + + pb_debug_fn("%s--%s", efi_mount->path, efi_mount->guid); } -inline const char *get_efivarfs_path(void) +bool efi_check_mount_magic(const struct efi_mount *efi_mount, bool check_magic) { + struct statfs s; + + assert(efi_mount); + + if (!efi_mount->guid) { + pb_debug_fn("guid not set\n"); + return false; + } + + if (access(efi_mount->path, R_OK | W_OK)) { + pb_debug_fn("Can't access %s\n", efi_mount->path); + return false; + } + + memset(&s, '\0', sizeof(s)); + if (statfs(efi_mount->path, &s)) { + pb_debug_fn("statfs failed: %s: (%d) %s\n", efi_mount->path, + errno, strerror(errno)); + return false; + } + + if (check_magic && s.f_type != EFIVARFS_MAGIC) { + pb_debug_fn("Bad magic = 0x%lx\n", (unsigned long)s.f_type); + return false; + } - return efivarfs_path; + return true; } -static int efi_open(const char *name, const char *guidstr, int flags, - mode_t mode, char **path) +static int efi_open(const struct efi_mount *efi_mount, const char *name, + int flags, mode_t mode, char **path) { int fd; + assert(efi_mount); + *path = NULL; - if (!get_efivarfs_path()) + if (!efi_mount->path || !efi_mount->guid) return -1; - *path = talloc_asprintf(NULL, "%s%s-%s", get_efivarfs_path(), name, guidstr); + *path = talloc_asprintf(NULL, "%s/%s-%s", efi_mount->path, name, + efi_mount->guid); if (!*path) return -1; @@ -62,8 +101,8 @@ static int efi_open(const char *name, const char *guidstr, int flags, fd = open(*path, flags, mode); if (fd < 0) { - pb_log("%s: open failed %s: %s\n", __func__, *path, - strerror(errno)); + pb_log("%s: open failed '%s': (%d) %s\n", __func__, *path, + errno, strerror(errno)); talloc_free(*path); *path = NULL; return -1; @@ -72,20 +111,22 @@ static int efi_open(const char *name, const char *guidstr, int flags, return fd; } -int efi_del_variable(const char *guidstr, const char *name) +int efi_del_variable(const struct efi_mount *efi_mount, const char *name) { int fd, flag; int rc = -1; char *path; - fd = efi_open(name, guidstr, 0, 0, &path); + assert(efi_mount); + + fd = efi_open(efi_mount, name, 0, 0, &path); if (fd < 0) return -1; rc = ioctl(fd, FS_IOC_GETFLAGS, &flag); if (rc == -1 && errno == ENOTTY) { pb_debug_fn("'%s' does not support ioctl_iflags.\n", - efivarfs_path); + efi_mount->path); goto delete; } else if (rc == -1) { pb_log_fn("FS_IOC_GETFLAGS failed: (%d) %s\n", errno, @@ -116,8 +157,8 @@ exit: return rc; } -int efi_get_variable(void *ctx, const char *guidstr, const char *name, - struct efi_data **efi_data) +int efi_get_variable(void *ctx, const struct efi_mount *efi_mount, + const char *name, struct efi_data **efi_data) { int fd; int rc = -1; @@ -127,9 +168,11 @@ int efi_get_variable(void *ctx, const char *guidstr, const char *name, ssize_t count; char *path; + assert(efi_mount); + *efi_data = NULL; - fd = efi_open(name, guidstr, 0, 0, &path); + fd = efi_open(efi_mount, name, 0, 0, &path); if (fd < 0) return -1; @@ -139,8 +182,8 @@ int efi_get_variable(void *ctx, const char *guidstr, const char *name, if (errno == EAGAIN || errno == EWOULDBLOCK) continue; - pb_log("%s: read failed %s: (%ld) %s\n", __func__, path, - count, strerror(errno)); + pb_log("%s: read failed %s: (%ld) (%d) %s\n", __func__, path, + count, errno, strerror(errno)); goto exit; } if (p >= (buf + sizeof(buf))) { @@ -169,7 +212,7 @@ exit: return rc; } -int efi_set_variable(const char *guidstr, const char *name, +int efi_set_variable(const struct efi_mount *efi_mount, const char *name, const struct efi_data *efi_data) { int rc = -1; @@ -179,9 +222,11 @@ int efi_set_variable(const char *guidstr, const char *name, size_t bufsize; char *path; - efi_del_variable(guidstr, name); + assert(efi_mount); + + efi_del_variable(efi_mount, name); - fd = efi_open(name, guidstr, O_CREAT | O_WRONLY, + fd = efi_open(efi_mount, name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &path); if (fd < 0) return -1; @@ -196,8 +241,8 @@ int efi_set_variable(const char *guidstr, const char *name, count = write(fd, buf, bufsize); if ((size_t)count != bufsize) { - pb_log("%s: write failed %s: (%ld) %s\n", __func__, name, - count, strerror(errno)); + pb_log("%s: write failed %s: (%ld) (%d) %s\n", __func__, name, + count, errno, strerror(errno)); goto exit; } rc = 0;