Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:GA
efivar
efivar-nvme-no-kernel-header.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File efivar-nvme-no-kernel-header.patch of Package efivar
From 8910f45c27fadba0904f707e7c40ad80bf828f7e Mon Sep 17 00:00:00 2001 From: Peter Jones <pjones@redhat.com> Date: Fri, 19 Feb 2016 18:53:00 -0500 Subject: [PATCH] libefiboot: rework NVME so we get EUI right and don't need kernel headers The headers are broken enough on various distros that it's better to avoid them entirely. Signed-off-by: Peter Jones <pjones@redhat.com> --- src/linux.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++-------------- src/linux.h | 8 ++++ 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/src/linux.c b/src/linux.c index 0063476..084e9c2 100644 --- a/src/linux.c +++ b/src/linux.c @@ -23,11 +23,6 @@ #include <limits.h> #include <linux/ethtool.h> #include <linux/version.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) -#include <linux/nvme_ioctl.h> -#else -#include <linux/nvme.h> -#endif #include <linux/sockios.h> #include <net/if.h> #include <scsi/scsi.h> @@ -48,17 +43,6 @@ int __attribute__((__visibility__ ("hidden"))) -eb_nvme_ns_id(int fd, uint32_t *ns_id) -{ - uint64_t ret = ioctl(fd, NVME_IOCTL_ID, NULL); - if ((int)ret < 0) - return ret; - *ns_id = (uint32_t)ret; - return 0; -} - -int -__attribute__((__visibility__ ("hidden"))) set_disk_and_part_name(struct disk_info *info) { char *linkbuf; @@ -168,6 +152,23 @@ get_partition_number(const char *devpath) } static int +sysfs_test_nvme(const char *buf, ssize_t size) +{ + int rc; + + int32_t tosser0; + int32_t ctrl_id; + int32_t ns_id; + + errno = 0; + rc = sscanf(buf, "nvme/nvme%d/nvme%dn%d", &tosser0, &ctrl_id, &ns_id); + if (rc < 1) + return (errno == 0) ? 0 : -1; + + return 1; +} + +static int sysfs_test_sata(const char *buf, ssize_t size) { if (!strncmp(buf, "ata", MIN(size,3))) @@ -259,6 +260,69 @@ sysfs_sata_get_port_info(uint32_t print_id, struct disk_info *info) } static ssize_t +sysfs_parse_nvme(uint8_t *buf, ssize_t size, ssize_t *off, + const char *pbuf, ssize_t psize, ssize_t *poff, + struct disk_info *info) +{ + int rc; + int psz = 0; + char *filebuf = NULL; + + *poff = 0; + *off = 0; + + int32_t tosser0; + int32_t ctrl_id; + int32_t ns_id; + + /* buf is: + * nvme/nvme0/nvme0n1 + */ + rc = sscanf(pbuf+*poff, "nvme/nvme%d/nvme%dn%d%n", &tosser0, + &ctrl_id, &ns_id, &psz); + if (rc != 3) + return -1; + *poff += psz; + + info->nvme_info.ctrl_id = ctrl_id; + info->nvme_info.ns_id = ns_id; + info->nvme_info.has_eui = 0; + info->interface_type = nvme; + + /* + * now fish the eui out of sysfs is there is one... + */ + rc = read_sysfs_file(&filebuf, + "/sys/class/block/nvme%dn%d/device/eui", + ctrl_id, ns_id); + if (rc >= 0) { + uint8_t eui[8]; + if (rc < 23) { + errno = EINVAL; + return -1; + } + rc = sscanf(filebuf, + "%02hhx-%02hhx-%02hhx-%02hhx-" + "%02hhx-%02hhx-%02hhx-%02hhx", + &eui[0], &eui[1], &eui[2], &eui[3], + &eui[4], &eui[5], &eui[6], &eui[7]); + if (rc < 8) { + errno = EINVAL; + return -1; + } + info->nvme_info.has_eui = 1; + memcpy(info->nvme_info.eui, eui, sizeof(eui)); + } + + *off = efidp_make_nvme(buf, size, + info->nvme_info.ns_id, + info->nvme_info.has_eui ? info->nvme_info.eui + : NULL); + return *off; +} + + +static ssize_t sysfs_parse_sata(uint8_t *buf, ssize_t size, ssize_t *off, const char *pbuf, ssize_t psize, ssize_t *poff, struct disk_info *info) @@ -665,20 +729,25 @@ make_blockdev_path(uint8_t *buf, ssize_t size, int fd, struct disk_info *info) loff += tmpoff; found = 1; } + } - if (!found) { - uint32_t ns_id=0; - int rc = eb_nvme_ns_id(fd, &ns_id); - if (rc >= 0) { - sz = efidp_make_nvme(buf+off, size?size-off:0, - ns_id, NULL); - if (sz < 0) - return -1; - - info->interface_type = nvme; - off += sz; - found = 1; - } + /* /dev/nvme0n1 looks like: + * /sys/dev/block/259:0 -> ../../devices/pci0000:00/0000:00:1d.0/0000:05:00.0/nvme/nvme0/nvme0n1 + */ + if (!found) { + rc = sysfs_test_nvme(linkbuf+loff, PATH_MAX-off); + if (rc < 0) + return -1; + else if (rc > 0) { + ssize_t linksz; + rc = sysfs_parse_nvme(buf+off, size?size-off:0, &sz, + linkbuf+loff, PATH_MAX-off, + &linksz, info); + if (rc < 0) + return -1; + loff += linksz; + off += sz; + found = 1; } } diff --git a/src/linux.h b/src/linux.h index 5e8d003..539fb23 100644 --- a/src/linux.h +++ b/src/linux.h @@ -60,6 +60,13 @@ struct sata_info { uint32_t ata_pmp; }; +struct nvme_info { + int32_t ctrl_id; + int32_t ns_id; + int has_eui; + uint8_t eui[8]; +}; + struct disk_info { int interface_type; unsigned int controllernum; @@ -76,6 +83,7 @@ struct disk_info { struct scsi_info scsi_info; struct sas_info sas_info; struct sata_info sata_info; + struct nvme_info nvme_info; }; char *disk_name; -- 2.7.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor