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

Cache object: a7e06e586886c402788041e32ac6b38d


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