From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
To: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: linux-modules@vger.kernel.org, ykaliuta@redhat.com
Subject: Re: [RFC PATCH 1/2] libkmod: module: introduce common symbol API.
Date: Thu, 20 Dec 2018 13:08:34 +0200 [thread overview]
Message-ID: <xunypntwjw0d.fsf@redhat.com> (raw)
In-Reply-To: <20181219184930.GD6410@ldmartin-desk.jf.intel.com> (Lucas De Marchi's message of "Wed, 19 Dec 2018 10:49:30 -0800")
Hi, Lucas!
>>>>> On Wed, 19 Dec 2018 10:49:30 -0800, Lucas De Marchi wrote:
> On Fri, Nov 23, 2018 at 11:53:21PM +0200, Yauheni Kaliuta wrote:
>> Introduce one family of functions to replace the duplicated:
>>
>> - kmod_module_version_get_symbol()
>> - kmod_module_version_get_crc()
>> - kmod_module_symbol_get_symbol()
>> - kmod_module_symbol_get_crc()
>> - kmod_module_dependency_symbol_get_symbol()
>> - kmod_module_dependency_symbol_get_crc()
>> - kmod_module_versions_free_list()
>> - kmod_module_symbols_free_list()
>> - kmod_module_dependency_symbols_free_list()
>>
>> It reuses kmod_module_symbol structure but extends it with the
>> "bind" field, keeping the API still the same.
>>
>> Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
>> ---
>> libkmod/libkmod-module.c | 196 ++++++++++++++++++++++++++++++++++++++-
>> libkmod/libkmod.h | 12 +++
>> 2 files changed, 203 insertions(+), 5 deletions(-)
>>
>> diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
>> index 889f26479a98..f595f40032e0 100644
>> --- a/libkmod/libkmod-module.c
>> +++ b/libkmod/libkmod-module.c
>> @@ -2419,6 +2419,197 @@ KMOD_EXPORT void kmod_module_info_free_list(struct kmod_list *list)
>> }
>> }
>>
>> +struct kmod_module_symbol {
>> + uint64_t crc;
>> + uint8_t bind;
> I think this can be enum kmod_symbol_bind. Or just use "unsigned
> int"... we would have a whole here nonetheless.
Ok. As with the parts below, it's a copy of the existing code.
>> + char symbol[];
>> +};
>> +
>> +static struct kmod_module_symbol
>> *kmod_module_typed_symbol_new(uint64_t crc, uint8_t bind, const char
>> *symbol)
>> +{
>> + struct kmod_module_symbol *ms;
>> + size_t symbollen = strlen(symbol) + 1;
> I know this comes from the other functions, but the naming is not ideal:
> use len for the string len, use sz when including the '\0'. So
> size_t symbolsz = strlen(symbol) + 1;
>> +
>> + ms = malloc(sizeof(struct kmod_module_symbol) + symbollen);
> ms = malloc(sizeof(*ms) + symbolsz);
Sure, I prefer it myself.
>> + if (ms == NULL)
>> + return NULL;
>> +
>> + ms->crc = crc;
>> + ms->bind = bind;
>> + memcpy(ms->symbol, symbol, symbollen);
> blank line
>> + return ms;
>> +}
>> +
>> +static void kmod_module_typed_symbol_free(struct kmod_module_symbol *ms)
>> +{
>> + free(ms);
>> +}
>> +
>> +typedef int (*kmod_symbols_getter)(const struct kmod_elf *elf,
>> struct kmod_modversion **array);
>> +
>> +static kmod_symbols_getter kmod_module_getter_lookup(const struct
>> kmod_module *mod,
>> + enum kmod_symbol_type type)
>> +{
>> + switch (type) {
>> + case KMOD_SYMBOL_VERSIONS:
>> + return kmod_elf_get_modversions;
>> + case KMOD_SYMBOL_CRC:
>> + return kmod_elf_get_symbols;
>> + case KMOD_SYMBOL_DEPENDENCY:
>> + return kmod_elf_get_dependency_symbols;
>> + default:
>> + ERR(mod->ctx, "Wrong symbol type requested: %d\n", type);
>> + }
> I think we can get away without this indirection and just embed the
> switch inside kmod_module_get_typed_symbols().
If you insist.
>> +
>> + return NULL;
>> +}
>> +
>> +/**
>> + * kmod_module_get_typed_symbols:
>> + * @mod: kmod module
>> + * @type: type of symbols to get:
>> + * KMOD_SYMBOL_VERSIONS
>> + * KMOD_SYMBOL_CRC
>> + * KMDO_SYMBOL_DEPENDENCY
>> + * @list: where to return list of module symbols. Use
>> + * kmod_module_typed_symbol_get_symbol(),
>> + * kmod_module_typed_symbol_get_crc() and
>> + * kmod_module_typed_symbol_get_bind() to access the data.
> humn... bind() only makes sense for KMDO_SYMBOL_DEPENDENCY, but I think
> it's fine since we won't return garbage.
>> + *
>> + * After use, free the @list by calling
>> + * kmod_module_typed_symbols_free_list().
>> + *
>> + * Returns: 0 on success or < 0 otherwise.
>> + */
>> +KMOD_EXPORT int kmod_module_get_typed_symbols(const struct
>> kmod_module *mod, enum kmod_symbol_type type, struct kmod_list
>> **list)
>> +{
>> + struct kmod_elf *elf;
>> + struct kmod_modversion *symbols;
>> + int i, count, ret = 0;
>> + kmod_symbols_getter getter;
>> +
>> + if (mod == NULL || list == NULL)
>> + return -ENOENT;
>> +
>> + assert(*list == NULL);
>> +
>> + elf = kmod_module_get_elf(mod);
>> + if (elf == NULL)
>> + return -errno;
>> +
>> + getter = kmod_module_getter_lookup(mod, type);
>> + if (getter == NULL)
>> + return -ENOENT;
>> +
>> + count = getter(elf, &symbols);
>> + if (count < 0)
>> + return count;
>> +
>> + for (i = 0; i < count; i++) {
>> + struct kmod_module_symbol *ms;
>> + struct kmod_list *n;
>> +
>> + ms = kmod_module_typed_symbol_new(symbols[i].crc,
>> + symbols[i].bind,
>> + symbols[i].symbol);
>> + if (ms == NULL) {
>> + ret = -errno;
>> + kmod_module_typed_symbols_free_list(*list);
>> + *list = NULL;
>> + goto list_error;
>> + }
>> +
>> + n = kmod_list_append(*list, ms);
>> + if (n != NULL)
>> + *list = n;
>> + else {
>> + kmod_module_typed_symbol_free(ms);
>> + kmod_module_typed_symbols_free_list(*list);
>> + *list = NULL;
>> + ret = -ENOMEM;
>> + goto list_error;
>> + }
>> + }
>> + ret = count;
>> +
>> +list_error:
>> + free(symbols);
>> + return ret;
>> +}
>> +
>> +/**
>> + * kmod_module_typed_symbol_get_symbol:
>> + * @entry: a list entry representing a kmod module typed symbol
>> + *
>> + * Get the symbol's name of the entry.
>> + *
>> + * Returns: the symbol's name of this kmod module symbols on success or NULL
>> + * on failure. The string is owned by the list, do not free it.
>> + */
>> +KMOD_EXPORT const char *kmod_module_typed_symbol_get_symbol(const
>> struct kmod_list *entry)
>> +{
>> + struct kmod_module_symbol *ms;
>> +
>> + if (entry == NULL || entry->data == NULL)
>> + return NULL;
>> +
>> + ms = entry->data;
>> + return ms->symbol;
> we can make this smaller with
> return ((struct kmod_module_symbol *)entry->data)->symbol
I ususally declare temporary variables (optimizer gets rid of
them anyway) to make the types obvious for readers, but here with
the casting it's fine. Ok.
>> +}
>> +
>> +/**
>> + * kmod_module_typed_symbol_get_crc:
>> + * @entry: a list entry representing a kmod module symbol
>> + *
>> + * Get the crc of the symbol.
>> + *
>> + * Returns: the crc of this kmod module symbol if available,
>> otherwise default to 0.
>> + */
>> +KMOD_EXPORT uint64_t kmod_module_typed_symbol_get_crc(const struct
>> kmod_list *entry)
>> +{
>> + struct kmod_module_symbol *ms;
>> +
>> + if (entry == NULL || entry->data == NULL)
>> + return 0;
>> +
>> + ms = entry->data;
>> + return ms->crc;
> ditto
>> +}
>> +
>> +/**
>> + * kmod_module_dependency_symbol_get_bind:
>> + * @entry: a list entry representing a kmod module symbol
>> + *
>> + * Get the bind type of the symbol.
>> + *
>> + * Returns: the bind of this kmod module symbol on success
>> + * or < 0 on failure.
>> + */
>> +KMOD_EXPORT int kmod_module_typed_symbol_get_bind(const struct kmod_list *entry)
>> +{
>> + struct kmod_module_symbol *ms;
>> +
>> + if (entry == NULL || entry->data == NULL)
>> + return 0;
>> +
>> + ms = entry->data;
>> + return ms->bind;
>> +}
>> +
>> +/**
>> + * kmod_module_typed_symbols_free_list:
>> + * @list: kmod module typed symbols list
>> + *
>> + * Release the resources taken by @list
>> + */
>> +KMOD_EXPORT void kmod_module_typed_symbols_free_list(struct kmod_list *list)
>> +{
>> + while (list) {
>> + kmod_module_typed_symbol_free(list->data);
>> + list = kmod_list_remove(list);
>> + }
>> +}
>> +
>> struct kmod_module_version {
>> uint64_t crc;
>> char symbol[];
>> @@ -2559,11 +2750,6 @@ KMOD_EXPORT void kmod_module_versions_free_list(struct kmod_list *list)
>> }
>> }
>>
>> -struct kmod_module_symbol {
>> - uint64_t crc;
>> - char symbol[];
>> -};
>> -
>> static struct kmod_module_symbol *kmod_module_symbols_new(uint64_t crc, const char *symbol)
>> {
>> struct kmod_module_symbol *mv;
>> diff --git a/libkmod/libkmod.h b/libkmod/libkmod.h
>> index 352627e5d018..9c10e8a54f54 100644
>> --- a/libkmod/libkmod.h
>> +++ b/libkmod/libkmod.h
>> @@ -258,6 +258,18 @@ int kmod_module_dependency_symbol_get_bind(const struct kmod_list *entry);
>> uint64_t kmod_module_dependency_symbol_get_crc(const struct kmod_list *entry);
>> void kmod_module_dependency_symbols_free_list(struct kmod_list *list);
>>
>> +enum kmod_symbol_type {
>> + KMOD_SYMBOL_VERSIONS = 1,
> why 1? we usually start counting from 0.
Well, 0 is too special in my mind and easy to mix with default
initialized value. Not a big deal, will change.
> thanks
> Lucas De Marchi
>> + KMOD_SYMBOL_CRC,
>> + KMOD_SYMBOL_DEPENDENCY,
>> +};
>> +
>> +int kmod_module_get_typed_symbols(const struct kmod_module *mod,
>> enum kmod_symbol_type type, struct kmod_list **list);
>> +const char *kmod_module_typed_symbol_get_symbol(const struct kmod_list *entry);
>> +int kmod_module_typed_symbol_get_bind(const struct kmod_list *entry);
>> +uint64_t kmod_module_typed_symbol_get_crc(const struct kmod_list *entry);
>> +void kmod_module_typed_symbols_free_list(struct kmod_list *list);
>> +
>> #ifdef __cplusplus
>> } /* extern "C" */
>> #endif
>> --
>> 2.19.1
>>
--
WBR,
Yauheni Kaliuta
next prev parent reply other threads:[~2018-12-20 11:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-23 21:53 [RFC PATCH 0/2] Unify symbol access API Yauheni Kaliuta
2018-11-23 21:53 ` [RFC PATCH 1/2] libkmod: module: introduce common symbol API Yauheni Kaliuta
[not found] ` <20181219184930.GD6410@ldmartin-desk.jf.intel.com>
2018-12-20 11:08 ` Yauheni Kaliuta [this message]
2018-11-23 21:53 ` [RFC PATCH 2/2] libkmod: module: make old symbol access API as wrapper to the new Yauheni Kaliuta
2018-12-19 19:24 ` [RFC PATCH 0/2] Unify symbol access API Lucas De Marchi
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=xunypntwjw0d.fsf@redhat.com \
--to=yauheni.kaliuta@redhat.com \
--cc=linux-modules@vger.kernel.org \
--cc=lucas.demarchi@intel.com \
--cc=ykaliuta@redhat.com \
/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).