modules/rp/rp_load.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. make_sql2pack
  2. RP_sql_load_attr_space
  3. RP_sql_load_reg
  4. RP_asc_load

   1 /***************************************
   2   $Revision: 1.24 $
   3 
   4   Radix payload (rp) - user level functions for storing data in radix trees
   5 
   6   rp_load = loading the radix trees with data on startup
   7 
   8   Status: NOT REVIEWED, TESTED
   9   
  10   Design and implementation by: Marek Bukowy
  11   
  12   ******************/ /******************
  13   Copyright (c) 1999                              RIPE NCC
  14  
  15   All Rights Reserved
  16   
  17   Permission to use, copy, modify, and distribute this software and its
  18   documentation for any purpose and without fee is hereby granted,
  19   provided that the above copyright notice appear in all copies and that
  20   both that copyright notice and this permission notice appear in
  21   supporting documentation, and that the name of the author not be
  22   used in advertising or publicity pertaining to distribution of the
  23   software without specific, written prior permission.
  24   
  25   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  26   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  27   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  28   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  29   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  30   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  31   ***************************************/
  32 #include <rp.h>
  33 #include <mysql_driver.h>
  34 #include <constants.h>
  35 #include "ca_configFns.h"
  36 #include "ca_dictionary.h"
  37 #include "ca_macros.h"
  38 #include "ca_srcAttribs.h"
  39 #include "ta.h"
  40 
  41 static
  42 er_ret_t
  43 make_sql2pack(SQ_result_set_t *result, SQ_row_t *row, 
     /* [<][>][^][v][top][bottom][index][help] */
  44               rp_upd_pack_t *pack, rp_attr_t  attr, ip_space_t space, 
  45               int colcount)
  46 {
  47   er_ret_t   conv = RP_OK;
  48   rp_uni_t   *uniptr = &(pack->uni);
  49   char       *idptr; /* initially set to the 0'th column */
  50   char       *col[5];
  51   unsigned   i;
  52 
  53   dieif(colcount>5); /* size of the col array */
  54 
  55   for(i=0; i<colcount; i++) {
  56     col[i] = SQ_get_column_string_nocopy(result, row, i);
  57     if (col[i] == NULL) {
  58       die;
  59     }
  60   }
  61 
  62   idptr = col[0];
  63 
  64   pack->type = attr;
  65   pack->d.origin = NULL;
  66   switch( attr ) {
  67   case A_IN:
  68     /*
  69       read 0-2 from inetnum
  70       0 - objectid
  71       1 - begin   
  72       2 - end     
  73     */
  74     uniptr->space = IP_V4;
  75     conv = IP_rang_f2b_v4( &(uniptr->u.in), col[1], col[2] );
  76     break;
  77   case A_RT:
  78     /*
  79       read 0-3 from route
  80       0 - objectid 
  81       1 - prefix    
  82       2 - prefix_length   
  83       3 - origin
  84     */
  85     uniptr->space = IP_V4;
  86     if( NOERR(conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] ))) {
  87       dieif(wr_malloc( (void **) &(pack->d.origin), strlen(col[3])+1)
  88             != UT_OK);
  89 
  90       strcpy(pack->d.origin, col[3]);
  91     }
  92     break;
  93   case A_DN:
  94     if( space == IP_V4 ) {
  95     /*
  96       read 0-3 from inaddr
  97       0 - objectid 
  98       1 - prefix
  99       2 - prefix_length   
 100       3 - domain
 101     */
 102       conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] );
 103       uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
 104       dieif(wr_malloc( (void **) &(pack->d.domain), strlen(col[3])+1)
 105             != UT_OK);
 106       strcpy(pack->d.domain, col[3]);
 107     }
 108     else {
 109       /* read 0-4 from ip6int
 110          0 - objectid 
 111          1 - msb
 112          2 - lsb
 113          3 - prefix_length 
 114          4 - domain
 115     */
 116       conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3] );
 117       uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
 118     
 119       dieif(wr_malloc( (void **) &(pack->d.domain), strlen(col[4])+1)
 120             != UT_OK);
 121       strcpy(pack->d.domain, col[4]);
 122     }
 123     break;
 124   case A_I6: 
 125     /*
 126       read 0-3 from inaddr
 127       0 - objectid 
 128       1 - msb
 129       2 - lsb
 130       3 - prefix_length 
 131     */
 132     conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3]);
 133     uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
 134     break;
 135   default:
 136     /*    die; / * shouldn't have got here */
 137     conv = IP_INVARG;
 138   }
 139   
 140   if( sscanf(idptr, "%lu", &(pack->key) ) < 1 ) {
 141     conv = IP_INVARG;
 142   }
 143   
 144 
 145   for(i=0; i<colcount; i++) {
 146     /*    wr_free(col[i]);*/ ;
 147   }
 148   
 149   return conv;
 150 }
 151 
 152 static
 153 er_ret_t
 154 RP_sql_load_attr_space( rp_attr_t attr, ip_space_t space, 
     /* [<][>][^][v][top][bottom][index][help] */
 155                         rp_regid_t reg_id, SQ_connection_t *con
 156                         )
 157 {
 158   SQ_row_t *row;
 159   SQ_result_set_t *result;
 160   int objnr=0;
 161   rx_tree_t   *mytree;
 162   rp_upd_pack_t pack;
 163   int colcount;
 164   int sizedebug = ER_is_traced(FAC_RP, ASP_RP_LOAD_DET);
 165   char *v4 = DF_attrcode_radix_load_v4(attr);
 166   char *v6 = DF_attrcode_radix_load_v6(attr);
 167   char *vu = (space == IP_V4) ? v4 : v6;
 168   char *srcnam = ca_get_srcname(reg_id);
 169   char activity[64];
 170 
 171   dieif( vu == NULL /* loading query undefined */ );
 172 #if 0
 173   if( attr==A_IN && space==IP_V4 ) {
 174     vu = "SELECT  object_id,begin_in,end_in FROM    inetnum WHERE   thread_id = 0 AND begin_in >= 3238002688 AND end_in < 3254779904 ";
 175   }
 176 #endif
 177 
 178   dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
 179  
 180   ER_inf_va(FAC_RP, ASP_RP_LOAD_DET, "loading using %s", vu);
 181   ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size before query = %x", sbrk(0));
 182   
 183   sprintf(activity, "%s/%s, query ", srcnam, DF_get_attribute_code(attr));
 184   TA_setactivity(activity);
 185   TA_increment();
 186 
 187   if ( SQ_execute_query(con, vu, &result) == -1 ) { 
 188     fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
 189     die;
 190   }
 191   else { 
 192     colcount = SQ_get_column_count(result);
 193     
 194     ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, 
 195               "size after query = %x; columns = %d", sbrk(0), colcount);
 196     
 197     /* LOCKED when created, so no need to acquire lock here */
 198     
 199     while ( (row = SQ_row_next(result)) != NULL 
 200             && SQ_errno(con) == 0 ) {
 201       
 202       dieif( ! NOERR(make_sql2pack(result, row, &pack, attr, space, 
 203                                    colcount)) );
 204       
 205       if( ! NOERR(RP_pack_node_l(RX_OPER_CRE, &pack, mytree))) {
 206         fprintf(stderr,"%d:\t%ld\n", objnr, pack.key);
 207         die;
 208       }
 209       
 210       /* free allocated memory */
 211       if( pack.d.origin != NULL ) {
 212         wr_free(pack.d.origin);
 213         pack.d.origin = NULL;
 214       }
 215       
 216       objnr++;
 217       
 218       if( sizedebug ) {
 219         ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size after object %d = %x", 
 220                   objnr, sbrk(0));
 221       }
 222       
 223       if( objnr % 1000 == 0 ) {
 224 
 225           sprintf(activity, "%s/%s, %d done ", 
 226                   srcnam, DF_get_attribute_code(attr), objnr);
 227           TA_setactivity(activity);
 228       }
 229     }
 230     /* XXX UNLOCK */
 231     TH_release_write_lockw( &(mytree->rwlock) );
 232   }
 233 
 234   if( SQ_errno(con) == 0 ) {
 235       SQ_free_result(result);
 236   } else {
 237       die;
 238   }
 239 
 240   ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN, "loaded %d objects into %s", objnr,
 241             DF_get_attribute_code(attr) );
 242  
 243   wr_free(srcnam);
 244   return RP_OK;
 245 }
 246 
 247 er_ret_t
 248 RP_sql_load_reg(rp_regid_t reg_id) 
     /* [<][>][^][v][top][bottom][index][help] */
 249 {
 250   
 251   er_ret_t err;
 252   SQ_connection_t *con;
 253   char *dbhost = ca_get_srcdbmachine(reg_id);
 254   char *dbname = ca_get_srcdbname(reg_id);
 255   char *dbuser = ca_get_srcdbuser(reg_id);
 256   char *dbpass = ca_get_srcdbpassword(reg_id);
 257   char *srcnam = ca_get_srcname(reg_id);
 258   unsigned dbport = ca_get_srcdbport(reg_id);
 259 
 260   TA_add( 0, "rx load");
 261 
 262   con = SQ_get_connection( dbhost, dbport, dbname, dbuser, dbpass );
 263 
 264   dieif ( SQ_execute_query(con, "LOCK TABLES     " 
 265      "route READ, inetnum READ, inet6num READ,   "
 266      "inaddr_arpa READ, domain READ, ip6int READ ",
 267                            NULL) == -1 );
 268 
 269   do {
 270     if( !NOERR(err=RP_sql_load_attr_space( A_RT, IP_V4, reg_id, con))) {
 271       break;
 272     }
 273     if( !NOERR(err=RP_sql_load_attr_space( A_IN, IP_V4, reg_id, con))) {
 274       break;
 275     }
 276     if( !NOERR(err=RP_sql_load_attr_space( A_I6, IP_V6, reg_id, con))) {
 277       break;
 278     }
 279     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V4, reg_id, con))) {
 280       break;
 281     }
 282     if( !NOERR(err=RP_sql_load_attr_space( A_DN, IP_V6, reg_id, con))) {
 283       break;
 284     }
 285     /* CONSTCOND */
 286   } while(0);
 287 
 288   dieif ( SQ_execute_query(con, "UNLOCK TABLES", NULL) == -1 );
 289 
 290   /* Close connection */
 291   SQ_close_connection(con);
 292 
 293   TA_delete();
 294 
 295   /* free junk */
 296   wr_free(dbhost);
 297   wr_free(dbname);
 298   wr_free(dbuser);
 299   wr_free(dbpass);
 300   wr_free(srcnam);
 301   return err;
 302 }
 303 
 304 
 305 /* 
 306    load the tree from an ascii file (short attr names).
 307    mainly for testing... 
 308 */
 309 er_ret_t
 310 RP_asc_load(char *filename, int maxobj, int operation, 
     /* [<][>][^][v][top][bottom][index][help] */
 311             rp_regid_t reg_id)
 312 {
 313   er_ret_t err;
 314   FILE *fp;
 315   char buf[1024];
 316   char fulltext[65536];
 317   int objnr = 0;
 318   unsigned len, oldlen=0, ranlen;
 319   char rangstr[IP_RANGSTR_MAX];
 320   int parsed = 0;
 321   int eor; /* end of record */
 322 
 323   
 324   if( (fp = fopen(filename,"r")) == NULL ) {
 325     perror(filename);
 326     die; 
 327   }
 328  
 329   do {
 330     fgets(buf, 128, fp);
 331 
 332     eor = ( strlen(buf) <= 1 || feof(fp) );
 333       
 334     if( strlen(buf) > 1 ) {
 335       len = strlen(buf);
 336       dieif( oldlen+len+1 > 65536 ); /* object too long */
 337       memcpy( fulltext+oldlen, buf, len);
 338       oldlen+=len;
 339       
 340       fulltext[oldlen]=0;
 341     }
 342     
 343     if( eor ) {              /* end of object: put into the database. */
 344       parsed++;
 345       
 346       /* see if it was just some whitespace junk and nothing more */
 347       if( *fulltext==0 ) {
 348         continue;  /* discard */
 349       }
 350 
 351       /* check if it's a radix object */
 352       do {
 353         char attrname[3];
 354         A_Type_t attrcode;
 355         
 356         if( fulltext[0] == '*' &&  fulltext[3] == ':' ) {
 357           strncpy(attrname, fulltext+1, 2);
 358           attrname[2]=0;
 359           
 360           if(strcmp(attrname, "XX") == 0 ) {
 361             /* object deleted */
 362             break;
 363           }
 364           
 365           if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
 366             fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
 367             break;
 368           }
 369           
 370           if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
 371             /* no interest to radix */
 372             break;
 373           }
 374         
 375           /* copy and translate the range */
 376           ranlen = index(fulltext+5,'\n')-fulltext-5;
 377           strncpy(rangstr, fulltext+5, ranlen);
 378           rangstr[ranlen]=0;
 379                
 380           if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,  
 381                                     fulltext, strlen(fulltext)+1, 0L )) ) {
 382             objnr++;
 383           }
 384           else {
 385             die; /* error putting into the radix tree */
 386             return err;
 387           }
 388           
 389         }
 390         /* CONSTCOND */
 391       } while(0);
 392       
 393       *fulltext=0;
 394       oldlen=0;
 395     }
 396   }
 397   while(!feof(fp) && objnr<maxobj);  
 398 
 399   return RP_OK;
 400 }

/* [<][>][^][v][top][bottom][index][help] */