OSDN Git Service

Make it so efibootmgr doesn't have to have the full OS path of loader.
authorPeter Jones <pjones@redhat.com>
Wed, 29 Apr 2015 18:55:54 +0000 (14:55 -0400)
committerPeter Jones <pjones@redhat.com>
Fri, 1 May 2015 15:05:39 +0000 (11:05 -0400)
Signed-off-by: Peter Jones <pjones@redhat.com>
src/creator.c
src/include/efivar/efiboot-creator.h
src/linux.c
src/linux.h

index 5280f94..a803be2 100644 (file)
@@ -34,6 +34,7 @@
 #include "dp.h"
 #include "linux.h"
 #include "list.h"
+#include "util.h"
 
 static int
 __attribute__((__nonnull__ (1,2,3)))
@@ -135,16 +136,13 @@ err:
 static int
 open_disk(struct disk_info *info, int flags)
 {
-       char diskname[PATH_MAX+1] = "";
-       char diskpath[PATH_MAX+1] = "";
+       char *diskpath = NULL;
        int rc;
 
-       rc = get_disk_name(info->major, info->minor, diskname, PATH_MAX);
+       rc = asprintfa(&diskpath, "/dev/%s", info->disk_name);
        if (rc < 0)
                return -1;
 
-       strcpy(diskpath, "/dev/");
-       strncat(diskpath, diskname, PATH_MAX - 5);
        return open(diskpath, flags);
 }
 
@@ -186,9 +184,16 @@ make_the_whole_path(uint8_t *buf, size_t size, int fd, struct disk_info *info,
        }
 
        if (!(options & EFIBOOT_ABBREV_FILE)) {
-               int disk_fd = open_disk(info,
-                   (options& EFIBOOT_OPTIONS_WRITE_SIGNATURE)?O_RDWR:O_RDONLY);
+               int disk_fd;
                int saved_errno;
+               int rc;
+
+               rc = set_disk_and_part_name(info);
+               if (rc < 0)
+                       goto err;
+
+               disk_fd = open_disk(info,
+                   (options& EFIBOOT_OPTIONS_WRITE_SIGNATURE)?O_RDWR:O_RDONLY);
                if (disk_fd < 0)
                        goto err;
 
@@ -218,24 +223,17 @@ err:
 }
 
 ssize_t
-__attribute__((__nonnull__ (3)))
-__attribute__((__visibility__ ("default")))
-efi_generate_file_device_path(uint8_t *buf, ssize_t size,
-                             const char const *filepath,
-                             uint32_t options, ...)
+efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
+                                      const char *devpath, int partition,
+                                      const char *relpath,
+                                      uint32_t options, va_list ap)
 {
        int rc;
        ssize_t ret = -1;
-       char *devpath = NULL;
-       char *relpath = NULL;
        struct disk_info info = { 0, };
        int fd = -1;
        int saved_errno;
 
-       rc = find_file(filepath, &devpath, &relpath);
-       if (rc < 0)
-               return -1;
-
        fd = open(devpath, O_RDONLY);
        if (fd < 0)
                goto err;
@@ -244,17 +242,21 @@ efi_generate_file_device_path(uint8_t *buf, ssize_t size,
        if (rc < 0)
                goto err;
 
+       if (partition > 0)
+               info.part = partition;
+
        if (options & EFIBOOT_ABBREV_EDD10) {
-               va_list ap;
-               va_start(ap, options);
+               va_list aq;
+               va_copy(aq, ap);
 
-               info.edd10_devicenum = va_arg(ap, uint32_t);
+               info.edd10_devicenum = va_arg(aq, uint32_t);
 
-               va_end(ap);
+               va_end(aq);
        }
 
-       ret = make_the_whole_path(buf, size, fd, &info, devpath,
-                                 relpath, options);
+       char *dp = strdupa(devpath);
+       char *rp = strdupa(relpath);
+       ret = make_the_whole_path(buf, size, fd, &info, dp, rp, options);
 err:
        saved_errno = errno;
        if (info.disk_name) {
@@ -269,6 +271,57 @@ err:
 
        if (fd >= 0)
                close(fd);
+       errno = saved_errno;
+       return ret;
+}
+
+ssize_t
+__attribute__((__nonnull__ (3, 5)))
+__attribute__((__visibility__ ("default")))
+efi_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
+                                      const char *devpath, int partition,
+                                      const char *relpath,
+                                      uint32_t options, ...)
+{
+       ssize_t ret;
+       int saved_errno;
+       va_list ap;
+
+       va_start(ap, options);
+       ret = efi_va_generate_file_device_path_from_esp(buf, size, devpath,
+                                                       partition, relpath,
+                                                       options, ap);
+       saved_errno = errno;
+       va_end(ap);
+       errno = saved_errno;
+       return ret;
+}
+
+
+ssize_t
+__attribute__((__nonnull__ (3)))
+__attribute__((__visibility__ ("default")))
+efi_generate_file_device_path(uint8_t *buf, ssize_t size,
+                             const char const *filepath,
+                             uint32_t options, ...)
+{
+       int rc;
+       ssize_t ret;
+       char *devpath = NULL;
+       char *relpath = NULL;
+       va_list ap;
+       int saved_errno;
+
+       rc = find_file(filepath, &devpath, &relpath);
+       if (rc < 0)
+               return -1;
+
+       va_start(ap, options);
+
+       ret = efi_va_generate_file_device_path_from_esp(buf, size, devpath,
+                                                      0, relpath, options, ap);
+       saved_errno = errno;
+       va_end(ap);
        if (devpath)
                free(devpath);
        if (relpath)
index e9bca3e..d6ddc7a 100644 (file)
@@ -32,6 +32,15 @@ extern ssize_t efi_generate_file_device_path(uint8_t *buf, ssize_t size,
                                             uint32_t options, ...)
        __attribute__((__nonnull__ (3)));
 
+extern ssize_t efi_generate_file_device_path_from_esp(uint8_t *buf,
+                                                     ssize_t size,
+                                                     const char *devpath,
+                                                     int partition,
+                                                     const char *relpath,
+                                                     uint32_t options, ...)
+       __attribute__((__nonnull__ (3, 5)))
+       __attribute__((__visibility__ ("default")));
+
 extern ssize_t efi_generate_network_device_path(uint8_t *buf, ssize_t size,
                                                const char const *ifname,
                                                uint32_t options)
index bd23cfb..d3f137e 100644 (file)
@@ -177,32 +177,58 @@ eb_scsi_pci(int fd, const struct disk_info *info, uint8_t *bus,
 
 int
 __attribute__((__visibility__ ("hidden")))
-get_disk_name(uint64_t major, unsigned char minor,
-             char *pathname, size_t max)
+set_disk_and_part_name(struct disk_info *info)
 {
        char *linkbuf;
        ssize_t rc;
 
        rc = sysfs_readlink(&linkbuf, "/sys/dev/block/%"PRIu64":%hhd",
-                     major, minor);
+                     info->major, info->minor);
        if (rc < 0)
                return -1;
 
-       char *dev;
-       dev = strrchr(linkbuf, '/');
-       if (!dev) {
+       char *ultimate;
+       ultimate = strrchr(linkbuf, '/');
+       if (!ultimate) {
                errno = EINVAL;
                return -1;
        }
-       *dev = '\0';
+       *ultimate = '\0';
+       ultimate++;
 
-       dev = strrchr(linkbuf, '/');
-       if (!dev) {
+       char *penultimate;
+       penultimate = strrchr(linkbuf, '/');
+       if (!penultimate) {
                errno = EINVAL;
                return -1;
        }
+       penultimate++;
+
+       if (!strcmp(penultimate, "block")) {
+               if (!info->disk_name) {
+                       info->disk_name = strdup(ultimate);
+                       if (!info->disk_name)
+                               return -1;
+               }
+               if (!info->part_name) {
+                       rc = asprintf(&info->part_name, "%s%d", info->disk_name,
+                                     info->part);
+                       if (rc < 0)
+                               return -1;
+               }
+       } else {
+               if (!info->disk_name) {
+                       info->disk_name = strdup(penultimate);
+                       if (!info->disk_name)
+                               return -1;
+               }
+               if (!info->part_name) {
+                       info->part_name = strdup(ultimate);
+                       if (!info->part_name)
+                               return -1;
+               }
+       }
 
-       strncpy(pathname, dev+1, max);
        return 0;
 }
 
@@ -339,11 +365,23 @@ sysfs_parse_sata(uint8_t *buf, ssize_t size, ssize_t *off,
         */
        char *disk_name = NULL;
        char *part_name = NULL;
-       rc = sscanf(pbuf+*poff, "block/%m[^/]/%m[^/]%n", &disk_name, &part_name,
-                   &psz);
-       if (rc != 2)
+       int psz1 = 0;
+       rc = sscanf(pbuf+*poff, "block/%m[^/]%n/%m[^/]%n", &disk_name, &psz,
+                   &part_name, &psz1);
+       if (rc == 1) {
+               rc = asprintf(&part_name, "%s%d", disk_name, info->part);
+               if (rc < 0) {
+                       free(disk_name);
+                       errno = EINVAL;
+                       return -1;
+               }
+               *poff += psz;
+       } else if (rc != 2) {
+               errno = EINVAL;
                return -1;
-       *poff += psz;
+       } else {
+               *poff += psz1;
+       }
 
        info->sata_info.scsi_bus = scsi_bus;
        info->sata_info.scsi_device = scsi_device;
index 5379290..70736f6 100644 (file)
@@ -89,8 +89,7 @@ enum _interface_type {interface_type_unknown,
                      virtblk, nvme};
 
 extern int eb_disk_info_from_fd(int fd, struct disk_info *info);
-extern int get_disk_name(uint64_t major, unsigned char minor,
-                        char *diskname, size_t max);
+extern int set_disk_and_part_name(struct disk_info *info);
 extern int make_blockdev_path(uint8_t *buf, ssize_t size, int fd,
                                struct disk_info *info);
 extern int eb_scsi_pci(int fd, const struct disk_info *info, uint8_t *bus,