1009ea47eSEdward Tomasz Napierala /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4009ea47eSEdward Tomasz Napierala * Copyright (c) 2003, 2004 Silicon Graphics International Corp. 5009ea47eSEdward Tomasz Napierala * Copyright (c) 1997-2007 Kenneth D. Merry 6009ea47eSEdward Tomasz Napierala * Copyright (c) 2012 The FreeBSD Foundation 78951f055SMarcelo Araujo * Copyright (c) 2017 Jakub Wojciech Klama <jceel@FreeBSD.org> 8009ea47eSEdward Tomasz Napierala * All rights reserved. 9009ea47eSEdward Tomasz Napierala * 10009ea47eSEdward Tomasz Napierala * Portions of this software were developed by Edward Tomasz Napierala 11009ea47eSEdward Tomasz Napierala * under sponsorship from the FreeBSD Foundation. 12009ea47eSEdward Tomasz Napierala * 13009ea47eSEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without 14009ea47eSEdward Tomasz Napierala * modification, are permitted provided that the following conditions 15009ea47eSEdward Tomasz Napierala * are met: 16009ea47eSEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright 17009ea47eSEdward Tomasz Napierala * notice, this list of conditions, and the following disclaimer, 18009ea47eSEdward Tomasz Napierala * without modification. 19009ea47eSEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce at minimum a disclaimer 20009ea47eSEdward Tomasz Napierala * substantially similar to the "NO WARRANTY" disclaimer below 21009ea47eSEdward Tomasz Napierala * ("Disclaimer") and any redistribution must be conditioned upon 22009ea47eSEdward Tomasz Napierala * including a substantially similar Disclaimer requirement for further 23009ea47eSEdward Tomasz Napierala * binary redistribution. 24009ea47eSEdward Tomasz Napierala * 25009ea47eSEdward Tomasz Napierala * NO WARRANTY 26009ea47eSEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27009ea47eSEdward Tomasz Napierala * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28009ea47eSEdward Tomasz Napierala * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 29009ea47eSEdward Tomasz Napierala * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30009ea47eSEdward Tomasz Napierala * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31009ea47eSEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32009ea47eSEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33009ea47eSEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34009ea47eSEdward Tomasz Napierala * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 35009ea47eSEdward Tomasz Napierala * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36009ea47eSEdward Tomasz Napierala * POSSIBILITY OF SUCH DAMAGES. 37009ea47eSEdward Tomasz Napierala * 38009ea47eSEdward Tomasz Napierala */ 39009ea47eSEdward Tomasz Napierala 40009ea47eSEdward Tomasz Napierala #include <sys/param.h> 419118b1b0SEnji Cooper #include <sys/capsicum.h> 429118b1b0SEnji Cooper #include <sys/callout.h> 439118b1b0SEnji Cooper #include <sys/ioctl.h> 44009ea47eSEdward Tomasz Napierala #include <sys/linker.h> 45653e7d63SEnji Cooper #include <sys/module.h> 46009ea47eSEdward Tomasz Napierala #include <sys/queue.h> 47009ea47eSEdward Tomasz Napierala #include <sys/sbuf.h> 488951f055SMarcelo Araujo #include <sys/nv.h> 499118b1b0SEnji Cooper #include <sys/stat.h> 50009ea47eSEdward Tomasz Napierala #include <assert.h> 51009ea47eSEdward Tomasz Napierala #include <bsdxml.h> 521489776dSMariusz Zaborski #include <capsicum_helpers.h> 53009ea47eSEdward Tomasz Napierala #include <ctype.h> 54009ea47eSEdward Tomasz Napierala #include <errno.h> 55009ea47eSEdward Tomasz Napierala #include <fcntl.h> 56009ea47eSEdward Tomasz Napierala #include <stdint.h> 57009ea47eSEdward Tomasz Napierala #include <stdio.h> 58009ea47eSEdward Tomasz Napierala #include <stdlib.h> 59009ea47eSEdward Tomasz Napierala #include <string.h> 60009ea47eSEdward Tomasz Napierala #include <strings.h> 61009ea47eSEdward Tomasz Napierala #include <cam/scsi/scsi_all.h> 62009ea47eSEdward Tomasz Napierala #include <cam/scsi/scsi_message.h> 63009ea47eSEdward Tomasz Napierala #include <cam/ctl/ctl.h> 64009ea47eSEdward Tomasz Napierala #include <cam/ctl/ctl_io.h> 65009ea47eSEdward Tomasz Napierala #include <cam/ctl/ctl_backend.h> 66009ea47eSEdward Tomasz Napierala #include <cam/ctl/ctl_ioctl.h> 67009ea47eSEdward Tomasz Napierala #include <cam/ctl/ctl_util.h> 68009ea47eSEdward Tomasz Napierala #include <cam/ctl/ctl_scsi_all.h> 69009ea47eSEdward Tomasz Napierala 70ba3a2d31SEdward Tomasz Napierala #include "ctld.h" 71ba3a2d31SEdward Tomasz Napierala 72009ea47eSEdward Tomasz Napierala #ifdef ICL_KERNEL_PROXY 73009ea47eSEdward Tomasz Napierala #include <netdb.h> 74009ea47eSEdward Tomasz Napierala #endif 75009ea47eSEdward Tomasz Napierala 768951f055SMarcelo Araujo #define NVLIST_BUFSIZE 1024 778951f055SMarcelo Araujo 78ba3a2d31SEdward Tomasz Napierala extern bool proxy_mode; 79009ea47eSEdward Tomasz Napierala 80009ea47eSEdward Tomasz Napierala static int ctl_fd = 0; 81009ea47eSEdward Tomasz Napierala 82009ea47eSEdward Tomasz Napierala void 83009ea47eSEdward Tomasz Napierala kernel_init(void) 84009ea47eSEdward Tomasz Napierala { 85009ea47eSEdward Tomasz Napierala int retval, saved_errno; 86009ea47eSEdward Tomasz Napierala 87009ea47eSEdward Tomasz Napierala ctl_fd = open(CTL_DEFAULT_DEV, O_RDWR); 88c76e8a9aSEdward Tomasz Napierala if (ctl_fd < 0 && errno == ENOENT) { 89009ea47eSEdward Tomasz Napierala saved_errno = errno; 90009ea47eSEdward Tomasz Napierala retval = kldload("ctl"); 91009ea47eSEdward Tomasz Napierala if (retval != -1) 92009ea47eSEdward Tomasz Napierala ctl_fd = open(CTL_DEFAULT_DEV, O_RDWR); 93009ea47eSEdward Tomasz Napierala else 94009ea47eSEdward Tomasz Napierala errno = saved_errno; 95009ea47eSEdward Tomasz Napierala } 96009ea47eSEdward Tomasz Napierala if (ctl_fd < 0) 97009ea47eSEdward Tomasz Napierala log_err(1, "failed to open %s", CTL_DEFAULT_DEV); 98653e7d63SEnji Cooper #ifdef WANT_ISCSI 99653e7d63SEnji Cooper else { 100653e7d63SEnji Cooper saved_errno = errno; 101653e7d63SEnji Cooper if (modfind("cfiscsi") == -1 && kldload("cfiscsi") == -1) 102653e7d63SEnji Cooper log_warn("couldn't load cfiscsi"); 103653e7d63SEnji Cooper errno = saved_errno; 104653e7d63SEnji Cooper } 105653e7d63SEnji Cooper #endif 106009ea47eSEdward Tomasz Napierala } 107009ea47eSEdward Tomasz Napierala 108009ea47eSEdward Tomasz Napierala /* 109009ea47eSEdward Tomasz Napierala * Name/value pair used for per-LUN attributes. 110009ea47eSEdward Tomasz Napierala */ 111009ea47eSEdward Tomasz Napierala struct cctl_lun_nv { 112009ea47eSEdward Tomasz Napierala char *name; 113009ea47eSEdward Tomasz Napierala char *value; 114009ea47eSEdward Tomasz Napierala STAILQ_ENTRY(cctl_lun_nv) links; 115009ea47eSEdward Tomasz Napierala }; 116009ea47eSEdward Tomasz Napierala 117009ea47eSEdward Tomasz Napierala /* 118009ea47eSEdward Tomasz Napierala * Backend LUN information. 119009ea47eSEdward Tomasz Napierala */ 120009ea47eSEdward Tomasz Napierala struct cctl_lun { 121009ea47eSEdward Tomasz Napierala uint64_t lun_id; 122009ea47eSEdward Tomasz Napierala char *backend_type; 12391be33dcSAlexander Motin uint8_t device_type; 124009ea47eSEdward Tomasz Napierala uint64_t size_blocks; 125009ea47eSEdward Tomasz Napierala uint32_t blocksize; 126009ea47eSEdward Tomasz Napierala char *serial_number; 127009ea47eSEdward Tomasz Napierala char *device_id; 128920c6cbaSAlexander Motin char *ctld_name; 129009ea47eSEdward Tomasz Napierala STAILQ_HEAD(,cctl_lun_nv) attr_list; 130009ea47eSEdward Tomasz Napierala STAILQ_ENTRY(cctl_lun) links; 131009ea47eSEdward Tomasz Napierala }; 132009ea47eSEdward Tomasz Napierala 133917d38fbSAlexander Motin struct cctl_port { 134917d38fbSAlexander Motin uint32_t port_id; 135e543b3a8SAlexander Motin char *port_frontend; 136057abcb0SAlexander Motin char *port_name; 137d83595b2SAlexander Motin int pp; 138d83595b2SAlexander Motin int vp; 13992847ee1SAlexander Motin int cfiscsi_state; 140917d38fbSAlexander Motin char *cfiscsi_target; 141917d38fbSAlexander Motin uint16_t cfiscsi_portal_group_tag; 14292847ee1SAlexander Motin char *ctld_portal_group_name; 143917d38fbSAlexander Motin STAILQ_HEAD(,cctl_lun_nv) attr_list; 144917d38fbSAlexander Motin STAILQ_ENTRY(cctl_port) links; 145917d38fbSAlexander Motin }; 146917d38fbSAlexander Motin 147009ea47eSEdward Tomasz Napierala struct cctl_devlist_data { 148009ea47eSEdward Tomasz Napierala int num_luns; 149009ea47eSEdward Tomasz Napierala STAILQ_HEAD(,cctl_lun) lun_list; 150009ea47eSEdward Tomasz Napierala struct cctl_lun *cur_lun; 151917d38fbSAlexander Motin int num_ports; 152917d38fbSAlexander Motin STAILQ_HEAD(,cctl_port) port_list; 153917d38fbSAlexander Motin struct cctl_port *cur_port; 154009ea47eSEdward Tomasz Napierala int level; 155009ea47eSEdward Tomasz Napierala struct sbuf *cur_sb[32]; 156009ea47eSEdward Tomasz Napierala }; 157009ea47eSEdward Tomasz Napierala 158009ea47eSEdward Tomasz Napierala static void 159009ea47eSEdward Tomasz Napierala cctl_start_element(void *user_data, const char *name, const char **attr) 160009ea47eSEdward Tomasz Napierala { 161009ea47eSEdward Tomasz Napierala int i; 162009ea47eSEdward Tomasz Napierala struct cctl_devlist_data *devlist; 163009ea47eSEdward Tomasz Napierala struct cctl_lun *cur_lun; 164009ea47eSEdward Tomasz Napierala 165009ea47eSEdward Tomasz Napierala devlist = (struct cctl_devlist_data *)user_data; 166009ea47eSEdward Tomasz Napierala cur_lun = devlist->cur_lun; 167009ea47eSEdward Tomasz Napierala devlist->level++; 1681af40365SEdward Tomasz Napierala if ((u_int)devlist->level >= (sizeof(devlist->cur_sb) / 169009ea47eSEdward Tomasz Napierala sizeof(devlist->cur_sb[0]))) 170009ea47eSEdward Tomasz Napierala log_errx(1, "%s: too many nesting levels, %zd max", __func__, 1718f65dcd6SElyes Haouas nitems(devlist->cur_sb)); 172009ea47eSEdward Tomasz Napierala 173009ea47eSEdward Tomasz Napierala devlist->cur_sb[devlist->level] = sbuf_new_auto(); 174009ea47eSEdward Tomasz Napierala if (devlist->cur_sb[devlist->level] == NULL) 175009ea47eSEdward Tomasz Napierala log_err(1, "%s: unable to allocate sbuf", __func__); 176009ea47eSEdward Tomasz Napierala 177009ea47eSEdward Tomasz Napierala if (strcmp(name, "lun") == 0) { 178009ea47eSEdward Tomasz Napierala if (cur_lun != NULL) 179009ea47eSEdward Tomasz Napierala log_errx(1, "%s: improper lun element nesting", 180009ea47eSEdward Tomasz Napierala __func__); 181009ea47eSEdward Tomasz Napierala 182009ea47eSEdward Tomasz Napierala cur_lun = calloc(1, sizeof(*cur_lun)); 183009ea47eSEdward Tomasz Napierala if (cur_lun == NULL) 184009ea47eSEdward Tomasz Napierala log_err(1, "%s: cannot allocate %zd bytes", __func__, 185009ea47eSEdward Tomasz Napierala sizeof(*cur_lun)); 186009ea47eSEdward Tomasz Napierala 187009ea47eSEdward Tomasz Napierala devlist->num_luns++; 188009ea47eSEdward Tomasz Napierala devlist->cur_lun = cur_lun; 189009ea47eSEdward Tomasz Napierala 190009ea47eSEdward Tomasz Napierala STAILQ_INIT(&cur_lun->attr_list); 191009ea47eSEdward Tomasz Napierala STAILQ_INSERT_TAIL(&devlist->lun_list, cur_lun, links); 192009ea47eSEdward Tomasz Napierala 193009ea47eSEdward Tomasz Napierala for (i = 0; attr[i] != NULL; i += 2) { 194009ea47eSEdward Tomasz Napierala if (strcmp(attr[i], "id") == 0) { 195009ea47eSEdward Tomasz Napierala cur_lun->lun_id = strtoull(attr[i+1], NULL, 0); 196009ea47eSEdward Tomasz Napierala } else { 197009ea47eSEdward Tomasz Napierala log_errx(1, "%s: invalid LUN attribute %s = %s", 198009ea47eSEdward Tomasz Napierala __func__, attr[i], attr[i+1]); 199009ea47eSEdward Tomasz Napierala } 200009ea47eSEdward Tomasz Napierala } 201009ea47eSEdward Tomasz Napierala } 202009ea47eSEdward Tomasz Napierala } 203009ea47eSEdward Tomasz Napierala 204009ea47eSEdward Tomasz Napierala static void 205009ea47eSEdward Tomasz Napierala cctl_end_element(void *user_data, const char *name) 206009ea47eSEdward Tomasz Napierala { 207009ea47eSEdward Tomasz Napierala struct cctl_devlist_data *devlist; 208009ea47eSEdward Tomasz Napierala struct cctl_lun *cur_lun; 209009ea47eSEdward Tomasz Napierala char *str; 210009ea47eSEdward Tomasz Napierala 211009ea47eSEdward Tomasz Napierala devlist = (struct cctl_devlist_data *)user_data; 212009ea47eSEdward Tomasz Napierala cur_lun = devlist->cur_lun; 213009ea47eSEdward Tomasz Napierala 214009ea47eSEdward Tomasz Napierala if ((cur_lun == NULL) 215009ea47eSEdward Tomasz Napierala && (strcmp(name, "ctllunlist") != 0)) 216009ea47eSEdward Tomasz Napierala log_errx(1, "%s: cur_lun == NULL! (name = %s)", __func__, name); 217009ea47eSEdward Tomasz Napierala 218009ea47eSEdward Tomasz Napierala if (devlist->cur_sb[devlist->level] == NULL) 219009ea47eSEdward Tomasz Napierala log_errx(1, "%s: no valid sbuf at level %d (name %s)", __func__, 220009ea47eSEdward Tomasz Napierala devlist->level, name); 221009ea47eSEdward Tomasz Napierala 222009ea47eSEdward Tomasz Napierala sbuf_finish(devlist->cur_sb[devlist->level]); 223009ea47eSEdward Tomasz Napierala str = checked_strdup(sbuf_data(devlist->cur_sb[devlist->level])); 224009ea47eSEdward Tomasz Napierala 225009ea47eSEdward Tomasz Napierala if (strlen(str) == 0) { 226009ea47eSEdward Tomasz Napierala free(str); 227009ea47eSEdward Tomasz Napierala str = NULL; 228009ea47eSEdward Tomasz Napierala } 229009ea47eSEdward Tomasz Napierala 230009ea47eSEdward Tomasz Napierala sbuf_delete(devlist->cur_sb[devlist->level]); 231009ea47eSEdward Tomasz Napierala devlist->cur_sb[devlist->level] = NULL; 232009ea47eSEdward Tomasz Napierala devlist->level--; 233009ea47eSEdward Tomasz Napierala 234009ea47eSEdward Tomasz Napierala if (strcmp(name, "backend_type") == 0) { 235009ea47eSEdward Tomasz Napierala cur_lun->backend_type = str; 236009ea47eSEdward Tomasz Napierala str = NULL; 23791be33dcSAlexander Motin } else if (strcmp(name, "lun_type") == 0) { 238e3529571SEdward Tomasz Napierala if (str == NULL) 239e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 24091be33dcSAlexander Motin cur_lun->device_type = strtoull(str, NULL, 0); 241009ea47eSEdward Tomasz Napierala } else if (strcmp(name, "size") == 0) { 242e3529571SEdward Tomasz Napierala if (str == NULL) 243e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 244009ea47eSEdward Tomasz Napierala cur_lun->size_blocks = strtoull(str, NULL, 0); 245009ea47eSEdward Tomasz Napierala } else if (strcmp(name, "blocksize") == 0) { 246e3529571SEdward Tomasz Napierala if (str == NULL) 247e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 248009ea47eSEdward Tomasz Napierala cur_lun->blocksize = strtoul(str, NULL, 0); 249009ea47eSEdward Tomasz Napierala } else if (strcmp(name, "serial_number") == 0) { 250009ea47eSEdward Tomasz Napierala cur_lun->serial_number = str; 251009ea47eSEdward Tomasz Napierala str = NULL; 252009ea47eSEdward Tomasz Napierala } else if (strcmp(name, "device_id") == 0) { 253009ea47eSEdward Tomasz Napierala cur_lun->device_id = str; 254009ea47eSEdward Tomasz Napierala str = NULL; 255920c6cbaSAlexander Motin } else if (strcmp(name, "ctld_name") == 0) { 256920c6cbaSAlexander Motin cur_lun->ctld_name = str; 257009ea47eSEdward Tomasz Napierala str = NULL; 258009ea47eSEdward Tomasz Napierala } else if (strcmp(name, "lun") == 0) { 259009ea47eSEdward Tomasz Napierala devlist->cur_lun = NULL; 260009ea47eSEdward Tomasz Napierala } else if (strcmp(name, "ctllunlist") == 0) { 2612bd28269SEdward Tomasz Napierala /* Nothing. */ 262009ea47eSEdward Tomasz Napierala } else { 263009ea47eSEdward Tomasz Napierala struct cctl_lun_nv *nv; 264009ea47eSEdward Tomasz Napierala 265009ea47eSEdward Tomasz Napierala nv = calloc(1, sizeof(*nv)); 266009ea47eSEdward Tomasz Napierala if (nv == NULL) 267009ea47eSEdward Tomasz Napierala log_err(1, "%s: can't allocate %zd bytes for nv pair", 268009ea47eSEdward Tomasz Napierala __func__, sizeof(*nv)); 269009ea47eSEdward Tomasz Napierala 270009ea47eSEdward Tomasz Napierala nv->name = checked_strdup(name); 271009ea47eSEdward Tomasz Napierala 272009ea47eSEdward Tomasz Napierala nv->value = str; 273009ea47eSEdward Tomasz Napierala str = NULL; 274009ea47eSEdward Tomasz Napierala STAILQ_INSERT_TAIL(&cur_lun->attr_list, nv, links); 275009ea47eSEdward Tomasz Napierala } 276009ea47eSEdward Tomasz Napierala 277009ea47eSEdward Tomasz Napierala free(str); 278009ea47eSEdward Tomasz Napierala } 279009ea47eSEdward Tomasz Napierala 280009ea47eSEdward Tomasz Napierala static void 281917d38fbSAlexander Motin cctl_start_pelement(void *user_data, const char *name, const char **attr) 282917d38fbSAlexander Motin { 283917d38fbSAlexander Motin int i; 284917d38fbSAlexander Motin struct cctl_devlist_data *devlist; 285917d38fbSAlexander Motin struct cctl_port *cur_port; 286917d38fbSAlexander Motin 287917d38fbSAlexander Motin devlist = (struct cctl_devlist_data *)user_data; 288917d38fbSAlexander Motin cur_port = devlist->cur_port; 289917d38fbSAlexander Motin devlist->level++; 290917d38fbSAlexander Motin if ((u_int)devlist->level >= (sizeof(devlist->cur_sb) / 291917d38fbSAlexander Motin sizeof(devlist->cur_sb[0]))) 292917d38fbSAlexander Motin log_errx(1, "%s: too many nesting levels, %zd max", __func__, 2938f65dcd6SElyes Haouas nitems(devlist->cur_sb)); 294917d38fbSAlexander Motin 295917d38fbSAlexander Motin devlist->cur_sb[devlist->level] = sbuf_new_auto(); 296917d38fbSAlexander Motin if (devlist->cur_sb[devlist->level] == NULL) 297917d38fbSAlexander Motin log_err(1, "%s: unable to allocate sbuf", __func__); 298917d38fbSAlexander Motin 299917d38fbSAlexander Motin if (strcmp(name, "targ_port") == 0) { 300917d38fbSAlexander Motin if (cur_port != NULL) 301917d38fbSAlexander Motin log_errx(1, "%s: improper port element nesting (%s)", 302917d38fbSAlexander Motin __func__, name); 303917d38fbSAlexander Motin 304917d38fbSAlexander Motin cur_port = calloc(1, sizeof(*cur_port)); 305917d38fbSAlexander Motin if (cur_port == NULL) 306917d38fbSAlexander Motin log_err(1, "%s: cannot allocate %zd bytes", __func__, 307917d38fbSAlexander Motin sizeof(*cur_port)); 308917d38fbSAlexander Motin 309917d38fbSAlexander Motin devlist->num_ports++; 310917d38fbSAlexander Motin devlist->cur_port = cur_port; 311917d38fbSAlexander Motin 312917d38fbSAlexander Motin STAILQ_INIT(&cur_port->attr_list); 313917d38fbSAlexander Motin STAILQ_INSERT_TAIL(&devlist->port_list, cur_port, links); 314917d38fbSAlexander Motin 315917d38fbSAlexander Motin for (i = 0; attr[i] != NULL; i += 2) { 316917d38fbSAlexander Motin if (strcmp(attr[i], "id") == 0) { 317917d38fbSAlexander Motin cur_port->port_id = strtoul(attr[i+1], NULL, 0); 318917d38fbSAlexander Motin } else { 319917d38fbSAlexander Motin log_errx(1, "%s: invalid LUN attribute %s = %s", 320917d38fbSAlexander Motin __func__, attr[i], attr[i+1]); 321917d38fbSAlexander Motin } 322917d38fbSAlexander Motin } 323917d38fbSAlexander Motin } 324917d38fbSAlexander Motin } 325917d38fbSAlexander Motin 326917d38fbSAlexander Motin static void 327917d38fbSAlexander Motin cctl_end_pelement(void *user_data, const char *name) 328917d38fbSAlexander Motin { 329917d38fbSAlexander Motin struct cctl_devlist_data *devlist; 330917d38fbSAlexander Motin struct cctl_port *cur_port; 331917d38fbSAlexander Motin char *str; 332917d38fbSAlexander Motin 333917d38fbSAlexander Motin devlist = (struct cctl_devlist_data *)user_data; 334917d38fbSAlexander Motin cur_port = devlist->cur_port; 335917d38fbSAlexander Motin 336917d38fbSAlexander Motin if ((cur_port == NULL) 337917d38fbSAlexander Motin && (strcmp(name, "ctlportlist") != 0)) 338917d38fbSAlexander Motin log_errx(1, "%s: cur_port == NULL! (name = %s)", __func__, name); 339917d38fbSAlexander Motin 340917d38fbSAlexander Motin if (devlist->cur_sb[devlist->level] == NULL) 341917d38fbSAlexander Motin log_errx(1, "%s: no valid sbuf at level %d (name %s)", __func__, 342917d38fbSAlexander Motin devlist->level, name); 343917d38fbSAlexander Motin 344917d38fbSAlexander Motin sbuf_finish(devlist->cur_sb[devlist->level]); 345917d38fbSAlexander Motin str = checked_strdup(sbuf_data(devlist->cur_sb[devlist->level])); 346917d38fbSAlexander Motin 347917d38fbSAlexander Motin if (strlen(str) == 0) { 348917d38fbSAlexander Motin free(str); 349917d38fbSAlexander Motin str = NULL; 350917d38fbSAlexander Motin } 351917d38fbSAlexander Motin 352917d38fbSAlexander Motin sbuf_delete(devlist->cur_sb[devlist->level]); 353917d38fbSAlexander Motin devlist->cur_sb[devlist->level] = NULL; 354917d38fbSAlexander Motin devlist->level--; 355917d38fbSAlexander Motin 356e543b3a8SAlexander Motin if (strcmp(name, "frontend_type") == 0) { 357e543b3a8SAlexander Motin cur_port->port_frontend = str; 358e543b3a8SAlexander Motin str = NULL; 359e543b3a8SAlexander Motin } else if (strcmp(name, "port_name") == 0) { 360057abcb0SAlexander Motin cur_port->port_name = str; 361057abcb0SAlexander Motin str = NULL; 362d83595b2SAlexander Motin } else if (strcmp(name, "physical_port") == 0) { 363e3529571SEdward Tomasz Napierala if (str == NULL) 364e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 365d83595b2SAlexander Motin cur_port->pp = strtoul(str, NULL, 0); 366d83595b2SAlexander Motin } else if (strcmp(name, "virtual_port") == 0) { 367e3529571SEdward Tomasz Napierala if (str == NULL) 368e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 369d83595b2SAlexander Motin cur_port->vp = strtoul(str, NULL, 0); 370057abcb0SAlexander Motin } else if (strcmp(name, "cfiscsi_target") == 0) { 371917d38fbSAlexander Motin cur_port->cfiscsi_target = str; 372917d38fbSAlexander Motin str = NULL; 37392847ee1SAlexander Motin } else if (strcmp(name, "cfiscsi_state") == 0) { 374e3529571SEdward Tomasz Napierala if (str == NULL) 375e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 37692847ee1SAlexander Motin cur_port->cfiscsi_state = strtoul(str, NULL, 0); 377917d38fbSAlexander Motin } else if (strcmp(name, "cfiscsi_portal_group_tag") == 0) { 378e3529571SEdward Tomasz Napierala if (str == NULL) 379e3529571SEdward Tomasz Napierala log_errx(1, "%s: %s missing its argument", __func__, name); 380917d38fbSAlexander Motin cur_port->cfiscsi_portal_group_tag = strtoul(str, NULL, 0); 38192847ee1SAlexander Motin } else if (strcmp(name, "ctld_portal_group_name") == 0) { 38292847ee1SAlexander Motin cur_port->ctld_portal_group_name = str; 38392847ee1SAlexander Motin str = NULL; 384917d38fbSAlexander Motin } else if (strcmp(name, "targ_port") == 0) { 385917d38fbSAlexander Motin devlist->cur_port = NULL; 386917d38fbSAlexander Motin } else if (strcmp(name, "ctlportlist") == 0) { 3872bd28269SEdward Tomasz Napierala /* Nothing. */ 388917d38fbSAlexander Motin } else { 389917d38fbSAlexander Motin struct cctl_lun_nv *nv; 390917d38fbSAlexander Motin 391917d38fbSAlexander Motin nv = calloc(1, sizeof(*nv)); 392917d38fbSAlexander Motin if (nv == NULL) 393917d38fbSAlexander Motin log_err(1, "%s: can't allocate %zd bytes for nv pair", 394917d38fbSAlexander Motin __func__, sizeof(*nv)); 395917d38fbSAlexander Motin 396917d38fbSAlexander Motin nv->name = checked_strdup(name); 397917d38fbSAlexander Motin 398917d38fbSAlexander Motin nv->value = str; 399917d38fbSAlexander Motin str = NULL; 400917d38fbSAlexander Motin STAILQ_INSERT_TAIL(&cur_port->attr_list, nv, links); 401917d38fbSAlexander Motin } 402917d38fbSAlexander Motin 403917d38fbSAlexander Motin free(str); 404917d38fbSAlexander Motin } 405917d38fbSAlexander Motin 406917d38fbSAlexander Motin static void 407009ea47eSEdward Tomasz Napierala cctl_char_handler(void *user_data, const XML_Char *str, int len) 408009ea47eSEdward Tomasz Napierala { 409009ea47eSEdward Tomasz Napierala struct cctl_devlist_data *devlist; 410009ea47eSEdward Tomasz Napierala 411009ea47eSEdward Tomasz Napierala devlist = (struct cctl_devlist_data *)user_data; 412009ea47eSEdward Tomasz Napierala 413009ea47eSEdward Tomasz Napierala sbuf_bcat(devlist->cur_sb[devlist->level], str, len); 414009ea47eSEdward Tomasz Napierala } 415009ea47eSEdward Tomasz Napierala 416009ea47eSEdward Tomasz Napierala struct conf * 417*969876fcSAlan Somers conf_new_from_kernel(struct kports *kports) 418009ea47eSEdward Tomasz Napierala { 419009ea47eSEdward Tomasz Napierala struct conf *conf = NULL; 420009ea47eSEdward Tomasz Napierala struct target *targ; 42192847ee1SAlexander Motin struct portal_group *pg; 422057abcb0SAlexander Motin struct pport *pp; 42392847ee1SAlexander Motin struct port *cp; 424009ea47eSEdward Tomasz Napierala struct lun *cl; 425398290f2SAlexander Motin struct option *o; 426009ea47eSEdward Tomasz Napierala struct ctl_lun_list list; 427009ea47eSEdward Tomasz Napierala struct cctl_devlist_data devlist; 428009ea47eSEdward Tomasz Napierala struct cctl_lun *lun; 429917d38fbSAlexander Motin struct cctl_port *port; 430009ea47eSEdward Tomasz Napierala XML_Parser parser; 431d83595b2SAlexander Motin char *str, *name; 432917d38fbSAlexander Motin int len, retval; 433009ea47eSEdward Tomasz Napierala 434009ea47eSEdward Tomasz Napierala bzero(&devlist, sizeof(devlist)); 435009ea47eSEdward Tomasz Napierala STAILQ_INIT(&devlist.lun_list); 436917d38fbSAlexander Motin STAILQ_INIT(&devlist.port_list); 437009ea47eSEdward Tomasz Napierala 438009ea47eSEdward Tomasz Napierala log_debugx("obtaining previously configured CTL luns from the kernel"); 439009ea47eSEdward Tomasz Napierala 440917d38fbSAlexander Motin str = NULL; 441917d38fbSAlexander Motin len = 4096; 442009ea47eSEdward Tomasz Napierala retry: 443917d38fbSAlexander Motin str = realloc(str, len); 444917d38fbSAlexander Motin if (str == NULL) 445009ea47eSEdward Tomasz Napierala log_err(1, "realloc"); 446009ea47eSEdward Tomasz Napierala 447009ea47eSEdward Tomasz Napierala bzero(&list, sizeof(list)); 448917d38fbSAlexander Motin list.alloc_len = len; 449009ea47eSEdward Tomasz Napierala list.status = CTL_LUN_LIST_NONE; 450917d38fbSAlexander Motin list.lun_xml = str; 451009ea47eSEdward Tomasz Napierala 452009ea47eSEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_LUN_LIST, &list) == -1) { 453009ea47eSEdward Tomasz Napierala log_warn("error issuing CTL_LUN_LIST ioctl"); 454917d38fbSAlexander Motin free(str); 455009ea47eSEdward Tomasz Napierala return (NULL); 456009ea47eSEdward Tomasz Napierala } 457009ea47eSEdward Tomasz Napierala 458009ea47eSEdward Tomasz Napierala if (list.status == CTL_LUN_LIST_ERROR) { 459009ea47eSEdward Tomasz Napierala log_warnx("error returned from CTL_LUN_LIST ioctl: %s", 460009ea47eSEdward Tomasz Napierala list.error_str); 461917d38fbSAlexander Motin free(str); 462009ea47eSEdward Tomasz Napierala return (NULL); 463009ea47eSEdward Tomasz Napierala } 464009ea47eSEdward Tomasz Napierala 465009ea47eSEdward Tomasz Napierala if (list.status == CTL_LUN_LIST_NEED_MORE_SPACE) { 466917d38fbSAlexander Motin len = len << 1; 467009ea47eSEdward Tomasz Napierala goto retry; 468009ea47eSEdward Tomasz Napierala } 469009ea47eSEdward Tomasz Napierala 470009ea47eSEdward Tomasz Napierala parser = XML_ParserCreate(NULL); 471009ea47eSEdward Tomasz Napierala if (parser == NULL) { 472009ea47eSEdward Tomasz Napierala log_warnx("unable to create XML parser"); 473917d38fbSAlexander Motin free(str); 474009ea47eSEdward Tomasz Napierala return (NULL); 475009ea47eSEdward Tomasz Napierala } 476009ea47eSEdward Tomasz Napierala 477009ea47eSEdward Tomasz Napierala XML_SetUserData(parser, &devlist); 478009ea47eSEdward Tomasz Napierala XML_SetElementHandler(parser, cctl_start_element, cctl_end_element); 479009ea47eSEdward Tomasz Napierala XML_SetCharacterDataHandler(parser, cctl_char_handler); 480009ea47eSEdward Tomasz Napierala 481917d38fbSAlexander Motin retval = XML_Parse(parser, str, strlen(str), 1); 482009ea47eSEdward Tomasz Napierala XML_ParserFree(parser); 483917d38fbSAlexander Motin free(str); 484917d38fbSAlexander Motin if (retval != 1) { 485917d38fbSAlexander Motin log_warnx("XML_Parse failed"); 486917d38fbSAlexander Motin return (NULL); 487917d38fbSAlexander Motin } 488917d38fbSAlexander Motin 489917d38fbSAlexander Motin str = NULL; 490917d38fbSAlexander Motin len = 4096; 491917d38fbSAlexander Motin retry_port: 492917d38fbSAlexander Motin str = realloc(str, len); 493917d38fbSAlexander Motin if (str == NULL) 494917d38fbSAlexander Motin log_err(1, "realloc"); 495917d38fbSAlexander Motin 496917d38fbSAlexander Motin bzero(&list, sizeof(list)); 497917d38fbSAlexander Motin list.alloc_len = len; 498917d38fbSAlexander Motin list.status = CTL_LUN_LIST_NONE; 499917d38fbSAlexander Motin list.lun_xml = str; 500917d38fbSAlexander Motin 501917d38fbSAlexander Motin if (ioctl(ctl_fd, CTL_PORT_LIST, &list) == -1) { 502917d38fbSAlexander Motin log_warn("error issuing CTL_PORT_LIST ioctl"); 503917d38fbSAlexander Motin free(str); 504917d38fbSAlexander Motin return (NULL); 505917d38fbSAlexander Motin } 506917d38fbSAlexander Motin 5079c887a4fSAlexander Motin if (list.status == CTL_LUN_LIST_ERROR) { 508917d38fbSAlexander Motin log_warnx("error returned from CTL_PORT_LIST ioctl: %s", 509917d38fbSAlexander Motin list.error_str); 510917d38fbSAlexander Motin free(str); 511917d38fbSAlexander Motin return (NULL); 512917d38fbSAlexander Motin } 513917d38fbSAlexander Motin 514917d38fbSAlexander Motin if (list.status == CTL_LUN_LIST_NEED_MORE_SPACE) { 515917d38fbSAlexander Motin len = len << 1; 516917d38fbSAlexander Motin goto retry_port; 517917d38fbSAlexander Motin } 518917d38fbSAlexander Motin 519917d38fbSAlexander Motin parser = XML_ParserCreate(NULL); 520917d38fbSAlexander Motin if (parser == NULL) { 521917d38fbSAlexander Motin log_warnx("unable to create XML parser"); 522917d38fbSAlexander Motin free(str); 523917d38fbSAlexander Motin return (NULL); 524917d38fbSAlexander Motin } 525917d38fbSAlexander Motin 526917d38fbSAlexander Motin XML_SetUserData(parser, &devlist); 527917d38fbSAlexander Motin XML_SetElementHandler(parser, cctl_start_pelement, cctl_end_pelement); 528917d38fbSAlexander Motin XML_SetCharacterDataHandler(parser, cctl_char_handler); 529917d38fbSAlexander Motin 530917d38fbSAlexander Motin retval = XML_Parse(parser, str, strlen(str), 1); 531917d38fbSAlexander Motin XML_ParserFree(parser); 532917d38fbSAlexander Motin free(str); 533009ea47eSEdward Tomasz Napierala if (retval != 1) { 534009ea47eSEdward Tomasz Napierala log_warnx("XML_Parse failed"); 535009ea47eSEdward Tomasz Napierala return (NULL); 536009ea47eSEdward Tomasz Napierala } 537009ea47eSEdward Tomasz Napierala 538009ea47eSEdward Tomasz Napierala conf = conf_new(); 539009ea47eSEdward Tomasz Napierala 540d83595b2SAlexander Motin name = NULL; 541917d38fbSAlexander Motin STAILQ_FOREACH(port, &devlist.port_list, links) { 542e543b3a8SAlexander Motin if (strcmp(port->port_frontend, "ha") == 0) 543e543b3a8SAlexander Motin continue; 5440bb4b989SAlexander Motin free(name); 54505c3dfeeSEdward Tomasz Napierala if (port->pp == 0 && port->vp == 0) { 546d83595b2SAlexander Motin name = checked_strdup(port->port_name); 54705c3dfeeSEdward Tomasz Napierala } else if (port->vp == 0) { 54805c3dfeeSEdward Tomasz Napierala retval = asprintf(&name, "%s/%d", 54905c3dfeeSEdward Tomasz Napierala port->port_name, port->pp); 55005c3dfeeSEdward Tomasz Napierala if (retval <= 0) 55105c3dfeeSEdward Tomasz Napierala log_err(1, "asprintf"); 55205c3dfeeSEdward Tomasz Napierala } else { 55305c3dfeeSEdward Tomasz Napierala retval = asprintf(&name, "%s/%d/%d", 55405c3dfeeSEdward Tomasz Napierala port->port_name, port->pp, port->vp); 55505c3dfeeSEdward Tomasz Napierala if (retval <= 0) 55605c3dfeeSEdward Tomasz Napierala log_err(1, "asprintf"); 55705c3dfeeSEdward Tomasz Napierala } 558917d38fbSAlexander Motin 559917d38fbSAlexander Motin if (port->cfiscsi_target == NULL) { 560057abcb0SAlexander Motin log_debugx("CTL port %u \"%s\" wasn't managed by ctld; ", 561d83595b2SAlexander Motin port->port_id, name); 562*969876fcSAlan Somers pp = pport_find(kports, name); 563057abcb0SAlexander Motin if (pp == NULL) { 564057abcb0SAlexander Motin #if 0 565057abcb0SAlexander Motin log_debugx("found new kernel port %u \"%s\"", 566d83595b2SAlexander Motin port->port_id, name); 567057abcb0SAlexander Motin #endif 568*969876fcSAlan Somers pp = pport_new(kports, name, port->port_id); 569057abcb0SAlexander Motin if (pp == NULL) { 570057abcb0SAlexander Motin log_warnx("pport_new failed"); 571057abcb0SAlexander Motin continue; 572057abcb0SAlexander Motin } 573057abcb0SAlexander Motin } 574917d38fbSAlexander Motin continue; 575917d38fbSAlexander Motin } 57692847ee1SAlexander Motin if (port->cfiscsi_state != 1) { 5771380b77cSAlexander Motin log_debugx("CTL port %ju is not active (%d); ignoring", 57892847ee1SAlexander Motin (uintmax_t)port->port_id, port->cfiscsi_state); 5791380b77cSAlexander Motin continue; 5801380b77cSAlexander Motin } 581917d38fbSAlexander Motin 582917d38fbSAlexander Motin targ = target_find(conf, port->cfiscsi_target); 583917d38fbSAlexander Motin if (targ == NULL) { 584917d38fbSAlexander Motin #if 0 585917d38fbSAlexander Motin log_debugx("found new kernel target %s for CTL port %ld", 586917d38fbSAlexander Motin port->cfiscsi_target, port->port_id); 587917d38fbSAlexander Motin #endif 588917d38fbSAlexander Motin targ = target_new(conf, port->cfiscsi_target); 589917d38fbSAlexander Motin if (targ == NULL) { 590917d38fbSAlexander Motin log_warnx("target_new failed"); 591917d38fbSAlexander Motin continue; 592917d38fbSAlexander Motin } 593917d38fbSAlexander Motin } 59492847ee1SAlexander Motin 59592847ee1SAlexander Motin if (port->ctld_portal_group_name == NULL) 59692847ee1SAlexander Motin continue; 59792847ee1SAlexander Motin pg = portal_group_find(conf, port->ctld_portal_group_name); 59892847ee1SAlexander Motin if (pg == NULL) { 59992847ee1SAlexander Motin #if 0 60092847ee1SAlexander Motin log_debugx("found new kernel portal group %s for CTL port %ld", 60192847ee1SAlexander Motin port->ctld_portal_group_name, port->port_id); 60292847ee1SAlexander Motin #endif 60392847ee1SAlexander Motin pg = portal_group_new(conf, port->ctld_portal_group_name); 60492847ee1SAlexander Motin if (pg == NULL) { 60592847ee1SAlexander Motin log_warnx("portal_group_new failed"); 60692847ee1SAlexander Motin continue; 60792847ee1SAlexander Motin } 60892847ee1SAlexander Motin } 60992847ee1SAlexander Motin pg->pg_tag = port->cfiscsi_portal_group_tag; 61092847ee1SAlexander Motin cp = port_new(conf, targ, pg); 61192847ee1SAlexander Motin if (cp == NULL) { 61292847ee1SAlexander Motin log_warnx("port_new failed"); 61392847ee1SAlexander Motin continue; 61492847ee1SAlexander Motin } 61592847ee1SAlexander Motin cp->p_ctl_port = port->port_id; 616917d38fbSAlexander Motin } 6172909ddd1SAlan Somers while ((port = STAILQ_FIRST(&devlist.port_list))) { 6182909ddd1SAlan Somers struct cctl_lun_nv *nv; 6192909ddd1SAlan Somers 6202909ddd1SAlan Somers STAILQ_REMOVE_HEAD(&devlist.port_list, links); 6212909ddd1SAlan Somers free(port->port_frontend); 6222909ddd1SAlan Somers free(port->port_name); 6232909ddd1SAlan Somers free(port->cfiscsi_target); 6242909ddd1SAlan Somers free(port->ctld_portal_group_name); 6252909ddd1SAlan Somers while ((nv = STAILQ_FIRST(&port->attr_list))) { 6262909ddd1SAlan Somers STAILQ_REMOVE_HEAD(&port->attr_list, links); 6272909ddd1SAlan Somers free(nv->value); 6282909ddd1SAlan Somers free(nv->name); 6292909ddd1SAlan Somers free(nv); 6302909ddd1SAlan Somers } 6312909ddd1SAlan Somers free(port); 6322909ddd1SAlan Somers } 633d83595b2SAlexander Motin free(name); 634917d38fbSAlexander Motin 635009ea47eSEdward Tomasz Napierala STAILQ_FOREACH(lun, &devlist.lun_list, links) { 636009ea47eSEdward Tomasz Napierala struct cctl_lun_nv *nv; 637009ea47eSEdward Tomasz Napierala 638920c6cbaSAlexander Motin if (lun->ctld_name == NULL) { 639009ea47eSEdward Tomasz Napierala log_debugx("CTL lun %ju wasn't managed by ctld; " 640009ea47eSEdward Tomasz Napierala "ignoring", (uintmax_t)lun->lun_id); 641009ea47eSEdward Tomasz Napierala continue; 642009ea47eSEdward Tomasz Napierala } 643009ea47eSEdward Tomasz Napierala 644920c6cbaSAlexander Motin cl = lun_find(conf, lun->ctld_name); 645009ea47eSEdward Tomasz Napierala if (cl != NULL) { 646920c6cbaSAlexander Motin log_warnx("found CTL lun %ju \"%s\", " 647920c6cbaSAlexander Motin "also backed by CTL lun %d; ignoring", 648920c6cbaSAlexander Motin (uintmax_t)lun->lun_id, lun->ctld_name, 649920c6cbaSAlexander Motin cl->l_ctl_lun); 650009ea47eSEdward Tomasz Napierala continue; 651009ea47eSEdward Tomasz Napierala } 652009ea47eSEdward Tomasz Napierala 653920c6cbaSAlexander Motin log_debugx("found CTL lun %ju \"%s\"", 654920c6cbaSAlexander Motin (uintmax_t)lun->lun_id, lun->ctld_name); 655009ea47eSEdward Tomasz Napierala 656920c6cbaSAlexander Motin cl = lun_new(conf, lun->ctld_name); 657009ea47eSEdward Tomasz Napierala if (cl == NULL) { 658009ea47eSEdward Tomasz Napierala log_warnx("lun_new failed"); 659009ea47eSEdward Tomasz Napierala continue; 660009ea47eSEdward Tomasz Napierala } 661009ea47eSEdward Tomasz Napierala lun_set_backend(cl, lun->backend_type); 66291be33dcSAlexander Motin lun_set_device_type(cl, lun->device_type); 663009ea47eSEdward Tomasz Napierala lun_set_blocksize(cl, lun->blocksize); 664009ea47eSEdward Tomasz Napierala lun_set_device_id(cl, lun->device_id); 665009ea47eSEdward Tomasz Napierala lun_set_serial(cl, lun->serial_number); 666009ea47eSEdward Tomasz Napierala lun_set_size(cl, lun->size_blocks * cl->l_blocksize); 667009ea47eSEdward Tomasz Napierala lun_set_ctl_lun(cl, lun->lun_id); 668009ea47eSEdward Tomasz Napierala 669009ea47eSEdward Tomasz Napierala STAILQ_FOREACH(nv, &lun->attr_list, links) { 670009ea47eSEdward Tomasz Napierala if (strcmp(nv->name, "file") == 0 || 671009ea47eSEdward Tomasz Napierala strcmp(nv->name, "dev") == 0) { 672009ea47eSEdward Tomasz Napierala lun_set_path(cl, nv->value); 673009ea47eSEdward Tomasz Napierala continue; 674009ea47eSEdward Tomasz Napierala } 675398290f2SAlexander Motin o = option_new(&cl->l_options, nv->name, nv->value); 676398290f2SAlexander Motin if (o == NULL) 677009ea47eSEdward Tomasz Napierala log_warnx("unable to add CTL lun option %s " 678920c6cbaSAlexander Motin "for CTL lun %ju \"%s\"", 679009ea47eSEdward Tomasz Napierala nv->name, (uintmax_t) lun->lun_id, 680920c6cbaSAlexander Motin cl->l_name); 681009ea47eSEdward Tomasz Napierala } 682009ea47eSEdward Tomasz Napierala } 6832909ddd1SAlan Somers while ((lun = STAILQ_FIRST(&devlist.lun_list))) { 6842909ddd1SAlan Somers struct cctl_lun_nv *nv; 6852909ddd1SAlan Somers 6862909ddd1SAlan Somers STAILQ_REMOVE_HEAD(&devlist.lun_list, links); 6872909ddd1SAlan Somers while ((nv = STAILQ_FIRST(&lun->attr_list))) { 6882909ddd1SAlan Somers STAILQ_REMOVE_HEAD(&lun->attr_list, links); 6892909ddd1SAlan Somers free(nv->value); 6902909ddd1SAlan Somers free(nv->name); 6912909ddd1SAlan Somers free(nv); 6922909ddd1SAlan Somers } 6932909ddd1SAlan Somers free(lun); 6942909ddd1SAlan Somers } 695009ea47eSEdward Tomasz Napierala 696009ea47eSEdward Tomasz Napierala return (conf); 697009ea47eSEdward Tomasz Napierala } 698009ea47eSEdward Tomasz Napierala 699009ea47eSEdward Tomasz Napierala int 700009ea47eSEdward Tomasz Napierala kernel_lun_add(struct lun *lun) 701009ea47eSEdward Tomasz Napierala { 702398290f2SAlexander Motin struct option *o; 703009ea47eSEdward Tomasz Napierala struct ctl_lun_req req; 7048951f055SMarcelo Araujo int error; 705009ea47eSEdward Tomasz Napierala 706009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 707009ea47eSEdward Tomasz Napierala 708009ea47eSEdward Tomasz Napierala strlcpy(req.backend, lun->l_backend, sizeof(req.backend)); 709009ea47eSEdward Tomasz Napierala req.reqtype = CTL_LUNREQ_CREATE; 710009ea47eSEdward Tomasz Napierala 711009ea47eSEdward Tomasz Napierala req.reqdata.create.blocksize_bytes = lun->l_blocksize; 712009ea47eSEdward Tomasz Napierala 713009ea47eSEdward Tomasz Napierala if (lun->l_size != 0) 714009ea47eSEdward Tomasz Napierala req.reqdata.create.lun_size_bytes = lun->l_size; 715009ea47eSEdward Tomasz Napierala 7163933f7b1SAlexander Motin if (lun->l_ctl_lun >= 0) { 7173933f7b1SAlexander Motin req.reqdata.create.req_lun_id = lun->l_ctl_lun; 7183933f7b1SAlexander Motin req.reqdata.create.flags |= CTL_LUN_FLAG_ID_REQ; 7193933f7b1SAlexander Motin } 7203933f7b1SAlexander Motin 721009ea47eSEdward Tomasz Napierala req.reqdata.create.flags |= CTL_LUN_FLAG_DEV_TYPE; 72291be33dcSAlexander Motin req.reqdata.create.device_type = lun->l_device_type; 723009ea47eSEdward Tomasz Napierala 724009ea47eSEdward Tomasz Napierala if (lun->l_serial != NULL) { 7258ea4f2efSAlexander Motin strncpy(req.reqdata.create.serial_num, lun->l_serial, 726009ea47eSEdward Tomasz Napierala sizeof(req.reqdata.create.serial_num)); 727009ea47eSEdward Tomasz Napierala req.reqdata.create.flags |= CTL_LUN_FLAG_SERIAL_NUM; 728009ea47eSEdward Tomasz Napierala } 729009ea47eSEdward Tomasz Napierala 730009ea47eSEdward Tomasz Napierala if (lun->l_device_id != NULL) { 7318ea4f2efSAlexander Motin strncpy(req.reqdata.create.device_id, lun->l_device_id, 732009ea47eSEdward Tomasz Napierala sizeof(req.reqdata.create.device_id)); 733009ea47eSEdward Tomasz Napierala req.reqdata.create.flags |= CTL_LUN_FLAG_DEVID; 734009ea47eSEdward Tomasz Napierala } 735009ea47eSEdward Tomasz Napierala 736009ea47eSEdward Tomasz Napierala if (lun->l_path != NULL) { 737398290f2SAlexander Motin o = option_find(&lun->l_options, "file"); 738398290f2SAlexander Motin if (o != NULL) { 739398290f2SAlexander Motin option_set(o, lun->l_path); 740009ea47eSEdward Tomasz Napierala } else { 741398290f2SAlexander Motin o = option_new(&lun->l_options, "file", lun->l_path); 742398290f2SAlexander Motin assert(o != NULL); 743009ea47eSEdward Tomasz Napierala } 744009ea47eSEdward Tomasz Napierala } 745009ea47eSEdward Tomasz Napierala 746398290f2SAlexander Motin o = option_find(&lun->l_options, "ctld_name"); 747398290f2SAlexander Motin if (o != NULL) { 748398290f2SAlexander Motin option_set(o, lun->l_name); 749009ea47eSEdward Tomasz Napierala } else { 750398290f2SAlexander Motin o = option_new(&lun->l_options, "ctld_name", lun->l_name); 751398290f2SAlexander Motin assert(o != NULL); 752009ea47eSEdward Tomasz Napierala } 753009ea47eSEdward Tomasz Napierala 754398290f2SAlexander Motin o = option_find(&lun->l_options, "scsiname"); 755398290f2SAlexander Motin if (o == NULL && lun->l_scsiname != NULL) { 756398290f2SAlexander Motin o = option_new(&lun->l_options, "scsiname", lun->l_scsiname); 757398290f2SAlexander Motin assert(o != NULL); 758027e5269SAlexander Motin } 759027e5269SAlexander Motin 7608951f055SMarcelo Araujo if (!TAILQ_EMPTY(&lun->l_options)) { 7618951f055SMarcelo Araujo req.args_nvl = nvlist_create(0); 7628951f055SMarcelo Araujo if (req.args_nvl == NULL) { 7638951f055SMarcelo Araujo log_warn("error allocating nvlist"); 764009ea47eSEdward Tomasz Napierala return (1); 765009ea47eSEdward Tomasz Napierala } 766009ea47eSEdward Tomasz Napierala 7678951f055SMarcelo Araujo TAILQ_FOREACH(o, &lun->l_options, o_next) 7688951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, o->o_name, o->o_value); 7698951f055SMarcelo Araujo 7708951f055SMarcelo Araujo req.args = nvlist_pack(req.args_nvl, &req.args_len); 7718951f055SMarcelo Araujo if (req.args == NULL) { 7722909ddd1SAlan Somers nvlist_destroy(req.args_nvl); 7738951f055SMarcelo Araujo log_warn("error packing nvlist"); 7748951f055SMarcelo Araujo return (1); 775009ea47eSEdward Tomasz Napierala } 776009ea47eSEdward Tomasz Napierala } 777009ea47eSEdward Tomasz Napierala 778009ea47eSEdward Tomasz Napierala error = ioctl(ctl_fd, CTL_LUN_REQ, &req); 7792909ddd1SAlan Somers free(req.args); 7808951f055SMarcelo Araujo nvlist_destroy(req.args_nvl); 7818951f055SMarcelo Araujo 782009ea47eSEdward Tomasz Napierala if (error != 0) { 783009ea47eSEdward Tomasz Napierala log_warn("error issuing CTL_LUN_REQ ioctl"); 784009ea47eSEdward Tomasz Napierala return (1); 785009ea47eSEdward Tomasz Napierala } 786009ea47eSEdward Tomasz Napierala 78719720f41SAlexander Motin switch (req.status) { 78819720f41SAlexander Motin case CTL_LUN_ERROR: 78919720f41SAlexander Motin log_warnx("LUN creation error: %s", req.error_str); 790009ea47eSEdward Tomasz Napierala return (1); 79119720f41SAlexander Motin case CTL_LUN_WARNING: 79219720f41SAlexander Motin log_warnx("LUN creation warning: %s", req.error_str); 79319720f41SAlexander Motin break; 79419720f41SAlexander Motin case CTL_LUN_OK: 79519720f41SAlexander Motin break; 79619720f41SAlexander Motin default: 79719720f41SAlexander Motin log_warnx("unknown LUN creation status: %d", 798009ea47eSEdward Tomasz Napierala req.status); 799009ea47eSEdward Tomasz Napierala return (1); 800009ea47eSEdward Tomasz Napierala } 801009ea47eSEdward Tomasz Napierala 802009ea47eSEdward Tomasz Napierala lun_set_ctl_lun(lun, req.reqdata.create.req_lun_id); 803009ea47eSEdward Tomasz Napierala return (0); 804009ea47eSEdward Tomasz Napierala } 805009ea47eSEdward Tomasz Napierala 806009ea47eSEdward Tomasz Napierala int 807a3977beaSAlexander Motin kernel_lun_modify(struct lun *lun) 808009ea47eSEdward Tomasz Napierala { 809398290f2SAlexander Motin struct option *o; 810009ea47eSEdward Tomasz Napierala struct ctl_lun_req req; 8118951f055SMarcelo Araujo int error; 812009ea47eSEdward Tomasz Napierala 813009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 814009ea47eSEdward Tomasz Napierala 815009ea47eSEdward Tomasz Napierala strlcpy(req.backend, lun->l_backend, sizeof(req.backend)); 816009ea47eSEdward Tomasz Napierala req.reqtype = CTL_LUNREQ_MODIFY; 817009ea47eSEdward Tomasz Napierala 818009ea47eSEdward Tomasz Napierala req.reqdata.modify.lun_id = lun->l_ctl_lun; 819009ea47eSEdward Tomasz Napierala req.reqdata.modify.lun_size_bytes = lun->l_size; 820009ea47eSEdward Tomasz Napierala 8213b11655cSAlexander Motin if (lun->l_path != NULL) { 8223b11655cSAlexander Motin o = option_find(&lun->l_options, "file"); 8233b11655cSAlexander Motin if (o != NULL) { 8243b11655cSAlexander Motin option_set(o, lun->l_path); 8253b11655cSAlexander Motin } else { 8263b11655cSAlexander Motin o = option_new(&lun->l_options, "file", lun->l_path); 8273b11655cSAlexander Motin assert(o != NULL); 8283b11655cSAlexander Motin } 8293b11655cSAlexander Motin } 8303b11655cSAlexander Motin 8313b11655cSAlexander Motin o = option_find(&lun->l_options, "ctld_name"); 8323b11655cSAlexander Motin if (o != NULL) { 8333b11655cSAlexander Motin option_set(o, lun->l_name); 8343b11655cSAlexander Motin } else { 8353b11655cSAlexander Motin o = option_new(&lun->l_options, "ctld_name", lun->l_name); 8363b11655cSAlexander Motin assert(o != NULL); 8373b11655cSAlexander Motin } 8383b11655cSAlexander Motin 8393b11655cSAlexander Motin o = option_find(&lun->l_options, "scsiname"); 8403b11655cSAlexander Motin if (o == NULL && lun->l_scsiname != NULL) { 8413b11655cSAlexander Motin o = option_new(&lun->l_options, "scsiname", lun->l_scsiname); 8423b11655cSAlexander Motin assert(o != NULL); 8433b11655cSAlexander Motin } 8443b11655cSAlexander Motin 8458951f055SMarcelo Araujo if (!TAILQ_EMPTY(&lun->l_options)) { 8468951f055SMarcelo Araujo req.args_nvl = nvlist_create(0); 8478951f055SMarcelo Araujo if (req.args_nvl == NULL) { 8488951f055SMarcelo Araujo log_warn("error allocating nvlist"); 849a3977beaSAlexander Motin return (1); 850a3977beaSAlexander Motin } 851a3977beaSAlexander Motin 8528951f055SMarcelo Araujo TAILQ_FOREACH(o, &lun->l_options, o_next) 8538951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, o->o_name, o->o_value); 8548951f055SMarcelo Araujo 8558951f055SMarcelo Araujo req.args = nvlist_pack(req.args_nvl, &req.args_len); 8568951f055SMarcelo Araujo if (req.args == NULL) { 8572909ddd1SAlan Somers nvlist_destroy(req.args_nvl); 8588951f055SMarcelo Araujo log_warn("error packing nvlist"); 8598951f055SMarcelo Araujo return (1); 860a3977beaSAlexander Motin } 861a3977beaSAlexander Motin } 862a3977beaSAlexander Motin 863a3977beaSAlexander Motin error = ioctl(ctl_fd, CTL_LUN_REQ, &req); 8642909ddd1SAlan Somers free(req.args); 8658951f055SMarcelo Araujo nvlist_destroy(req.args_nvl); 8668951f055SMarcelo Araujo 867a3977beaSAlexander Motin if (error != 0) { 868009ea47eSEdward Tomasz Napierala log_warn("error issuing CTL_LUN_REQ ioctl"); 869009ea47eSEdward Tomasz Napierala return (1); 870009ea47eSEdward Tomasz Napierala } 871009ea47eSEdward Tomasz Napierala 87219720f41SAlexander Motin switch (req.status) { 87319720f41SAlexander Motin case CTL_LUN_ERROR: 87419720f41SAlexander Motin log_warnx("LUN modification error: %s", req.error_str); 875009ea47eSEdward Tomasz Napierala return (1); 87619720f41SAlexander Motin case CTL_LUN_WARNING: 87719720f41SAlexander Motin log_warnx("LUN modification warning: %s", req.error_str); 87819720f41SAlexander Motin break; 87919720f41SAlexander Motin case CTL_LUN_OK: 88019720f41SAlexander Motin break; 88119720f41SAlexander Motin default: 88219720f41SAlexander Motin log_warnx("unknown LUN modification status: %d", 883009ea47eSEdward Tomasz Napierala req.status); 884009ea47eSEdward Tomasz Napierala return (1); 885009ea47eSEdward Tomasz Napierala } 886009ea47eSEdward Tomasz Napierala 887009ea47eSEdward Tomasz Napierala return (0); 888009ea47eSEdward Tomasz Napierala } 889009ea47eSEdward Tomasz Napierala 890009ea47eSEdward Tomasz Napierala int 891009ea47eSEdward Tomasz Napierala kernel_lun_remove(struct lun *lun) 892009ea47eSEdward Tomasz Napierala { 893009ea47eSEdward Tomasz Napierala struct ctl_lun_req req; 894009ea47eSEdward Tomasz Napierala 895009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 896009ea47eSEdward Tomasz Napierala 897009ea47eSEdward Tomasz Napierala strlcpy(req.backend, lun->l_backend, sizeof(req.backend)); 898009ea47eSEdward Tomasz Napierala req.reqtype = CTL_LUNREQ_RM; 899009ea47eSEdward Tomasz Napierala 900009ea47eSEdward Tomasz Napierala req.reqdata.rm.lun_id = lun->l_ctl_lun; 901009ea47eSEdward Tomasz Napierala 902009ea47eSEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_LUN_REQ, &req) == -1) { 903009ea47eSEdward Tomasz Napierala log_warn("error issuing CTL_LUN_REQ ioctl"); 904009ea47eSEdward Tomasz Napierala return (1); 905009ea47eSEdward Tomasz Napierala } 906009ea47eSEdward Tomasz Napierala 90719720f41SAlexander Motin switch (req.status) { 90819720f41SAlexander Motin case CTL_LUN_ERROR: 90919720f41SAlexander Motin log_warnx("LUN removal error: %s", req.error_str); 910009ea47eSEdward Tomasz Napierala return (1); 91119720f41SAlexander Motin case CTL_LUN_WARNING: 91219720f41SAlexander Motin log_warnx("LUN removal warning: %s", req.error_str); 91319720f41SAlexander Motin break; 91419720f41SAlexander Motin case CTL_LUN_OK: 91519720f41SAlexander Motin break; 91619720f41SAlexander Motin default: 91719720f41SAlexander Motin log_warnx("unknown LUN removal status: %d", req.status); 918009ea47eSEdward Tomasz Napierala return (1); 919009ea47eSEdward Tomasz Napierala } 920009ea47eSEdward Tomasz Napierala 921009ea47eSEdward Tomasz Napierala return (0); 922009ea47eSEdward Tomasz Napierala } 923009ea47eSEdward Tomasz Napierala 924009ea47eSEdward Tomasz Napierala void 92563783933SJohn Baldwin kernel_handoff(struct ctld_connection *conn) 926009ea47eSEdward Tomasz Napierala { 927009ea47eSEdward Tomasz Napierala struct ctl_iscsi req; 928009ea47eSEdward Tomasz Napierala 929009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 930009ea47eSEdward Tomasz Napierala 931009ea47eSEdward Tomasz Napierala req.type = CTL_ISCSI_HANDOFF; 932009ea47eSEdward Tomasz Napierala strlcpy(req.data.handoff.initiator_name, 933009ea47eSEdward Tomasz Napierala conn->conn_initiator_name, sizeof(req.data.handoff.initiator_name)); 934009ea47eSEdward Tomasz Napierala strlcpy(req.data.handoff.initiator_addr, 935009ea47eSEdward Tomasz Napierala conn->conn_initiator_addr, sizeof(req.data.handoff.initiator_addr)); 936009ea47eSEdward Tomasz Napierala if (conn->conn_initiator_alias != NULL) { 937009ea47eSEdward Tomasz Napierala strlcpy(req.data.handoff.initiator_alias, 938009ea47eSEdward Tomasz Napierala conn->conn_initiator_alias, sizeof(req.data.handoff.initiator_alias)); 939009ea47eSEdward Tomasz Napierala } 9406d81c129SAlexander Motin memcpy(req.data.handoff.initiator_isid, conn->conn_initiator_isid, 9416d81c129SAlexander Motin sizeof(req.data.handoff.initiator_isid)); 942009ea47eSEdward Tomasz Napierala strlcpy(req.data.handoff.target_name, 943f7ae5bf8SEdward Tomasz Napierala conn->conn_target->t_name, sizeof(req.data.handoff.target_name)); 944a9d78210SEdward Tomasz Napierala if (conn->conn_portal->p_portal_group->pg_offload != NULL) { 94507b49a3eSEdward Tomasz Napierala strlcpy(req.data.handoff.offload, 946a9d78210SEdward Tomasz Napierala conn->conn_portal->p_portal_group->pg_offload, 947a9d78210SEdward Tomasz Napierala sizeof(req.data.handoff.offload)); 94807b49a3eSEdward Tomasz Napierala } 949ba3a2d31SEdward Tomasz Napierala #ifdef ICL_KERNEL_PROXY 950ba3a2d31SEdward Tomasz Napierala if (proxy_mode) 95163783933SJohn Baldwin req.data.handoff.connection_id = conn->conn.conn_socket; 952ba3a2d31SEdward Tomasz Napierala else 95363783933SJohn Baldwin req.data.handoff.socket = conn->conn.conn_socket; 954ba3a2d31SEdward Tomasz Napierala #else 95563783933SJohn Baldwin req.data.handoff.socket = conn->conn.conn_socket; 956ba3a2d31SEdward Tomasz Napierala #endif 957009ea47eSEdward Tomasz Napierala req.data.handoff.portal_group_tag = 958009ea47eSEdward Tomasz Napierala conn->conn_portal->p_portal_group->pg_tag; 95963783933SJohn Baldwin if (conn->conn.conn_header_digest == CONN_DIGEST_CRC32C) 960009ea47eSEdward Tomasz Napierala req.data.handoff.header_digest = CTL_ISCSI_DIGEST_CRC32C; 96163783933SJohn Baldwin if (conn->conn.conn_data_digest == CONN_DIGEST_CRC32C) 962009ea47eSEdward Tomasz Napierala req.data.handoff.data_digest = CTL_ISCSI_DIGEST_CRC32C; 96363783933SJohn Baldwin req.data.handoff.cmdsn = conn->conn.conn_cmdsn; 96463783933SJohn Baldwin req.data.handoff.statsn = conn->conn.conn_statsn; 965009ea47eSEdward Tomasz Napierala req.data.handoff.max_recv_data_segment_length = 96663783933SJohn Baldwin conn->conn.conn_max_recv_data_segment_length; 96797b84d34SNavdeep Parhar req.data.handoff.max_send_data_segment_length = 96863783933SJohn Baldwin conn->conn.conn_max_send_data_segment_length; 96963783933SJohn Baldwin req.data.handoff.max_burst_length = conn->conn.conn_max_burst_length; 97063783933SJohn Baldwin req.data.handoff.first_burst_length = 97163783933SJohn Baldwin conn->conn.conn_first_burst_length; 97263783933SJohn Baldwin req.data.handoff.immediate_data = conn->conn.conn_immediate_data; 973009ea47eSEdward Tomasz Napierala 9748cab2ed4SEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) { 975009ea47eSEdward Tomasz Napierala log_err(1, "error issuing CTL_ISCSI ioctl; " 976009ea47eSEdward Tomasz Napierala "dropping connection"); 9778cab2ed4SEdward Tomasz Napierala } 978009ea47eSEdward Tomasz Napierala 9798cab2ed4SEdward Tomasz Napierala if (req.status != CTL_ISCSI_OK) { 980009ea47eSEdward Tomasz Napierala log_errx(1, "error returned from CTL iSCSI handoff request: " 981009ea47eSEdward Tomasz Napierala "%s; dropping connection", req.error_str); 982009ea47eSEdward Tomasz Napierala } 9838cab2ed4SEdward Tomasz Napierala } 984009ea47eSEdward Tomasz Napierala 98507b49a3eSEdward Tomasz Napierala void 9867b02c1e8SJohn Baldwin kernel_limits(const char *offload, int s, int *max_recv_dsl, int *max_send_dsl, 98797b84d34SNavdeep Parhar int *max_burst_length, int *first_burst_length) 98807b49a3eSEdward Tomasz Napierala { 98907b49a3eSEdward Tomasz Napierala struct ctl_iscsi req; 99097b84d34SNavdeep Parhar struct ctl_iscsi_limits_params *cilp; 99107b49a3eSEdward Tomasz Napierala 99207b49a3eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 99307b49a3eSEdward Tomasz Napierala 99407b49a3eSEdward Tomasz Napierala req.type = CTL_ISCSI_LIMITS; 99597b84d34SNavdeep Parhar cilp = (struct ctl_iscsi_limits_params *)&(req.data.limits); 99607b49a3eSEdward Tomasz Napierala if (offload != NULL) { 99797b84d34SNavdeep Parhar strlcpy(cilp->offload, offload, sizeof(cilp->offload)); 99807b49a3eSEdward Tomasz Napierala } 9997b02c1e8SJohn Baldwin cilp->socket = s; 100007b49a3eSEdward Tomasz Napierala 100107b49a3eSEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) { 100207b49a3eSEdward Tomasz Napierala log_err(1, "error issuing CTL_ISCSI ioctl; " 100307b49a3eSEdward Tomasz Napierala "dropping connection"); 100407b49a3eSEdward Tomasz Napierala } 100507b49a3eSEdward Tomasz Napierala 100607b49a3eSEdward Tomasz Napierala if (req.status != CTL_ISCSI_OK) { 100707b49a3eSEdward Tomasz Napierala log_errx(1, "error returned from CTL iSCSI limits request: " 100807b49a3eSEdward Tomasz Napierala "%s; dropping connection", req.error_str); 100907b49a3eSEdward Tomasz Napierala } 101007b49a3eSEdward Tomasz Napierala 101197b84d34SNavdeep Parhar if (cilp->max_recv_data_segment_length != 0) { 101297b84d34SNavdeep Parhar *max_recv_dsl = cilp->max_recv_data_segment_length; 101397b84d34SNavdeep Parhar *max_send_dsl = cilp->max_recv_data_segment_length; 101497b84d34SNavdeep Parhar } 101597b84d34SNavdeep Parhar if (cilp->max_send_data_segment_length != 0) 101697b84d34SNavdeep Parhar *max_send_dsl = cilp->max_send_data_segment_length; 101797b84d34SNavdeep Parhar if (cilp->max_burst_length != 0) 101897b84d34SNavdeep Parhar *max_burst_length = cilp->max_burst_length; 101997b84d34SNavdeep Parhar if (cilp->first_burst_length != 0) 102097b84d34SNavdeep Parhar *first_burst_length = cilp->first_burst_length; 102197b84d34SNavdeep Parhar if (*max_burst_length < *first_burst_length) 102297b84d34SNavdeep Parhar *first_burst_length = *max_burst_length; 102397b84d34SNavdeep Parhar 102407b49a3eSEdward Tomasz Napierala if (offload != NULL) { 102597b84d34SNavdeep Parhar log_debugx("Kernel limits for offload \"%s\" are " 102697b84d34SNavdeep Parhar "MaxRecvDataSegment=%d, max_send_dsl=%d, " 102797b84d34SNavdeep Parhar "MaxBurstLength=%d, FirstBurstLength=%d", 102897b84d34SNavdeep Parhar offload, *max_recv_dsl, *max_send_dsl, *max_burst_length, 102997b84d34SNavdeep Parhar *first_burst_length); 103007b49a3eSEdward Tomasz Napierala } else { 103197b84d34SNavdeep Parhar log_debugx("Kernel limits are " 103297b84d34SNavdeep Parhar "MaxRecvDataSegment=%d, max_send_dsl=%d, " 103397b84d34SNavdeep Parhar "MaxBurstLength=%d, FirstBurstLength=%d", 103497b84d34SNavdeep Parhar *max_recv_dsl, *max_send_dsl, *max_burst_length, 103597b84d34SNavdeep Parhar *first_burst_length); 103607b49a3eSEdward Tomasz Napierala } 103707b49a3eSEdward Tomasz Napierala } 103807b49a3eSEdward Tomasz Napierala 1039009ea47eSEdward Tomasz Napierala int 104092847ee1SAlexander Motin kernel_port_add(struct port *port) 1041009ea47eSEdward Tomasz Napierala { 1042398290f2SAlexander Motin struct option *o; 1043009ea47eSEdward Tomasz Napierala struct ctl_port_entry entry; 1044917d38fbSAlexander Motin struct ctl_req req; 1045920c6cbaSAlexander Motin struct ctl_lun_map lm; 104692847ee1SAlexander Motin struct target *targ = port->p_target; 104792847ee1SAlexander Motin struct portal_group *pg = port->p_portal_group; 10488951f055SMarcelo Araujo char result_buf[NVLIST_BUFSIZE]; 10498951f055SMarcelo Araujo int error, i; 1050917d38fbSAlexander Motin 1051920c6cbaSAlexander Motin /* Create iSCSI port. */ 10528951f055SMarcelo Araujo if (port->p_portal_group || port->p_ioctl_port) { 1053917d38fbSAlexander Motin bzero(&req, sizeof(req)); 1054917d38fbSAlexander Motin req.reqtype = CTL_REQ_CREATE; 10558951f055SMarcelo Araujo 10568951f055SMarcelo Araujo if (port->p_portal_group) { 10578951f055SMarcelo Araujo strlcpy(req.driver, "iscsi", sizeof(req.driver)); 10588951f055SMarcelo Araujo req.args_nvl = nvlist_create(0); 10598951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, "cfiscsi_target", 10608951f055SMarcelo Araujo targ->t_name); 10618951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, 10628951f055SMarcelo Araujo "ctld_portal_group_name", pg->pg_name); 10638951f055SMarcelo Araujo nvlist_add_stringf(req.args_nvl, 10648951f055SMarcelo Araujo "cfiscsi_portal_group_tag", "%u", pg->pg_tag); 10658951f055SMarcelo Araujo 10668951f055SMarcelo Araujo if (targ->t_alias) { 10678951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, 10688951f055SMarcelo Araujo "cfiscsi_target_alias", targ->t_alias); 10698951f055SMarcelo Araujo } 10708951f055SMarcelo Araujo 1071398290f2SAlexander Motin TAILQ_FOREACH(o, &pg->pg_options, o_next) 10728951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, o->o_name, 10738951f055SMarcelo Araujo o->o_value); 10748951f055SMarcelo Araujo } 10758951f055SMarcelo Araujo 10768951f055SMarcelo Araujo if (port->p_ioctl_port) { 10778951f055SMarcelo Araujo strlcpy(req.driver, "ioctl", sizeof(req.driver)); 10788951f055SMarcelo Araujo req.args_nvl = nvlist_create(0); 10798951f055SMarcelo Araujo nvlist_add_stringf(req.args_nvl, "pp", "%d", 10808951f055SMarcelo Araujo port->p_ioctl_pp); 10818951f055SMarcelo Araujo nvlist_add_stringf(req.args_nvl, "vp", "%d", 10828951f055SMarcelo Araujo port->p_ioctl_vp); 10838951f055SMarcelo Araujo } 10848951f055SMarcelo Araujo 10858951f055SMarcelo Araujo req.args = nvlist_pack(req.args_nvl, &req.args_len); 10868951f055SMarcelo Araujo if (req.args == NULL) { 10872909ddd1SAlan Somers nvlist_destroy(req.args_nvl); 10888951f055SMarcelo Araujo log_warn("error packing nvlist"); 10898951f055SMarcelo Araujo return (1); 10908951f055SMarcelo Araujo } 10918951f055SMarcelo Araujo 10928951f055SMarcelo Araujo req.result = result_buf; 10938951f055SMarcelo Araujo req.result_len = sizeof(result_buf); 1094917d38fbSAlexander Motin error = ioctl(ctl_fd, CTL_PORT_REQ, &req); 10952909ddd1SAlan Somers free(req.args); 10968951f055SMarcelo Araujo nvlist_destroy(req.args_nvl); 10978951f055SMarcelo Araujo 1098917d38fbSAlexander Motin if (error != 0) { 1099917d38fbSAlexander Motin log_warn("error issuing CTL_PORT_REQ ioctl"); 1100917d38fbSAlexander Motin return (1); 1101917d38fbSAlexander Motin } 1102917d38fbSAlexander Motin if (req.status == CTL_LUN_ERROR) { 1103917d38fbSAlexander Motin log_warnx("error returned from port creation request: %s", 1104917d38fbSAlexander Motin req.error_str); 1105917d38fbSAlexander Motin return (1); 1106917d38fbSAlexander Motin } 1107917d38fbSAlexander Motin if (req.status != CTL_LUN_OK) { 1108917d38fbSAlexander Motin log_warnx("unknown port creation request status %d", 1109917d38fbSAlexander Motin req.status); 1110917d38fbSAlexander Motin return (1); 1111917d38fbSAlexander Motin } 11128951f055SMarcelo Araujo 11138951f055SMarcelo Araujo req.result_nvl = nvlist_unpack(result_buf, req.result_len, 0); 11148951f055SMarcelo Araujo if (req.result_nvl == NULL) { 11158951f055SMarcelo Araujo log_warnx("error unpacking result nvlist"); 11168951f055SMarcelo Araujo return (1); 11178951f055SMarcelo Araujo } 11188951f055SMarcelo Araujo 11198951f055SMarcelo Araujo port->p_ctl_port = nvlist_get_number(req.result_nvl, "port_id"); 11208951f055SMarcelo Araujo nvlist_destroy(req.result_nvl); 1121aadf439bSAlexander Motin } else if (port->p_pport) { 1122057abcb0SAlexander Motin port->p_ctl_port = port->p_pport->pp_ctl_port; 1123009ea47eSEdward Tomasz Napierala 1124aadf439bSAlexander Motin if (strncmp(targ->t_name, "naa.", 4) == 0 && 1125aadf439bSAlexander Motin strlen(targ->t_name) == 20) { 1126aadf439bSAlexander Motin bzero(&entry, sizeof(entry)); 1127aadf439bSAlexander Motin entry.port_type = CTL_PORT_NONE; 1128aadf439bSAlexander Motin entry.targ_port = port->p_ctl_port; 1129aadf439bSAlexander Motin entry.flags |= CTL_PORT_WWNN_VALID; 1130aadf439bSAlexander Motin entry.wwnn = strtoull(targ->t_name + 4, NULL, 16); 1131aadf439bSAlexander Motin if (ioctl(ctl_fd, CTL_SET_PORT_WWNS, &entry) == -1) 1132aadf439bSAlexander Motin log_warn("CTL_SET_PORT_WWNS ioctl failed"); 1133aadf439bSAlexander Motin } 1134aadf439bSAlexander Motin } 1135aadf439bSAlexander Motin 1136920c6cbaSAlexander Motin /* Explicitly enable mapping to block any access except allowed. */ 113792847ee1SAlexander Motin lm.port = port->p_ctl_port; 1138920c6cbaSAlexander Motin lm.plun = UINT32_MAX; 1139920c6cbaSAlexander Motin lm.lun = 0; 1140920c6cbaSAlexander Motin error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); 1141920c6cbaSAlexander Motin if (error != 0) 1142920c6cbaSAlexander Motin log_warn("CTL_LUN_MAP ioctl failed"); 1143009ea47eSEdward Tomasz Napierala 1144920c6cbaSAlexander Motin /* Map configured LUNs */ 1145920c6cbaSAlexander Motin for (i = 0; i < MAX_LUNS; i++) { 1146920c6cbaSAlexander Motin if (targ->t_luns[i] == NULL) 1147920c6cbaSAlexander Motin continue; 114892847ee1SAlexander Motin lm.port = port->p_ctl_port; 1149920c6cbaSAlexander Motin lm.plun = i; 1150920c6cbaSAlexander Motin lm.lun = targ->t_luns[i]->l_ctl_lun; 1151920c6cbaSAlexander Motin error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); 1152920c6cbaSAlexander Motin if (error != 0) 1153920c6cbaSAlexander Motin log_warn("CTL_LUN_MAP ioctl failed"); 1154920c6cbaSAlexander Motin } 1155920c6cbaSAlexander Motin 1156920c6cbaSAlexander Motin /* Enable port */ 1157920c6cbaSAlexander Motin bzero(&entry, sizeof(entry)); 115892847ee1SAlexander Motin entry.targ_port = port->p_ctl_port; 1159009ea47eSEdward Tomasz Napierala error = ioctl(ctl_fd, CTL_ENABLE_PORT, &entry); 1160009ea47eSEdward Tomasz Napierala if (error != 0) { 1161009ea47eSEdward Tomasz Napierala log_warn("CTL_ENABLE_PORT ioctl failed"); 1162009ea47eSEdward Tomasz Napierala return (-1); 1163009ea47eSEdward Tomasz Napierala } 1164009ea47eSEdward Tomasz Napierala 1165009ea47eSEdward Tomasz Napierala return (0); 1166009ea47eSEdward Tomasz Napierala } 1167009ea47eSEdward Tomasz Napierala 1168009ea47eSEdward Tomasz Napierala int 1169828524c1SAlexander Motin kernel_port_update(struct port *port, struct port *oport) 1170920c6cbaSAlexander Motin { 1171920c6cbaSAlexander Motin struct ctl_lun_map lm; 117292847ee1SAlexander Motin struct target *targ = port->p_target; 1173828524c1SAlexander Motin struct target *otarg = oport->p_target; 1174920c6cbaSAlexander Motin int error, i; 1175828524c1SAlexander Motin uint32_t olun; 1176920c6cbaSAlexander Motin 1177920c6cbaSAlexander Motin /* Map configured LUNs and unmap others */ 1178920c6cbaSAlexander Motin for (i = 0; i < MAX_LUNS; i++) { 117992847ee1SAlexander Motin lm.port = port->p_ctl_port; 1180920c6cbaSAlexander Motin lm.plun = i; 1181920c6cbaSAlexander Motin if (targ->t_luns[i] == NULL) 1182920c6cbaSAlexander Motin lm.lun = UINT32_MAX; 1183920c6cbaSAlexander Motin else 1184920c6cbaSAlexander Motin lm.lun = targ->t_luns[i]->l_ctl_lun; 1185828524c1SAlexander Motin if (otarg->t_luns[i] == NULL) 1186828524c1SAlexander Motin olun = UINT32_MAX; 1187828524c1SAlexander Motin else 1188828524c1SAlexander Motin olun = otarg->t_luns[i]->l_ctl_lun; 1189828524c1SAlexander Motin if (lm.lun == olun) 1190828524c1SAlexander Motin continue; 1191920c6cbaSAlexander Motin error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); 1192920c6cbaSAlexander Motin if (error != 0) 1193920c6cbaSAlexander Motin log_warn("CTL_LUN_MAP ioctl failed"); 1194920c6cbaSAlexander Motin } 1195920c6cbaSAlexander Motin return (0); 1196920c6cbaSAlexander Motin } 1197920c6cbaSAlexander Motin 1198920c6cbaSAlexander Motin int 119992847ee1SAlexander Motin kernel_port_remove(struct port *port) 1200009ea47eSEdward Tomasz Napierala { 1201057abcb0SAlexander Motin struct ctl_port_entry entry; 1202057abcb0SAlexander Motin struct ctl_lun_map lm; 1203917d38fbSAlexander Motin struct ctl_req req; 120492847ee1SAlexander Motin struct target *targ = port->p_target; 120592847ee1SAlexander Motin struct portal_group *pg = port->p_portal_group; 1206009ea47eSEdward Tomasz Napierala int error; 1207009ea47eSEdward Tomasz Napierala 1208057abcb0SAlexander Motin /* Disable port */ 1209057abcb0SAlexander Motin bzero(&entry, sizeof(entry)); 1210057abcb0SAlexander Motin entry.targ_port = port->p_ctl_port; 1211057abcb0SAlexander Motin error = ioctl(ctl_fd, CTL_DISABLE_PORT, &entry); 1212057abcb0SAlexander Motin if (error != 0) { 1213057abcb0SAlexander Motin log_warn("CTL_DISABLE_PORT ioctl failed"); 1214057abcb0SAlexander Motin return (-1); 1215057abcb0SAlexander Motin } 1216057abcb0SAlexander Motin 12178951f055SMarcelo Araujo /* Remove iSCSI or ioctl port. */ 12188951f055SMarcelo Araujo if (port->p_portal_group || port->p_ioctl_port) { 1219917d38fbSAlexander Motin bzero(&req, sizeof(req)); 12208951f055SMarcelo Araujo strlcpy(req.driver, port->p_ioctl_port ? "ioctl" : "iscsi", 12218951f055SMarcelo Araujo sizeof(req.driver)); 1222917d38fbSAlexander Motin req.reqtype = CTL_REQ_REMOVE; 12238951f055SMarcelo Araujo req.args_nvl = nvlist_create(0); 12248951f055SMarcelo Araujo if (req.args_nvl == NULL) 12258951f055SMarcelo Araujo log_err(1, "nvlist_create"); 12268951f055SMarcelo Araujo 12278951f055SMarcelo Araujo if (port->p_ioctl_port) 12288951f055SMarcelo Araujo nvlist_add_stringf(req.args_nvl, "port_id", "%d", 12298951f055SMarcelo Araujo port->p_ctl_port); 12308951f055SMarcelo Araujo else { 12318951f055SMarcelo Araujo nvlist_add_string(req.args_nvl, "cfiscsi_target", 12328951f055SMarcelo Araujo targ->t_name); 12338951f055SMarcelo Araujo nvlist_add_stringf(req.args_nvl, 12348951f055SMarcelo Araujo "cfiscsi_portal_group_tag", "%u", pg->pg_tag); 12358951f055SMarcelo Araujo } 12368951f055SMarcelo Araujo 12378951f055SMarcelo Araujo req.args = nvlist_pack(req.args_nvl, &req.args_len); 12388951f055SMarcelo Araujo if (req.args == NULL) { 12392909ddd1SAlan Somers nvlist_destroy(req.args_nvl); 12408951f055SMarcelo Araujo log_warn("error packing nvlist"); 12418951f055SMarcelo Araujo return (1); 12428951f055SMarcelo Araujo } 12438951f055SMarcelo Araujo 1244917d38fbSAlexander Motin error = ioctl(ctl_fd, CTL_PORT_REQ, &req); 12452909ddd1SAlan Somers free(req.args); 12468951f055SMarcelo Araujo nvlist_destroy(req.args_nvl); 12478951f055SMarcelo Araujo 1248009ea47eSEdward Tomasz Napierala if (error != 0) { 1249917d38fbSAlexander Motin log_warn("error issuing CTL_PORT_REQ ioctl"); 1250917d38fbSAlexander Motin return (1); 1251917d38fbSAlexander Motin } 1252917d38fbSAlexander Motin if (req.status == CTL_LUN_ERROR) { 1253917d38fbSAlexander Motin log_warnx("error returned from port removal request: %s", 1254917d38fbSAlexander Motin req.error_str); 1255917d38fbSAlexander Motin return (1); 1256917d38fbSAlexander Motin } 1257917d38fbSAlexander Motin if (req.status != CTL_LUN_OK) { 1258917d38fbSAlexander Motin log_warnx("unknown port removal request status %d", 1259917d38fbSAlexander Motin req.status); 1260917d38fbSAlexander Motin return (1); 1261009ea47eSEdward Tomasz Napierala } 1262057abcb0SAlexander Motin } else { 1263057abcb0SAlexander Motin /* Disable LUN mapping. */ 1264057abcb0SAlexander Motin lm.port = port->p_ctl_port; 1265057abcb0SAlexander Motin lm.plun = UINT32_MAX; 1266057abcb0SAlexander Motin lm.lun = UINT32_MAX; 1267057abcb0SAlexander Motin error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); 1268057abcb0SAlexander Motin if (error != 0) 1269057abcb0SAlexander Motin log_warn("CTL_LUN_MAP ioctl failed"); 1270057abcb0SAlexander Motin } 1271009ea47eSEdward Tomasz Napierala return (0); 1272009ea47eSEdward Tomasz Napierala } 1273009ea47eSEdward Tomasz Napierala 1274009ea47eSEdward Tomasz Napierala #ifdef ICL_KERNEL_PROXY 1275009ea47eSEdward Tomasz Napierala void 12768cab2ed4SEdward Tomasz Napierala kernel_listen(struct addrinfo *ai, bool iser, int portal_id) 1277009ea47eSEdward Tomasz Napierala { 1278009ea47eSEdward Tomasz Napierala struct ctl_iscsi req; 1279009ea47eSEdward Tomasz Napierala 1280009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 1281009ea47eSEdward Tomasz Napierala 1282009ea47eSEdward Tomasz Napierala req.type = CTL_ISCSI_LISTEN; 1283009ea47eSEdward Tomasz Napierala req.data.listen.iser = iser; 1284009ea47eSEdward Tomasz Napierala req.data.listen.domain = ai->ai_family; 1285009ea47eSEdward Tomasz Napierala req.data.listen.socktype = ai->ai_socktype; 1286009ea47eSEdward Tomasz Napierala req.data.listen.protocol = ai->ai_protocol; 1287009ea47eSEdward Tomasz Napierala req.data.listen.addr = ai->ai_addr; 1288009ea47eSEdward Tomasz Napierala req.data.listen.addrlen = ai->ai_addrlen; 12898cab2ed4SEdward Tomasz Napierala req.data.listen.portal_id = portal_id; 1290009ea47eSEdward Tomasz Napierala 12918cab2ed4SEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) 1292b3361aabSEdward Tomasz Napierala log_err(1, "error issuing CTL_ISCSI ioctl"); 1293b3361aabSEdward Tomasz Napierala 1294b3361aabSEdward Tomasz Napierala if (req.status != CTL_ISCSI_OK) { 1295b3361aabSEdward Tomasz Napierala log_errx(1, "error returned from CTL iSCSI listen: %s", 1296b3361aabSEdward Tomasz Napierala req.error_str); 1297b3361aabSEdward Tomasz Napierala } 1298009ea47eSEdward Tomasz Napierala } 1299009ea47eSEdward Tomasz Napierala 13008cab2ed4SEdward Tomasz Napierala void 13018eab95d6SEdward Tomasz Napierala kernel_accept(int *connection_id, int *portal_id, 13028eab95d6SEdward Tomasz Napierala struct sockaddr *client_sa, socklen_t *client_salen) 1303009ea47eSEdward Tomasz Napierala { 1304009ea47eSEdward Tomasz Napierala struct ctl_iscsi req; 13058eab95d6SEdward Tomasz Napierala struct sockaddr_storage ss; 1306009ea47eSEdward Tomasz Napierala 1307009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 1308009ea47eSEdward Tomasz Napierala 1309009ea47eSEdward Tomasz Napierala req.type = CTL_ISCSI_ACCEPT; 13108eab95d6SEdward Tomasz Napierala req.data.accept.initiator_addr = (struct sockaddr *)&ss; 1311009ea47eSEdward Tomasz Napierala 13128cab2ed4SEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) 13138cab2ed4SEdward Tomasz Napierala log_err(1, "error issuing CTL_ISCSI ioctl"); 1314b3361aabSEdward Tomasz Napierala 1315b3361aabSEdward Tomasz Napierala if (req.status != CTL_ISCSI_OK) { 13168cab2ed4SEdward Tomasz Napierala log_errx(1, "error returned from CTL iSCSI accept: %s", 1317b3361aabSEdward Tomasz Napierala req.error_str); 1318009ea47eSEdward Tomasz Napierala } 1319009ea47eSEdward Tomasz Napierala 13208cab2ed4SEdward Tomasz Napierala *connection_id = req.data.accept.connection_id; 13218cab2ed4SEdward Tomasz Napierala *portal_id = req.data.accept.portal_id; 13228eab95d6SEdward Tomasz Napierala *client_salen = req.data.accept.initiator_addrlen; 13238eab95d6SEdward Tomasz Napierala memcpy(client_sa, &ss, *client_salen); 1324009ea47eSEdward Tomasz Napierala } 1325009ea47eSEdward Tomasz Napierala 1326009ea47eSEdward Tomasz Napierala void 1327009ea47eSEdward Tomasz Napierala kernel_send(struct pdu *pdu) 1328009ea47eSEdward Tomasz Napierala { 1329009ea47eSEdward Tomasz Napierala struct ctl_iscsi req; 1330009ea47eSEdward Tomasz Napierala 1331009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 1332009ea47eSEdward Tomasz Napierala 1333009ea47eSEdward Tomasz Napierala req.type = CTL_ISCSI_SEND; 1334009ea47eSEdward Tomasz Napierala req.data.send.connection_id = pdu->pdu_connection->conn_socket; 1335009ea47eSEdward Tomasz Napierala req.data.send.bhs = pdu->pdu_bhs; 1336009ea47eSEdward Tomasz Napierala req.data.send.data_segment_len = pdu->pdu_data_len; 1337009ea47eSEdward Tomasz Napierala req.data.send.data_segment = pdu->pdu_data; 1338009ea47eSEdward Tomasz Napierala 1339b3361aabSEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) { 1340009ea47eSEdward Tomasz Napierala log_err(1, "error issuing CTL_ISCSI ioctl; " 1341009ea47eSEdward Tomasz Napierala "dropping connection"); 1342b3361aabSEdward Tomasz Napierala } 1343009ea47eSEdward Tomasz Napierala 1344b3361aabSEdward Tomasz Napierala if (req.status != CTL_ISCSI_OK) { 1345009ea47eSEdward Tomasz Napierala log_errx(1, "error returned from CTL iSCSI send: " 1346009ea47eSEdward Tomasz Napierala "%s; dropping connection", req.error_str); 1347009ea47eSEdward Tomasz Napierala } 1348b3361aabSEdward Tomasz Napierala } 1349009ea47eSEdward Tomasz Napierala 1350009ea47eSEdward Tomasz Napierala void 1351009ea47eSEdward Tomasz Napierala kernel_receive(struct pdu *pdu) 1352009ea47eSEdward Tomasz Napierala { 135397b84d34SNavdeep Parhar struct connection *conn; 1354009ea47eSEdward Tomasz Napierala struct ctl_iscsi req; 1355009ea47eSEdward Tomasz Napierala 135697b84d34SNavdeep Parhar conn = pdu->pdu_connection; 135797b84d34SNavdeep Parhar pdu->pdu_data = malloc(conn->conn_max_recv_data_segment_length); 1358009ea47eSEdward Tomasz Napierala if (pdu->pdu_data == NULL) 1359009ea47eSEdward Tomasz Napierala log_err(1, "malloc"); 1360009ea47eSEdward Tomasz Napierala 1361009ea47eSEdward Tomasz Napierala bzero(&req, sizeof(req)); 1362009ea47eSEdward Tomasz Napierala 1363009ea47eSEdward Tomasz Napierala req.type = CTL_ISCSI_RECEIVE; 136497b84d34SNavdeep Parhar req.data.receive.connection_id = conn->conn_socket; 1365009ea47eSEdward Tomasz Napierala req.data.receive.bhs = pdu->pdu_bhs; 136697b84d34SNavdeep Parhar req.data.receive.data_segment_len = 136797b84d34SNavdeep Parhar conn->conn_max_recv_data_segment_length; 1368009ea47eSEdward Tomasz Napierala req.data.receive.data_segment = pdu->pdu_data; 1369009ea47eSEdward Tomasz Napierala 1370b3361aabSEdward Tomasz Napierala if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) { 1371009ea47eSEdward Tomasz Napierala log_err(1, "error issuing CTL_ISCSI ioctl; " 1372009ea47eSEdward Tomasz Napierala "dropping connection"); 1373b3361aabSEdward Tomasz Napierala } 1374009ea47eSEdward Tomasz Napierala 1375b3361aabSEdward Tomasz Napierala if (req.status != CTL_ISCSI_OK) { 1376009ea47eSEdward Tomasz Napierala log_errx(1, "error returned from CTL iSCSI receive: " 1377009ea47eSEdward Tomasz Napierala "%s; dropping connection", req.error_str); 1378b3361aabSEdward Tomasz Napierala } 1379009ea47eSEdward Tomasz Napierala 1380009ea47eSEdward Tomasz Napierala } 1381009ea47eSEdward Tomasz Napierala 1382009ea47eSEdward Tomasz Napierala #endif /* ICL_KERNEL_PROXY */ 1383009ea47eSEdward Tomasz Napierala 1384009ea47eSEdward Tomasz Napierala /* 1385009ea47eSEdward Tomasz Napierala * XXX: I CANT INTO LATIN 1386009ea47eSEdward Tomasz Napierala */ 1387009ea47eSEdward Tomasz Napierala void 1388009ea47eSEdward Tomasz Napierala kernel_capsicate(void) 1389009ea47eSEdward Tomasz Napierala { 1390009ea47eSEdward Tomasz Napierala cap_rights_t rights; 1391009ea47eSEdward Tomasz Napierala const unsigned long cmds[] = { CTL_ISCSI }; 1392009ea47eSEdward Tomasz Napierala 1393009ea47eSEdward Tomasz Napierala cap_rights_init(&rights, CAP_IOCTL); 13941489776dSMariusz Zaborski if (caph_rights_limit(ctl_fd, &rights) < 0) 1395009ea47eSEdward Tomasz Napierala log_err(1, "cap_rights_limit"); 1396009ea47eSEdward Tomasz Napierala 13971489776dSMariusz Zaborski if (caph_ioctls_limit(ctl_fd, cmds, nitems(cmds)) < 0) 1398009ea47eSEdward Tomasz Napierala log_err(1, "cap_ioctls_limit"); 1399009ea47eSEdward Tomasz Napierala 14001489776dSMariusz Zaborski if (caph_enter() < 0) 1401009ea47eSEdward Tomasz Napierala log_err(1, "cap_enter"); 1402009ea47eSEdward Tomasz Napierala 1403009ea47eSEdward Tomasz Napierala if (cap_sandboxed()) 1404009ea47eSEdward Tomasz Napierala log_debugx("Capsicum capability mode enabled"); 1405009ea47eSEdward Tomasz Napierala else 1406009ea47eSEdward Tomasz Napierala log_warnx("Capsicum capability mode not supported"); 1407009ea47eSEdward Tomasz Napierala } 1408009ea47eSEdward Tomasz Napierala 1409