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

Cache object: 13b7640858213d42eddeed7c70c6e02b


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