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

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"
1.1.1.2 ! root        6: #include "qemu-log.h"
1.1       root        7: 
                      8: #include <xenguest.h>
                      9: 
                     10: static int xenstore_domain_mkdir(char *path)
                     11: {
                     12:     struct xs_permissions perms_ro[] = {{
                     13:             .id    = 0, /* set owner: dom0 */
                     14:         },{
                     15:             .id    = xen_domid,
                     16:             .perms = XS_PERM_READ,
                     17:         }};
                     18:     struct xs_permissions perms_rw[] = {{
                     19:             .id    = 0, /* set owner: dom0 */
                     20:         },{
                     21:             .id    = xen_domid,
                     22:             .perms = XS_PERM_READ | XS_PERM_WRITE,
                     23:         }};
                     24:     const char *writable[] = { "device", "control", "error", NULL };
                     25:     char subpath[256];
                     26:     int i;
                     27: 
                     28:     if (!xs_mkdir(xenstore, 0, path)) {
                     29:         fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, path);
                     30:        return -1;
                     31:     }
                     32:     if (!xs_set_permissions(xenstore, 0, path, perms_ro, 2)) {
                     33:         fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
                     34:        return -1;
                     35:     }
                     36: 
                     37:     for (i = 0; writable[i]; i++) {
                     38:         snprintf(subpath, sizeof(subpath), "%s/%s", path, writable[i]);
                     39:         if (!xs_mkdir(xenstore, 0, subpath)) {
                     40:             fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, subpath);
                     41:             return -1;
                     42:         }
                     43:         if (!xs_set_permissions(xenstore, 0, subpath, perms_rw, 2)) {
                     44:             fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
                     45:             return -1;
                     46:         }
                     47:     }
                     48:     return 0;
                     49: }
                     50: 
                     51: int xenstore_domain_init1(const char *kernel, const char *ramdisk,
                     52:                           const char *cmdline)
                     53: {
                     54:     char *dom, uuid_string[42], vm[256], path[256];
                     55:     int i;
                     56: 
                     57:     snprintf(uuid_string, sizeof(uuid_string), UUID_FMT,
                     58:              qemu_uuid[0], qemu_uuid[1], qemu_uuid[2], qemu_uuid[3],
                     59:              qemu_uuid[4], qemu_uuid[5], qemu_uuid[6], qemu_uuid[7],
                     60:              qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], qemu_uuid[11],
                     61:              qemu_uuid[12], qemu_uuid[13], qemu_uuid[14], qemu_uuid[15]);
                     62:     dom = xs_get_domain_path(xenstore, xen_domid);
                     63:     snprintf(vm,  sizeof(vm),  "/vm/%s", uuid_string);
                     64: 
                     65:     xenstore_domain_mkdir(dom);
                     66: 
                     67:     xenstore_write_str(vm, "image/ostype",  "linux");
                     68:     if (kernel)
                     69:         xenstore_write_str(vm, "image/kernel",  kernel);
                     70:     if (ramdisk)
                     71:         xenstore_write_str(vm, "image/ramdisk", ramdisk);
                     72:     if (cmdline)
                     73:         xenstore_write_str(vm, "image/cmdline", cmdline);
                     74: 
                     75:     /* name + id */
                     76:     xenstore_write_str(vm,  "name",   qemu_name ? qemu_name : "no-name");
                     77:     xenstore_write_str(vm,  "uuid",   uuid_string);
                     78:     xenstore_write_str(dom, "name",   qemu_name ? qemu_name : "no-name");
                     79:     xenstore_write_int(dom, "domid",  xen_domid);
                     80:     xenstore_write_str(dom, "vm",     vm);
                     81: 
                     82:     /* memory */
                     83:     xenstore_write_int(dom, "memory/target", ram_size >> 10);  // kB
                     84:     xenstore_write_int(vm, "memory",         ram_size >> 20);  // MB
                     85:     xenstore_write_int(vm, "maxmem",         ram_size >> 20);  // MB
                     86: 
                     87:     /* cpus */
                     88:     for (i = 0; i < smp_cpus; i++) {
                     89:        snprintf(path, sizeof(path), "cpu/%d/availability",i);
                     90:        xenstore_write_str(dom, path, "online");
                     91:     }
                     92:     xenstore_write_int(vm, "vcpu_avail",  smp_cpus);
                     93:     xenstore_write_int(vm, "vcpus",       smp_cpus);
                     94: 
                     95:     /* vnc password */
                     96:     xenstore_write_str(vm, "vncpassword", "" /* FIXME */);
                     97: 
                     98:     free(dom);
                     99:     return 0;
                    100: }
                    101: 
                    102: int xenstore_domain_init2(int xenstore_port, int xenstore_mfn,
                    103:                           int console_port, int console_mfn)
                    104: {
                    105:     char *dom;
                    106: 
                    107:     dom = xs_get_domain_path(xenstore, xen_domid);
                    108: 
                    109:     /* signal new domain */
                    110:     xs_introduce_domain(xenstore,
                    111:                         xen_domid,
                    112:                         xenstore_mfn,
                    113:                         xenstore_port);
                    114: 
                    115:     /* xenstore */
                    116:     xenstore_write_int(dom, "store/ring-ref",   xenstore_mfn);
                    117:     xenstore_write_int(dom, "store/port",       xenstore_port);
                    118: 
                    119:     /* console */
                    120:     xenstore_write_str(dom, "console/type",     "ioemu");
                    121:     xenstore_write_int(dom, "console/limit",    128 * 1024);
                    122:     xenstore_write_int(dom, "console/ring-ref", console_mfn);
                    123:     xenstore_write_int(dom, "console/port",     console_port);
                    124:     xen_config_dev_console(0);
                    125: 
                    126:     free(dom);
                    127:     return 0;
                    128: }
                    129: 
                    130: /* ------------------------------------------------------------- */
                    131: 
                    132: static QEMUTimer *xen_poll;
                    133: 
                    134: /* check domain state once per second */
                    135: static void xen_domain_poll(void *opaque)
                    136: {
                    137:     struct xc_dominfo info;
                    138:     int rc;
                    139: 
                    140:     rc = xc_domain_getinfo(xen_xc, xen_domid, 1, &info);
                    141:     if ((rc != 1) || (info.domid != xen_domid)) {
                    142:         qemu_log("xen: domain %d is gone\n", xen_domid);
                    143:         goto quit;
                    144:     }
                    145:     if (info.dying) {
                    146:         qemu_log("xen: domain %d is dying (%s%s)\n", xen_domid,
                    147:                  info.crashed  ? "crashed"  : "",
                    148:                  info.shutdown ? "shutdown" : "");
                    149:         goto quit;
                    150:     }
                    151: 
                    152:     qemu_mod_timer(xen_poll, qemu_get_clock(rt_clock) + 1000);
                    153:     return;
                    154: 
                    155: quit:
                    156:     qemu_system_shutdown_request();
                    157:     return;
                    158: }
                    159: 
1.1.1.2 ! root      160: static int xen_domain_watcher(void)
1.1       root      161: {
                    162:     int qemu_running = 1;
                    163:     int fd[2], i, n, rc;
                    164:     char byte;
                    165: 
1.1.1.2 ! root      166:     if (pipe(fd) != 0) {
        !           167:         qemu_log("%s: Huh? pipe error: %s\n", __FUNCTION__, strerror(errno));
        !           168:         return -1;
        !           169:     }
1.1       root      170:     if (fork() != 0)
1.1.1.2 ! root      171:         return 0; /* not child */
1.1       root      172: 
                    173:     /* close all file handles, except stdio/out/err,
                    174:      * our watch pipe and the xen interface handle */
                    175:     n = getdtablesize();
                    176:     for (i = 3; i < n; i++) {
                    177:         if (i == fd[0])
                    178:             continue;
                    179:         if (i == xen_xc)
                    180:             continue;
                    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: 
                    294:     xen_poll = qemu_new_timer(rt_clock, xen_domain_poll, NULL);
                    295:     qemu_mod_timer(xen_poll, qemu_get_clock(rt_clock) + 1000);
                    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.