N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/OrbisQuartus/server/xen/backend/sim_if.c

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright 2007. Los Alamos National Security, LLC. This material
00016  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00017  * Los Alamos National Laboratory (LANL), which is operated by Los
00018  * Alamos National Security, LLC, for the Department of Energy. The
00019  * U.S. Government has rights to use, reproduce, and distribute this
00020  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00021  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00022  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00023  * produce derivative works, such modified software should be clearly
00024  * marked, so as not to confuse it with the version available from LANL.
00025  *
00026  * Additionally, this program is free software; you can redistribute
00027  * it and/or modify it under the terms of the GNU General Public
00028  * License as published by the Free Software Foundation; version 2 of
00029  * the License. Accordingly, this program is distributed in the hope
00030  * it will be useful, but WITHOUT ANY WARRANTY; without even the
00031  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00032  * PURPOSE. See the GNU General Public License for more details.
00033  */
00034 
00035 
00036 #include <linux/kernel.h>
00037 #include <linux/module.h>
00038 #include <linux/ioctl.h>
00039 #include <linux/proc_fs.h>
00040 #include <linux/fs.h>
00041 
00042 #include "oq_kmod.h"
00043 #include "avl.h"
00044 #include <sim_if.h>
00045 
00046 
00048 
00049 
00050 struct oq_req_resp_list *req_resp_lists;
00051 EXPORT_SYMBOL(req_resp_lists);
00052 
00053 
00054 extern char oq_simulation_daemon[PATH_MAX];
00055 extern struct proc_dir_entry *oq_dir;
00056 extern struct oq_dev *oq_device;
00057 
00058 
00059 struct proc_dir_entry *oq_hosts;
00060 struct proc_dir_entry *oq_sensors;
00061 
00062 struct knode {
00063         unsigned int id;
00064 };
00065 
00066 struct ksensor {
00067         unsigned int node_id;
00068         unsigned int sensor_number;
00069         struct proc_dir_entry *proc_entry;
00070         struct sensor_stats sensor;
00071 };
00072 
00073 struct avltree ksensors;
00074 struct avltree knodes;
00075 
00076 
00077 unsigned int simulation_on;
00078 unsigned long ksim_id;
00079 unsigned long ktime_dilation_ratio;
00080 
00081 struct khost {
00082         struct list_head list;
00083         char name[MAX_NAME];
00084 } khosts;
00085 
00086 
00087 
00088 static int sim_test;
00089 static struct oq_req_resp_list rr_lists;
00090 
00091 
00092 
00093 /******************************
00094          base spec
00095  ******************************/
00096 
00097 #define META_NUM_TYPES 4
00098 
00099 enum file_t {
00100         SIM_ID = 0, TIME = 1, ADD_HOST = 2, RM_HOST = 3,
00101 };
00102 
00103 struct data_t {
00104         enum file_t file;
00105 }  metadata[META_NUM_TYPES];
00106 
00107 
00108 
00109 
00110 static int read_base(char *page, char **start, off_t off,
00111                      int count, int *eof, void *data)
00112 {
00113         int result = 0;
00114         enum file_t type = *((enum file_t *) data);
00115 
00116         if (off > 0) {
00117                 *eof = 1;
00118                 return 0;
00119         }
00120 
00121         switch (type) {
00122         case SIM_ID:
00123                 result = sprintf(page, "%ld\n", ksim_id);
00124                 break;
00125 
00126         case TIME:
00127                 result = sprintf(page, "%ld\n", ktime_dilation_ratio);
00128                 break;
00129 
00130         default:
00131                 break;
00132         }
00133         return result;
00134 }
00135 
00136 
00137 static ssize_t write_base(struct file *filp, const char __user *buf,
00138                           unsigned long len, void *data)
00139 {
00140         struct khost *tmp;
00141         struct list_head *pos, *q;
00142         char user_str[len + 1];
00143         enum file_t type = *((enum file_t *) data);
00144 
00145         memset(user_str, '\0', len + 1);
00146 
00147         if (copy_from_user(&user_str, buf, len))
00148                 return -EFAULT;
00149 
00150         switch (type) {
00151         case SIM_ID:
00152                 ksim_id = simple_strtoul(user_str, NULL, 10);
00153                 break;
00154 
00155         case TIME:
00156                 ktime_dilation_ratio =
00157                         simple_strtoul(user_str, NULL, 10);
00158                 break;
00159 
00160         case ADD_HOST:
00161                 tmp = (struct khost *) 
00162                         kmalloc(sizeof(struct khost), GFP_KERNEL);
00163                 strncpy(tmp->name, user_str, len);
00164                 list_add(&(tmp->list), &(khosts.list));
00165                 create_proc_entry(tmp->name, 0666, oq_hosts);
00166                 break;
00167 
00168         case RM_HOST:
00169                 list_for_each_safe(pos, q, &khosts.list) {
00170                         tmp = list_entry(pos, struct khost, list);
00171                         if (strncmp(tmp->name, user_str, len) == 0) {
00172                                 remove_proc_entry(tmp->name, oq_hosts);
00173                                 list_del(pos);
00174                                 kfree(tmp);
00175                         }
00176                 }
00177                 break;
00178 
00179         default:
00180                 break;
00181         }
00182         return len;
00183 }
00184 
00185 
00186 
00187 
00188 static void initialize(struct ksensor *ksensor, unsigned int node_id,
00189                        unsigned int sensor_num, unsigned int id)
00190 {
00191         if (ksensor == NULL)
00192                 return;
00193 
00194         ksensor->node_id = node_id;
00195         ksensor->sensor_number = sensor_num;
00196         ksensor->proc_entry = NULL;
00197         ksensor->sensor.id = id;
00198         ksensor->sensor.rx_bytes = ksensor->sensor.rx_errors = 0;
00199         ksensor->sensor.rx_dropped = ksensor->sensor.rx_overruns = 0;
00200         ksensor->sensor.tx_bytes = ksensor->sensor.tx_errors = 0;
00201         ksensor->sensor.tx_dropped = ksensor->sensor.tx_overruns = 0;
00202 }
00203 
00204 
00205 
00206 static int read_nodes(char *page, char **start, off_t off,
00207                       int count, int *eof, void *data)
00208 {
00209         struct avlnode *item;
00210         unsigned int len = MAX_NODES * (INTEGER_STRING + 2);
00211         char nodes[len];
00212 
00213         if (off > 0) {
00214                 *eof = 1;
00215                 return 0;
00216         }
00217 
00218 
00219         while ((item = avl_find_min(&knodes)) != NULL) {
00220                 char name[INTEGER_STRING];
00221                 snprintf(name, INTEGER_STRING, "%d, ", 
00222                          ((struct knode *)item->element)->id);
00223                 strncat(nodes, name, len - (strlen(nodes) + strlen(name)));
00224         }
00225         nodes[strlen(nodes)-2] = '\0';
00226 
00227         return sprintf(page, "%s\n", nodes);
00228 }
00229 
00230 
00231 
00232 static int read_sensor(char *page, char **start, off_t off,
00233                        int count, int *eof, void *data)
00234 {
00235         unsigned int number = *(unsigned int *) data;
00236         struct ksensor *ksensor = 
00237                 (struct ksensor *) avl_retrieve(number, &ksensors);
00238         struct sensor_stats *sensor;
00239 
00240         if (ksensor == NULL)
00241                 return 0;
00242 
00243         if (off > 0) {
00244                 *eof = 1;
00245                 return 0;
00246         }
00247 
00248         sensor = &(ksensor->sensor);
00249         return sprintf(page, 
00250                        "RX bytes:%ld  errors:%ld dropped:%ld overruns:%ld\n"
00251                        "TX bytes:%ld  errors:%ld dropped:%ld overruns:%ld\n",
00252                        sensor->rx_bytes, sensor->rx_errors, 
00253                        sensor->rx_dropped, sensor->rx_overruns, 
00254                        sensor->tx_bytes, sensor->tx_errors, 
00255                        sensor->tx_dropped, sensor->tx_overruns);
00256 }
00257 
00258 
00259 int add_node(unsigned int id)
00260 {
00261         struct knode *knode;
00262         if ((knode = OQ_ALLOCATE(sizeof(struct knode))) == NULL) {
00263                 printk(KERN_WARNING 
00264                        "orbisquartus: knode id %d failed\n", id);
00265                 return -ENOMEM;
00266         }
00267 
00268         knode->id = id;
00269 
00270         if (avl_insert(knode, id, &knodes) != 0) {
00271                 printk(KERN_WARNING 
00272                        "orbisquartus: knode id %d insertion failed\n", id);
00273                 OQ_FREE(knode);
00274                 return -EFAULT;
00275         }
00276 
00277         return 0;
00278 }
00279 
00280 
00281 void remove_node(unsigned int number)
00282 {
00283         void *knode = NULL;
00284 
00285         avl_delete(knode, number, &knodes);
00286         OQ_FREE(knode);
00287 }
00288 
00289 
00290 int add_sensor_entry(unsigned int node, unsigned int number, unsigned int id)
00291 {
00292         int len = 0;
00293         char entry_name[MAX_NAME];
00294         struct ksensor *ksensor = 
00295                 (struct ksensor *) avl_retrieve(id, &ksensors);
00296 
00297         if (ksensor != NULL) {
00298                 printk(KERN_WARNING 
00299                        "orbisquartus: sensor id %d is in use\n", id);
00300                 return -EFAULT;
00301         }
00302         if ((ksensor = OQ_ALLOCATE(sizeof(struct ksensor))) == NULL) {
00303                 printk(KERN_WARNING 
00304                        "orbisquartus: ksensor id %d failed\n", id);
00305                 return -ENOMEM;
00306         }
00307 
00308         if (avl_insert(ksensor, id, &ksensors) != 0) {
00309                 printk(KERN_WARNING 
00310                        "orbisquartus: ksensor id %d insertion failed\n", id);
00311                 len = -EFAULT;
00312                 goto cleanup_avl_entry;
00313         }
00314 
00315         initialize(ksensor, node, number, id);
00316         snprintf(entry_name, MAX_NAME, "%d::%d", node, number);
00317 
00318         if ((ksensor->proc_entry =
00319              proc_mkdir(entry_name, oq_sensors)) == NULL) {
00320                 printk(KERN_WARNING 
00321                        "orbisquartus: Couldn't create sensor proc entry\n");
00322                 len = -ENOMEM;
00323                 goto cleanup_proc_entry;
00324         }
00325         ksensor->proc_entry->read_proc = read_sensor;
00326         ksensor->proc_entry->owner = THIS_MODULE;
00327         ksensor->proc_entry->data = &(ksensor->sensor.id);
00328 
00329         goto end;
00330 
00331 
00332 cleanup_proc_entry:
00333         remove_proc_entry(entry_name, oq_sensors);
00334         ksensor->proc_entry = NULL;
00335 cleanup_avl_entry:
00336         avl_delete(NULL, id, &ksensors);
00337         OQ_FREE(ksensor);
00338 end:
00339         return len;
00340 }
00341 
00342 
00343 void remove_sensor_entry(unsigned int number)
00344 {
00345         char entry_name[MAX_NAME];
00346         struct ksensor *ksensor = 
00347                 (struct ksensor *) avl_retrieve(number, &ksensors);
00348 
00349         if (ksensor == NULL)
00350                 return;
00351 
00352         snprintf(entry_name, MAX_NAME, "%d::%d", 
00353                  ksensor->node_id, ksensor->sensor_number);
00354         remove_proc_entry(entry_name, oq_sensors);
00355         ksensor->proc_entry = NULL;
00356         avl_delete(NULL, ksensor->sensor.id, &ksensors);
00357         OQ_FREE(ksensor);
00358 }
00359 
00360 
00361 int post_sensor_stats(struct sensor_stats stats)
00362 {
00363         struct ksensor *ksensor = 
00364                 (struct ksensor *) avl_retrieve(stats.id, &ksensors);
00365         if (ksensor == NULL)
00366                 return 0;
00367 
00368         ksensor->sensor.rx_bytes = stats.rx_bytes;
00369         ksensor->sensor.rx_errors = stats.rx_errors;
00370         ksensor->sensor.rx_dropped = stats.rx_dropped;
00371         ksensor->sensor.rx_overruns = stats.rx_overruns;
00372         ksensor->sensor.tx_bytes = stats.tx_bytes;
00373         ksensor->sensor.tx_errors = stats.tx_errors;
00374         ksensor->sensor.tx_dropped = stats.tx_dropped;
00375         ksensor->sensor.tx_overruns = stats.tx_overruns;
00376         return 1;
00377 }
00378 
00379         
00380 
00381 
00382 /******************************
00383     char device functionality
00384  ******************************/
00385 
00386 
00387 
00388 static int oq_clear_log(struct oq_dev *dev)
00389 {
00390         struct oq_log_item *next, *dptr;
00391         int i, qset = OQ_LOG_SIZE;
00392 
00393         for (dptr = dev->data; dptr; dptr = next) {
00394                 if (dptr->data) {
00395                         for (i = 0; i < qset; i++)
00396                                 kfree(dptr->data[i]);
00397                         kfree(dptr->data);
00398                         dptr->data = NULL;
00399                 }
00400                 next = dptr->next;
00401                 kfree(dptr);
00402         }
00403         dev->size = 0;
00404         dev->data = NULL;
00405         return 0;
00406 }
00407 
00408 
00409 static struct oq_log_item *oq_traverse_log(struct oq_dev *dev, int where)
00410 {
00411         struct oq_log_item *items = dev->data;
00412 
00413         if (!items) {
00414                 dev->data = kmalloc(sizeof(struct oq_log_item), GFP_KERNEL);
00415                 if ((items = dev->data) == NULL)
00416                         return NULL;
00417                 memset(items, 0, sizeof(struct oq_log_item));
00418         }
00419         while (where--) {
00420                 if (!items->next) {
00421                         if ((items->next = kmalloc(sizeof(struct oq_log_item), 
00422                                                    GFP_KERNEL)) == NULL)
00423                                 return NULL;
00424                         memset(items->next, 0, sizeof(struct oq_log_item));
00425                 }
00426                 items = items->next;
00427         }
00428         return items;
00429 }
00430                         
00431 
00432 
00433 loff_t oq_llseek(struct file *filp, loff_t pos, int where)
00434 {
00435         struct oq_dev *dev = filp->private_data;
00436         loff_t new_pos;
00437 
00438         switch(where) {
00439         case 0: /* set */
00440                 new_pos = pos;
00441                 break;
00442 
00443         case 1: /* current */
00444                 new_pos = filp->f_pos + pos;
00445                 break;
00446                 
00447         case 2: /* end */
00448                 new_pos = dev->size + pos;
00449                 break;
00450 
00451         default:
00452                 return -EINVAL;
00453         }
00454 
00455         if (new_pos < 0) 
00456                 return -EINVAL;
00457 
00458         filp->f_pos = new_pos;
00459         return new_pos;
00460 }
00461 
00462 
00463 ssize_t oq_read(struct file *filp, char __user *buf, size_t count, 
00464                 loff_t *f_pos)
00465 {
00466         struct oq_dev *dev = filp->private_data;
00467         struct oq_log_item *dptr;
00468         int quantum = OQ_LOG_ITEM_SIZE;
00469         int qset = OQ_LOG_SIZE;
00470         int itemsize = quantum * qset;
00471         int item, s_pos, q_pos, rest;
00472         ssize_t retval = 0;
00473 
00474         if (down_interruptible(&dev->sem))
00475                 return -ERESTARTSYS;
00476         if (*f_pos >= dev->size)
00477                 goto end;
00478         if (*f_pos + count > dev->size)
00479                 count = dev->size - *f_pos;
00480 
00481         item = (long)*f_pos / itemsize;
00482         rest = (long)*f_pos % itemsize;
00483         s_pos = rest / quantum; q_pos = rest % quantum;
00484 
00485         dptr = oq_traverse_log(dev, item);
00486 
00487         if (dptr == NULL || !dptr->data || ! dptr->data[s_pos])
00488                 goto end;
00489 
00490         if (count > quantum - q_pos)
00491                 count = quantum - q_pos;
00492 
00493         if (copy_to_user(buf, dptr->data[s_pos] + q_pos, count)) {
00494                 retval = -EFAULT;
00495                 goto end;
00496         }
00497         *f_pos += count;
00498         retval = count;
00499 
00500   end:
00501         up(&dev->sem);
00502         return retval;
00503 }
00504 
00505 
00506 static ssize_t __oq_wrt(struct oq_dev *dev, const char __user *buf, 
00507                         size_t count, loff_t *f_pos)
00508 {
00509         struct oq_log_item *dptr;
00510         int quantum = OQ_LOG_ITEM_SIZE;
00511         int qset = OQ_LOG_SIZE;
00512         int itemsize = quantum * qset;
00513         int item, s_pos, q_pos, rest;
00514         ssize_t retval = -ENOMEM;
00515 
00516         if (down_interruptible(&dev->sem))
00517                 return -ERESTARTSYS;
00518 
00519         item = (long)*f_pos / itemsize;
00520         rest = (long)*f_pos % itemsize;
00521         s_pos = rest / quantum; 
00522         q_pos = rest % quantum;
00523 
00524         dptr = oq_traverse_log(dev, item);
00525         if (dptr == NULL)
00526                 goto end;
00527         if (!dptr->data) {
00528                 dptr->data = kmalloc(qset * sizeof(char *), GFP_KERNEL);
00529                 if (!dptr->data)
00530                         goto end;
00531                 memset(dptr->data, 0, qset * sizeof(char *));
00532         }
00533         if (!dptr->data[s_pos]) {
00534                 dptr->data[s_pos] = kmalloc(quantum, GFP_KERNEL);
00535                 if (!dptr->data[s_pos])
00536                         goto end;
00537         }
00538 
00539         if (count > quantum - q_pos)
00540                 count = quantum - q_pos;
00541 
00542         if (copy_from_user(dptr->data[s_pos]+q_pos, buf, count)) {
00543                 retval = -EFAULT;
00544                 goto end;
00545         }
00546         *f_pos += count;
00547         retval = count;
00548 
00549         if (dev->size < *f_pos)
00550                 dev->size = *f_pos;
00551 
00552   end:
00553         up(&dev->sem);
00554         return retval;
00555 }
00556 
00557 
00558 ssize_t oq_write(struct file *filp, const char __user *buf, size_t count,
00559                 loff_t *f_pos)
00560 {
00561         struct oq_dev *dev = filp->private_data;
00562         return __oq_wrt(dev, buf, count, f_pos);
00563 }
00564 
00565 
00566 /* interfaces with user-space solver */
00567 int oq_ioctl(struct inode *inode, struct file *filp,
00568              unsigned int cmd, unsigned long arg)
00569 {
00570         DECLARE_WAITQUEUE(waitqueue, current);
00571         struct oq_req_resp *req;
00572         struct oq_req_resp *resp;
00573         int result = 0;
00574 
00575 
00577         switch (cmd) {
00578         case OQ_RESP_INIT:
00579                 simulation_on++;
00580                 if (down_interruptible(&req_resp_lists->simd_sem))
00581                         return -ERESTARTSYS;
00582                 goto await_result;
00583                 break;
00584 
00585         case OQ_RESP_REINIT:
00586                 if (down_interruptible(&req_resp_lists->simd_sem))
00587                         return -ERESTARTSYS;
00588                 goto await_result;
00589                 break;
00590 
00591         case OQ_RESP_RESULT:
00592                 if (down_interruptible(&req_resp_lists->simd_sem))
00593                         return -ERESTARTSYS;
00594 
00595                 if ((resp = new_response(arg)) == NULL)
00596                         return OQ_REQ_REPEAT;
00597                 list_add_tail(&resp->list, &req_resp_lists->response_list);
00598                 wake_up_interruptible(&req_resp_lists->response_wait);
00599 
00600         await_result:
00601                 add_wait_queue(&req_resp_lists->request_wait, &waitqueue);
00602                 set_current_state(TASK_INTERRUPTIBLE);
00603                 while (list_empty(&req_resp_lists->request_list)) {
00604                         up(&req_resp_lists->simd_sem);
00605 
00606                         schedule();  /* enter:sleep -> exit:wake */
00607 
00608                         if (signal_pending(current))
00609                                 return OQ_REQ_REPEAT;
00610                         if (down_interruptible(&req_resp_lists->simd_sem))
00611                                 return OQ_REQ_REPEAT;
00612                 }
00613                 __set_current_state(TASK_RUNNING);
00614                 remove_wait_queue(&req_resp_lists->request_wait, &waitqueue);
00615 
00616                 req = list_entry(&req_resp_lists->request_list, 
00617                                  struct oq_req_resp, list);
00618                 list_del(&req->list);
00619                 result = copy_to_user((struct oq_req_resp __user *)arg, req, 
00620                                       sizeof(struct oq_req_resp));
00621                 kfree(req);
00622                 up(&req_resp_lists->simd_sem);
00623                 break;
00624 
00625         default:
00626                 return -ENOIOCTLCMD;
00627         }
00628 
00629         return result;
00630 }
00631 
00632 
00633 int oq_open(struct inode *inode, struct file *filp)
00634 {
00635         struct oq_dev *dev;
00636         dev = container_of(inode->i_cdev, struct oq_dev, cdev);
00637         filp->private_data = dev;
00638 
00639         if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
00640                 if (down_interruptible(&dev->sem))
00641                         return -ERESTARTSYS;
00642                 oq_clear_log(dev);
00643                 up(&dev->sem);
00644         }
00645         return 0;
00646 }
00647 
00648 
00649 int oq_release(struct inode *inode, struct file *filp)
00650 {
00651         return 0;
00652 }
00653 
00654 
00655 
00656 int OQLOG(const char *fmt, ...)
00657 {
00658         va_list ap;
00659         char buf[OQ_LOG_ITEM_SIZE];
00660         int len;
00661 
00662         va_start(ap, fmt);
00663         if ((len = vsnprintf(buf, OQ_LOG_ITEM_SIZE, fmt, ap)) < 0)
00664                 return len;
00665         if (oq_device == NULL)
00666                 return -ENODEV;
00667         len = __oq_wrt(oq_device, buf, strlen(buf) + 1, 
00668                        (loff_t *) &oq_device->size);
00669         va_end(ap);
00670         return len;
00671 }
00672 
00673 
00674 
00675 
00676 /******************************/
00677 
00678 
00679 
00680 
00681 int init_simulator_iface(int test)
00682 {
00683         int result = -1;
00684         struct proc_dir_entry *id_entry, *dilation_entry, 
00685                 *add_entry, *rm_entry, *nodes_entry;
00686 
00687         req_resp_lists = &rr_lists;
00688         simulation_on = 0;
00689         sim_test = test;
00690 
00691         init_waitqueue_head(&req_resp_lists->request_wait);
00692         init_waitqueue_head(&req_resp_lists->response_wait);
00693         init_MUTEX_LOCKED(&req_resp_lists->simd_sem);
00694         INIT_LIST_HEAD(&req_resp_lists->request_list);
00695         INIT_LIST_HEAD(&req_resp_lists->response_list);
00696 
00697         INIT_LIST_HEAD(&khosts.list);
00698 
00699         if ((id_entry = 
00700              create_proc_entry("simulation_id", 0666, oq_dir)) == NULL) {
00701                 printk(KERN_WARNING
00702                        "orbisquartus: Couldn't create sim id entry\n");
00703                 result = -ENOMEM;
00704                 goto cleanup_id;
00705         }
00706         id_entry->read_proc = read_base;
00707         id_entry->write_proc = write_base;
00708         id_entry->owner = THIS_MODULE;
00709         id_entry->data = &metadata[SIM_ID];
00710 
00711 
00712         if ((dilation_entry = 
00713              create_proc_entry("time_dilation", 0666, oq_dir)) == NULL) {
00714                 printk(KERN_WARNING
00715                        "orbisquartus: Couldn't enable time dilation entry\n");
00716                 result = -ENOMEM;
00717                 goto cleanup_time;
00718         }
00719         dilation_entry->read_proc = read_base;
00720         dilation_entry->write_proc = write_base;
00721         dilation_entry->owner = THIS_MODULE;
00722         dilation_entry->data = &metadata[TIME];
00723 
00724 
00725         if ((oq_hosts = proc_mkdir("hosts", oq_dir)) == NULL) {
00726                 printk(KERN_ERR
00727                        "orbisquartus: Couldn't create hosts proc entry\n");
00728                 result = -ENOMEM;
00729                 goto cleanup_hosts;
00730         }
00731         oq_hosts->owner = THIS_MODULE;
00732 
00733 
00734         if ((add_entry = 
00735              create_proc_entry("add", 0666, oq_hosts)) == NULL) {
00736                 printk(KERN_WARNING
00737                        "orbisquartus: Couldn't enable hosts entry\n");
00738                 result = -ENOMEM;
00739                 goto cleanup_add;
00740         }
00741         add_entry->read_proc = read_base;
00742         add_entry->write_proc = write_base;
00743         add_entry->owner = THIS_MODULE;
00744         add_entry->data = &metadata[ADD_HOST];
00745 
00746 
00747         if ((rm_entry = 
00748              create_proc_entry("remove", 0666, oq_hosts)) == NULL) {
00749                 printk(KERN_WARNING
00750                        "orbisquartus: Couldn't enable hosts entry\n");
00751                 result = -ENOMEM;
00752                 goto cleanup_rm;
00753         }
00754         rm_entry->read_proc = read_base;
00755         rm_entry->write_proc = write_base;
00756         rm_entry->owner = THIS_MODULE;
00757         rm_entry->data = &metadata[RM_HOST];
00758 
00759 
00760         if ((oq_sensors = proc_mkdir("sensors", oq_dir)) == NULL) {
00761                 printk(KERN_WARNING
00762                        "orbisquartus: Couldn't create sensors proc entry\n");
00763                 result = -ENOMEM;
00764                 goto cleanup_sensors;
00765         }
00766         oq_sensors->owner = THIS_MODULE;
00767 
00768         if ((nodes_entry = 
00769              create_proc_entry("nodes", 0666, oq_dir)) == NULL) {
00770                 printk(KERN_WARNING
00771                        "orbisquartus: Couldn't create nodes entry\n");
00772                 result = -ENOMEM;
00773                 goto cleanup_nodes;
00774         }
00775         nodes_entry->read_proc = read_nodes;
00776         nodes_entry->owner = THIS_MODULE;
00777 
00778 /*
00779         argv[0] = oq_simulation_daemon;
00780         argv[1] = 0;
00781 
00782         envp[0] = "HOME=/";
00783         envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
00784         envp[2] = 0;
00785 
00786         result = call_usermodehelper(argv[0], argv, envp, 0);
00787 */
00788         goto end;
00789 
00790 
00791 cleanup_nodes:
00792         remove_proc_entry("nodes", oq_dir);
00793 cleanup_sensors:
00794         remove_proc_entry("sensors", oq_dir);
00795 cleanup_time:
00796         remove_proc_entry("time_dilation", oq_dir);
00797 cleanup_rm:
00798         remove_proc_entry("remove", oq_hosts);
00799 cleanup_add:
00800         remove_proc_entry("add", oq_hosts);
00801 cleanup_hosts:
00802         remove_proc_entry("hosts", oq_dir);
00803 cleanup_id:
00804         remove_proc_entry("simulation_id", oq_dir);
00805  end:
00806         return result;
00807 }
00808 
00809 
00810 
00811 void shutdown_simulator_iface(void)
00812 {
00813         struct khost *tmp;
00814         struct list_head *pos, *q;
00815         struct avlnode *item;
00816 
00817         simulation_on = 0;
00818 
00819         
00820         while ((item = avl_find_min(&ksensors)) != NULL) {
00821                 unsigned int num = ((struct knode *)item->element)->id;
00822                 remove_node(num);
00823         }
00824         remove_proc_entry("nodes", oq_dir);
00825         while ((item = avl_find_min(&ksensors)) != NULL) {
00826                 unsigned int num = 
00827                         ((struct ksensor *)item->element)->sensor.id;
00828                 remove_sensor_entry(num);
00829         }
00830         remove_proc_entry("sensors", oq_dir);
00831         remove_proc_entry("time_dilation", oq_dir);
00832 
00833         list_for_each_safe(pos, q, &khosts.list) {
00834                 tmp = list_entry(pos, struct khost, list);
00835                 remove_proc_entry(tmp->name, oq_hosts);
00836                 list_del(pos);
00837                 kfree(tmp);
00838         }       
00839 
00840         remove_proc_entry("remove", oq_hosts);
00841         remove_proc_entry("add", oq_hosts);
00842         remove_proc_entry("hosts", oq_dir);
00843         remove_proc_entry("simulation_id", oq_dir);
00844 }


© 2007, Los Alamos National Security, LLC.