The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=afcae14d2f241484c9c52aaa130a313eec0991c9
commit afcae14d2f241484c9c52aaa130a313eec0991c9 Author: John Baldwin <j...@freebsd.org> AuthorDate: 2025-08-04 19:38:07 +0000 Commit: John Baldwin <j...@freebsd.org> CommitDate: 2025-08-04 19:38:07 +0000 ctld: Convert struct lun to a C++ class - Use std::string and freebsd::nvlist_up for class members. - Turn most lun_* and kernel_lun_* functions into class methods. Sponsored by: Chelsio Communications Pull Request: https://github.com/freebsd/freebsd-src/pull/1794 --- usr.sbin/ctld/conf.cc | 91 ++-------- usr.sbin/ctld/ctld.cc | 434 ++++++++++++++++++++++++++++++++---------------- usr.sbin/ctld/ctld.hh | 60 ++++--- usr.sbin/ctld/kernel.cc | 159 +++++++----------- 4 files changed, 401 insertions(+), 343 deletions(-) diff --git a/usr.sbin/ctld/conf.cc b/usr.sbin/ctld/conf.cc index ce2003b09880..8913cccd5889 100644 --- a/usr.sbin/ctld/conf.cc +++ b/usr.sbin/ctld/conf.cc @@ -277,126 +277,55 @@ lun_finish(void) bool lun_add_option(const char *name, const char *value) { - return (option_new(lun->l_options, name, value)); + return (lun->add_option(name, value)); } bool lun_set_backend(const char *value) { - if (lun->l_backend != NULL) { - log_warnx("backend for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - - lun->l_backend = checked_strdup(value); - return (true); + return (lun->set_backend(value)); } bool lun_set_blocksize(size_t value) { - if (lun->l_blocksize != 0) { - log_warnx("blocksize for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - lun->l_blocksize = value; - return (true); + return (lun->set_blocksize(value)); } bool lun_set_device_type(const char *value) { - const char *errstr; - int device_type; - - if (strcasecmp(value, "disk") == 0 || - strcasecmp(value, "direct") == 0) - device_type = T_DIRECT; - else if (strcasecmp(value, "processor") == 0) - device_type = T_PROCESSOR; - else if (strcasecmp(value, "cd") == 0 || - strcasecmp(value, "cdrom") == 0 || - strcasecmp(value, "dvd") == 0 || - strcasecmp(value, "dvdrom") == 0) - device_type = T_CDROM; - else { - device_type = strtonum(value, 0, 15, &errstr); - if (errstr != NULL) { - log_warnx("invalid device-type \"%s\" for lun \"%s\"", value, - lun->l_name); - return (false); - } - } - - lun->l_device_type = device_type; - return (true); + return (lun->set_device_type(value)); } bool lun_set_device_id(const char *value) { - if (lun->l_device_id != NULL) { - log_warnx("device_id for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - - lun->l_device_id = checked_strdup(value); - return (true); + return (lun->set_device_id(value)); } bool lun_set_path(const char *value) { - if (lun->l_path != NULL) { - log_warnx("path for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - - lun->l_path = checked_strdup(value); - return (true); + return (lun->set_path(value)); } bool lun_set_serial(const char *value) { - if (lun->l_serial != NULL) { - log_warnx("serial for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - - lun->l_serial = checked_strdup(value); - return (true); + return (lun->set_serial(value)); } bool lun_set_size(uint64_t value) { - if (lun->l_size != 0) { - log_warnx("size for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - - lun->l_size = value; - return (true); + return (lun->set_size(value)); } bool lun_set_ctl_lun(uint32_t value) { - - if (lun->l_ctl_lun >= 0) { - log_warnx("ctl_lun for lun \"%s\" specified more than once", - lun->l_name); - return (false); - } - lun->l_ctl_lun = value; - return (true); + return (lun->set_ctl_lun(value)); } bool @@ -616,7 +545,7 @@ target_start_lun(u_int id) if (new_lun == NULL) return (false); - lun_set_scsiname(new_lun, name); + new_lun->set_scsiname(name); free(name); target->t_luns[id] = new_lun; diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc index 29bbea126273..1dbc6988b9d1 100644 --- a/usr.sbin/ctld/ctld.cc +++ b/usr.sbin/ctld/ctld.cc @@ -101,7 +101,6 @@ conf_new(void) struct conf *conf; conf = new struct conf(); - TAILQ_INIT(&conf->conf_luns); TAILQ_INIT(&conf->conf_targets); conf->conf_isns_period = 900; @@ -116,13 +115,10 @@ conf_new(void) void conf_delete(struct conf *conf) { - struct lun *lun, *ltmp; struct target *targ, *tmp; assert(conf->conf_pidfh == NULL); - TAILQ_FOREACH_SAFE(lun, &conf->conf_luns, l_next, ltmp) - lun_delete(lun); TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp) target_delete(targ); free(conf->conf_pidfile_path); @@ -1162,71 +1158,243 @@ target_find(struct conf *conf, const char *name) return (NULL); } +lun::lun(struct conf *conf, std::string_view name) + : l_conf(conf), l_options(nvlist_create(0)), l_name(name) +{ +} + struct lun * lun_new(struct conf *conf, const char *name) { - struct lun *lun; - - lun = lun_find(conf, name); - if (lun != NULL) { + const auto &pair = conf->conf_luns.try_emplace(name, + std::make_unique<lun>(conf, name)); + if (!pair.second) { log_warnx("duplicated lun \"%s\"", name); return (NULL); } - - lun = reinterpret_cast<struct lun *>(calloc(1, sizeof(*lun))); - if (lun == NULL) - log_err(1, "calloc"); - lun->l_conf = conf; - lun->l_name = checked_strdup(name); - lun->l_options = nvlist_create(0); - TAILQ_INSERT_TAIL(&conf->conf_luns, lun, l_next); - lun->l_ctl_lun = -1; - - return (lun); + return (pair.first->second.get()); } -void -lun_delete(struct lun *lun) +static void +conf_delete_target_luns(struct conf *conf, struct lun *lun) { struct target *targ; int i; - TAILQ_FOREACH(targ, &lun->l_conf->conf_targets, t_next) { + TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { for (i = 0; i < MAX_LUNS; i++) { if (targ->t_luns[i] == lun) targ->t_luns[i] = NULL; } } - TAILQ_REMOVE(&lun->l_conf->conf_luns, lun, l_next); - - nvlist_destroy(lun->l_options); - free(lun->l_name); - free(lun->l_backend); - free(lun->l_device_id); - free(lun->l_path); - free(lun->l_scsiname); - free(lun->l_serial); - free(lun); } struct lun * lun_find(const struct conf *conf, const char *name) { - struct lun *lun; + auto it = conf->conf_luns.find(name); + if (it == conf->conf_luns.end()) + return (nullptr); + return (it->second.get()); +} - TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { - if (strcmp(lun->l_name, name) == 0) - return (lun); +static void +nvlist_replace_string(nvlist_t *nvl, const char *name, const char *value) +{ + if (nvlist_exists_string(nvl, name)) + nvlist_free_string(nvl, name); + nvlist_add_string(nvl, name, value); +} + +freebsd::nvlist_up +lun::options() const +{ + freebsd::nvlist_up nvl(nvlist_clone(l_options.get())); + if (!l_path.empty()) + nvlist_replace_string(nvl.get(), "file", l_path.c_str()); + + nvlist_replace_string(nvl.get(), "ctld_name", l_name.c_str()); + + if (!nvlist_exists_string(nvl.get(), "scsiname") && + !l_scsiname.empty()) + nvlist_add_string(nvl.get(), "scsiname", l_scsiname.c_str()); + return (nvl); +} + +bool +lun::add_option(const char *name, const char *value) +{ + return (option_new(l_options.get(), name, value)); +} + +bool +lun::set_backend(std::string_view value) +{ + if (!l_backend.empty()) { + log_warnx("backend for lun \"%s\" specified more than once", + name()); + return (false); } - return (NULL); + l_backend = value; + return (true); +} + +bool +lun::set_blocksize(size_t value) +{ + if (l_blocksize != 0) { + log_warnx("blocksize for lun \"%s\" specified more than once", + name()); + return (false); + } + l_blocksize = value; + return (true); +} + +bool +lun::set_ctl_lun(uint32_t value) +{ + if (l_ctl_lun >= 0) { + log_warnx("ctl_lun for lun \"%s\" specified more than once", + name()); + return (false); + } + + l_ctl_lun = value; + return (true); +} + +bool +lun::set_device_type(uint8_t device_type) +{ + if (device_type > 15) { + log_warnx("invalid device-type \"%u\" for lun \"%s\"", + device_type, name()); + return (false); + } + + l_device_type = device_type; + return (true); +} + +bool +lun::set_device_type(const char *value) +{ + const char *errstr; + int device_type; + + if (strcasecmp(value, "disk") == 0 || + strcasecmp(value, "direct") == 0) + device_type = T_DIRECT; + else if (strcasecmp(value, "processor") == 0) + device_type = T_PROCESSOR; + else if (strcasecmp(value, "cd") == 0 || + strcasecmp(value, "cdrom") == 0 || + strcasecmp(value, "dvd") == 0 || + strcasecmp(value, "dvdrom") == 0) + device_type = T_CDROM; + else { + device_type = strtonum(value, 0, 15, &errstr); + if (errstr != NULL) { + log_warnx("invalid device-type \"%s\" for lun \"%s\"", + value, name()); + return (false); + } + } + + l_device_type = device_type; + return (true); +} + +bool +lun::set_device_id(std::string_view value) +{ + if (!l_device_id.empty()) { + log_warnx("device_id for lun \"%s\" specified more than once", + name()); + return (false); + } + + l_device_id = value; + return (true); +} + +bool +lun::set_path(std::string_view value) +{ + if (!l_path.empty()) { + log_warnx("path for lun \"%s\" specified more than once", + name()); + return (false); + } + + l_path = value; + return (true); } void -lun_set_scsiname(struct lun *lun, const char *value) +lun::set_scsiname(std::string_view value) { - free(lun->l_scsiname); - lun->l_scsiname = checked_strdup(value); + l_scsiname = value; +} + +bool +lun::set_serial(std::string_view value) +{ + if (!l_serial.empty()) { + log_warnx("serial for lun \"%s\" specified more than once", + name()); + return (false); + } + + l_serial = value; + return (true); +} + +bool +lun::set_size(uint64_t value) +{ + if (l_size != 0) { + log_warnx("size for lun \"%s\" specified more than once", + name()); + return (false); + } + + l_size = value; + return (true); +} + + +bool +lun::changed(const struct lun &newlun) const +{ + if (l_backend != newlun.l_backend) { + log_debugx("backend for lun \"%s\", CTL lun %d changed; " + "removing", name(), l_ctl_lun); + return (true); + } + if (l_blocksize != newlun.l_blocksize) { + log_debugx("blocksize for lun \"%s\", CTL lun %d changed; " + "removing", name(), l_ctl_lun); + return (true); + } + if (l_device_id != newlun.l_device_id) { + log_debugx("device-id for lun \"%s\", CTL lun %d changed; " + "removing", name(), l_ctl_lun); + return (true); + } + if (l_path != newlun.l_path) { + log_debugx("path for lun \"%s\", CTL lun %d, changed; " + "removing", name(), l_ctl_lun); + return (true); + } + if (l_serial != newlun.l_serial) { + log_debugx("serial for lun \"%s\", CTL lun %d changed; " + "removing", name(), l_ctl_lun); + return (true); + } + return (false); } bool @@ -1305,59 +1473,45 @@ connection_new(struct portal *portal, int fd, const char *host, return (conn); } -static bool -conf_verify_lun(struct lun *lun) +bool +lun::verify() { - const struct lun *lun2; - - if (lun->l_backend == NULL) - lun->l_backend = checked_strdup("block"); - if (strcmp(lun->l_backend, "block") == 0) { - if (lun->l_path == NULL) { + if (l_backend.empty()) + l_backend = "block"; + if (l_backend == "block") { + if (l_path.empty()) { log_warnx("missing path for lun \"%s\"", - lun->l_name); + name()); return (false); } - } else if (strcmp(lun->l_backend, "ramdisk") == 0) { - if (lun->l_size == 0) { + } else if (l_backend == "ramdisk") { + if (l_size == 0) { log_warnx("missing size for ramdisk-backed lun \"%s\"", - lun->l_name); + name()); return (false); } - if (lun->l_path != NULL) { + if (!l_path.empty()) { log_warnx("path must not be specified " "for ramdisk-backed lun \"%s\"", - lun->l_name); + name()); return (false); } } - if (lun->l_blocksize == 0) { - if (lun->l_device_type == T_CDROM) - lun->l_blocksize = DEFAULT_CD_BLOCKSIZE; + if (l_blocksize == 0) { + if (l_device_type == T_CDROM) + l_blocksize = DEFAULT_CD_BLOCKSIZE; else - lun->l_blocksize = DEFAULT_BLOCKSIZE; - } else if (lun->l_blocksize < 0) { - log_warnx("invalid blocksize for lun \"%s\"; " - "must be larger than 0", lun->l_name); + l_blocksize = DEFAULT_BLOCKSIZE; + } else if (l_blocksize < 0) { + log_warnx("invalid blocksize %d for lun \"%s\"; " + "must be larger than 0", l_blocksize, name()); return (false); } - if (lun->l_size != 0 && lun->l_size % lun->l_blocksize != 0) { + if (l_size != 0 && (l_size % l_blocksize) != 0) { log_warnx("invalid size for lun \"%s\"; " - "must be multiple of blocksize", lun->l_name); + "must be multiple of blocksize", name()); return (false); } - TAILQ_FOREACH(lun2, &lun->l_conf->conf_luns, l_next) { - if (lun == lun2) - continue; - if (lun->l_path != NULL && lun2->l_path != NULL && - strcmp(lun->l_path, lun2->l_path) == 0) { - log_debugx("WARNING: path \"%s\" duplicated " - "between lun \"%s\", and " - "lun \"%s\"", lun->l_path, - lun->l_name, lun2->l_name); - } - } - return (true); } @@ -1366,17 +1520,32 @@ conf_verify(struct conf *conf) { struct portal_group *pg; struct target *targ; - struct lun *lun; bool found; int i; if (conf->conf_pidfile_path == NULL) conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE); - TAILQ_FOREACH(lun, &conf->conf_luns, l_next) { - if (!conf_verify_lun(lun)) + std::unordered_map<std::string, struct lun *> path_map; + for (const auto &kv : conf->conf_luns) { + struct lun *lun = kv.second.get(); + if (!lun->verify()) return (false); + + const std::string &path = lun->path(); + if (path.empty()) + continue; + + const auto &pair = path_map.try_emplace(path, lun); + if (!pair.second) { + struct lun *lun2 = pair.first->second; + log_debugx("WARNING: path \"%s\" duplicated " + "between lun \"%s\", and " + "lun \"%s\"", path.c_str(), + lun->name(), lun2->name()); + } } + TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { if (targ->t_auth_group == NULL) { targ->t_auth_group = auth_group_find(conf, @@ -1560,8 +1729,7 @@ conf::reuse_portal_group_socket(struct portal &newp) static int conf_apply(struct conf *oldconf, struct conf *newconf) { - struct lun *oldlun, *newlun, *tmplun; - int changed, cumulated_error = 0, error; + int cumulated_error = 0; if (oldconf->conf_debug != newconf->conf_debug) { log_debugx("changing debug level to %d", newconf->conf_debug); @@ -1646,101 +1814,75 @@ conf_apply(struct conf *oldconf, struct conf *newconf) * Second, remove any LUNs present in the old configuration * and missing in the new one. */ - TAILQ_FOREACH_SAFE(oldlun, &oldconf->conf_luns, l_next, tmplun) { - newlun = lun_find(newconf, oldlun->l_name); - if (newlun == NULL) { + for (auto it = oldconf->conf_luns.begin(); + it != oldconf->conf_luns.end(); ) { + struct lun *oldlun = it->second.get(); + + auto newit = newconf->conf_luns.find(it->first); + if (newit == newconf->conf_luns.end()) { log_debugx("lun \"%s\", CTL lun %d " "not found in new configuration; " - "removing", oldlun->l_name, oldlun->l_ctl_lun); - error = kernel_lun_remove(oldlun); - if (error != 0) { + "removing", oldlun->name(), oldlun->ctl_lun()); + if (!oldlun->kernel_remove()) { log_warnx("failed to remove lun \"%s\", " "CTL lun %d", - oldlun->l_name, oldlun->l_ctl_lun); + oldlun->name(), oldlun->ctl_lun()); cumulated_error++; } + it++; continue; } /* * Also remove the LUNs changed by more than size. */ - changed = 0; - assert(oldlun->l_backend != NULL); - assert(newlun->l_backend != NULL); - if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { - log_debugx("backend for lun \"%s\", " - "CTL lun %d changed; removing", - oldlun->l_name, oldlun->l_ctl_lun); - changed = 1; - } - if (oldlun->l_blocksize != newlun->l_blocksize) { - log_debugx("blocksize for lun \"%s\", " - "CTL lun %d changed; removing", - oldlun->l_name, oldlun->l_ctl_lun); - changed = 1; - } - if (newlun->l_device_id != NULL && - (oldlun->l_device_id == NULL || - strcmp(oldlun->l_device_id, newlun->l_device_id) != - 0)) { - log_debugx("device-id for lun \"%s\", " - "CTL lun %d changed; removing", - oldlun->l_name, oldlun->l_ctl_lun); - changed = 1; - } - if (newlun->l_path != NULL && - (oldlun->l_path == NULL || - strcmp(oldlun->l_path, newlun->l_path) != 0)) { - log_debugx("path for lun \"%s\", " - "CTL lun %d, changed; removing", - oldlun->l_name, oldlun->l_ctl_lun); - changed = 1; - } - if (newlun->l_serial != NULL && - (oldlun->l_serial == NULL || - strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { - log_debugx("serial for lun \"%s\", " - "CTL lun %d changed; removing", - oldlun->l_name, oldlun->l_ctl_lun); - changed = 1; - } - if (changed) { - error = kernel_lun_remove(oldlun); - if (error != 0) { + struct lun *newlun = newit->second.get(); + if (oldlun->changed(*newlun)) { + if (!oldlun->kernel_remove()) { log_warnx("failed to remove lun \"%s\", " "CTL lun %d", - oldlun->l_name, oldlun->l_ctl_lun); + oldlun->name(), oldlun->ctl_lun()); cumulated_error++; } - lun_delete(oldlun); + + /* + * Delete the lun from the old configuration + * so it is added as a new LUN below. + */ + it = oldconf->conf_luns.erase(it); continue; } - newlun->l_ctl_lun = oldlun->l_ctl_lun; + newlun->set_ctl_lun(oldlun->ctl_lun()); + it++; } - TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) { - oldlun = lun_find(oldconf, newlun->l_name); - if (oldlun != NULL) { + for (auto it = newconf->conf_luns.begin(); + it != newconf->conf_luns.end(); ) { + struct lun *newlun = it->second.get(); + + auto oldit = oldconf->conf_luns.find(it->first); + if (oldit != oldconf->conf_luns.end()) { log_debugx("modifying lun \"%s\", CTL lun %d", - newlun->l_name, newlun->l_ctl_lun); - error = kernel_lun_modify(newlun); - if (error != 0) { + newlun->name(), newlun->ctl_lun()); + if (!newlun->kernel_modify()) { log_warnx("failed to " "modify lun \"%s\", CTL lun %d", - newlun->l_name, newlun->l_ctl_lun); + newlun->name(), newlun->ctl_lun()); cumulated_error++; } + it++; continue; } - log_debugx("adding lun \"%s\"", newlun->l_name); - error = kernel_lun_add(newlun); - if (error != 0) { - log_warnx("failed to add lun \"%s\"", newlun->l_name); - lun_delete(newlun); + + log_debugx("adding lun \"%s\"", newlun->name()); + if (!newlun->kernel_add()) { + log_warnx("failed to add lun \"%s\"", newlun->name()); + conf_delete_target_luns(newconf, newlun); + it = newconf->conf_luns.erase(it); cumulated_error++; - } + } else + it++; } /* diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh index 5ccb24160eac..7fb0ed7a8bea 100644 --- a/usr.sbin/ctld/ctld.hh +++ b/usr.sbin/ctld/ctld.hh @@ -303,20 +303,47 @@ private: }; struct lun { - TAILQ_ENTRY(lun) l_next; + lun(struct conf *conf, std::string_view name); + + const char *name() const { return l_name.c_str(); } + const std::string &path() const { return l_path; } + int ctl_lun() const { return l_ctl_lun; } + + freebsd::nvlist_up options() const; + + bool add_option(const char *name, const char *value); + bool set_backend(std::string_view value); + bool set_blocksize(size_t value); + bool set_ctl_lun(uint32_t value); + bool set_device_type(uint8_t device_type); + bool set_device_type(const char *value); + bool set_device_id(std::string_view value); + bool set_path(std::string_view value); + void set_scsiname(std::string_view value); + bool set_serial(std::string_view value); + bool set_size(uint64_t value); + + bool changed(const struct lun &old) const; + bool verify(); + + bool kernel_add(); + bool kernel_modify() const; + bool kernel_remove() const; + +private: struct conf *l_conf; - nvlist_t *l_options; - char *l_name; - char *l_backend; - uint8_t l_device_type; - int l_blocksize; - char *l_device_id; - char *l_path; - char *l_scsiname; - char *l_serial; - uint64_t l_size; - - int l_ctl_lun; + freebsd::nvlist_up l_options; + std::string l_name; + std::string l_backend; + uint8_t l_device_type = 0; + int l_blocksize = 0; + std::string l_device_id; + std::string l_path; + std::string l_scsiname; + std::string l_serial; + uint64_t l_size = 0; + + int l_ctl_lun = -1; }; struct target { @@ -351,7 +378,7 @@ struct conf { bool reuse_portal_group_socket(struct portal &newp); char *conf_pidfile_path = nullptr; - TAILQ_HEAD(, lun) conf_luns; + std::unordered_map<std::string, std::unique_ptr<lun>> conf_luns; TAILQ_HEAD(, target) conf_targets; std::unordered_map<std::string, auth_group_sp> conf_auth_groups; std::unordered_map<std::string, std::unique_ptr<port>> conf_ports; @@ -464,17 +491,12 @@ struct target *target_find(struct conf *conf, const char *name); struct lun *lun_new(struct conf *conf, const char *name); -void lun_delete(struct lun *lun); struct lun *lun_find(const struct conf *conf, const char *name); -void lun_set_scsiname(struct lun *lun, const char *value); bool option_new(nvlist_t *nvl, const char *name, const char *value); void kernel_init(void); -int kernel_lun_add(struct lun *lun); -int kernel_lun_modify(struct lun *lun); -int kernel_lun_remove(struct lun *lun); void kernel_handoff(struct ctld_connection *conn); void kernel_capsicate(void); diff --git a/usr.sbin/ctld/kernel.cc b/usr.sbin/ctld/kernel.cc index 8ccfd3cd55fa..7ce1bf210027 100644 --- a/usr.sbin/ctld/kernel.cc +++ b/usr.sbin/ctld/kernel.cc @@ -410,7 +410,7 @@ conf_new_from_kernel(struct kports &kports) const char *key; char *str, *name; void *cookie; - int error, len, retval; + int len, retval; bzero(&devlist, sizeof(devlist)); STAILQ_INIT(&devlist.lun_list); @@ -602,7 +602,7 @@ retry_port: log_warnx("found CTL lun %ju \"%s\", " "also backed by CTL lun %d; ignoring", (uintmax_t)lun->lun_id, lun->ctld_name, - cl->l_ctl_lun); + cl->ctl_lun()); continue; } @@ -614,34 +614,27 @@ retry_port: log_warnx("lun_new failed"); continue; } - cl->l_backend = lun->backend_type; - lun->backend_type = NULL; - cl->l_device_type = lun->device_type; - cl->l_blocksize = lun->blocksize; - cl->l_device_id = lun->device_id; - lun->device_id = NULL; - cl->l_serial = lun->serial_number; - lun->serial_number = NULL; - cl->l_size = lun->size_blocks * cl->l_blocksize; - cl->l_ctl_lun = lun->lun_id; + cl->set_backend(lun->backend_type); + cl->set_device_type(lun->device_type); + cl->set_blocksize(lun->blocksize); + cl->set_device_id(lun->device_id); + cl->set_serial(lun->serial_number); + cl->set_size(lun->size_blocks * lun->blocksize); + cl->set_ctl_lun(lun->lun_id); cookie = NULL; while ((key = nvlist_next(lun->attr_list, NULL, &cookie)) != NULL) { if (strcmp(key, "file") == 0 || strcmp(key, "dev") == 0) { - cl->l_path = checked_strdup( - cnvlist_get_string(cookie)); + cl->set_path(cnvlist_get_string(cookie)); continue; } - nvlist_add_string(cl->l_options, key, - cnvlist_get_string(cookie)); - error = nvlist_error(cl->l_options); - if (error != 0) - log_warnc(error, "unable to add CTL lun option " + if (!cl->add_option(key, cnvlist_get_string(cookie))) + log_warnx("unable to add CTL lun option " "%s for CTL lun %ju \"%s\"", key, (uintmax_t)lun->lun_id, - cl->l_name); + cl->name()); } } while ((lun = STAILQ_FIRST(&devlist.lun_list))) { @@ -653,65 +646,47 @@ retry_port: return (conf); } -static void -nvlist_replace_string(nvlist_t *nvl, const char *name, const char *value) -{ - if (nvlist_exists_string(nvl, name)) - nvlist_free_string(nvl, name); - nvlist_add_string(nvl, name, value); -} - -int -kernel_lun_add(struct lun *lun) +bool +lun::kernel_add() { struct ctl_lun_req req; int error; bzero(&req, sizeof(req)); - strlcpy(req.backend, lun->l_backend, sizeof(req.backend)); + strlcpy(req.backend, l_backend.c_str(), sizeof(req.backend)); req.reqtype = CTL_LUNREQ_CREATE; - req.reqdata.create.blocksize_bytes = lun->l_blocksize; + req.reqdata.create.blocksize_bytes = l_blocksize; - if (lun->l_size != 0) - req.reqdata.create.lun_size_bytes = lun->l_size; + if (l_size != 0) + req.reqdata.create.lun_size_bytes = l_size; - if (lun->l_ctl_lun >= 0) { - req.reqdata.create.req_lun_id = lun->l_ctl_lun; + if (l_ctl_lun >= 0) { + req.reqdata.create.req_lun_id = l_ctl_lun; req.reqdata.create.flags |= CTL_LUN_FLAG_ID_REQ; } req.reqdata.create.flags |= CTL_LUN_FLAG_DEV_TYPE; - req.reqdata.create.device_type = lun->l_device_type; + req.reqdata.create.device_type = l_device_type; - if (lun->l_serial != NULL) { - strncpy((char *)req.reqdata.create.serial_num, lun->l_serial, + if (!l_serial.empty()) { + strncpy((char *)req.reqdata.create.serial_num, l_serial.c_str(), sizeof(req.reqdata.create.serial_num)); req.reqdata.create.flags |= CTL_LUN_FLAG_SERIAL_NUM; } - if (lun->l_device_id != NULL) { - strncpy((char *)req.reqdata.create.device_id, lun->l_device_id, - sizeof(req.reqdata.create.device_id)); + if (!l_device_id.empty()) { + strncpy((char *)req.reqdata.create.device_id, + l_device_id.c_str(), sizeof(req.reqdata.create.device_id)); req.reqdata.create.flags |= CTL_LUN_FLAG_DEVID; } - if (lun->l_path != NULL) - nvlist_replace_string(lun->l_options, "file", lun->l_path); - - nvlist_replace_string(lun->l_options, "ctld_name", lun->l_name); - - if (!nvlist_exists_string(lun->l_options, "scsiname") && - lun->l_scsiname != NULL) - nvlist_add_string(lun->l_options, "scsiname", lun->l_scsiname); - - if (!nvlist_empty(lun->l_options)) { - req.args = nvlist_pack(lun->l_options, &req.args_len); - if (req.args == NULL) { - log_warn("error packing nvlist"); - return (1); - } *** 174 LINES SKIPPED ***