|
|
1.1 ! root 1: #include <signal.h> ! 2: #include "xen_backend.h" ! 3: #include "xen_domainbuild.h" ! 4: #include "sysemu.h" ! 5: #include "qemu-timer.h" ! 6: ! 7: #include <xenguest.h> ! 8: ! 9: static int xenstore_domain_mkdir(char *path) ! 10: { ! 11: struct xs_permissions perms_ro[] = {{ ! 12: .id = 0, /* set owner: dom0 */ ! 13: },{ ! 14: .id = xen_domid, ! 15: .perms = XS_PERM_READ, ! 16: }}; ! 17: struct xs_permissions perms_rw[] = {{ ! 18: .id = 0, /* set owner: dom0 */ ! 19: },{ ! 20: .id = xen_domid, ! 21: .perms = XS_PERM_READ | XS_PERM_WRITE, ! 22: }}; ! 23: const char *writable[] = { "device", "control", "error", NULL }; ! 24: char subpath[256]; ! 25: int i; ! 26: ! 27: if (!xs_mkdir(xenstore, 0, path)) { ! 28: fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, path); ! 29: return -1; ! 30: } ! 31: if (!xs_set_permissions(xenstore, 0, path, perms_ro, 2)) { ! 32: fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__); ! 33: return -1; ! 34: } ! 35: ! 36: for (i = 0; writable[i]; i++) { ! 37: snprintf(subpath, sizeof(subpath), "%s/%s", path, writable[i]); ! 38: if (!xs_mkdir(xenstore, 0, subpath)) { ! 39: fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, subpath); ! 40: return -1; ! 41: } ! 42: if (!xs_set_permissions(xenstore, 0, subpath, perms_rw, 2)) { ! 43: fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__); ! 44: return -1; ! 45: } ! 46: } ! 47: return 0; ! 48: } ! 49: ! 50: int xenstore_domain_init1(const char *kernel, const char *ramdisk, ! 51: const char *cmdline) ! 52: { ! 53: char *dom, uuid_string[42], vm[256], path[256]; ! 54: int i; ! 55: ! 56: snprintf(uuid_string, sizeof(uuid_string), UUID_FMT, ! 57: qemu_uuid[0], qemu_uuid[1], qemu_uuid[2], qemu_uuid[3], ! 58: qemu_uuid[4], qemu_uuid[5], qemu_uuid[6], qemu_uuid[7], ! 59: qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], qemu_uuid[11], ! 60: qemu_uuid[12], qemu_uuid[13], qemu_uuid[14], qemu_uuid[15]); ! 61: dom = xs_get_domain_path(xenstore, xen_domid); ! 62: snprintf(vm, sizeof(vm), "/vm/%s", uuid_string); ! 63: ! 64: xenstore_domain_mkdir(dom); ! 65: ! 66: xenstore_write_str(vm, "image/ostype", "linux"); ! 67: if (kernel) ! 68: xenstore_write_str(vm, "image/kernel", kernel); ! 69: if (ramdisk) ! 70: xenstore_write_str(vm, "image/ramdisk", ramdisk); ! 71: if (cmdline) ! 72: xenstore_write_str(vm, "image/cmdline", cmdline); ! 73: ! 74: /* name + id */ ! 75: xenstore_write_str(vm, "name", qemu_name ? qemu_name : "no-name"); ! 76: xenstore_write_str(vm, "uuid", uuid_string); ! 77: xenstore_write_str(dom, "name", qemu_name ? qemu_name : "no-name"); ! 78: xenstore_write_int(dom, "domid", xen_domid); ! 79: xenstore_write_str(dom, "vm", vm); ! 80: ! 81: /* memory */ ! 82: xenstore_write_int(dom, "memory/target", ram_size >> 10); // kB ! 83: xenstore_write_int(vm, "memory", ram_size >> 20); // MB ! 84: xenstore_write_int(vm, "maxmem", ram_size >> 20); // MB ! 85: ! 86: /* cpus */ ! 87: for (i = 0; i < smp_cpus; i++) { ! 88: snprintf(path, sizeof(path), "cpu/%d/availability",i); ! 89: xenstore_write_str(dom, path, "online"); ! 90: } ! 91: xenstore_write_int(vm, "vcpu_avail", smp_cpus); ! 92: xenstore_write_int(vm, "vcpus", smp_cpus); ! 93: ! 94: /* vnc password */ ! 95: xenstore_write_str(vm, "vncpassword", "" /* FIXME */); ! 96: ! 97: free(dom); ! 98: return 0; ! 99: } ! 100: ! 101: int xenstore_domain_init2(int xenstore_port, int xenstore_mfn, ! 102: int console_port, int console_mfn) ! 103: { ! 104: char *dom; ! 105: ! 106: dom = xs_get_domain_path(xenstore, xen_domid); ! 107: ! 108: /* signal new domain */ ! 109: xs_introduce_domain(xenstore, ! 110: xen_domid, ! 111: xenstore_mfn, ! 112: xenstore_port); ! 113: ! 114: /* xenstore */ ! 115: xenstore_write_int(dom, "store/ring-ref", xenstore_mfn); ! 116: xenstore_write_int(dom, "store/port", xenstore_port); ! 117: ! 118: /* console */ ! 119: xenstore_write_str(dom, "console/type", "ioemu"); ! 120: xenstore_write_int(dom, "console/limit", 128 * 1024); ! 121: xenstore_write_int(dom, "console/ring-ref", console_mfn); ! 122: xenstore_write_int(dom, "console/port", console_port); ! 123: xen_config_dev_console(0); ! 124: ! 125: free(dom); ! 126: return 0; ! 127: } ! 128: ! 129: /* ------------------------------------------------------------- */ ! 130: ! 131: static QEMUTimer *xen_poll; ! 132: ! 133: /* check domain state once per second */ ! 134: static void xen_domain_poll(void *opaque) ! 135: { ! 136: struct xc_dominfo info; ! 137: int rc; ! 138: ! 139: rc = xc_domain_getinfo(xen_xc, xen_domid, 1, &info); ! 140: if ((rc != 1) || (info.domid != xen_domid)) { ! 141: qemu_log("xen: domain %d is gone\n", xen_domid); ! 142: goto quit; ! 143: } ! 144: if (info.dying) { ! 145: qemu_log("xen: domain %d is dying (%s%s)\n", xen_domid, ! 146: info.crashed ? "crashed" : "", ! 147: info.shutdown ? "shutdown" : ""); ! 148: goto quit; ! 149: } ! 150: ! 151: qemu_mod_timer(xen_poll, qemu_get_clock(rt_clock) + 1000); ! 152: return; ! 153: ! 154: quit: ! 155: qemu_system_shutdown_request(); ! 156: return; ! 157: } ! 158: ! 159: static void xen_domain_watcher(void) ! 160: { ! 161: int qemu_running = 1; ! 162: int fd[2], i, n, rc; ! 163: char byte; ! 164: ! 165: pipe(fd); ! 166: if (fork() != 0) ! 167: return; /* not child */ ! 168: ! 169: /* close all file handles, except stdio/out/err, ! 170: * our watch pipe and the xen interface handle */ ! 171: n = getdtablesize(); ! 172: for (i = 3; i < n; i++) { ! 173: if (i == fd[0]) ! 174: continue; ! 175: if (i == xen_xc) ! 176: continue; ! 177: close(i); ! 178: } ! 179: ! 180: /* ignore term signals */ ! 181: signal(SIGINT, SIG_IGN); ! 182: signal(SIGTERM, SIG_IGN); ! 183: ! 184: /* wait for qemu exiting */ ! 185: while (qemu_running) { ! 186: rc = read(fd[0], &byte, 1); ! 187: switch (rc) { ! 188: case -1: ! 189: if (errno == EINTR) ! 190: continue; ! 191: qemu_log("%s: Huh? read error: %s\n", __FUNCTION__, strerror(errno)); ! 192: qemu_running = 0; ! 193: break; ! 194: case 0: ! 195: /* EOF -> qemu exited */ ! 196: qemu_running = 0; ! 197: break; ! 198: default: ! 199: qemu_log("%s: Huh? data on the watch pipe?\n", __FUNCTION__); ! 200: break; ! 201: } ! 202: } ! 203: ! 204: /* cleanup */ ! 205: qemu_log("%s: destroy domain %d\n", __FUNCTION__, xen_domid); ! 206: xc_domain_destroy(xen_xc, xen_domid); ! 207: _exit(0); ! 208: } ! 209: ! 210: /* normal cleanup */ ! 211: static void xen_domain_cleanup(void) ! 212: { ! 213: char *dom; ! 214: ! 215: dom = xs_get_domain_path(xenstore, xen_domid); ! 216: if (dom) { ! 217: xs_rm(xenstore, 0, dom); ! 218: free(dom); ! 219: } ! 220: xs_release_domain(xenstore, xen_domid); ! 221: } ! 222: ! 223: int xen_domain_build_pv(const char *kernel, const char *ramdisk, ! 224: const char *cmdline) ! 225: { ! 226: uint32_t ssidref = 0; ! 227: uint32_t flags = 0; ! 228: xen_domain_handle_t uuid; ! 229: unsigned int xenstore_port = 0, console_port = 0; ! 230: unsigned long xenstore_mfn = 0, console_mfn = 0; ! 231: int rc; ! 232: ! 233: memcpy(uuid, qemu_uuid, sizeof(uuid)); ! 234: rc = xc_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid); ! 235: if (rc < 0) { ! 236: fprintf(stderr, "xen: xc_domain_create() failed\n"); ! 237: goto err; ! 238: } ! 239: qemu_log("xen: created domain %d\n", xen_domid); ! 240: atexit(xen_domain_cleanup); ! 241: xen_domain_watcher(); ! 242: ! 243: xenstore_domain_init1(kernel, ramdisk, cmdline); ! 244: ! 245: rc = xc_domain_max_vcpus(xen_xc, xen_domid, smp_cpus); ! 246: if (rc < 0) { ! 247: fprintf(stderr, "xen: xc_domain_max_vcpus() failed\n"); ! 248: goto err; ! 249: } ! 250: ! 251: #if 0 ! 252: rc = xc_domain_setcpuweight(xen_xc, xen_domid, 256); ! 253: if (rc < 0) { ! 254: fprintf(stderr, "xen: xc_domain_setcpuweight() failed\n"); ! 255: goto err; ! 256: } ! 257: #endif ! 258: ! 259: rc = xc_domain_setmaxmem(xen_xc, xen_domid, ram_size >> 10); ! 260: if (rc < 0) { ! 261: fprintf(stderr, "xen: xc_domain_setmaxmem() failed\n"); ! 262: goto err; ! 263: } ! 264: ! 265: xenstore_port = xc_evtchn_alloc_unbound(xen_xc, xen_domid, 0); ! 266: console_port = xc_evtchn_alloc_unbound(xen_xc, xen_domid, 0); ! 267: ! 268: rc = xc_linux_build(xen_xc, xen_domid, ram_size >> 20, ! 269: kernel, ramdisk, cmdline, ! 270: 0, flags, ! 271: xenstore_port, &xenstore_mfn, ! 272: console_port, &console_mfn); ! 273: if (rc < 0) { ! 274: fprintf(stderr, "xen: xc_linux_build() failed\n"); ! 275: goto err; ! 276: } ! 277: ! 278: xenstore_domain_init2(xenstore_port, xenstore_mfn, ! 279: console_port, console_mfn); ! 280: ! 281: qemu_log("xen: unpausing domain %d\n", xen_domid); ! 282: rc = xc_domain_unpause(xen_xc, xen_domid); ! 283: if (rc < 0) { ! 284: fprintf(stderr, "xen: xc_domain_unpause() failed\n"); ! 285: goto err; ! 286: } ! 287: ! 288: xen_poll = qemu_new_timer(rt_clock, xen_domain_poll, NULL); ! 289: qemu_mod_timer(xen_poll, qemu_get_clock(rt_clock) + 1000); ! 290: return 0; ! 291: ! 292: err: ! 293: return -1; ! 294: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.