/* Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef ConfigObject_H #define ConfigObject_H #include #define OUR_V2_VERSION true /* Error codes */ #define WRONG_MAGIC_SIZE 1 #define WRONG_MAGIC_CONTENT 2 #define WRONG_CHECKSUM 3 #define MEMORY_ALLOC_ERROR 4 #define WRONG_STRING_LENGTH 5 #define WRONG_ENTRY_TYPE 6 #define SET_NOT_REAL_SECTION_ERROR 7 #define SET_REAL_SECTION_ERROR 8 #define SET_NODE_SECTION_ERROR 9 #define SET_CONNECTION_SECTION_ERROR 10 #define SET_SYSTEM_SECTION_ERROR 11 #define UNDEFINED_SECTION_TYPE 12 #define WRONG_PARENT_POINTER 13 #define WRONG_AMOUNT_OF_DATA 14 #define WRONG_AMOUNT_OF_SYSTEM_SECTIONS 15 #define NO_SUCH_POINTER_TYPE 16 #define NO_SUCH_SECTION_TYPE 17 #define INCONSISTENT_NUM_ENTRIES 18 #define WRONG_V2_UNPACK_LENGTH 19 #define WRONG_V2_INPUT_LENGTH 20 #define WRONG_EMPTY_SECTION_LENGTH 21 #define WRONG_SECTION_TYPE 22 #define WRONG_VALUE_TYPE 23 #define WRONG_NODE_TYPE 24 #define WRONG_COMM_TYPE 25 #define WRONG_VERSION_RECEIVED 26 #define INCONSISTENT_CONFIGURATION 27 #define WRONG_DATA_TYPE_OF_SECTION 28 #define WRONG_DATA_TYPE_IN_SET 29 class ConfigSection; class ConfigObject { friend class ConfigSection; public: /* Public methods */ ConfigObject(); ~ConfigObject(); /** * Create a new section, with section type and node/comm type * added. * This section will become the current section where we can * perform put's. */ bool createSection(Uint32 section_type, Uint32 type); void closeSection(); /** * Open a section, the first parameter is the section type * where * 1000 is System section * 2000 is Node sections and * 3000 is the Communication sections * No other values of section type are allowed. The index * is the section id within this section type. */ ConfigSection* openSection(Uint32 section_type, Uint32 index) const; /** * Fill the current section with a new key and its value. * 3 different functions based on their data type. */ bool put(Uint32 key, Uint32 val); bool put64(Uint32 key, Uint64 val); bool put(Uint32 key, const char *string); /** * Get an key entry from the current section. */ bool get(ConfigSection *curr_section, Uint32 key, ConfigSection::Entry &entry) const; /** * Set one item in the current section. */ bool set(ConfigSection *curr_section, ConfigSection::Entry &entry, bool free_string); /** * A configuration binary is used to create the ConfigObject. * This binary can have been retrieved from a get config call towards the * NDB management server, received in a message from another MGM server * in process of updating the config, it could be retrieved from a client * that desires to update the configuration and it can have been read from * the binary configuration file. */ bool unpack_v2(const Uint32 *cfg_binary, Uint32 size); /** * A configuration binary is created from the contents of the ConfigObject. * This returns a pointer to a contiguos memory area that has to be free'd * by the caller. */ Uint32 get_v2_packed_size(Uint32 node_id) const; void pack_v2(Uint32 *packed_v2_ptr, Uint32 len, Uint32 node_id = 0) const; /** * Same as unpack, but this unpacks the old format and creates a ConfigObject * based on the old binary format. This is used when a node retrieves a * configuration from an old MGM server or when a new MGM server sends a * configuration to a node using the old configuration format. */ bool unpack_v1(const Uint32 *cfg_binary, Uint32 size); /** * Same as pack, but this returns a configuration binary in the old format. */ Uint32 get_v1_packed_size() const; void pack_v1(Uint32 *packed_v1_ptr, Uint32 len) const; /** * Create a new ConfigObject consisting of only the specified ConfigSection. */ ConfigObject* copy_current(ConfigSection *cs) const; /** * Read all entries in configuration one by one. */ Uint32 getNextEntry(Uint32 key, ConfigSection::Entry *in_entry) const; /** * Call begin before structural changes to ConfigObject. * Call commitConfig when done. */ bool begin(); /** * We have completed inserting data into the config, commit the * changes. */ bool commitConfig(bool only_sort); /** * Print the error code from the previous call to ConfigObject. */ void print_error_code() const; int get_error_code() const; private: /* Private methods */ Uint32 get_num_comm_sections(Uint32 node_id) const; /* Remove pointer sections as final unpack_v1 step */ void remove_pointer_sections(); /** * Method used when unpacking a configuration binary, it will create an * array, and fill the array with pointers to ConfigSection objects of * currently unknown type. */ void createSections(Uint32 num_sections); /** * Get the type from key using the old packed format. * Get the section id from key using old packed format. * Get the key from key using old packed format. */ ConfigSection::ValueType get_old_type(Uint32); Uint32 get_old_section(Uint32); Uint32 get_old_key(Uint32); /* Create the default sections */ void create_default_sections(); bool build_arrays(bool from_unpack); /** * Functions to create the v1 configuration binary. */ void create_v1_header_section(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_node_header_section(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_mgm_node_sections(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_api_node_sections(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_system_header_section(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_system_section(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_comm_header_section(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_comm_sections(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_data_node_sections(Uint32 **v1_ptr, Uint32 &curr_section) const; void create_v1_entry(Uint32**, Uint32 type, Uint32 key, Uint32 section); void create_v1_comm_specific_sections(Uint32 **v1_ptr, ConfigSection::SectionType sect_type, Uint32 &curr_section) const; void create_v1_node_specific_sections(Uint32 **v1_ptr, ConfigSection::SectionType sect_type, Uint32 &curr_section) const; /** * Functions to create v2 configuration binary. */ void create_v2_header_section(Uint32** v2_ptr, Uint32 tot_len, Uint32 num_comm_sections) const; void create_empty_default_trp_section(Uint32 **v2_ptr, Uint32 type) const; /** * Functions to unpack v2 configuration binary */ bool check_checksum(const Uint32 *src, Uint32 len_bytes); bool unpack_default_sections(const Uint32 **data); bool unpack_system_section(const Uint32 **data); bool unpack_node_sections(const Uint32 **data); bool unpack_comm_sections(const Uint32 **data); bool read_v2_header_info(const Uint32 **data); private: /* Private data */ /** * Variable pointing to the currently opened ConfigSection object. */ ConfigSection *m_curr_cfg_section; /** * The array of the current set of ConfigSection objects in this * configuration. */ std::vector m_cfg_sections; /** * Number of ConfigSection* entries in m_cfg_sections array. */ Uint32 m_num_sections; /** * Pointer to the system section */ ConfigSection *m_system_section; /** * Pointer to an array of node sections. * Number of entries in the array. */ std::vector m_node_sections; Uint32 m_num_node_sections; Uint32 m_num_data_nodes; Uint32 m_num_api_nodes; Uint32 m_num_mgm_nodes; Uint32 m_v2_tot_len; Uint32 m_num_default_sections; /** * Pointer to an array of communication sections. * Number of entries in the array. */ std::vector m_comm_sections; Uint32 m_num_comm_sections; /** * */ ConfigSection *m_data_node_default_section; ConfigSection *m_api_node_default_section; ConfigSection *m_mgm_node_default_section; ConfigSection *m_tcp_default_section; ConfigSection *m_shm_default_section; protected: /** * Error code after failure of some kind. */ Uint32 m_error_code; }; inline ConfigSection::ValueType ConfigObject::get_old_type(Uint32 key) { return (ConfigSection::ValueType)(key >> OLD_KP_TYPE_SHIFT); } inline Uint32 ConfigObject::get_old_section(Uint32 key) { return ((key >> OLD_KP_SECTION_SHIFT) & OLD_KP_SECTION_MASK); } inline Uint32 ConfigObject::get_old_key(Uint32 key) { return ((key >> OLD_KP_KEYVAL_SHIFT) & OLD_KP_KEYVAL_MASK); } #endif