[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [kvm-devel] [PATCH][RFC] Allowing QEMU to directly exec
From: |
Anthony Liguori |
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 |
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
> address@hidden https://lists.sourceforge.net/lists/listinfo/kvm-devel