|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2007 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Abstract:
|
|
Packit |
13e616 |
* Implementation of the osm_db interface using simple text files
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <sys/stat.h>
|
|
Packit |
13e616 |
#include <sys/types.h>
|
|
Packit |
13e616 |
#include <errno.h>
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <unistd.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_DB_FILES_C
|
|
Packit |
13e616 |
#include <opensm/st.h>
|
|
Packit |
13e616 |
#include <opensm/osm_db.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****d* Database/OSM_DB_MAX_LINE_LEN
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* OSM_DB_MAX_LINE_LEN
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* The Maximal line length allowed for the file
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
#define OSM_DB_MAX_LINE_LEN 1024
|
|
Packit |
13e616 |
/**********/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****s* OpenSM: Database/osm_db_domain_imp
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osm_db_domain_imp
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* An implementation for domain of the database based on text files and
|
|
Packit |
13e616 |
* hash tables.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
typedef struct osm_db_domain_imp {
|
|
Packit |
13e616 |
char *file_name;
|
|
Packit |
13e616 |
st_table *p_hash;
|
|
Packit |
13e616 |
cl_spinlock_t lock;
|
|
Packit |
13e616 |
boolean_t dirty;
|
|
Packit |
13e616 |
} osm_db_domain_imp_t;
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* FIELDS
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
* osm_db_domain_t
|
|
Packit |
13e616 |
*********/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****s* OpenSM: Database/osm_db_imp_t
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* osm_db_imp_t
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* An implementation for file based database
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
typedef struct osm_db_imp {
|
|
Packit |
13e616 |
const char *db_dir_name;
|
|
Packit |
13e616 |
} osm_db_imp_t;
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* FIELDS
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* db_dir_name
|
|
Packit |
13e616 |
* The directory holding the database
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
* osm_db_t
|
|
Packit |
13e616 |
*********/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_db_construct(IN osm_db_t * p_db)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
memset(p_db, 0, sizeof(osm_db_t));
|
|
Packit |
13e616 |
cl_list_construct(&p_db->domains);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_db_domain_destroy(IN osm_db_domain_t * p_db_domain)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp;
|
|
Packit |
13e616 |
p_domain_imp = (osm_db_domain_imp_t *) p_db_domain->p_domain_imp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_db_clear(p_db_domain);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_destroy(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
st_free_table(p_domain_imp->p_hash);
|
|
Packit |
13e616 |
free(p_domain_imp->file_name);
|
|
Packit |
13e616 |
free(p_domain_imp);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_db_destroy(IN osm_db_t * p_db)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_domain_t *p_domain;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while ((p_domain = cl_list_remove_head(&p_db->domains)) != NULL) {
|
|
Packit |
13e616 |
osm_db_domain_destroy(p_domain);
|
|
Packit |
13e616 |
free(p_domain);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_list_destroy(&p_db->domains);
|
|
Packit |
13e616 |
free(p_db->p_db_imp);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_init(IN osm_db_t * p_db, IN osm_log_t * p_log)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_imp_t *p_db_imp;
|
|
Packit |
13e616 |
struct stat dstat;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_db_imp = malloc(sizeof(osm_db_imp_t));
|
|
Packit |
13e616 |
if (!p_db_imp) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6100: "
|
|
Packit |
13e616 |
"Failed to allocate db memory\n");
|
|
Packit |
13e616 |
return -1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_db_imp->db_dir_name = getenv("OSM_CACHE_DIR");
|
|
Packit |
13e616 |
if (!p_db_imp->db_dir_name || !(*p_db_imp->db_dir_name))
|
|
Packit |
13e616 |
p_db_imp->db_dir_name = OSM_DEFAULT_CACHE_DIR;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Create the directory if it doesn't exist */
|
|
Packit |
13e616 |
/* There is a difference in creating directory between windows and linux */
|
|
Packit |
13e616 |
#ifdef __WIN__
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
int ret;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = SHCreateDirectoryEx(NULL, p_db_imp->db_dir_name, NULL);
|
|
Packit |
13e616 |
if (ret != ERROR_SUCCESS && ret != ERROR_ALREADY_EXISTS &&
|
|
Packit |
13e616 |
ret != ERROR_FILE_EXISTS)
|
|
Packit |
13e616 |
goto err;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#else /* __WIN__ */
|
|
Packit |
13e616 |
/* make sure the directory exists */
|
|
Packit |
13e616 |
if (lstat(p_db_imp->db_dir_name, &dstat)) {
|
|
Packit |
13e616 |
if (mkdir(p_db_imp->db_dir_name, 0755))
|
|
Packit |
13e616 |
goto err;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_db->p_log = p_log;
|
|
Packit |
13e616 |
p_db->p_db_imp = (void *)p_db_imp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_init(&p_db->domains, 5);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
err:
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6101: "
|
|
Packit |
13e616 |
"Failed to create the db directory:%s\n",
|
|
Packit |
13e616 |
p_db_imp->db_dir_name);
|
|
Packit |
13e616 |
free(p_db_imp);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return 1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_db_domain_t *osm_db_domain_init(IN osm_db_t * p_db, IN const char *domain_name)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_domain_t *p_domain;
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp;
|
|
Packit |
13e616 |
size_t path_len;
|
|
Packit |
13e616 |
osm_log_t *p_log = p_db->p_log;
|
|
Packit |
13e616 |
FILE *p_file;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* allocate a new domain object */
|
|
Packit |
13e616 |
p_domain = malloc(sizeof(osm_db_domain_t));
|
|
Packit |
13e616 |
if (p_domain == NULL) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610C: "
|
|
Packit |
13e616 |
"Failed to allocate domain memory\n");
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_domain_imp = malloc(sizeof(osm_db_domain_imp_t));
|
|
Packit |
13e616 |
if (p_domain_imp == NULL) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610D: "
|
|
Packit |
13e616 |
"Failed to allocate domain_imp memory\n");
|
|
Packit |
13e616 |
free(p_domain);
|
|
Packit |
13e616 |
p_domain = NULL;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
path_len = strlen(((osm_db_imp_t *) p_db->p_db_imp)->db_dir_name)
|
|
Packit |
13e616 |
+ strlen(domain_name) + 2;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* set the domain file name */
|
|
Packit |
13e616 |
p_domain_imp->file_name = malloc(path_len);
|
|
Packit |
13e616 |
if (p_domain_imp->file_name == NULL) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 610E: "
|
|
Packit |
13e616 |
"Failed to allocate file_name memory\n");
|
|
Packit |
13e616 |
free(p_domain_imp);
|
|
Packit |
13e616 |
free(p_domain);
|
|
Packit |
13e616 |
p_domain = NULL;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
snprintf(p_domain_imp->file_name, path_len, "%s/%s",
|
|
Packit |
13e616 |
((osm_db_imp_t *) p_db->p_db_imp)->db_dir_name, domain_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* make sure the file exists - or exit if not writable */
|
|
Packit |
13e616 |
p_file = fopen(p_domain_imp->file_name, "a+");
|
|
Packit |
13e616 |
if (!p_file) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6102: "
|
|
Packit |
13e616 |
"Failed to open the db file:%s\n",
|
|
Packit |
13e616 |
p_domain_imp->file_name);
|
|
Packit |
13e616 |
free(p_domain_imp);
|
|
Packit |
13e616 |
free(p_domain);
|
|
Packit |
13e616 |
p_domain = NULL;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
fclose(p_file);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* initialize the hash table object */
|
|
Packit |
13e616 |
p_domain_imp->p_hash = st_init_strtable();
|
|
Packit |
13e616 |
CL_ASSERT(p_domain_imp->p_hash != NULL);
|
|
Packit |
13e616 |
p_domain_imp->dirty = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_domain->p_db = p_db;
|
|
Packit |
13e616 |
cl_list_insert_tail(&p_db->domains, p_domain);
|
|
Packit |
13e616 |
p_domain->p_domain_imp = p_domain_imp;
|
|
Packit |
13e616 |
cl_spinlock_construct(&p_domain_imp->lock);
|
|
Packit |
13e616 |
cl_spinlock_init(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return p_domain;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_restore(IN osm_db_domain_t * p_domain)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log_t *p_log = p_domain->p_db->p_log;
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp =
|
|
Packit |
13e616 |
(osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
FILE *p_file;
|
|
Packit |
13e616 |
int status;
|
|
Packit |
13e616 |
char sLine[OSM_DB_MAX_LINE_LEN];
|
|
Packit |
13e616 |
boolean_t before_key;
|
|
Packit |
13e616 |
char *p_first_word, *p_rest_of_line, *p_last;
|
|
Packit |
13e616 |
char *p_key = NULL;
|
|
Packit |
13e616 |
char *p_prev_val = NULL, *p_accum_val = NULL;
|
|
Packit |
13e616 |
char *endptr = NULL;
|
|
Packit |
13e616 |
unsigned int line_num;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* take the lock on the domain */
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* open the file - read mode */
|
|
Packit |
13e616 |
p_file = fopen(p_domain_imp->file_name, "r");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_file) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6103: "
|
|
Packit |
13e616 |
"Failed to open the db file:%s\n",
|
|
Packit |
13e616 |
p_domain_imp->file_name);
|
|
Packit |
13e616 |
status = 1;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* parse the file allocating new hash tables as required */
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
states:
|
|
Packit |
13e616 |
before_key (0) -> in_key (1)
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
before_key: if a word on the first byte - it is the key. state=in_key
|
|
Packit |
13e616 |
the rest of the line is start of the value.
|
|
Packit |
13e616 |
in_key: unless the line is empty - add it (with newlines) to the value.
|
|
Packit |
13e616 |
if empty: state=before_key
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
status = 0;
|
|
Packit |
13e616 |
before_key = TRUE;
|
|
Packit |
13e616 |
line_num = 0;
|
|
Packit |
13e616 |
/* if we got to EOF in the middle of a key we add a last newline */
|
|
Packit |
13e616 |
while ((fgets(sLine, OSM_DB_MAX_LINE_LEN, p_file) != NULL) ||
|
|
Packit |
13e616 |
((before_key == FALSE) && strcpy(sLine, "\n"))
|
|
Packit |
13e616 |
) {
|
|
Packit |
13e616 |
line_num++;
|
|
Packit |
13e616 |
if (before_key) {
|
|
Packit |
13e616 |
if ((sLine[0] != ' ') && (sLine[0] != '\t')
|
|
Packit |
13e616 |
&& (sLine[0] != '\n')) {
|
|
Packit |
13e616 |
/* we got a new key */
|
|
Packit |
13e616 |
before_key = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* handle the key */
|
|
Packit |
13e616 |
p_first_word =
|
|
Packit |
13e616 |
strtok_r(sLine, " \t\n", &p_last);
|
|
Packit |
13e616 |
if (!p_first_word) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"ERR 6104: "
|
|
Packit |
13e616 |
"Failed to get key from line:%u : %s (file:%s)\n",
|
|
Packit |
13e616 |
line_num, sLine,
|
|
Packit |
13e616 |
p_domain_imp->file_name);
|
|
Packit |
13e616 |
status = 1;
|
|
Packit |
13e616 |
goto EndParsing;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_key = malloc(sizeof(char) *
|
|
Packit |
13e616 |
(strlen(p_first_word) + 1));
|
|
Packit |
13e616 |
strcpy(p_key, p_first_word);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_rest_of_line = strtok_r(NULL, "\n", &p_last);
|
|
Packit |
13e616 |
if (p_rest_of_line != NULL) {
|
|
Packit |
13e616 |
p_accum_val = malloc(sizeof(char) *
|
|
Packit |
13e616 |
(strlen(p_rest_of_line) + 1));
|
|
Packit |
13e616 |
strcpy(p_accum_val, p_rest_of_line);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
p_accum_val = malloc(2);
|
|
Packit |
13e616 |
strcpy(p_accum_val, "\0");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else if (sLine[0] != '\n') {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6105: "
|
|
Packit |
13e616 |
"How did we get here? line:%u : %s (file:%s)\n",
|
|
Packit |
13e616 |
line_num, sLine,
|
|
Packit |
13e616 |
p_domain_imp->file_name);
|
|
Packit |
13e616 |
status = 1;
|
|
Packit |
13e616 |
goto EndParsing;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} /* before key */
|
|
Packit |
13e616 |
else {
|
|
Packit |
13e616 |
/* we already have a key */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (sLine[0] == '\n') {
|
|
Packit |
13e616 |
/* got an end of key */
|
|
Packit |
13e616 |
before_key = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* make sure the key was not previously used */
|
|
Packit |
13e616 |
if (st_lookup(p_domain_imp->p_hash,
|
|
Packit |
13e616 |
(st_data_t) p_key,
|
|
Packit |
13e616 |
(void *)&p_prev_val)) {
|
|
Packit |
13e616 |
/* if previously used we ignore this guid */
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"ERR 6106: "
|
|
Packit |
13e616 |
"Key:%s already exists in:%s with value:%s."
|
|
Packit |
13e616 |
" Removing it\n", p_key,
|
|
Packit |
13e616 |
p_domain_imp->file_name,
|
|
Packit |
13e616 |
p_prev_val);
|
|
Packit |
13e616 |
free(p_key);
|
|
Packit |
13e616 |
p_key = NULL;
|
|
Packit |
13e616 |
free(p_accum_val);
|
|
Packit |
13e616 |
p_accum_val = NULL;
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
p_prev_val = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Got key:%s value:%s\n", p_key,
|
|
Packit |
13e616 |
p_accum_val);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* check that the key is a number */
|
|
Packit |
13e616 |
if (!strtouq(p_key, &endptr, 0)
|
|
Packit |
13e616 |
&& *endptr != '\0') {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"ERR 610B: "
|
|
Packit |
13e616 |
"Key:%s is invalid\n", p_key);
|
|
Packit |
13e616 |
free(p_key);
|
|
Packit |
13e616 |
p_key = NULL;
|
|
Packit |
13e616 |
free(p_accum_val);
|
|
Packit |
13e616 |
p_accum_val = NULL;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* store our key and value */
|
|
Packit |
13e616 |
st_insert(p_domain_imp->p_hash,
|
|
Packit |
13e616 |
(st_data_t) p_key,
|
|
Packit |
13e616 |
(st_data_t) p_accum_val);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* accumulate into the value */
|
|
Packit |
13e616 |
p_prev_val = p_accum_val;
|
|
Packit |
13e616 |
p_accum_val = malloc(strlen(p_prev_val) +
|
|
Packit |
13e616 |
strlen(sLine) + 1);
|
|
Packit |
13e616 |
strcpy(p_accum_val, p_prev_val);
|
|
Packit |
13e616 |
free(p_prev_val);
|
|
Packit |
13e616 |
p_prev_val = NULL;
|
|
Packit |
13e616 |
strcat(p_accum_val, sLine);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} /* in key */
|
|
Packit |
13e616 |
} /* while lines or last line */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
EndParsing:
|
|
Packit |
13e616 |
fclose(p_file);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int dump_tbl_entry(st_data_t key, st_data_t val, st_data_t arg)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FILE *p_file = (FILE *) arg;
|
|
Packit |
13e616 |
char *p_key = (char *)key;
|
|
Packit |
13e616 |
char *p_val = (char *)val;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fprintf(p_file, "%s %s\n\n", p_key, p_val);
|
|
Packit |
13e616 |
return ST_CONTINUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_store(IN osm_db_domain_t * p_domain,
|
|
Packit |
13e616 |
IN boolean_t fsync_high_avail_files)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_log_t *p_log = p_domain->p_db->p_log;
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp;
|
|
Packit |
13e616 |
FILE *p_file = NULL;
|
|
Packit |
13e616 |
int fd, status = 0;
|
|
Packit |
13e616 |
char *p_tmp_file_name = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_domain_imp = (osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tmp_file_name = malloc(sizeof(char) *
|
|
Packit |
13e616 |
(strlen(p_domain_imp->file_name) + 8));
|
|
Packit |
13e616 |
if (!p_tmp_file_name) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6113: "
|
|
Packit |
13e616 |
"Failed to allocate memory for temporary file name\n");
|
|
Packit |
13e616 |
goto Exit2;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
strcpy(p_tmp_file_name, p_domain_imp->file_name);
|
|
Packit |
13e616 |
strcat(p_tmp_file_name, ".tmp");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_domain_imp->dirty == FALSE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* open up the output file */
|
|
Packit |
13e616 |
p_file = fopen(p_tmp_file_name, "w");
|
|
Packit |
13e616 |
if (!p_file) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6107: "
|
|
Packit |
13e616 |
"Failed to open the db file:%s for writing: err:%s\n",
|
|
Packit |
13e616 |
p_domain_imp->file_name, strerror(errno));
|
|
Packit |
13e616 |
status = 1;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
st_foreach(p_domain_imp->p_hash, dump_tbl_entry, (st_data_t) p_file);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (fsync_high_avail_files) {
|
|
Packit |
13e616 |
if (fflush(p_file) == 0) {
|
|
Packit |
13e616 |
fd = fileno(p_file);
|
|
Packit |
13e616 |
if (fd != -1) {
|
|
Packit |
13e616 |
if (fsync(fd) == -1)
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"ERR 6110: fsync() failed (%s) for %s\n",
|
|
Packit |
13e616 |
strerror(errno),
|
|
Packit |
13e616 |
p_domain_imp->file_name);
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6111: "
|
|
Packit |
13e616 |
"fileno() failed for %s\n",
|
|
Packit |
13e616 |
p_domain_imp->file_name);
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6112: "
|
|
Packit |
13e616 |
"fflush() failed (%s) for %s\n",
|
|
Packit |
13e616 |
strerror(errno), p_domain_imp->file_name);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fclose(p_file);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = rename(p_tmp_file_name, p_domain_imp->file_name);
|
|
Packit |
13e616 |
if (status) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 6108: "
|
|
Packit |
13e616 |
"Failed to rename the db file to:%s (err:%s)\n",
|
|
Packit |
13e616 |
p_domain_imp->file_name, strerror(errno));
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_domain_imp->dirty = FALSE;
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
free(p_tmp_file_name);
|
|
Packit |
13e616 |
Exit2:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* simply de-allocate the key and the value and return the code
|
|
Packit |
13e616 |
that makes the st_foreach delete the entry */
|
|
Packit |
13e616 |
static int clear_tbl_entry(st_data_t key, st_data_t val, st_data_t arg)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
free((char *)key);
|
|
Packit |
13e616 |
free((char *)val);
|
|
Packit |
13e616 |
return ST_DELETE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_clear(IN osm_db_domain_t * p_domain)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp =
|
|
Packit |
13e616 |
(osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
st_foreach(p_domain_imp->p_hash, clear_tbl_entry, (st_data_t) NULL);
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int get_key_of_tbl_entry(st_data_t key, st_data_t val, st_data_t arg)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_t *p_list = (cl_list_t *) arg;
|
|
Packit |
13e616 |
cl_list_insert_tail(p_list, (void *)key);
|
|
Packit |
13e616 |
return ST_CONTINUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_keys(IN osm_db_domain_t * p_domain, OUT cl_list_t * p_key_list)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp =
|
|
Packit |
13e616 |
(osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
st_foreach(p_domain_imp->p_hash, get_key_of_tbl_entry,
|
|
Packit |
13e616 |
(st_data_t) p_key_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
char *osm_db_lookup(IN osm_db_domain_t * p_domain, IN char *p_key)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp =
|
|
Packit |
13e616 |
(osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
char *p_val = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!st_lookup(p_domain_imp->p_hash, (st_data_t) p_key, (void *)&p_val))
|
|
Packit |
13e616 |
p_val = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return p_val;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_update(IN osm_db_domain_t * p_domain, IN char *p_key, IN char *p_val)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_log_t *p_log = p_domain->p_db->p_log;
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp =
|
|
Packit |
13e616 |
(osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
char *p_prev_val = NULL;
|
|
Packit |
13e616 |
char *p_new_key;
|
|
Packit |
13e616 |
char *p_new_val;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (st_lookup(p_domain_imp->p_hash,
|
|
Packit |
13e616 |
(st_data_t) p_key, (void *)&p_prev_val)) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Key:%s previously exists in:%s with value:%s\n",
|
|
Packit |
13e616 |
p_key, p_domain_imp->file_name, p_prev_val);
|
|
Packit |
13e616 |
p_new_key = p_key;
|
|
Packit |
13e616 |
/* same key, same value - nothing to update */
|
|
Packit |
13e616 |
if (p_prev_val && !strcmp(p_val, p_prev_val))
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* need to allocate the key */
|
|
Packit |
13e616 |
p_new_key = malloc(sizeof(char) * (strlen(p_key) + 1));
|
|
Packit |
13e616 |
strcpy(p_new_key, p_key);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* need to arrange a new copy of the value */
|
|
Packit |
13e616 |
p_new_val = malloc(sizeof(char) * (strlen(p_val) + 1));
|
|
Packit |
13e616 |
strcpy(p_new_val, p_val);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
st_insert(p_domain_imp->p_hash, (st_data_t) p_new_key,
|
|
Packit |
13e616 |
(st_data_t) p_new_val);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_prev_val)
|
|
Packit |
13e616 |
free(p_prev_val);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_domain_imp->dirty = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_db_delete(IN osm_db_domain_t * p_domain, IN char *p_key)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_log_t *p_log = p_domain->p_db->p_log;
|
|
Packit |
13e616 |
osm_db_domain_imp_t *p_domain_imp =
|
|
Packit |
13e616 |
(osm_db_domain_imp_t *) p_domain->p_domain_imp;
|
|
Packit |
13e616 |
char *p_prev_val = NULL;
|
|
Packit |
13e616 |
int res;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_acquire(&p_domain_imp->lock);
|
|
Packit |
13e616 |
if (st_delete(p_domain_imp->p_hash,
|
|
Packit |
13e616 |
(void *)&p_key, (void *)&p_prev_val)) {
|
|
Packit |
13e616 |
if (st_lookup(p_domain_imp->p_hash,
|
|
Packit |
13e616 |
(st_data_t) p_key, (void *)&p_prev_val)) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"key:%s still exists in:%s with value:%s\n",
|
|
Packit |
13e616 |
p_key, p_domain_imp->file_name, p_prev_val);
|
|
Packit |
13e616 |
res = 1;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
free(p_key);
|
|
Packit |
13e616 |
free(p_prev_val);
|
|
Packit |
13e616 |
p_domain_imp->dirty = TRUE;
|
|
Packit |
13e616 |
res = 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"fail to find key:%s. delete failed\n", p_key);
|
|
Packit |
13e616 |
res = 1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_spinlock_release(&p_domain_imp->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return res;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef TEST_OSMDB
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <math.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int main(int argc, char **argv)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_t db;
|
|
Packit |
13e616 |
osm_log_t log;
|
|
Packit |
13e616 |
osm_db_domain_t *p_dbd;
|
|
Packit |
13e616 |
cl_list_t keys;
|
|
Packit |
13e616 |
cl_list_iterator_t kI;
|
|
Packit |
13e616 |
char *p_key;
|
|
Packit |
13e616 |
char *p_val;
|
|
Packit |
13e616 |
int i;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&keys);
|
|
Packit |
13e616 |
cl_list_init(&keys, 10);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log_init_v2(&log, TRUE, 0xff, "/var/log/osm_db_test.log", 0, FALSE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_db_construct(&db);
|
|
Packit |
13e616 |
if (osm_db_init(&db, &log)) {
|
|
Packit |
13e616 |
printf("db init failed\n");
|
|
Packit |
13e616 |
exit(1);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_dbd = osm_db_domain_init(&db, "lid_by_guid");
|
|
Packit |
13e616 |
if (!p_dbd) {
|
|
Packit |
13e616 |
printf("db domain init failed\n");
|
|
Packit |
13e616 |
exit(1);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_db_restore(p_dbd)) {
|
|
Packit |
13e616 |
printf("failed to restore\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_db_keys(p_dbd, &keys)) {
|
|
Packit |
13e616 |
printf("failed to get keys\n");
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
kI = cl_list_head(&keys);
|
|
Packit |
13e616 |
while (kI != cl_list_end(&keys)) {
|
|
Packit |
13e616 |
p_key = cl_list_obj(kI);
|
|
Packit |
13e616 |
kI = cl_list_next(kI);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_val = osm_db_lookup(p_dbd, p_key);
|
|
Packit |
13e616 |
printf("key = %s val = %s\n", p_key, p_val);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_remove_all(&keys);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* randomly add and remove numbers */
|
|
Packit |
13e616 |
for (i = 0; i < 10; i++) {
|
|
Packit |
13e616 |
int k;
|
|
Packit |
13e616 |
float v;
|
|
Packit |
13e616 |
int is_add;
|
|
Packit |
13e616 |
char val_buf[16];
|
|
Packit |
13e616 |
char key_buf[16];
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
k = floor(1.0 * rand() / RAND_MAX * 100);
|
|
Packit |
13e616 |
v = rand();
|
|
Packit |
13e616 |
sprintf(key_buf, "%u", k);
|
|
Packit |
13e616 |
sprintf(val_buf, "%u", v);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
is_add = (rand() < RAND_MAX / 2);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (is_add) {
|
|
Packit |
13e616 |
osm_db_update(p_dbd, key_buf, val_buf);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
osm_db_delete(p_dbd, key_buf);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
if (osm_db_keys(p_dbd, &keys)) {
|
|
Packit |
13e616 |
printf("failed to get keys\n");
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
kI = cl_list_head(&keys);
|
|
Packit |
13e616 |
while (kI != cl_list_end(&keys)) {
|
|
Packit |
13e616 |
p_key = cl_list_obj(kI);
|
|
Packit |
13e616 |
kI = cl_list_next(kI);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_val = osm_db_lookup(p_dbd, p_key);
|
|
Packit |
13e616 |
printf("key = %s val = %s\n", p_key, p_val);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
if (osm_db_store(p_dbd, FALSE))
|
|
Packit |
13e616 |
printf("failed to store\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_db_destroy(&db);
|
|
Packit |
13e616 |
cl_list_destroy(&keys);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#endif
|