From: Kay Sievers Date: Mon, 21 Apr 2008 16:07:05 +0000 (+0200) Subject: fstab_import: add program to IMPORT matching fstab entry X-Git-Tag: 174~1722 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=6b795c99e00c92dd29abafcc1022cace7bbcb795 fstab_import: add program to IMPORT matching fstab entry DEVPATH=/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6 SUBSYSTEM=block ... ID_FS_USAGE=filesystem ID_FS_TYPE=ext3 ID_FS_VERSION=1.0 ... FSTAB_NAME=/dev/disk/by-id/scsi-SATA_ST910021AS_3MH0Y3KF-part6 FSTAB_DIR=/home/kay/work FSTAB_TYPE=ext3 FSTAB_OPTS=defaults FSTAB_FREQ=1 FSTAB_PASSNO=1 --- diff --git a/extras/fstab_import/79-fstab_import.rules b/extras/fstab_import/79-fstab_import.rules new file mode 100644 index 000000000..ccd718c5f --- /dev/null +++ b/extras/fstab_import/79-fstab_import.rules @@ -0,0 +1,2 @@ +ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem|other", IMPORT="fstab_import --root=$root $name $links mapper/$env{DM_NAME}" + diff --git a/extras/fstab_import/Makefile b/extras/fstab_import/Makefile new file mode 100644 index 000000000..23448f321 --- /dev/null +++ b/extras/fstab_import/Makefile @@ -0,0 +1,72 @@ +# Makefile for udev extra invoked from the udev main Makefile +# +# Copyright (C) 2008 Kay Sievers +# +# Released under the GNU General Public License, version 2. +# + +PROG = fstab_import +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = + +prefix = +etcdir = ${prefix}/etc +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev +mandir = ${prefix}/usr/share/man +configdir = ${etcdir}/udev/ + +INSTALL = install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL} + +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all + +%.o: %.c $(GEN_HEADERS) + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ + +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + +# man pages +%.8: %.xml + $(E) " XMLTO " $@ + $(Q) xmlto man $? +.PRECIOUS: %.8 + +clean: + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean + +install-bin: all + $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG) + $(INSTALL_DATA) 79-fstab_import.rules $(DESTDIR)$(configdir)/rules.d/79-fstab_import.rules +.PHONY: install-bin + +uninstall-bin: + - rm $(DESTDIR)$(libudevdir)/$(PROG) + - rm $(DESTDIR)$(configdir)/rules.d/79-fstab_import.rules +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: install-man + +uninstall-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-man + +install-config: + @echo "no config file to install" +.PHONY: install-config + diff --git a/extras/fstab_import/fstab_import.c b/extras/fstab_import/fstab_import.c new file mode 100644 index 000000000..a8de067b3 --- /dev/null +++ b/extras/fstab_import/fstab_import.c @@ -0,0 +1,213 @@ +/* + * find matching entry in fstab and export it + * + * Copyright (C) 2008 Kay Sievers + * + * 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, either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev.h" + +static int debug; +static char root[PATH_SIZE] = "/dev"; +static char **devices; + +#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 (debug && udev_log < LOG_INFO) + udev_log = LOG_INFO; + } + + if (priority > udev_log) + return; + + va_start(args, format); + if (debug) { + fprintf(stderr, "[%d] ", (int) getpid()); + vfprintf(stderr, format, args); + } else + vsyslog(priority, format, args); + va_end(args); +} +#endif + +static int matches_device_list(const char *name) +{ + int i; + + for (i = 0; devices[i] != NULL; i++) { + info("compare '%s' == '%s'\n", name, devices[i]); + if (strcmp(devices[i], name) == 0) + return 1; + } + return 0; +} + +static void print_fstab_entry(struct mntent *mnt) +{ + printf("FSTAB_NAME=%s\n", mnt->mnt_fsname); + printf("FSTAB_DIR=%s\n", mnt->mnt_dir); + printf("FSTAB_TYPE=%s\n", mnt->mnt_type); + printf("FSTAB_OPTS=%s\n", mnt->mnt_opts); + printf("FSTAB_FREQ=%d\n", mnt->mnt_freq); + printf("FSTAB_PASSNO=%d\n", mnt->mnt_passno); +} + +int main(int argc, char *argv[]) +{ + static const struct option options[] = { + { "export", 0, NULL, 'x' }, + { "root", 1, NULL, 'r' }, + { "debug", 0, NULL, 'd' }, + { "help", 0, NULL, 'h' }, + {} + }; + + FILE *fp; + struct mntent *mnt; + int rc = 0; + + logging_init("fstab_id"); + + while (1) { + int option; + + option = getopt_long(argc, argv, "dr:xh", options, NULL); + if (option == -1) + break; + + switch (option) { + case 'r': + strlcpy(root, optarg, sizeof(root)); + break; + case 'd': + debug = 1; + break; + case 'h': + printf("Usage: fstab_id [OPTIONS] name [...]\n" + " --export print environment keys\n" + " --root device node root (default /dev)\n" + " --debug debug to stderr\n" + " --help print this help text\n\n"); + default: + rc = 1; + goto exit; + } + } + + devices = &argv[optind]; + if (devices[0] == NULL) { + fprintf(stderr, "error: missing device(s) to match\n"); + rc = 2; + goto exit; + } + + fp = setmntent ("/etc/fstab", "r"); + if (fp == NULL) { + fprintf(stderr, "error: opening fstab: %s\n", strerror(errno)); + rc = 2; + goto exit; + } + + while (1) { + mnt = getmntent(fp); + if (mnt == NULL) + break; + + /* skip root device */ + if (strcmp(mnt->mnt_dir, "/") == 0) + continue; + + /* match LABEL */ + if (strncmp(mnt->mnt_fsname, "LABEL=", 6) == 0) { + const char *label; + char str[256]; + + label = &mnt->mnt_fsname[6]; + if (label[0] == '"' || label[0] == '\'') { + char *pos; + + strlcpy(str, &label[1], sizeof(str)); + pos = strrchr(str, label[0]); + if (pos == NULL) + continue; + pos[0] = '\0'; + label = str; + } + if (matches_device_list(str)) { + print_fstab_entry(mnt); + break; + } + continue; + } + + /* match UUID */ + if (strncmp(mnt->mnt_fsname, "UUID=", 5) == 0) { + const char *uuid; + char str[256]; + + uuid = &mnt->mnt_fsname[5]; + if (uuid[0] == '"' || uuid[0] == '\'') { + char *pos; + + strlcpy(str, &uuid[1], sizeof(str)); + pos = strrchr(str, uuid[0]); + if (pos == NULL) + continue; + pos[0] = '\0'; + uuid = str; + } + if (matches_device_list(str)) { + print_fstab_entry(mnt); + break; + } + continue; + } + + /* only devices */ + if (strncmp(mnt->mnt_fsname, root, strlen(root)) != 0) + continue; + + if (matches_device_list(&mnt->mnt_fsname[strlen(root)+1])) { + print_fstab_entry(mnt); + break; + } + } + + endmntent(fp); + +exit: + logging_close(); + return rc; +} diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 6bf12013d..e391846de 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -11,7 +11,8 @@ EXTRAS="\ extras/floppy \ extras/firmware \ extras/collect \ - extras/rule_generator" + extras/rule_generator \ + extras/fstab_import" # with debug make clean EXTRAS="$EXTRAS" >/dev/null