2 * edd_id - naming of BIOS disk devices via EDD
4 * Copyright (C) 2005 John Hull <John_Hull@Dell.com>
5 * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation version 2 of the License.
26 #include "../../logging.h"
27 #include "../../udev_utils.h"
30 void log_message(int priority, const char *format, ...)
33 static int udev_log = -1;
38 value = getenv("UDEV_LOG");
40 udev_log = log_priority(value);
45 if (priority > udev_log)
48 va_start(args, format);
49 vsyslog(priority, format, args);
54 int main(int argc, char *argv[])
56 const char *node = NULL;
68 logging_init("edd_id");
70 for (i = 1 ; i < argc; i++) {
73 if (strcmp(arg, "--export") == 0) {
79 err("no node specified");
80 fprintf(stderr, "no node specified\n");
84 /* check for kernel support */
85 dir = opendir("/sys/firmware/edd");
87 info("no kernel EDD support");
88 fprintf(stderr, "no kernel EDD support\n");
93 disk_fd = open(node, O_RDONLY);
95 info("unable to open '%s'", node);
96 fprintf(stderr, "unable to open '%s'\n", node);
101 /* check for valid MBR signature */
102 if (lseek(disk_fd, 510, SEEK_SET) < 0) {
103 info("seek to MBR validity failed '%s'", node);
107 if (read(disk_fd, &mbr_valid, sizeof(mbr_valid)) != sizeof(mbr_valid)) {
108 info("read MBR validity failed '%s'", node);
112 if (mbr_valid != 0xAA55) {
113 fprintf(stderr, "no valid MBR signature '%s'\n", node);
114 info("no valid MBR signature '%s'", node);
119 /* read EDD signature */
120 if (lseek(disk_fd, 440, SEEK_SET) < 0) {
121 info("seek to signature failed '%s'", node);
125 if (read(disk_fd, &disk_id, sizeof(disk_id)) != sizeof(disk_id)) {
126 info("read signature failed '%s'", node);
130 /* all zero is invalid */
131 info("read id 0x%08x from '%s'", disk_id, node);
133 fprintf(stderr, "no EDD signature '%s'\n", node);
134 info("'%s' signature is zero", node);
139 /* lookup signature in sysfs to determine the name */
140 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
141 char file[PATH_SIZE];
142 char sysfs_id_buf[256];
146 if (dent->d_name[0] == '.')
149 snprintf(file, sizeof(file), "/sys/firmware/edd/%s/mbr_signature", dent->d_name);
150 file[sizeof(file)-1] = '\0';
152 sysfs_fd = open(file, O_RDONLY);
154 info("unable to open sysfs '%s'", file);
158 size = read(sysfs_fd, sysfs_id_buf, sizeof(sysfs_id_buf)-1);
161 info("read sysfs '%s' failed", file);
164 sysfs_id_buf[size] = '\0';
165 info("read '%s' from '%s'", sysfs_id_buf, file);
167 sysfs_id = strtoul(sysfs_id_buf, NULL, 16);
168 if (disk_id == sysfs_id) {
170 match = dent->d_name;
172 info("'%s' does not have a unique signature", node);
173 fprintf(stderr, "'%s' does not have a unique signature\n", node);
182 printf("ID_EDD=%s\n", match);
184 printf("%s\n", match);