mirror of
https://github.com/systemd/systemd.git
synced 2025-08-29 01:49:55 +03:00
add edd_id tool to match BIOS EDD disk information
Thanks to: John Hull <John_Hull@Dell.com> Matt Domsch <Matt_Domsch@Dell.com> Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
50
extras/edd_id/Makefile
Normal file
50
extras/edd_id/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
# Makefile for edd_id
|
||||
#
|
||||
# Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
|
||||
PROG = edd_id
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
prefix =
|
||||
exec_prefix = ${prefix}
|
||||
etcdir = ${prefix}/etc
|
||||
sbindir = ${exec_prefix}/sbin
|
||||
usrbindir = ${exec_prefix}/usr/bin
|
||||
usrsbindir = ${exec_prefix}/usr/sbin
|
||||
mandir = ${prefix}/usr/share/man
|
||||
devddir = ${etcdir}/dev.d/default
|
||||
configdir = ${etcdir}/udev/
|
||||
initdir = ${etcdir}/init.d/
|
||||
srcdir = .
|
||||
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
|
||||
|
||||
OBJS = $(PROG).o $(LIBUDEV)
|
||||
|
||||
$(OBJS): $(HEADERS)
|
||||
|
||||
.c.o:
|
||||
$(QUIET) $(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(PROG): $(OBJS) $(HEADERS)
|
||||
$(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
spotless: clean
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
|
||||
|
||||
uninstall:
|
||||
- rm $(DESTDIR)$(sbindir)/$(PROG)
|
184
extras/edd_id/edd_id.c
Normal file
184
extras/edd_id/edd_id.c
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* edd_id - naming of BIOS disk devices via EDD
|
||||
*
|
||||
* Copyright (C) 2005 John Hull <John_Hull@Dell.com>
|
||||
* Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation version 2 of the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../../logging.h"
|
||||
#include "../../udev_utils.h"
|
||||
|
||||
#ifdef USE_LOG
|
||||
void log_message(int priority, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
static int udev_log = -1;
|
||||
|
||||
if (udev_log == -1) {
|
||||
const char *value;
|
||||
|
||||
value = getenv("UDEV_LOG");
|
||||
if (value)
|
||||
udev_log = log_priority(value);
|
||||
else
|
||||
udev_log = LOG_ERR;
|
||||
}
|
||||
|
||||
if (priority > udev_log)
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
vsyslog(priority, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *node = NULL;
|
||||
int i;
|
||||
int export = 0;
|
||||
uint32_t disk_id;
|
||||
uint16_t mbr_valid;
|
||||
struct dirent *dent;
|
||||
int disk_fd;
|
||||
int sysfs_fd;
|
||||
DIR *dir = NULL;
|
||||
int rc = 1;
|
||||
|
||||
logging_init("edd_id");
|
||||
|
||||
for (i = 1 ; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
|
||||
if (strcmp(arg, "--export") == 0) {
|
||||
export = 1;
|
||||
} else
|
||||
node = arg;
|
||||
}
|
||||
if (!node) {
|
||||
err("no node specified");
|
||||
fprintf(stderr, "no node specified\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* check for kernel support */
|
||||
dir = opendir("/sys/firmware/edd");
|
||||
if (!dir) {
|
||||
info("no kernel EDD support");
|
||||
fprintf(stderr, "no kernel EDD support\n");
|
||||
rc = 2;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
disk_fd = open(node, O_RDONLY);
|
||||
if (disk_fd < 0) {
|
||||
info("unable to open '%s'", node);
|
||||
fprintf(stderr, "unable to open '%s'\n", node);
|
||||
rc = 3;
|
||||
goto closedir;
|
||||
}
|
||||
|
||||
/* check for valid MBR signature */
|
||||
if (lseek(disk_fd, 510, SEEK_SET) < 0) {
|
||||
info("seek to MBR validity failed '%s'", node);
|
||||
rc = 4;
|
||||
goto close;
|
||||
}
|
||||
if (read(disk_fd, &mbr_valid, sizeof(mbr_valid)) != sizeof(mbr_valid)) {
|
||||
info("read MBR validity failed '%s'", node);
|
||||
rc = 5;
|
||||
goto close;
|
||||
}
|
||||
if (mbr_valid != 0xAA55) {
|
||||
fprintf(stderr, "no valid MBR signature '%s'\n", node);
|
||||
info("no valid MBR signature '%s'", node);
|
||||
rc=6;
|
||||
goto close;
|
||||
}
|
||||
|
||||
/* read EDD signature */
|
||||
if (lseek(disk_fd, 440, SEEK_SET) < 0) {
|
||||
info("seek to signature failed '%s'", node);
|
||||
rc = 7;
|
||||
goto close;
|
||||
}
|
||||
if (read(disk_fd, &disk_id, sizeof(disk_id)) != sizeof(disk_id)) {
|
||||
info("read signature failed '%s'", node);
|
||||
rc = 8;
|
||||
goto close;
|
||||
}
|
||||
/* all zero is invalid */
|
||||
info("read id 0x%08x from '%s'", disk_id, node);
|
||||
if (disk_id == 0) {
|
||||
fprintf(stderr, "no EDD signature '%s'\n", node);
|
||||
info("'%s' signature is zero", node);
|
||||
rc = 9;
|
||||
goto close;
|
||||
}
|
||||
|
||||
/* lookup signature in sysfs to determine the name */
|
||||
for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
|
||||
char file[PATH_SIZE];
|
||||
char sysfs_id_buf[256];
|
||||
uint32_t sysfs_id;
|
||||
ssize_t size;
|
||||
|
||||
if (dent->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
snprintf(file, sizeof(file), "/sys/firmware/edd/%s/mbr_signature", dent->d_name);
|
||||
file[sizeof(file)-1] = '\0';
|
||||
|
||||
sysfs_fd = open(file, O_RDONLY);
|
||||
if (sysfs_fd < 0) {
|
||||
info("unable to open sysfs '%s'", file);
|
||||
continue;
|
||||
}
|
||||
|
||||
size = read(sysfs_fd, sysfs_id_buf, sizeof(sysfs_id_buf)-1);
|
||||
close(sysfs_fd);
|
||||
if (size < 0) {
|
||||
info("read sysfs '%s' failed", file);
|
||||
continue;
|
||||
}
|
||||
sysfs_id_buf[size] = '\0';
|
||||
info("read '%s' from '%s'", sysfs_id_buf, file);
|
||||
|
||||
sysfs_id = strtoul(sysfs_id_buf, NULL, 16);
|
||||
if (disk_id == sysfs_id) {
|
||||
if (export)
|
||||
printf("ID_EDD=%s\n", dent->d_name);
|
||||
else
|
||||
printf("%s\n", dent->d_name);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close:
|
||||
close(disk_fd);
|
||||
closedir:
|
||||
closedir(dir);
|
||||
exit:
|
||||
logging_close();
|
||||
return rc;
|
||||
}
|
@ -8,6 +8,7 @@ EXTRAS="\
|
||||
extras/usb_id \
|
||||
extras/dasd_id \
|
||||
extras/cdrom_id \
|
||||
extras/edd_id \
|
||||
extras/floppy \
|
||||
extras/run_directory \
|
||||
extras/firmware"
|
||||
|
Reference in New Issue
Block a user