Annotation of qemu/hw/xen_domainbuild.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.