From: Anthony Liguori <anthony@codemonkey.ws>
To: "Jorge Lucángeli Obes" <t4m5yn@gmail.com>
Cc: kvm-devel@lists.sourceforge.net, qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [kvm-devel] [PATCH][RFC] Allowing QEMU to directly execute a directory (and storing command line options in it)
Date: Fri, 31 Aug 2007 13:54:17 -0500 [thread overview]
Message-ID: <1188586457.8543.2.camel@squirrel> (raw)
In-Reply-To: <59abf66e0708311119p2b83fcffg31fac1c298cfc10a@mail.gmail.com>
It makes little sense to pass a directory when you can pass a config
file and assume that the directory the config file is in is the CWD.
For instance, if vm.cfg contained just the command line arguments, you
could have:
MyImage/vm.cfg: -hda disk0.qcow -m 512
MyImage/disk0.qcow: <disk image>
And then do:
qemu -c MyImage/vm.cfg
Regards,
Anthony Liguori
On Fri, 2007-08-31 at 15:19 -0300, Jorge Lucángeli Obes wrote:
> Hi all,
>
> The last time this issue was discussed, the executable-directory idea
> gained more consensus than the snapshot-based idea. This patch
> implements my perception of the first idea. Non-Windows for now, as I
> can't test on a Windows system. Suggestions and constructive criticism
> more than welcome.
>
> Cheers,
> Jorge
>
> This patch allows QEMU to execute a directory with a special format.
>
> This patch allows storing command line options in a configuration file inside
> a directory and then directly executing that directory. A simple check is
> included to prevent the configuration file to access image files outside
> the executed directory. Extra command line options can be passed on invocation,
> which will take precedence over the ones stored in the configuration file.
>
> The configuration file specifies, on its first line, the image file to use.
> The rest of the file specifies command line options separated by spaces or
> newlines. Careful reconstruction of the command line makes sure the speficied
> image file gets executed even if other image files were included later in the
> configuration file.
>
> Signed-off-by: Jorge Lucángeli Obes
> ---
> diff --git a/qemu/vl.c b/qemu/vl.c
> index fcc899b..88cefd2 100644
> --- a/qemu/vl.c
> +++ b/qemu/vl.c
> @@ -42,8 +42,8 @@
> #include <netinet/in.h>
> #include <dirent.h>
> #include <netdb.h>
> -#ifdef _BSD
> #include <sys/stat.h>
> +#ifdef _BSD
> #ifndef __APPLE__
> #include <libutil.h>
> #endif
> @@ -6367,9 +6367,16 @@ int main_loop(void)
> void help(void)
> {
> printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c)
> 2003-2007 Fabrice Bellard\n"
> - "usage: %s [options] [disk_image]\n"
> + "usage: %s [options] [disk_image|folder]\n"
> "\n"
> +#ifdef _WIN32
> "'disk_image' is a raw hard image image for IDE hard disk 0\n"
> +#else
> + "'disk_image' is a raw hard image image for IDE hard disk 0 or\n"
> + "'folder' is a folder with a file 'config' containing in
> the first line\n"
> + "the name of an image file inside the folder and in the
> rest of the file\n"
> + "options separated by ' ' or '\\n'\n"
> +#endif
> "\n"
> "Standard options:\n"
> "-M machine select emulated machine (-M ? for list)\n"
> @@ -6892,6 +6899,20 @@ void qemu_get_launch_info(int *argc, char
> ***argv, int *opt_daemonize, const cha
> *opt_incoming = incoming;
> }
>
> +char *dir_file_cat(const char *folder, const char *file) {
> + int foldlen = strlen(folder);
> + int filelen = strlen(file);
> + int reslen = foldlen + 1 + filelen + 1;
> +
> + char *res = malloc(sizeof(char) * reslen);
> +
> + pstrcpy(res, reslen, folder);
> + strncat(res, "/", 1);
> + strncat(res, file, filelen);
> +
> + return res;
> +}
> +
> int main(int argc, char **argv)
> {
> #ifdef CONFIG_GDBSTUB
> @@ -7003,7 +7024,120 @@ int main(int argc, char **argv)
>
> nb_nics = 0;
> /* default mac address of the first network interface */
> +
> +#ifndef _WIN32
> +#define DIR_CMDLINE_SIZE 1<<13
> + int hd_found = 0;
> + char *dir, *opts;
> + struct stat *s = NULL;
> +
> + optind = 1;
> + for(;;) {
> + if (optind >= argc)
> + break;
> +
> + dir = argv[optind++];
> +
> + if (dir[0] != '-') {
> + hd_found = 1;
> + break;
> + }
> + }
>
> + if (hd_found) {
> + s = malloc(sizeof(*s));
> +
> + if (stat(dir, s) < 0) {
> + /* Error */
> + fprintf(stderr, "unable to stat: '%s'\n",
> + dir);
> + exit(1);
> + }
> +
> + if (S_ISDIR(s->st_mode)) {
> + /* The user specified a directory, search for ./config */
> + int configlen = strlen(dir);
> + configlen += 8; /* "/config\0" */
> + char *config = malloc(sizeof(char) * configlen);
> +
> + pstrcpy(config, configlen, dir);
> + strncat(config, "/config", 7);
> +
> + int fd_config;
> +
> + if ((fd_config = open(config, 0)) < 0) {
> + /* Error */
> + if (errno == ENOENT)
> + fprintf(stderr, "config file not found: '%s'\n",
> + config);
> + else
> + fprintf(stderr, "unable to open config file: '%s'\n",
> + config);
> + exit(1);
> + }
> +
> + opts = malloc(sizeof(char) * (DIR_CMDLINE_SIZE));
> +
> + ssize_t readb = read(fd_config, opts, (DIR_CMDLINE_SIZE) - 1);
> +
> + opts[readb] = '\0';
> +
> + char *filename = strsep(&opts, "\n");
> +
> + if (filename == NULL) {
> + /* Error */
> + fprintf(stderr, "malformed configuration file: '%s'\n",
> + config);
> + exit(1);
> + } else if (strchr(filename, '/') != NULL) {
> + /* Error */
> + fprintf(stderr, "'%s' may point outside folder '%s'\n"
> + "avoid using '/' in config file\n",
> + filename, dir);
> + exit(1);
> + }
> +
> + char tmpopts[DIR_CMDLINE_SIZE];
> + int done = 0;
> + unsigned int nbtoks = 0;
> + char *tok;
> +
> + pstrcpy(tmpopts, DIR_CMDLINE_SIZE, opts);
> +
> + do {
> + tok = strtok(nbtoks == 0? tmpopts : NULL, " \n");
> +
> + if (tok != NULL)
> + nbtoks++;
> + else
> + done = 1;
> + } while (!done);
> +
> + if (nbtoks > 0) {
> + char **argvprime = malloc((nbtoks + argc + 1) * sizeof(char*));
> +
> + argvprime[0] = argv[0];
> +
> + for (i = 0; i < nbtoks; i++)
> + argvprime[i + 1] = strtok(i == 0? opts : NULL, " \n");
> +
> + for (i = 1; i < argc; i++)
> + argvprime[nbtoks + i] = argv[i];
> +
> + argvprime[nbtoks + argc] = dir_file_cat(dir, filename);
> +
> + argv = argvprime;
> + argc = nbtoks + argc + 1;
> +
> + for (i = 0; i < argc; i++)
> + printf("argv[%d] = %s\n", i, argv[i]);
> + }
> + }
> + }
> +
> + free(s);
> +#endif
> +
> optind = 1;
> for(;;) {
> if (optind >= argc)
> @@ -7773,5 +7907,10 @@ int main(int argc, char **argv)
>
> main_loop();
> quit_timers();
> +
> + /* argv was overwritten when parsing config file */
> + if (hd_found)
> + free(argv);
> +
> return 0;
> }
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems? Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >> http://get.splunk.com/
> _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
next prev parent reply other threads:[~2007-08-31 18:54 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-31 18:19 [Qemu-devel] [PATCH][RFC] Allowing QEMU to directly execute a directory (and storing command line options in it) Jorge Lucángeli Obes
2007-08-31 18:54 ` Anthony Liguori [this message]
2007-08-31 19:05 ` [Qemu-devel] Re: [kvm-devel] " Jorge Lucángeli Obes
2007-08-31 19:13 ` Anthony Liguori
2007-09-01 11:02 ` Markus Hitter
2007-09-01 14:26 ` Luke -Jr
2007-09-01 14:49 ` Andreas Färber
2007-09-01 14:39 ` Andreas Färber
2007-09-01 18:45 ` Jorge Lucángeli Obes
2007-09-01 19:52 ` Andreas Färber
2007-09-01 20:26 ` Jorge Lucángeli Obes
2007-09-03 9:19 ` Philip Boulain
2007-09-03 10:01 ` Christian Brunschen
2007-09-03 11:10 ` Philip Boulain
2007-09-03 11:40 ` Andreas Färber
2007-09-03 13:54 ` Andreas Färber
2007-09-03 14:54 ` Luke -Jr
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=1188586457.8543.2.camel@squirrel \
--to=anthony@codemonkey.ws \
--cc=kvm-devel@lists.sourceforge.net \
--cc=qemu-devel@nongnu.org \
--cc=t4m5yn@gmail.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).