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

Cache object: a016de159942518a1ae23fd17ed2fc4c


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