kern_sysctl.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id$
00027 
00028 *****************************************************************************************/
00029 
00030 #include <sys/kern_sysctl.h>
00031 #include <ubixos/types.h>
00032 #include <ubixos/endtask.h>
00033 #include <ubixos/kpanic.h>
00034 #include <ubixos/spinlock.h>
00035 #include <sys/thread.h>
00036 #include <lib/kprintf.h>
00037 #include <lib/kmalloc.h>
00038 #include <assert.h>
00039 #include <string.h>
00040 
00041 static struct sysctl_entry *ctls = 0x0;
00042 static struct sysctl_entry *sysctl_find(int *,int);
00043 
00044 bool sysctl_enabled = FALSE;
00045 
00049 static void def_ctls() {
00050   int name[CTL_MAXNAME], name_len;
00051   uInt32 page_val = 0x1000;
00052   name[0] = 6;
00053   name[1] = 7;
00054   name_len = 2; 
00055   sysctl_add(name,name_len,"page_size",&page_val,sizeof(uInt32));
00056   /* Clock Rate */
00057   name[0] = 1;
00058   name [1] = 12;
00059   page_val = 0x3E8;
00060   sysctl_add(name,name_len,"page_size",&page_val,sizeof(uInt32));
00061   /* User Stack */
00062   name[0] = 1;
00063   name [1] = 33;
00064   page_val = 0xCBE8000;
00065   sysctl_add(name,name_len,"page_size",&page_val,sizeof(uInt32));
00066   }
00067 
00069 
00072 int sysctl_init() {
00073   struct sysctl_entry *tmpCtl = 0x0;
00074   if (ctls != 0x0)
00075     K_PANIC("sysctl already Initialized\n");
00076 
00077   ctls = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00078   ctls->prev     = 0x0;
00079   ctls->id       = CTL_UNSPEC;
00080   ctls->children = 0x0;
00081   sprintf(ctls->name,"unspec");
00082 
00083   tmpCtl = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00084   tmpCtl->prev     = ctls;
00085   tmpCtl->id       = CTL_KERN;
00086   tmpCtl->children = 0x0;
00087   sprintf(tmpCtl->name,"kern");
00088   ctls->next = tmpCtl;
00089 
00090   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00091   tmpCtl->next->prev = tmpCtl;
00092   tmpCtl             = tmpCtl->next;
00093   tmpCtl->id         = CTL_VM;
00094   tmpCtl->children   = 0x0;
00095   sprintf(tmpCtl->name,"vm");
00096 
00097   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00098   tmpCtl->next->prev = tmpCtl;
00099   tmpCtl             = tmpCtl->next;
00100   tmpCtl->id         = CTL_VFS;
00101   tmpCtl->children   = 0x0;
00102   sprintf(tmpCtl->name,"vfs");
00103 
00104   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00105   tmpCtl->next->prev = tmpCtl;
00106   tmpCtl             = tmpCtl->next;
00107   tmpCtl->id         = CTL_NET;
00108   tmpCtl->children   = 0x0;
00109   sprintf(tmpCtl->name,"net");
00110 
00111   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00112   tmpCtl->next->prev = tmpCtl;
00113   tmpCtl             = tmpCtl->next;
00114   tmpCtl->id         = CTL_DEBUG;
00115   tmpCtl->children   = 0x0;
00116   sprintf(tmpCtl->name,"debug");
00117 
00118   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00119   tmpCtl->next->prev = tmpCtl;
00120   tmpCtl             = tmpCtl->next;
00121   tmpCtl->id         = CTL_HW;
00122   tmpCtl->children   = 0x0;
00123   sprintf(tmpCtl->name,"hw");
00124 
00125   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00126   tmpCtl->next->prev = tmpCtl;
00127   tmpCtl             = tmpCtl->next;
00128   tmpCtl->id         = CTL_MACHDEP;
00129   tmpCtl->children   = 0x0;
00130   sprintf(tmpCtl->name,"machdep");
00131 
00132   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00133   tmpCtl->next->prev = tmpCtl;
00134   tmpCtl             = tmpCtl->next;
00135   tmpCtl->id         = CTL_USER;
00136   tmpCtl->children   = 0x0;
00137   sprintf(tmpCtl->name,"user");
00138 
00139   tmpCtl->next = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00140   tmpCtl->next->prev = tmpCtl;
00141   tmpCtl             = tmpCtl->next;
00142   tmpCtl->id         = CTL_P1003_1B;
00143   tmpCtl->children   = 0x0;
00144   sprintf(tmpCtl->name,"p1003_1b");
00145 
00146   tmpCtl->next = (struct sysctl_enctry *)kmalloc(sizeof(struct sysctl_entry));
00147   tmpCtl->next->prev = tmpCtl;
00148   tmpCtl             = tmpCtl->next;
00149   tmpCtl->id         = CTL_UBIX;
00150   tmpCtl->children   = 0x0;
00151   sprintf(tmpCtl->name,"ubix");
00152 
00154   def_ctls();
00155 
00156   sysctl_enabled = TRUE;
00157 
00158   return(0x0);
00159   }
00160 
00161 int __sysctl(struct thread *td, struct sysctl_args *uap) {
00162   int err = 0x0;
00163   int name[CTL_MAXNAME];
00164   size_t j = 0x0;
00165 
00169   if ((uap->namelen < 0x2) || (uap->namelen > CTL_MAXNAME)) {
00170     return(EINVAL);
00171     }
00172 
00176   err = memcpy(name,uap->name,uap->namelen * sizeof(int));
00177   if (err)
00178     return(err);
00179   spinLock(&Master);
00180 
00181   kern_sysctl(td,name,uap->namelen, uap->old,uap->oldlenp,0x0,uap->new, uap->newlen, &j, 0x0);
00182   spinUnlock(&Master);
00183 
00184   return(0x0);
00185   }
00186 
00187 int kern_sysctl(struct thread *td,int *name,u_int namelen,void *old,size_t *oldlenp,int inkernel,void *new,size_t newlen,size_t *retval,int flags) {
00188   struct sysctl_entry *tmpCtl = 0x0;
00189   int i = 0;
00190 
00191   if (newlen < 0) {
00192     kprintf("Changing Not supported yet.\n");
00193     endTask(_current->id);
00194     }
00195 
00196   tmpCtl = sysctl_find(name,namelen);
00197   if (tmpCtl == 0x0) { 
00198     kprintf("Invalid CTL\n");
00199     for (i = 0x0;i < namelen;i++)
00200       kprintf("(%i)",name[i]);
00201     kprintf("\n");
00202     endTask(_current->id);
00203     }
00204 
00205   if (oldlenp < tmpCtl->val_len) 
00206      memcpy(old,tmpCtl->value,oldlenp);
00207   else
00208      memcpy(old,tmpCtl->value,tmpCtl->val_len);
00209 
00210   td->td_retval[0] = 0x0;
00211 
00212   return(0x0);
00213   }
00214 
00215 static struct sysctl_entry *sysctl_find(int *name,int namelen) {
00216   int i = 0x0;
00217   struct sysctl_entry *tmpCtl = 0x0;
00218   struct sysctl_entry *lCtl = ctls;
00219 
00220   /* Loop Name Len */
00221   for (i = 0; i < namelen;i++) {
00222     for (tmpCtl = lCtl;tmpCtl != 0x0;tmpCtl = tmpCtl->next) {
00223       //kprintf("ctlName: [%s], ctlId; [%i]\n",tmpCtl->name,tmpCtl->id);
00224       if (tmpCtl->id == name[i]) {
00225          if ((i+1) == namelen) {
00226            return(tmpCtl);
00227            }
00228          lCtl = tmpCtl->children;
00229          break;
00230          }
00231       }
00232     }
00233   return(0x0);
00234   }
00235 
00236 int sysctl_add(int *name,int namelen,char *str_name,void *buf,int buf_size) {
00237   struct sysctl_entry *tmpCtl = 0x0;
00238   struct sysctl_entry *newCtl = 0x0;
00239 
00240   /* Check if it exists */
00241   tmpCtl = sysctl_find(name,namelen);
00242   if (tmpCtl != 0x0) {
00243     kprintf("Node Exists!\n");
00244     while (1);
00245     }
00246 
00247   /* Get Parent Node */
00248   tmpCtl = sysctl_find(name,namelen-1);
00249   if (tmpCtl == 0x0) {
00250     kprintf("Parent Node Non Existant\n");
00251     return(-1);
00252     }
00253   if (tmpCtl->children == 0x0) {
00254     tmpCtl->children = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry));
00255     tmpCtl->children->children = 0x0;
00256     tmpCtl->children->prev     = 0x0;
00257     tmpCtl->children->next     = 0x0;
00258     tmpCtl->children->id       = name[namelen-1];
00259     sprintf(tmpCtl->children->name,str_name);
00260     tmpCtl->children->value = (void  *)kmalloc(buf_size);
00261     memcpy(tmpCtl->children->value,buf,buf_size);
00262     tmpCtl->children->val_len = buf_size;
00263     }
00264   else {
00265     newCtl = (struct sysctl_entry *)kmalloc(sizeof(struct sysctl_entry)); 
00266     newCtl->prev     = 0x0;
00267     newCtl->next     = tmpCtl->children;
00268     newCtl->children = 0x0;
00269     newCtl->id       = name[namelen-1];
00270     sprintf(newCtl->name,str_name);
00271     newCtl->value    = (void *)kmalloc(buf_size);
00272     memcpy(newCtl->value,buf,buf_size);
00273     newCtl->val_len  = buf_size;
00274     tmpCtl->children->prev = newCtl;
00275     tmpCtl->children = newCtl;
00276     }
00277 
00278   return(0x0);
00279   }
00280 
00281 
00282 /***
00283  END
00284  ***/

Generated on Sun Dec 3 02:38:04 2006 for UbixOS V2 by  doxygen 1.4.7