From patchwork Wed Apr 13 12:36:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 65717 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp2479939qge; Wed, 13 Apr 2016 05:36:52 -0700 (PDT) X-Received: by 10.66.235.9 with SMTP id ui9mr12575046pac.135.1460551011975; Wed, 13 Apr 2016 05:36:51 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z75si1157593pfi.48.2016.04.13.05.36.51; Wed, 13 Apr 2016 05:36:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758330AbcDMMgu (ORCPT + 29 others); Wed, 13 Apr 2016 08:36:50 -0400 Received: from mail-lf0-f42.google.com ([209.85.215.42]:35179 "EHLO mail-lf0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751372AbcDMMgs (ORCPT ); Wed, 13 Apr 2016 08:36:48 -0400 Received: by mail-lf0-f42.google.com with SMTP id c126so67503191lfb.2 for ; Wed, 13 Apr 2016 05:36:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=/9PTe4/Hw3xfQgK+ZPgJi6qbJQCWLKL9Utl1tmdFc+Q=; b=f/v796NMkdG6B8C5LYj8x81bGH3H1cRvJKPeW1vjCv3AWNtWMC/qHZrMkp+4zBEDMv QSn8my7Cmeurl2wU5f8C3oP+udcktbK5hc1z3pzjZ4lkZn9oPLJxaZhi0Ook/0YxkgRt TH8CM3YGZLDfjocuBHkssjDEa8pF3cHshWz3A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=/9PTe4/Hw3xfQgK+ZPgJi6qbJQCWLKL9Utl1tmdFc+Q=; b=mFa4DAUfOsFQu16lThwKVEqnhBfDGiP4HOp1i/R31YD70Q/rzhA6bkI2+sQIvPDVMQ cYIiQDY+MBgIbimGs9ZTka2yxHqV5gPxnwFVE3JUyZb4lYG7vYcq+/cWNfXA01IXac6l a/nYahMvbzMoV8sLg/sXjCbasmI0WoVW+QRiNgu1PCVBjHczorzC5/65JnLQtRXdTg8q HjPDSxWZa+B6aH3mmTp63HpoUGnrBwJ2jxbP0uYud4KhNlXSWXAgdn9wZsmIlWU+jib+ FsXtnPmjoijZcv9gQYHj4udvudlze9+unuyA8Y2Bq0y/Mfh3Uh5jGDYpN0w69xlir8N8 FAdw== X-Gm-Message-State: AOPr4FWt8MzunbIiHg78Q1Av4sUrAGWhdzRFaRLELAr/c8JU4mfDGO4YVtiwINjxoclgkNC5 X-Received: by 10.112.221.129 with SMTP id qe1mr4107437lbc.118.1460551006403; Wed, 13 Apr 2016 05:36:46 -0700 (PDT) Received: from localhost.localdomain ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id j205sm6142736lfd.0.2016.04.13.05.36.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Apr 2016 05:36:44 -0700 (PDT) From: Linus Walleij To: linux-kernel@vger.kernel.org Cc: Isaac Dunham , Greg Kroah-Hartman , Jonathan Cameron , Linus Walleij Subject: [PATCH v2] mdev: create devices from /sys/dev Date: Wed, 13 Apr 2016 14:36:43 +0200 Message-Id: <1460551003-21560-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 2.4.3 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently some new devices that have a bus but no class will be missed by mdev coldplug device creation after boot. This happens because mdev recursively searches /sys/class which will by definition only find class devices. Some important devices such as iio and gpiochip does not have a class. But users will need them. This switches from using /sys/class as the place to look for devices to create to using /sys/dev where all char and block devices are listed. The subsystem lookup code that provide the G.subsystem environment variable is changed from using the directory name of the class device to instead dereference the "subsystem" symlink for the device, and look at the last element of the path of the symlink for the subsystem, which will work with class devices and bus devices alike. (The new bus-only devices only symlink to the /sys/bus/* hierarchy.) We delete the legacy kernel v2.6.2x /sys/block device path code as part of this change. It's too old to be kept alive. Tested on kernel v4.6-rc2 with a bunch of devices, including some IIO and gpiochip devices. With a print inserted before make_device() the log looks like so: Create device from "/sys/dev/char/1:1", subsystem "mem" Create device from "/sys/dev/char/1:2", subsystem "mem" Create device from "/sys/dev/char/1:3", subsystem "mem" Create device from "/sys/dev/char/1:5", subsystem "mem" (...) Create device from "/sys/dev/block/179:56", subsystem "block" Create device from "/sys/dev/block/179:64", subsystem "block" Cc: Isaac Dunham Cc: Greg Kroah-Hartman Cc: Jonathan Cameron Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Restore the subsystem environment setting behaviour by following the subsystem symlink like decribed in the commit message. This may be needed by mdev scripts. - Kill of /sys/block device scanning - Do not fall back to /sys/class device scanning, just scan /sys/dev --- util-linux/mdev.c | 61 ++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) -- 2.4.3 diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 37fa56827520..00219092fb25 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -816,6 +816,9 @@ static int FAST_FUNC fileAction(const char *fileName, { size_t len = strlen(fileName) - 4; /* can't underflow */ char *scratch = userData; + char subsys[PATH_MAX]; + char sublink[PATH_MAX]; + int res; /* len check is for paranoid reasons */ if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX) @@ -823,26 +826,24 @@ static int FAST_FUNC fileAction(const char *fileName, strcpy(scratch, fileName); scratch[len] = '\0'; - make_device(/*DEVNAME:*/ NULL, scratch, OP_add); - return TRUE; -} + /* Check the symlink for subsystem */ + strcpy(subsys, scratch); + subsys[len] = '\0'; + strncat(subsys, "/subsystem", sizeof(subsys)); + subsys[sizeof(subsys)-1] = '\0'; -/* Directory callback for /sys/ traversal */ -static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, - struct stat *statbuf UNUSED_PARAM, - void *userData UNUSED_PARAM, - int depth) -{ - /* Extract device subsystem -- the name of the directory - * under /sys/class/ */ - if (1 == depth) { + /* Reserve the last byte of the buffer for a NULL terminator */ + res = readlink(subsys, sublink, sizeof(sublink)-1); + + if (res > 0) { + sublink[res] = '\0'; free(G.subsystem); if (G.subsys_env) { bb_unsetenv_and_free(G.subsys_env); G.subsys_env = NULL; } - G.subsystem = strrchr(fileName, '/'); + G.subsystem = strrchr(sublink, '/'); if (G.subsystem) { G.subsystem = xstrdup(G.subsystem + 1); G.subsys_env = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); @@ -850,6 +851,17 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, } } + make_device(/*DEVNAME:*/ NULL, scratch, OP_add); + + return TRUE; +} + +/* Directory callback for /sys/ traversal */ +static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, + struct stat *statbuf UNUSED_PARAM, + void *userData UNUSED_PARAM, + int depth) +{ return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); } @@ -1063,25 +1075,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) putenv((char*)"ACTION=add"); - /* ACTION_FOLLOWLINKS is needed since in newer kernels - * /sys/block/loop* (for example) are symlinks to dirs, - * not real directories. - * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs, - * but we can't enforce that on users) - */ - if (access("/sys/class/block", F_OK) != 0) { - /* Scan obsolete /sys/block only if /sys/class/block - * doesn't exist. Otherwise we'll have dupes. - * Also, do not complain if it doesn't exist. - * Some people configure kernel to have no blockdevs. - */ - recursive_action("/sys/block", - ACTION_RECURSE | ACTION_FOLLOWLINKS | ACTION_QUIET, - fileAction, dirAction, temp, 0); - } - recursive_action("/sys/class", - ACTION_RECURSE | ACTION_FOLLOWLINKS, - fileAction, dirAction, temp, 0); + /* By default create all devices from /sys/dev hierarchy */ + recursive_action("/sys/dev", + ACTION_RECURSE | ACTION_FOLLOWLINKS, + fileAction, dirAction, temp, 0); } else { char *fw; char *seq;