int
grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx)
{
	char key_str[PATH_MAX] = {0};
	char val_str[PATH_MAX] = {0};
	void *mempool_obj_va;

	if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
		return -1;
	}

	if (snprintf(key_str, sizeof(key_str),
		DPDK_XENSTORE_PATH"%d"MEMPOOL_XENSTORE_STR, mempool_idx) == -1)
		return -1;
	if (xenstore_write(key_str, val_str) == -1)
		return -1;

	if (snprintf(key_str, sizeof(key_str),
		DPDK_XENSTORE_PATH"%d"MEMPOOL_VA_XENSTORE_STR, mempool_idx) == -1)
		return -1;
	if (mpool->nb_mem_chunks != 1) {
		RTE_LOG(ERR, PMD,
			"mempool with more than 1 chunk is not supported\n");
		return -1;
	}
	mempool_obj_va = STAILQ_FIRST(&mpool->mem_list)->addr;
	if (snprintf(val_str, sizeof(val_str), "%"PRIxPTR,
			(uintptr_t)mempool_obj_va) == -1)
		return -1;
	if (xenstore_write(key_str, val_str) == -1)
		return -1;

	return 0;
}
Exemple #2
0
//Exactly what it says on the tin.
void write_battery_info_to_xenstore(unsigned int battery_index) {

    if (battery_slot_exists(battery_index) == NO || battery_index >= num_battery_structs_allocd) {
        xcpmd_log(LOG_INFO, "Detected removal of battery slot %d in info.\n", battery_index);
        cleanup_removed_battery(battery_index);
        return;
    }

    struct battery_info * info;
    char bif[1024], string_info[256], xenstore_path[128];

    info = &last_info[battery_index];

    memset(bif, 0, 1024);
    memset(string_info, 0, 256);
    // write 9 dwords (so 9*4) + length of 4 strings + 4 null terminators
    snprintf(bif, 3, "%02x",
             (unsigned int)(9*4 +
                            strlen(info->model_number) +
                            strlen(info->serial_number) +
                            strlen(info->battery_type) +
                            strlen(info->oem_info) + 4));
    write_ulong_lsb_first(bif+2, info->power_unit);
    write_ulong_lsb_first(bif+10, info->design_capacity);
    write_ulong_lsb_first(bif+18, info->last_full_capacity);
    write_ulong_lsb_first(bif+26, info->battery_technology);
    write_ulong_lsb_first(bif+34, info->design_voltage);
    write_ulong_lsb_first(bif+42, info->design_capacity_warning);
    write_ulong_lsb_first(bif+50, info->design_capacity_low);
    write_ulong_lsb_first(bif+58, info->capacity_granularity_1);
    write_ulong_lsb_first(bif+66, info->capacity_granularity_2);

    snprintf(string_info, 256, "%02x%s%02x%s%02x%s%02x%s",
             (unsigned int)strlen(info->model_number), info->model_number,
             (unsigned int)strlen(info->serial_number), info->serial_number,
             (unsigned int)strlen(info->battery_type), info->battery_type,
             (unsigned int)strlen(info->oem_info), info->oem_info);
    strncat(bif+73, string_info, 1024-73-1);

    //Ensure the directory exists before trying to write the leaves
    make_xenstore_battery_dir(battery_index);

    //Now write the leaves.
    snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BIF_LEAF);
    xenstore_write(bif, xenstore_path);


    //Here for compatibility--will be removed eventually
    if (battery_index == 0)
        xenstore_write(bif, XS_BIF);
    else
        xenstore_write(bif, XS_BIF1);
}
Exemple #3
0
static long xenstore_setkey(char *key, char *val, size_t val_len)
{
  uint32_t req_id, key_len, res, type;
  char *outbuf, *resbuf;

  /* convert our inputs into KEY0VAL */
  key_len = strlen(key);
  outbuf = malloc(key_len + 1 + val_len);
  memcpy(outbuf, key, key_len);
  memcpy(outbuf + key_len + 1, val, val_len);
  outbuf[key_len] = 0;

  req_id = xenstore_write(XS_WRITE, key_len + 1 + val_len, outbuf);
  res = xenstore_read(req_id, &type, (void**)&resbuf);
  if(type == XS_ERROR) {
    printf("PROFILING: Error writing key |%s|: %s\n", key, resbuf);
    res = 0;
  } else if(type != XS_WRITE) {
    printf("PROFILING: Error writing key |%s|: %d\n", key, type);
    res = 0;
  } else res = 1;

  free(outbuf);
  free(resbuf);

  return res;
}
Exemple #4
0
static char *xenstore_getkey(char *key)
{
  uint32_t req_id, type, len;
  char *res, *buffer;

  req_id = xenstore_write(XS_READ, strlen(key) + 1, key);
  len    = xenstore_read(req_id, &type, (void**)&buffer);
  if(type == XS_ERROR) {
    printf("PROFILING: Error reading key |%s|: %s\n", key, buffer);
    free(buffer);
    return NULL;
  }
  if(type != XS_READ) {
    printf("PROFILING: Error reading key |%s|: %d\n", key, type);
    free(buffer);
    return NULL;
  }

  /* the Xenstore doesn't send back 0-terminated values on reads, so
     make our result zero terminated */
  res = malloc(len + 1);
  memcpy(res, buffer, len);
  res[len] = 0;
  free(buffer);

  return res;
}
Exemple #5
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;
}
Exemple #6
0
char* clickos_read_handler(int domid, char *elem, char *attr)
{
	char *ctrlpath = NULL, *elempath = NULL;
	char *rpath = NULL, *wpath = NULL;
	char *value;
	int err;
	unsigned int len = 0;
	struct pollfd fds[1];

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

	asprintf(&ctrlpath, "/local/domain/%d/clickos/0/control", domid);
	asprintf(&elempath, "/local/domain/%d/clickos/0/elements", domid);
	asprintf(&wpath, "%s/read/%s/%s", ctrlpath, elem, attr);
	asprintf(&rpath, "%s/%s/%s", elempath, elem, attr);

	th = xs_transaction_start(xs);
	xenstore_write(wpath, " ");
	xs_transaction_end(xs, th, 0);

	err = xs_watch(xs, rpath, "lock");
	if (!err) {
		printf("Error setting a watch\n");
		return NULL;
	}

	fds[0].fd = xs_fileno(xs);
	fds[0].events = (POLLIN);
	while (len <= 0) {
	   if (poll(fds, 1, 1000) <= 0) {
		   continue;
	   }

retry_wh:
	   th = xs_transaction_start(xs);
	   //value = xenstore_read(rpath);
	   value = xs_read(xs, XBT_NULL, rpath, &len);
	   //printf("read: len %d value %s\n", len, value);
	   if (!xs_transaction_end(xs, th, 0)) {
			if (errno == EAGAIN)
				goto retry_wh;
	   }
	   usleep(5000);
	}

	err = xs_unwatch(xs, rpath, "lock");
	th = xs_transaction_start(xs);
	xs_write(xs, th, rpath, "", 0);
	err = xs_transaction_end(xs, th, 0);
	return value;
}
Exemple #7
0
//Remove a battery's entries from the xenstore.
static void cleanup_removed_battery(unsigned int battery_index) {

    char path[256];

    snprintf(path, 255, "%s%d", XS_BATTERY_PATH, battery_index);
    xenstore_rm(path);

    if (battery_index > 0) {
        xenstore_rm(XS_BST1);
        xenstore_rm(XS_BIF1);
    }
    else {
        xenstore_rm(XS_BST);
        xenstore_rm(XS_BIF);
    }

    if (get_num_batteries_present() == 0)
        xenstore_write("0", XS_BATTERY_PRESENT);
    else
        xenstore_write("1", XS_BATTERY_PRESENT);
}
Exemple #8
0
char* clickos_write_handler(int domid, char *elem, char *attr, char *value)
{
	char *elempath = NULL;
	char *wpath = NULL;

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

	asprintf(&elempath, "/local/domain/%d/clickos/0/elements", domid);
	asprintf(&wpath, "%s/%s/%s", elempath, elem, attr);

	xenstore_write(wpath, value);
	return 0;
}
Exemple #9
0
int clickos_stop(int domid, int configid)
{
	char *statuspath = NULL;

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

	asprintf(&statuspath, "/local/domain/%d/clickos/%d/status", domid, configid);

retry_stop:
	th = xs_transaction_start(xs);
	xenstore_write(statuspath, "Halted");
	if (!xs_transaction_end(xs, th, 0)) {
		if (errno == EAGAIN)
			goto retry_stop;
	}
	return 0;
}
Exemple #10
0
FILE *profile_fopen(const char *fname, const char *mode)
{
  char *key = NULL, *val = NULL, *rsp = NULL, *domStr = NULL, *diskname = NULL;
  uint32_t req, rsptype, rsplen, domId;
  XenStorePaths *xsp = NULL;
  uint64_t store_mptr;
  FILE *retval = NULL;
  int vallen;
  long res;

  if(strncmp(mode, "w", 1) != 0)
    goto fail;

  if(strncmp(fname, "HaLVM.prof", 11) == 0)
    diskname = "xvdp1";
  if(strncmp(fname, "HaLVM.hp", 9) == 0)
    diskname = "xvdp2";
  if(!diskname)
    goto fail;

  store_mptr = (uint64_t)system_start_info->store_mfn << 12;
  unmask_channel(system_start_info->store_evtchn);
  xsint = (struct xenstore_domain_interface*)machine_to_virtual(store_mptr);
  if(!xsint) {
    printf("PROFILING ERROR: Could not map XenStore page.\n");
    goto fail;
  }

  /* Try to run "ls devices/vbd" */
  req = xenstore_write(XS_DIRECTORY, strlen("device/vbd") + 1, "device/vbd");
  rsplen = xenstore_read(req, &rsptype, (void**)&rsp);
  if(rsptype == XS_ERROR) {
    printf("PROFILING: XenStore read error. Did you forget to add a disk?\n");
    goto fail;
  }
  if(rsptype != XS_DIRECTORY) {
    printf("PROFILING: XenStore has gone weird. Giving up.\n");
    goto fail;
  }

  /* Find the XenStore paths associated with the disk we want */
  xsp = find_xs_paths(diskname, rsp, rsplen);
  if(!xsp) {
    printf("PROFILING: Couldn't find file to open.\n");
    goto fail;
  }

  /* Pull out the other's domId */
  key = malloc(256);
  snprintf(key, 256, "%s/backend-id", xsp->feDir);
  domStr = xenstore_getkey(key);
  domId = atoi(domStr);

  /* allocate the return structure and buffers */
  retval = malloc(sizeof(FILE));
  if(!retval)
    goto fail;
  memset(retval, 0, sizeof(FILE));
  retval->cur_block_num = 1;
  retval->block = runtime_alloc(NULL, 4096, PROT_READ|PROT_WRITE);
  if(!retval->block)
    goto fail;
  assert( (((uintptr_t)retval->block) & 4095) == 0 );
  retval->ring.sring = runtime_alloc(NULL, 4096, PROT_READ|PROT_WRITE);
  if(!retval->ring.sring)
    goto fail;
  assert( (((uintptr_t)retval->ring.sring) & 4095) == 0 );
  SHARED_RING_INIT(retval->ring.sring);
  FRONT_RING_INIT(&(retval->ring), retval->ring.sring, 4096);

  /* get the device handle */
  snprintf(key, 256, "%s/virtual-device", xsp->feDir);
  val = xenstore_getkey(key);
  retval->disk_handle = atoi(val);

  /* allocate the grant references and event channel */
  res = alloc_grant(domId, retval->ring.sring, 4096, 0, &retval->ring_grant);
  if(res) {
    printf("PROFILING: Failed to allocate ring grant reference: %d\n", res);
    goto fail;
  }
  res = alloc_grant(domId, retval->block, 4096, 0, &retval->block_grant);
  if(res) {
    printf("PROFILING: Failed to allocate block grant reference: %d\n", res);
    goto fail;
  }
  res = channel_alloc(DOMID_SELF, domId);
  if(res < 0) {
    printf("PROFILING: Failed to allocate grant reference: %d\n", res);
    goto fail;
  }
  retval->chan = (uint32_t)res;
  set_c_handler(retval->chan, handler);

  /* write them into our tree */
  val    = malloc(256);
  /*    */ snprintf(key, 256, "%s/ring-ref", xsp->feDir);
  vallen = snprintf(val, 256, "%d", retval->ring_grant);
  if(!xenstore_setkey(key, val, vallen)) goto fail;
  /*    */ snprintf(key, 256, "%s/event-channel", xsp->feDir);
  vallen = snprintf(val, 256, "%d", retval->chan);
  if(!xenstore_setkey(key, val, vallen)) goto fail;
  /*    */ snprintf(key, 256, "%s/state", xsp->feDir);
  vallen = snprintf(val, 256, "%d", XenbusStateInitialised);
  if(!xenstore_setkey(key, val, vallen)) goto fail;

  /* wait for the other side to sync up */
  do {
    char *state;

    runtime_block(1);
    snprintf(key, 256, "%s/state", xsp->beDir);
    state = xenstore_getkey(key);
    res = atoi(state);
    free(state);
  } while(res != XenbusStateConnected);

  /* write out that we're good */
  /*    */ snprintf(key, 256, "%s/state", xsp->feDir);
  vallen = snprintf(val, 256, "%d", XenbusStateConnected);
  if(!xenstore_setkey(key, val, vallen)) goto fail;

  return retval;

fail:
  if(key) free(key);
  if(val) free(val);
  if(rsp) free(rsp);
  if(xsp) {
    free(xsp->feDir);
    free(xsp->beDir);
    free(xsp);
  }
  if(domStr) free(domStr);
  if(retval) {
    if(retval->block_grant) end_grant(retval->block_grant);
    if(retval->ring_grant) end_grant(retval->ring_grant);
    if(retval->block) runtime_free(retval->block, 4096);
    if(retval->ring.sring) runtime_free(retval->ring.sring, 4096);
    if(retval->chan) channel_close(retval->chan);
    free(retval);
  }
  errno = -EACCES;
  return NULL;
}
Exemple #11
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;
}
Exemple #12
0
//Updates status and info of all batteries locally and in the xenstore.
void update_batteries(void) {

    struct battery_status *old_status = NULL;
    struct battery_info *old_info = NULL;
    char path[256];
    unsigned int old_num_batteries = 0;
    unsigned int num_batteries = 0;
    unsigned int i, new_array_size, old_array_size, num_batteries_to_update;
    bool present_batteries_changed = false;

    if ( pm_specs & PM_SPEC_NO_BATTERIES )
        return;

    //Keep a copy of what the battery status/info used to be.
    old_status = (struct battery_status *)malloc(num_battery_structs_allocd * sizeof(struct battery_status));
    old_info = (struct battery_info *)malloc(num_battery_structs_allocd * sizeof(struct battery_info));

    if (last_status != NULL)
        memcpy(old_status, last_status, num_battery_structs_allocd * sizeof(struct battery_status));
    else
        memset(old_status, 0, num_battery_structs_allocd * sizeof(struct battery_status));

    if (last_info != NULL)
        memcpy(old_info, last_info, num_battery_structs_allocd * sizeof(struct battery_info));
    else
        memset(old_info, 0, num_battery_structs_allocd * sizeof(struct battery_info));

    old_array_size = num_battery_structs_allocd;


    //Resize the arrays if necessary.
    new_array_size = (unsigned int)(get_max_battery_index() + 1);
    if (new_array_size != old_array_size) {
        if (new_array_size == 0) {
            xcpmd_log(LOG_INFO, "All batteries removed.\n");
            free(last_info);
            free(last_status);
        }
        else {
            last_info = (struct battery_info *)realloc(last_info, new_array_size * sizeof(struct battery_info));
            last_status = (struct battery_status *)realloc(last_status, new_array_size * sizeof(struct battery_status));
            memset(last_info, 0, new_array_size * sizeof(struct battery_info));
            memset(last_status, 0, new_array_size * sizeof(struct battery_status));
        }
        num_battery_structs_allocd = new_array_size;
    }

    num_batteries_to_update = (new_array_size > old_array_size) ? new_array_size : old_array_size;

    //Updating all status/info before writing to the xenstore prevents bad
    //calculations of aggregate data (e.g., warning level).
    for (i=0; i < num_batteries_to_update; ++i) {
        update_battery_status(i);
        update_battery_info(i);
    }

    //Write back to the xenstore and only send notifications if things have changed.
    for (i=0; i < num_batteries_to_update; ++i) {

        //No need to update status/info in Xenstore if there was no battery to begin with.
        //   On some latops, batteries index are not contiguous. It is not a big
        //   deal to have one or two empty array slot, but it should not be
        //   reported as a removed battery (OXT-614).
        if (last_status[i].present || old_status[i].present) {
            write_battery_status_to_xenstore(i);
            write_battery_info_to_xenstore(i);
        }

        if (i < old_array_size && i < new_array_size) {
            if (memcmp(&old_info[i], &last_info[i], sizeof(struct battery_info))) {
                snprintf(path, 255, "%s%i/%s", XS_BATTERY_EVENT_PATH, i, XS_BATTERY_INFO_EVENT_LEAF);
                xenstore_write("1", path);
            }

            if (memcmp(&old_status[i], &last_status[i], sizeof(struct battery_status))) {
                snprintf(path, 255, "%s%i/%s", XS_BATTERY_EVENT_PATH, i, XS_BATTERY_STATUS_EVENT_LEAF);
                xenstore_write("1", path);
            }

            if (old_status[i].present == YES)
                ++old_num_batteries;

            if (last_status[i].present == YES)
                ++num_batteries;

            if (old_status[i].present != last_status[i].present)
                present_batteries_changed = true;

        }
        else if (new_array_size > old_array_size) {
            //a battery has been added
            snprintf(path, 255, "%s%i/%s", XS_BATTERY_EVENT_PATH, i, XS_BATTERY_INFO_EVENT_LEAF);
            xenstore_write("1", path);
            snprintf(path, 255, "%s%i/%s", XS_BATTERY_EVENT_PATH, i, XS_BATTERY_STATUS_EVENT_LEAF);
            xenstore_write("1", path);

            if (last_status[i].present == YES)
                ++num_batteries;

            if (i < old_array_size) {
                if (old_status[i].present != last_status[i].present)
                    present_batteries_changed = true;
            }
            else {
                if (last_status[i].present == YES)
                    present_batteries_changed = true;
            }
        }
        else if (new_array_size < old_array_size) {
            //a battery has been removed
            snprintf(path, 255, "%s%i/%s", XS_BATTERY_EVENT_PATH, i, XS_BATTERY_INFO_EVENT_LEAF);
            xenstore_write("1", path);
            snprintf(path, 255, "%s%i/%s", XS_BATTERY_EVENT_PATH, i, XS_BATTERY_STATUS_EVENT_LEAF);
            xenstore_write("1", path);

            if (old_status[i].present == YES)
                ++old_num_batteries;

            if (i < new_array_size) {
                if (old_status[i].present != last_status[i].present)
                    present_batteries_changed = true;
            }
            else {
                if (old_status[i].present == YES)
                    present_batteries_changed = true;
            }
        }
    }

    if ((old_array_size != new_array_size) || (memcmp(old_info, last_info, new_array_size * sizeof(struct battery_info)))) {
        notify_com_citrix_xenclient_xcpmd_battery_info_changed(xcdbus_conn, XCPMD_SERVICE, XCPMD_PATH);
    }

    if ((old_array_size != new_array_size) || (memcmp(old_status, last_status, new_array_size * sizeof(struct battery_status)))) {
        //Here for compatibility--should eventually be removed
        xenstore_write("1", XS_BATTERY_STATUS_CHANGE_EVENT_PATH);
        notify_com_citrix_xenclient_xcpmd_battery_status_changed(xcdbus_conn, XCPMD_SERVICE, XCPMD_PATH);
    }

    if (present_batteries_changed) {
        notify_com_citrix_xenclient_xcpmd_num_batteries_changed(xcdbus_conn, XCPMD_SERVICE, XCPMD_PATH);
    }

    free(old_info);
    free(old_status);
}
Exemple #13
0
//Exactly what it says on the tin.
void write_battery_status_to_xenstore(unsigned int battery_index) {

    struct battery_status * status;
    char bst[35], xenstore_path[128];
    int num_batteries, current_battery_level;

    if (battery_index >= num_battery_structs_allocd) {
        cleanup_removed_battery(battery_index);
    }

    num_batteries = get_num_batteries_present();
    if (num_batteries == 0) {
        xenstore_write("0", XS_BATTERY_PRESENT);
        return;
    }
    else {
        xenstore_write("1", XS_BATTERY_PRESENT);
    }

    status = &last_status[battery_index];

    //Delete the BST and reset the "present" flag if the battery is not currently present.
    if (status->present != YES) {

        snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BST_LEAF);
        xenstore_rm(xenstore_path);

        snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BATTERY_PRESENT_LEAF);
        xenstore_write("0", xenstore_path);
        return;
    }

    //Build the BST structure.
    memset(bst, 0, 35);
    snprintf(bst, 3, "%02x", 16);
    write_ulong_lsb_first(bst+2, status->state);
    write_ulong_lsb_first(bst+10, status->present_rate);
    write_ulong_lsb_first(bst+18, status->remaining_capacity);
    write_ulong_lsb_first(bst+26, status->present_voltage);

    //Ensure the directory exists before trying to write the leaves
    make_xenstore_battery_dir(battery_index);

    //Now write the leaves.
    snprintf(xenstore_path, 255, XS_BATTERY_PATH "%i/" XS_BST_LEAF, battery_index);
    xenstore_write(bst, xenstore_path);

    snprintf(xenstore_path, 255, "%s%i/%s", XS_BATTERY_PATH, battery_index, XS_BATTERY_PRESENT_LEAF);
    xenstore_write("1", xenstore_path);

    //Here for compatibility--will be removed eventually
    if (battery_index == 0)
        xenstore_write(bst, XS_BST);
    else
        xenstore_write(bst, XS_BST1);

    current_battery_level = get_current_battery_level();
    if (current_battery_level == NORMAL || get_ac_adapter_status() == ON_AC)
        xenstore_rm(XS_CURRENT_BATTERY_LEVEL);
    else {
        xenstore_write_int(current_battery_level, XS_CURRENT_BATTERY_LEVEL);
        notify_com_citrix_xenclient_xcpmd_battery_level_notification(xcdbus_conn, XCPMD_SERVICE, XCPMD_PATH);
        xcpmd_log(LOG_ALERT, "Battery level below normal - %d!\n", current_battery_level);
    }

#ifdef XCPMD_DEBUG
    xcpmd_log(LOG_DEBUG, "~Updated battery information in xenstore\n");
#endif
}
Exemple #14
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");
}
Exemple #15
0
static void domain_command(const char *path, void *opaque)
{
    struct domain       *d = opaque;
    char                *tmp;
    int                 slot;
    int                 domid;

    tmp = xenstore_read(path);
    if (!tmp)
        return;

    if (!*tmp)  {
        free(tmp);
        return;
    }

    info("Command \"%s\", domid %d\n", tmp, d->domid);

    if (strcmp(tmp, "switch") == 0)
    {
        switcher_switch(d, 0, 0);
    }
    else if (sscanf(tmp, "switch slot %d", &slot) == 1)
    {
        struct domain   *s = domain_with_slot(slot);

        if (!s)
        {
            error("slot %d doesn't exist", slot);
            return;
        }
        info("try to switch to slot %d", slot);
        switcher_switch(s, 0, 0);
    }
    else if (sscanf(tmp, "switch domid %d", &domid) == 1)
    {
        struct domain   *s = domain_with(domid,  &domid);
        if (!s)
        {
            error("domain %d doesn't exist", domid);
            return;
        }
        switcher_switch(s, 0, 0);
    }
    else if (strcmp("keyboard take", tmp) == 0)
    {
        input_give_keyboard(d);
    }
    else if (sscanf(tmp, "keyboard take %d", &domid) == 1)
    {
        struct domain *src_domain = domain_with(domid, &domid);
        if (!src_domain)
        {
            error("domain %d doesn't exist", domid);
            return;
        }
        input_give_keyboard_from_domain(src_domain, d);
    }
    else if (strcmp("keyboard release", tmp) == 0)
    {
        input_return_keyboard(d);
    }
    else if (sscanf(tmp, "keyboard release %d", &domid) == 1)
    {
        struct domain *dest_domain = domain_with(domid, &domid);
        if (!dest_domain)
        {
            error("domain %d doesn't exist", domid);
            return;
        }
        input_return_keyboard_to_domain(dest_domain, d);
    }

    xenstore_write("", path);
    free(tmp);
}
Exemple #16
0
void netfe_init(void)
{
	int index = 0;
	netfe_t **link = &net_front_ends;

	while (1)
	{
		int n;
		char xs_key[256];
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/backend-id", index);
		int rs = xenstore_read_int(&n, xs_key);
		if (rs != 0)
			break;

		// FE/(index) is present
		domid_t backend_id = (domid_t)n;

		netfe_t *fe = (netfe_t *)mm_alloc_pages(PSIZE(sizeof(netfe_t)));
		memset(fe, 0, sizeof(*fe));
		
		// setup shared rings
		fe->rxs = (netif_rx_sring_t *)mm_alloc_page();
		assert(fe->rxs != 0);
		fe->txs = (netif_tx_sring_t *)mm_alloc_page();
		assert(fe->txs != 0);

		SHARED_RING_INIT(fe->rxs);
		SHARED_RING_INIT(fe->txs);
	
		FRONT_RING_INIT(&fe->rx_ring, fe->rxs, PAGE_SIZE);
		FRONT_RING_INIT(&fe->tx_ring, fe->txs, PAGE_SIZE);
	
		grants_allow_access(&fe->rx_ref, backend_id, virt_to_mfn(fe->rxs));
		grants_allow_access(&fe->tx_ref, backend_id, virt_to_mfn(fe->txs));

		// set up receive buffers
		for (int i = 0; i < NR_RX_BUFFERS; i++)
		{
			fe->rx_buffers[i] = mm_alloc_page();
			assert(fe->rx_buffers[i] != 0);
			unsigned long mfn = virt_to_mfn(fe->rx_buffers[i]);
			grants_allow_access(&fe->rx_buf_refs[i], backend_id, mfn);
		}
	
		// set up send buffers
		fe->free_tx_head = NO_TX_BUFFER;
		for (int i = 0; i < NR_TX_BUFFERS; i++)
		{
			fe->tx_buffers[i] = mm_alloc_page();
			assert(fe->tx_buffers[i] != 0);
			unsigned long mfn = virt_to_mfn(fe->tx_buffers[i]);
			grants_allow_access(&fe->tx_buf_refs[i], backend_id, mfn);

			fe->free_tx_bufs[i] = fe->free_tx_head;
			fe->free_tx_head = i;
		}
	
		// set up interrupt
		fe->evtchn = event_alloc_unbound(backend_id);
		event_bind(fe->evtchn, netfe_int, (void *)fe);
	
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/rx-ring-ref", index);
		rs = xenstore_write_uint(xs_key, fe->rx_ref);
		assert(rs == 0);
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/tx-ring-ref", index);
		rs = xenstore_write_uint(xs_key, fe->tx_ref);
		assert(rs == 0);
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/event-channel", index);
		rs = xenstore_write_uint(xs_key, fe->evtchn);
		assert(rs == 0);
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/request-rx-copy", index);
		rs = xenstore_write(xs_key, "1");
		assert(rs == 0);
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/feature-no-csum-offload", index);
		rs = xenstore_write(xs_key, "1");
		assert(rs == 0);
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/feature-rx-notify", index);
		rs = xenstore_write(xs_key, "1");
		assert(rs == 0);
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/state", index);
		rs = xenstore_write(xs_key, "4");	// XenbusStateConnected
		assert(rs == 0);

		// read MAC address
		char buf[64];
		snprintf(xs_key, sizeof(xs_key), "device/vif/%d/mac", index);
		rs = xenstore_read(xs_key, buf, sizeof(buf));
		assert(rs == 0);
		rs = parse_mac(buf, fe->mac);
		assert(rs == 0);

		fe->mac_len = ETH_ALEN;
		printk("\reth%d: MAC %02x:%02x:%02x:%02x:%02x:%02x\r\n", index,
					fe->mac[0], fe->mac[1], fe->mac[2],
					fe->mac[3], fe->mac[4], fe->mac[5]);

		//
		// Publish EXT_RX_BUFFERS requests only and replenish then to this number
		// during each interrupt handler invocation.
		//
		for (int i = 0; i < EXT_RX_BUFFERS; i++)
		{
			netif_rx_request_t *req = RING_GET_REQUEST(&fe->rx_ring, fe->rx_ring.req_prod_pvt);
			req->id = i; //rx_id++;
			req->gref = fe->rx_buf_refs[i];
			fe->rx_ring.req_prod_pvt++;
		}

		RING_PUSH_REQUESTS(&fe->rx_ring);
		event_kick(fe->evtchn);	

		fe->index = index++;
		//fe->next = 0;

		//fe->attached_lwip_netif = 0;
		//fe->attached_outlet = 0;

		// add to net_front_ends list
		*link = fe;
		link = &fe->next;
	}

	num_net_front_ends = index;
}