The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/linux/linux_mib.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 Marcel Moolenaar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer 
   10  *    in this position and unchanged.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD: releng/9.0/sys/compat/linux/linux_mib.c 219668 2011-03-15 13:40:47Z netchild $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/kernel.h>
   34 #include <sys/systm.h>
   35 #include <sys/sysctl.h>
   36 #include <sys/proc.h>
   37 #include <sys/malloc.h>
   38 #include <sys/mount.h>
   39 #include <sys/jail.h>
   40 #include <sys/lock.h>
   41 #include <sys/mutex.h>
   42 #include <sys/sx.h>
   43 
   44 #include "opt_compat.h"
   45 
   46 #ifdef COMPAT_LINUX32
   47 #include <machine/../linux32/linux.h>
   48 #else
   49 #include <machine/../linux/linux.h>
   50 #endif
   51 #include <compat/linux/linux_mib.h>
   52 
   53 struct linux_prison {
   54         char    pr_osname[LINUX_MAX_UTSNAME];
   55         char    pr_osrelease[LINUX_MAX_UTSNAME];
   56         int     pr_oss_version;
   57         int     pr_osrel;
   58 };
   59 
   60 static struct linux_prison lprison0 = {
   61         .pr_osname =            "Linux",
   62         .pr_osrelease =         "2.6.16",
   63         .pr_oss_version =       0x030600,
   64         .pr_osrel =             2006016
   65 };
   66 
   67 static unsigned linux_osd_jail_slot;
   68 
   69 SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
   70             "Linux mode");
   71 
   72 static int      linux_set_osname(struct thread *td, char *osname);
   73 static int      linux_set_osrelease(struct thread *td, char *osrelease);
   74 static int      linux_set_oss_version(struct thread *td, int oss_version);
   75 
   76 static int
   77 linux_sysctl_osname(SYSCTL_HANDLER_ARGS)
   78 {
   79         char osname[LINUX_MAX_UTSNAME];
   80         int error;
   81 
   82         linux_get_osname(req->td, osname);
   83         error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req);
   84         if (error || req->newptr == NULL)
   85                 return (error);
   86         error = linux_set_osname(req->td, osname);
   87         return (error);
   88 }
   89 
   90 SYSCTL_PROC(_compat_linux, OID_AUTO, osname,
   91             CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
   92             0, 0, linux_sysctl_osname, "A",
   93             "Linux kernel OS name");
   94 
   95 static int
   96 linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS)
   97 {
   98         char osrelease[LINUX_MAX_UTSNAME];
   99         int error;
  100 
  101         linux_get_osrelease(req->td, osrelease);
  102         error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
  103         if (error || req->newptr == NULL)
  104                 return (error);
  105         error = linux_set_osrelease(req->td, osrelease);
  106         return (error);
  107 }
  108 
  109 SYSCTL_PROC(_compat_linux, OID_AUTO, osrelease,
  110             CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
  111             0, 0, linux_sysctl_osrelease, "A",
  112             "Linux kernel OS release");
  113 
  114 static int
  115 linux_sysctl_oss_version(SYSCTL_HANDLER_ARGS)
  116 {
  117         int oss_version;
  118         int error;
  119 
  120         oss_version = linux_get_oss_version(req->td);
  121         error = sysctl_handle_int(oidp, &oss_version, 0, req);
  122         if (error || req->newptr == NULL)
  123                 return (error);
  124         error = linux_set_oss_version(req->td, oss_version);
  125         return (error);
  126 }
  127 
  128 SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version,
  129             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
  130             0, 0, linux_sysctl_oss_version, "I",
  131             "Linux OSS version");
  132 
  133 /*
  134  * Map the osrelease into integer
  135  */
  136 static int
  137 linux_map_osrel(char *osrelease, int *osrel)
  138 {
  139         char *sep, *eosrelease;
  140         int len, v0, v1, v2, v;
  141 
  142         len = strlen(osrelease);
  143         eosrelease = osrelease + len;
  144         v0 = strtol(osrelease, &sep, 10);
  145         if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
  146                 return (EINVAL);
  147         osrelease = sep + 1;
  148         v1 = strtol(osrelease, &sep, 10);
  149         if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
  150                 return (EINVAL);
  151         osrelease = sep + 1;
  152         v2 = strtol(osrelease, &sep, 10);
  153         if (osrelease == sep || sep != eosrelease)
  154                 return (EINVAL);
  155 
  156         v = v0 * 1000000 + v1 * 1000 + v2;
  157         if (v < 1000000)
  158                 return (EINVAL);
  159 
  160         *osrel = v;
  161         return (0);
  162 }
  163 
  164 /*
  165  * Find a prison with Linux info.
  166  * Return the Linux info and the (locked) prison.
  167  */
  168 static struct linux_prison *
  169 linux_find_prison(struct prison *spr, struct prison **prp)
  170 {
  171         struct prison *pr;
  172         struct linux_prison *lpr;
  173 
  174         if (!linux_osd_jail_slot)
  175                 /* In case osd_register failed. */
  176                 spr = &prison0;
  177         for (pr = spr;; pr = pr->pr_parent) {
  178                 mtx_lock(&pr->pr_mtx);
  179                 lpr = (pr == &prison0)
  180                     ? &lprison0
  181                     : osd_jail_get(pr, linux_osd_jail_slot);
  182                 if (lpr != NULL)
  183                         break;
  184                 mtx_unlock(&pr->pr_mtx);
  185         }
  186         *prp = pr;
  187         return (lpr);
  188 }
  189 
  190 /*
  191  * Ensure a prison has its own Linux info.  If lprp is non-null, point it to
  192  * the Linux info and lock the prison.
  193  */
  194 static int
  195 linux_alloc_prison(struct prison *pr, struct linux_prison **lprp)
  196 {
  197         struct prison *ppr;
  198         struct linux_prison *lpr, *nlpr;
  199         int error;
  200 
  201         /* If this prison already has Linux info, return that. */
  202         error = 0;
  203         lpr = linux_find_prison(pr, &ppr);
  204         if (ppr == pr)
  205                 goto done;
  206         /*
  207          * Allocate a new info record.  Then check again, in case something
  208          * changed during the allocation.
  209          */
  210         mtx_unlock(&ppr->pr_mtx);
  211         nlpr = malloc(sizeof(struct linux_prison), M_PRISON, M_WAITOK);
  212         lpr = linux_find_prison(pr, &ppr);
  213         if (ppr == pr) {
  214                 free(nlpr, M_PRISON);
  215                 goto done;
  216         }
  217         /* Inherit the initial values from the ancestor. */
  218         mtx_lock(&pr->pr_mtx);
  219         error = osd_jail_set(pr, linux_osd_jail_slot, nlpr);
  220         if (error == 0) {
  221                 bcopy(lpr, nlpr, sizeof(*lpr));
  222                 lpr = nlpr;
  223         } else {
  224                 free(nlpr, M_PRISON);
  225                 lpr = NULL;
  226         }
  227         mtx_unlock(&ppr->pr_mtx);
  228  done:
  229         if (lprp != NULL)
  230                 *lprp = lpr;
  231         else
  232                 mtx_unlock(&pr->pr_mtx);
  233         return (error);
  234 }
  235 
  236 /*
  237  * Jail OSD methods for Linux prison data.
  238  */
  239 static int
  240 linux_prison_create(void *obj, void *data)
  241 {
  242         struct prison *pr = obj;
  243         struct vfsoptlist *opts = data;
  244         int jsys;
  245 
  246         if (vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)) == 0 &&
  247             jsys == JAIL_SYS_INHERIT)
  248                 return (0);
  249         /*
  250          * Inherit a prison's initial values from its parent
  251          * (different from JAIL_SYS_INHERIT which also inherits changes).
  252          */
  253         return linux_alloc_prison(pr, NULL);
  254 }
  255 
  256 static int
  257 linux_prison_check(void *obj __unused, void *data)
  258 {
  259         struct vfsoptlist *opts = data;
  260         char *osname, *osrelease;
  261         int error, jsys, len, osrel, oss_version;
  262 
  263         /* Check that the parameters are correct. */
  264         error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
  265         if (error != ENOENT) {
  266                 if (error != 0)
  267                         return (error);
  268                 if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT)
  269                         return (EINVAL);
  270         }
  271         error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
  272         if (error != ENOENT) {
  273                 if (error != 0)
  274                         return (error);
  275                 if (len == 0 || osname[len - 1] != '\0')
  276                         return (EINVAL);
  277                 if (len > LINUX_MAX_UTSNAME) {
  278                         vfs_opterror(opts, "linux.osname too long");
  279                         return (ENAMETOOLONG);
  280                 }
  281         }
  282         error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
  283         if (error != ENOENT) {
  284                 if (error != 0)
  285                         return (error);
  286                 if (len == 0 || osrelease[len - 1] != '\0')
  287                         return (EINVAL);
  288                 if (len > LINUX_MAX_UTSNAME) {
  289                         vfs_opterror(opts, "linux.osrelease too long");
  290                         return (ENAMETOOLONG);
  291                 }
  292                 error = linux_map_osrel(osrelease, &osrel);
  293                 if (error != 0) {
  294                         vfs_opterror(opts, "linux.osrelease format error");
  295                         return (error);
  296                 }
  297         }
  298         error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
  299             sizeof(oss_version));
  300         return (error == ENOENT ? 0 : error);
  301 }
  302 
  303 static int
  304 linux_prison_set(void *obj, void *data)
  305 {
  306         struct linux_prison *lpr;
  307         struct prison *pr = obj;
  308         struct vfsoptlist *opts = data;
  309         char *osname, *osrelease;
  310         int error, gotversion, jsys, len, oss_version;
  311 
  312         /* Set the parameters, which should be correct. */
  313         error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
  314         if (error == ENOENT)
  315                 jsys = -1;
  316         error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
  317         if (error == ENOENT)
  318                 osname = NULL;
  319         else
  320                 jsys = JAIL_SYS_NEW;
  321         error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
  322         if (error == ENOENT)
  323                 osrelease = NULL;
  324         else
  325                 jsys = JAIL_SYS_NEW;
  326         error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
  327             sizeof(oss_version));
  328         if (error == ENOENT)
  329                 gotversion = 0;
  330         else {
  331                 gotversion = 1;
  332                 jsys = JAIL_SYS_NEW;
  333         }
  334         switch (jsys) {
  335         case JAIL_SYS_INHERIT:
  336                 /* "linux=inherit": inherit the parent's Linux info. */
  337                 mtx_lock(&pr->pr_mtx);
  338                 osd_jail_del(pr, linux_osd_jail_slot);
  339                 mtx_unlock(&pr->pr_mtx);
  340                 break;
  341         case JAIL_SYS_NEW:
  342                 /*
  343                  * "linux=new" or "linux.*":
  344                  * the prison gets its own Linux info.
  345                  */
  346                 error = linux_alloc_prison(pr, &lpr);
  347                 if (error) {
  348                         mtx_unlock(&pr->pr_mtx);
  349                         return (error);
  350                 }
  351                 if (osrelease) {
  352                         error = linux_map_osrel(osrelease, &lpr->pr_osrel);
  353                         if (error) {
  354                                 mtx_unlock(&pr->pr_mtx);
  355                                 return (error);
  356                         }
  357                         strlcpy(lpr->pr_osrelease, osrelease,
  358                             LINUX_MAX_UTSNAME);
  359                 }
  360                 if (osname)
  361                         strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
  362                 if (gotversion)
  363                         lpr->pr_oss_version = oss_version;
  364                 mtx_unlock(&pr->pr_mtx);
  365         }
  366         return (0);
  367 }
  368 
  369 SYSCTL_JAIL_PARAM_SYS_NODE(linux, CTLFLAG_RW, "Jail Linux parameters");
  370 SYSCTL_JAIL_PARAM_STRING(_linux, osname, CTLFLAG_RW, LINUX_MAX_UTSNAME,
  371     "Jail Linux kernel OS name");
  372 SYSCTL_JAIL_PARAM_STRING(_linux, osrelease, CTLFLAG_RW, LINUX_MAX_UTSNAME,
  373     "Jail Linux kernel OS release");
  374 SYSCTL_JAIL_PARAM(_linux, oss_version, CTLTYPE_INT | CTLFLAG_RW,
  375     "I", "Jail Linux OSS version");
  376 
  377 static int
  378 linux_prison_get(void *obj, void *data)
  379 {
  380         struct linux_prison *lpr;
  381         struct prison *ppr;
  382         struct prison *pr = obj;
  383         struct vfsoptlist *opts = data;
  384         int error, i;
  385 
  386         static int version0;
  387 
  388         /* See if this prison is the one with the Linux info. */
  389         lpr = linux_find_prison(pr, &ppr);
  390         i = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT;
  391         error = vfs_setopt(opts, "linux", &i, sizeof(i));
  392         if (error != 0 && error != ENOENT)
  393                 goto done;
  394         if (i) {
  395                 error = vfs_setopts(opts, "linux.osname", lpr->pr_osname);
  396                 if (error != 0 && error != ENOENT)
  397                         goto done;
  398                 error = vfs_setopts(opts, "linux.osrelease", lpr->pr_osrelease);
  399                 if (error != 0 && error != ENOENT)
  400                         goto done;
  401                 error = vfs_setopt(opts, "linux.oss_version",
  402                     &lpr->pr_oss_version, sizeof(lpr->pr_oss_version));
  403                 if (error != 0 && error != ENOENT)
  404                         goto done;
  405         } else {
  406                 /*
  407                  * If this prison is inheriting its Linux info, report
  408                  * empty/zero parameters.
  409                  */
  410                 error = vfs_setopts(opts, "linux.osname", "");
  411                 if (error != 0 && error != ENOENT)
  412                         goto done;
  413                 error = vfs_setopts(opts, "linux.osrelease", "");
  414                 if (error != 0 && error != ENOENT)
  415                         goto done;
  416                 error = vfs_setopt(opts, "linux.oss_version", &version0,
  417                     sizeof(lpr->pr_oss_version));
  418                 if (error != 0 && error != ENOENT)
  419                         goto done;
  420         }
  421         error = 0;
  422 
  423  done:
  424         mtx_unlock(&ppr->pr_mtx);
  425         return (error);
  426 }
  427 
  428 static void
  429 linux_prison_destructor(void *data)
  430 {
  431 
  432         free(data, M_PRISON);
  433 }
  434 
  435 void
  436 linux_osd_jail_register(void)
  437 {
  438         struct prison *pr;
  439         osd_method_t methods[PR_MAXMETHOD] = {
  440             [PR_METHOD_CREATE] =        linux_prison_create,
  441             [PR_METHOD_GET] =           linux_prison_get,
  442             [PR_METHOD_SET] =           linux_prison_set,
  443             [PR_METHOD_CHECK] =         linux_prison_check
  444         };
  445 
  446         linux_osd_jail_slot =
  447             osd_jail_register(linux_prison_destructor, methods);
  448         if (linux_osd_jail_slot > 0) {
  449                 /* Copy the system linux info to any current prisons. */
  450                 sx_xlock(&allprison_lock);
  451                 TAILQ_FOREACH(pr, &allprison, pr_list)
  452                         (void)linux_alloc_prison(pr, NULL);
  453                 sx_xunlock(&allprison_lock);
  454         }
  455 }
  456 
  457 void
  458 linux_osd_jail_deregister(void)
  459 {
  460 
  461         if (linux_osd_jail_slot)
  462                 osd_jail_deregister(linux_osd_jail_slot);
  463 }
  464 
  465 void
  466 linux_get_osname(struct thread *td, char *dst)
  467 {
  468         struct prison *pr;
  469         struct linux_prison *lpr;
  470 
  471         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  472         bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME);
  473         mtx_unlock(&pr->pr_mtx);
  474 }
  475 
  476 static int
  477 linux_set_osname(struct thread *td, char *osname)
  478 {
  479         struct prison *pr;
  480         struct linux_prison *lpr;
  481 
  482         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  483         strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
  484         mtx_unlock(&pr->pr_mtx);
  485         return (0);
  486 }
  487 
  488 void
  489 linux_get_osrelease(struct thread *td, char *dst)
  490 {
  491         struct prison *pr;
  492         struct linux_prison *lpr;
  493 
  494         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  495         bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME);
  496         mtx_unlock(&pr->pr_mtx);
  497 }
  498 
  499 int
  500 linux_kernver(struct thread *td)
  501 {
  502         struct prison *pr;
  503         struct linux_prison *lpr;
  504         int osrel;
  505 
  506         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  507         osrel = lpr->pr_osrel;
  508         mtx_unlock(&pr->pr_mtx);
  509         return (osrel);
  510 }
  511 
  512 static int
  513 linux_set_osrelease(struct thread *td, char *osrelease)
  514 {
  515         struct prison *pr;
  516         struct linux_prison *lpr;
  517         int error;
  518 
  519         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  520         error = linux_map_osrel(osrelease, &lpr->pr_osrel);
  521         if (error == 0)
  522                 strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME);
  523         mtx_unlock(&pr->pr_mtx);
  524         return (error);
  525 }
  526 
  527 int
  528 linux_get_oss_version(struct thread *td)
  529 {
  530         struct prison *pr;
  531         struct linux_prison *lpr;
  532         int version;
  533 
  534         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  535         version = lpr->pr_oss_version;
  536         mtx_unlock(&pr->pr_mtx);
  537         return (version);
  538 }
  539 
  540 static int
  541 linux_set_oss_version(struct thread *td, int oss_version)
  542 {
  543         struct prison *pr;
  544         struct linux_prison *lpr;
  545 
  546         lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
  547         lpr->pr_oss_version = oss_version;
  548         mtx_unlock(&pr->pr_mtx);
  549         return (0);
  550 }
  551 
  552 #if defined(DEBUG) || defined(KTR)
  553 
  554 u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))];
  555 
  556 static int
  557 linux_debug(int syscall, int toggle, int global)
  558 {
  559 
  560         if (global) {
  561                 char c = toggle ? 0 : 0xff;
  562 
  563                 memset(linux_debug_map, c, sizeof(linux_debug_map));
  564                 return (0);
  565         }
  566         if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL)
  567                 return (EINVAL);
  568         if (toggle)
  569                 clrbit(linux_debug_map, syscall);
  570         else
  571                 setbit(linux_debug_map, syscall);
  572         return (0);
  573 }
  574 
  575 /*
  576  * Usage: sysctl linux.debug=<syscall_nr>.<0/1>
  577  *
  578  *    E.g.: sysctl linux.debug=21.0
  579  *
  580  * As a special case, syscall "all" will apply to all syscalls globally.
  581  */
  582 #define LINUX_MAX_DEBUGSTR      16
  583 static int
  584 linux_sysctl_debug(SYSCTL_HANDLER_ARGS)
  585 {
  586         char value[LINUX_MAX_DEBUGSTR], *p;
  587         int error, sysc, toggle;
  588         int global = 0;
  589 
  590         value[0] = '\0';
  591         error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req);
  592         if (error || req->newptr == NULL)
  593                 return (error);
  594         for (p = value; *p != '\0' && *p != '.'; p++);
  595         if (*p == '\0')
  596                 return (EINVAL);
  597         *p++ = '\0';
  598         sysc = strtol(value, NULL, 0);
  599         toggle = strtol(p, NULL, 0);
  600         if (strcmp(value, "all") == 0)
  601                 global = 1;
  602         error = linux_debug(sysc, toggle, global);
  603         return (error);
  604 }
  605 
  606 SYSCTL_PROC(_compat_linux, OID_AUTO, debug,
  607             CTLTYPE_STRING | CTLFLAG_RW,
  608             0, 0, linux_sysctl_debug, "A",
  609             "Linux debugging control");
  610 
  611 #endif /* DEBUG || KTR */

Cache object: 0da48ed7956a674b4f7385aa5522dedf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.