From: Scott James Remnant <scott@ubuntu.com>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] The Ubuntu Collection: Winter/Spring 2006
Date: Thu, 09 Feb 2006 22:43:44 +0000 [thread overview]
Message-ID: <1139525024.17150.22.camel@localhost.localdomain> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1388 bytes --]
Further patches added to udev since the last drop to the list; note that
we've frozen at 079 for the time being as we're planning on releasing
with 2.6.15 so wanted a version "well tested" with that; as such these
patches are aimed at that, though should apply to later.
New patches:
70-ifrename-wait-on-eexist.patch
This is an improvement to the rename_net_if() function to allow
interface names to be swapped if probed at the same time. Should
the ioctl return the EEXIST error, the interface is instead renamed
to something temporary (__name) and then goes into a loop
trying to rename to the desired interface.
The theory is that another udev process will do the opposite, and
both renames will succeed.
80-extras-iftab_helper.patch
Adds an iftab_helper program that parses a tiny subset of the
ifrename-style /etc/iftab file and outputs the name the interface
should have.
As an improvement, if the kernel-assigned name would be taken by an
interface in this file and the selectors don't match, the interface
is renamed out of the kernel namespace (_name) so it doesn't clash
later.
We use the above patches for the following rule:
SUBSYSTEM=="net", ACTION=="add", \
PROGRAM="iftab_helper %k $sysfs{address}", \
NAME="$result"
Scott
--
Scott James Remnant
scott@ubuntu.com
[-- Attachment #1.2: Type: text/x-patch, Size: 1353 bytes --]
diff -ruNp udev-079~/udev_add.c udev-079/udev_add.c
--- udev-079~/udev_add.c 2005-12-22 23:51:30.000000000 +0000
+++ udev-079/udev_add.c 2006-02-09 22:25:59.498029768 +0000
@@ -32,6 +32,7 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
+#include <errno.h>
#include "libsysfs/sysfs/libsysfs.h"
#include "udev_libc_wrapper.h"
@@ -262,10 +263,30 @@ static int rename_net_if(struct udevice
strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ);
retval = ioctl(sk, SIOCSIFNAME, &ifr);
- if (retval != 0)
+ if ((retval != 0) && (errno == EEXIST)) {
+ /* Rename to something temporary then keep trying until
+ * the name we want stops being hogged. */
+ strlcpy(ifr.ifr_newname, "__", IFNAMSIZ);
+ strlcat(ifr.ifr_newname, udev->name, IFNAMSIZ);
+
+ retval = ioctl(sk, SIOCSIFNAME, &ifr);
+ if (retval != 0)
+ err("error changing net interface name: %s", strerror(errno));
+
+ strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ);
+ while ((retval = ioctl(sk, SIOCSIFNAME, &ifr)) != 0) {
+ if (errno != EEXIST) {
+ err("error changing net interface name: %s", strerror(errno));
+ break;
+ }
+
+ usleep(10000);
+ }
+ } else if (retval != 0) {
err("error changing net interface name: %s", strerror(errno));
- close(sk);
+ }
+ close(sk);
return retval;
}
[-- Attachment #1.3: Type: text/x-patch, Size: 11108 bytes --]
diff -ruNp udev-079~/extras/iftab/Makefile udev-079/extras/iftab/Makefile
--- udev-079~/extras/iftab/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ udev-079/extras/iftab/Makefile 2006-02-09 21:41:12.115562240 +0000
@@ -0,0 +1,68 @@
+# Copyright © 2006 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+# Released under the GNU General Public License, version 2.
+
+PROG = iftab_helper
+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 = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+all: $(PROG) $(MAN_PAGES)
+.PHONY: all
+.DEFAULT: all
+
+%.o: %.c $(GEN_HEADERS)
+ $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+$(PROG): %: $(HEADERS) %.o $(OBJS)
+ $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+ifneq ($(strip $(STRIPCMD)),)
+ $(QUIET) $(STRIPCMD) $@
+endif
+
+# man pages
+%.8: %.xml
+ xmlto man $?
+.PRECIOUS: %.8
+
+clean:
+ rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
+.PHONY: clean
+
+install-bin: all
+ $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: install-bin
+
+uninstall-bin:
+ - rm $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: uninstall-bin
+
+install-man:
+ $(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
+ $(INSTALL_DATA) -D iftab.5 $(DESTDIR)$(mandir)/man5/iftab.5
+.PHONY: uninstall-man
+
+uninstall-man:
+ -rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
+ -rm -f $(DESTDIR)$(mandir)/man5/iftab.5
+.PHONY: uninstall-man
+
+install-config:
+ @echo "no config file to install"
+.PHONY: install-config
diff -ruNp udev-079~/extras/iftab/iftab.5 udev-079/extras/iftab/iftab.5
--- udev-079~/extras/iftab/iftab.5 1970-01-01 01:00:00.000000000 +0100
+++ udev-079/extras/iftab/iftab.5 2006-02-09 21:41:43.575779560 +0000
@@ -0,0 +1,74 @@
+.TH IFTAB 5 "February 2006" "" "Linux Administrator's Manual"
+.SH NAME
+iftab \- assign consistent names to network interfaces
+.SH DESCRIPTION
+The file
+.B /etc/iftab
+contains descriptive information about the various network interfaces and
+is used by
+.BR udev (8)
+and its
+.BR iftab_helper (8)
+to assign consistent names to network interfaces.
+
+.B /etc/iftab
+defines a set of \fImappings\fR. Each mapping contains an interface name
+and a set of selectors which identify the physical network device that
+should be assigned that name.
+
+If a network device matches all selectors of a mapping, \fBudev\fR will
+rename the interface to the name given by the mapping.
+
+If a network device \fIdoes not\fR match all of the selectors,
+but has the same name as the mapping, \fBudev\fR instead will rename the
+interface so that it does not have the name given by the kernel.
+.\"
+.SH COMPATIBILITY
+Please note that this file format is a subset of that supported by the
+.BR ifrename (8)
+tool you may find in other distributions, and does not (yet) support the
+full range of selectors and features.
+.\"
+.SH MAPPINGS
+Each mapping is described on a separate line, which may be broken across
+multiple lines by terminating the first line with a backslash. A mapping
+starts with an \fIinterface name\fR and contains a set of \fIselector\fR
+name and value pairs; all separated by space or tabs.
+
+The relationship between selectors of a mapping is a \fIlogical and\fR.
+A mapping only matches a network deivce if all of the selectors for it
+match.
+
+When multiple matching selectors are present, the last in the file is used.
+.\"
+.SH SELECTORS
+Each selector is composed of a selector name and selector value
+separated by spaces or tabs. Selectors specify a static attribute of a
+network device, the goal being to uniquely identify each piece of hardware.
+
+Currently only the \fBmac\fR selector is supported, other selectors supported
+by the
+.BR ifrename (8)
+tool will be supported as and when required.
+
+.TP
+.BI mac mac-address
+Matches the MAC address of the device which can be obtained by using
+.BR ifconfig (8)
+or
+.BR ip (8).
+.\"
+.SH EXAMPLE
+# This is a comment
+.br
+eth0 mac 00:12:79:59:8D:38
+.br
+eth1 mac 00:0B:CD:5C:9E:2A
+.SH SEE ALSO
+.BR udev (8)
+.BR iftab_helper (8)
+.BR ifconfig (8)
+.BR ip (8)
+.BR ifrename (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-079~/extras/iftab/iftab_helper.8 udev-079/extras/iftab/iftab_helper.8
--- udev-079~/extras/iftab/iftab_helper.8 1970-01-01 01:00:00.000000000 +0100
+++ udev-079/extras/iftab/iftab_helper.8 2006-02-09 21:49:48.502059560 +0000
@@ -0,0 +1,33 @@
+.TH IFTAB_HELPER 8 "February 2006" "" "Linux Administrator's Manual"
+.SH NAME
+iftab_helper \- udev callout to parse /etc/iftab and name network devices
+.SH SYNOPSIS
+.BI iftab_helper
+\fIdevicename\fP \fIaddress\fP
+.SH DESCRIPTION
+.B iftab_helper
+is normally called from a udev rule to provide the name for a detected
+network device. Udev can use this information to rename devices and thus
+provide consistent names for network devices.
+.SH USAGE
+.B iftab_helper
+looks up the address specified on the command-line in the \fI/etc/iftab\fR
+file and returns the name assigned to it in that file. If it is not present
+it checks whether the kernel-assigned name is assigned to a different device
+in that file and if so returns a new name for the device.
+
+.B iftab_helper
+is not responsible for performing the actual renaming, that is instead
+eperformed by udev using a NAME rule. This replaces the functionality
+previously offered by
+.BR ifrename (8)
+though note that
+.B iftab_helper
+does not support as wide a range of selectors for devices and files may
+need to be simplified.
+.SH SEE ALSO
+.BR iftab (5)
+.BR ifrename (8)
+.BR udev (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-079~/extras/iftab/iftab_helper.c udev-079/extras/iftab/iftab_helper.c
--- udev-079~/extras/iftab/iftab_helper.c 1970-01-01 01:00:00.000000000 +0100
+++ udev-079/extras/iftab/iftab_helper.c 2006-02-09 21:49:09.995913384 +0000
@@ -0,0 +1,205 @@
+/*
+ * iftab_helper - parses /etc/iftab and outputs network device name
+ *
+ * Copyright © 2006 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "../../logging.h"
+#include "../../udev_utils.h"
+
+#define IFTAB "/etc/iftab"
+
+#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);
+ vprintf(format, args);
+ if (format[strlen(format)-1] != '\n')
+ printf("\n");
+ vsyslog(priority, format, args);
+ va_end(args);
+}
+#endif
+
+char *next_token(char **linepos)
+{
+ char *token = *linepos;
+
+ /* read up to whitespace */
+ while (**linepos && !isspace(**linepos))
+ (*linepos)++;
+
+ /* split the string and skip over whitespace */
+ if (**linepos) {
+ *((*linepos)++) = '\0';
+ while (isspace(**linepos))
+ (*linepos)++;
+ }
+
+ return token;
+}
+
+const char *whats_my_name(const char *name, const char *address)
+{
+ static char iftab_name[NAME_SIZE] = "";
+ char *buf;
+ size_t bufsize, cur, lineno;
+
+ if (file_map(IFTAB, &buf, &bufsize)) {
+ if (errno != ENOENT)
+ err("%s: unable to open: %s", IFTAB, strerror(errno));
+ return NULL;
+ }
+
+ cur = 0;
+ lineno = 0;
+ while (cur < bufsize) {
+ char line[LINE_SIZE], *bufline, *linepos;
+ char *ifname;
+ size_t count;
+ int match = 1;
+
+ count = buf_get_line(buf, bufsize, cur);
+ bufline = &buf[cur];
+ cur += count+1;
+ lineno++;
+
+ if (count >= sizeof(line)) {
+ err("%s:%d: line too long", IFTAB, lineno);
+ continue;
+ }
+
+ /* eat initial whitespace */
+ while ((count > 0) && isspace(bufline[0])) {
+ bufline++;
+ count--;
+ }
+ if (!count)
+ continue;
+
+ /* comment? */
+ if (bufline[0] == '#')
+ continue;
+
+ /* copy into buffer */
+ memcpy(line, bufline, count);
+ line[count] = '\0';
+ linepos = line;
+
+ /* up to the first whitespace is the interface name */
+ ifname = next_token(&linepos);
+ if (!*linepos) {
+ err("%s:%d: no selectors for %s", IFTAB, lineno, ifname);
+ continue;
+ }
+
+ while (*linepos) {
+ char *selector, *value;
+
+ /* read selector name and value */
+ selector = next_token(&linepos);
+ if (!*linepos) {
+ err("%s:%d: no value after %s selector for %s", IFTAB, lineno, selector, ifname);
+ break;
+ }
+ value = next_token(&linepos);
+
+ if (!strcasecmp(selector, "mac")) {
+ if (strcasecmp(value, address))
+ match = 0;
+
+ } else {
+ err("%s:%d: unknown or unsupported %s selector for %s", IFTAB, lineno, selector, ifname);
+ }
+ }
+
+ if (match) {
+ /* Matched details: use assigned name */
+ strncpy(iftab_name, ifname, sizeof(iftab_name));
+ iftab_name[sizeof(iftab_name)-1] = '\0';
+ } else if (!strcasecmp(ifname, name)) {
+ /* Name already used: invent new name */
+ snprintf(iftab_name, sizeof(iftab_name), "_%s", name);
+ }
+ }
+
+ file_unmap(buf, bufsize);
+ return iftab_name;
+}
+
+
+int main(int argc, char *argv[])
+{
+ const char *name = NULL, *address = NULL, *iftab_name;
+ int ret = 0;
+ int i;
+
+ logging_init("iftab_helper");
+
+ for (i = 1; i < argc; i++) {
+ if (!name) {
+ name = argv[i];
+ } else if (!address) {
+ address = argv[i];
+ }
+ }
+
+ if (!name) {
+ err("no device name specified");
+ ret = 1;
+ goto exit;
+ }
+
+ if (!address) {
+ err("no mac address specified");
+ ret = 1;
+ goto exit;
+ }
+
+ iftab_name = whats_my_name(name, address);
+ if (!*iftab_name)
+ iftab_name = name;
+
+ printf("%s\n", iftab_name);
+
+exit:
+ logging_close();
+ return ret;
+}
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2006-02-09 22:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-09 22:43 Scott James Remnant [this message]
2006-02-09 22:52 ` [PATCH] The Ubuntu Collection: Winter/Spring 2006 Marco d'Itri
2006-02-10 1:30 ` Scott James Remnant
2006-02-10 1:35 ` Scott James Remnant
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1139525024.17150.22.camel@localhost.localdomain \
--to=scott@ubuntu.com \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).