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/geom/vinum/geom_vinum_list.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) 2004, 2007 Lukas Ertl
    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  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 
   14  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD: releng/8.3/sys/geom/vinum/geom_vinum_list.c 190507 2009-03-28 17:20:08Z lulf $");
   30 
   31 #include <sys/libkern.h>
   32 #include <sys/malloc.h>
   33 
   34 #include <geom/geom.h>
   35 #include <geom/vinum/geom_vinum_var.h>
   36 #include <geom/vinum/geom_vinum.h>
   37 #include <geom/vinum/geom_vinum_share.h>
   38 
   39 void    gv_lvi(struct gv_volume *, struct sbuf *, int);
   40 void    gv_lpi(struct gv_plex *, struct sbuf *, int);
   41 void    gv_lsi(struct gv_sd *, struct sbuf *, int);
   42 void    gv_ldi(struct gv_drive *, struct sbuf *, int);
   43 
   44 void
   45 gv_list(struct g_geom *gp, struct gctl_req *req)
   46 {
   47         struct gv_softc *sc;
   48         struct gv_drive *d;
   49         struct gv_plex *p;
   50         struct gv_sd *s;
   51         struct gv_volume *v;
   52         struct sbuf *sb;
   53         int *argc, i, *flags, type;
   54         char *arg, buf[20], *cmd;
   55 
   56         argc = gctl_get_paraml(req, "argc", sizeof(*argc));
   57 
   58         if (argc == NULL) {
   59                 gctl_error(req, "no arguments given");
   60                 return;
   61         }
   62 
   63         flags = gctl_get_paraml(req, "flags", sizeof(*flags));
   64         if (flags == NULL) {
   65                 gctl_error(req, "no flags given");
   66                 return;
   67         }
   68 
   69         sc = gp->softc;
   70 
   71         sb = sbuf_new(NULL, NULL, GV_CFG_LEN, SBUF_FIXEDLEN);
   72 
   73         /* Figure out which command was given. */
   74         cmd = gctl_get_param(req, "cmd", NULL);
   75         if (cmd == NULL) {
   76                 gctl_error(req, "no command given");
   77                 return;
   78         }
   79 
   80         /* List specific objects or everything. */
   81         if (!strcmp(cmd, "list") || !strcmp(cmd, "l")) {
   82                 if (*argc) {
   83                         for (i = 0; i < *argc; i++) {
   84                                 snprintf(buf, sizeof(buf), "argv%d", i);
   85                                 arg = gctl_get_param(req, buf, NULL);
   86                                 if (arg == NULL)
   87                                         continue;
   88                                 type = gv_object_type(sc, arg);
   89                                 switch (type) {
   90                                 case GV_TYPE_VOL:
   91                                         v = gv_find_vol(sc, arg);
   92                                         gv_lvi(v, sb, *flags);
   93                                         break;
   94                                 case GV_TYPE_PLEX:
   95                                         p = gv_find_plex(sc, arg);
   96                                         gv_lpi(p, sb, *flags);
   97                                         break;
   98                                 case GV_TYPE_SD:
   99                                         s = gv_find_sd(sc, arg);
  100                                         gv_lsi(s, sb, *flags);
  101                                         break;
  102                                 case GV_TYPE_DRIVE:
  103                                         d = gv_find_drive(sc, arg);
  104                                         gv_ldi(d, sb, *flags);
  105                                         break;
  106                                 default:
  107                                         gctl_error(req, "unknown object '%s'",
  108                                             arg);
  109                                         break;
  110                                 }
  111                         }
  112                 } else {
  113                         gv_ld(gp, req, sb);
  114                         sbuf_printf(sb, "\n");
  115                         gv_lv(gp, req, sb);
  116                         sbuf_printf(sb, "\n");
  117                         gv_lp(gp, req, sb);
  118                         sbuf_printf(sb, "\n");
  119                         gv_ls(gp, req, sb);
  120                 }
  121 
  122         /* List drives. */
  123         } else if (!strcmp(cmd, "ld")) {
  124                 if (*argc) {
  125                         for (i = 0; i < *argc; i++) {
  126                                 snprintf(buf, sizeof(buf), "argv%d", i);
  127                                 arg = gctl_get_param(req, buf, NULL);
  128                                 if (arg == NULL)
  129                                         continue;
  130                                 type = gv_object_type(sc, arg);
  131                                 if (type != GV_TYPE_DRIVE) {
  132                                         gctl_error(req, "'%s' is not a drive",
  133                                             arg);
  134                                         continue;
  135                                 } else {
  136                                         d = gv_find_drive(sc, arg);
  137                                         gv_ldi(d, sb, *flags);
  138                                 }
  139                         }
  140                 } else
  141                         gv_ld(gp, req, sb);
  142 
  143         /* List volumes. */
  144         } else if (!strcmp(cmd, "lv")) {
  145                 if (*argc) {
  146                         for (i = 0; i < *argc; i++) {
  147                                 snprintf(buf, sizeof(buf), "argv%d", i);
  148                                 arg = gctl_get_param(req, buf, NULL);
  149                                 if (arg == NULL)
  150                                         continue;
  151                                 type = gv_object_type(sc, arg);
  152                                 if (type != GV_TYPE_VOL) {
  153                                         gctl_error(req, "'%s' is not a volume",
  154                                             arg);
  155                                         continue;
  156                                 } else {
  157                                         v = gv_find_vol(sc, arg);
  158                                         gv_lvi(v, sb, *flags);
  159                                 }
  160                         }
  161                 } else
  162                         gv_lv(gp, req, sb);
  163 
  164         /* List plexes. */
  165         } else if (!strcmp(cmd, "lp")) {
  166                 if (*argc) {
  167                         for (i = 0; i < *argc; i++) {
  168                                 snprintf(buf, sizeof(buf), "argv%d", i);
  169                                 arg = gctl_get_param(req, buf, NULL);
  170                                 if (arg == NULL)
  171                                         continue;
  172                                 type = gv_object_type(sc, arg);
  173                                 if (type != GV_TYPE_PLEX) {
  174                                         gctl_error(req, "'%s' is not a plex",
  175                                             arg);
  176                                         continue;
  177                                 } else {
  178                                         p = gv_find_plex(sc, arg);
  179                                         gv_lpi(p, sb, *flags);
  180                                 }
  181                         }
  182                 } else
  183                         gv_lp(gp, req, sb);
  184 
  185         /* List subdisks. */
  186         } else if (!strcmp(cmd, "ls")) {
  187                 if (*argc) {
  188                         for (i = 0; i < *argc; i++) {
  189                                 snprintf(buf, sizeof(buf), "argv%d", i);
  190                                 arg = gctl_get_param(req, buf, NULL);
  191                                 if (arg == NULL)
  192                                         continue;
  193                                 type = gv_object_type(sc, arg);
  194                                 if (type != GV_TYPE_SD) {
  195                                         gctl_error(req, "'%s' is not a subdisk",
  196                                             arg);
  197                                         continue;
  198                                 } else {
  199                                         s = gv_find_sd(sc, arg);
  200                                         gv_lsi(s, sb, *flags);
  201                                 }
  202                         }
  203                 } else
  204                         gv_ls(gp, req, sb);
  205 
  206         } else
  207                 gctl_error(req, "unknown command '%s'", cmd);
  208 
  209         sbuf_finish(sb);
  210         gctl_set_param(req, "config", sbuf_data(sb), sbuf_len(sb) + 1);
  211         sbuf_delete(sb);
  212 }
  213 
  214 /* List one or more volumes. */
  215 void
  216 gv_lv(struct g_geom *gp, struct gctl_req *req, struct sbuf *sb)
  217 {
  218         struct gv_softc *sc;
  219         struct gv_volume *v;
  220         int i, *flags;
  221 
  222         sc = gp->softc;
  223         i = 0;
  224 
  225         LIST_FOREACH(v, &sc->volumes, volume)
  226                 i++;
  227         
  228         sbuf_printf(sb, "%d volume%s:\n", i, i == 1 ? "" : "s");
  229 
  230         if (i) {
  231                 flags = gctl_get_paraml(req, "flags", sizeof(*flags));
  232                 LIST_FOREACH(v, &sc->volumes, volume)
  233                         gv_lvi(v, sb, *flags);
  234         }
  235 }
  236 
  237 /* List a single volume. */
  238 void
  239 gv_lvi(struct gv_volume *v, struct sbuf *sb, int flags)
  240 {
  241         struct gv_plex *p;
  242         int i;
  243 
  244         if (flags & GV_FLAG_V) {
  245                 sbuf_printf(sb, "Volume %s:\tSize: %jd bytes (%jd MB)\n",
  246                     v->name, (intmax_t)v->size, (intmax_t)v->size / MEGABYTE);
  247                 sbuf_printf(sb, "\t\tState: %s\n", gv_volstate(v->state));
  248         } else {
  249                 sbuf_printf(sb, "V %-21s State: %s\tPlexes: %7d\tSize: %s\n",
  250                     v->name, gv_volstate(v->state), v->plexcount,
  251                     gv_roughlength(v->size, 0));
  252         }
  253 
  254         if (flags & GV_FLAG_VV) {
  255                 i = 0;
  256                 LIST_FOREACH(p, &v->plexes, in_volume) {
  257                         sbuf_printf(sb, "\t\tPlex %2d:\t%s\t(%s), %s\n", i,
  258                             p->name, gv_plexstate(p->state),
  259                             gv_roughlength(p->size, 0));
  260                         i++;
  261                 }
  262         }
  263 
  264         if (flags & GV_FLAG_R) {
  265                 LIST_FOREACH(p, &v->plexes, in_volume)
  266                         gv_lpi(p, sb, flags);
  267         }
  268 }
  269 
  270 /* List one or more plexes. */
  271 void
  272 gv_lp(struct g_geom *gp, struct gctl_req *req, struct sbuf *sb)
  273 {
  274         struct gv_softc *sc;
  275         struct gv_plex *p;
  276         int i, *flags;
  277 
  278         sc = gp->softc;
  279         i = 0;
  280 
  281         LIST_FOREACH(p, &sc->plexes, plex)
  282                 i++;
  283 
  284         sbuf_printf(sb, "%d plex%s:\n", i, i == 1 ? "" : "es");
  285 
  286         if (i) {
  287                 flags = gctl_get_paraml(req, "flags", sizeof(*flags));
  288                 LIST_FOREACH(p, &sc->plexes, plex)
  289                         gv_lpi(p, sb, *flags);
  290         }
  291 }
  292 
  293 /* List a single plex. */
  294 void
  295 gv_lpi(struct gv_plex *p, struct sbuf *sb, int flags)
  296 {
  297         struct gv_sd *s;
  298         int i;
  299 
  300         if (flags & GV_FLAG_V) {
  301                 sbuf_printf(sb, "Plex %s:\tSize:\t%9jd bytes (%jd MB)\n",
  302                     p->name, (intmax_t)p->size, (intmax_t)p->size / MEGABYTE);
  303                 sbuf_printf(sb, "\t\tSubdisks: %8d\n", p->sdcount);
  304                 sbuf_printf(sb, "\t\tState: %s\n", gv_plexstate(p->state));
  305                 if ((p->flags & GV_PLEX_SYNCING) ||
  306                     (p->flags & GV_PLEX_GROWING) ||
  307                     (p->flags & GV_PLEX_REBUILDING)) {
  308                         sbuf_printf(sb, "\t\tSynced: ");
  309                         sbuf_printf(sb, "%16jd bytes (%d%%)\n",
  310                             (intmax_t)p->synced,
  311                             (p->size > 0) ? (int)((p->synced * 100) / p->size) :
  312                             0);
  313                 }
  314                 sbuf_printf(sb, "\t\tOrganization: %s", gv_plexorg(p->org));
  315                 if (gv_is_striped(p)) {
  316                         sbuf_printf(sb, "\tStripe size: %s\n",
  317                             gv_roughlength(p->stripesize, 1));
  318                 }
  319                 sbuf_printf(sb, "\t\tFlags: %d\n", p->flags);
  320                 if (p->vol_sc != NULL) {
  321                         sbuf_printf(sb, "\t\tPart of volume %s\n", p->volume);
  322                 }
  323         } else {
  324                 sbuf_printf(sb, "P %-18s %2s State: ", p->name,
  325                 gv_plexorg_short(p->org));
  326                 if ((p->flags & GV_PLEX_SYNCING) ||
  327                     (p->flags & GV_PLEX_GROWING) ||
  328                     (p->flags & GV_PLEX_REBUILDING)) {
  329                         sbuf_printf(sb, "S %d%%\t", (int)((p->synced * 100) /
  330                             p->size));
  331                 } else {
  332                         sbuf_printf(sb, "%s\t", gv_plexstate(p->state));
  333                 }
  334                 sbuf_printf(sb, "Subdisks: %5d\tSize: %s\n", p->sdcount,
  335                     gv_roughlength(p->size, 0));
  336         }
  337 
  338         if (flags & GV_FLAG_VV) {
  339                 i = 0;
  340                 LIST_FOREACH(s, &p->subdisks, in_plex) {
  341                         sbuf_printf(sb, "\t\tSubdisk %d:\t%s\n", i, s->name);
  342                         sbuf_printf(sb, "\t\t  state: %s\tsize %11jd "
  343                             "(%jd MB)\n", gv_sdstate(s->state),
  344                             (intmax_t)s->size, (intmax_t)s->size / MEGABYTE);
  345                         if (p->org == GV_PLEX_CONCAT) {
  346                                 sbuf_printf(sb, "\t\t\toffset %9jd (0x%jx)\n",
  347                                     (intmax_t)s->plex_offset,
  348                                     (intmax_t)s->plex_offset);
  349                         }
  350                         i++;
  351                 }
  352         }
  353 
  354         if (flags & GV_FLAG_R) {
  355                 LIST_FOREACH(s, &p->subdisks, in_plex)
  356                         gv_lsi(s, sb, flags);
  357         }
  358 }
  359 
  360 /* List one or more subdisks. */
  361 void
  362 gv_ls(struct g_geom *gp, struct gctl_req *req, struct sbuf *sb)
  363 {
  364         struct gv_softc *sc;
  365         struct gv_sd *s;
  366         int i, *flags;
  367 
  368         sc = gp->softc;
  369         i = 0;
  370 
  371         LIST_FOREACH(s, &sc->subdisks, sd)
  372                 i++;
  373         
  374         sbuf_printf(sb, "%d subdisk%s:\n", i, i == 1 ? "" : "s");
  375 
  376         if (i) {
  377                 flags = gctl_get_paraml(req, "flags", sizeof(*flags));
  378                 LIST_FOREACH(s, &sc->subdisks, sd)
  379                         gv_lsi(s, sb, *flags);
  380         }
  381 }
  382 
  383 /* List a single subdisk. */
  384 void
  385 gv_lsi(struct gv_sd *s, struct sbuf *sb, int flags)
  386 {
  387         if (flags & GV_FLAG_V) {
  388                 sbuf_printf(sb, "Subdisk %s:\n", s->name);
  389                 sbuf_printf(sb, "\t\tSize: %16jd bytes (%jd MB)\n",
  390                     (intmax_t)s->size, (intmax_t)s->size / MEGABYTE);
  391                 sbuf_printf(sb, "\t\tState: %s\n", gv_sdstate(s->state));
  392 
  393                 if (s->state == GV_SD_INITIALIZING ||
  394                     s->state == GV_SD_REVIVING) {
  395                         if (s->state == GV_SD_INITIALIZING)
  396                                 sbuf_printf(sb, "\t\tInitialized: ");
  397                         else
  398                                 sbuf_printf(sb, "\t\tRevived: ");
  399                                 
  400                         sbuf_printf(sb, "%16jd bytes (%d%%)\n",
  401                             (intmax_t)s->initialized,
  402                             (int)((s->initialized * 100) / s->size));
  403                 }
  404 
  405                 if (s->plex_sc != NULL) {
  406                         sbuf_printf(sb, "\t\tPlex %s at offset %jd (%s)\n",
  407                             s->plex, (intmax_t)s->plex_offset,
  408                             gv_roughlength(s->plex_offset, 1));
  409                 }
  410 
  411                 sbuf_printf(sb, "\t\tDrive %s (%s) at offset %jd (%s)\n",
  412                     s->drive,
  413                     s->drive_sc == NULL ? "*missing*" : s->drive_sc->name,
  414                     (intmax_t)s->drive_offset,
  415                     gv_roughlength(s->drive_offset, 1));
  416                 sbuf_printf(sb, "\t\tFlags: %d\n", s->flags);
  417         } else {
  418                 sbuf_printf(sb, "S %-21s State: ", s->name);
  419                 if (s->state == GV_SD_INITIALIZING ||
  420                     s->state == GV_SD_REVIVING) {
  421                         if (s->state == GV_SD_INITIALIZING)
  422                                 sbuf_printf(sb, "I ");
  423                         else
  424                                 sbuf_printf(sb, "R ");
  425                         sbuf_printf(sb, "%d%%\t",
  426                             (int)((s->initialized * 100) / s->size));
  427                 } else {
  428                         sbuf_printf(sb, "%s\t", gv_sdstate(s->state));
  429                 }
  430                 sbuf_printf(sb, "D: %-12s Size: %s\n", s->drive,
  431                     gv_roughlength(s->size, 0));
  432         }
  433 }
  434 
  435 /* List one or more drives. */
  436 void
  437 gv_ld(struct g_geom *gp, struct gctl_req *req, struct sbuf *sb)
  438 {
  439         struct gv_softc *sc;
  440         struct gv_drive *d;
  441         int i, *flags;
  442 
  443         sc = gp->softc;
  444         i = 0;
  445 
  446         LIST_FOREACH(d, &sc->drives, drive)
  447                 i++;
  448         
  449         sbuf_printf(sb, "%d drive%s:\n", i, i == 1 ? "" : "s");
  450 
  451         if (i) {
  452                 flags = gctl_get_paraml(req, "flags", sizeof(*flags));
  453                 LIST_FOREACH(d, &sc->drives, drive)
  454                         gv_ldi(d, sb, *flags);
  455         }
  456 }
  457 
  458 /* List a single drive. */
  459 void
  460 gv_ldi(struct gv_drive *d, struct sbuf *sb, int flags)
  461 {
  462         struct gv_freelist *fl;
  463         struct gv_sd *s;
  464 
  465         /* Verbose listing. */
  466         if (flags & GV_FLAG_V) {
  467                 sbuf_printf(sb, "Drive %s:\tDevice %s\n", d->name, d->device);
  468                 sbuf_printf(sb, "\t\tSize: %16jd bytes (%jd MB)\n",
  469                     (intmax_t)d->size, (intmax_t)d->size / MEGABYTE);
  470                 sbuf_printf(sb, "\t\tUsed: %16jd bytes (%jd MB)\n",
  471                     (intmax_t)d->size - d->avail,
  472                     (intmax_t)(d->size - d->avail) / MEGABYTE);
  473                 sbuf_printf(sb, "\t\tAvailable: %11jd bytes (%jd MB)\n",
  474                     (intmax_t)d->avail, (intmax_t)d->avail / MEGABYTE);
  475                 sbuf_printf(sb, "\t\tState: %s\n", gv_drivestate(d->state));
  476                 sbuf_printf(sb, "\t\tFlags: %d\n", d->flags);
  477 
  478                 /* Be very verbose. */
  479                 if (flags & GV_FLAG_VV) {
  480                         sbuf_printf(sb, "\t\tFree list contains %d entries:\n",
  481                             d->freelist_entries);
  482                         sbuf_printf(sb, "\t\t   Offset\t     Size\n");
  483                         LIST_FOREACH(fl, &d->freelist, freelist)
  484                                 sbuf_printf(sb, "\t\t%9jd\t%9jd\n",
  485                                     (intmax_t)fl->offset, (intmax_t)fl->size);
  486                 }
  487         } else {
  488                 sbuf_printf(sb, "D %-21s State: %s\t/dev/%s\tA: %jd/%jd MB "
  489                     "(%d%%)\n", d->name, gv_drivestate(d->state), d->device,
  490                     (intmax_t)d->avail / MEGABYTE, (intmax_t)d->size / MEGABYTE,
  491                     d->size > 0 ? (int)((d->avail * 100) / d->size) : 0);
  492         }
  493 
  494         /* Recursive listing. */
  495         if (flags & GV_FLAG_R) {
  496                 LIST_FOREACH(s, &d->subdisks, from_drive)
  497                         gv_lsi(s, sb, flags);
  498         }
  499 }

Cache object: 7f594d9090106e2d41f620b981c57e2b


[ 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.