Пример #1
0
static bool get_script(const char *path, xmlNodePtr ptr)
{
   if (gl_script_program)
   {
      RARCH_ERR("Script already imported.\n");
      return false;
   }

   char script_class[64];
   xml_get_prop(script_class, sizeof(script_class), ptr, "class");
   if (*script_class)
      strlcpy(gl_tracker_script_class, script_class, sizeof(gl_tracker_script_class));

   char language[64];
   xml_get_prop(language, sizeof(language), ptr, "language");
   if (strcmp(language, "python") != 0)
   {
      RARCH_ERR("Script language is not Python.\n");
      return false;
   }

   char *script = xml_get_content(ptr);
   if (!script)
      return false;

   gl_script_program = xml_replace_if_file(script, path, ptr, "src"); 
   if (!gl_script_program)
   {
      RARCH_ERR("Cannot find Python script.\n");
      return false;
   }

   return true;
}
Пример #2
0
	xml_conf_xpath_result_for_each(xmldisk_set, xmldisk, i)
	{
	    const char *path_prop;
	    const char *node_name;
	    char path[EXA_MAXSIZE_DEVPATH + 1];
	    struct adm_disk *disk;
	    struct adm_node *node;

	    node_name = xml_get_prop(xmldisk, "node");
	    node = adm_cluster_get_node_by_name(node_name);
	    if (!node)
	    {
		set_error(err_desc, -ADMIND_ERR_UNKNOWN_NODENAME,
			  "Node '%s' is not part of the cluster.", node_name);
		xml_conf_xpath_free(xmldisk_set);
		return;
	    }

	    path_prop = xml_get_prop(xmldisk, "path");
	    os_disk_normalize_path(path_prop, path, sizeof(path));

	    exalog_debug("Checking rdev '%s:%s' is not already used", node_name, path);

	    if (info->nb_disks >= NBMAX_DISKS_PER_GROUP)
	    {
		set_error(err_desc, -ADMIND_ERR_TOO_MANY_DISKS_IN_GROUP,
			  "too many disks in group (> %d)", NBMAX_DISKS_PER_GROUP);
		xml_conf_xpath_free(xmldisk_set);
		return;
	    }

	    disk = adm_cluster_get_disk_by_path(node_name, path);
	    if (!disk)
	    {
		set_error(err_desc, -ADMIND_ERR_UNKNOWN_DISK,
			  "disk '%s:%s' is unknown", node_name, path);
		xml_conf_xpath_free(xmldisk_set);
		return;
	    }

	    uuid_copy(&info->disks[info->nb_disks], &disk->uuid);
	    info->nb_disks++;
	}
Пример #3
0
/**
 * Extracts an unsigned int value from a XML node
 */
static int xml_get_uint_prop(const xmlNodePtr xml_node, const char *prop_name,
                             uint32_t *prop_val, cl_error_desc_t *err_desc)
{
    const char *val_str = xml_get_prop(xml_node, prop_name);
    if (sscanf(val_str, "%u", prop_val) != 1)
    {
        set_error(err_desc, -EXA_ERR_XML_GET,
                  "Inappropriate value '%s' for parameter '%s'", val_str, prop_name);
        return -1;
    }

    return 0;
}
Пример #4
0
int main(int argc, char *argv[])
{
    xmlDocPtr doc   = NULL;
	xmlChar *result = NULL;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <xmlfile>\n", argv[0]);
        return -1;
    }

    doc = xml_get_doc(argv[1]);
    if (doc == NULL) {
        xmlCleanupParser();
        return -1;
    }

    result = xml_get_value(doc, "//Format/meta/good");
    if (result == NULL)
        fprintf(stderr, "Not found\n");
    else {
        fprintf(stdout, "result = %s\n", result);
        xmlFree(result);
    }

    result = xml_get_prop(doc, "//Format", "FmtName");
    if (result == NULL)
        fprintf(stderr, "Not found\n");
    else {
        fprintf(stdout, "prop result: %s\n", result);
        xmlFree(result);
    }

    result = xml_doc_to_string(doc);
    if (result == NULL)
        fprintf(stderr, "Not fount\n");
    else {
        fprintf(stdout, "result = %s\n", result);
        xmlFree(result);
    }

    xmlFreeDoc(doc);
    xmlCleanupParser();

	return 0;
}
Пример #5
0
static char *xml_replace_if_file(char *content, const char *path, xmlNodePtr node, const char *src_prop)
{
   char prop[64];
   if (!xml_get_prop(prop, sizeof(prop), node, src_prop))
      return content;

   free(content);
   content = NULL;

   char shader_path[PATH_MAX];
   fill_pathname_resolve_relative(shader_path, path, (const char*)prop, sizeof(shader_path));

   RARCH_LOG("Loading external source from \"%s\".\n", shader_path);
   if (read_file(shader_path, (void**)&content) >= 0)
      return content;
   else
      return NULL;
}
Пример #6
0
static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size)
{
   LIBXML_TEST_VERSION;

   xmlParserCtxtPtr ctx = xmlNewParserCtxt();
   if (!ctx)
   {
      RARCH_ERR("Failed to load libxml2 context.\n");
      return false;
   }

   RARCH_LOG("Loading XML shader: %s\n", path);
   xmlDocPtr doc = xmlCtxtReadFile(ctx, path, NULL, 0);
   xmlNodePtr head = NULL;
   xmlNodePtr cur = NULL;
   unsigned num = 0;

   if (!doc)
   {
      RARCH_ERR("Failed to parse XML file: %s\n", path);
      goto error;
   }

#ifdef HAVE_LIBXML2
   if (ctx->valid == 0)
   {
      RARCH_ERR("Cannot validate XML shader: %s\n", path);
      goto error;
   }
#endif

   head = xmlDocGetRootElement(doc);

   for (cur = head; cur; cur = cur->next)
   {
      if (cur->type != XML_ELEMENT_NODE)
         continue;
      if (strcmp((const char*)cur->name, "shader") != 0)
         continue;

      char attr[64];
      xml_get_prop(attr, sizeof(attr), cur, "language");
      if (strcmp(attr, "GLSL") != 0)
         continue;

      xml_get_prop(attr, sizeof(attr), cur, "style");
      glsl_modern = strcmp(attr, "GLES2") == 0;

      if (glsl_modern)
         RARCH_LOG("[GL]: Shader reports a GLES2 style shader.\n");
      break;
   }

   if (!cur) // We couldn't find any GLSL shader :(
      goto error;

   memset(prog, 0, sizeof(struct shader_program) * size);

   // Iterate to check if we find fragment and/or vertex shaders.
   for (cur = cur->children; cur && num < size; cur = cur->next)
   {
      if (cur->type != XML_ELEMENT_NODE)
         continue;

      char *content = xml_get_content(cur);
      if (!content)
         continue;

      if (strcmp((const char*)cur->name, "vertex") == 0)
      {
         if (prog[num].vertex)
         {
            RARCH_ERR("Cannot have more than one vertex shader in a program.\n");
            free(content);
            goto error;
         }

         content = xml_replace_if_file(content, path, cur, "src");
         if (!content)
         {
            RARCH_ERR("Shader source file was provided, but failed to read.\n");
            goto error;
         }

         prog[num].vertex = content;
      }
      else if (strcmp((const char*)cur->name, "fragment") == 0)
      {
         if (glsl_modern && !prog[num].vertex)
         {
            RARCH_ERR("Modern GLSL was chosen and vertex shader was not provided. This is an error.\n");
            free(content);
            goto error;
         }

         content = xml_replace_if_file(content, path, cur, "src");
         if (!content)
         {
            RARCH_ERR("Shader source file was provided, but failed to read.\n");
            goto error;
         }

         prog[num].fragment = content;
         if (!get_xml_attrs(&prog[num], cur))
         {
            RARCH_ERR("XML shader attributes do not comply with specifications.\n");
            goto error;
         }
         num++;
      }
      else if (strcmp((const char*)cur->name, "texture") == 0)
      {
         free(content);
         if (!get_texture_image(path, cur))
         {
            RARCH_ERR("Texture image failed to load.\n");
            goto error;
         }
      }
      else if (strcmp((const char*)cur->name, "import") == 0)
      {
         free(content);
         if (!get_import_value(cur))
         {
            RARCH_ERR("Import value is invalid.\n");
            goto error;
         }
      }
#ifdef HAVE_PYTHON
      else if (strcmp((const char*)cur->name, "script") == 0)
      {
         free(content);
         if (!get_script(path, cur))
         {
            RARCH_ERR("Script is invalid.\n");
            goto error;
         }
      }
#endif
   }

   if (num == 0)
   {
      RARCH_ERR("Couldn't find vertex shader nor fragment shader in XML file.\n");
      goto error;
   }

   xmlFreeDoc(doc);
   xmlFreeParserCtxt(ctx);
   return num;

error:
   RARCH_ERR("Failed to load XML shader ...\n");
   if (doc)
      xmlFreeDoc(doc);
   xmlFreeParserCtxt(ctx);
   return 0;
}
Пример #7
0
static bool get_import_value(xmlNodePtr ptr)
{
   if (gl_tracker_info_cnt >= MAX_VARIABLES)
   {
      RARCH_ERR("Too many import variables ...\n");
      return false;
   }

   char id[64], semantic[64], wram[64], input[64], bitmask[64], bitequal[64];
   xml_get_prop(id, sizeof(id), ptr, "id");
   xml_get_prop(semantic, sizeof(semantic), ptr, "semantic");
   xml_get_prop(wram, sizeof(wram), ptr, "wram");
   xml_get_prop(input, sizeof(input), ptr, "input_slot");
   xml_get_prop(bitmask, sizeof(bitmask), ptr, "mask");
   xml_get_prop(bitequal, sizeof(bitequal), ptr, "equal");

   unsigned memtype;
   enum state_tracker_type tracker_type;
   enum state_ram_type ram_type = RARCH_STATE_NONE;
   uint32_t addr = 0;
   unsigned mask_value = 0;
   unsigned mask_equal = 0;

   if (!*semantic || !*id)
   {
      RARCH_ERR("No semantic or ID for import value.\n");
      return false;
   }

   if (strcmp(semantic, "capture") == 0)
      tracker_type = RARCH_STATE_CAPTURE;
   else if (strcmp(semantic, "capture_previous") == 0)
      tracker_type = RARCH_STATE_CAPTURE_PREV;
   else if (strcmp(semantic, "transition") == 0)
      tracker_type = RARCH_STATE_TRANSITION;
   else if (strcmp(semantic, "transition_count") == 0)
      tracker_type = RARCH_STATE_TRANSITION_COUNT;
   else if (strcmp(semantic, "transition_previous") == 0)
      tracker_type = RARCH_STATE_TRANSITION_PREV;
#ifdef HAVE_PYTHON
   else if (strcmp(semantic, "python") == 0)
      tracker_type = RARCH_STATE_PYTHON;
#endif
   else
   {
      RARCH_ERR("Invalid semantic for import value.\n");
      return false;
   }

#ifdef HAVE_PYTHON
   if (tracker_type != RARCH_STATE_PYTHON)
#endif
   {
      if (*input) 
      {
         unsigned slot = strtoul(input, NULL, 0);
         switch (slot)
         {
            case 1:
               ram_type = RARCH_STATE_INPUT_SLOT1;
               break;
            case 2:
               ram_type = RARCH_STATE_INPUT_SLOT2;
               break;

            default:
               RARCH_ERR("Invalid input slot for import.\n");
               return false;
         }
      }
      else if (*wram)
      {
         addr = strtoul(wram, NULL, 16);
         ram_type = RARCH_STATE_WRAM;
      }
      else
      {
         RARCH_ERR("No RAM address specificed for import value.\n");
         return false;
      }
   }

   switch (ram_type)
   {
      case RARCH_STATE_WRAM:
         memtype = RETRO_MEMORY_SYSTEM_RAM;
         break;

      default:
         memtype = -1u;
   }

   if ((memtype != -1u) && (addr >= pretro_get_memory_size(memtype)))
   {
      RARCH_ERR("Address out of bounds.\n");
      return false;
   }

   if (*bitmask)
      mask_value = strtoul(bitmask, NULL, 16);
   if (*bitequal)
      mask_equal = strtoul(bitequal, NULL, 16);

   strlcpy(gl_tracker_info[gl_tracker_info_cnt].id, id, sizeof(gl_tracker_info[0].id));
   gl_tracker_info[gl_tracker_info_cnt].addr = addr;
   gl_tracker_info[gl_tracker_info_cnt].type = tracker_type;
   gl_tracker_info[gl_tracker_info_cnt].ram_type = ram_type;
   gl_tracker_info[gl_tracker_info_cnt].mask = mask_value;
   gl_tracker_info[gl_tracker_info_cnt].equal = mask_equal;
   gl_tracker_info_cnt++;

   return true;
}
Пример #8
0
static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
{
   if (gl_teximage_cnt >= MAX_TEXTURES)
   {
      RARCH_WARN("Too many texture images. Ignoring ...\n");
      return true;
   }

   bool linear = true;
   char filename[PATH_MAX];
   char filter[64];
   char id[64];
   xml_get_prop(filename, sizeof(filename), ptr, "file");
   xml_get_prop(filter, sizeof(filter), ptr, "filter");
   xml_get_prop(id, sizeof(id), ptr, "id");
   struct texture_image img;

   if (!*id)
   {
      RARCH_ERR("Could not find ID in texture.\n");
      return false;
   }

   if (!*filename)
   {
      RARCH_ERR("Could not find filename in texture.\n");
      return false;
   }

   if (strcmp(filter, "nearest") == 0)
      linear = false;

   char tex_path[PATH_MAX];
   fill_pathname_resolve_relative(tex_path, shader_path, (const char*)filename, sizeof(tex_path));

   RARCH_LOG("Loading texture image from: \"%s\" ...\n", tex_path);

   if (!texture_image_load(tex_path, &img))
   {
      RARCH_ERR("Failed to load texture image from: \"%s\"\n", tex_path);
      return false;
   }

   strlcpy(gl_teximage_uniforms[gl_teximage_cnt], (const char*)id, sizeof(gl_teximage_uniforms[0]));

   glGenTextures(1, &gl_teximage[gl_teximage_cnt]);

   pglActiveTexture(GL_TEXTURE0 + gl_teximage_cnt + 1);
   glBindTexture(GL_TEXTURE_2D, gl_teximage[gl_teximage_cnt]);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, BORDER_FUNC);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, BORDER_FUNC);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);

   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
   glTexImage2D(GL_TEXTURE_2D,
         0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32,
         img.width, img.height, 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32,
         RARCH_GL_FORMAT32, img.pixels);

   pglActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, 0);
   free(img.pixels);

   gl_teximage_cnt++;

   return true;
}
Пример #9
0
static bool get_xml_attrs(struct shader_program *prog, xmlNodePtr ptr)
{
   prog->scale_x = 1.0;
   prog->scale_y = 1.0;
   prog->type_x = prog->type_y = RARCH_SCALE_INPUT;
   prog->valid_scale = false;

   // Check if shader forces a certain texture filtering.
   char attr[64];
   if (xml_get_prop(attr, sizeof(attr), ptr, "filter"))
   {
      if (strcmp(attr, "nearest") == 0)
      {
         prog->filter = RARCH_GL_NEAREST;
         RARCH_LOG("XML: Shader forces GL_NEAREST.\n");
      }
      else if (strcmp(attr, "linear") == 0)
      {
         prog->filter = RARCH_GL_LINEAR;
         RARCH_LOG("XML: Shader forces GL_LINEAR.\n");
      }
      else
         RARCH_WARN("XML: Invalid property for filter.\n");
   }
   else
      prog->filter = RARCH_GL_NOFORCE;

   // Check for scaling attributes *lots of code <_<*
   char attr_scale[64], attr_scale_x[64], attr_scale_y[64];
   char attr_size[64], attr_size_x[64], attr_size_y[64];
   char attr_outscale[64], attr_outscale_x[64], attr_outscale_y[64];

   xml_get_prop(attr_scale, sizeof(attr_scale), ptr, "scale");
   xml_get_prop(attr_scale_x, sizeof(attr_scale_x), ptr, "scale_x");
   xml_get_prop(attr_scale_y, sizeof(attr_scale_y), ptr, "scale_y");
   xml_get_prop(attr_size, sizeof(attr_size), ptr, "size");
   xml_get_prop(attr_size_x, sizeof(attr_size_x), ptr, "size_x");
   xml_get_prop(attr_size_y, sizeof(attr_size_y), ptr, "size_y");
   xml_get_prop(attr_outscale, sizeof(attr_outscale), ptr, "outscale");
   xml_get_prop(attr_outscale_x, sizeof(attr_outscale_x), ptr, "outscale_x");
   xml_get_prop(attr_outscale_y, sizeof(attr_outscale_y), ptr, "outscale_y");

   unsigned x_attr_cnt = 0, y_attr_cnt = 0;

   if (*attr_scale)
   {
      float scale = strtod(attr_scale, NULL);
      prog->scale_x = scale;
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_x = prog->type_y = RARCH_SCALE_INPUT;
      RARCH_LOG("Got scale attr: %.1f\n", scale);
      x_attr_cnt++;
      y_attr_cnt++;
   }

   if (*attr_scale_x)
   {
      float scale = strtod(attr_scale_x, NULL);
      prog->scale_x = scale;
      prog->valid_scale = true;
      prog->type_x = RARCH_SCALE_INPUT;
      RARCH_LOG("Got scale_x attr: %.1f\n", scale);
      x_attr_cnt++;
   }

   if (*attr_scale_y)
   {
      float scale = strtod(attr_scale_y, NULL);
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_y = RARCH_SCALE_INPUT;
      RARCH_LOG("Got scale_y attr: %.1f\n", scale);
      y_attr_cnt++;
   }
   
   if (*attr_size)
   {
      prog->abs_x = prog->abs_y = strtoul(attr_size, NULL, 0);
      prog->valid_scale = true;
      prog->type_x = prog->type_y = RARCH_SCALE_ABSOLUTE;
      RARCH_LOG("Got size attr: %u\n", prog->abs_x);
      x_attr_cnt++;
      y_attr_cnt++;
   }

   if (*attr_size_x)
   {
      prog->abs_x = strtoul(attr_size_x, NULL, 0);
      prog->valid_scale = true;
      prog->type_x = RARCH_SCALE_ABSOLUTE;
      RARCH_LOG("Got size_x attr: %u\n", prog->abs_x);
      x_attr_cnt++;
   }

   if (*attr_size_y)
   {
      prog->abs_y = strtoul(attr_size_y, NULL, 0);
      prog->valid_scale = true;
      prog->type_y = RARCH_SCALE_ABSOLUTE;
      RARCH_LOG("Got size_y attr: %u\n", prog->abs_y);
      y_attr_cnt++;
   }

   if (*attr_outscale)
   {
      float scale = strtod(attr_outscale, NULL);
      prog->scale_x = scale;
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_x = prog->type_y = RARCH_SCALE_VIEWPORT;
      RARCH_LOG("Got outscale attr: %.1f\n", scale);
      x_attr_cnt++;
      y_attr_cnt++;
   }

   if (*attr_outscale_x)
   {
      float scale = strtod(attr_outscale_x, NULL);
      prog->scale_x = scale;
      prog->valid_scale = true;
      prog->type_x = RARCH_SCALE_VIEWPORT;
      RARCH_LOG("Got outscale_x attr: %.1f\n", scale);
      x_attr_cnt++;
   }

   if (*attr_outscale_y)
   {
      float scale = strtod(attr_outscale_y, NULL);
      prog->scale_y = scale;
      prog->valid_scale = true;
      prog->type_y = RARCH_SCALE_VIEWPORT;
      RARCH_LOG("Got outscale_y attr: %.1f\n", scale);
      y_attr_cnt++;
   }

   if (x_attr_cnt > 1)
      return false;
   if (y_attr_cnt > 1)
      return false;

   return true;
}
Пример #10
0
gint
rc_extract_packages_from_undump_buffer (const guint8 *data, int len,
                                        RCChannelAndSubdFn channel_callback,
                                        RCPackageFn package_callback,
                                        RCPackageMatchFn lock_callback,
                                        gpointer user_data)
{

    xmlDoc *doc;
    xmlNode *dump_node;
    RCChannel *system_channel = NULL;
    RCChannel *current_channel = NULL;
    xmlNode *channel_node;
    int count = 0;

    doc = rc_parse_xml_from_buffer (data, len);
    if (doc == NULL)
        return -1;

    dump_node = xmlDocGetRootElement (doc);
    if (dump_node == NULL)
        return -1;

    if (g_strcasecmp (dump_node->name, "world")) {
        rc_debug (RC_DEBUG_LEVEL_WARNING,
                  "Unrecognized top-level node for undump: '%s'",
                  dump_node->name);
        return -1;
    }

    channel_node = dump_node->xmlChildrenNode;

    while (channel_node != NULL) {

        if (! g_strcasecmp (channel_node->name, "locks")) {
            xmlNode *lock_node = channel_node->xmlChildrenNode;

            while (lock_node) {
                RCPackageMatch *lock;

                lock = rc_package_match_from_xml_node (lock_node);

                if (lock_callback)
                    lock_callback (lock, user_data);

                lock_node = lock_node->next;
            }

        } else if (! g_strcasecmp (channel_node->name, "system_packages")) {

            int subcount;

            if (!system_channel) {
                system_channel = rc_channel_new ("@system",
                                                 "System Packages",
                                                 "@system",
                                                 "System Packages");
                rc_channel_set_system (system_channel);
                rc_channel_set_hidden (system_channel);
            }

            if (channel_callback)
                channel_callback (system_channel, FALSE, user_data);
            
            subcount = rc_extract_packages_from_xml_node (channel_node,
                                                          system_channel,
                                                          package_callback,
                                                          user_data);

            if (subcount < 0) {
                /* Do something clever */
                g_assert_not_reached ();
            }
            
            count += subcount;

        } else if (! g_strcasecmp (channel_node->name, "channel")) {

            char *name;
            char *alias;
            char *id_str;
            static guint32 dummy_id = 0xdeadbeef;
            char *subd_str;
            int subd;
            char *priority_str;
            char *priority_unsubd_str;
            
            name = xml_get_prop (channel_node, "name");
            alias = xml_get_prop (channel_node, "alias");
            
            id_str = xml_get_prop (channel_node, "id");
            if (id_str == NULL) {
                id_str = g_strdup_printf ("dummy:%d", dummy_id);
                ++dummy_id;
            }

            subd_str = xml_get_prop (channel_node, "subscribed");
            subd = subd_str ? atoi (subd_str) : 0;

            priority_str = xml_get_prop (channel_node, "priority_base");
            priority_unsubd_str = xml_get_prop (channel_node, "priority_unsubd");

            current_channel = rc_channel_new (id_str, name, alias, NULL);

            if (current_channel) {
                int subd_priority, unsubd_priority;

                subd_priority = priority_str ? atoi (priority_str) : 0;
                unsubd_priority = priority_unsubd_str ?
                    atoi (priority_unsubd_str) : 0;
                
                rc_channel_set_priorities (current_channel,
                                           subd_priority, unsubd_priority);

                if (channel_callback)
                    channel_callback (current_channel, subd, user_data);

                if (package_callback) {
                    int subcount;
                    subcount = rc_extract_packages_from_xml_node (channel_node,
                                                                  current_channel,
                                                                  package_callback,
                                                                  user_data);
                    if (subcount < 0) {
                        /* FIXME: do something clever */
                        g_assert_not_reached ();
                    }
                    count += subcount;
                }
            }

            g_free (name);
            g_free (alias);
            g_free (id_str);
            g_free (subd_str);

            g_free (priority_str);
            g_free (priority_unsubd_str);
        }

        channel_node = channel_node->next;
    }

    xmlFreeDoc (doc);

    return count;
}
Пример #11
0
static void
get_info_from_params(const struct dgcreate_params *params,
		     struct dgcreate_info *info,
		     cl_error_desc_t *err_desc)
{
    xmlDocPtr config;
    xmlNodePtr diskgroup_ptr;
    xmlAttrPtr attr;
    int i;

    EXA_ASSERT(params);
    EXA_ASSERT(info);
    EXA_ASSERT(err_desc);

    config = params->config;
    memset(info, 0, sizeof(*info));

    diskgroup_ptr = xml_conf_xpath_singleton(config, "/Exanodes/diskgroup");

    uuid_generate(&info->uuid);
    /* 0 means that the slot width will be automagically computed */
    info->slot_width = 0;
    info->chunk_size = adm_cluster_get_param_int("default_chunk_size");
    info->su_size = adm_cluster_get_param_int("default_su_size");
    info->dirty_zone_size = adm_cluster_get_param_int("default_dirty_zone_size");
    info->blended_stripes = false;
    info->nb_disks = 0;
    info->nb_spare = VRT_DEFAULT_NB_SPARES;
    info->layout[0] = '\0';

    for (attr = diskgroup_ptr->properties; attr != NULL; attr = attr->next)
    {
	if (xmlStrEqual(attr->name, BAD_CAST("name")))
	    strlcpy(info->name, xml_get_prop(diskgroup_ptr, "name"), EXA_MAXSIZE_GROUPNAME + 1);
	else if (xmlStrEqual(attr->name, BAD_CAST("layout")))
	    strlcpy(info->layout, xml_get_prop(diskgroup_ptr, "layout"), EXA_MAXSIZE_LAYOUTNAME + 1);
	else if (xmlStrEqual(attr->name, BAD_CAST("slot_width")))
	{
	    if (xml_get_uint_prop(diskgroup_ptr, "slot_width",
				  &info->slot_width, err_desc) != 0)
		return;
	    /* NOTE User can not give a zero value
	     * If slot_width is not provided, we pass zero
	     * to vrt so that it can calculate the proper slot_width
	     */
	    if (info->slot_width == 0)
	    {
		set_error(err_desc, -EXA_ERR_XML_GET,
			  "slot_width must be greater than zero");
		return;
	    }
	}
	else if (xmlStrEqual(attr->name, BAD_CAST("chunk_size")))
	{
	    if (xml_get_uint_prop(diskgroup_ptr, "chunk_size",
				  &info->chunk_size, err_desc) != 0)
		return;
	}
	else if (xmlStrEqual(attr->name, BAD_CAST("su_size")))
	{
	    if (xml_get_uint_prop(diskgroup_ptr, "su_size",
				  &info->su_size, err_desc) != 0)
		return;
	}
	else if (xmlStrEqual(attr->name, BAD_CAST("dirty_zone_size")))
	{
	    if (xml_get_uint_prop(diskgroup_ptr, "dirty_zone_size",
				  &info->dirty_zone_size, err_desc) != 0)
		return;
	}
	else if (xmlStrEqual(attr->name, BAD_CAST("blended_stripes")))
	{
	    if (xml_get_uint_prop(diskgroup_ptr, "blended_stripes",
				  &info->blended_stripes, err_desc) != 0)
		return;
	}
	else if (xmlStrEqual(attr->name, BAD_CAST("nb_spare")))
	{
	    if (xml_get_uint_prop(diskgroup_ptr, "nb_spare",
				  &info->nb_spare, err_desc) != 0)
		return;
	}
	else if (!xmlStrEqual(attr->name, BAD_CAST("cluster")))
	{
	    set_error(err_desc, -EXA_ERR_XML_GET,
		      "Unknown group property '%s'", (char *)attr->name);
	    return;
	}
    }

    /* Check the group name */
    if (info->name == NULL || info->name[0] == '\0')
    {
	set_error(err_desc, -EXA_ERR_INVALID_PARAM, NULL);
	return;
    }

    /* Check if a group with that name already exist */
    if (adm_group_get_group_by_name(info->name) != NULL)
    {
	set_error(err_desc, -VRT_ERR_GROUPNAME_USED, NULL);
	return;
    }

    if (info->layout[0] == '\0')
    {
	set_error(err_desc, -EXA_ERR_XML_GET, NULL);
	return;
    }

    if (params->alldisks)
    {
	struct adm_node *node;
	adm_cluster_for_each_node(node)
	{
	    struct adm_disk *disk;
	    adm_node_for_each_disk(node, disk)
	    {
		if (uuid_is_zero(&disk->group_uuid))
                {
                    if (disk->path[0] == '\0')
                    {
                        set_error(err_desc, -ADMIND_ERR_UNKNOWN_DISK,
                              "disk " UUID_FMT " is unknown", UUID_VAL(&disk->uuid));
                              return;
                    }

		    if (info->nb_disks >= NBMAX_DISKS_PER_GROUP)
		    {
			set_error(err_desc, -ADMIND_ERR_TOO_MANY_DISKS_IN_GROUP,
				  "too many disks in group (> %d)", NBMAX_DISKS_PER_GROUP);
			return;
		    }

		    uuid_copy(&info->disks[info->nb_disks], &disk->uuid);
		    info->nb_disks++;
		}
	    }
	}
    }
    else
    {