示例#1
0
/*!
 * Forcibly stop the Hypervisor.
 *
 * \param config \ref cc_oci_config.
 * \param state \ref oci_state.
 * \param signum Signal number to send to hypervisor.
 * \param all_processes \c true to send a signal to all container's processes,
 *  \c false to send a signal to container's workload.
 *
 * \return \c true on success, else \c false.
 */
gboolean
cc_oci_kill (struct cc_oci_config *config,
		struct oci_state *state,
		int signum,
		gboolean all_processes)
{
	enum oci_status last_status;

	if (! (config && state)) {
		return false;
	}

	if (! cc_oci_get_signame (signum)) {
		g_critical ("signal %d is not supported", signum);
		return false;
	}

	/* save current status */
	last_status = config->state.status;

	/* A sandbox is not a running container, nothing to kill here */
	if (cc_pod_is_sandbox(config)) {
		config->state.status = OCI_STATUS_STOPPED;

		/* update state file */
		if (! cc_oci_state_file_create (config, state->create_time)) {
			g_critical ("failed to recreate state file");
			goto error;
		}

		return true;
	}

	/* stopping container */
	config->state.status = OCI_STATUS_STOPPING;

	/* update state file */
	if (! cc_oci_state_file_create (config, state->create_time)) {
		g_critical ("failed to recreate state file");
		goto error;
	}

#ifndef UNIT_TESTING
	/* kill container's processes, cc-shim will catch exit code
	 * and will end
	 */
	if (! cc_proxy_hyper_kill_container (config, signum, all_processes)) {
		g_critical ("failed to kill container %s: %s",
			config->optarg_container_id,
			strerror (errno));
		/* revert container status */
		config->state.status = last_status;
		if (! cc_oci_state_file_create (config, state->create_time)) {
			g_critical ("failed to recreate state file");
		}
		return false;
	}
#endif //UNIT_TESTING

	if (signum == SIGKILL) {
		/* cc-shim is not able to catch the exit code of a process
		 * finished with SIGKILL signal hence cc-shim MUST receive
		 * this signal too
		 */
		if (kill (state->pid, signum) < 0 && errno != ESRCH) {
			g_critical ("failed to stop cc-shim %u: %s",
					(unsigned)state->pid,
					strerror (errno));
			return false;
		}
	}

	last_status = config->state.status;

	config->state.status = OCI_STATUS_STOPPED;

	/* update state file */
	if (! cc_oci_state_file_create (config, state->create_time)) {
		g_critical ("failed to recreate state file");
		goto error;
	}

	return true;

error:
	/* revert container status */
	config->state.status = last_status;

	return false;
}
示例#2
0
} END_TEST

START_TEST(test_cc_oci_state_file_create) {
	struct cc_oci_config config = { { 0 } };
	const gchar *timestamp = "foo";
        struct oci_cfg_annotation* a = NULL;
	struct cc_oci_mount *m = NULL;
	g_autofree gchar *tmpdir = g_dir_make_tmp (NULL, NULL);
	gboolean ret;

	ck_assert(! cc_oci_state_file_create (NULL, NULL));

	/* Needs:
	 *
	 * - comms_path
	 * - procsock_path
	 * - optarg_bundle_path
	 * - optarg_container_id
	 * - runtime_path
	 *
	 */
	ck_assert(! cc_oci_state_file_create (&config, NULL));
	ck_assert(! cc_oci_state_file_create (&config, timestamp));

	config.optarg_container_id = "";

	ck_assert(! cc_oci_state_file_create (&config, NULL));
	ck_assert(! cc_oci_state_file_create (&config, timestamp));

	config.optarg_container_id = "foo";

	ck_assert(! cc_oci_state_file_create (&config, NULL));
	ck_assert(! cc_oci_state_file_create (&config, timestamp));

	config.bundle_path = g_strdup ("/tmp/bundle");

	ck_assert(! cc_oci_state_file_create (&config, NULL));
	ck_assert(! cc_oci_state_file_create (&config, timestamp));

	config.root_dir = g_strdup (tmpdir);
	ck_assert (config.root_dir);

	ck_assert (cc_oci_runtime_dir_setup (&config));

	ck_assert(! cc_oci_state_file_create (&config, NULL));
	ck_assert(! cc_oci_state_file_create (&config, timestamp));

	g_snprintf(config.state.comms_path, PATH_MAX, "/tmp");
	g_snprintf(config.state.procsock_path, PATH_MAX, "/tmp");

	ck_assert(! cc_oci_state_file_create (&config, NULL));

        a = g_new0(struct oci_cfg_annotation, 1);
        a->key = g_strdup("key1");
        a->value = g_strdup("val1");

        config.oci.annotations = g_slist_append(config.oci.annotations, a);

	/* config->vm not set */
	ck_assert(! cc_oci_state_file_create (&config, timestamp));

	config.vm = g_malloc0 (sizeof(struct cc_oci_vm_cfg));
	ck_assert (config.vm);

	g_strlcpy (config.vm->hypervisor_path, "hypervisor-path",
			sizeof (config.vm->hypervisor_path));

	g_strlcpy (config.vm->image_path, "image-path",
			sizeof (config.vm->image_path));

	g_strlcpy (config.vm->kernel_path, "kernel-path",
			sizeof (config.vm->kernel_path));

	g_strlcpy (config.vm->workload_path, "workload-path",
			sizeof (config.vm->workload_path));

	config.vm->kernel_params = g_strdup ("kernel params");

	/* All required elements now set */
	m = g_new0(struct cc_oci_mount, 1);
	g_snprintf(m->dest, sizeof(m->dest), "/tmp/tmp/tmp");
	m->directory_created = g_strdup("/tmp/tmp/");
	m->ignore_mount = true;
	config.oci.mounts = g_slist_append(config.oci.mounts, m);

	ck_assert (cc_oci_state_file_create (&config, timestamp));

	ret = g_file_test (config.state.state_file_path,
			G_FILE_TEST_EXISTS);
	ck_assert (ret);

	ck_assert (! g_remove (config.state.state_file_path));
	ck_assert (! g_remove (config.state.runtime_path));
	ck_assert (! g_remove (tmpdir));

	g_snprintf(config.state.runtime_path, PATH_MAX, "/abc/xyz/123");
	ck_assert(!cc_oci_state_file_create (&config, timestamp));

	/* clean up */
	cc_oci_config_free (&config);
} END_TEST
示例#3
0
/**
 * Create a fake state file for the specified VM.
 *
 * \param name Name to use for VM.
 * \param root_dir Root directory to use.
 * \param config Already allocated \ref cc_oci_config.
 *
 * \return \c true on success, else \c false.
 */
gboolean
test_helper_create_state_file (const char *name,
		const char *root_dir,
		struct cc_oci_config *config)
{
	g_autofree gchar *timestamp = NULL;

	assert (name);
	assert (root_dir);
	assert (config);

	timestamp = g_strdup_printf ("timestamp for %s", name);
	assert (timestamp);

	config->optarg_container_id = name;

	config->root_dir = g_strdup (root_dir);
	assert (config->root_dir);

	config->console = g_strdup_printf ("console device for %s", name);
	assert (config->console);

	config->bundle_path = g_strdup_printf ("/tmp/bundle-for-%s",
			name);
	assert (config->bundle_path);

	/* set pid to ourselves so we know it's running */
	if (! config->state.workload_pid) {
		config->state.workload_pid = getpid ();
	}

	g_strlcpy (config->state.procsock_path,
			"procsock-path",
		  sizeof (config->state.procsock_path));

	if (! cc_oci_runtime_dir_setup (config)) {
		fprintf (stderr, "ERROR: failed to setup runtime dir "
				"for vm %s", name);
		return false;
	}

	/* config->vm not set */
	if (cc_oci_state_file_create (config, timestamp)) {
		fprintf (stderr, "ERROR: cc_oci_state_file_create "
				"worked unexpectedly for vm %s", name);
		return false;
	}

	config->vm = g_malloc0 (sizeof(struct cc_oci_vm_cfg));
	assert (config->vm);

	g_strlcpy (config->vm->hypervisor_path, "hypervisor-path",
			sizeof (config->vm->hypervisor_path));

	g_strlcpy (config->vm->image_path, "image-path",
			sizeof (config->vm->image_path));

	g_strlcpy (config->vm->kernel_path, "kernel-path",
			sizeof (config->vm->kernel_path));

	g_strlcpy (config->vm->workload_path, "workload-path",
			sizeof (config->vm->workload_path));

	config->vm->kernel_params = g_strdup_printf ("kernel params for %s", name);

	/* config->vm now set */
	if (! cc_oci_state_file_create (config, timestamp)) {
		fprintf (stderr, "ERROR: cc_oci_state_file_create "
				"failed unexpectedly");
		return false;

	}

	return true;
}
示例#4
0
/*!
 * Forcibly stop the Hypervisor.
 *
 * \param config \ref cc_oci_config.
 * \param state \ref oci_state.
 * \param signum Signal number to send to hypervisor.
 *
 * \return \c true on success, else \c false.
 */
gboolean
cc_oci_kill (struct cc_oci_config *config,
		struct oci_state *state,
		int signum)
{
	enum oci_status last_status;

	if (! (config && state)) {
		return false;
	}

	/* save current status */
	last_status = config->state.status;

	/* A sandbox is not a running container, nothing to kill here */
	if (cc_pod_is_sandbox(config)) {
		config->state.status = OCI_STATUS_STOPPED;

		/* update state file */
		if (! cc_oci_state_file_create (config, state->create_time)) {
			g_critical ("failed to recreate state file");
			goto error;
		}

		return true;
	}

	/* stopping container */
	config->state.status = OCI_STATUS_STOPPING;

	/* update state file */
	if (! cc_oci_state_file_create (config, state->create_time)) {
		g_critical ("failed to recreate state file");
		goto error;
	}

	/* send signal to cc-shim because it
	 * will send killcontainer to hyperstart
	 */
	if (kill (state->pid, signum) < 0) {
		g_critical ("failed to stop container %s "
				"running with pid %u: %s",
				config->optarg_container_id,
				(unsigned)state->pid,
				strerror (errno));
		/* revert container status */
		config->state.status = last_status;
		if (! cc_oci_state_file_create (config, state->create_time)) {
			g_critical ("failed to recreate state file");
		}
		return false;
	}

#ifndef UNIT_TESTING
	/* cc-shim is not able to catch SIGKILL and SIGSTOP
	 * signals for this reason we must kill the container
	 * using hyperstart's API
	 */
	if (signum == SIGKILL || signum == SIGSTOP) {
		if (! cc_proxy_hyper_kill_container (config, signum)) {
			g_critical ("failed to kill container");
			return false;
		}
	}
#endif //UNIT_TESTING

	last_status = config->state.status;

	config->state.status = OCI_STATUS_STOPPED;

	/* update state file */
	if (! cc_oci_state_file_create (config, state->create_time)) {
		g_critical ("failed to recreate state file");
		goto error;
	}

	return true;

error:
	/* revert container status */
	config->state.status = last_status;

	return false;
}