linux/lib/dynamic_debug.c
<<
>>
Prefs
   1/*
   2 * lib/dynamic_debug.c
   3 *
   4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their
   5 * source module.
   6 *
   7 * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
   8 * By Greg Banks <gnb@melbourne.sgi.com>
   9 * Copyright (c) 2008 Silicon Graphics Inc.  All Rights Reserved.
  10 * Copyright (C) 2011 Bart Van Assche.  All Rights Reserved.
  11 */
  12
  13#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
  14
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/moduleparam.h>
  18#include <linux/kallsyms.h>
  19#include <linux/types.h>
  20#include <linux/mutex.h>
  21#include <linux/proc_fs.h>
  22#include <linux/seq_file.h>
  23#include <linux/list.h>
  24#include <linux/sysctl.h>
  25#include <linux/ctype.h>
  26#include <linux/string.h>
  27#include <linux/uaccess.h>
  28#include <linux/dynamic_debug.h>
  29#include <linux/debugfs.h>
  30#include <linux/slab.h>
  31#include <linux/jump_label.h>
  32#include <linux/hardirq.h>
  33#include <linux/sched.h>
  34#include <linux/device.h>
  35#include <linux/netdevice.h>
  36
  37extern struct _ddebug __start___verbose[];
  38extern struct _ddebug __stop___verbose[];
  39
  40struct ddebug_table {
  41        struct list_head link;
  42        char *mod_name;
  43        unsigned int num_ddebugs;
  44        struct _ddebug *ddebugs;
  45};
  46
  47struct ddebug_query {
  48        const char *filename;
  49        const char *module;
  50        const char *function;
  51        const char *format;
  52        unsigned int first_lineno, last_lineno;
  53};
  54
  55struct ddebug_iter {
  56        struct ddebug_table *table;
  57        unsigned int idx;
  58};
  59
  60static DEFINE_MUTEX(ddebug_lock);
  61static LIST_HEAD(ddebug_tables);
  62static int verbose = 0;
  63
  64/* Return the last part of a pathname */
  65static inline const char *basename(const char *path)
  66{
  67        const char *tail = strrchr(path, '/');
  68        return tail ? tail+1 : path;
  69}
  70
  71static struct { unsigned flag:8; char opt_char; } opt_array[] = {
  72        { _DPRINTK_FLAGS_PRINT, 'p' },
  73        { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
  74        { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
  75        { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
  76        { _DPRINTK_FLAGS_INCL_TID, 't' },
  77};
  78
  79/* format a string into buf[] which describes the _ddebug's flags */
  80static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
  81                                    size_t maxlen)
  82{
  83        char *p = buf;
  84        int i;
  85
  86        BUG_ON(maxlen < 4);
  87        for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
  88                if (dp->flags & opt_array[i].flag)
  89                        *p++ = opt_array[i].opt_char;
  90        if (p == buf)
  91                *p++ = '-';
  92        *p = '\0';
  93
  94        return buf;
  95}
  96
  97/*
  98 * Search the tables for _ddebug's which match the given
  99 * `query' and apply the `flags' and `mask' to them.  Tells
 100 * the user which ddebug's were changed, or whether none
 101 * were matched.
 102 */
 103static void ddebug_change(const struct ddebug_query *query,
 104                           unsigned int flags, unsigned int mask)
 105{
 106        int i;
 107        struct ddebug_table *dt;
 108        unsigned int newflags;
 109        unsigned int nfound = 0;
 110        char flagbuf[8];
 111
 112        /* search for matching ddebugs */
 113        mutex_lock(&ddebug_lock);
 114        list_for_each_entry(dt, &ddebug_tables, link) {
 115
 116                /* match against the module name */
 117                if (query->module != NULL &&
 118                    strcmp(query->module, dt->mod_name))
 119                        continue;
 120
 121                for (i = 0 ; i < dt->num_ddebugs ; i++) {
 122                        struct _ddebug *dp = &dt->ddebugs[i];
 123
 124                        /* match against the source filename */
 125                        if (query->filename != NULL &&
 126                            strcmp(query->filename, dp->filename) &&
 127                            strcmp(query->filename, basename(dp->filename)))
 128                                continue;
 129
 130                        /* match against the function */
 131                        if (query->function != NULL &&
 132                            strcmp(query->function, dp->function))
 133                                continue;
 134
 135                        /* match against the format */
 136                        if (query->format != NULL &&
 137                            strstr(dp->format, query->format) == NULL)
 138                                continue;
 139
 140                        /* match against the line number range */
 141                        if (query->first_lineno &&
 142                            dp->lineno < query->first_lineno)
 143                                continue;
 144                        if (query->last_lineno &&
 145                            dp->lineno > query->last_lineno)
 146                                continue;
 147
 148                        nfound++;
 149
 150                        newflags = (dp->flags & mask) | flags;
 151                        if (newflags == dp->flags)
 152                                continue;
 153                        dp->flags = newflags;
 154                        if (newflags)
 155                                dp->enabled = 1;
 156                        else
 157                                dp->enabled = 0;
 158                        if (verbose)
 159                                pr_info("changed %s:%d [%s]%s %s\n",
 160                                        dp->filename, dp->lineno,
 161                                        dt->mod_name, dp->function,
 162                                        ddebug_describe_flags(dp, flagbuf,
 163                                                        sizeof(flagbuf)));
 164                }
 165        }
 166        mutex_unlock(&ddebug_lock);
 167
 168        if (!nfound && verbose)
 169                pr_info("no matches for query\n");
 170}
 171
 172/*
 173 * Split the buffer `buf' into space-separated words.
 174 * Handles simple " and ' quoting, i.e. without nested,
 175 * embedded or escaped \".  Return the number of words
 176 * or <0 on error.
 177 */
 178static int ddebug_tokenize(char *buf, char *words[], int maxwords)
 179{
 180        int nwords = 0;
 181
 182        while (*buf) {
 183                char *end;
 184
 185                /* Skip leading whitespace */
 186                buf = skip_spaces(buf);
 187                if (!*buf)
 188                        break;  /* oh, it was trailing whitespace */
 189
 190                /* Run `end' over a word, either whitespace separated or quoted */
 191                if (*buf == '"' || *buf == '\'') {
 192                        int quote = *buf++;
 193                        for (end = buf ; *end && *end != quote ; end++)
 194                                ;
 195                        if (!*end)
 196                                return -EINVAL; /* unclosed quote */
 197                } else {
 198                        for (end = buf ; *end && !isspace(*end) ; end++)
 199                                ;
 200                        BUG_ON(end == buf);
 201                }
 202                /* Here `buf' is the start of the word, `end' is one past the end */
 203
 204                if (nwords == maxwords)
 205                        return -EINVAL; /* ran out of words[] before bytes */
 206                if (*end)
 207                        *end++ = '\0';  /* terminate the word */
 208                words[nwords++] = buf;
 209                buf = end;
 210        }
 211
 212        if (verbose) {
 213                int i;
 214                pr_info("split into words:");
 215                for (i = 0 ; i < nwords ; i++)
 216                        pr_cont(" \"%s\"", words[i]);
 217                pr_cont("\n");
 218        }
 219
 220        return nwords;
 221}
 222
 223/*
 224 * Parse a single line number.  Note that the empty string ""
 225 * is treated as a special case and converted to zero, which
 226 * is later treated as a "don't care" value.
 227 */
 228static inline int parse_lineno(const char *str, unsigned int *val)
 229{
 230        char *end = NULL;
 231        BUG_ON(str == NULL);
 232        if (*str == '\0') {
 233                *val = 0;
 234                return 0;
 235        }
 236        *val = simple_strtoul(str, &end, 10);
 237        return end == NULL || end == str || *end != '\0' ? -EINVAL : 0;
 238}
 239
 240/*
 241 * Undo octal escaping in a string, inplace.  This is useful to
 242 * allow the user to express a query which matches a format
 243 * containing embedded spaces.
 244 */
 245#define isodigit(c)             ((c) >= '0' && (c) <= '7')
 246static char *unescape(char *str)
 247{
 248        char *in = str;
 249        char *out = str;
 250
 251        while (*in) {
 252                if (*in == '\\') {
 253                        if (in[1] == '\\') {
 254                                *out++ = '\\';
 255                                in += 2;
 256                                continue;
 257                        } else if (in[1] == 't') {
 258                                *out++ = '\t';
 259                                in += 2;
 260                                continue;
 261                        } else if (in[1] == 'n') {
 262                                *out++ = '\n';
 263                                in += 2;
 264                                continue;
 265                        } else if (isodigit(in[1]) &&
 266                                 isodigit(in[2]) &&
 267                                 isodigit(in[3])) {
 268                                *out++ = ((in[1] - '0')<<6) |
 269                                          ((in[2] - '0')<<3) |
 270                                          (in[3] - '0');
 271                                in += 4;
 272                                continue;
 273                        }
 274                }
 275                *out++ = *in++;
 276        }
 277        *out = '\0';
 278
 279        return str;
 280}
 281
 282/*
 283 * Parse words[] as a ddebug query specification, which is a series
 284 * of (keyword, value) pairs chosen from these possibilities:
 285 *
 286 * func <function-name>
 287 * file <full-pathname>
 288 * file <base-filename>
 289 * module <module-name>
 290 * format <escaped-string-to-find-in-format>
 291 * line <lineno>
 292 * line <first-lineno>-<last-lineno> // where either may be empty
 293 */
 294static int ddebug_parse_query(char *words[], int nwords,
 295                               struct ddebug_query *query)
 296{
 297        unsigned int i;
 298
 299        /* check we have an even number of words */
 300        if (nwords % 2 != 0)
 301                return -EINVAL;
 302        memset(query, 0, sizeof(*query));
 303
 304        for (i = 0 ; i < nwords ; i += 2) {
 305                if (!strcmp(words[i], "func"))
 306                        query->function = words[i+1];
 307                else if (!strcmp(words[i], "file"))
 308                        query->filename = words[i+1];
 309                else if (!strcmp(words[i], "module"))
 310                        query->module = words[i+1];
 311                else if (!strcmp(words[i], "format"))
 312                        query->format = unescape(words[i+1]);
 313                else if (!strcmp(words[i], "line")) {
 314                        char *first = words[i+1];
 315                        char *last = strchr(first, '-');
 316                        if (last)
 317                                *last++ = '\0';
 318                        if (parse_lineno(first, &query->first_lineno) < 0)
 319                                return -EINVAL;
 320                        if (last != NULL) {
 321                                /* range <first>-<last> */
 322                                if (parse_lineno(last, &query->last_lineno) < 0)
 323                                        return -EINVAL;
 324                        } else {
 325                                query->last_lineno = query->first_lineno;
 326                        }
 327                } else {
 328                        if (verbose)
 329                                pr_err("unknown keyword \"%s\"\n", words[i]);
 330                        return -EINVAL;
 331                }
 332        }
 333
 334        if (verbose)
 335                pr_info("q->function=\"%s\" q->filename=\"%s\" "
 336                        "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
 337                        query->function, query->filename,
 338                        query->module, query->format, query->first_lineno,
 339                        query->last_lineno);
 340
 341        return 0;
 342}
 343
 344/*
 345 * Parse `str' as a flags specification, format [-+=][p]+.
 346 * Sets up *maskp and *flagsp to be used when changing the
 347 * flags fields of matched _ddebug's.  Returns 0 on success
 348 * or <0 on error.
 349 */
 350static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
 351                               unsigned int *maskp)
 352{
 353        unsigned flags = 0;
 354        int op = '=', i;
 355
 356        switch (*str) {
 357        case '+':
 358        case '-':
 359        case '=':
 360                op = *str++;
 361                break;
 362        default:
 363                return -EINVAL;
 364        }
 365        if (verbose)
 366                pr_info("op='%c'\n", op);
 367
 368        for ( ; *str ; ++str) {
 369                for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
 370                        if (*str == opt_array[i].opt_char) {
 371                                flags |= opt_array[i].flag;
 372                                break;
 373                        }
 374                }
 375                if (i < 0)
 376                        return -EINVAL;
 377        }
 378        if (flags == 0)
 379                return -EINVAL;
 380        if (verbose)
 381                pr_info("flags=0x%x\n", flags);
 382
 383        /* calculate final *flagsp, *maskp according to mask and op */
 384        switch (op) {
 385        case '=':
 386                *maskp = 0;
 387                *flagsp = flags;
 388                break;
 389        case '+':
 390                *maskp = ~0U;
 391                *flagsp = flags;
 392                break;
 393        case '-':
 394                *maskp = ~flags;
 395                *flagsp = 0;
 396                break;
 397        }
 398        if (verbose)
 399                pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
 400        return 0;
 401}
 402
 403static int ddebug_exec_query(char *query_string)
 404{
 405        unsigned int flags = 0, mask = 0;
 406        struct ddebug_query query;
 407#define MAXWORDS 9
 408        int nwords;
 409        char *words[MAXWORDS];
 410
 411        nwords = ddebug_tokenize(query_string, words, MAXWORDS);
 412        if (nwords <= 0)
 413                return -EINVAL;
 414        if (ddebug_parse_query(words, nwords-1, &query))
 415                return -EINVAL;
 416        if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
 417                return -EINVAL;
 418
 419        /* actually go and implement the change */
 420        ddebug_change(&query, flags, mask);
 421        return 0;
 422}
 423
 424#define PREFIX_SIZE 64
 425
 426static int remaining(int wrote)
 427{
 428        if (PREFIX_SIZE - wrote > 0)
 429                return PREFIX_SIZE - wrote;
 430        return 0;
 431}
 432
 433static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
 434{
 435        int pos_after_tid;
 436        int pos = 0;
 437
 438        pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG);
 439        if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
 440                if (in_interrupt())
 441                        pos += snprintf(buf + pos, remaining(pos), "%s ",
 442                                                "<intr>");
 443                else
 444                        pos += snprintf(buf + pos, remaining(pos), "[%d] ",
 445                                                task_pid_vnr(current));
 446        }
 447        pos_after_tid = pos;
 448        if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
 449                pos += snprintf(buf + pos, remaining(pos), "%s:",
 450                                        desc->modname);
 451        if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
 452                pos += snprintf(buf + pos, remaining(pos), "%s:",
 453                                        desc->function);
 454        if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
 455                pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno);
 456        if (pos - pos_after_tid)
 457                pos += snprintf(buf + pos, remaining(pos), " ");
 458        if (pos >= PREFIX_SIZE)
 459                buf[PREFIX_SIZE - 1] = '\0';
 460
 461        return buf;
 462}
 463
 464int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
 465{
 466        va_list args;
 467        int res;
 468        struct va_format vaf;
 469        char buf[PREFIX_SIZE];
 470
 471        BUG_ON(!descriptor);
 472        BUG_ON(!fmt);
 473
 474        va_start(args, fmt);
 475        vaf.fmt = fmt;
 476        vaf.va = &args;
 477        res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
 478        va_end(args);
 479
 480        return res;
 481}
 482EXPORT_SYMBOL(__dynamic_pr_debug);
 483
 484int __dynamic_dev_dbg(struct _ddebug *descriptor,
 485                      const struct device *dev, const char *fmt, ...)
 486{
 487        struct va_format vaf;
 488        va_list args;
 489        int res;
 490        char buf[PREFIX_SIZE];
 491
 492        BUG_ON(!descriptor);
 493        BUG_ON(!fmt);
 494
 495        va_start(args, fmt);
 496        vaf.fmt = fmt;
 497        vaf.va = &args;
 498        res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
 499        va_end(args);
 500
 501        return res;
 502}
 503EXPORT_SYMBOL(__dynamic_dev_dbg);
 504
 505#ifdef CONFIG_NET
 506
 507int __dynamic_netdev_dbg(struct _ddebug *descriptor,
 508                      const struct net_device *dev, const char *fmt, ...)
 509{
 510        struct va_format vaf;
 511        va_list args;
 512        int res;
 513        char buf[PREFIX_SIZE];
 514
 515        BUG_ON(!descriptor);
 516        BUG_ON(!fmt);
 517
 518        va_start(args, fmt);
 519        vaf.fmt = fmt;
 520        vaf.va = &args;
 521        res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
 522        va_end(args);
 523
 524        return res;
 525}
 526EXPORT_SYMBOL(__dynamic_netdev_dbg);
 527
 528#endif
 529
 530static __initdata char ddebug_setup_string[1024];
 531static __init int ddebug_setup_query(char *str)
 532{
 533        if (strlen(str) >= 1024) {
 534                pr_warn("ddebug boot param string too large\n");
 535                return 0;
 536        }
 537        strcpy(ddebug_setup_string, str);
 538        return 1;
 539}
 540
 541__setup("ddebug_query=", ddebug_setup_query);
 542
 543/*
 544 * File_ops->write method for <debugfs>/dynamic_debug/conrol.  Gathers the
 545 * command text from userspace, parses and executes it.
 546 */
 547static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
 548                                  size_t len, loff_t *offp)
 549{
 550        char tmpbuf[256];
 551        int ret;
 552
 553        if (len == 0)
 554                return 0;
 555        /* we don't check *offp -- multiple writes() are allowed */
 556        if (len > sizeof(tmpbuf)-1)
 557                return -E2BIG;
 558        if (copy_from_user(tmpbuf, ubuf, len))
 559                return -EFAULT;
 560        tmpbuf[len] = '\0';
 561        if (verbose)
 562                pr_info("read %d bytes from userspace\n", (int)len);
 563
 564        ret = ddebug_exec_query(tmpbuf);
 565        if (ret)
 566                return ret;
 567
 568        *offp += len;
 569        return len;
 570}
 571
 572/*
 573 * Set the iterator to point to the first _ddebug object
 574 * and return a pointer to that first object.  Returns
 575 * NULL if there are no _ddebugs at all.
 576 */
 577static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
 578{
 579        if (list_empty(&ddebug_tables)) {
 580                iter->table = NULL;
 581                iter->idx = 0;
 582                return NULL;
 583        }
 584        iter->table = list_entry(ddebug_tables.next,
 585                                 struct ddebug_table, link);
 586        iter->idx = 0;
 587        return &iter->table->ddebugs[iter->idx];
 588}
 589
 590/*
 591 * Advance the iterator to point to the next _ddebug
 592 * object from the one the iterator currently points at,
 593 * and returns a pointer to the new _ddebug.  Returns
 594 * NULL if the iterator has seen all the _ddebugs.
 595 */
 596static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
 597{
 598        if (iter->table == NULL)
 599                return NULL;
 600        if (++iter->idx == iter->table->num_ddebugs) {
 601                /* iterate to next table */
 602                iter->idx = 0;
 603                if (list_is_last(&iter->table->link, &ddebug_tables)) {
 604                        iter->table = NULL;
 605                        return NULL;
 606                }
 607                iter->table = list_entry(iter->table->link.next,
 608                                         struct ddebug_table, link);
 609        }
 610        return &iter->table->ddebugs[iter->idx];
 611}
 612
 613/*
 614 * Seq_ops start method.  Called at the start of every
 615 * read() call from userspace.  Takes the ddebug_lock and
 616 * seeks the seq_file's iterator to the given position.
 617 */
 618static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
 619{
 620        struct ddebug_iter *iter = m->private;
 621        struct _ddebug *dp;
 622        int n = *pos;
 623
 624        if (verbose)
 625                pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
 626
 627        mutex_lock(&ddebug_lock);
 628
 629        if (!n)
 630                return SEQ_START_TOKEN;
 631        if (n < 0)
 632                return NULL;
 633        dp = ddebug_iter_first(iter);
 634        while (dp != NULL && --n > 0)
 635                dp = ddebug_iter_next(iter);
 636        return dp;
 637}
 638
 639/*
 640 * Seq_ops next method.  Called several times within a read()
 641 * call from userspace, with ddebug_lock held.  Walks to the
 642 * next _ddebug object with a special case for the header line.
 643 */
 644static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
 645{
 646        struct ddebug_iter *iter = m->private;
 647        struct _ddebug *dp;
 648
 649        if (verbose)
 650                pr_info("called m=%p p=%p *pos=%lld\n",
 651                        m, p, (unsigned long long)*pos);
 652
 653        if (p == SEQ_START_TOKEN)
 654                dp = ddebug_iter_first(iter);
 655        else
 656                dp = ddebug_iter_next(iter);
 657        ++*pos;
 658        return dp;
 659}
 660
 661/*
 662 * Seq_ops show method.  Called several times within a read()
 663 * call from userspace, with ddebug_lock held.  Formats the
 664 * current _ddebug as a single human-readable line, with a
 665 * special case for the header line.
 666 */
 667static int ddebug_proc_show(struct seq_file *m, void *p)
 668{
 669        struct ddebug_iter *iter = m->private;
 670        struct _ddebug *dp = p;
 671        char flagsbuf[8];
 672
 673        if (verbose)
 674                pr_info("called m=%p p=%p\n", m, p);
 675
 676        if (p == SEQ_START_TOKEN) {
 677                seq_puts(m,
 678                        "# filename:lineno [module]function flags format\n");
 679                return 0;
 680        }
 681
 682        seq_printf(m, "%s:%u [%s]%s %s \"",
 683                   dp->filename, dp->lineno,
 684                   iter->table->mod_name, dp->function,
 685                   ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
 686        seq_escape(m, dp->format, "\t\r\n\"");
 687        seq_puts(m, "\"\n");
 688
 689        return 0;
 690}
 691
 692/*
 693 * Seq_ops stop method.  Called at the end of each read()
 694 * call from userspace.  Drops ddebug_lock.
 695 */
 696static void ddebug_proc_stop(struct seq_file *m, void *p)
 697{
 698        if (verbose)
 699                pr_info("called m=%p p=%p\n", m, p);
 700        mutex_unlock(&ddebug_lock);
 701}
 702
 703static const struct seq_operations ddebug_proc_seqops = {
 704        .start = ddebug_proc_start,
 705        .next = ddebug_proc_next,
 706        .show = ddebug_proc_show,
 707        .stop = ddebug_proc_stop
 708};
 709
 710/*
 711 * File_ops->open method for <debugfs>/dynamic_debug/control.  Does the seq_file
 712 * setup dance, and also creates an iterator to walk the _ddebugs.
 713 * Note that we create a seq_file always, even for O_WRONLY files
 714 * where it's not needed, as doing so simplifies the ->release method.
 715 */
 716static int ddebug_proc_open(struct inode *inode, struct file *file)
 717{
 718        struct ddebug_iter *iter;
 719        int err;
 720
 721        if (verbose)
 722                pr_info("called\n");
 723
 724        iter = kzalloc(sizeof(*iter), GFP_KERNEL);
 725        if (iter == NULL)
 726                return -ENOMEM;
 727
 728        err = seq_open(file, &ddebug_proc_seqops);
 729        if (err) {
 730                kfree(iter);
 731                return err;
 732        }
 733        ((struct seq_file *) file->private_data)->private = iter;
 734        return 0;
 735}
 736
 737static const struct file_operations ddebug_proc_fops = {
 738        .owner = THIS_MODULE,
 739        .open = ddebug_proc_open,
 740        .read = seq_read,
 741        .llseek = seq_lseek,
 742        .release = seq_release_private,
 743        .write = ddebug_proc_write
 744};
 745
 746/*
 747 * Allocate a new ddebug_table for the given module
 748 * and add it to the global list.
 749 */
 750int ddebug_add_module(struct _ddebug *tab, unsigned int n,
 751                             const char *name)
 752{
 753        struct ddebug_table *dt;
 754        char *new_name;
 755
 756        dt = kzalloc(sizeof(*dt), GFP_KERNEL);
 757        if (dt == NULL)
 758                return -ENOMEM;
 759        new_name = kstrdup(name, GFP_KERNEL);
 760        if (new_name == NULL) {
 761                kfree(dt);
 762                return -ENOMEM;
 763        }
 764        dt->mod_name = new_name;
 765        dt->num_ddebugs = n;
 766        dt->ddebugs = tab;
 767
 768        mutex_lock(&ddebug_lock);
 769        list_add_tail(&dt->link, &ddebug_tables);
 770        mutex_unlock(&ddebug_lock);
 771
 772        if (verbose)
 773                pr_info("%u debug prints in module %s\n", n, dt->mod_name);
 774        return 0;
 775}
 776EXPORT_SYMBOL_GPL(ddebug_add_module);
 777
 778static void ddebug_table_free(struct ddebug_table *dt)
 779{
 780        list_del_init(&dt->link);
 781        kfree(dt->mod_name);
 782        kfree(dt);
 783}
 784
 785/*
 786 * Called in response to a module being unloaded.  Removes
 787 * any ddebug_table's which point at the module.
 788 */
 789int ddebug_remove_module(const char *mod_name)
 790{
 791        struct ddebug_table *dt, *nextdt;
 792        int ret = -ENOENT;
 793
 794        if (verbose)
 795                pr_info("removing module \"%s\"\n", mod_name);
 796
 797        mutex_lock(&ddebug_lock);
 798        list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
 799                if (!strcmp(dt->mod_name, mod_name)) {
 800                        ddebug_table_free(dt);
 801                        ret = 0;
 802                }
 803        }
 804        mutex_unlock(&ddebug_lock);
 805        return ret;
 806}
 807EXPORT_SYMBOL_GPL(ddebug_remove_module);
 808
 809static void ddebug_remove_all_tables(void)
 810{
 811        mutex_lock(&ddebug_lock);
 812        while (!list_empty(&ddebug_tables)) {
 813                struct ddebug_table *dt = list_entry(ddebug_tables.next,
 814                                                      struct ddebug_table,
 815                                                      link);
 816                ddebug_table_free(dt);
 817        }
 818        mutex_unlock(&ddebug_lock);
 819}
 820
 821static __initdata int ddebug_init_success;
 822
 823static int __init dynamic_debug_init_debugfs(void)
 824{
 825        struct dentry *dir, *file;
 826
 827        if (!ddebug_init_success)
 828                return -ENODEV;
 829
 830        dir = debugfs_create_dir("dynamic_debug", NULL);
 831        if (!dir)
 832                return -ENOMEM;
 833        file = debugfs_create_file("control", 0644, dir, NULL,
 834                                        &ddebug_proc_fops);
 835        if (!file) {
 836                debugfs_remove(dir);
 837                return -ENOMEM;
 838        }
 839        return 0;
 840}
 841
 842static int __init dynamic_debug_init(void)
 843{
 844        struct _ddebug *iter, *iter_start;
 845        const char *modname = NULL;
 846        int ret = 0;
 847        int n = 0;
 848
 849        if (__start___verbose != __stop___verbose) {
 850                iter = __start___verbose;
 851                modname = iter->modname;
 852                iter_start = iter;
 853                for (; iter < __stop___verbose; iter++) {
 854                        if (strcmp(modname, iter->modname)) {
 855                                ret = ddebug_add_module(iter_start, n, modname);
 856                                if (ret)
 857                                        goto out_free;
 858                                n = 0;
 859                                modname = iter->modname;
 860                                iter_start = iter;
 861                        }
 862                        n++;
 863                }
 864                ret = ddebug_add_module(iter_start, n, modname);
 865        }
 866
 867        /* ddebug_query boot param got passed -> set it up */
 868        if (ddebug_setup_string[0] != '\0') {
 869                ret = ddebug_exec_query(ddebug_setup_string);
 870                if (ret)
 871                        pr_warn("Invalid ddebug boot param %s",
 872                                ddebug_setup_string);
 873                else
 874                        pr_info("ddebug initialized with string %s",
 875                                ddebug_setup_string);
 876        }
 877
 878out_free:
 879        if (ret)
 880                ddebug_remove_all_tables();
 881        else
 882                ddebug_init_success = 1;
 883        return 0;
 884}
 885/* Allow early initialization for boot messages via boot param */
 886arch_initcall(dynamic_debug_init);
 887/* Debugfs setup must be done later */
 888module_init(dynamic_debug_init_debugfs);
 889
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.