/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "isns_server.h"
#include "isns_obj.h"
#include "isns_log.h"
#if LIBXML_VERSION >= 20904
#define XMLSTRING_CAST (const char *)
#else
#endif
/*
* external variables
*/
extern const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE];
extern const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE];
extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
extern char data_store[MAXPATHLEN];
/*
* local variables
*/
0,
1, /* OBJ_ENTITY */
2, /* OBJ_ISCSI */
3, /* OBJ_PORTAL */
4, /* OBJ_PG */
5, /* OBJ_DD */
6, /* OBJ_DDS */
0, /* MAX_OBJ_TYPE */
0, /* OBJ_DUMMY1 */
0, /* OBJ_DUMMY2 */
0, /* OBJ_DUMMY3 */
0, /* OBJ_DUMMY4 */
12, /* OBJ_ASSOC_ISCSI */
14, /* OBJ_ASSOC_DD */
};
#include "data.def"
};
#include "data.def"
};
static const char *xmlType[] = {
#include "data.def"
};
static const int xmlArg1[] = {
#include "data.def"
};
static const int xmlArg2[] = {
#include "data.def"
};
static const unsigned char xmlPropType[] = {
#include "data.def"
};
#include "data.def"
};
static const int xmlPropTag[] = {
#include "data.def"
};
static const int xmlPropID[] = {
#include "data.def"
};
/*
* ****************************************************************************
*
* get_index_by_name:
* find the index in the global tables for the name of an attribute.
*
* name - the name of an attribute.
* return - index or -1 for error.
*
* ****************************************************************************
*/
static int
)
{
int i;
for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
return (i);
}
}
return (-1);
}
/*
* ****************************************************************************
*
* get_index_by_otype:
* find the index in the global tables for the type of an object.
*
* name - the type of an object.
* return - index or -1 for error.
*
* ****************************************************************************
*/
static int
int otype
)
{
int i;
for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
return (i);
}
}
return (-1);
}
/*
* ****************************************************************************
*
* get_index_by_tag:
* find the index in the global tables for the tag of an attribute.
*
* name - the tag of an attribute.
* return - index or -1 for error.
*
* ****************************************************************************
*/
static int
int tag
)
{
int i;
for (i = 0; i < ARRAY_LENGTH(xmlTag); i++) {
xmlType[i][0] != 'o' &&
xmlType[i][0] != 'a') {
return (i);
}
}
return (-1);
}
/*
* ****************************************************************************
*
* get_xml_doc:
* open the xml file and assign the global xml doc if the xml file
* is not opened, set the doc pointer with the opened xml file for
* returnning.
*
* docp - the doc pointer for returning.
* return - error code.
*
* ****************************************************************************
*/
static int
)
{
int ec = 0;
/* validate the xml file */
/* open the xml file */
}
}
return (ec);
}
/*
* ****************************************************************************
*
* close_xml_doc:
* close the global xml doc and ignore any changes that has been
* made in it.
*
* ****************************************************************************
*/
static void
)
{
if (xml_doc) {
/* just close it */
}
}
/*
* ****************************************************************************
*
* convert_xml2attr:
* convert a xml data to a TLV format isns attribute.
*
* tag - the tag of attribute.
* type - the data type of the xml data.
* value - the xml data.
* attr - TLV format attribute for returning.
* return - error code.
*
* ****************************************************************************
*/
static int
const int tag,
const unsigned char type,
)
{
int ec = 0;
switch (type) {
case 'u':
/* 4-bytes non-negative integer */
break;
case 's':
/* literal string */
(char *)value);
} else {
}
break;
case 'p':
/* IPv6 block data */
(char *)value,
} else {
}
break;
default:
break;
}
return (ec);
}
/*
* ****************************************************************************
*
* convert_attr2xml:
* convert a TLV format isns attribute to xml node format.
*
* node - the xml node where the new node is being added to.
* attr - the TLV format attribute.
* name - the name of the attribute in xml node.
* type - the data type of the attribute.
* elm_flag - 0: adding a xml attlist.
* 1: adding a xml child node.
* 2: adding a previous sibling node.
* 3: adding a xml content node.
* 4: adding a xml attribute.
* return - xml node.
*
* ****************************************************************************
*/
static xmlNodePtr
const isns_attr_t *attr,
const char type,
const int elm_flag
)
{
switch (type) {
case 'u':
/* 4-bytes non-negative integer */
XMLSTRING_CAST "%u",
}
break;
case 's':
/* literal string */
break;
case 'p':
/* IPv6 block data */
(char *)buff,
sizeof (buff));
break;
default:
break;
}
if (!value) {
return (NULL);
}
switch (elm_flag) {
case 0: /* attlist */
}
break;
case 1: /* child element */
break;
case 2: /* prev sibling element */
} else {
}
/* LINTED E_CASE_FALLTHRU */
case 3: /* set content */
if (node) {
}
break;
case 4: /* new attr value */
}
break;
default:
ASSERT(0);
break;
}
return (child);
}
/*
* ****************************************************************************
*
* parse_xml_prop:
* parse the properties of a xml node and convert them to the attributes
* of an isns object, these xml properties are the UID attribute and
* key attributes of the isns object.
*
* node - the xml node that contains the properties.
* obj - the isns object.
* i - the index of the attribute in the global tables.
* return - error code.
*
* ****************************************************************************
*/
static int
int i
)
{
int ec = 0;
unsigned char prop_type;
int prop_tag;
int prop_id;
char prop;
int j;
j = 0;
while (ec == 0 &&
prop -= 'a';
if (prop_value) {
}
}
return (ec);
}
/*
* ****************************************************************************
*
* parse_xml_attr:
* parse a xml node and convert it to one isns object attribute.
* this attribute is the non-key attribute of the isns object.
*
* node - the xml node.
* obj - the isns object.
* i - the index of the attribute in the global tables.
* return - error code.
*
* ****************************************************************************
*/
static int
int i
)
{
int ec = 0;
if (attr_value) {
}
return (ec);
}
/*
* ****************************************************************************
*
* parse_xml_obj:
* parse one isns object from the xml doc.
*
* nodep - the pointer of the xml node for parsing.
* objp - the pointer of isns object for returning.
* return - error code.
*
* ****************************************************************************
*/
static int
)
{
int ec = 0;
int i, j;
ASSERT(i >= 0);
j = xmlType[i][0];
break;
}
0)) {
}
} else {
}
break;
/* LINTED E_NOP_IF_STMT */
} else if (j == 'o') {
} else if (j != 0) {
} else {
/* assign a default value */
}
} else {
/* unknown xml node */
break;
}
/* LINTED E_NOP_ELSE_STMT */
} else {
/* carry return or blank spaces, skip it */
}
}
return (ec);
}
/*
* ****************************************************************************
*
* locate_xml_node:
* locate the xml node from xml doc by matching the object UID.
*
* doc - the xml doc.
* otype - the matching object type.
* match_uid - the matching object UID.
* node - the pointer of matched xml node for returning.
* context - the xml context for matching process.
* result - the xml result for matching process.
* return - error code.
*
* ****************************************************************************
*/
static int
int otype,
int match_uid,
)
{
int ec = 0;
char prop;
int uid;
int i, j;
i = get_index_by_otype(otype);
ASSERT(i >= 0);
if (*context &&
xmlTag[i]) != -1) {
if (*result) {
for (j = 0;
j++) {
if (prop_value) {
/* found it */
return (ec);
}
}
}
} else {
}
} else {
}
if (*result) {
}
if (*context) {
}
return (ec);
}
/*
* ****************************************************************************
*
* make_xml_node:
* generate a xml node for presenting an isns object.
*
* obj - an isns object.
* return - the xml node.
*
* ****************************************************************************
*/
static xmlNodePtr
const isns_obj_t *obj
)
{
const char *props;
char prop;
unsigned char type;
int prop_id;
int i, j;
ASSERT(i >= 0);
if (!node) {
return (NULL);
}
/* generate xml attributes of the node */
prop -= 'a';
return (NULL);
}
/* attr->tag = 0; */
}
/* generate sub elements for isns attributes of the object */
i = 0;
if (j >= 0) {
return (NULL);
}
}
}
return (node);
}
/*
* ****************************************************************************
*
* xml_init_data:
* initialization of the xml data store.
*
* return - error code.
*
* ****************************************************************************
*/
static int
)
{
int fd;
int len;
int has_bak = 0;
/* cannot reset the xml file when server is running */
return (1);
}
/* set the data store file name along with the backup */
/* file name and temporary file name */
if (len > 0) {
if (p != NULL &&
xml_bak_file != NULL &&
xml_tmp_file != NULL) {
} else {
return (1);
}
} else {
}
/* save current working directory */
return (1);
}
/* check access permission on data store directory */
return (1);
}
} else {
return (1);
}
}
/* go back to original working directory */
free(p);
/* do not keep blank spaces */
(void) xmlKeepBlanksDefault(0);
/* remove the tmp file if it exists */
(void) remove(xml_tmp_file);
}
/* test if we can write the bak file */
if (fd == -1) {
if (fd == -1) {
return (1);
} else {
(void) remove(xml_bak_file);
}
} else {
has_bak = 1;
}
/* Test if we have the data store file, create an empty */
/* data store if we do not have the data store file and */
/* the backup data store. */
if (fd == -1) {
if (has_bak == 0) {
NULL &&
NULL) {
return (-1);
}
} else {
}
}
return (1);
}
} else {
"initializing with backup data");
return (1);
}
}
} else {
}
return (0);
}
/*
* ****************************************************************************
*
* xml_load_obj:
* load an isns object from the xml data store.
*
* p - the pointer of current xml node.
* objp - the pointer of the object for returning.
* level - the direction of xml parsing for returning.
* return - error code.
*
* ****************************************************************************
*/
static int
void **p,
isns_obj_t **objp,
)
{
int ec = 0;
*level = '^';
return (ec);
}
}
*level = '>';
*level = 'v';
} else {
*level = 'v';
*level = '<';
}
}
}
}
/* there is a node, parse it */
if (node) {
*p = (void *)node;
}
if (ec != 0) {
free_object(*objp);
}
}
/* no object available, close the xml doc */
(void) close_xml_doc();
}
return (ec);
}
/*
* ****************************************************************************
*
* xml_add_obj:
* add an isns object to the xml data store.
*
* obj - the object being added.
* return - error code.
*
* ****************************************************************************
*/
static int
const isns_obj_t *obj
)
{
int ec = 0;
int i;
/* get the xml doc */
goto add_done;
}
/* create the candidate node */
goto add_done;
}
/* locate the position */
if (parent_type > 0) {
} else {
}
/* cannot locate the point for inserting the node */
goto add_done;
}
/* add it with the apporiate child order */
while (node) {
ASSERT(i >= 0);
if (xmlType[i][0] == 'o' &&
OBJ_DTD_ORDER[xmlArg1[i]] >=
break;
}
}
}
} else {
}
} else {
}
/* Failed, free the candidate node. */
}
if (result) {
}
if (context) {
}
return (ec);
}
/*
* ****************************************************************************
*
* xml_modify_obj:
* modify an isns object in the xml data store.
*
* obj - the new object.
* return - error code.
*
* ****************************************************************************
*/
static int
const isns_obj_t *obj
)
{
int ec = 0;
const char *props;
char prop;
int prop_id;
int prop_tag;
unsigned char type;
int i, j, k;
int make_child;
/* get the doc pointer */
return (ec);
}
/* locate the node for the object */
ASSERT(i >= 0);
/* modify it */
prop -= 'a';
/* no need to update the key attributes, skip it. */
/* btw, dd and dd-set names are non-key attributes. */
if (prop_tag == ISNS_DD_NAME_ATTR_ID ||
if (!convert_attr2xml(node,
goto modify_done;
}
}
/* attr->tag = 0; */
}
/* set the child */
make_child = 1;
} else {
make_child = 0;
}
if (j < 0) {
continue;
}
if (make_child == 1) {
/* make a child node */
goto modify_done;
}
continue;
}
while (child) {
ASSERT(k >= 0);
if (xmlType[k][0] == 'o' ||
xmlType[k][0] == 'a' ||
if (!convert_attr2xml(child,
/* internal error */
ec = 11;
goto modify_done;
}
break;
/* replace content */
if (!convert_attr2xml(child,
/* internal error */
ec = 11;
goto modify_done;
}
break;
}
}
}
/* make a child node */
goto modify_done;
}
}
}
} else {
/* This case is for registering a node which has */
/* membership in one or more non-default DD(s). */
}
if (result) {
}
if (context) {
}
return (ec);
}
/*
* ****************************************************************************
*
* xml_delete_obj:
* delete an isns object from the xml data store.
*
* obj - the object being deleted.
* return - error code.
*
* ****************************************************************************
*/
static int
const isns_obj_t *obj
)
{
int ec = 0;
/* get the xml doc */
return (ec);
}
#ifdef WRITE_DATA_ASYNC
/* it is a thin clone */
#else
#endif
/* locate the object */
uid,
/* destroy it */
if (node) {
}
if (result) {
}
if (context) {
}
return (ec);
}
/*
* ****************************************************************************
*
* xml_delete_assoc:
* delete a DD or DD-set membership from the xml data store.
*
* assoc - the membership being deleted.
* return - error code.
*
* ****************************************************************************
*/
static int
const isns_obj_t *assoc
)
{
int ec = 0;
char prop;
int i;
/* get the xml doc */
return (ec);
}
/* get the container object UID */
ASSERT(parent_type != 0);
/* get the member object UID */
/* locate the container object */
/* get the membership nodes */
}
/* get the matching membership node */
while (node) {
ASSERT(i >= 0);
if (xmlType[i][0] == 'o' &&
if (prop_value) {
break;
}
}
}
}
}
/* destroy it */
if (node) {
}
if (result) {
}
if (context) {
}
return (ec);
}
/*
* ****************************************************************************
*
* xml_update_commit:
* backup the current written file and commit all updates from
* the xml doc to the written file.
*
* return - error code.
*
* ****************************************************************************
*/
static int
)
{
int ec = 0;
if (xml_doc) {
/* write to tmp file */
/* backup the current file */
/* rename the tmp file to the current file */
/* failed saving file */
}
/* close the xml_doc */
}
return (ec);
}
/*
* ****************************************************************************
*
* xml_update_retreat:
* ignore all of updates in the xml doc.
*
* return - 0: always successful.
*
* ****************************************************************************
*/
static int
)
{
if (xml_doc) {
/* close the xml_doc */
}
return (0);
}