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 http://www.opensolaris.org/os/licensing. 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 #include <alloca.h> 24 #include <errno.h> 25 #include <fcntl.h> 26 #include <libintl.h> 27 #include <math.h> 28 #include <poll.h> 29 #include <stdarg.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <strings.h> 33 #include <sys/inotify.h> 34 #include <sys/mntent.h> 35 #include <sys/mnttab.h> 36 #include <sys/stat.h> 37 #include <sys/timerfd.h> 38 #include <sys/types.h> 39 #include <sys/wait.h> 40 #include <unistd.h> 41 42 #include <libzfs.h> 43 #include <libzfs_core.h> 44 45 #include "../../libzfs_impl.h" 46 #include "zfs_prop.h" 47 #include <libzutil.h> 48 #include <sys/zfs_sysfs.h> 49 50 #define ZDIFF_SHARESDIR "/.zfs/shares/" 51 52 int 53 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc) 54 { 55 return (ioctl(hdl->libzfs_fd, request, zc)); 56 } 57 58 const char * 59 libzfs_error_init(int error) 60 { 61 switch (error) { 62 case ENXIO: 63 return (dgettext(TEXT_DOMAIN, "The ZFS modules are not " 64 "loaded.\nTry running 'modprobe zfs' as root " 65 "to load them.")); 66 case ENOENT: 67 return (dgettext(TEXT_DOMAIN, "/dev/zfs and /proc/self/mounts " 68 "are required.\nTry running 'udevadm trigger' and 'mount " 69 "-t proc proc /proc' as root.")); 70 case ENOEXEC: 71 return (dgettext(TEXT_DOMAIN, "The ZFS modules cannot be " 72 "auto-loaded.\nTry running 'modprobe zfs' as " 73 "root to manually load them.")); 74 case EACCES: 75 return (dgettext(TEXT_DOMAIN, "Permission denied the " 76 "ZFS utilities must be run as root.")); 77 default: 78 return (dgettext(TEXT_DOMAIN, "Failed to initialize the " 79 "libzfs library.")); 80 } 81 } 82 83 /* 84 * zfs(4) is loaded by udev if there's a fstype=zfs device present, 85 * but if there isn't, load them automatically; 86 * always wait for ZFS_DEV to appear via udev. 87 * 88 * Environment variables: 89 * - ZFS_MODULE_TIMEOUT="<seconds>" - Seconds to wait for ZFS_DEV, 90 * defaults to 10, max. 10 min. 91 */ 92 int 93 libzfs_load_module(void) 94 { 95 if (access(ZFS_DEV, F_OK) == 0) 96 return (0); 97 98 if (access(ZFS_SYSFS_DIR, F_OK) != 0) { 99 char *argv[] = {"modprobe", "zfs", NULL}; 100 if (libzfs_run_process("modprobe", argv, 0)) 101 return (ENOEXEC); 102 103 if (access(ZFS_SYSFS_DIR, F_OK) != 0) 104 return (ENXIO); 105 } 106 107 const char *timeout_str = getenv("ZFS_MODULE_TIMEOUT"); 108 int seconds = 10; 109 if (timeout_str) 110 seconds = MIN(strtol(timeout_str, NULL, 0), 600); 111 struct itimerspec timeout = {.it_value.tv_sec = MAX(seconds, 0)}; 112 113 int ino = inotify_init1(IN_CLOEXEC); 114 if (ino == -1) 115 return (ENOENT); 116 inotify_add_watch(ino, ZFS_DEVDIR, IN_CREATE); 117 118 if (access(ZFS_DEV, F_OK) == 0) { 119 close(ino); 120 return (0); 121 } else if (seconds == 0) { 122 close(ino); 123 return (ENOENT); 124 } 125 126 size_t evsz = sizeof (struct inotify_event) + NAME_MAX + 1; 127 struct inotify_event *ev = alloca(evsz); 128 129 int tout = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); 130 if (tout == -1) { 131 close(ino); 132 return (ENOENT); 133 } 134 timerfd_settime(tout, 0, &timeout, NULL); 135 136 int ret = ENOENT; 137 struct pollfd pfds[] = { 138 {.fd = ino, .events = POLLIN}, 139 {.fd = tout, .events = POLLIN}, 140 }; 141 while (poll(pfds, ARRAY_SIZE(pfds), -1) != -1) { 142 if (pfds[0].revents & POLLIN) { 143 verify(read(ino, ev, evsz) > 144 sizeof (struct inotify_event)); 145 if (strcmp(ev->name, &ZFS_DEV[sizeof (ZFS_DEVDIR)]) 146 == 0) { 147 ret = 0; 148 break; 149 } 150 } 151 if (pfds[1].revents & POLLIN) 152 break; 153 } 154 close(tout); 155 close(ino); 156 return (ret); 157 } 158 159 int 160 find_shares_object(differ_info_t *di) 161 { 162 char fullpath[MAXPATHLEN]; 163 struct stat64 sb = { 0 }; 164 165 (void) strlcpy(fullpath, di->dsmnt, MAXPATHLEN); 166 (void) strlcat(fullpath, ZDIFF_SHARESDIR, MAXPATHLEN); 167 168 if (stat64(fullpath, &sb) != 0) { 169 (void) snprintf(di->errbuf, sizeof (di->errbuf), 170 dgettext(TEXT_DOMAIN, "Cannot stat %s"), fullpath); 171 return (zfs_error(di->zhp->zfs_hdl, EZFS_DIFF, di->errbuf)); 172 } 173 174 di->shares = (uint64_t)sb.st_ino; 175 return (0); 176 } 177 178 int 179 zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps) 180 { 181 (void) hdl, (void) snaps; 182 return (0); 183 } 184 185 /* 186 * Return allocated loaded module version, or NULL on error (with errno set) 187 */ 188 char * 189 zfs_version_kernel(void) 190 { 191 FILE *f = fopen(ZFS_SYSFS_DIR "/version", "re"); 192 if (f == NULL) 193 return (NULL); 194 195 char *ret = NULL; 196 size_t l; 197 ssize_t read; 198 if ((read = getline(&ret, &l, f)) == -1) { 199 int err = errno; 200 fclose(f); 201 errno = err; 202 return (NULL); 203 } 204 205 fclose(f); 206 if (ret[read - 1] == '\n') 207 ret[read - 1] = '\0'; 208 return (ret); 209 } 210