From patchwork Fri Nov 8 17:25:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Gladkov X-Patchwork-Id: 11235307 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 48DD91864 for ; Fri, 8 Nov 2019 17:25:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 287EA207FA for ; Fri, 8 Nov 2019 17:25:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728742AbfKHRZn convert rfc822-to-8bit (ORCPT ); Fri, 8 Nov 2019 12:25:43 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:52243 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727168AbfKHRZn (ORCPT ); Fri, 8 Nov 2019 12:25:43 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-388-XRXUA6GzO9CljTly2oy7XA-1; Fri, 08 Nov 2019 12:25:38 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 62BF98017DD; Fri, 8 Nov 2019 17:25:37 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id B0DC01001DC2; Fri, 8 Nov 2019 17:25:36 +0000 (UTC) From: Alexey Gladkov To: linux-modules@vger.kernel.org Cc: Lucas De Marchi Subject: [PATCH v2 1/4] libkmod: Add parser for modules.builtin.modinfo Date: Fri, 8 Nov 2019 18:25:20 +0100 Message-Id: <20191108172524.468494-2-gladkov.alexey@gmail.com> In-Reply-To: <20191108172524.468494-1-gladkov.alexey@gmail.com> References: <20191108172524.468494-1-gladkov.alexey@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-MC-Unique: XRXUA6GzO9CljTly2oy7XA-1 X-Mimecast-Spam-Score: 0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: The kernel since version v5.2-rc1 exports information about built-in modules in the modules.builtin.modinfo. Information is stored in the same format as in the separate modules (null-terminated string array). The module name is a prefix for each line. $ tr '\0' '\n' < modules.builtin.modinfo ext4.softdep=pre: crc32c ext4.license=GPL ext4.description=Fourth Extended Filesystem ext4.author=Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others ext4.alias=fs-ext4 ext4.alias=ext3 ext4.alias=fs-ext3 ext4.alias=ext2 ext4.alias=fs-ext2 md_mod.alias=block-major-9-* md_mod.alias=md md_mod.description=MD RAID framework md_mod.license=GPL md_mod.parmtype=create_on_open:bool md_mod.parmtype=start_dirty_degraded:int ... Signed-off-by: Alexey Gladkov --- Makefile.am | 1 + libkmod/libkmod-builtin.c | 329 +++++++++++++++++++++++++++++++++++++ libkmod/libkmod-internal.h | 8 + 3 files changed, 338 insertions(+) create mode 100644 libkmod/libkmod-builtin.c diff --git a/Makefile.am b/Makefile.am index c5c2f06..176dcfc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,7 @@ libkmod_libkmod_la_SOURCES = \ libkmod/libkmod.h \ libkmod/libkmod-internal.h \ libkmod/libkmod.c \ + libkmod/libkmod-builtin.c \ libkmod/libkmod-list.c \ libkmod/libkmod-config.c \ libkmod/libkmod-index.c \ diff --git a/libkmod/libkmod-builtin.c b/libkmod/libkmod-builtin.c new file mode 100644 index 0000000..c7b888a --- /dev/null +++ b/libkmod/libkmod-builtin.c @@ -0,0 +1,329 @@ +/* + * libkmod - interface to kernel built-in modules + * + * Copyright (C) 2019 Alexey Gladkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "libkmod.h" +#include "libkmod-internal.h" + +#define MODULES_BUILTIN_MODINFO "modules.builtin.modinfo" + +struct kmod_builtin_iter { + struct kmod_ctx *ctx; + + // The file descriptor. + int file; + + // The total size in bytes. + ssize_t size; + + // The offset of current module. + off_t pos; + + // The offset at which the next module is located. + off_t next; + + // Number of strings in the current block. + ssize_t nstrings; + + // Internal buffer and its size. + size_t bufsz; + char *buf; +}; + +struct kmod_builtin_iter *kmod_builtin_iter_new(struct kmod_ctx *ctx) +{ + char path[PATH_MAX]; + int file, sv_errno; + struct stat sb; + struct kmod_builtin_iter *iter = NULL; + const char *dirname = kmod_get_dirname(ctx); + size_t len = strlen(dirname); + + file = -1; + + if ((len + 1 + strlen(MODULES_BUILTIN_MODINFO) + 1) >= PATH_MAX) { + sv_errno = ENAMETOOLONG; + goto fail; + } + + snprintf(path, PATH_MAX, "%s/%s", dirname, MODULES_BUILTIN_MODINFO); + + file = open(path, O_RDONLY|O_CLOEXEC); + if (file < 0) { + sv_errno = errno; + goto fail; + } + + if (fstat(file, &sb) < 0) { + sv_errno = errno; + goto fail; + } + + iter = malloc(sizeof(*iter)); + if (!iter) { + sv_errno = ENOMEM; + goto fail; + } + + iter->ctx = ctx; + iter->file = file; + iter->size = sb.st_size; + iter->nstrings = 0; + iter->pos = 0; + iter->next = 0; + iter->bufsz = 0; + iter->buf = NULL; + + return iter; +fail: + if (file >= 0) + close(file); + + errno = sv_errno; + + return iter; +} + +void kmod_builtin_iter_free(struct kmod_builtin_iter *iter) +{ + close(iter->file); + free(iter->buf); + free(iter); +} + +static off_t get_string(struct kmod_builtin_iter *iter, off_t offset, + char **line, size_t *size) +{ + int sv_errno; + char *nullp = NULL; + size_t linesz = 0; + + while (!nullp) { + char buf[BUFSIZ]; + ssize_t sz; + size_t partsz; + + sz = pread(iter->file, buf, BUFSIZ, offset); + if (sz < 0) { + sv_errno = errno; + goto fail; + } else if (sz == 0) { + offset = 0; + break; + } + + nullp = memchr(buf, '\0', (size_t) sz); + partsz = (size_t)((nullp) ? (nullp - buf) + 1 : sz); + offset += (off_t) partsz; + + if (iter->bufsz < linesz + partsz) { + iter->bufsz = linesz + partsz; + iter->buf = realloc(iter->buf, iter->bufsz); + + if (!iter->buf) { + sv_errno = errno; + goto fail; + } + } + + strncpy(iter->buf + linesz, buf, partsz); + linesz += partsz; + } + + if (linesz) { + *line = iter->buf; + *size = linesz; + } + + return offset; +fail: + errno = sv_errno; + return -1; +} + +bool kmod_builtin_iter_next(struct kmod_builtin_iter *iter) +{ + char *line, *modname; + size_t linesz; + off_t pos, offset, modlen; + + modname = NULL; + + iter->nstrings = 0; + offset = pos = iter->next; + + while (offset < iter->size) { + char *dot; + off_t len; + + offset = get_string(iter, pos, &line, &linesz); + if (offset <= 0) { + if (offset) + ERR(iter->ctx, "get_string: %s\n", strerror(errno)); + pos = iter->size; + break; + } + + dot = strchr(line, '.'); + if (!dot) { + ERR(iter->ctx, "kmod_builtin_iter_next: unexpected string without modname prefix\n"); + pos = iter->size; + break; + } + + len = dot - line; + + if (!modname) { + modname = strdup(line); + modlen = len; + } else if (modlen != len || strncmp(modname, line, len)) { + break; + } + + iter->nstrings++; + pos = offset; + } + + iter->pos = iter->next; + iter->next = pos; + + free(modname); + + return (iter->pos < iter->size); +} + +bool kmod_builtin_iter_get_modname(struct kmod_builtin_iter *iter, + char modname[static PATH_MAX]) +{ + int sv_errno; + char *line, *dot; + size_t linesz, len; + off_t offset; + + if (iter->pos == iter->size) + return false; + + line = NULL; + + offset = get_string(iter, iter->pos, &line, &linesz); + if (offset <= 0) { + sv_errno = errno; + if (offset) + ERR(iter->ctx, "get_string: %s\n", strerror(errno)); + goto fail; + } + + dot = strchr(line, '.'); + if (!dot) { + sv_errno = errno; + ERR(iter->ctx, "kmod_builtin_iter_get_modname: unexpected string without modname prefix\n"); + goto fail; + } + + len = dot - line; + + if (len > PATH_MAX) { + sv_errno = ENAMETOOLONG; + goto fail; + } + + strncpy(modname, line, len); + modname[len] = '\0'; + + return true; +fail: + errno = sv_errno; + return false; +} + +/* array will be allocated with strings in a single malloc, just free *array */ +ssize_t kmod_builtin_get_modinfo(struct kmod_ctx *ctx, const char *modname, + char ***modinfo) +{ + ssize_t count = 0; + char *s, *line = NULL; + size_t i, n, linesz, modlen, size; + off_t pos, offset; + + char *name = NULL; + char buf[PATH_MAX]; + + struct kmod_builtin_iter *iter = kmod_builtin_iter_new(ctx); + + if (!iter) + return -1; + + while (!name && kmod_builtin_iter_next(iter)) { + if (!kmod_builtin_iter_get_modname(iter, buf)) { + count = -errno; + goto fail; + } + + if (strcmp(modname, buf)) + continue; + + name = buf; + } + + if (!name) { + count = -ENOSYS; + goto fail; + } + + modlen = strlen(modname) + 1; + count = iter->nstrings; + size = iter->next - iter->pos - (modlen * count); + + *modinfo = malloc(size + sizeof(char *) * (count + 1)); + if (!*modinfo) { + count = -errno; + goto fail; + } + + s = (char *)(*modinfo + count + 1); + i = 0; + + n = 0; + offset = pos = iter->pos; + + while (offset < iter->next) { + offset = get_string(iter, pos, &line, &linesz); + if (offset <= 0) { + count = (offset) ? -errno : -EOF; + goto fail; + } + + strcpy(s + i, line + modlen); + (*modinfo)[n++] = s + i; + i += linesz - modlen; + + pos = offset; + } +fail: + kmod_builtin_iter_free(iter); + return count; +} diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index a65ddd1..df01df1 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -193,3 +193,11 @@ struct kmod_signature_info { }; bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signature_info *sig_info) _must_check_ __attribute__((nonnull(1, 2))); void kmod_module_signature_info_free(struct kmod_signature_info *sig_info) __attribute__((nonnull)); + +/* libkmod-builtin.c */ +struct kmod_builtin_iter; +struct kmod_builtin_iter *kmod_builtin_iter_new(struct kmod_ctx *ctx) __attribute__((nonnull(1))); +void kmod_builtin_iter_free(struct kmod_builtin_iter *iter) __attribute__((nonnull(1))); +bool kmod_builtin_iter_next(struct kmod_builtin_iter *iter) __attribute__((nonnull(1))); +bool kmod_builtin_iter_get_modname(struct kmod_builtin_iter *iter, char modname[static PATH_MAX]) __attribute__((nonnull(1, 2))); +ssize_t kmod_builtin_get_modinfo(struct kmod_ctx *ctx, const char *modname, char ***modinfo) __attribute__((nonnull(1, 2, 3))); From patchwork Fri Nov 8 17:25:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Gladkov X-Patchwork-Id: 11235305 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1EEC61575 for ; Fri, 8 Nov 2019 17:25:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 078C02084D for ; Fri, 8 Nov 2019 17:25:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727168AbfKHRZn convert rfc822-to-8bit (ORCPT ); Fri, 8 Nov 2019 12:25:43 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:36355 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728714AbfKHRZn (ORCPT ); Fri, 8 Nov 2019 12:25:43 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-263-xXfbT6iUMwiwetJ8Hw6FEw-1; Fri, 08 Nov 2019 12:25:39 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 529788017E0; Fri, 8 Nov 2019 17:25:38 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id A77EF1001281; Fri, 8 Nov 2019 17:25:37 +0000 (UTC) From: Alexey Gladkov To: linux-modules@vger.kernel.org Cc: Lucas De Marchi Subject: [PATCH v2 2/4] libkmod: Add function to get list of built-in modules Date: Fri, 8 Nov 2019 18:25:21 +0100 Message-Id: <20191108172524.468494-3-gladkov.alexey@gmail.com> In-Reply-To: <20191108172524.468494-1-gladkov.alexey@gmail.com> References: <20191108172524.468494-1-gladkov.alexey@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-MC-Unique: xXfbT6iUMwiwetJ8Hw6FEw-1 X-Mimecast-Spam-Score: 0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: Signed-off-by: Alexey Gladkov --- libkmod/libkmod-internal.h | 1 + libkmod/libkmod-module.c | 40 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index df01df1..ee4b97b 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -145,6 +145,7 @@ void kmod_module_set_visited(struct kmod_module *mod, bool visited) __attribute_ void kmod_module_set_builtin(struct kmod_module *mod, bool builtin) __attribute__((nonnull((1)))); void kmod_module_set_required(struct kmod_module *mod, bool required) __attribute__((nonnull(1))); bool kmod_module_is_builtin(struct kmod_module *mod) __attribute__((nonnull(1))); +int kmod_module_get_builtin(struct kmod_ctx *ctx, struct kmod_list **list) __attribute__((nonnull(1, 2))); /* libkmod-file.c */ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename) _must_check_ __attribute__((nonnull(1,2))); diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index bffe715..8fbabd2 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -2866,3 +2866,43 @@ KMOD_EXPORT void kmod_module_dependency_symbols_free_list(struct kmod_list *list list = kmod_list_remove(list); } } + +/** + * kmod_module_get_builtin: + * @ctx: kmod library context + * @list: where to save the builtin module list + * + * Returns: 0 on success or < 0 otherwise. + */ +int kmod_module_get_builtin(struct kmod_ctx *ctx, struct kmod_list **list) +{ + struct kmod_builtin_iter *iter; + int err = 0; + + iter = kmod_builtin_iter_new(ctx); + if (!iter) + return -errno; + + while (kmod_builtin_iter_next(iter)) { + struct kmod_module *mod = NULL; + char modname[PATH_MAX]; + + if (!kmod_builtin_iter_get_modname(iter, modname)) { + err = -errno; + goto fail; + } + + kmod_module_new_from_name(ctx, modname, &mod); + kmod_module_set_builtin(mod, true); + + *list = kmod_list_append(*list, mod); + } + + kmod_builtin_iter_free(iter); + return err; +fail: + kmod_builtin_iter_free(iter); + kmod_module_unref_list(*list); + *list = NULL; + return err; +} From patchwork Fri Nov 8 17:25:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Gladkov X-Patchwork-Id: 11235309 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4FDDB1986 for ; Fri, 8 Nov 2019 17:25:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2E6132084D for ; Fri, 8 Nov 2019 17:25:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728892AbfKHRZp convert rfc822-to-8bit (ORCPT ); Fri, 8 Nov 2019 12:25:45 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:35479 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728714AbfKHRZp (ORCPT ); Fri, 8 Nov 2019 12:25:45 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-7-OrwgZTBzMcq2utvwMpbrXA-1; Fri, 08 Nov 2019 12:25:40 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4314C477; Fri, 8 Nov 2019 17:25:39 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9999C1001281; Fri, 8 Nov 2019 17:25:38 +0000 (UTC) From: Alexey Gladkov To: linux-modules@vger.kernel.org Cc: Lucas De Marchi Subject: [PATCH v2 3/4] Lookup aliases in the modules.builtin.modinfo Date: Fri, 8 Nov 2019 18:25:22 +0100 Message-Id: <20191108172524.468494-4-gladkov.alexey@gmail.com> In-Reply-To: <20191108172524.468494-1-gladkov.alexey@gmail.com> References: <20191108172524.468494-1-gladkov.alexey@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-MC-Unique: OrwgZTBzMcq2utvwMpbrXA-1 X-Mimecast-Spam-Score: 0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: New modules.builtin.modinfo duplicates modules.builtin in the built-in module name search. If it exists, then we can use this file, but if not, then we need to fallback to the old file. Signed-off-by: Alexey Gladkov --- libkmod/libkmod-internal.h | 1 + libkmod/libkmod-module.c | 10 ++++-- libkmod/libkmod.c | 25 +++++++++++++++ libkmod/libkmod.h | 1 + tools/depmod.c | 63 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index ee4b97b..b22ac2a 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -89,6 +89,7 @@ int kmod_lookup_alias_from_config(struct kmod_ctx *ctx, const char *name, struct int kmod_lookup_alias_from_symbols_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); int kmod_lookup_alias_from_aliases_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); int kmod_lookup_alias_from_moddep_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); +int kmod_lookup_alias_from_kernel_builtin_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); int kmod_lookup_alias_from_builtin_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); bool kmod_lookup_alias_is_builtin(struct kmod_ctx *ctx, const char *name) __attribute__((nonnull(1, 2))); int kmod_lookup_alias_from_commands(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 8fbabd2..ee7e6bd 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -575,10 +575,16 @@ KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx, err = kmod_lookup_alias_from_aliases_file(ctx, alias, list); CHECK_ERR_AND_FINISH(err, fail, list, finish); - DBG(ctx, "lookup modules.builtin %s\n", alias); - err = kmod_lookup_alias_from_builtin_file(ctx, alias, list); + DBG(ctx, "lookup modules.builtin.modinfo %s\n", alias); + err = kmod_lookup_alias_from_kernel_builtin_file(ctx, alias, list); CHECK_ERR_AND_FINISH(err, fail, list, finish); + if (err == 0) { + DBG(ctx, "lookup modules.builtin %s\n", alias); + err = kmod_lookup_alias_from_builtin_file(ctx, alias, list); + CHECK_ERR_AND_FINISH(err, fail, list, finish); + } + finish: DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list); return err; diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c index 69fe431..c9d9e2a 100644 --- a/libkmod/libkmod.c +++ b/libkmod/libkmod.c @@ -57,6 +57,7 @@ static struct _index_files { [KMOD_INDEX_MODULES_DEP] = { .fn = "modules.dep", .prefix = "" }, [KMOD_INDEX_MODULES_ALIAS] = { .fn = "modules.alias", .prefix = "alias " }, [KMOD_INDEX_MODULES_SYMBOL] = { .fn = "modules.symbols", .prefix = "alias "}, + [KMOD_INDEX_MODULES_BUILTIN_ALIAS] = { .fn = "modules.builtin.alias", .prefix = "" }, [KMOD_INDEX_MODULES_BUILTIN] = { .fn = "modules.builtin", .prefix = ""}, }; @@ -522,6 +523,30 @@ static char *lookup_builtin_file(struct kmod_ctx *ctx, const char *name) return line; } +int kmod_lookup_alias_from_kernel_builtin_file(struct kmod_ctx *ctx, + const char *name, + struct kmod_list **list) +{ + struct kmod_list *l; + int ret = kmod_lookup_alias_from_alias_bin(ctx, + KMOD_INDEX_MODULES_BUILTIN_ALIAS, + name, list); + if (ret > 0) { + kmod_list_foreach(l, *list) { + struct kmod_module *mod = l->data; + kmod_module_set_builtin(mod, true); + } + } else if (ret == -ENOSYS) { + /* + * If the system does not support this yet, then + * there is no need to return an error. + */ + ret = 0; + } + + return ret; +} + int kmod_lookup_alias_from_builtin_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) { diff --git a/libkmod/libkmod.h b/libkmod/libkmod.h index 352627e..3cab2e5 100644 --- a/libkmod/libkmod.h +++ b/libkmod/libkmod.h @@ -70,6 +70,7 @@ enum kmod_index { KMOD_INDEX_MODULES_DEP = 0, KMOD_INDEX_MODULES_ALIAS, KMOD_INDEX_MODULES_SYMBOL, + KMOD_INDEX_MODULES_BUILTIN_ALIAS, KMOD_INDEX_MODULES_BUILTIN, /* Padding to make sure enum is not mapped to char */ _KMOD_INDEX_PAD = 1U << 31, diff --git a/tools/depmod.c b/tools/depmod.c index 391afe9..fbbce10 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -2402,6 +2402,68 @@ static int output_devname(struct depmod *depmod, FILE *out) return 0; } +static int output_builtin_alias_bin(struct depmod *depmod, FILE *out) +{ + int ret = 0, count = 0; + struct index_node *idx; + struct kmod_list *l, *builtin = NULL; + + idx = index_create(); + + if (idx == NULL) { + ret = -ENOMEM; + goto fail; + } + + ret = kmod_module_get_builtin(depmod->ctx, &builtin); + if (ret < 0) { + if (ret == -ENOENT) + ret = 0; + goto fail; + } + + kmod_list_foreach(l, builtin) { + struct kmod_list *ll, *info_list = NULL; + struct kmod_module *mod = l->data; + const char *modname = kmod_module_get_name(mod); + + ret = kmod_module_get_info(mod, &info_list); + if (ret < 0) + goto fail; + + kmod_list_foreach(ll, info_list) { + char alias[PATH_MAX]; + const char *key = kmod_module_info_get_key(ll); + const char *value = kmod_module_info_get_value(ll); + + if (!streq(key, "alias")) + continue; + + alias[0] = '\0'; + if (alias_normalize(value, alias, NULL) < 0) { + WRN("Unmatched bracket in %s\n", value); + continue; + } + + index_insert(idx, alias, modname, 0); + } + + kmod_module_info_free_list(info_list); + + index_insert(idx, modname, modname, 0); + count++; + } + + if (count) + index_write(idx, out); + index_destroy(idx); +fail: + if (builtin) + kmod_module_unref_list(builtin); + + return ret; +} + static int depmod_output(struct depmod *depmod, FILE *out) { static const struct depfile { @@ -2416,6 +2478,7 @@ static int depmod_output(struct depmod *depmod, FILE *out) { "modules.symbols", output_symbols }, { "modules.symbols.bin", output_symbols_bin }, { "modules.builtin.bin", output_builtin_bin }, + { "modules.builtin.alias.bin", output_builtin_alias_bin }, { "modules.devname", output_devname }, { } }; From patchwork Fri Nov 8 17:25:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Gladkov X-Patchwork-Id: 11235311 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6B824A7D for ; Fri, 8 Nov 2019 17:25:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AF0A42084D for ; Fri, 8 Nov 2019 17:25:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728714AbfKHRZq convert rfc822-to-8bit (ORCPT ); Fri, 8 Nov 2019 12:25:46 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:23947 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728769AbfKHRZq (ORCPT ); Fri, 8 Nov 2019 12:25:46 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-265-jD6sSU1TOqK9EHjXQNjYmA-1; Fri, 08 Nov 2019 12:25:41 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3509B2A3; Fri, 8 Nov 2019 17:25:40 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.2.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8AC6C1001281; Fri, 8 Nov 2019 17:25:39 +0000 (UTC) From: Alexey Gladkov To: linux-modules@vger.kernel.org Cc: Lucas De Marchi Subject: [PATCH v2 4/4] modinfo: Show information about built-in modules Date: Fri, 8 Nov 2019 18:25:23 +0100 Message-Id: <20191108172524.468494-5-gladkov.alexey@gmail.com> In-Reply-To: <20191108172524.468494-1-gladkov.alexey@gmail.com> References: <20191108172524.468494-1-gladkov.alexey@gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-MC-Unique: jD6sSU1TOqK9EHjXQNjYmA-1 X-Mimecast-Spam-Score: 0 Sender: owner-linux-modules@vger.kernel.org Precedence: bulk List-ID: Signed-off-by: Alexey Gladkov --- libkmod/libkmod-builtin.c | 2 +- libkmod/libkmod-module.c | 23 ++++++++++++++++------- tools/modinfo.c | 39 +++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/libkmod/libkmod-builtin.c b/libkmod/libkmod-builtin.c index c7b888a..6b4651c 100644 --- a/libkmod/libkmod-builtin.c +++ b/libkmod/libkmod-builtin.c @@ -275,7 +275,7 @@ ssize_t kmod_builtin_get_modinfo(struct kmod_ctx *ctx, const char *modname, struct kmod_builtin_iter *iter = kmod_builtin_iter_new(ctx); if (!iter) - return -1; + return -errno; while (!name && kmod_builtin_iter_next(iter)) { if (!kmod_builtin_iter_get_modname(iter, buf)) { diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index ee7e6bd..8044a8f 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -2286,13 +2286,22 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_ assert(*list == NULL); - elf = kmod_module_get_elf(mod); - if (elf == NULL) - return -errno; + /* remove const: this can only change internal state */ + if (kmod_module_is_builtin((struct kmod_module *)mod)) { + count = kmod_builtin_get_modinfo(mod->ctx, + kmod_module_get_name(mod), + &strings); + if (count < 0) + return count; + } else { + elf = kmod_module_get_elf(mod); + if (elf == NULL) + return -errno; - count = kmod_elf_get_strings(elf, ".modinfo", &strings); - if (count < 0) - return count; + count = kmod_elf_get_strings(elf, ".modinfo", &strings); + if (count < 0) + return count; + } for (i = 0; i < count; i++) { struct kmod_list *n; @@ -2316,7 +2325,7 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_ goto list_error; } - if (kmod_module_signature_info(mod->file, &sig_info)) { + if (mod->file && kmod_module_signature_info(mod->file, &sig_info)) { struct kmod_list *n; n = kmod_module_info_append(list, "sig_id", strlen("sig_id"), diff --git a/tools/modinfo.c b/tools/modinfo.c index 86ac04b..0231bb0 100644 --- a/tools/modinfo.c +++ b/tools/modinfo.c @@ -172,18 +172,33 @@ static int modinfo_do(struct kmod_module *mod) { struct kmod_list *l, *list = NULL; struct param *params = NULL; - int err; + int err, is_builtin; + const char *filename = kmod_module_get_path(mod); + + is_builtin = (filename == NULL); + + if (is_builtin) { + printf("%-16s%s%c", "name:", kmod_module_get_name(mod), separator); + filename = "(builtin)"; + } if (field != NULL && streq(field, "filename")) { - printf("%s%c", kmod_module_get_path(mod), separator); + printf("%s%c", filename, separator); return 0; } else if (field == NULL) { printf("%-16s%s%c", "filename:", - kmod_module_get_path(mod), separator); + filename, separator); } err = kmod_module_get_info(mod, &list); if (err < 0) { + if (is_builtin && err == -ENOENT) { + /* + * This is an old kernel that does not have a file + * with information about built-in modules. + */ + return 0; + } ERR("could not get modinfo from '%s': %s\n", kmod_module_get_name(mod), strerror(-err)); return err; @@ -276,7 +291,7 @@ static int modinfo_path_do(struct kmod_ctx *ctx, const char *path) static int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias) { - struct kmod_list *l, *filtered, *list = NULL; + struct kmod_list *l, *list = NULL; int err = kmod_module_new_from_lookup(ctx, alias, &list); if (err < 0) { ERR("Module alias %s not found.\n", alias); @@ -288,26 +303,14 @@ static int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias) return -ENOENT; } - err = kmod_module_apply_filter(ctx, KMOD_FILTER_BUILTIN, list, &filtered); - kmod_module_unref_list(list); - if (err < 0) { - ERR("Failed to filter list: %m\n"); - return err; - } - - if (filtered == NULL) { - ERR("Module %s not found.\n", alias); - return -ENOENT; - } - - kmod_list_foreach(l, filtered) { + kmod_list_foreach(l, list) { struct kmod_module *mod = kmod_module_get_module(l); int r = modinfo_do(mod); kmod_module_unref(mod); if (r < 0) err = r; } - kmod_module_unref_list(filtered); + kmod_module_unref_list(list); return err; }