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; }
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; }
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; }
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"); }