debuggers.hg

changeset 22845:b59f04eb8978

libxl, minios: stubdom console based save/restore

Add two "special" PV consoles to stubdoms that are going to be used
to send and receive the qemu-xen save files on save/restore.

Use the second PV console to send the qemu-xen save file and the third
PV console to receive the qemu-xen save file on restore.

Fix the console shutdown function free_consfront that is called when the
qemu save file is closed.

Stubdom save/restore is still broken with xend.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
date Fri Jan 21 18:06:23 2011 +0000 (2011-01-21)
parents d6a79425a287
children c50ae9d5dda4
files extras/mini-os/console/xencons_ring.c extras/mini-os/include/lib.h extras/mini-os/lib/sys.c tools/libxl/libxl.c tools/libxl/libxl_dm.c tools/libxl/libxl_internal.h
line diff
     1.1 --- a/extras/mini-os/console/xencons_ring.c	Fri Jan 21 18:03:18 2011 +0000
     1.2 +++ b/extras/mini-os/console/xencons_ring.c	Fri Jan 21 18:06:23 2011 +0000
     1.3 @@ -184,16 +184,43 @@ struct consfront_dev *xencons_ring_init(
     1.4  
     1.5  void free_consfront(struct consfront_dev *dev)
     1.6  {
     1.7 -    mask_evtchn(dev->evtchn);
     1.8 +    char* err = NULL;
     1.9 +    XenbusState state;
    1.10 +
    1.11 +    char path[strlen(dev->backend) + 1 + 5 + 1];
    1.12 +    char nodename[strlen(dev->nodename) + 1 + 5 + 1];
    1.13 +
    1.14 +    snprintf(path, sizeof(path), "%s/state", dev->backend);
    1.15 +    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
    1.16  
    1.17 +    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
    1.18 +        printk("free_consfront: error changing state to %d: %s\n",
    1.19 +                XenbusStateClosing, err);
    1.20 +        goto close;
    1.21 +    }
    1.22 +    state = xenbus_read_integer(path);
    1.23 +    while (err == NULL && state < XenbusStateClosing)
    1.24 +        err = xenbus_wait_for_state_change(path, &state, &dev->events);
    1.25 +    if (err) free(err);
    1.26 +
    1.27 +    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
    1.28 +        printk("free_consfront: error changing state to %d: %s\n",
    1.29 +                XenbusStateClosed, err);
    1.30 +        goto close;
    1.31 +    }
    1.32 +
    1.33 +close:
    1.34 +    if (err) free(err);
    1.35 +    xenbus_unwatch_path_token(XBT_NIL, path, path);
    1.36 +
    1.37 +    mask_evtchn(dev->evtchn);
    1.38 +    unbind_evtchn(dev->evtchn);
    1.39      free(dev->backend);
    1.40 +    free(dev->nodename);
    1.41  
    1.42      gnttab_end_access(dev->ring_ref);
    1.43 +
    1.44      free_page(dev->ring);
    1.45 -
    1.46 -    unbind_evtchn(dev->evtchn);
    1.47 -
    1.48 -    free(dev->nodename);
    1.49      free(dev);
    1.50  }
    1.51  
    1.52 @@ -206,7 +233,7 @@ struct consfront_dev *init_consfront(cha
    1.53      char* msg = NULL;
    1.54      char nodename[256];
    1.55      char path[256];
    1.56 -    static int consfrontends = 1;
    1.57 +    static int consfrontends = 3;
    1.58      struct consfront_dev *dev;
    1.59      int res;
    1.60  
     2.1 --- a/extras/mini-os/include/lib.h	Fri Jan 21 18:03:18 2011 +0000
     2.2 +++ b/extras/mini-os/include/lib.h	Fri Jan 21 18:06:23 2011 +0000
     2.3 @@ -146,6 +146,7 @@ enum fd_type {
     2.4      FTYPE_KBD,
     2.5      FTYPE_FB,
     2.6      FTYPE_MEM,
     2.7 +    FTYPE_SAVEFILE,
     2.8  };
     2.9  
    2.10  #define MAX_EVTCHN_PORTS 16
     3.1 --- a/extras/mini-os/lib/sys.c	Fri Jan 21 18:03:18 2011 +0000
     3.2 +++ b/extras/mini-os/lib/sys.c	Fri Jan 21 18:06:23 2011 +0000
     3.3 @@ -154,6 +154,9 @@ char *getcwd(char *buf, size_t size)
     3.4  }
     3.5  
     3.6  #define LOG_PATH "/var/log/"
     3.7 +#define SAVE_PATH "/var/lib/xen"
     3.8 +#define SAVE_CONSOLE 1
     3.9 +#define RESTORE_CONSOLE 2
    3.10  
    3.11  int mkdir(const char *pathname, mode_t mode)
    3.12  {
    3.13 @@ -175,6 +178,21 @@ int posix_openpt(int flags)
    3.14      return(dev->fd);
    3.15  }
    3.16  
    3.17 +int open_savefile(char *path, int save)
    3.18 +{
    3.19 +    struct consfront_dev *dev;
    3.20 +    char *nodename[64];
    3.21 +
    3.22 +    snprintf(nodename, sizeof(nodename), "device/console/%d", save ? SAVE_CONSOLE : RESTORE_CONSOLE);
    3.23 +
    3.24 +    dev = init_consfront(nodename);
    3.25 +    dev->fd = alloc_fd(FTYPE_SAVEFILE);
    3.26 +    files[dev->fd].cons.dev = dev;
    3.27 +
    3.28 +    printk("fd(%d) = open_savefile\n", dev->fd);
    3.29 +    return(dev->fd);
    3.30 +}
    3.31 +
    3.32  int open(const char *pathname, int flags, ...)
    3.33  {
    3.34      int fd;
    3.35 @@ -191,6 +209,8 @@ int open(const char *pathname, int flags
    3.36      }
    3.37      if (!strncmp(pathname, "/dev/ptmx", strlen("/dev/ptmx")))
    3.38          return posix_openpt(flags);
    3.39 +    if (!strncmp(pathname,SAVE_PATH,strlen(SAVE_PATH)))
    3.40 +        return open_savefile(pathname, flags & O_WRONLY);
    3.41      errno = EIO;
    3.42      return -1;
    3.43  }
    3.44 @@ -203,6 +223,7 @@ int isatty(int fd)
    3.45  int read(int fd, void *buf, size_t nbytes)
    3.46  {
    3.47      switch (files[fd].type) {
    3.48 +        case FTYPE_SAVEFILE:
    3.49  	case FTYPE_CONSOLE: {
    3.50  	    int ret;
    3.51              DEFINE_WAIT(w);
    3.52 @@ -260,6 +281,15 @@ int read(int fd, void *buf, size_t nbyte
    3.53  int write(int fd, const void *buf, size_t nbytes)
    3.54  {
    3.55      switch (files[fd].type) {
    3.56 +        case FTYPE_SAVEFILE: {
    3.57 +                int ret = 0, tot = nbytes;
    3.58 +                while (nbytes > 0) {
    3.59 +                    ret = xencons_ring_send(files[fd].cons.dev, (char *)buf, nbytes);
    3.60 +                    nbytes -= ret;
    3.61 +                    buf += ret;
    3.62 +                }
    3.63 +                return tot - nbytes;
    3.64 +            }
    3.65  	case FTYPE_CONSOLE:
    3.66  	    console_print(files[fd].cons.dev, (char *)buf, nbytes);
    3.67  	    return nbytes;
    3.68 @@ -331,6 +361,7 @@ int close(int fd)
    3.69              shutdown_fbfront(files[fd].fb.dev);
    3.70              files[fd].type = FTYPE_NONE;
    3.71              return 0;
    3.72 +        case FTYPE_SAVEFILE:
    3.73          case FTYPE_CONSOLE:
    3.74              fini_console(files[fd].cons.dev);
    3.75              files[fd].type = FTYPE_NONE;
    3.76 @@ -364,9 +395,15 @@ int fstat(int fd, struct stat *buf)
    3.77  {
    3.78      init_stat(buf);
    3.79      switch (files[fd].type) {
    3.80 +	case FTYPE_SAVEFILE:
    3.81  	case FTYPE_CONSOLE:
    3.82  	case FTYPE_SOCKET: {
    3.83 -	    buf->st_mode = (files[fd].type == FTYPE_CONSOLE?S_IFCHR:S_IFSOCK) | S_IRUSR|S_IWUSR;
    3.84 +            if (files[fd].type == FTYPE_CONSOLE)
    3.85 +                buf->st_mode = S_IFCHR|S_IRUSR|S_IWUSR;
    3.86 +            else if (files[fd].type == FTYPE_SOCKET)
    3.87 +                buf->st_mode = S_IFSOCK|S_IRUSR|S_IWUSR;
    3.88 +            else if (files[fd].type == FTYPE_SAVEFILE)
    3.89 +                buf->st_mode = S_IFREG|S_IRUSR|S_IWUSR;
    3.90  	    buf->st_uid = 0;
    3.91  	    buf->st_gid = 0;
    3.92  	    buf->st_size = 0;
     4.1 --- a/tools/libxl/libxl.c	Fri Jan 21 18:03:18 2011 +0000
     4.2 +++ b/tools/libxl/libxl.c	Fri Jan 21 18:06:23 2011 +0000
     4.3 @@ -737,7 +737,8 @@ int libxl_primary_console_exec(libxl_ctx
     4.4  {
     4.5      uint32_t stubdomid = libxl_get_stubdom_id(ctx, domid_vm);
     4.6      if (stubdomid)
     4.7 -        return libxl_console_exec(ctx, stubdomid, 1, LIBXL_CONSTYPE_PV);
     4.8 +        return libxl_console_exec(ctx, stubdomid,
     4.9 +                STUBDOM_CONSOLE_SERIAL, LIBXL_CONSTYPE_PV);
    4.10      else {
    4.11          if (libxl__domain_is_hvm(ctx, domid_vm))
    4.12              return libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSTYPE_SERIAL);
     5.1 --- a/tools/libxl/libxl_dm.c	Fri Jan 21 18:03:18 2011 +0000
     5.2 +++ b/tools/libxl/libxl_dm.c	Fri Jan 21 18:06:23 2011 +0000
     5.3 @@ -440,7 +440,7 @@ static int libxl_create_stubdom(libxl_ct
     5.4                                  libxl__device_model_starting **starting_r)
     5.5  {
     5.6      libxl__gc gc = LIBXL_INIT_GC(ctx);
     5.7 -    int i, num_console = 1, ret;
     5.8 +    int i, num_console = STUBDOM_SPECIAL_CONSOLES, ret;
     5.9      libxl_device_console *console;
    5.10      libxl_domain_create_info c_info;
    5.11      libxl_domain_build_info b_info;
    5.12 @@ -543,15 +543,31 @@ retry_transaction:
    5.13          console[i].devid = i;
    5.14          console[i].consback = LIBXL_CONSBACK_IOEMU;
    5.15          console[i].domid = domid;
    5.16 -        if (!i) {
    5.17 +        /* STUBDOM_CONSOLE_LOGGING (console 0) is for minios logging
    5.18 +         * STUBDOM_CONSOLE_SAVE (console 1) is for writing the save file
    5.19 +         * STUBDOM_CONSOLE_RESTORE (console 2) is for reading the save file
    5.20 +         */
    5.21 +        switch (i) {
    5.22              char *filename;
    5.23 -            char *name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
    5.24 -            libxl_create_logfile(ctx, name, &filename);
    5.25 -            console[i].output = libxl__sprintf(&gc, "file:%s", filename);
    5.26 -            console[i].build_state = &state;
    5.27 -            free(filename);
    5.28 -        } else
    5.29 -            console[i].output = "pty";
    5.30 +            char *name;
    5.31 +            case STUBDOM_CONSOLE_LOGGING:
    5.32 +                name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
    5.33 +                libxl_create_logfile(ctx, name, &filename);
    5.34 +                console[i].output = libxl__sprintf(&gc, "file:%s", filename);
    5.35 +                console[i].build_state = &state;
    5.36 +                free(filename);
    5.37 +                break;
    5.38 +            case STUBDOM_CONSOLE_SAVE:
    5.39 +                console[i].output = libxl__sprintf(&gc, "file:"SAVEFILE".%d", info->domid);
    5.40 +                break;
    5.41 +            case STUBDOM_CONSOLE_RESTORE:
    5.42 +                if (info->saved_state)
    5.43 +                    console[i].output = libxl__sprintf(&gc, "pipe:%s", info->saved_state);
    5.44 +                break;
    5.45 +            default:
    5.46 +                console[i].output = "pty";
    5.47 +                break;
    5.48 +        }
    5.49          ret = libxl_device_console_add(ctx, domid, &console[i]);
    5.50          if (ret)
    5.51              goto out_free;
     6.1 --- a/tools/libxl/libxl_internal.h	Fri Jan 21 18:03:18 2011 +0000
     6.2 +++ b/tools/libxl/libxl_internal.h	Fri Jan 21 18:06:23 2011 +0000
     6.3 @@ -45,6 +45,11 @@
     6.4  #define LIBXL_HVM_EXTRA_MEMORY 2048
     6.5  #define LIBXL_MIN_DOM0_MEM (128*1024)
     6.6  #define QEMU_SIGNATURE "DeviceModelRecord0002"
     6.7 +#define STUBDOM_CONSOLE_LOGGING 0
     6.8 +#define STUBDOM_CONSOLE_SAVE 1
     6.9 +#define STUBDOM_CONSOLE_RESTORE 2
    6.10 +#define STUBDOM_CONSOLE_SERIAL 3
    6.11 +#define STUBDOM_SPECIAL_CONSOLES 3
    6.12  #define SAVEFILE "/var/lib/xen/qemu-save"
    6.13  
    6.14  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))