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/contrib/openzfs/lib/libzutil/os/freebsd/zutil_import_os.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  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 
   22 /*
   23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   24  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
   25  * Copyright 2015 RackTop Systems.
   26  * Copyright 2016 Nexenta Systems, Inc.
   27  */
   28 
   29 /*
   30  * Pool import support functions.
   31  *
   32  * To import a pool, we rely on reading the configuration information from the
   33  * ZFS label of each device.  If we successfully read the label, then we
   34  * organize the configuration information in the following hierarchy:
   35  *
   36  *      pool guid -> toplevel vdev guid -> label txg
   37  *
   38  * Duplicate entries matching this same tuple will be discarded.  Once we have
   39  * examined every device, we pick the best label txg config for each toplevel
   40  * vdev.  We then arrange these toplevel vdevs into a complete pool config, and
   41  * update any paths that have changed.  Finally, we attempt to import the pool
   42  * using our derived config, and record the results.
   43  */
   44 
   45 #include <sys/types.h>
   46 #include <sys/disk.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/stat.h>
   49 #include <sys/sysctl.h>
   50 
   51 #include <aio.h>
   52 #include <ctype.h>
   53 #include <dirent.h>
   54 #include <errno.h>
   55 #include <libintl.h>
   56 #include <libgen.h>
   57 #include <stddef.h>
   58 #include <stdlib.h>
   59 #include <string.h>
   60 #include <unistd.h>
   61 #include <fcntl.h>
   62 
   63 #include <sys/efi_partition.h>
   64 #include <thread_pool.h>
   65 #include <libgeom.h>
   66 
   67 #include <sys/vdev_impl.h>
   68 
   69 #include <libzutil.h>
   70 
   71 #include "zutil_import.h"
   72 
   73 /*
   74  * Update a leaf vdev's persistent device strings
   75  *
   76  * - only applies for a dedicated leaf vdev (aka whole disk)
   77  * - updated during pool create|add|attach|import
   78  * - used for matching device matching during auto-{online,expand,replace}
   79  * - stored in a leaf disk config label (i.e. alongside 'path' NVP)
   80  * - these strings are currently not used in kernel (i.e. for vdev_disk_open)
   81  *
   82  * On FreeBSD we currently just strip devid and phys_path to avoid confusion.
   83  */
   84 void
   85 update_vdev_config_dev_strs(nvlist_t *nv)
   86 {
   87         (void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);
   88         (void) nvlist_remove_all(nv, ZPOOL_CONFIG_PHYS_PATH);
   89 }
   90 
   91 /*
   92  * Do not even look at these devices.
   93  */
   94 static const char * const excluded_devs[] = {
   95         "nfslock",
   96         "sequencer",
   97         "zfs",
   98 };
   99 #define EXCLUDED_DIR            "/dev/"
  100 #define EXCLUDED_DIR_LEN        5
  101 
  102 void
  103 zpool_open_func(void *arg)
  104 {
  105         rdsk_node_t *rn = arg;
  106         struct stat64 statbuf;
  107         nvlist_t *config;
  108         size_t i;
  109         int num_labels;
  110         int fd;
  111         off_t mediasize = 0;
  112 
  113         /*
  114          * Do not even look at excluded devices.
  115          */
  116         if (strncmp(rn->rn_name, EXCLUDED_DIR, EXCLUDED_DIR_LEN) == 0) {
  117                 char *name = rn->rn_name + EXCLUDED_DIR_LEN;
  118                 for (i = 0; i < nitems(excluded_devs); ++i) {
  119                         const char *excluded_name = excluded_devs[i];
  120                         size_t len = strlen(excluded_name);
  121                         if (strncmp(name, excluded_name, len) == 0) {
  122                                 return;
  123                         }
  124                 }
  125         }
  126 
  127         /*
  128          * O_NONBLOCK so we don't hang trying to open things like serial ports.
  129          */
  130         if ((fd = open(rn->rn_name, O_RDONLY|O_NONBLOCK|O_CLOEXEC)) < 0)
  131                 return;
  132 
  133         /*
  134          * Ignore failed stats.
  135          */
  136         if (fstat64(fd, &statbuf) != 0)
  137                 goto out;
  138         /*
  139          * We only want regular files, character devs and block devs.
  140          */
  141         if (S_ISREG(statbuf.st_mode)) {
  142                 /* Check if this file is too small to hold a zpool. */
  143                 if (statbuf.st_size < SPA_MINDEVSIZE) {
  144                         goto out;
  145                 }
  146         } else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) {
  147                 /* Check if this device is too small to hold a zpool. */
  148                 if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) != 0 ||
  149                     mediasize < SPA_MINDEVSIZE) {
  150                         goto out;
  151                 }
  152         } else {
  153                 goto out;
  154         }
  155 
  156         if (zpool_read_label(fd, &config, &num_labels) != 0)
  157                 goto out;
  158         if (num_labels == 0) {
  159                 nvlist_free(config);
  160                 goto out;
  161         }
  162 
  163         rn->rn_config = config;
  164         rn->rn_num_labels = num_labels;
  165 
  166         /* TODO: Reuse labelpaths logic from Linux? */
  167 out:
  168         (void) close(fd);
  169 }
  170 
  171 static const char * const
  172 zpool_default_import_path[] = {
  173         "/dev"
  174 };
  175 
  176 const char * const *
  177 zpool_default_search_paths(size_t *count)
  178 {
  179         *count = nitems(zpool_default_import_path);
  180         return (zpool_default_import_path);
  181 }
  182 
  183 int
  184 zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
  185     avl_tree_t **slice_cache)
  186 {
  187         const char *oid = "vfs.zfs.vol.recursive";
  188         char *end, path[MAXPATHLEN];
  189         rdsk_node_t *slice;
  190         struct gmesh mesh;
  191         struct gclass *mp;
  192         struct ggeom *gp;
  193         struct gprovider *pp;
  194         avl_index_t where;
  195         int error, value;
  196         size_t pathleft, size = sizeof (value);
  197         boolean_t skip_zvols = B_FALSE;
  198 
  199         end = stpcpy(path, "/dev/");
  200         pathleft = &path[sizeof (path)] - end;
  201 
  202         error = geom_gettree(&mesh);
  203         if (error != 0)
  204                 return (error);
  205 
  206         if (sysctlbyname(oid, &value, &size, NULL, 0) == 0 && value == 0)
  207                 skip_zvols = B_TRUE;
  208 
  209         *slice_cache = zutil_alloc(hdl, sizeof (avl_tree_t));
  210         avl_create(*slice_cache, slice_cache_compare, sizeof (rdsk_node_t),
  211             offsetof(rdsk_node_t, rn_node));
  212 
  213         LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
  214                 if (skip_zvols && strcmp(mp->lg_name, "ZFS::ZVOL") == 0)
  215                         continue;
  216                 LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
  217                         LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
  218                                 strlcpy(end, pp->lg_name, pathleft);
  219                                 slice = zutil_alloc(hdl, sizeof (rdsk_node_t));
  220                                 slice->rn_name = zutil_strdup(hdl, path);
  221                                 slice->rn_vdev_guid = 0;
  222                                 slice->rn_lock = lock;
  223                                 slice->rn_avl = *slice_cache;
  224                                 slice->rn_hdl = hdl;
  225                                 slice->rn_labelpaths = B_FALSE;
  226                                 slice->rn_order = IMPORT_ORDER_DEFAULT;
  227 
  228                                 pthread_mutex_lock(lock);
  229                                 if (avl_find(*slice_cache, slice, &where)) {
  230                                         free(slice->rn_name);
  231                                         free(slice);
  232                                 } else {
  233                                         avl_insert(*slice_cache, slice, where);
  234                                 }
  235                                 pthread_mutex_unlock(lock);
  236                         }
  237                 }
  238         }
  239 
  240         geom_deletetree(&mesh);
  241 
  242         return (0);
  243 }
  244 
  245 int
  246 zfs_dev_flush(int fd)
  247 {
  248         (void) fd;
  249         return (0);
  250 }
  251 
  252 void
  253 update_vdevs_config_dev_sysfs_path(nvlist_t *config)
  254 {
  255         (void) config;
  256 }

Cache object: a5784d1dddc0b94cd789348439864636


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