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

Cache object: cdb02a2cf4aacb57136bfeda3d80a528


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