• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

CachePagesInternal.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #include "P_Cache.h"
00025 
00026 #include "Show.h"
00027 #include "I_Tasks.h"
00028 
00029 struct ShowCacheInternal: public ShowCont
00030 {
00031   int vol_index;
00032   int seg_index;
00033   CacheKey show_cache_key;
00034   CacheVC *cache_vc;
00035 
00036 
00037   int showMain(int event, Event * e);
00038   int showEvacuations(int event, Event * e);
00039   int showVolEvacuations(int event, Event * e);
00040   int showVolumes(int event, Event * e);
00041   int showVolVolumes(int event, Event * e);
00042   int showSegments(int event, Event * e);
00043   int showSegSegment(int event, Event * e);
00044 #ifdef CACHE_STAT_PAGES
00045   int showConnections(int event, Event * e);
00046   int showVolConnections(int event, Event * e);
00047 #endif
00048 
00049   ShowCacheInternal(Continuation * c, HTTPHdr * h)
00050     : ShowCont(c, h), vol_index(0), seg_index(0)
00051   {
00052     SET_HANDLER(&ShowCacheInternal::showMain);
00053   }
00054 
00055   ~ShowCacheInternal() {
00056   }
00057 
00058 };
00059 extern ShowCacheInternal *theshowcacheInternal;
00060 Action *register_ShowCacheInternal(Continuation * c, HTTPHdr * h);
00061 
00062 
00063 
00064 
00065 extern Vol **gvol;
00066 extern volatile int gnvol;
00067 
00068 
00069 // Stat Pages
00070 ShowCacheInternal *theshowcacheInternal = NULL;
00071 
00072 
00073 #define STREQ_PREFIX(_x,_s) (!strncasecmp(_x,_s,sizeof(_s)-1))
00074 #define STREQ_LEN_PREFIX(_x,_l,_s) (path_len < sizeof(_s) && !strncasecmp(_x,_s,sizeof(_s)-1))
00075 
00076 
00077 Action *
00078 register_ShowCacheInternal(Continuation * c, HTTPHdr * h)
00079 {
00080   theshowcacheInternal = new ShowCacheInternal(c, h);
00081   URL *u = h->url_get();
00082 
00083   int path_len;
00084   const char *path = u->path_get(&path_len);
00085 
00086   if (!path) {
00087   }
00088 #ifdef CACHE_STAT_PAGES
00089   else if (STREQ_LEN_PREFIX(path, path_len, "connections")) {
00090     SET_CONTINUATION_HANDLER(theshowcacheInternal, &ShowCacheInternal::showConnections);
00091   }
00092 #endif
00093   else if (STREQ_PREFIX(path, "evacuations")) {
00094     SET_CONTINUATION_HANDLER(theshowcacheInternal, &ShowCacheInternal::showEvacuations);
00095   } else if (STREQ_PREFIX(path, "volumes")) {
00096     SET_CONTINUATION_HANDLER(theshowcacheInternal, &ShowCacheInternal::showVolumes);
00097   }
00098 
00099   if (theshowcacheInternal->mutex->thread_holding)
00100     CONT_SCHED_LOCK_RETRY(theshowcacheInternal);
00101   else
00102     eventProcessor.schedule_imm(theshowcacheInternal, ET_TASK);
00103   return &theshowcacheInternal->action;
00104 }
00105 
00106 
00107 int
00108 ShowCacheInternal::showMain(int event, Event * e)
00109 {
00110   CHECK_SHOW(begin("Cache"));
00111 #ifdef CACHE_STAT_PAGES
00112   CHECK_SHOW(show("<H3>Show <A HREF=\"./connections\">Connections</A></H3>\n"
00113                   "<H3>Show <A HREF=\"./evacuations\">Evacuations</A></H3>\n"
00114                   "<H3>Show <A HREF=\"./volumes\">Volumes</A></H3>\n"));
00115 #else
00116   CHECK_SHOW(show("<H3>Show <A HREF=\"./evacuations\">Evacuations</A></H3>\n"
00117                   "<H3>Show <A HREF=\"./volumes\">Volumes</A></H3>\n"));
00118 #endif
00119   return complete(event, e);
00120 }
00121 
00122 #ifdef CACHE_STAT_PAGES
00123 int
00124 ShowCacheInternal::showConnections(int event, Event * e)
00125 {
00126   CHECK_SHOW(begin("Cache VConnections"));
00127   CHECK_SHOW(show("<H3>Cache Connections</H3>\n"
00128                   "<table border=1><tr>"
00129                   "<th>Operation</th>"
00130                   "<th>Volume</th>"
00131                   "<th>URL/Hash</th>" "<th>Bytes Done</th>" "<th>Total Bytes</th>" "<th>Bytes Todo</th>" "</tr>\n"));
00132 
00133   SET_HANDLER(&ShowCacheInternal::showVolConnections);
00134   CONT_SCHED_LOCK_RETRY_RET(this);
00135 }
00136 
00137 
00138 int
00139 ShowCacheInternal::showVolConnections(int event, Event * e)
00140 {
00141   CACHE_TRY_LOCK(lock, gvol[vol_index]->mutex, mutex->thread_holding);
00142   if (!lock) {
00143     CONT_SCHED_LOCK_RETRY_RET(this);
00144   }
00145   for (CacheVC * vc = (CacheVC *) gvol[vol_index]->stat_cache_vcs.head; vc; vc = vc->stat_link.next) {
00146 
00147     char nbytes[60], todo[60], url[81092];
00148     int ib = 0, xd = 0;
00149     URL uu;
00150 
00151     MUTEX_LOCK(lock2, vc->mutex, mutex->thread_holding);
00152     // if vc is closed ignore - Ramki 08/30/2000
00153     if (vc->closed == 1)
00154       continue;
00155     sprintf(nbytes, "%d", vc->vio.nbytes);
00156     sprintf(todo, "%d", vc->vio.ntodo());
00157 
00158     if (vc->f.frag_type == CACHE_FRAG_TYPE_HTTP && vc->request.valid()) {
00159       URL *u = vc->request.url_get(&uu);
00160       u->print(url, 8000, &ib, &xd);
00161       url[ib] = 0;
00162     } else if (vc->alternate.valid()) {
00163       URL *u = vc->alternate.request_url_get(&uu);
00164       u->print(url, 8000, &ib, &xd);
00165       url[ib] = 0;
00166     } else
00167       vc->key.string(url);
00168     CHECK_SHOW(show("<tr>" "<td>%s</td>"        // operation
00169                     "<td>%s</td>"       // Vol
00170                     "<td>%s</td>"       // URL/Hash
00171                     "<td>%d</td>"
00172                     "<td>%s</td>"
00173                     "<td>%s</td>"
00174                     "</tr>\n",
00175                     ((vc->vio.op == VIO::READ) ? "Read" : "Write"),
00176                     vc->vol->hash_id,
00177                     url,
00178                     vc->vio.ndone,
00179                     vc->vio.nbytes == INT64_MAX ? "all" : nbytes, vc->vio.nbytes == INT64_MAX ? "all" : todo));
00180   }
00181   vol_index++;
00182   if (vol_index < gnvol)
00183     CONT_SCHED_LOCK_RETRY(this);
00184   else {
00185     CHECK_SHOW(show("</table>\n"));
00186     return complete(event, e);
00187   }
00188   return EVENT_CONT;
00189 }
00190 
00191 #endif
00192 
00193 
00194 int
00195 ShowCacheInternal::showEvacuations(int event, Event * e)
00196 {
00197   CHECK_SHOW(begin("Cache Pending Evacuations"));
00198   CHECK_SHOW(show("<H3>Cache Evacuations</H3>\n"
00199                   "<table border=1><tr>"
00200                   "<th>Offset</th>" "<th>Estimated Size</th>" "<th>Reader Count</th>" "<th>Done</th>" "</tr>\n"));
00201 
00202   SET_HANDLER(&ShowCacheInternal::showVolEvacuations);
00203   CONT_SCHED_LOCK_RETRY_RET(this);
00204 }
00205 
00206 
00207 int
00208 ShowCacheInternal::showVolEvacuations(int event, Event * e)
00209 {
00210   Vol *p = gvol[vol_index];
00211   CACHE_TRY_LOCK(lock, p->mutex, mutex->thread_holding);
00212   if (!lock)
00213     CONT_SCHED_LOCK_RETRY_RET(this);
00214 
00215   EvacuationBlock *b;
00216   int last = (p->len - (p->start - p->skip)) / EVACUATION_BUCKET_SIZE;
00217   for (int i = 0; i < last; i++) {
00218     for (b = p->evacuate[i].head; b; b = b->link.next) {
00219       char offset[60];
00220       sprintf(offset, "%" PRIu64 "", (uint64_t) vol_offset(p, &b->dir));
00221       CHECK_SHOW(show("<tr>" "<td>%s</td>"      // offset
00222                       "<td>%d</td>"     // estimated size
00223                       "<td>%d</td>"     // reader count
00224                       "<td>%s</td>"     // done
00225                       "</tr>\n", offset, (int) dir_approx_size(&b->dir), b->readers, b->f.done ? "yes" : "no"));
00226     }
00227   }
00228   vol_index++;
00229   if (vol_index < gnvol)
00230     CONT_SCHED_LOCK_RETRY(this);
00231   else {
00232     CHECK_SHOW(show("</table>\n"));
00233     return complete(event, e);
00234   }
00235   return EVENT_CONT;
00236 }
00237 
00238 int
00239 ShowCacheInternal::showVolumes(int event, Event * e)
00240 {
00241   CHECK_SHOW(begin("Cache Volumes"));
00242   CHECK_SHOW(show("<H3>Cache Volumes</H3>\n"
00243                   "<table border=1><tr>"
00244                   "<th>ID</th>"
00245                   "<th>Blocks</th>"
00246                   "<th>Directory Entries</th>"
00247                   "<th>Write Position</th>"
00248                   "<th>Write Agg Todo</th>"
00249                   "<th>Write Agg Todo Size</th>"
00250                   "<th>Write Agg Done</th>"
00251                   "<th>Phase</th>" "<th>Create Time</th>" "<th>Sync Serial</th>" "<th>Write Serial</th>" "</tr>\n"));
00252 
00253   SET_HANDLER(&ShowCacheInternal::showVolVolumes);
00254   CONT_SCHED_LOCK_RETRY_RET(this);
00255 }
00256 
00257 
00258 int
00259 ShowCacheInternal::showVolVolumes(int event, Event * e)
00260 {
00261   Vol *p = gvol[vol_index];
00262   CACHE_TRY_LOCK(lock, p->mutex, mutex->thread_holding);
00263   if (!lock)
00264     CONT_SCHED_LOCK_RETRY_RET(this);
00265 
00266   char ctime[256];
00267   ink_ctime_r(&p->header->create_time, ctime);
00268   ctime[strlen(ctime) - 1] = 0;
00269   int agg_todo = 0;
00270   int agg_done = p->agg_buf_pos;
00271   CacheVC *c = 0;
00272   for (c = p->agg.head; c; c = (CacheVC *) c->link.next)
00273     agg_todo++;
00274   CHECK_SHOW(show("<tr>" "<td>%s</td>"  // ID
00275                   "<td>%" PRId64 "</td>" // blocks
00276                   "<td>%" PRId64 "</td>" // directory entries
00277                   "<td>%" PRId64 "</td>" // write position
00278                   "<td>%d</td>" // write agg to do
00279                   "<td>%d</td>" // write agg to do size
00280                   "<td>%d</td>" // write agg done
00281                   "<td>%d</td>" // phase
00282                   "<td>%s</td>" // create time
00283                   "<td>%u</td>" // sync serial
00284                   "<td>%u</td>" // write serial
00285                   "</tr>\n",
00286                   p->hash_text.get(),
00287                   (uint64_t)((p->len - (p->start - p->skip)) / CACHE_BLOCK_SIZE),
00288                   (uint64_t)(p->buckets * DIR_DEPTH * p->segments),
00289                   (uint64_t)((p->header->write_pos - p->start) / CACHE_BLOCK_SIZE),
00290                   agg_todo,
00291                   p->agg_todo_size,
00292                   agg_done, p->header->phase, ctime, p->header->sync_serial, p->header->write_serial));
00293   CHECK_SHOW(show("</table>\n"));
00294   SET_HANDLER(&ShowCacheInternal::showSegments);
00295   return showSegments(event, e);
00296 }
00297 
00298 int
00299 ShowCacheInternal::showSegments(int event, Event * e)
00300 {
00301   CHECK_SHOW(show("<H3>Cache Volume Segments</H3>\n"
00302                   "<table border=1><tr>"
00303                   "<th>Free</th>"
00304                   "<th>Used</th>"
00305                   "<th>Empty</th>" "<th>Valid</th>" "<th>Agg Valid</th>" "<th>Avg Size</th>" "</tr>\n"));
00306 
00307   SET_HANDLER(&ShowCacheInternal::showSegSegment);
00308   seg_index = 0;
00309   CONT_SCHED_LOCK_RETRY_RET(this);
00310 }
00311 
00312 int
00313 ShowCacheInternal::showSegSegment(int event, Event * e)
00314 {
00315   Vol *p = gvol[vol_index];
00316   CACHE_TRY_LOCK(lock, p->mutex, mutex->thread_holding);
00317   if (!lock)
00318     CONT_SCHED_LOCK_RETRY_RET(this);
00319   int free = 0, used = 0, empty = 0, valid = 0, agg_valid = 0, avg_size = 0;
00320   dir_segment_accounted(seg_index, p, 0, &free, &used, &empty, &valid, &agg_valid, &avg_size);
00321   CHECK_SHOW(show("<tr>"
00322                   "<td>%d</td>"
00323                   "<td>%d</td>"
00324                   "<td>%d</td>"
00325                   "<td>%d</td>" "<td>%d</td>" "<td>%d</td>" "</tr>\n", free, used, empty, valid, agg_valid, avg_size));
00326   seg_index++;
00327   if (seg_index < p->segments)
00328     CONT_SCHED_LOCK_RETRY(this);
00329   else {
00330     CHECK_SHOW(show("</table>\n"));
00331     seg_index = 0;
00332     vol_index++;
00333     if (vol_index < gnvol)
00334       CONT_SCHED_LOCK_RETRY(this);
00335     else
00336       return complete(event, e);
00337   }
00338   return EVENT_CONT;
00339 }
00340 

Generated by  doxygen 1.7.1