Annotation of qemu/hw/xen_domainbuild.c, revision 1.1.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.