Ejemplo n.º 1
0
int domain_setup(struct domain *d)
{
    int rc;

    /* Allocate/Store the domain UUID in /struct domain/. */
    domain_read_uuid(d);
    /* xc_getphysinfo to check if this domain is PV or HVM. */
    domain_read_is_pv_domain(d);
    /* Assign the slot passed by the toostack through Xenstore to this domain.
     *  - Slot read from /vm/<uuid>/slot (uuid needs to be known beforehand)
     *  - Also setup relevant nodes in XenStore to manage that slot.
     */
    rc = domain_assign_slot(d);
    if (rc)
        return rc;

    /* Slot 0 (UIVM) special case.
     * XXX: Stuff in here might be deprecated... */
    if (d->slot == 0) {
        char path[128], perm[128];

        xenstore_dom_write(d->domid, "http://1.0.0.0/auth.html", "login/url");
        xenstore_dom_write(d->domid, "3", "login/state");

        sprintf(perm, "n%d", d->domid);
        sprintf(path, "/local/domain/%d/report/state", d->domid);
        xenstore_write_int(3, path);
        xenstore_chmod(perm, 1, path);

        sprintf(path, "/local/domain/%d/report/url", d->domid);
        xenstore_write("http://1.0.0.0/create_report.html", path);
        xenstore_chmod(perm, 1, path);
    }

    /* Watch on node attr/desktopDimensions for resize events?
     * XXX: Isn't that HVM/Windows only ? */
    if (!xenstore_dom_watch(d->domid, domain_calculate_abs_scaling, d,
                            "attr/desktopDimensions"))
        warning("%s: Could not setup xenstore watch on switcher/command."
                " Slot will be static.", __func__);

    /* Handle PM events.
     * Setup watch on Xenstore node <dompath>/power-state. */
    if (!xenstore_dom_watch(d->domid, domain_power_state, d, "power-state"))
        warning("%s: Could not setup xenstore watch on power-state."
                " Power-management event will not be handled properly.",
                __func__);
    domain_power_state("power-state", d);

    /* Initialise display position for mouse switching.
     * XXX: Uses <dompath>/switcher/<slot>/{left,right} and talks with
     *      xenvm over dbus. */
    domain_mouse_switch_config(d);

    d->initialised = true;
    return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[]) {

    int ret = 0;

#ifndef RUN_STANDALONE
    openlog("xcpmd", 0, LOG_DAEMON);
    daemonize();
#endif

    xcpmd_log(LOG_INFO, "Starting XenClient power management daemon.\n");

    //Initialize libevent library
    event_init();

    //Initialize xenstore.
    if (xenstore_init() == -1) {
        xcpmd_log(LOG_ERR, "Unable to init xenstore\n");
        return -1;
    }

    // Allow everyone to read from /pm/ in xenstore
    xenstore_rm("/pm");
    xenstore_mkdir("/pm");
    xenstore_chmod("r0", 1, "/pm");

    initialize_platform_info();


    xcpmd_log(LOG_INFO, "Starting DBUS server.\n");
    if (xcpmd_dbus_initialize() == -1) {
        xcpmd_log(LOG_ERR, "Failed to initialize DBUS server\n");
        goto xcpmd_err;
    }

    xcpmd_log(LOG_INFO, "Starting ACPI events monitor.\n");
    if (acpi_events_initialize() == -1) {
        xcpmd_log(LOG_ERR, "Failed to initialize ACPI events monitor\n");
        goto xcpmd_err;
    }

    // Load modules
    xcpmd_log(LOG_INFO, "Loading modules.\n");
    if (init_modules() == -1) {
        xcpmd_log(LOG_ERR, "Failed to load all modules\n");
        goto xcpmd_err;
    }

    //This relies on both acpi-events and acpi-module having been initialized
    xcpmd_log(LOG_INFO, "Initializing ACPI state.\n");
    acpi_initialize_state();

    // Load policy
    xcpmd_log(LOG_INFO, "Loading policy.\n");
    if (load_policy_from_db() == -1) {
        xcpmd_log(LOG_WARNING, "Error loading policy from DB; continuing...\n");
    }

#ifdef POLICY_FILE_PATH
    if (load_policy_from_file(POLICY_FILE_PATH) == -1) {
        xcpmd_log(LOG_WARNING, "Error loading policy from file %s; continuing...\n", POLICY_FILE_PATH);
    }
#endif

#ifdef XCPMD_DEBUG
    xcpmd_log(LOG_DEBUG, "Rules loaded:\n");
    print_rules();
#endif

    xcpmd_log(LOG_INFO, "Entering event loop.\n");
    event_dispatch();

    goto xcpmd_out;

xcpmd_err:
    ret = -1;
xcpmd_out:
    uninit_modules();
    acpi_events_cleanup();
    xcpmd_dbus_cleanup();
#ifndef RUN_STANDALONE
    closelog();
#endif

    return ret;
}
Ejemplo n.º 3
0
int clickos_start(int domid, const char *name, const char *script)
{
	const char *clickos_config_path_tail = "/config/";
	char clickos_script_chunk[1501];

	char *clickos_root_path = NULL;
	char *clickos_elem_path = NULL;
	char *clickos_ctl_path = NULL;
	char *clickos_config_name_path = NULL;
	char *clickos_config_path = NULL;
	char *clickos_status_path = NULL;
	char *clickos_router_path = NULL;
	int clickos_config_id = 0;
	default_domain_perms.id = domid;
	default_domain_perms.perms = XS_PERM_READ | XS_PERM_WRITE;

	if (!xs) {
		xenstore_init(domid);
	}

retry_clickos:
	// Transaction for ClickOS
	th = xs_transaction_start(xs);

	asprintf(&domain_root_path, "/local/domain/%d", domid);

	do {
		asprintf(&clickos_root_path, "%s/clickos/%d", domain_root_path, clickos_config_id);
		clickos_router_path = xenstore_read(clickos_root_path);
		if (clickos_router_path)
			clickos_config_id++;
	} while (clickos_router_path != NULL);

	asprintf(&clickos_elem_path, "%s/elements", clickos_root_path);
	asprintf(&clickos_ctl_path, "%s/control", clickos_root_path);
	asprintf(&clickos_config_name_path, "%s/config_name", clickos_root_path);
	asprintf(&clickos_status_path, "%s/status", clickos_root_path);

	xenstore_write(clickos_elem_path, "");
	xenstore_write(clickos_ctl_path, "");

	xenstore_chmod(clickos_elem_path, &default_domain_perms);
	xenstore_chmod(clickos_ctl_path, &default_domain_perms);

	xenstore_write(clickos_config_name_path, name);

	// we need one character for each chunk
	int config_path_len = strlen(clickos_root_path)
						  + strlen(clickos_config_path_tail) + 1;
	clickos_config_path = malloc(config_path_len + 1);
	int chunk = 0;
	int scriptSize = strlen(script);
	int remainingScriptSize = scriptSize;
	do {
		snprintf(clickos_config_path, config_path_len + 1, "%s%s%d",
				 clickos_root_path, clickos_config_path_tail, chunk);
		int chunkSize = MAX_CHUNK_LENGTH;
		if (remainingScriptSize < MAX_CHUNK_LENGTH) {
			chunkSize = remainingScriptSize;
		}
		memcpy(clickos_script_chunk, script + (chunk * MAX_CHUNK_LENGTH), chunkSize);
		clickos_script_chunk[chunkSize] = '\0';
		xenstore_write(clickos_config_path, clickos_script_chunk);
		chunk++;
		remainingScriptSize -= chunkSize;
	} while (remainingScriptSize > 0);

	if (!xs_transaction_end(xs, th, 0)) {
		if (errno == EAGAIN)
			goto retry_clickos;
	}

retry_status:
	// Transaction for ClickOS state
	th = xs_transaction_start(xs);

	xenstore_write(clickos_status_path, "Running");

	if (!xs_transaction_end(xs, th, 0)) {
		if (errno == EAGAIN)
			goto retry_status;
	}

	return 0;
}
Ejemplo n.º 4
0
static void switcher_domid(struct domain *d, uint32_t domid)
{
  char perm[8];
  char path[64];
  char perms[128];
  char *tmp = 0;
  int stubdom_domid;
  int slot;
  struct domain       *d_pvm;

  if (domain_with(domid,&domid))
    {
      error("domain %d already exists", domid);
      return;
    }

  d->domid = domid;

  domain_read_uuid(d);
  domain_read_is_pv_domain(d);

  slot = domain_read_slot(d);

  // Ensures that no "zombie" domains are taking up valuable switcher slots.
  // Ideally, this shouldn't be necessary-- but in development environments
  // it's possible for interesting things to happen (e.g. for a developer to
  // destroy a stub-domain without giving us notice of the termination.)

  // This safeguard function isn't strictly neccessary, but it's lightweight
  // and prevents some awful behavior (including huge delays) if developers do
  // manage to do fun things like kernel panic their stubdomains.
  if(slot_occupied_by_dead_domain(slot))
  {
      warning("slot %d is held by a dead domain; cleaning up", slot);
      domain_gone(domain_with(slot, &slot));
  }

  if (domain_with(slot,&slot) || (slot == -1))
  {
      error("slot %d already taken (wanted by domain %d)",slot,domid);
      return;
  }
  d->slot = slot;

  info("New domain %d (slot %d)", domid, slot);

  /* init xenstore nodes and permissions for midori secure window and status report */
  if (slot == 0)
  {
      xenstore_dom_write(domid, "http://1.0.0.0/auth.html", "login/url");
      xenstore_dom_write(domid, "3", "login/state");

      sprintf(perm, "n%d", domid);

      sprintf(path, "/local/domain/%d/report/state", domid);
      xenstore_write_int(3, path);
      xenstore_chmod(perm, 1, path);

      sprintf(path, "/local/domain/%d/report/url", domid);
      xenstore_write("http://1.0.0.0/create_report.html", path);
      xenstore_chmod (perm, 1, path);
  }

  xenstore_dom_write(domid, "", "switcher/command");
  sprintf(perms, "r%d", domid);
  xenstore_dom_chmod(domid, perms, 1, "switcher/command");
  if (!xenstore_dom_watch(domid, domain_command, d, "switcher/command"))
          warning("failed to install xenstore watch! switcher/command");


  d->rel_x_mult = MAX_MOUSE_ABS_X / DEFAULT_RESOLUTION_X;
  d->rel_y_mult = MAX_MOUSE_ABS_Y / DEFAULT_RESOLUTION_Y;
  d->desktop_xres = d->desktop_yres = 0;
  if (!xenstore_dom_watch(d->domid, domain_calculate_abs_scaling, d, "attr/desktopDimensions"))
          warning("failed to install xenstore watch! attr/desktopDimensions");

  d->is_pvm = 0;
  d->keyboard_led_code = 0;
  xenstore_dom_write_int(d->domid, 0, "switcher/have_gpu");

  if (!xenstore_dom_watch(domid, domain_power_state, d, "power-state"))
          warning("failed to install xenstore watch! power-state");
  domain_power_state("power-state",d);

  d_pvm = domain_with(is_pvm, &one);
  domain_surface_disabled_detect_init(d);

  xen_vkbd_backend_create(d);
  domain_read_has_secondary_gpu(d);

  domain_mouse_switch_config(d);

  focus_update_domain(d);

/* call our callbacks*/
  struct callbacklist* c = domainstart_callback;
  while (c)
  {
     c->callback(d);
     c = c->next;
  }

  /* we are ready to receive switch commands for this domain */
  xenstore_dom_write(domid, "true", "switcher/ready");
}