SyncBase.c

Go to the documentation of this file.
00001 /**
00002  * @file sync/SyncBase.c
00003  * 
00004  * Part of CCNx Sync.
00005  *
00006  * Copyright (C) 2011 Palo Alto Research Center, Inc.
00007  *
00008  * This work is free software; you can redistribute it and/or modify it under
00009  * the terms of the GNU General Public License version 2 as published by the
00010  * Free Software Foundation.
00011  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00014  * for more details. You should have received a copy of the GNU General Public
00015  * License along with this program; if not, write to the
00016  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "SyncActions.h"
00021 #include "SyncBase.h"
00022 #include "SyncPrivate.h"
00023 #include "SyncUtil.h"
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <ccn/uri.h>
00027 #include <ccnr/ccnr_msg.h>
00028 #include <ccnr/ccnr_private.h>
00029 #include <ccnr/ccnr_sync.h>
00030 
00031 // Error support
00032 
00033 extern void
00034 SyncSetErrInner(struct SyncBaseStruct *base,
00035                 enum SyncErrCode code,
00036                 char * file, int line) {
00037     struct SyncErrStruct *err = NEW_STRUCT(1, SyncErrStruct);
00038     err->code = code;
00039     err->file = file;
00040     err->line = line;
00041     struct SyncErrStruct *lag = base->errList;
00042     while (lag != NULL) {
00043         struct SyncErrStruct *next = lag->next;
00044         if (next == NULL) break;
00045         lag = next;
00046     }
00047     if (lag != NULL) lag->next = err;
00048     else base->errList = err;
00049 }
00050 
00051 extern void
00052 SyncClearErr(struct SyncBaseStruct *base) {
00053     for (;;) {
00054         struct SyncErrStruct *err = base->errList;
00055         if (err == NULL) break;
00056         base->errList = err->next;
00057         free(err);
00058     }
00059 }
00060 
00061 
00062 
00063 // Basic object support
00064 
00065 extern struct SyncBaseStruct *
00066 SyncNewBase(struct ccnr_handle *ccnr,
00067             struct ccn *ccn,
00068             struct ccn_schedule *sched) {
00069     sync_time now = SyncCurrentTime();
00070     struct SyncBaseStruct *base = NEW_STRUCT(1, SyncBaseStruct);
00071     base->ccnr = ccnr;
00072     base->ccn = ccn;
00073     base->sched = sched;
00074     struct SyncPrivate *priv = NEW_STRUCT(1, SyncPrivate);
00075     base->priv = priv;
00076     priv->topoAccum = SyncAllocNameAccum(4);
00077     priv->prefixAccum = SyncAllocNameAccum(4);
00078     priv->sliceCmdPrefix = ccn_charbuf_create();
00079     priv->localHostPrefix = ccn_charbuf_create();
00080     priv->comps = ccn_indexbuf_create();
00081     priv->stableTarget = CCNR_NULL_HWM;
00082     priv->stableStored = CCNR_NULL_HWM;
00083     priv->lastStable = now;
00084     priv->lastCacheClean = now;
00085     ccn_name_from_uri(priv->localHostPrefix, "/%C1.M.S.localhost");
00086     ccn_name_from_uri(priv->sliceCmdPrefix, "/%C1.M.S.localhost/%C1.S.cs");
00087     return base;
00088 }
00089 
00090 static int
00091 getEnvLimited(char *key, int lo, int hi, int def) {
00092     char *s = getenv(key);
00093     if (s != NULL && s[0] != 0) {
00094         int x = strtol(s, NULL, 10);
00095         if (x >= lo && x <= hi) return x;
00096     }
00097     return def;
00098 }
00099 
00100 extern void
00101 SyncInit(struct SyncBaseStruct *bp) {
00102     if (bp != NULL) {
00103         struct ccnr_handle *ccnr = bp->ccnr;
00104         char *here = "Sync.SyncInit";
00105         
00106         if (ccnr != NULL) {
00107             // called when there is a Repo that is ready for Sync activity
00108             // TBD: read sync state and restart at the saved commit point
00109             struct SyncPrivate *priv = bp->priv;
00110             bp->debug = ccnr->syncdebug;
00111             
00112             int enable = 1;
00113             char *s = getenv("CCNS_ENABLE");
00114             if (s != NULL && s[0] != 0)
00115                 enable = strtol(s, NULL, 10);
00116             
00117             if (enable <= 0) return;
00118             
00119             char *debugStr = getenv("CCNS_DEBUG");
00120             
00121             // enable/disable storing of sync tree nodes
00122             // default is to store
00123             priv->useRepoStore = getEnvLimited("CCNS_REPO_STORE", 0, 1, 1);
00124             
00125             // enable/disable stable recovery point
00126             // default is to disable recovery, but to calculate stable points
00127             priv->stableEnabled = getEnvLimited("CCNS_STABLE_ENABLED", 0, 1, 1);
00128             
00129             // get faux error percent
00130             priv->fauxErrorTrigger = getEnvLimited("CCNS_FAUX_ERROR",
00131                                                    0, 99, 0);
00132             
00133             // get private flags for SyncActions
00134             priv->syncActionsPrivate = getEnvLimited("CCNS_ACTIONS_PRIVATE",
00135                                                      0, 255, 3);
00136             
00137             // heartbeat rate
00138             priv->heartbeatMicros = getEnvLimited("CCNS_HEARTBEAT_MICROS",
00139                                                   10000, 10*1000000, 200000);
00140             
00141             // root advise lifetime
00142             priv->rootAdviseFresh = getEnvLimited("CCNS_ROOT_ADVISE_FRESH",
00143                                                   1, 30, 4);
00144             
00145             // root advise lifetime
00146             priv->rootAdviseLifetime = getEnvLimited("CCNS_ROOT_ADVISE_LIFETIME",
00147                                                      1, 30, 20);
00148             
00149             // root advise lifetime
00150             priv->fetchLifetime = getEnvLimited("CCNS_NODE_FETCH_LIFETIME",
00151                                                 1, 30, 4);
00152 
00153             // max node or content fetches busy per root
00154             priv->maxFetchBusy = getEnvLimited("CCNS_MAX_FETCH_BUSY",
00155                                                1, 100, 6);
00156 
00157             // max number of compares busy
00158             priv->maxComparesBusy = getEnvLimited("CCNS_MAX_COMPARES_BUSY",
00159                                                1, 100, 4);
00160             
00161             
00162             if (bp->debug >= CCNL_INFO) {
00163                 char temp[1024];
00164                 int pos = 0;
00165                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00166                                 "CCNS_ENABLE=%d",
00167                                 enable);
00168                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00169                                 ",CCNS_DEBUG=%s",
00170                                 debugStr);
00171                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00172                                 ",CCNS_REPO_STORE=%d",
00173                                 priv->useRepoStore);
00174                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00175                                 ",CCNS_STABLE_ENABLED=%d",
00176                                 priv->stableEnabled);
00177                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00178                                 ",CCNS_FAUX_ERROR=%d",
00179                                 priv->fauxErrorTrigger);
00180                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00181                                 ",CCNS_ACTIONS_PRIVATE=%d",
00182                                 priv->syncActionsPrivate);
00183                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00184                                 ",CCNS_HEARTBEAT_MICROS=%d",
00185                                 priv->heartbeatMicros);
00186                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00187                                 ",CCNS_ROOT_ADVISE_FRESH=%d",
00188                                 priv->rootAdviseFresh);
00189                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00190                                 ",CCNS_ROOT_ADVISE_LIFETIME=%d",
00191                                 priv->rootAdviseLifetime);
00192                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00193                                 ",CCNS_NODE_FETCH_LIFETIME=%d",
00194                                 priv->fetchLifetime);
00195                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00196                                 ",CCNS_MAX_FETCH_BUSY=%d",
00197                                 priv->maxFetchBusy);
00198                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00199                                 ",CCNS_MAX_COMPARES_BUSY=%d",
00200                                 priv->maxComparesBusy);
00201 #if (CCN_API_VERSION >= 4004)
00202                 pos += snprintf(temp+pos, sizeof(temp)-pos,
00203                                 ",defer_verification=%d",
00204                                 ccn_defer_verification(bp->ccn, -1));
00205 #endif
00206                 ccnr_msg(ccnr, "%s, %s", here, temp);
00207             }
00208             
00209             SyncStartHeartbeat(bp);
00210         }
00211     }
00212 }
00213 
00214 extern void
00215 SyncFreeBase(struct SyncBaseStruct **bp) {
00216     if (bp != NULL) {
00217         struct SyncBaseStruct *base = *bp;
00218         *bp = NULL;
00219         if (base != NULL) {
00220             struct SyncPrivate *priv = base->priv;
00221             // free the errList
00222             SyncClearErr(base);
00223             // free the roots
00224             while (priv->rootHead != NULL) {
00225                 if (SyncRemRoot(priv->rootHead) != NULL) break;
00226             }
00227             // free the name accums
00228             if (priv->topoAccum != NULL)
00229                 SyncFreeNameAccumAndNames(priv->topoAccum);
00230             if (priv->prefixAccum != NULL)
00231                 SyncFreeNameAccumAndNames(priv->prefixAccum);
00232             if (priv->comps != NULL)
00233                 ccn_indexbuf_destroy(&priv->comps);
00234             ccn_charbuf_destroy(&priv->sliceCmdPrefix);
00235             free(priv);
00236             free(base);
00237         }
00238     }
00239 }
00240 
00241 // Enumeration support
00242 extern int
00243 SyncNotifyContent(struct SyncBaseStruct *base,
00244                   int enumeration,
00245                   ccnr_accession item,
00246                   struct ccn_charbuf *name) {
00247     // here for any updates, whether from time-based enumeration
00248     // or from prefix-based enumeration
00249     char *here = "Sync.SyncNotifyContent";
00250     
00251     if (base != NULL && base->ccnr != NULL) {
00252         struct SyncPrivate *priv = base->priv;
00253         int debug = base->debug;
00254         
00255         if (name == NULL) {
00256             // end of an enumeration
00257             if (enumeration == 0) {
00258                 if (debug >= CCNL_WARNING)
00259                     ccnr_msg(base->ccnr, "%s, end of time-based enum?", here);
00260             } else if (enumeration == priv->sliceEnum) {
00261                 priv->sliceEnum = 0;
00262                 if (debug >= CCNL_INFO)
00263                     ccnr_msg(base->ccnr, "%s, all slice names seen", here);
00264             } else if (enumeration == priv->sliceBusy) {
00265                 priv->sliceBusy = 0;
00266                 struct SyncRootStruct *root = priv->rootHead;
00267                 while (root != NULL) {
00268                     struct SyncRootPrivate *rp = root->priv;
00269                     if (enumeration == rp->sliceBusy) {
00270                         rp->sliceBusy = 0;
00271                         if (debug >= CCNL_INFO)
00272                             SyncNoteSimple(root, here, "slice enum done");
00273                         break;
00274                     }
00275                     root = root->next;
00276                 }
00277                 // may need a new enumeration started
00278                 root = priv->rootHead;
00279                 while (root != NULL) {
00280                     struct SyncRootPrivate *rp = root->priv;
00281                     if (rp->sliceBusy < 0) {
00282                         SyncStartSliceEnum(root);
00283                         break;
00284                     }
00285                     root = root->next;
00286                 }  
00287             } else {
00288                 if (debug >= CCNL_WARNING)
00289                     ccnr_msg(base->ccnr, "%s, end of what enum?", here);
00290             }
00291             return -1;
00292         }
00293         
00294         if (debug >= CCNL_FINE) {
00295             struct ccn_charbuf *uri = SyncUriForName(name);
00296             ccnr_msg(base->ccnr,
00297                      "%s, enum %d, %s!",
00298                      here, enumeration, ccn_charbuf_as_string(uri));
00299             ccn_charbuf_destroy(&uri);
00300         }
00301         
00302         struct ccn_indexbuf *comps = priv->comps;
00303         int splitRes = ccn_name_split(name, comps);
00304         if (splitRes < 0) {
00305             // really hould not happen!  but it does not hurt to log and ignore it
00306             if (debug >= CCNL_SEVERE)
00307                 ccnr_msg(base->ccnr, "%s, invalid name!", here);
00308             return 0;
00309         }
00310         
00311         unsigned char *comp0 = NULL;
00312         size_t size0 = 0;
00313         unsigned char *comp1 = NULL;
00314         size_t size1 = 0;
00315         ccn_name_comp_get(name->buf, comps, 0, 
00316                           (const unsigned char **) &comp0, &size0);
00317         ccn_name_comp_get(name->buf, comps, 1,
00318                           (const unsigned char **) &comp1, &size1);
00319         ccnr_accession mark = item;
00320         if (SyncPrefixMatch(priv->localHostPrefix, name, 0)) {
00321             // to the local host, don't update the stable target
00322             mark = CCNR_NULL_ACCESSION;
00323             if (SyncPrefixMatch(priv->sliceCmdPrefix, name, 0))
00324                 // this is a new slice
00325                 SyncHandleSlice(base, name);
00326         }
00327         if (mark != CCNR_NULL_ACCESSION)
00328             priv->stableTarget = ccnr_hwm_update(base->ccnr, priv->stableTarget, mark);
00329         
00330         // add the name to any applicable roots
00331         SyncAddName(base, name, item);
00332         return 0;
00333     }
00334     return -1;
00335 }
00336 
00337 extern void
00338 SyncShutdown(struct SyncBaseStruct *bp) {
00339     char *here = "Sync.SyncShutdown";
00340     int debug = bp->debug;
00341     if (debug >= CCNL_INFO)
00342         ccnr_msg(bp->ccnr, "%s", here);
00343     // TBD: shutdown the hearbeat
00344     // TBD: unregister the prefixes
00345 }
00346 
00347 

Generated on Thu Feb 16 00:44:01 2012 for Content-Centric Networking in C by  doxygen 1.5.6