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 "../../udev.h"
29 void log_message(int priority, const char *format, ...)
32 static int udev_log = -1;
37 value = getenv("UDEV_LOG");
39 udev_log = log_priority(value);
44 if (priority > udev_log)
47 va_start(args, format);
48 vsyslog(priority, format, args);
53 int main(int argc, char *argv[])
55 const char *node = NULL;
65 char match[NAME_MAX] = "";
67 logging_init("edd_id");
69 for (i = 1 ; i < argc; i++) {
72 if (strcmp(arg, "--export") == 0) {
78 err("no node specified");
79 fprintf(stderr, "no node specified\n");
83 /* check for kernel support */
84 dir = opendir("/sys/firmware/edd");
86 info("no kernel EDD support");
87 fprintf(stderr, "no kernel EDD support\n");
92 disk_fd = open(node, O_RDONLY);
94 info("unable to open '%s'", node);
95 fprintf(stderr, "unable to open '%s'\n", node);
100 /* check for valid MBR signature */
101 if (lseek(disk_fd, 510, SEEK_SET) < 0) {
102 info("seek to MBR validity failed '%s'", node);
106 if (read(disk_fd, &mbr_valid, sizeof(mbr_valid)) != sizeof(mbr_valid)) {
107 info("read MBR validity failed '%s'", node);
111 if (mbr_valid != 0xAA55) {
112 fprintf(stderr, "no valid MBR signature '%s'\n", node);
113 info("no valid MBR signature '%s'", node);
118 /* read EDD signature */
119 if (lseek(disk_fd, 440, SEEK_SET) < 0) {
120 info("seek to signature failed '%s'", node);
124 if (read(disk_fd, &disk_id, sizeof(disk_id)) != sizeof(disk_id)) {
125 info("read signature failed '%s'", node);
129 /* all zero is invalid */
130 info("read id 0x%08x from '%s'", disk_id, node);
132 fprintf(stderr, "no EDD signature '%s'\n", node);
133 info("'%s' signature is zero", node);
138 /* lookup signature in sysfs to determine the name */
139 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
140 char file[PATH_SIZE];
141 char sysfs_id_buf[256];
145 if (dent->d_name[0] == '.')
148 snprintf(file, sizeof(file), "/sys/firmware/edd/%s/mbr_signature", dent->d_name);
149 file[sizeof(file)-1] = '\0';
151 sysfs_fd = open(file, O_RDONLY);
153 info("unable to open sysfs '%s'", file);
157 size = read(sysfs_fd, sysfs_id_buf, sizeof(sysfs_id_buf)-1);
160 info("read sysfs '%s' failed", file);
163 sysfs_id_buf[size] = '\0';
164 info("read '%s' from '%s'", sysfs_id_buf, file);
165 sysfs_id = strtoul(sysfs_id_buf, NULL, 16);
167 /* look for matching value, that appears only once */
168 if (disk_id == sysfs_id) {
169 if (match[0] == '\0') {
171 strlcpy(match, dent->d_name, sizeof(match));
173 /* error, same signature for another device */
174 info("'%s' does not have a unique signature", node);
175 fprintf(stderr, "'%s' does not have a unique signature\n", node);
182 if (match[0] != '\0') {
184 printf("ID_EDD=%s\n", match);
186 printf("%s\n", match);