#include #include #include #include #include #include //#include #include #include #include int main(int argc, char **argv) { xentoollog_logger *logger; xc_interface *xch; int rv; const char *image; uint32_t domid = 1; xen_domain_handle_t handle; int maxmem = 128; /* MB */ //atoi(argv[2]); int memory_kb = 2*(maxmem + 1)*1024; /* bit of slack... */ struct xc_dom_image *dom; unsigned long console_mfn; unsigned long console_port; unsigned long store_mfn; unsigned long store_port; struct xs_handle *xs; char *dom_path; char path[256]; char val[256]; xs_transaction_t t; struct xs_permissions frontend_perms[2]; struct xs_permissions backend_perms[2]; image = (argc < 2) ? "guest.img" : argv[1]; printf("Image: %s\n", image); printf("Memory: %dKB\n", memory_kb); logger = (xentoollog_logger*) xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0); if ( logger == NULL ) { perror("xtl_createlogger_stdiostream"); exit(1); } xch = xc_interface_open(logger, logger, 0); if ( xch == NULL ) { perror("xc_interface_open"); exit(1); } rv = xc_dom_loginit(xch); if (rv) return rv; //rv = xc_flask_context_to_sid(xch, argv[3], strlen(argv[3]), &ssid); //if (rv) return rv; rv = xc_domain_create(xch, 0 /* ssid */, handle, 0 /* flags */, &domid); printf("xc_domain_create: %d (%d)\n", rv, errno); if ( rv < 0 ) { perror("xc_domain_create"); exit(1); } printf("building dom%d\n", domid); rv = xc_domain_max_vcpus(xch, domid, 1); if ( rv < 0) { perror("xc_domain_max_vcpus"); exit(1); } //rc = xc_domain_setmaxmem(xch, domid, 2*memory_kb); /* 2x == overheads... */ rv = xc_domain_setmaxmem(xch, domid, memory_kb); if ( rv < 0) { perror("xc_domain_setmaxmem"); exit(1); } #if USE_HVM_BUILD printf("using xc_hvm_build to build image %s\n", image); hvm_args.image_file_name = image; hvm_args.mem_size = hvm_args.mem_target = memory_kb << 10 /* bytes */; rv = xc_hvm_build(xch, domid, &hvm_args); printf("xc_hvm_build: %d (%d)\n", rc, errno); if ( rv < 0 ) { perror("xc_hvm_build"); exit(1); } #else printf("using xc_dom to build image %s\n", image); #if 0 /* X86 specific... */ rv = xc_domain_set_memmap_limit(xch, domid, memory_kb); if (rv) return rv; #endif dom = xc_dom_allocate(xch, "", NULL); rv = xc_dom_kernel_file(dom, image); if (rv) return rv; rv = xc_dom_boot_xen_init(dom, xch, domid); if (rv) return rv; rv = xc_dom_parse_image(dom); if (rv) return rv; rv = xc_dom_mem_init(dom, 2*maxmem);/* XXX */ if (rv) return rv; rv = xc_dom_boot_mem_init(dom); if (rv) return rv; rv = xc_dom_build_image(dom); if (rv) return rv; xc_get_hvm_param(xch, domid, HVM_PARAM_CONSOLE_PFN, &console_mfn); console_port = xc_evtchn_alloc_unbound(xch, domid, 0); xc_set_hvm_param(xch, domid, HVM_PARAM_CONSOLE_EVTCHN, console_port); xc_get_hvm_param(xch, domid, HVM_PARAM_STORE_PFN, &store_mfn); store_port = xc_evtchn_alloc_unbound(xch, domid, 0); xc_set_hvm_param(xch, domid, HVM_PARAM_STORE_EVTCHN, store_port); xs = xs_daemon_open(); if (xs == NULL) { printf("Could not contact XenStore"); return errno; } dom_path = xs_get_domain_path(xs, domid); snprintf(path, sizeof(path), "%s/console/port", dom_path); snprintf(val, sizeof(val), "%lu", console_port); xs_write(xs, XBT_NULL, path, val, strlen(val)); snprintf(path, sizeof(path), "%s/console/ring-ref", dom_path); snprintf(val, sizeof(val), "%lu", console_mfn); xs_write(xs, XBT_NULL, path, val, strlen(val)); snprintf(path, sizeof(path), "%s/console/type", dom_path); snprintf(val, sizeof(val), "xenconsoled"); xs_write(xs, XBT_NULL, path, val, strlen(val)); snprintf(path, sizeof(path), "%s/console/output", dom_path); snprintf(val, sizeof(val), "pty"); xs_write(xs, XBT_NULL, path, val, strlen(val)); snprintf(path, sizeof(path), "%s/console/limit", dom_path); snprintf(val, sizeof(val), "%d", 1048576); xs_write(xs, XBT_NULL, path, val, strlen(val)); snprintf(path, sizeof(path), "%s/store/port", dom_path); snprintf(val, sizeof(val), "%lu", store_port); xs_write(xs, XBT_NULL, path, val, strlen(val)); snprintf(path, sizeof(path), "%s/store/ring-ref", dom_path); snprintf(val, sizeof(val), "%lu", store_mfn); xs_write(xs, XBT_NULL, path, val, strlen(val)); xs_introduce_domain(xs, domid, store_mfn, store_port); retry_transaction: t = xs_transaction_start(xs); frontend_perms[0].id = domid; frontend_perms[0].perms = XS_PERM_NONE; frontend_perms[1].id = 0; frontend_perms[1].perms = XS_PERM_READ; snprintf(path, sizeof(path), "/local/domain/%d/device/vbd/%d", domid, 51712); xs_mkdir(xs, t, path); xs_set_permissions(xs, t, path, frontend_perms, 2); snprintf(path, sizeof(path), "/local/domain/%d/device/vbd", domid); xs_set_permissions(xs, t, path, frontend_perms, 2); snprintf(path, sizeof(path), "/local/domain/%d/device", domid); xs_set_permissions(xs, t, path, frontend_perms, 2); snprintf(path, sizeof(path), "/local/domain/%d/device/vif/%d", domid, 0); xs_mkdir(xs, t, path); xs_set_permissions(xs, t, path, frontend_perms, 2); snprintf(path, sizeof(path), "/local/domain/%d/device/vif", domid); xs_set_permissions(xs, t, path, frontend_perms, 2); snprintf(path, sizeof(path), "/local/domain/%d/device", domid); xs_set_permissions(xs, t, path, frontend_perms, 2); backend_perms[0].id = 0; backend_perms[0].perms = XS_PERM_NONE; backend_perms[1].id = domid; backend_perms[1].perms = XS_PERM_READ; snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d", domid, 51712); xs_mkdir(xs, t, path); xs_set_permissions(xs, t, path, backend_perms, 2); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d", domid, 0); xs_mkdir(xs, t, path); xs_set_permissions(xs, t, path, backend_perms, 2); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/frontend", domid, 51712); snprintf(val, sizeof(val), "/local/domain/%d/device/vbd/%d", domid, 51712); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/physical-device", domid, 51712); snprintf(val, sizeof(val), "7:0"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/params", domid, 51712); snprintf(val, sizeof(val), "/dev/loop0"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/frontend-id", domid, 51712); snprintf(val, sizeof(val), "%d", domid); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/online", domid, 51712); snprintf(val, sizeof(val), "1"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/removable", domid, 51712); snprintf(val, sizeof(val), "0"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/bootable", domid, 51712); snprintf(val, sizeof(val), "1"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/state", domid, 51712); snprintf(val, sizeof(val), "1"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/dev", domid, 51712); snprintf(val, sizeof(val), "xvda"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/type", domid, 51712); snprintf(val, sizeof(val), "phy"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/mode", domid, 51712); snprintf(val, sizeof(val), "w"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vbd/%d/%d/device-type", domid, 51712); snprintf(val, sizeof(val), "disk"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vbd/%d/backend", domid, 51712); snprintf(val, sizeof(val), "/local/domain/0/backend/vbd/%d/%d", domid, 51712); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vbd/%d/backend-id", domid, 51712); snprintf(val, sizeof(val), "%d", 0); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vbd/%d/state", domid, 51712); snprintf(val, sizeof(val), "%d", 1); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vbd/%d/virtual-device", domid, 51712); snprintf(val, sizeof(val), "%d", 51712); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vbd/%d/device-type", domid, 51712); snprintf(val, sizeof(val), "disk"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/0/frontend", domid); snprintf(val, sizeof(val), "/local/domain/%d/device/vif/0", domid); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/0/frontend-id", domid); snprintf(val, sizeof(val), "%d", domid); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d/online", domid, 0); snprintf(val, sizeof(val), "1"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d/state", domid, 0); snprintf(val, sizeof(val), "1"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d/mac", domid, 0); snprintf(val, sizeof(val), "00:16:3e:4f:c8:25"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d/bridge", domid, 0); snprintf(val, sizeof(val), "xenbr0"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d/handle", domid, 0); snprintf(val, sizeof(val), "0"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/0/backend/vif/%d/%d/script", domid, 0); snprintf(val, sizeof(val), "/vif-setup"); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vif/%d/backend", domid, 0); snprintf(val, sizeof(val), "/local/domain/0/backend/vif/%d/%d", domid, 0); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vif/%d/backend-id", domid, 0); snprintf(val, sizeof(val), "%d", 0); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vif/%d/state", domid, 0); snprintf(val, sizeof(val), "%d", 1); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vif/%d/handle", domid, 0); snprintf(val, sizeof(val), "%d", 0); xs_write(xs, t, path, val, strlen(val)); snprintf(path, sizeof(path), "/local/domain/%d/device/vif/%d/mac", domid, 0); snprintf(val, sizeof(val), "00:16:3e:4f:c8:25"); xs_write(xs, t, path, val, strlen(val)); if (!xs_transaction_end(xs, t, 0)) { if (errno == EAGAIN) goto retry_transaction; else printf("Failed transaction\n"); } xs_daemon_close(xs); rv = xc_dom_boot_image(dom); if (rv) return rv; xc_dom_release(dom); #endif rv = xc_domain_unpause(xch, domid); if ( rv ) { perror("xc_domain_unpause"); exit(1); } xc_interface_close(xch); return 0; }