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

1.1       root        1: #include <signal.h>
                      2: #include "xen_backend.h"
                      3: #include "xen_domainbuild.h"
                      4: #include "qemu-timer.h"
1.1.1.2   root        5: #include "qemu-log.h"
1.1       root        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: 
1.1.1.3 ! root      151:     qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000);
1.1       root      152:     return;
                    153: 
                    154: quit:
                    155:     qemu_system_shutdown_request();
                    156:     return;
                    157: }
                    158: 
1.1.1.2   root      159: static int xen_domain_watcher(void)
1.1       root      160: {
                    161:     int qemu_running = 1;
                    162:     int fd[2], i, n, rc;
                    163:     char byte;
                    164: 
1.1.1.2   root      165:     if (pipe(fd) != 0) {
                    166:         qemu_log("%s: Huh? pipe error: %s\n", __FUNCTION__, strerror(errno));
                    167:         return -1;
                    168:     }
1.1       root      169:     if (fork() != 0)
1.1.1.2   root      170:         return 0; /* not child */
1.1       root      171: 
                    172:     /* close all file handles, except stdio/out/err,
                    173:      * our watch pipe and the xen interface handle */
                    174:     n = getdtablesize();
                    175:     for (i = 3; i < n; i++) {
                    176:         if (i == fd[0])
                    177:             continue;
1.1.1.3 ! root      178:         if (i == xc_fd(xen_xc)) {
1.1       root      179:             continue;
1.1.1.3 ! root      180:         }
1.1       root      181:         close(i);
                    182:     }
                    183: 
                    184:     /* ignore term signals */
                    185:     signal(SIGINT,  SIG_IGN);
                    186:     signal(SIGTERM, SIG_IGN);
                    187: 
                    188:     /* wait for qemu exiting */
                    189:     while (qemu_running) {
                    190:         rc = read(fd[0], &byte, 1);
                    191:         switch (rc) {
                    192:         case -1:
                    193:             if (errno == EINTR)
                    194:                 continue;
                    195:             qemu_log("%s: Huh? read error: %s\n", __FUNCTION__, strerror(errno));
                    196:             qemu_running = 0;
                    197:             break;
                    198:         case 0:
                    199:             /* EOF -> qemu exited */
                    200:             qemu_running = 0;
                    201:             break;
                    202:         default:
                    203:             qemu_log("%s: Huh? data on the watch pipe?\n", __FUNCTION__);
                    204:             break;
                    205:         }
                    206:     }
                    207: 
                    208:     /* cleanup */
                    209:     qemu_log("%s: destroy domain %d\n", __FUNCTION__, xen_domid);
                    210:     xc_domain_destroy(xen_xc, xen_domid);
                    211:     _exit(0);
                    212: }
                    213: 
                    214: /* normal cleanup */
                    215: static void xen_domain_cleanup(void)
                    216: {
                    217:     char *dom;
                    218: 
                    219:     dom = xs_get_domain_path(xenstore, xen_domid);
                    220:     if (dom) {
                    221:         xs_rm(xenstore, 0, dom);
                    222:         free(dom);
                    223:     }
                    224:     xs_release_domain(xenstore, xen_domid);
                    225: }
                    226: 
                    227: int xen_domain_build_pv(const char *kernel, const char *ramdisk,
                    228:                         const char *cmdline)
                    229: {
                    230:     uint32_t ssidref = 0;
                    231:     uint32_t flags = 0;
                    232:     xen_domain_handle_t uuid;
                    233:     unsigned int xenstore_port = 0, console_port = 0;
                    234:     unsigned long xenstore_mfn = 0, console_mfn = 0;
                    235:     int rc;
                    236: 
                    237:     memcpy(uuid, qemu_uuid, sizeof(uuid));
                    238:     rc = xc_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid);
                    239:     if (rc < 0) {
                    240:         fprintf(stderr, "xen: xc_domain_create() failed\n");
                    241:         goto err;
                    242:     }
                    243:     qemu_log("xen: created domain %d\n", xen_domid);
                    244:     atexit(xen_domain_cleanup);
1.1.1.2   root      245:     if (xen_domain_watcher() == -1) {
                    246:         goto err;
                    247:     }
1.1       root      248: 
                    249:     xenstore_domain_init1(kernel, ramdisk, cmdline);
                    250: 
                    251:     rc = xc_domain_max_vcpus(xen_xc, xen_domid, smp_cpus);
                    252:     if (rc < 0) {
                    253:         fprintf(stderr, "xen: xc_domain_max_vcpus() failed\n");
                    254:         goto err;
                    255:     }
                    256: 
                    257: #if 0
                    258:     rc = xc_domain_setcpuweight(xen_xc, xen_domid, 256);
                    259:     if (rc < 0) {
                    260:         fprintf(stderr, "xen: xc_domain_setcpuweight() failed\n");
                    261:         goto err;
                    262:     }
                    263: #endif
                    264: 
                    265:     rc = xc_domain_setmaxmem(xen_xc, xen_domid, ram_size >> 10);
                    266:     if (rc < 0) {
                    267:         fprintf(stderr, "xen: xc_domain_setmaxmem() failed\n");
                    268:         goto err;
                    269:     }
                    270: 
                    271:     xenstore_port = xc_evtchn_alloc_unbound(xen_xc, xen_domid, 0);
                    272:     console_port = xc_evtchn_alloc_unbound(xen_xc, xen_domid, 0);
                    273: 
                    274:     rc = xc_linux_build(xen_xc, xen_domid, ram_size >> 20,
                    275:                         kernel, ramdisk, cmdline,
                    276:                         0, flags,
                    277:                         xenstore_port, &xenstore_mfn,
                    278:                         console_port, &console_mfn);
                    279:     if (rc < 0) {
                    280:         fprintf(stderr, "xen: xc_linux_build() failed\n");
                    281:         goto err;
                    282:     }
                    283: 
                    284:     xenstore_domain_init2(xenstore_port, xenstore_mfn,
                    285:                           console_port, console_mfn);
                    286: 
                    287:     qemu_log("xen: unpausing domain %d\n", xen_domid);
                    288:     rc = xc_domain_unpause(xen_xc, xen_domid);
                    289:     if (rc < 0) {
                    290:         fprintf(stderr, "xen: xc_domain_unpause() failed\n");
                    291:         goto err;
                    292:     }
                    293: 
1.1.1.3 ! root      294:     xen_poll = qemu_new_timer_ms(rt_clock, xen_domain_poll, NULL);
        !           295:     qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000);
1.1       root      296:     return 0;
                    297: 
                    298: err:
                    299:     return -1;
                    300: }

unix.superglobalmegacorp.com

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