qemu-devel
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]