Le jeu. 8 mai 2025, 15:49, Yair Yarom <ir...@cs.huji.ac.il> a écrit :

> Initial testpci module and command used to query if PCI devices are
> present.
>
> ---
>  docs/grub.texi               |   8 ++
>  grub-core/Makefile.core.def  |   7 ++
>  grub-core/commands/testpci.c | 167 +++++++++++++++++++++++++++++++++++
>  3 files changed, 182 insertions(+)
>  create mode 100644 grub-core/commands/testpci.c
>
> diff --git a/docs/grub.texi b/docs/grub.texi
> index 2b3d536d3..296c60b72 100644
> --- a/docs/grub.texi
> +++ b/docs/grub.texi
> @@ -4139,6 +4139,7 @@ Modules can be loaded via the @command{insmod}
> (@pxref{insmod}) command.
>  * test_module::
>  * test_blockarg_module::
>  * testload_module::
> +* testpci_module::
>  * testspeed_module::
>  * tftp_module::
>  * tga_module::
> @@ -5728,6 +5729,12 @@ argument function in GRUB internal functions via a
> test command
>  This module is intended for performing a functional test of some file
> reading /
>  seeking functions in GRUB internals via a test command @command{testload}.
>
> +@node testpci_module
> +@section testpci
> +This module provides support for the @command{testpci} command. This
> +command can be used to test if specific PCI / PCIe devices are found on
> +the system.
> +
>
This needs more details. How to use it, format of the arguments and format
of the file. Is possible to know it from reading the code but this
shouldn't be a requirement.

>
> +#include <grub/dl.h>
> +#include <grub/extcmd.h>
> +#include <grub/mm.h>
> +#include <grub/file.h>
> +#include <grub/normal.h>
>
What requires normal.h? Just curious

> +static const struct grub_arg_option options[] = {
> +  {"file", 0, 0, "read device list from file", "FILE", ARG_TYPE_STRING},
>
You can also add a short option.

> +struct grub_testpci_devlist {
> +  char** devices;
> +  int n_devices;
> +  int s_devices;
>
What is s_devices? Maybe a more descriptive name? From reading code I see
that it's the number of allocated devices. Maybe name it allocated_devices?

> +  bool found;
> +};
> +
> +static int
> +grub_testpci_iter (grub_pci_device_t dev  __attribute__ ((unused)),
> +                   grub_pci_id_t pciid,
> +                   void *data) {
> +
> +  struct grub_testpci_devlist* devlist = (struct
> grub_testpci_devlist*)data;
> +
> +  char* device = grub_xasprintf ("%04x:%04x", pciid & 0xFFFF, pciid >>
> 16);
>
You forgot to check that allocation succeeded. The easiest way around it is
to allocate it on stack and use snprintf. 10 bytes should be enough

> +
> +static void
> +testpci_add_device_to_list(struct grub_testpci_devlist* devlist,
> +                           char* device)
> +{
> +  if (devlist->n_devices == devlist->s_devices) {
> +    devlist->s_devices *= 2;
> +    devlist->devices = grub_realloc(devlist->devices,
> +                                    devlist->s_devices * sizeof(char*));
> +    if (!(devlist->devices)) {
>
Memory leak if I remember realloc semantics correctly.

> +      return;
> +    }
> +  }
> +  devlist->devices[devlist->n_devices++] = grub_strdup(device);
>
You forgot the check for the error.

> +}
> +
> +static grub_err_t
> +grub_cmd_testpci (grub_extcmd_context_t ctxt,
> +                  int argc, char **args)
> +{
> +
> +  struct grub_testpci_devlist devlist;
> +
> +  devlist.found = false;
> +  devlist.n_devices = 0;
> +  devlist.s_devices = argc + (ctxt->state[0].set ? 5 : 0);
> +  devlist.devices = grub_malloc(devlist.s_devices * sizeof(char*));
> +  if (!(devlist.devices)) {
> +    return GRUB_ERR_OUT_OF_MEMORY;
>
return grub_errno;

> +  }
> +
> +  for (int i = 0; i < argc; i++) {
> +    testpci_add_device_to_list(&devlist, args[i]);
> +    if (!(devlist.devices)) {
> +      return GRUB_ERR_OUT_OF_MEMORY;
>
Ditto

> +    }
> +  }
> +
> +  /* device list from file */
> +  if (ctxt->state[0].set) {
> +
> +    grub_file_t listfile = grub_file_open(ctxt->state[0].arg,
> GRUB_FILE_TYPE_NONE);
>
File type is wrong

> +    if (listfile) {
>
You need to pass on the error if the file fails to open. Not just do
without it

> +
> +      char *buf = NULL;
> +      while (grub_free (buf), (buf = grub_file_getline (listfile))) {
> +
> +        /* remove comments */
> +        char *p = grub_strchr(buf, '#');
> +        if (p) {
> +          *p = '\0';
> +        }
> +
> +        /* remove suffix spaces */
> +        p = buf + grub_strlen(buf) - 1;
> +        while (p >= buf && *p && grub_isspace(*p)) {
> +          *p-- = '\0';
> +        }
> +
> +        /* remove prefix spaces */
> +        p = buf;
> +        while (*p && grub_isspace(*p)) {
> +          p++;
> +        }
> +
> +        /* ignore empty */
> +        if (*p == '\0')
> +          continue;
> +
> +        testpci_add_device_to_list(&devlist, p);
> +        if (!(devlist.devices)) {
> +          return GRUB_ERR_OUT_OF_MEMORY;
>
Ditto

> +        }
> +
> +      }
> +
> +      grub_file_close (listfile);
> +    }
> +  }
> +
> +  for (int d = 0 ; d < devlist.n_devices; d++) {
> +    if (grub_strlen(devlist.devices[d]) != 9 || devlist.devices[d][4] !=
> ':') {
> +      grub_printf("bad input device (%d) \"%s\", expected xxxx:xxxx\n",
> d, devlist.devices[d]);
>
Return an error.

> +    }
> +  }
> +
> +  grub_pci_iterate (grub_testpci_iter, (void*)&devlist);
> +
> +  for (int i = 0; i < devlist.n_devices; i++) {
> +    grub_free(devlist.devices[i]);
> +  }
> +  grub_free(devlist.devices);
> +  return devlist.found ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
>
You need to call grub_error here

> +}
> +
> +static grub_extcmd_t cmd;
> +
> +GRUB_MOD_INIT(testpci)
> +{
> +  cmd = grub_register_extcmd ("testpci", grub_cmd_testpci, 0,
> +                              "[<devid> [...]] [--file <filename>]",
> +                              N_("Check if any of the PCI devices
> exist."), options);
> +}
> +
> +GRUB_MOD_FINI(testpci)
> +{
> +  grub_unregister_extcmd (cmd);
> +}
> --
> 2.39.5
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
Regards
Vladimir 'phcoder' Serbinenko
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to