Пример #1
0
static void tpm_emulator_inst_finalize(Object *obj)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(obj);

    tpm_emulator_shutdown(tpm_emu);

    object_unref(OBJECT(tpm_emu->data_ioc));

    qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);

    qapi_free_TPMEmulatorOptions(tpm_emu->options);

    if (tpm_emu->migration_blocker) {
        migrate_del_blocker(tpm_emu->migration_blocker);
        error_free(tpm_emu->migration_blocker);
    }

    qemu_mutex_destroy(&tpm_emu->mutex);
}
Пример #2
0
static void main_loop(void)
{
    int sock = -1, devfd = -1, fh, res, npoll;
    int32_t in_len;
    uint32_t out_len;
    uint8_t in[TPM_CMD_BUF_SIZE], *out;
    struct sockaddr_un addr;
    socklen_t addr_len;
    struct pollfd poll_table[2];

    info("staring main loop");
    /* open UNIX socket */
    if (opt_socket_name) {
	sock = init_socket(opt_socket_name);
	if (sock < 0) exit(EXIT_FAILURE);
    }

    if (opt_dev_name) {
	devfd = init_device(opt_dev_name);
	if (devfd < 0)
	    exit(EXIT_FAILURE);
    }

    /* init tpm emulator */
    debug("initializing TPM emulator");
    if (tpm_emulator_init(tpm_startup, tpm_config) != 0) {
        error("tpm_emulator_init() failed");
        close(sock);
        unlink(opt_socket_name);
        exit(EXIT_FAILURE);
    }

    /* start command processing */
    while (!stopflag) {
        /* wait for incomming connections */
        debug("waiting for connections...");
	npoll = 0;
	if (sock != -1) {
	    poll_table[npoll].fd = sock;
	    poll_table[npoll].events = POLLIN;
	    poll_table[npoll++].revents = 0;
	}
	if (devfd != -1) {
	    poll_table[npoll].fd = devfd;
	    poll_table[npoll].events = POLLIN | POLLERR;
	    poll_table[npoll++].revents = 0;
	}
	res = poll(poll_table, npoll, -1);
        if (res < 0) {
            error("poll(sock,dev) failed: %s", strerror(errno));
            break;
        }

	if (devfd != -1 && poll_table[npoll - 1].revents) {
	    /* if POLLERR was set, let read() handle it */
	    if (handle_emuldev_command(devfd) < 0)
		break;
	}
	if (sock == -1 || !poll_table[0].revents)
	    continue;

	/* Beyond this point, npoll will always be 1 if the emulator device is
	 * not open and 2 if it is, so we can just fill in the second slot of
	 * the poll table unconditionally and rely on passing npoll to poll().
	 */

        addr_len = sizeof(addr);
        fh = accept(sock, (struct sockaddr*)&addr, &addr_len);
        if (fh < 0) {
            error("accept() failed: %s", strerror(errno));
            continue;
        }
        /* receive and handle commands */
        in_len = 0;
        do {
            debug("waiting for commands...");
	    poll_table[0].fd = fh;
	    poll_table[0].events = POLLIN;
	    poll_table[0].revents = 0;
	    poll_table[1].fd = devfd;
	    poll_table[1].events = POLLIN | POLLERR;
	    poll_table[1].revents = 0;

	    res = poll(poll_table, npoll, TPM_COMMAND_TIMEOUT);
            if (res < 0) {
                error("poll(fh) failed: %s", strerror(errno));
                close(fh);
                break;
            } else if (res == 0) {
#ifdef TPMD_DISCONNECT_IDLE_CLIENTS	    
                info("connection closed due to inactivity");
                close(fh);
                break;
#else		
                continue;
#endif		
            }

	    if (poll_table[1].revents) {
		/* if POLLERR was set, let read() handle it */
		if (handle_emuldev_command(devfd) < 0)
		    break;
	    }
	    if (!poll_table[0].revents)
		continue;

            in_len = read(fh, in, sizeof(in));
            if (in_len > 0) {
                debug("received %d bytes", in_len);
                out = NULL;
                res = tpm_handle_command(in, in_len, &out, &out_len);
                if (res < 0) {
                    error("tpm_handle_command() failed");
                } else {
                    debug("sending %d bytes", out_len);
                    uint32_t len = 0;
                    while (len < out_len) {
                        res = write(fh, &out[len], out_len - len);
                        if (res < 0) {
                            error("write(%d) failed: %s", 
                                  out_len - len, strerror(errno));
                            break;
                        }
                        len += res;
                    }
                    tpm_free(out);
                }
            }
        } while (in_len > 0);
        close(fh);
    }
    /* shutdown tpm emulator */
    tpm_emulator_shutdown();
    /* close socket */
    close(sock);
    unlink(opt_socket_name);
    info("main loop stopped");
}