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

📄 xc_ia64_linux_save.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    xc_dominfo_t info;    int rc = 1;    int debug = (flags & XCFLAGS_DEBUG);    int live  = (flags & XCFLAGS_LIVE);    /* The new domain's shared-info frame number. */    unsigned long shared_info_frame;    /* Live mapping of shared info structure */    shared_info_t *live_shinfo = NULL;    /* Iteration number.  */    int iter;    /* Number of pages sent in the last iteration (live only).  */    unsigned int sent_last_iter;    /* Number of pages sent (live only).  */    unsigned int total_sent;    /* total number of pages used by the current guest */    unsigned long p2m_size;    /* Size of the shadow bitmap (live only).  */    unsigned int bitmap_size = 0;    /* True if last iteration.  */    int last_iter;    /* Bitmap of pages to be sent.  */    unsigned long *to_send = NULL;    /* Bitmap of pages not to be sent (because dirtied).  */    unsigned long *to_skip = NULL;    char *mem;    /* HVM: shared-memory bitmaps for getting log-dirty bits from qemu-dm */    unsigned long *qemu_bitmaps[2];    int qemu_active = 0;    int qemu_non_active = 1;    /* for foreign p2m exposure */    unsigned int memmap_info_num_pages;    unsigned long memmap_size = 0;    xen_ia64_memmap_info_t *memmap_info_live = NULL;    xen_ia64_memmap_info_t *memmap_info = NULL;    void *memmap_desc_start;    void *memmap_desc_end;    void *p;    efi_memory_desc_t *md;    struct xen_ia64_p2m_table p2m_table;    xc_ia64_p2m_init(&p2m_table);    if (debug)        fprintf(stderr, "xc_linux_save (ia64): started dom=%d\n", dom);    /* If no explicit control parameters given, use defaults */    if (!max_iters)        max_iters = DEF_MAX_ITERS;    if (!max_factor)        max_factor = DEF_MAX_FACTOR;    //initialize_mbit_rate();    if (xc_domain_getinfo(xc_handle, dom, 1, &info) != 1) {        ERROR("Could not get domain info");        return 1;    }    shared_info_frame = info.shared_info_frame;#if 0    /* cheesy sanity check */    if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) {        ERROR("Invalid state record -- pfn count out of range: %lu",            (info.max_memkb >> (PAGE_SHIFT - 10)));        goto out;     }#endif    /* Map the shared info frame */    live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                                       PROT_READ, shared_info_frame);    if (!live_shinfo) {        ERROR("Couldn't map live_shinfo");        goto out;    }    p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1;    /* This is expected by xm restore.  */    if (write_exact(io_fd, &p2m_size, sizeof(unsigned long))) {        ERROR("write: p2m_size");        goto out;    }    /* xc_linux_restore starts to read here.  */    /* Write a version number.  This can avoid searching for a stupid bug       if the format change.       The version is hard-coded, don't forget to change the restore code       too!  */    {        unsigned long version = XC_IA64_SR_FORMAT_VER_CURRENT;        if (write_exact(io_fd, &version, sizeof(unsigned long))) {            ERROR("write: version");            goto out;        }    }    domctl.cmd = XEN_DOMCTL_arch_setup;    domctl.domain = (domid_t)dom;    domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query;    if (xc_domctl(xc_handle, &domctl) < 0) {        ERROR("Could not get domain setup");        goto out;    }    if (write_exact(io_fd, &domctl.u.arch_setup,                     sizeof(domctl.u.arch_setup))) {        ERROR("write: domain setup");        goto out;    }    /* Domain is still running at this point */    if (live) {        if (xc_shadow_control(xc_handle, dom,                              XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,                              NULL, 0, NULL, 0, NULL ) < 0) {            ERROR("Couldn't enable shadow mode");            goto out;        }        last_iter = 0;        bitmap_size = ((p2m_size + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;        to_send = malloc(bitmap_size);        to_skip = malloc(bitmap_size);        if (!to_send || !to_skip) {            ERROR("Couldn't allocate bitmap array");            goto out;        }        /* Initially all the pages must be sent.  */        memset(to_send, 0xff, bitmap_size);        if (lock_pages(to_send, bitmap_size)) {            ERROR("Unable to lock_pages to_send");            goto out;        }        if (lock_pages(to_skip, bitmap_size)) {            ERROR("Unable to lock_pages to_skip");            goto out;        }        if (hvm) {            /* Get qemu-dm logging dirty pages too */            void *seg = init_qemu_maps(dom, bitmap_size);            qemu_bitmaps[0] = seg;            qemu_bitmaps[1] = seg + bitmap_size;            qemu_active = 0;            qemu_non_active = 1;        }    } else {        /* This is a non-live suspend. Issue the call back to get the           domain suspended */        last_iter = 1;        if (suspend_and_state(suspend, xc_handle, io_fd, dom, &info)) {            ERROR("Domain appears not to have suspended");            goto out;        }    }    memmap_info_num_pages = live_shinfo->arch.memmap_info_num_pages;    memmap_size = PAGE_SIZE * memmap_info_num_pages;    memmap_info_live = xc_map_foreign_range(xc_handle, info.domid,                                       memmap_size, PROT_READ,                                            live_shinfo->arch.memmap_info_pfn);    if (memmap_info_live == NULL) {        PERROR("Could not map memmap info.");        goto out;    }    memmap_info = malloc(memmap_size);    if (memmap_info == NULL) {        PERROR("Could not allocate memmap info memory");        goto out;    }    memcpy(memmap_info, memmap_info_live, memmap_size);    munmap(memmap_info_live, memmap_size);    memmap_info_live = NULL;        if (xc_ia64_p2m_map(&p2m_table, xc_handle, dom, memmap_info, 0) < 0) {        PERROR("xc_ia64_p2m_map");        goto out;    }    if (write_exact(io_fd,                     &memmap_info_num_pages, sizeof(memmap_info_num_pages))) {        PERROR("write: arch.memmap_info_num_pages");        goto out;    }    if (write_exact(io_fd, memmap_info, memmap_size)) {        PERROR("write: memmap_info");        goto out;    }    sent_last_iter = p2m_size;    total_sent = 0;    for (iter = 1; ; iter++) {        unsigned int sent_this_iter, skip_this_iter;        unsigned long N;        sent_this_iter = 0;        skip_this_iter = 0;        /* Dirtied pages won't be saved.           slightly wasteful to peek the whole array evey time,           but this is fast enough for the moment. */        if (!last_iter) {            if (xc_shadow_control(xc_handle, dom,                                  XEN_DOMCTL_SHADOW_OP_PEEK,                                  to_skip, p2m_size,                                  NULL, 0, NULL) != p2m_size) {                ERROR("Error peeking shadow bitmap");                goto out;            }        }        /* Start writing out the saved-domain record. */        memmap_desc_start = &memmap_info->memdesc;        memmap_desc_end = memmap_desc_start + memmap_info->efi_memmap_size;        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))                    continue;                if (!last_iter) {                    if (test_bit(N, to_skip) && test_bit(N, to_send))                        skip_this_iter++;                    if (test_bit(N, to_skip) || !test_bit(N, to_send))                        continue;                } else if (live) {                    if (!test_bit(N, to_send))                        continue;                }                if (debug)                    fprintf(stderr, "xc_linux_save: page %lx (%lu/%lu)\n",                            xc_ia64_p2m_mfn(&p2m_table, N),                            N, p2m_size);                mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                                           PROT_READ|PROT_WRITE, N);                if (mem == NULL) {                    /* The page may have move.                       It will be remarked dirty.                       FIXME: to be tracked.  */                    fprintf(stderr, "cannot map mfn page %lx gpfn %lx: %s\n",                            xc_ia64_p2m_mfn(&p2m_table, N),                            N, safe_strerror(errno));                    continue;                }                if (write_exact(io_fd, &N, sizeof(N))) {                    ERROR("write: p2m_size");                    munmap(mem, PAGE_SIZE);                    goto out;                }                if (write(io_fd, mem, PAGE_SIZE) != PAGE_SIZE) {                    ERROR("Error when writing to state file (5)");                    munmap(mem, PAGE_SIZE);                    goto out;                }                munmap(mem, PAGE_SIZE);                sent_this_iter++;                total_sent++;            }        }        if (last_iter)            break;        DPRINTF(" %d: sent %d, skipped %d\n",                iter, sent_this_iter, skip_this_iter );        if (live) {            if ( /* ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) || */                (iter >= max_iters) || (sent_this_iter+skip_this_iter < 50) ||                (total_sent > p2m_size*max_factor)) {                DPRINTF("Start last iteration\n");                last_iter = 1;                if (suspend_and_state(suspend, xc_handle, io_fd, dom, &info)) {                    ERROR("Domain appears not to have suspended");                    goto out;                }            }            /* Pages to be sent are pages which were dirty.  */            if (xc_shadow_control(xc_handle, dom,                                  XEN_DOMCTL_SHADOW_OP_CLEAN,                                  to_send, p2m_size,                                  NULL, 0, NULL ) != p2m_size) {                ERROR("Error flushing shadow PT");                goto out;            }            if (hvm) {                unsigned int j;                /* Pull in the dirty bits from qemu-dm too */                if (!last_iter) {                    qemu_active = qemu_non_active;                    qemu_non_active = qemu_active ? 0 : 1;                    qemu_flip_buffer(dom, qemu_active);                    for (j = 0; j < bitmap_size / sizeof(unsigned long); j++) {                        to_send[j] |= qemu_bitmaps[qemu_non_active][j];                        qemu_bitmaps[qemu_non_active][j] = 0;                    }                } else {                    for (j = 0; j < bitmap_size / sizeof(unsigned long); j++)                        to_send[j] |= qemu_bitmaps[qemu_active][j];                }            }            sent_last_iter = sent_this_iter;            //print_stats(xc_handle, dom, sent_this_iter, &stats, 1);        }    }    fprintf(stderr, "All memory is saved\n");    /* terminate */    {        unsigned long pfn = INVALID_MFN;        if (write_exact(io_fd, &pfn, sizeof(pfn))) {            ERROR("Error when writing to state file (6)");            goto out;        }    }    if (xc_ia64_send_unallocated_list(xc_handle, io_fd, &p2m_table,                                      memmap_info,                                      memmap_desc_start, memmap_desc_end))        goto out;    if (!hvm)        rc = xc_ia64_pv_send_context(xc_handle, io_fd,                                     dom, &info, live_shinfo);    else        rc = xc_ia64_hvm_send_context(xc_handle, io_fd,                                      dom, &info, live_shinfo);    if (rc)        goto out;    /* Success! */    rc = 0; out:    if (live) {        if (xc_shadow_control(xc_handle, dom,                              XEN_DOMCTL_SHADOW_OP_OFF,                              NULL, 0, NULL, 0, NULL ) < 0) {            DPRINTF("Warning - couldn't disable shadow mode");        }    }    unlock_pages(to_send, bitmap_size);    free(to_send);    unlock_pages(to_skip, bitmap_size);    free(to_skip);    if (live_shinfo)        munmap(live_shinfo, PAGE_SIZE);    if (memmap_info_live)        munmap(memmap_info_live, memmap_size);    if (memmap_info)        free(memmap_info);    xc_ia64_p2m_unmap(&p2m_table);    fprintf(stderr,"Save exit rc=%d\n",rc);    return !!rc;}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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