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/libzfsbootenv/lzbe_device.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  * This file and its contents are supplied under the terms of the
    3  * Common Development and Distribution License ("CDDL"), version 1.0.
    4  * You may only use this file in accordance with the terms of version
    5  * 1.0 of the CDDL.
    6  *
    7  * A full copy of the text of the CDDL should have accompanied this
    8  * source.  A copy of the CDDL is also available via the Internet at
    9  * http://www.illumos.org/license/CDDL.
   10  */
   11 /*
   12  * Copyright 2020 Toomas Soome <tsoome@me.com>
   13  */
   14 
   15 #include <sys/types.h>
   16 #include <string.h>
   17 #include <libzfs.h>
   18 #include <libzfsbootenv.h>
   19 #include <sys/zfs_bootenv.h>
   20 #include <sys/vdev_impl.h>
   21 
   22 /*
   23  * Store device name to zpool label bootenv area.
   24  * This call will set bootenv version to VB_NVLIST, if bootenv currently
   25  * does contain other version, then old data will be replaced.
   26  */
   27 int
   28 lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device)
   29 {
   30         libzfs_handle_t *hdl;
   31         zpool_handle_t *zphdl;
   32         nvlist_t *nv;
   33         char *descriptor;
   34         uint64_t version;
   35         int rv = -1;
   36 
   37         if (pool == NULL || *pool == '\0')
   38                 return (rv);
   39 
   40         if ((hdl = libzfs_init()) == NULL)
   41                 return (rv);
   42 
   43         zphdl = zpool_open(hdl, pool);
   44         if (zphdl == NULL) {
   45                 libzfs_fini(hdl);
   46                 return (rv);
   47         }
   48 
   49         switch (flag) {
   50         case lzbe_add:
   51                 rv = zpool_get_bootenv(zphdl, &nv);
   52                 if (rv == 0) {
   53                         /*
   54                          * We got the nvlist, check for version.
   55                          * if version is missing or is not VB_NVLIST,
   56                          * create new list.
   57                          */
   58                         rv = nvlist_lookup_uint64(nv, BOOTENV_VERSION,
   59                             &version);
   60                         if (rv == 0 && version == VB_NVLIST)
   61                                 break;
   62 
   63                         /* Drop this nvlist */
   64                         fnvlist_free(nv);
   65                 }
   66                 zfs_fallthrough;
   67         case lzbe_replace:
   68                 nv = fnvlist_alloc();
   69                 break;
   70         default:
   71                 return (rv);
   72         }
   73 
   74         /* version is mandatory */
   75         fnvlist_add_uint64(nv, BOOTENV_VERSION, VB_NVLIST);
   76 
   77         rv = 0;
   78         /*
   79          * If device name is empty, remove boot device configuration.
   80          */
   81         if ((device == NULL || *device == '\0')) {
   82                 if (nvlist_exists(nv, OS_BOOTONCE))
   83                         fnvlist_remove(nv, OS_BOOTONCE);
   84         } else {
   85                 /*
   86                  * Use device name directly if it does start with
   87                  * prefix "zfs:". Otherwise, add prefix and suffix.
   88                  */
   89                 if (strncmp(device, "zfs:", 4) == 0) {
   90                         fnvlist_add_string(nv, OS_BOOTONCE, device);
   91                 } else {
   92                         if (asprintf(&descriptor, "zfs:%s:", device) > 0) {
   93                                 fnvlist_add_string(nv, OS_BOOTONCE, descriptor);
   94                                 free(descriptor);
   95                         } else
   96                                 rv = ENOMEM;
   97                 }
   98         }
   99         if (rv == 0)
  100                 rv = zpool_set_bootenv(zphdl, nv);
  101         if (rv != 0)
  102                 fprintf(stderr, "%s\n", libzfs_error_description(hdl));
  103 
  104         fnvlist_free(nv);
  105         zpool_close(zphdl);
  106         libzfs_fini(hdl);
  107         return (rv);
  108 }
  109 
  110 /*
  111  * Return boot device name from bootenv, if set.
  112  */
  113 int
  114 lzbe_get_boot_device(const char *pool, char **device)
  115 {
  116         libzfs_handle_t *hdl;
  117         zpool_handle_t *zphdl;
  118         nvlist_t *nv;
  119         char *val;
  120         int rv = -1;
  121 
  122         if (pool == NULL || *pool == '\0' || device == NULL)
  123                 return (rv);
  124 
  125         if ((hdl = libzfs_init()) == NULL)
  126                 return (rv);
  127 
  128         zphdl = zpool_open(hdl, pool);
  129         if (zphdl == NULL) {
  130                 libzfs_fini(hdl);
  131                 return (rv);
  132         }
  133 
  134         rv = zpool_get_bootenv(zphdl, &nv);
  135         if (rv == 0) {
  136                 rv = nvlist_lookup_string(nv, OS_BOOTONCE, &val);
  137                 if (rv == 0) {
  138                         /*
  139                          * zfs device descriptor is in form of "zfs:dataset:",
  140                          * we only do need dataset name.
  141                          */
  142                         if (strncmp(val, "zfs:", 4) == 0) {
  143                                 val += 4;
  144                                 val = strdup(val);
  145                                 if (val != NULL) {
  146                                         size_t len = strlen(val);
  147 
  148                                         if (val[len - 1] == ':')
  149                                                 val[len - 1] = '\0';
  150                                         *device = val;
  151                                 } else {
  152                                         rv = ENOMEM;
  153                                 }
  154                         } else {
  155                                 rv = EINVAL;
  156                         }
  157                 }
  158                 nvlist_free(nv);
  159         }
  160 
  161         zpool_close(zphdl);
  162         libzfs_fini(hdl);
  163         return (rv);
  164 }

Cache object: 1a0988c757a6f78e235214b8248ffe4c


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