static int get_os_hp_devices(struct hpdev **hpdev_list)
{
    struct hpdev *hp_list = NULL;
    struct hpdev *hpdev;
    DIR *d;
    struct dirent *de;
    int rc = 0;

    d = opendir(SYSFS_PCI_DEV_PATH);
    if (!d) {
        say(ERROR, "Failed to open %s\n", SYSFS_PCI_DEV_PATH);
        return -1;
    }

    while ((de = readdir(d)) != NULL) {
        if (is_dot_dir(de->d_name))
            continue;

        hpdev = zalloc(sizeof(*hpdev));
        if (!hpdev) {
            rc = -1;
            break;
        }

        rc = sprintf(hpdev->path, "%s/%s", SYSFS_PCI_DEV_PATH,
                     de->d_name);
        if (rc < 0)
            break;

        rc = get_str_attribute(hpdev->path, "devspec", hpdev->devspec,
                               256);
        if (rc)
            break;

        say(DEBUG, "HPDEV: %s\n       %s\n", hpdev->path,
            hpdev->devspec);
        hpdev->next = hp_list;
        hp_list = hpdev;
    }

    closedir(d);

    if (rc) {
        free_hpdev_list(hp_list);
        hp_list = NULL;
    }

    *hpdev_list = hp_list;
    return rc;
}
/**
 * add_linux_devices
 *
 */
static void
add_linux_devices(char *start_dir, struct dr_node *node_list)
{
	struct dirent *de;
	DIR *d;
	char *dir;
	int rc;

	if (start_dir == NULL)
		dir = "/sys/devices";
	else
		dir = start_dir;

	d = opendir(dir);
	if (d == NULL) {
		say(ERROR, "failed to open %s\n%s\n", dir, strerror(errno));
		return;
	}

	while ((de = readdir(d)) != NULL) {
		char buf[1024];

		if (is_dot_dir(de->d_name))
			continue;

		if (de->d_type == DT_DIR) {
			sprintf(buf, "%s/%s", dir, de->d_name);
			add_linux_devices(buf, node_list);
		} else if (! strcmp(de->d_name, "devspec")) {
			char devspec[DR_PATH_MAX];

			sprintf(buf, "%s/%s", dir, de->d_name);
			rc = get_str_attribute(buf, NULL, devspec, DR_PATH_MAX);
			if (rc == 0)
				rc = correlate_devspec(dir, devspec, node_list);
		}
	}
	closedir(d);
}
int
drmig_chrp_pmig(struct options *opts)
{
    int rc;
    char *cmd = opts->p_option;
    char sys_src[20];
    uint64_t stream_val;

    /* Ensure that this partition is migratable/mobile */
    if (! pmig_capable()) {
        fprintf(stderr, "drmig_chrp_pmig: Partition Mobility is not "
                "supported on this kernel.\n");
        return -1;
    }

    /* Today we do no pre-checks for migratability. The only check
     * we could do is whether the "ibm,suspend-me" RTAS call exists.
     * But if it doesn't, the firmware level doesn't support migration,
     * in which case why the heck are we being invoked anyways.
     */
    if (strcmp(cmd, "check") == 0) {
        say(DEBUG, "check: Nothing to do...\n");
        return 0;
    }

    /* The only other command is pre, any other command is invalid */
    if (strcmp(cmd, "pre")) {
        say(DEBUG, "Invalid command \"%s\" specified\n", cmd);
        return 1;
    }

    if (opts->usr_drc_name == NULL) {
        say(ERROR, "No streamid specified\n");
        return -1;
    }

    errno = 0;
    stream_val = strtoull(opts->usr_drc_name, NULL, 16);
    if (errno != 0) {
        say(ERROR, "Invalid streamid specified: %s\n", strerror(errno));
        return -1;
    }

    /* Get the ID of the original system, for later logging */
    get_str_attribute(OFDT_BASE, "system-id", sys_src, 20);
    sleep(5);

    /* Now do the actual migration */
    do {
        if (action == MIGRATE)
            rc = do_migration(stream_val);
        else if (action == HIBERNATE)
            rc = do_hibernation(stream_val);
        else
            rc = -EINVAL;

        if (rc == NOT_SUSPENDABLE)
            sleep(1);

    } while (rc == NOT_SUSPENDABLE);

    syslog(LOG_LOCAL0 | LOG_INFO, "drmgr: %s rc %d\n",
           (action == MIGRATE ? "migration" : "hibernation"), rc);
    if (rc)
        return rc;

    post_mobility_update(action);

    say(DEBUG, "Refreshing RMC via refrsrc\n");
    rc = system("/usr/sbin/rsct/bin/refrsrc IBM.ManagementServer");

    return 0;
}
Beispiel #4
0
/**
 * get_lmbs
 * @brief Build a list of all possible lmbs for the system
 *
 * @param sort LMB_NORMAL_SORT or LMB_REVERSE_SORT to control sort order
 *
 * @return list of lmbs, NULL on failure
 */
struct lmb_list_head *
get_lmbs(unsigned int sort)
{
	struct lmb_list_head *lmb_list = NULL;
	struct dr_node *lmb = NULL;
	struct stat sbuf;
	char buf[DR_STR_MAX];
	int rc = 0;

	lmb_list = zalloc(sizeof(*lmb_list));
	if (lmb_list == NULL) {
		say(DEBUG, "Could not allocate LMB list head\n");
		return NULL;
	}

	lmb_list->sort = sort;

	rc = get_str_attribute("/sys/devices/system/memory",
			       "/block_size_bytes", &buf, DR_STR_MAX);
	if (rc) {
		say(DEBUG,
		    "Could not determine block size bytes for memory.\n");
		free_lmbs(lmb_list);
		return NULL;
	}

	block_sz_bytes = strtoul(buf, NULL, 16);

	/* We also need to know which lmbs are already allocated to
	 * the system and their corresponding memory sections as defined
	 * by sysfs.  Walk the device tree and update the appropriate
	 * lmb entries (and their memory sections) as we find their device
	 * tree entries.
	 */
	if (stat(DYNAMIC_RECONFIG_MEM, &sbuf)) {
		struct dr_connector *drc_list, *drc;

		drc_list = get_drc_info(OFDT_BASE);
		if (drc_list == NULL) {
			report_unknown_error(__FILE__, __LINE__);
			rc = -1;
		} else {
			/* For memory dlpar, we need a list of all
			 * posiible memory nodes for the system, initalize
			 * those here.
			 */
			for (drc = drc_list; drc; drc = drc->next) {
				if (strncmp(drc->name, "LMB", 3))
					continue;

				lmb = lmb_list_add(drc->index, lmb_list);
				if (!lmb) {
					say(ERROR, "Failed to add LMB (%x)\n",
					    drc->index);
					rc = -1;
					break;
				}

				lmb_list->lmbs_found++;
			}
		}

		say(INFO, "Maximum of %d LMBs\n", lmb_list->lmbs_found);
		rc = get_mem_node_lmbs(lmb_list);
	} else {
		/* A small hack to here to allow memory add to work in
		 * certain kernels.  Due to a bug in the kernel (see comment
		 * in acquire_lmb()) we need to get lmb info from both places.
		 * For a good kernel, the get_mem_node_lmbs routine will not
		 * update the lmb_list.
		 */
		rc = get_dynamic_reconfig_lmbs(lmb_list);
		if (! rc)
			rc = get_mem_node_lmbs(lmb_list);
	}

	if (rc) {
		free_lmbs(lmb_list);
		lmb_list = NULL;
	} else if (sort == LMB_RANDOM_SORT) {
		shuffle_lmbs(lmb_list);
	}

	return lmb_list;
}