+ struct list_head head;
+ struct lnet_process_id *ids;
+ char *name;
+ unsigned feats = session_features;
+ int count;
+ int rc;
+ int i;
+ bool nodes_added = false;
+
+ if (session_key == 0) {
+ fprintf(stderr,
+ "Can't find env LST_SESSION or value is not valid\n");
+ return -1;
+ }
+
+ if (argc < 3) {
+ lst_print_usage(argv[0]);
+ return -1;
+ }
+
+ name = argv[1];
+ if (strlen(name) >= LST_NAME_SIZE) {
+ fprintf(stderr, "Name length is limited to %d\n",
+ LST_NAME_SIZE - 1);
+ return -1;
+ }
+
+ rc = lst_add_group_ioctl(name);
+ if (rc != 0) {
+ lst_print_error("group", "Failed to add group %s: %s\n",
+ name, strerror(errno));
+ return -1;
+ }
+
+ INIT_LIST_HEAD(&head);
+
+ for (i = 2; i < argc; i++) {
+ /* parse address list */
+ rc = lst_parse_nids(argv[i], &count, &ids);
+ if (rc < 0) {
+ fprintf(stderr, "Ignore invalid id list %s\n",
+ argv[i]);
+ continue;
+ }
+
+ if (count == 0)
+ continue;
+
+ rc = lst_alloc_rpcent(&head, count, 0);
+ if (rc != 0) {
+ fprintf(stderr, "Out of memory\n");
+ free(ids);
+ rc = -1;
+ goto failed;
+ }
+
+ rc = lst_add_nodes_ioctl(name, count, ids, &feats, &head);
+
+ free(ids);
+
+ if (rc != 0)
+ goto failed;
+
+ fprintf(stdout, "%s are added to session\n", argv[i]);
+
+ nodes_added = true;
+
+ if ((feats & session_features) != session_features) {
+ fprintf(stdout,
+ "Warning, this session will run with "
+ "compatible mode because some test nodes "
+ "might not understand these features: %x\n",
+ (~feats & session_features));
+ }
+
+ lst_free_rpcent(&head);
+ }
+
+ if (!nodes_added) {
+ /*
+ * The selftest kernel module expects that a group should
+ * have at least one node, since it doesn't make sense for
+ * an empty group to be added to a test.
+ */
+ fprintf(stderr,
+ "No nodes added successfully, deleting group %s\n",
+ name);
+ rc = lst_del_group(name);
+ if (rc != 0) {
+ fprintf(stderr,
+ "Failed to delete group %s."
+ " Group is empty.\n", name);
+ }
+ }
+
+ return rc;
+
+failed:
+ if (rc == -1) {
+ lst_print_error("group", "Failed to add nodes %s: %s\n",
+ argv[i], strerror(errno));
+
+ } else {
+ if (trans_stat.trs_fwk_errno == EPROTO) {
+ fprintf(stderr,
+ "test nodes might have different LST "
+ "features, please disable some features by "
+ "setting LST_FEATURES\n");
+ }
+
+ lst_print_transerr(&head, "create session");
+ }
+
+ lst_free_rpcent(&head);
+
+ if (!nodes_added) {
+ fprintf(stderr,
+ "No nodes added successfully, deleting group %s\n",
+ name);
+ if (lst_del_group(name) != 0) {
+ fprintf(stderr,
+ "Failed to delete group %s."
+ " Group is empty.\n", name);
+ }
+ }
+
+ return rc;