~ubuntu-branches/ubuntu/vivid/mpich/vivid-proposed

« back to all changes in this revision

Viewing changes to src/pm/hydra/tools/topo/hwloc/hwloc/src/topology-xml.c

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2014-04-01 20:24:20 UTC
  • mfrom: (5.2.4 sid)
  • Revision ID: package-import@ubuntu.com-20140401202420-t5ey1ia2klt5dkq3
Tags: 3.1-4
* [c3e3398] Disable test_primitives, which is unreliable on some platforms.
            (Closes: #743047)
* [265a699] Add minimal autotest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright © 2009 CNRS
3
 
 * Copyright © 2009-2012 Inria.  All rights reserved.
 
3
 * Copyright © 2009-2013 Inria.  All rights reserved.
4
4
 * Copyright © 2009-2011 Université Bordeaux 1
5
5
 * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
6
6
 * See COPYING in top-level directory.
570
570
    }
571
571
  }
572
572
 
 
573
  if (obj->parent) {
 
574
    /* root->parent is NULL, and root is already inserted */
 
575
    hwloc_insert_object_by_parent(topology, obj->parent /* filled by the caller */, obj);
 
576
    /* insert_object_by_parent() doesn't merge during insert, so obj is still valid */
 
577
  }
 
578
 
573
579
  /* process subnodes */
574
580
  while (1) {
575
581
    struct hwloc__xml_import_state_s childstate;
584
590
 
585
591
    if (!strcmp(tag, "object")) {
586
592
      hwloc_obj_t childobj = hwloc_alloc_setup_object(HWLOC_OBJ_TYPE_MAX, -1);
587
 
      hwloc_insert_object_by_parent(topology, obj, childobj);
 
593
      childobj->parent = obj; /* store the parent pointer for use in insert() below */
588
594
      ret = hwloc__xml_import_object(topology, data, childobj, &childstate);
589
595
    } else if (!strcmp(tag, "page_type")) {
590
596
      ret = hwloc__xml_import_pagetype(topology, obj, &childstate);
606
612
  return state->close_tag(state);
607
613
}
608
614
 
 
615
static int
 
616
hwloc__xml_import_diff_one(hwloc__xml_import_state_t state,
 
617
                           hwloc_topology_diff_t *firstdiffp,
 
618
                           hwloc_topology_diff_t *lastdiffp)
 
619
{
 
620
  char *type_s = NULL;
 
621
  char *obj_depth_s = NULL;
 
622
  char *obj_index_s = NULL;
 
623
  char *obj_attr_type_s = NULL;
 
624
/* char *obj_attr_index_s = NULL; unused for now */
 
625
  char *obj_attr_name_s = NULL;
 
626
  char *obj_attr_oldvalue_s = NULL;
 
627
  char *obj_attr_newvalue_s = NULL;
 
628
 
 
629
  while (1) {
 
630
    char *attrname, *attrvalue;
 
631
    if (state->next_attr(state, &attrname, &attrvalue) < 0)
 
632
      break;
 
633
    if (!strcmp(attrname, "type"))
 
634
      type_s = attrvalue;
 
635
    else if (!strcmp(attrname, "obj_depth"))
 
636
      obj_depth_s = attrvalue;
 
637
    else if (!strcmp(attrname, "obj_index"))
 
638
      obj_index_s = attrvalue;
 
639
    else if (!strcmp(attrname, "obj_attr_type"))
 
640
      obj_attr_type_s = attrvalue;
 
641
    else if (!strcmp(attrname, "obj_attr_index"))
 
642
      { /* obj_attr_index_s = attrvalue; unused for now */ }
 
643
    else if (!strcmp(attrname, "obj_attr_name"))
 
644
      obj_attr_name_s = attrvalue;
 
645
    else if (!strcmp(attrname, "obj_attr_oldvalue"))
 
646
      obj_attr_oldvalue_s = attrvalue;
 
647
    else if (!strcmp(attrname, "obj_attr_newvalue"))
 
648
      obj_attr_newvalue_s = attrvalue;
 
649
    else
 
650
      return -1;
 
651
  }
 
652
 
 
653
  if (type_s) {
 
654
    switch (atoi(type_s)) {
 
655
    default:
 
656
      break;
 
657
    case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR: {
 
658
      /* object attribute diff */
 
659
      hwloc_topology_diff_obj_attr_type_t obj_attr_type;
 
660
      hwloc_topology_diff_t diff;
 
661
 
 
662
      /* obj_attr mandatory generic attributes */
 
663
      if (!obj_depth_s || !obj_index_s || !obj_attr_type_s)
 
664
        break;
 
665
 
 
666
      /* obj_attr mandatory attributes common to all subtypes */
 
667
      if (!obj_attr_oldvalue_s || !obj_attr_newvalue_s)
 
668
        break;
 
669
 
 
670
      /* mandatory attributes for obj_attr_info subtype */
 
671
      obj_attr_type = atoi(obj_attr_type_s);
 
672
      if (obj_attr_type == HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO && !obj_attr_name_s)
 
673
        break;
 
674
 
 
675
      /* now we know we have everything we need */
 
676
      diff = malloc(sizeof(*diff));
 
677
      if (!diff)
 
678
        return -1;
 
679
      diff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
 
680
      diff->obj_attr.obj_depth = atoi(obj_depth_s);
 
681
      diff->obj_attr.obj_index = atoi(obj_index_s);
 
682
      memset(&diff->obj_attr.diff, 0, sizeof(diff->obj_attr.diff));
 
683
      diff->obj_attr.diff.generic.type = obj_attr_type;
 
684
 
 
685
      switch (atoi(obj_attr_type_s)) {
 
686
      case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE:
 
687
        diff->obj_attr.diff.uint64.oldvalue = strtoull(obj_attr_oldvalue_s, NULL, 0);
 
688
        diff->obj_attr.diff.uint64.newvalue = strtoull(obj_attr_newvalue_s, NULL, 0);
 
689
        break;
 
690
      case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO:
 
691
        diff->obj_attr.diff.string.name = strdup(obj_attr_name_s);
 
692
        /* fallthrough */
 
693
      case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME:
 
694
        diff->obj_attr.diff.string.oldvalue = strdup(obj_attr_oldvalue_s);
 
695
        diff->obj_attr.diff.string.newvalue = strdup(obj_attr_newvalue_s);
 
696
        break;
 
697
      }
 
698
 
 
699
      if (*firstdiffp)
 
700
        (*lastdiffp)->generic.next = diff;
 
701
      else
 
702
        *firstdiffp = diff;
 
703
      *lastdiffp = diff;
 
704
      diff->generic.next = NULL;
 
705
    }
 
706
    }
 
707
  }
 
708
 
 
709
  return state->close_tag(state);
 
710
}
 
711
 
 
712
int
 
713
hwloc__xml_import_diff(hwloc__xml_import_state_t state,
 
714
                       hwloc_topology_diff_t *firstdiffp)
 
715
{
 
716
  hwloc_topology_diff_t firstdiff = NULL, lastdiff = NULL;
 
717
  *firstdiffp = NULL;
 
718
 
 
719
  while (1) {
 
720
    struct hwloc__xml_import_state_s childstate;
 
721
    char *tag;
 
722
    int ret;
 
723
 
 
724
    ret = state->find_child(state, &childstate, &tag);
 
725
    if (ret < 0)
 
726
      return -1;
 
727
    if (!ret)
 
728
      break;
 
729
 
 
730
    if (!strcmp(tag, "diff")) {
 
731
      ret = hwloc__xml_import_diff_one(&childstate, &firstdiff, &lastdiff);
 
732
    } else
 
733
      ret = -1;
 
734
 
 
735
    if (ret < 0)
 
736
      return ret;
 
737
 
 
738
    state->close_child(&childstate);
 
739
  }
 
740
 
 
741
  *firstdiffp = firstdiff;
 
742
  return 0;
 
743
}
 
744
 
609
745
/***********************************
610
746
 ********* main XML import *********
611
747
 ***********************************/
612
748
 
613
 
static void
 
749
static int
614
750
hwloc_xml__handle_distances(struct hwloc_topology *topology,
615
751
                            struct hwloc_xml_backend_data_s *data)
616
752
{
617
753
  struct hwloc_xml_imported_distances_s *xmldist, *next = data->first_distances;
618
754
 
619
755
  if (!next)
620
 
    return;
 
756
    return 0;
621
757
 
622
758
  /* connect things now because we need levels to check/build, they'll be reconnected properly later anyway */
623
759
  hwloc_connect_children(topology->levels[0][0]);
624
 
  hwloc_connect_levels(topology);
 
760
  if (hwloc_connect_levels(topology) < 0)
 
761
    return -1;
625
762
 
626
763
  while ((xmldist = next) != NULL) {
627
764
    hwloc_obj_t root = xmldist->root;
652
789
    next = xmldist->next;
653
790
    free(xmldist);
654
791
  }
 
792
 
 
793
  return 0;
655
794
}
656
795
 
657
796
/* this canNOT be the first XML call */
691
830
  /* we could add "BackendSource=XML" to notify that XML was used between the actual backend and here */
692
831
 
693
832
  /* if we added some distances, we must check them, and make them groupable */
694
 
  hwloc_xml__handle_distances(topology, data);
 
833
  if (hwloc_xml__handle_distances(topology, data) < 0)
 
834
    goto err;
695
835
  data->first_distances = data->last_distances = NULL;
696
836
  topology->support.discovery->pu = 1;
697
837
 
701
841
 failed:
702
842
  if (data->look_failed)
703
843
    data->look_failed(data);
 
844
  if (hwloc__xml_verbose())
 
845
    fprintf(stderr, "XML component discovery failed.\n");
 
846
 err:
704
847
  hwloc_localeswitch_fini();
705
848
  return -1;
706
849
}
707
850
 
 
851
/* this can be the first XML call */
 
852
int
 
853
hwloc_topology_diff_load_xml(hwloc_topology_t topology __hwloc_attribute_unused,
 
854
                             const char *xmlpath,
 
855
                             hwloc_topology_diff_t *firstdiffp, char **refnamep)
 
856
{
 
857
  hwloc_localeswitch_declare;
 
858
  char *env;
 
859
  int force_nolibxml;
 
860
  int ret;
 
861
 
 
862
  if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
 
863
    errno = ENOSYS;
 
864
    return -1;
 
865
  }
 
866
 
 
867
  hwloc_localeswitch_init();
 
868
 
 
869
  *firstdiffp = NULL;
 
870
 
 
871
  env = getenv("HWLOC_NO_LIBXML_IMPORT");
 
872
  force_nolibxml = (env && atoi(env));
 
873
retry:
 
874
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
 
875
    ret = hwloc_nolibxml_callbacks->import_diff(xmlpath, NULL, 0, firstdiffp, refnamep);
 
876
  else {
 
877
    ret = hwloc_libxml_callbacks->import_diff(xmlpath, NULL, 0, firstdiffp, refnamep);
 
878
    if (ret < 0 && errno == ENOSYS) {
 
879
      hwloc_libxml_callbacks = NULL;
 
880
      goto retry;
 
881
    }
 
882
  }
 
883
 
 
884
  hwloc_localeswitch_fini();
 
885
  return ret;
 
886
}
 
887
 
 
888
/* this can be the first XML call */
 
889
int
 
890
hwloc_topology_diff_load_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_unused,
 
891
                                   const char *xmlbuffer, int buflen,
 
892
                                   hwloc_topology_diff_t *firstdiffp, char **refnamep)
 
893
{
 
894
  hwloc_localeswitch_declare;
 
895
  char *env;
 
896
  int force_nolibxml;
 
897
  int ret;
 
898
 
 
899
  if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
 
900
    errno = ENOSYS;
 
901
    return -1;
 
902
  }
 
903
 
 
904
  hwloc_localeswitch_init();
 
905
 
 
906
  *firstdiffp = NULL;
 
907
 
 
908
  env = getenv("HWLOC_NO_LIBXML_IMPORT");
 
909
  force_nolibxml = (env && atoi(env));
 
910
retry:
 
911
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
 
912
    ret = hwloc_nolibxml_callbacks->import_diff(NULL, xmlbuffer, buflen, firstdiffp, refnamep);
 
913
  else {
 
914
    ret = hwloc_libxml_callbacks->import_diff(NULL, xmlbuffer, buflen, firstdiffp, refnamep);
 
915
    if (ret < 0 && errno == ENOSYS) {
 
916
      hwloc_libxml_callbacks = NULL;
 
917
      goto retry;
 
918
    }
 
919
  }
 
920
 
 
921
  hwloc_localeswitch_fini();
 
922
  return ret;
 
923
}
 
924
 
708
925
/************************************************
709
926
 ********* XML export (common routines) *********
710
927
 ************************************************/
914
1131
  state.end_object(&state, "object");
915
1132
}
916
1133
 
 
1134
void
 
1135
hwloc__xml_export_diff(hwloc__xml_export_state_t parentstate, hwloc_topology_diff_t diff)
 
1136
{
 
1137
  while (diff) {
 
1138
    struct hwloc__xml_export_state_s state;
 
1139
    char tmp[255];
 
1140
 
 
1141
    parentstate->new_child(parentstate, &state, "diff");
 
1142
 
 
1143
    sprintf(tmp, "%u", diff->generic.type);
 
1144
    state.new_prop(&state, "type", tmp);
 
1145
 
 
1146
    switch (diff->generic.type) {
 
1147
    case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR:
 
1148
      sprintf(tmp, "%d", diff->obj_attr.obj_depth);
 
1149
      state.new_prop(&state, "obj_depth", tmp);
 
1150
      sprintf(tmp, "%u", diff->obj_attr.obj_index);
 
1151
      state.new_prop(&state, "obj_index", tmp);
 
1152
 
 
1153
      sprintf(tmp, "%u", diff->obj_attr.diff.generic.type);
 
1154
      state.new_prop(&state, "obj_attr_type", tmp);
 
1155
 
 
1156
      switch (diff->obj_attr.diff.generic.type) {
 
1157
      case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE:
 
1158
        sprintf(tmp, "%llu", (unsigned long long) diff->obj_attr.diff.uint64.index);
 
1159
        state.new_prop(&state, "obj_attr_index", tmp);
 
1160
        sprintf(tmp, "%llu", (unsigned long long) diff->obj_attr.diff.uint64.oldvalue);
 
1161
        state.new_prop(&state, "obj_attr_oldvalue", tmp);
 
1162
        sprintf(tmp, "%llu", (unsigned long long) diff->obj_attr.diff.uint64.newvalue);
 
1163
        state.new_prop(&state, "obj_attr_newvalue", tmp);
 
1164
        break;
 
1165
      case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME:
 
1166
      case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO:
 
1167
        if (diff->obj_attr.diff.string.name)
 
1168
          state.new_prop(&state, "obj_attr_name", diff->obj_attr.diff.string.name);
 
1169
        state.new_prop(&state, "obj_attr_oldvalue", diff->obj_attr.diff.string.oldvalue);
 
1170
        state.new_prop(&state, "obj_attr_newvalue", diff->obj_attr.diff.string.newvalue);
 
1171
        break;
 
1172
      }
 
1173
 
 
1174
      break;
 
1175
    default:
 
1176
      assert(0);
 
1177
    }
 
1178
    state.end_object(&state, "diff");
 
1179
 
 
1180
    diff = diff->generic.next;
 
1181
  }
 
1182
}
 
1183
 
917
1184
/**********************************
918
1185
 ********* main XML export ********
919
1186
 **********************************/
935
1202
 
936
1203
  env = getenv("HWLOC_NO_LIBXML_EXPORT");
937
1204
  force_nolibxml = (env && atoi(env));
 
1205
retry:
938
1206
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
939
1207
    ret = hwloc_nolibxml_callbacks->export_file(topology, filename);
940
 
  else
 
1208
  else {
941
1209
    ret = hwloc_libxml_callbacks->export_file(topology, filename);
 
1210
    if (ret < 0 && errno == ENOSYS) {
 
1211
      hwloc_libxml_callbacks = NULL;
 
1212
      goto retry;
 
1213
    }
 
1214
  }
942
1215
 
943
1216
  hwloc_localeswitch_fini();
944
1217
  return ret;
961
1234
 
962
1235
  env = getenv("HWLOC_NO_LIBXML_EXPORT");
963
1236
  force_nolibxml = (env && atoi(env));
 
1237
retry:
964
1238
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
965
1239
    ret = hwloc_nolibxml_callbacks->export_buffer(topology, xmlbuffer, buflen);
966
 
  else
 
1240
  else {
967
1241
    ret = hwloc_libxml_callbacks->export_buffer(topology, xmlbuffer, buflen);
 
1242
    if (ret < 0 && errno == ENOSYS) {
 
1243
      hwloc_libxml_callbacks = NULL;
 
1244
      goto retry;
 
1245
    }
 
1246
  }
 
1247
 
 
1248
  hwloc_localeswitch_fini();
 
1249
  return ret;
 
1250
}
 
1251
 
 
1252
/* this can be the first XML call */
 
1253
int
 
1254
hwloc_topology_diff_export_xml(hwloc_topology_t topology __hwloc_attribute_unused,
 
1255
                               hwloc_topology_diff_t diff, const char *refname,
 
1256
                               const char *filename)
 
1257
{
 
1258
  hwloc_localeswitch_declare;
 
1259
  hwloc_topology_diff_t tmpdiff;
 
1260
  char *env;
 
1261
  int force_nolibxml;
 
1262
  int ret;
 
1263
 
 
1264
  if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
 
1265
    errno = ENOSYS;
 
1266
    return -1;
 
1267
  }
 
1268
 
 
1269
  tmpdiff = diff;
 
1270
  while (tmpdiff) {
 
1271
    if (tmpdiff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX) {
 
1272
      errno = EINVAL;
 
1273
      return -1;
 
1274
    }
 
1275
    tmpdiff = tmpdiff->generic.next;
 
1276
  }
 
1277
 
 
1278
  hwloc_localeswitch_init();
 
1279
 
 
1280
  env = getenv("HWLOC_NO_LIBXML_EXPORT");
 
1281
  force_nolibxml = (env && atoi(env));
 
1282
retry:
 
1283
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
 
1284
    ret = hwloc_nolibxml_callbacks->export_diff_file(diff, refname, filename);
 
1285
  else {
 
1286
    ret = hwloc_libxml_callbacks->export_diff_file(diff, refname, filename);
 
1287
    if (ret < 0 && errno == ENOSYS) {
 
1288
      hwloc_libxml_callbacks = NULL;
 
1289
      goto retry;
 
1290
    }
 
1291
  }
 
1292
 
 
1293
  hwloc_localeswitch_fini();
 
1294
  return ret;
 
1295
}
 
1296
 
 
1297
/* this can be the first XML call */
 
1298
int
 
1299
hwloc_topology_diff_export_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_unused,
 
1300
                                     hwloc_topology_diff_t diff, const char *refname,
 
1301
                                     char **xmlbuffer, int *buflen)
 
1302
{
 
1303
  hwloc_localeswitch_declare;
 
1304
  hwloc_topology_diff_t tmpdiff;
 
1305
  char *env;
 
1306
  int force_nolibxml;
 
1307
  int ret;
 
1308
 
 
1309
  if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
 
1310
    errno = ENOSYS;
 
1311
    return -1;
 
1312
  }
 
1313
 
 
1314
  tmpdiff = diff;
 
1315
  while (tmpdiff) {
 
1316
    if (tmpdiff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX) {
 
1317
      errno = EINVAL;
 
1318
      return -1;
 
1319
    }
 
1320
    tmpdiff = tmpdiff->generic.next;
 
1321
  }
 
1322
 
 
1323
  hwloc_localeswitch_init();
 
1324
 
 
1325
  env = getenv("HWLOC_NO_LIBXML_EXPORT");
 
1326
  force_nolibxml = (env && atoi(env));
 
1327
retry:
 
1328
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
 
1329
    ret = hwloc_nolibxml_callbacks->export_diff_buffer(diff, refname, xmlbuffer, buflen);
 
1330
  else {
 
1331
    ret = hwloc_libxml_callbacks->export_diff_buffer(diff, refname, xmlbuffer, buflen);
 
1332
    if (ret < 0 && errno == ENOSYS) {
 
1333
      hwloc_libxml_callbacks = NULL;
 
1334
      goto retry;
 
1335
    }
 
1336
  }
968
1337
 
969
1338
  hwloc_localeswitch_fini();
970
1339
  return ret;
1037
1406
  hwloc__xml_export_state_t state = reserved;
1038
1407
  size_t encoded_length;
1039
1408
  char *encoded_buffer;
1040
 
  int ret;
 
1409
  int ret __hwloc_attribute_unused;
1041
1410
 
1042
1411
  if (name && hwloc__xml_export_check_buffer(name, strlen(name)) < 0) {
1043
1412
    errno = EINVAL;
1121
1490
 
1122
1491
  env = getenv("HWLOC_NO_LIBXML_IMPORT");
1123
1492
  force_nolibxml = (env && atoi(env));
 
1493
retry:
1124
1494
  if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
1125
1495
    err = hwloc_nolibxml_callbacks->backend_init(data, xmlpath, xmlbuffer, xmlbuflen);
1126
 
  else
 
1496
  else {
1127
1497
    err = hwloc_libxml_callbacks->backend_init(data, xmlpath, xmlbuffer, xmlbuflen);
 
1498
    if (err < 0 && errno == ENOSYS) {
 
1499
      hwloc_libxml_callbacks = NULL;
 
1500
      goto retry;
 
1501
    }
 
1502
  }
1128
1503
  if (err < 0)
1129
1504
    goto out_with_data;
1130
1505
 
1141
1516
static struct hwloc_disc_component hwloc_xml_disc_component = {
1142
1517
  HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
1143
1518
  "xml",
1144
 
  HWLOC_DISC_COMPONENT_TYPE_CPU | HWLOC_DISC_COMPONENT_TYPE_GLOBAL | HWLOC_DISC_COMPONENT_TYPE_ADDITIONAL,
 
1519
  ~0,
1145
1520
  hwloc_xml_component_instantiate,
1146
1521
  30,
1147
1522
  NULL