~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
cvs/emstar/devel/geonet/diskmanager/diskmanager_main.c


  1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: 1; c-basic-offset: 2 -*- */
  2 /*
  3  *
  4  * Copyright (c) 2007 The Regents of the University of California.  All 
  5  * rights reserved.
  6  *
  7  * Redistribution and use in source and binary forms, with or without
  8  * modification, are permitted provided that the following conditions
  9  * are met:
 10  *
 11  * - Redistributions of source code must retain the above copyright
 12  *   notice, this list of conditions and the following disclaimer.
 13  *
 14  * - Neither the name of the University nor the names of its
 15  *   contributors may be used to endorse or promote products derived
 16  *   from this software without specific prior written permission.
 17  *
 18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 21  * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29  *
 30  */
 31 
 32 #include "diskmanager_i.h"
 33 
 34 char diskmanager_main_c_cvsid[] = "$Id: diskmanager_main.c,v 1.18 2009-06-11 06:04:35 mlukac Exp $";
 35 
 36 static void diskmanager_shutdown(void *data)
 37 {
 38   //Do cleanup if necessary
 39   exit(0);
 40 }
 41 
 42 int diskmanager_update(ssync_sub_t *sub, diskmanager_table_t *table, int count, void *data)
 43 {
 44   int i = 0;
 45   diskmanager_state_t *dms = (diskmanager_state_t *) ssync_sub_data(sub); 
 46     
 47   for (i = 0; i < count; ++i) {
 48     if (table[i].header.flow_id.src == my_node_id) {
 49       elog(LOG_DEBUG(5), "pub from self... skipping");
 50       continue;
 51     }
 52     diskmanager_global_state_t *dgs = &(table[i].diskmanager);
 53     _dqueue_get_or_init(dms, table[i].header.flow_id.src, dgs->seqno, dgs->diskfull_percent);
 54     elog(LOG_NOTICE,"Got seqno = %-6i from %d",dgs->seqno,table[i].header.flow_id.src);
 55   }
 56 
 57   return EVENT_RENEW;
 58 }
 59 
 60 float get_free_diskspace_percent(diskmanager_state_t *d)
 61 {
 62   struct statvfs fiData;
 63 //  struct statvfs *fpData;
 64   char fnPath[10]=COMPACT_FLASH_DIRECTORY; 
 65     
 66   if((statvfs(fnPath,&fiData)) < 0 ) {
 67     elog(LOG_WARNING,"Failed to stat %s:\n", fnPath);
 68     return -1;
 69   } 
 70   else 
 71   {
 72     elog(LOG_DEBUG(15),"Disk %s: \n", fnPath);
 73     elog(LOG_DEBUG(15),"\tblock size: %ld\n", fiData.f_bsize);
 74     elog(LOG_DEBUG(15),"\ttotal no blocks: %ld\n", fiData.f_blocks);
 75     elog(LOG_DEBUG(15),"\tfree blocks: %ld\n", fiData.f_bfree);
 76     elog(LOG_DEBUG(10),"Free diskspace = %f%%",100*(float)(fiData.f_bfree)/(float)(fiData.f_blocks)); 
 77     /*sysman_log(SYSMAN_DISKMAN_SPACE,"free-diskspace=%.2f%% free-diskspace-threshold=%.2f%% free-diskspace-delete-threshold=%.2f%%",
 78          100*(float)(fiData.f_bfree)/(float)(fiData.f_blocks),
 79          d->free_diskspace_threshold,d->free_diskspace_delete_threshold); */
 80     return 100*(float)(fiData.f_bfree)/(float)(fiData.f_blocks);
 81   }
 82 }
 83   
 84 float get_diskspace(void)
 85 {
 86   struct statvfs fiData;
 87 //  struct statvfs *fpData;
 88   char fnPath[10]=COMPACT_FLASH_DIRECTORY; 
 89 
 90   if((statvfs(fnPath,&fiData)) < 0 ) {
 91     elog(LOG_WARNING,"Failed to stat %s:\n", fnPath);
 92     return -1;
 93   } 
 94   else 
 95     return (float)(fiData.f_blocks)* ((fiData.f_bsize + 0.0)/(ONE_GIGABYTE + 0.0));
 96 }
 97 
 98 float get_free_diskspace(void)
 99 {
100   struct statvfs fiData;
101 //  struct statvfs *fpData;
102   char fnPath[10]=COMPACT_FLASH_DIRECTORY; 
103     
104   if((statvfs(fnPath,&fiData)) < 0 ) {
105     elog(LOG_WARNING,"Failed to stat %s:\n", fnPath);
106     return -1;
107   } 
108   else 
109   {
110     elog(LOG_DEBUG(15),"Disk %s: \n", fnPath);
111     elog(LOG_DEBUG(15),"\tblock size: %ld\n", fiData.f_bsize);
112     elog(LOG_DEBUG(15),"\ttotal no blocks: %ld\n", fiData.f_blocks);
113     elog(LOG_DEBUG(15),"\tfree blocks: %ld\n", fiData.f_bfree);
114     elog(LOG_DEBUG(10),"Free disk space = %fGB",(float)(fiData.f_bfree) *((fiData.f_bsize + 0.0)/ (ONE_GIGABYTE +0.0)));  
115     return (float)(fiData.f_bfree) * ((fiData.f_bsize + 0.0)/ (ONE_GIGABYTE +0.0)) ;
116   }
117 }
118   
119 int diskmanager_publish_timer(void *data, int interval, g_event_t *ev)
120 {
121   diskmanager_state_t *d = (diskmanager_state_t *) data;
122   float free_diskspace = get_free_diskspace_percent(d);
123 
124   //Publish ID of the self
125   if(free_diskspace >= 0)
126   {
127     // COMMENTED OUT ON 06/10/09 -> MLL -> Chaning operation of diskman to always provide availability to neighborss
128     // if((d->provide_neighborhood == 0 && free_diskspace <= d->free_diskspace_threshold) || d->provide_neighborhood == 1)
129     {
130       //Publish if it is for the first time after booting or it has 5 minutes since the last publication
131       if(misc_tv_usec_l(&d->last_published) == 0 || msec_since(&d->last_published) >= 5*60*1000)
132       { 
133         flow_id_t fid = {
134           src: my_node_id,
135           dst: LINK_BROADCAST,
136           max_hops: 1,  
137         };
138         diskmanager_table_t thetable[1] = {};
139         thetable[0].diskmanager.seqno = d->seqno;
140         thetable[0].diskmanager.diskfull_percent = 100.00 - get_free_diskspace_percent(d);
141         //memmove(&(thetable[0].diskmanager), &(d->seqno), sizeof(diskmanager_global_state_t));
142 
143         if (diskmanager_pub(DISKMANAGER_SSYNC_DEFAULT_PREFIX, thetable, 1, &fid) < 0) {
144           elog(LOG_WARNING, "Unable to publish! %m");
145           exit(1);
146         }
147         gettimeofday(&(d->last_published), NULL);
148         (d->seqno)++;
149         /*
150         sysman_log(SYSMAN_DISKMAN_SPACE,"free-ds=%.2f%/%.2f%% "
151                  "total-ds=%.2f "
152                  "thresh=%.2f%% "
153                  "del-thresh=%.2f%%",
154                  (fiData.f_bfree*fiData.f_bsize + 0.0)/(ONE_MEGABYTE + 0.0),
155                  (fiData.f_blocks*fiData.f_bsize + 0.0),
156                  100*(float)(fiData.f_bfree)/(float)(fiData.f_blocks),
157                  d->free_diskspace_threshold,
158                  d->free_diskspace_delete_threshold);
159         */
160       }
161     }
162   }
163   elog(LOG_DEBUG(10),"Publish: Free disk space = %f%% Threshold = %f%%",free_diskspace,d->free_diskspace_threshold);  
164   //sysman_log(SYSMAN_DISKMAN_ALERT,"Published diskspace to neighbors.");
165   
166   //For testing only
167   /*if(d-> seqno == 10)
168     return TIMER_DONE;
169     else*/
170   return EVENT_RENEW;
171 } 
172 
173 /*int diskmanager_diskspace_timer(void *data, int interval, g_event_t *ev)
174   {
175   diskmanager_state_t *d = (diskmanager_state_t *) data;
176   
177   get_free_diskspace();
178   
179   return EVENT_RENEW;
180 }*/
181 
182 /*
183  // REMOVED ON 06/10/09 -> MLL -> don't need this anymore since everyone always publishes 
184 int diskmanager_diskfree_timer(void *data, int interval, g_event_t *ev)
185 {
186   //Traverse the entire dqueue and trash elements, which are older than 30 minutes
187   diskmanager_state_t *d = (diskmanager_state_t *) data;
188   diskfull_state_t *dfs;
189   int length = dqueue_qlen(d);
190   int i;
191   int updated = 0;
192 
193   for (i = 0; i < length; ++i) {
194     dfs = dqueue_pop(d);
195     if(msec_since(&dfs->last_heard) <= FULL_DISKSPACE_ENTRY_TIMEOUT) //Temporarily changed from 30 to 2 for the testing purposes
196       dqueue_push(d,dfs); 
197     else  
198     {
199       elog(LOG_NOTICE,"Removed diskfull record for %d",dfs->node_id);
200       free(dfs);
201       updated = 1;
202     } 
203   }
204   if (updated) {
205     g_status_dev_notify(d->diskmanager_status); 
206     //elog(LOG_WARNING, "Calling notify in main!");
207   }
208     
209   return EVENT_RENEW;
210 }
211 */
212 
213 int diskmanager_report_diskspace(void *data, int interval, g_event_t *ev)
214 {
215   diskmanager_state_t *d = (diskmanager_state_t *) data;
216   struct statvfs fiData = {};
217   char fnPath[10]=COMPACT_FLASH_DIRECTORY; 
218     
219   if((statvfs(fnPath,&fiData)) < 0 ) {
220     elog(LOG_WARNING,"Failed to stat %s:\n", fnPath);
221     sysman_log(SYSMAN_DISKMAN_SPACE,"STAT-ERR");
222   } else  {
223 
224     //    elog(LOG_DEBUG(15),"\tblock size: %ld\n", fiData.f_bsize);
225     //    elog(LOG_DEBUG(15),"\ttotal no blocks: %ld\n", fiData.f_blocks);
226     //    elog(LOG_DEBUG(15),"\tfree blocks: %ld\n", fiData.f_bfree);
227     //    elog(LOG_DEBUG(10),"Free disk space = %fGB",(float)(fiData.f_bfree*fiData.f_bsize)/ONE_GIGABYTE); 
228 
229     sysman_log(SYSMAN_DISKMAN_SPACE,
230                //              "free-ds=%.2f/%.2f%% "
231                //              "used-ds=%.2f/%.2f%% "
232                //              "total-ds=%.2f "
233                //              "thresh=%.2f%% "
234                //              "del-thresh=%.2f%%",
235                "%.2f %.2f "
236                "%.2f %.2f "
237                "%.2f "
238                "%.2f "
239                "%.2f",
240                fiData.f_bfree * ((fiData.f_bsize + 0.0)/(ONE_MEGABYTE + 0.0)),
241                100*(fiData.f_bfree + 0.0)/(fiData.f_blocks + 0.0),
242                (fiData.f_blocks - fiData.f_bfree) * ((fiData.f_bsize + 0.0)/(ONE_MEGABYTE + 0.0)),
243                100*(fiData.f_blocks - fiData.f_bfree  + 0.0)/(fiData.f_blocks + 0.0),
244                fiData.f_blocks* ((fiData.f_bsize + 0.0)/(ONE_MEGABYTE + 0.0)),
245                d->free_diskspace_threshold,
246                d->free_diskspace_delete_threshold);
247 
248   }
249 
250   return TIMER_RENEW;
251 }
252 
253 
254 int main(int argc, char **argv)
255 {
256   diskmanager_state_t diskmanager_state = {};
257   uint32_t free_diskspace_threshold, free_diskspace_delete_threshold;
258 
259   misc_init(&argc, argv, CVSTAG);
260 
261   emrun_opts_t eopts = {
262     shutdown: diskmanager_shutdown,
263     data: &diskmanager_state,
264   };
265 
266   if(misc_parse_option_as_uint(&argc, argv, "free-diskspace-threshold", 'F', &free_diskspace_threshold) < 0)
267     diskmanager_state.free_diskspace_threshold = FREE_DISKSPACE_THRESHOLD;
268   else
269     diskmanager_state.free_diskspace_threshold = (float)free_diskspace_threshold; 
270 
271   if(misc_parse_option_as_uint(&argc, argv, "free-diskspace-delete-threshold", 'D', &free_diskspace_delete_threshold) < 0)
272     diskmanager_state.free_diskspace_delete_threshold = FREE_DISKSPACE_DELETE_THRESHOLD;
273   else
274     diskmanager_state.free_diskspace_delete_threshold = (float)free_diskspace_delete_threshold;
275 
276   diskmanager_state.provide_neighborhood = misc_parse_out_switch(&argc, argv, "provide-neighborhood", 0);
277 
278   /* register with statesync for the updates */
279         // Changed 2 header files in devel/state
280     // The name "diskmanager" was too long. So changed to "diskman".
281   if (diskmanager_sub_open(DISKMANAGER_SSYNC_DEFAULT_PREFIX, diskmanager_update, &diskmanager_state, &(diskmanager_state.global_state_sub)) < 0) {
282     elog(LOG_WARNING, "Unable to connect to state sync dev: %s", strerror(errno));
283     exit(1);
284   }
285 
286   /* setup the status dev */
287   status_dev_opts_t sdo = {
288     device: {
289       devname: sim_path(DISKMANAGER_STATUS_DEVICE),
290       device_info: &diskmanager_state
291     },
292     binary: diskmanager_diskfull_nodes_binary,
293     printable: diskmanager_status_print 
294   };
295   if (g_status_dev(&sdo, &diskmanager_state.diskmanager_status) < 0) {
296     elog(LOG_CRIT, "Unable to create status device: %s %m", sdo.device.devname);
297     exit(1);
298   }
299 
300   if(diskmanager_state.provide_neighborhood == 1)
301   {
302     /* setup the neighbor dev */
303     status_dev_opts_t sdo = {
304       device: {
305         devname: sim_path(DISKMANAGER_NEIGHBORHOOD_DEVICE),
306         device_info: &diskmanager_state
307       },
308       binary: diskmanager_neighborhood_nodes_binary,
309       //printable: diskmanager_status_print 
310     };
311     if (g_status_dev(&sdo, &diskmanager_state.diskmanager_neighborhood) < 0) {
312       elog(LOG_CRIT, "Unable to create status device: %s %m", sdo.device.devname);
313       exit(1);
314     }
315   }
316 
317   //Timer to read the available free diskspace on the compact flash card and if necessary publish the disk space
318   // CHANGED TO 30 seconds on 06/10/09 by MLL
319   if (g_timer_add(30000, diskmanager_publish_timer, &diskmanager_state, NULL, NULL) < 0) {
320     elog(LOG_WARNING, "Unable to set pub timer!");
321     exit(1);
322   }
323 
324   //Timer to read the available free diskspace on the compact flash card
325   /*if (g_timer_add(10000, diskmanager_diskspace_timer, &diskmanager_state, NULL, NULL) < 0) {
326     elog(LOG_WARNING, "Unable to set diskspace timer!");
327                 exit(1);
328         }*/
329 
330   //Timer to delete the old entires about diskfree space
331  // REMOVED ON 06/10/09 -> MLL -> don't need this anymore since everyone always publishes 
332   /*
333     if (g_timer_add(10000, diskmanager_diskfree_timer, &diskmanager_state, NULL, NULL) < 0) {
334     elog(LOG_WARNING, "Unable to set diskfree timer!");
335     exit(1);
336     }
337   */
338 
339   //Timer to delete old files if the disk is full
340   if (g_timer_add(10000, diskmanager_delete_timer, &diskmanager_state, NULL,&(diskmanager_state.delete_timer)) < 0) {
341     elog(LOG_WARNING, "Unable to set delete timer!");
342     exit(1);
343   }
344 
345   //Timer to report space to syslog every 10 minutes - CHANGED TO 10 min on 06/10/09
346   if (g_timer_add(600000, diskmanager_report_diskspace, &diskmanager_state, NULL,&(diskmanager_state.report_timer)) < 0) {
347     elog(LOG_WARNING, "Unable to set delete timer!");
348     exit(1);
349   }
350 
351   emrun_init(&eopts);
352 
353   g_main();
354   
355   return 1;
356 } 
357 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.