X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=lib%2Fefi%2Fefivar.c;h=37bb6d9468440d6d95ca56b88b87ed675b328007;hb=ef0c91e9b6c99ccbb5a3c1a88bb4d5ca85d254b4;hp=21c5d344f582b212eec8af2bcd53d93a11040b80;hpb=c3dfc9b7b91045172d460651c0309b09b0ab121a;p=petitboot diff --git a/lib/efi/efivar.c b/lib/efi/efivar.c index 21c5d34..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,36 +111,54 @@ 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) + if (rc == -1 && errno == ENOTTY) { + pb_debug_fn("'%s' does not support ioctl_iflags.\n", + efi_mount->path); + goto delete; + } else if (rc == -1) { + pb_log_fn("FS_IOC_GETFLAGS failed: (%d) %s\n", errno, + strerror(errno)); goto exit; + } flag &= ~FS_IMMUTABLE_FL; rc = ioctl(fd, FS_IOC_SETFLAGS, &flag); - if (rc == -1) + if (rc == -1) { + pb_log_fn("FS_IOC_SETFLAGS failed: (%d) %s\n", errno, + strerror(errno)); goto exit; + } +delete: close(fd); fd = 0; rc = unlink(path); + if (rc == -1) { + pb_log_fn("unlink failed: (%d) %s\n", errno, strerror(errno)); + goto exit; + } + pb_debug_fn("Deleted: '%s'\n", name); exit: talloc_free(path); close(fd); 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; @@ -111,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; @@ -123,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))) { @@ -144,6 +203,7 @@ int efi_get_variable(void *ctx, const char *guidstr, const char *name, (*efi_data)->data_size = total; (*efi_data)->data = (*efi_data)->fill; memcpy((*efi_data)->data, buf + sizeof (uint32_t), total); + pb_debug_fn("Found: '%s'='%s'\n", name, (const char *)(*efi_data)->data); rc = 0; exit: @@ -152,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; @@ -162,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; @@ -179,11 +241,12 @@ 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; + pb_debug_fn("Set: '%s'='%s'\n", name, (const char *)efi_data->data); exit: talloc_free(path);