⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xc_ia64_linux_save.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * xc_ia64_linux_save.c * * Save the state of a running Linux session. * * Copyright (c) 2003, K A Fraser. *  Rewritten for ia64 by Tristan Gingold <tristan.gingold@bull.net> * * Copyright (c) 2007 Isaku Yamahata <yamahata@valinux.co.jp> *   Use foreign p2m exposure. *   VTi domain support. */#include <inttypes.h>#include <time.h>#include <stdlib.h>#include <unistd.h>#include <sys/time.h>#include "xg_private.h"#include "xc_ia64.h"#include "xc_ia64_save_restore.h"#include "xc_efi.h"#include "xen/hvm/params.h"/*** Default values for important tuning parameters. Can override by passing** non-zero replacement values to xc_linux_save().**** XXX SMH: should consider if want to be able to override MAX_MBIT_RATE too.***/#define DEF_MAX_ITERS    (4 - 1)        /* limit us to 4 times round loop  */#define DEF_MAX_FACTOR   3              /* never send more than 3x nr_pfns *//*** During (live) save/migrate, we maintain a number of bitmaps to track** which pages we have to send, and to skip.*/static inline int test_bit(int nr, volatile void * addr){    return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;}static inline void clear_bit(int nr, volatile void * addr){    BITMAP_ENTRY(nr, addr) &= ~(1UL << BITMAP_SHIFT(nr));}static inline void set_bit(int nr, volatile void * addr){    BITMAP_ENTRY(nr, addr) |= (1UL << BITMAP_SHIFT(nr));}static intsuspend_and_state(int (*suspend)(int), int xc_handle, int io_fd,                  int dom, xc_dominfo_t *info){    int i = 0;    if (!(*suspend)(dom)) {        ERROR("Suspend request failed");        return -1;    }retry:    if (xc_domain_getinfo(xc_handle, dom, 1, info) != 1) {        ERROR("Could not get domain info");        return -1;    }    if (info->shutdown && info->shutdown_reason == SHUTDOWN_suspend)        return 0; // success    if (info->paused) {        // try unpausing domain, wait, and retest        xc_domain_unpause(xc_handle, dom);        ERROR("Domain was paused. Wait and re-test.");        usleep(10000);  // 10ms        goto retry;    }    if(++i < 100) {        ERROR("Retry suspend domain.");        usleep(10000);  // 10ms        goto retry;    }    ERROR("Unable to suspend domain.");    return -1;}static inline intmd_is_not_ram(const efi_memory_desc_t *md){    return ((md->type != EFI_CONVENTIONAL_MEMORY) ||            (md->attribute != EFI_MEMORY_WB) ||            (md->num_pages == 0));}/* * Send through a list of all the PFNs that were not in map at the close. * We send pages which was allocated. However balloon driver may  * decreased after sending page. So we have to check the freed * page after pausing the domain. */static intxc_ia64_send_unallocated_list(int xc_handle, int io_fd,                               struct xen_ia64_p2m_table *p2m_table,                              xen_ia64_memmap_info_t *memmap_info,                               void *memmap_desc_start, void *memmap_desc_end){    void *p;    efi_memory_desc_t *md;    unsigned long N;    unsigned long pfntab[1024];    unsigned int j;    j = 0;    for (p = memmap_desc_start;         p < memmap_desc_end;         p += memmap_info->efi_memdesc_size) {        md = p;        if (md_is_not_ram(md))            continue;        for (N = md->phys_addr >> PAGE_SHIFT;             N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >>                 PAGE_SHIFT;             N++) {            if (!xc_ia64_p2m_allocated(p2m_table, N))                j++;        }    }    if (write_exact(io_fd, &j, sizeof(unsigned int))) {        ERROR("Error when writing to state file (6a)");        return -1;    }            j = 0;    for (p = memmap_desc_start;         p < memmap_desc_end;         p += memmap_info->efi_memdesc_size) {        md = p;        if (md_is_not_ram(md))            continue;        for (N = md->phys_addr >> PAGE_SHIFT;             N < (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >>                 PAGE_SHIFT;             N++) {            if (!xc_ia64_p2m_allocated(p2m_table, N))                pfntab[j++] = N;            if (j == sizeof(pfntab)/sizeof(pfntab[0])) {                if (write_exact(io_fd, &pfntab, sizeof(pfntab[0]) * j)) {                    ERROR("Error when writing to state file (6b)");                    return -1;                }                j = 0;            }        }    }    if (j > 0) {        if (write_exact(io_fd, &pfntab, sizeof(pfntab[0]) * j)) {            ERROR("Error when writing to state file (6c)");            return -1;        }    }    return 0;}static intxc_ia64_send_vcpu_context(int xc_handle, int io_fd, uint32_t dom,                          uint32_t vcpu, vcpu_guest_context_any_t *ctxt_any){    vcpu_guest_context_t *ctxt = &ctxt_any->c;    if (xc_vcpu_getcontext(xc_handle, dom, vcpu, ctxt_any)) {        ERROR("Could not get vcpu context");        return -1;    }    if (write_exact(io_fd, ctxt, sizeof(*ctxt))) {        ERROR("Error when writing to state file (1)");        return -1;    }    fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]);    return 0;}static intxc_ia64_send_shared_info(int xc_handle, int io_fd, shared_info_t *live_shinfo){    if (write_exact(io_fd, live_shinfo, PAGE_SIZE)) {        ERROR("Error when writing to state file (1)");        return -1;    }    return 0;}static intxc_ia64_send_vcpumap(int xc_handle, int io_fd, uint32_t dom,                     const xc_dominfo_t *info, uint64_t max_virt_cpus,                     uint64_t **vcpumapp){    int rc = -1;    unsigned int i;    unsigned long vcpumap_size;    uint64_t *vcpumap = NULL;    vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) /        sizeof(vcpumap[0]);    vcpumap = malloc(vcpumap_size);    if (vcpumap == NULL) {        ERROR("memory alloc for vcpumap");        goto out;    }    memset(vcpumap, 0, vcpumap_size);    for (i = 0; i <= info->max_vcpu_id; i++) {        xc_vcpuinfo_t vinfo;        if ((xc_vcpu_getinfo(xc_handle, dom, i, &vinfo) == 0) && vinfo.online)            __set_bit(i, vcpumap);    }    if (write_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {        ERROR("write max_virt_cpus");        goto out;    }    if (write_exact(io_fd, vcpumap, vcpumap_size)) {        ERROR("write vcpumap");        goto out;    }    rc = 0; out:    if (rc != 0 && vcpumap != NULL) {        free(vcpumap);        vcpumap = NULL;    }    *vcpumapp = vcpumap;    return rc;}static intxc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t dom,                        const xc_dominfo_t *info, shared_info_t *live_shinfo){    int rc = -1;    unsigned int i;    /* vcpu map */    uint64_t *vcpumap = NULL;    if (xc_ia64_send_vcpumap(xc_handle, io_fd, dom, info, MAX_VIRT_CPUS,                             &vcpumap))        goto out;    /* vcpu context */    for (i = 0; i <= info->max_vcpu_id; i++) {        /* A copy of the CPU context of the guest. */        vcpu_guest_context_any_t ctxt_any;        vcpu_guest_context_t *ctxt = &ctxt_any.c;        char *mem;        if (!__test_bit(i, vcpumap))            continue;        if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt_any))            goto out;        mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                                   PROT_READ|PROT_WRITE, ctxt->privregs_pfn);        if (mem == NULL) {            ERROR("cannot map privreg page");            goto out;        }        if (write_exact(io_fd, mem, PAGE_SIZE)) {            ERROR("Error when writing privreg to state file (5)");            munmap(mem, PAGE_SIZE);            goto out;        }        munmap(mem, PAGE_SIZE);    }        rc = xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo); out:    if (vcpumap != NULL)        free(vcpumap);    return rc;}static intxc_ia64_hvm_send_context(int xc_handle, int io_fd, uint32_t dom,                         const xc_dominfo_t *info, shared_info_t *live_shinfo){    int rc = -1;    unsigned int i;    /* vcpu map */    uint64_t *vcpumap = NULL;    /* HVM: magic frames for ioreqs and xenstore comms */    const int hvm_params[] = {        HVM_PARAM_STORE_PFN,        HVM_PARAM_IOREQ_PFN,        HVM_PARAM_BUFIOREQ_PFN,        HVM_PARAM_BUFPIOREQ_PFN,    };    const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]);    /* ioreq_pfn, bufioreq_pfn, store_pfn */    uint64_t magic_pfns[NR_PARAMS];    /* HVM: a buffer for holding HVM contxt */    uint64_t rec_size;    uint64_t hvm_buf_size = 0;    uint8_t *hvm_buf = NULL;    if (xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo))        return -1;    /* vcpu map */    if (xc_ia64_send_vcpumap(xc_handle, io_fd, dom, info, MAX_VIRT_CPUS,                             &vcpumap))        goto out;    /* vcpu context */    for (i = 0; i <= info->max_vcpu_id; i++) {        /* A copy of the CPU context of the guest. */        vcpu_guest_context_any_t ctxt_any;        if (!__test_bit(i, vcpumap))            continue;        if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt_any))            goto out;        /* system context of vcpu is sent as hvm context. */    }        /* Save magic-page locations. */    memset(magic_pfns, 0, sizeof(magic_pfns));    for (i = 0; i < NR_PARAMS; i++) {        if (xc_get_hvm_param(xc_handle, dom, hvm_params[i], &magic_pfns[i])) {            PERROR("Error when xc_get_hvm_param");            goto out;        }    }    if (write_exact(io_fd, magic_pfns, sizeof(magic_pfns))) {        ERROR("Error when writing to state file (7)");        goto out;    }    /* Need another buffer for HVM context */    hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);    if (hvm_buf_size == -1) {        ERROR("Couldn't get HVM context size from Xen");        goto out;    }    hvm_buf = malloc(hvm_buf_size);    if (!hvm_buf) {        ERROR("Couldn't allocate memory");        goto out;    }    /* Get HVM context from Xen and save it too */    rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, hvm_buf_size);    if (rec_size == -1) {        ERROR("HVM:Could not get hvm buffer");        goto out;    }            if (write_exact(io_fd, &rec_size, sizeof(rec_size))) {        ERROR("error write hvm buffer size");        goto out;    }            if (write_exact(io_fd, hvm_buf, rec_size)) {        ERROR("write HVM info failed!\n");        goto out;    }    rc = 0;out:    if (hvm_buf != NULL)        free(hvm_buf);    if (vcpumap != NULL)        free(vcpumap);    return rc;}intxc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,               uint32_t max_factor, uint32_t flags, int (*suspend)(int),               int hvm, void *(*init_qemu_maps)(int, unsigned),               void (*qemu_flip_buffer)(int, int)){    DECLARE_DOMCTL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -