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_rename.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) 2005 Chris Jones
    3  *  All rights reserved.
    4  *
    5  * This software was developed for the FreeBSD Project by Chris Jones
    6  * thanks to the support of Google's Summer of Code program and
    7  * mentoring by Lukas Ertl.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/10.0/sys/geom/vinum/geom_vinum_rename.c 213318 2010-10-01 06:12:13Z lulf $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/libkern.h>
   37 #include <sys/malloc.h>
   38 
   39 #include <geom/geom.h>
   40 #include <geom/vinum/geom_vinum_var.h>
   41 #include <geom/vinum/geom_vinum.h>
   42 
   43 void
   44 gv_rename(struct g_geom *gp, struct gctl_req *req)
   45 {
   46         struct gv_softc *sc;
   47         struct gv_volume *v;
   48         struct gv_plex *p;
   49         struct gv_sd *s;
   50         struct gv_drive *d;
   51         char *newname, *object, *name;
   52         int *flags, type;
   53 
   54         sc = gp->softc;
   55 
   56         flags = gctl_get_paraml(req, "flags", sizeof(*flags));
   57         if (flags == NULL) {
   58                 gctl_error(req, "no flags given");
   59                 return;
   60         }
   61 
   62         newname = gctl_get_param(req, "newname", NULL);
   63         if (newname == NULL) {
   64                 gctl_error(req, "no new name given");
   65                 return;
   66         }
   67 
   68         object = gctl_get_param(req, "object", NULL);
   69         if (object == NULL) {
   70                 gctl_error(req, "no object given");
   71                 return;
   72         }
   73 
   74         type = gv_object_type(sc, object);
   75         switch (type) {
   76         case GV_TYPE_VOL:
   77                 v = gv_find_vol(sc, object);
   78                 if (v == NULL)  {
   79                         gctl_error(req, "unknown volume '%s'", object);
   80                         return;
   81                 }
   82                 name = g_malloc(GV_MAXVOLNAME, M_WAITOK | M_ZERO);
   83                 strlcpy(name, newname, GV_MAXVOLNAME);
   84                 gv_post_event(sc, GV_EVENT_RENAME_VOL, v, name, *flags, 0);
   85                 break;
   86         case GV_TYPE_PLEX:
   87                 p = gv_find_plex(sc, object);
   88                 if (p == NULL) {
   89                         gctl_error(req, "unknown plex '%s'", object);
   90                         return;
   91                 }
   92                 name = g_malloc(GV_MAXPLEXNAME, M_WAITOK | M_ZERO);
   93                 strlcpy(name, newname, GV_MAXPLEXNAME);
   94                 gv_post_event(sc, GV_EVENT_RENAME_PLEX, p, name, *flags, 0);
   95                 break;
   96         case GV_TYPE_SD:
   97                 s = gv_find_sd(sc, object);
   98                 if (s == NULL) {
   99                         gctl_error(req, "unknown subdisk '%s'", object);
  100                         return;
  101                 }
  102                 name = g_malloc(GV_MAXSDNAME, M_WAITOK | M_ZERO);
  103                 strlcpy(name, newname, GV_MAXSDNAME);
  104                 gv_post_event(sc, GV_EVENT_RENAME_SD, s, name, *flags, 0);
  105                 break;
  106         case GV_TYPE_DRIVE:
  107                 d = gv_find_drive(sc, object);
  108                 if (d == NULL) {
  109                         gctl_error(req, "unknown drive '%s'", object);
  110                         return;
  111                 }
  112                 name = g_malloc(GV_MAXDRIVENAME, M_WAITOK | M_ZERO);
  113                 strlcpy(name, newname, GV_MAXDRIVENAME);
  114                 gv_post_event(sc, GV_EVENT_RENAME_DRIVE, d, name, *flags, 0);
  115                 break;
  116         default:
  117                 gctl_error(req, "unknown object '%s'", object);
  118                 return;
  119         }
  120 }
  121 
  122 int
  123 gv_rename_drive(struct gv_softc *sc, struct gv_drive *d, char *newname,
  124     int flags)
  125 {
  126         struct gv_sd *s;
  127 
  128         KASSERT(d != NULL, ("gv_rename_drive: NULL d"));
  129 
  130         if (gv_object_type(sc, newname) != GV_ERR_NOTFOUND) {
  131                 G_VINUM_DEBUG(1, "drive name '%s' already in use", newname);
  132                 return (GV_ERR_NAMETAKEN);
  133         }
  134 
  135         strlcpy(d->name, newname, sizeof(d->name));
  136         if (d->hdr != NULL)
  137                 strlcpy(d->hdr->label.name, newname, sizeof(d->hdr->label.name));
  138 
  139         LIST_FOREACH(s, &d->subdisks, from_drive)
  140                 strlcpy(s->drive, d->name, sizeof(s->drive));
  141 
  142         return (0);
  143 }
  144 
  145 int
  146 gv_rename_plex(struct gv_softc *sc, struct gv_plex *p, char *newname, int flags)
  147 {
  148         char newsd[GV_MAXSDNAME];
  149         struct gv_sd *s;
  150         char *ptr;
  151         int err;
  152 
  153         KASSERT(p != NULL, ("gv_rename_plex: NULL p"));
  154 
  155         if (gv_object_type(sc, newname) != GV_ERR_NOTFOUND) {
  156                 G_VINUM_DEBUG(1, "plex name '%s' already in use", newname);
  157                 return (GV_ERR_NAMETAKEN);
  158         }
  159 
  160         /*
  161          * Locate the plex number part of the plex names.
  162          * XXX: might be a good idea to sanitize input a bit more
  163          */
  164         ptr = strrchr(newname, '.');
  165         if (ptr == NULL) {
  166                 G_VINUM_DEBUG(0, "proposed plex name '%s' is not a valid plex "
  167                     "name", newname);
  168                 return (GV_ERR_INVNAME);
  169         }
  170 
  171         strlcpy(p->name, newname, sizeof(p->name));
  172 
  173         /* Fix up references and potentially rename subdisks. */
  174         LIST_FOREACH(s, &p->subdisks, in_plex) {
  175                 strlcpy(s->plex, p->name, sizeof(s->plex));
  176                 if (flags & GV_FLAG_R) {
  177                         /*
  178                          * Look for the two last dots in the string, and assume
  179                          * that the old value was ok.
  180                          */
  181                         ptr = strrchr(s->name, '.');
  182                         if (ptr == NULL)
  183                                 return (GV_ERR_INVNAME);
  184                         ptr++;
  185                         snprintf(newsd, sizeof(newsd), "%s.%s", p->name, ptr);
  186                         err = gv_rename_sd(sc, s, newsd, flags);
  187                         if (err)
  188                                 return (err);
  189                 }
  190         }
  191         return (0);
  192 }
  193 
  194 /*
  195  * gv_rename_sd: renames a subdisk.  Note that the 'flags' argument is ignored,
  196  * since there are no structures below a subdisk.  Similarly, we don't have to
  197  * clean up any references elsewhere to the subdisk's name.
  198  */
  199 int
  200 gv_rename_sd(struct gv_softc *sc, struct gv_sd *s, char *newname, int flags)
  201 {
  202         char *dot1, *dot2;
  203 
  204         KASSERT(s != NULL, ("gv_rename_sd: NULL s"));
  205 
  206         if (gv_object_type(sc, newname) != GV_ERR_NOTFOUND) {
  207                 G_VINUM_DEBUG(1, "subdisk name %s already in use", newname);
  208                 return (GV_ERR_NAMETAKEN);
  209         }
  210 
  211         /* Locate the sd number part of the sd names. */
  212         dot1 = strchr(newname, '.');
  213         if (dot1 == NULL || (dot2 = strchr(dot1 +  1, '.')) == NULL) {
  214                 G_VINUM_DEBUG(0, "proposed sd name '%s' is not a valid sd name",
  215                     newname);
  216                 return (GV_ERR_INVNAME);
  217         }
  218         strlcpy(s->name, newname, sizeof(s->name));
  219         return (0);
  220 }
  221 
  222 int
  223 gv_rename_vol(struct gv_softc *sc, struct gv_volume *v, char *newname,
  224     int flags)
  225 {
  226         struct g_provider *pp;
  227         struct gv_plex *p;
  228         char newplex[GV_MAXPLEXNAME], *ptr;
  229         int err;
  230 
  231         KASSERT(v != NULL, ("gv_rename_vol: NULL v"));
  232         pp = v->provider;
  233         KASSERT(pp != NULL, ("gv_rename_vol: NULL pp"));
  234 
  235         if (gv_object_type(sc, newname) != GV_ERR_NOTFOUND) {
  236                 G_VINUM_DEBUG(1, "volume name %s already in use", newname);
  237                 return (GV_ERR_NAMETAKEN);
  238         }
  239 
  240         /* Rename the volume. */
  241         strlcpy(v->name, newname, sizeof(v->name));
  242 
  243         /* Fix up references and potentially rename plexes. */
  244         LIST_FOREACH(p, &v->plexes, in_volume) {
  245                 strlcpy(p->volume, v->name, sizeof(p->volume));
  246                 if (flags & GV_FLAG_R) {
  247                         /*
  248                          * Look for the last dot in the string, and assume that
  249                          * the old value was ok.
  250                          */
  251                         ptr = strrchr(p->name, '.');
  252                         ptr++;
  253                         snprintf(newplex, sizeof(newplex), "%s.%s", v->name, ptr);
  254                         err = gv_rename_plex(sc, p, newplex, flags);
  255                         if (err)
  256                                 return (err);
  257                 }
  258         }
  259 
  260         return (0);
  261 }

Cache object: 2411b2a26345cb2eab1267aecc59e564


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