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; }
/** * 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; }