From: Marco Gerards <metgerards@student.han.nl>
To: grub-devel@gnu.org
Subject: Re: Automagic command loading
Date: Wed, 29 Sep 2004 12:16:50 +0000 [thread overview]
Message-ID: <87fz51mfrh.fsf@marco.marco-g.com> (raw)
In-Reply-To: <20040928190544.GA24852@artax.karlin.mff.cuni.cz> (Tomas Ebenlendr's message of "Tue, 28 Sep 2004 21:05:44 +0200")
Tomas Ebenlendr <ebik@artax.karlin.mff.cuni.cz> writes:
> Here is new patch. The commands list is stored in elf section
> .uinfo.norm_cmds. The module searching mechanism is in autocmd.mod,
> so you switch on autoloading by inserting this module. Interface
> is designed such that there may be other modules autoregistering
> commands.
>
> The contents of .uinfo.norm_cmds of all modules in $prefix gets
> cached on insert of autocmd.mod, because reading of all modules takes
> about 5 seconds on my bochs under Linux, 300Mhz Pentium. The contents
> is recached by command cache_autocommands or when $prefix does not
> match cached directory. This will be used on very rare ocasions.
Does that mean that GRUB hangs for 5 seconds on boot when autocmd is
used? I seriously doubt if that would be acceptable... So is there
any way to speed this up, I think no one want to wait 5 seconds when
GRUB is started...
Here are my comments on your patch. A lot of comments are still
related to the GCS. But I also have a lot of questions on how things
work. Perhaps I can comment better on certain parts of the patch
after you explained this.
> conf/i386-pc.rmk (pkgdata_MODULES): New module autocmd.mod
Please end the sentence with a ".".
> gencmdlist.sh: New file. Greps NORMAL_COMMAND in sources and generates
> list of commands (c source).
Two spaces between sentences. But just "New file." would be enough
already. Explaining what something does should be done in comments in
the file.
> incude/grub/normal.h (NORMAL_COMMAND): New macro. Used for marking
> commands to appear in special elf section.
in a special elf section
> normal/command.c (grub_register_command_autoloader): New function.
You forgot the '*' here.
> (grub_unregister_command_autoloader): New function.
> (grub_command_find): Execute autoloaders when command not found.
was not found
> - char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1];
> + char pathname[grub_strlen (dirname) + grub_strlen (filename) + 2];
Please document this change in the changelog entry.
> - grub_register_command ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
> + grub_register_command (NORMAL_COMMAND("hello"), grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
> "hello", "Say hello", 0);
Please make sure lines can be fully shown on 80x25 terminals.
> +/* The command autoloader description. */
> +struct grub_command_autoloader
What is is used for? How?
> +{
> + /* The callback function. */
> + grub_dl_t (*func) (const char * command);
const char *command
What does this callback do?
> +void EXPORT_FUNC(grub_register_command_autoloader) (
> + grub_dl_t (*hook) (const char * cmd));
> +void EXPORT_FUNC(grub_unregister_command_autoloader) (
> + grub_dl_t (*hook) (const char * cmd));
Can you explain this as well?
> +#define MEMFAILED \
> + ({\
> + grub_error (GRUB_ERR_OUT_OF_MEMORY, "Out of memory");\
> + goto failed;\
> + })
> +
> +#define READFAILED \
> + ({\
> + grub_error (GRUB_ERR_FILE_READ_ERROR, "Error reading file");\
> + goto failed;\
> + })
Personally I don't like this and this is not required. grub_malloc
sets the right error string and sets grub_errno. The same is true for
any generic function. So you should just have "goto failed" where
you have either MEMFAILED or READFAILED.
If any of the functions you use don't do the right thing, it should be
fixed there.
> +/* Reads value of user information in file (elf - module).
> + Don't forget to free() result. */
Isn't that something that is obvious? IMHO such things should not be
documented. Or do you mean a malloc'ed buffer should be returned? In
That case I would just say that.
> +grub_err_t
> +grub_dl_read_file_uinfo (const char *filename, const char * secname, char ** value, int * len)
In the case of pointers, please do not add those extra spaces. Write:
grub_dl_read_file_uinfo (const char *filename, const char *secname, char **value, int *len)
> + section = grub_malloc (grub_strlen (secname) + 8);
Where does this 8 come from?
> + readbytes = grub_file_read (file,(char *) &e, sizeof (e));
A space after the comma.
> + if ((readbytes < (signed) sizeof (e)) || (e.e_ehsize < readbytes) || (e.e_shentsize < (signed) sizeof (*s)))
This line is too long...
> + readbytes = grub_file_read (file,(char *) s, wantbytes);
A space after the comma.
> + if (0)
> + {
> +failed:
> + ret = grub_errno;
> + }
This looks like something you used when debugging? Can you please
clean this up?
> +char * dirname = 0;
Can you remove the space and make this static?
> +module_commands_t modules_list = 0;
Same here.
> + module_commands_t p, q;
module_commands_t p;
module_commands_t q;
> +
> + for (p = modules_list; p; p=q)
p = q
> +static grub_err_t
> +cache_uinfo_files (struct grub_arg_list *state __attribute__ ((unused)),
> + int argc __attribute__ ((unused)),
> + char **args __attribute__ ((unused)))
The function name does not make clear to me that it is a command. I
just recognised it as such because of the arguments.
> + {
> + char * pathname = 0;
Space...
> + if ((suffixidx <= 0) || (grub_strcmp (filename + suffixidx,".mod") != 0))
A space before ".mod".
> +
> + if (0)
> + {
> +ret:
> + grub_free (secbuf);
> + }
Same comment as before. Is this debug code?
> + fs = grub_fs_probe (dev);
> + path = grub_strchr (dirname, ')') + 1;
> +
> + if (! path || ! fs || (path[0] != '/'))
> + goto fail;
> +
> + (fs->dir) (dev, path, cache_module);
Please don't do it like this. Just use grub_fs_dir.
> + /* Test if module has in .uinfo.norm_cmds written the command name. */
> + s = p->commands;
> + while (s - p->commands < p->commands_len)
> + {
> + if (grub_strcmp (s, command) == 0)
> + break;
> + s += grub_strlen (s) + 1;
> + }
What does it mean if .uinfo.norm_cmds is not found?
> + if (s >= p->commands + p->commands_len)
> + return 0;
> +
> + /* Test that module is not loaded. */
> + suffixidx = grub_strlen (p->module) - 4;
Why "- 4"?
> + /* Check if prefix is cached. */
> + path = grub_env_get ("prefix");
Isn't there a grub_get_prefix command?
> + (dirname[len] && ((dirname[len] != '/') || dirname[len+1])))
len + 1
> + cache_uinfo_files (0, 0, 0);
What is this?
> + /* Try <commandname>.mod. */
> + len = grub_strlen (command);
> + modname = grub_malloc (len + 5);
Where is this memory freed?
> +void
> +grub_register_command_autoloader (grub_dl_t (*hook) (const char *
> +cmd))
So if I understand it correctly you made this generic. You can
register an autoloader that is responsible for looking up modules. In
that case it is easy to replace or could be not present at all.
Can you have multiple autoloaders?
Can you elaborate on the design of the autoloader? So explain us how
an autoloader works, how it is used, the interfaces, etc?
> +{
> + grub_command_autoloader_t func, *p;
Please don't declare multiple variable on one line.
> +grub_unregister_command_autoloader (grub_dl_t (*hook) (const char *
> +cmd))
I am not happy with the prefix. You can better use the
"grub_autoloader_" prefix. Not only here but everywhere where this is
logical.
> + grub_command_autoloader_t *p, q;
Same here.
Two questions related to the cache:
- Where is it cached?
- How will the cache be depleted when autocmd is unloaded?
Thanks,
Marco
next prev parent reply other threads:[~2004-09-29 12:23 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-28 19:05 Automagic command loading Tomas Ebenlendr
2004-09-29 12:16 ` Marco Gerards [this message]
2004-09-29 22:14 ` Tomas Ebenlendr
2004-09-29 15:02 ` Yoshinori K. Okuji
2004-09-29 21:38 ` Tomas Ebenlendr
2004-09-29 22:00 ` Marco Gerards
2004-09-29 22:23 ` Tomas Ebenlendr
2004-09-30 13:33 ` Yoshinori K. Okuji
2004-09-30 15:05 ` Marco Gerards
2004-09-30 17:44 ` Tomas Ebenlendr
2004-10-01 15:09 ` Yoshinori K. Okuji
2004-10-01 15:36 ` chaac
2004-10-01 21:56 ` Tomas Ebenlendr
2004-10-06 8:43 ` Yoshinori K. Okuji
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=87fz51mfrh.fsf@marco.marco-g.com \
--to=metgerards@student.han.nl \
--cc=grub-devel@gnu.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.