1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2017 Red Hat, Inc. <contact@redhat.com>
8 * Author: Adam C. Emerson <aemerson@redhat.com>
10 * This is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License version
12 * 2.1, as published by the Free Software Foundation. See file
18 #include "common/error_code.h"
20 #pragma GCC diagnostic push
21 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
22 #pragma clang diagnostic push
23 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
25 using boost::system::error_category
;
26 using boost::system::error_condition
;
27 using boost::system::generic_category
;
28 using boost::system::system_category
;
32 // A category for error conditions particular to Ceph
34 class ceph_error_category
: public converting_category
{
36 ceph_error_category(){}
37 const char* name() const noexcept override
;
38 using converting_category::message
;
39 std::string
message(int ev
) const override
;
40 const char* message(int ev
, char*, std::size_t) const noexcept override
;
41 using converting_category::equivalent
;
42 bool equivalent(const boost::system::error_code
& c
,
43 int ev
) const noexcept override
;
44 int from_code(int ev
) const noexcept override
;
47 const char* ceph_error_category::name() const noexcept
{
51 const char* ceph_error_category::message(int ev
, char*,
52 std::size_t) const noexcept
{
56 switch (static_cast<errc
>(ev
)) {
58 case errc::not_in_map
:
59 return "Map does not contain requested entry.";
60 case errc::does_not_exist
:
61 return "Item does not exist";
63 return "An internal fault or inconsistency occurred";
65 return "Already exists";
66 case errc::limit_exceeded
:
67 return "Attempt to use too much";
69 return "Authentication error";
71 return "Conflict detected or precondition failed";
74 return "Unknown error.";
77 std::string
ceph_error_category::message(int ev
) const {
78 return message(ev
, nullptr, 0);
81 bool ceph_error_category::equivalent(const boost::system::error_code
& c
,
82 int ev
) const noexcept
{
83 if (c
.category() == system_category()) {
84 if (c
.value() == boost::system::errc::no_such_file_or_directory
) {
85 if (ev
== static_cast<int>(errc::not_in_map
) ||
86 ev
== static_cast<int>(errc::does_not_exist
)) {
87 // Blargh. A bunch of stuff returns ENOENT now, so just to be safe.
91 if (c
.value() == boost::system::errc::io_error
) {
92 if (ev
== static_cast<int>(errc::failure
)) {
96 if (c
.value() == boost::system::errc::file_exists
) {
97 if (ev
== static_cast<int>(errc::exists
)) {
101 if (c
.value() == boost::system::errc::no_space_on_device
||
102 c
.value() == boost::system::errc::invalid_argument
) {
103 if (ev
== static_cast<int>(errc::limit_exceeded
)) {
107 if (c
.value() == boost::system::errc::operation_not_permitted
) {
108 if (ev
== static_cast<int>(ceph::errc::conflict
)) {
116 int ceph_error_category::from_code(int ev
) const noexcept
{
120 switch (static_cast<errc
>(ev
)) {
121 case errc::not_in_map
:
122 case errc::does_not_exist
:
129 case errc::limit_exceeded
:
139 const error_category
& ceph_category() noexcept
{
140 static const ceph_error_category c
;
145 // This is part of the glue for hooking new code to old. Since
146 // Context* and other things give us integer codes from errno, wrap
147 // them in an error_code.
148 [[nodiscard
]] boost::system::error_code
to_error_code(int ret
) noexcept
152 return { std::abs(ret
), boost::system::system_category() };
155 // This is more complicated. For the case of categories defined
156 // elsewhere, we have to convert everything here.
157 [[nodiscard
]] int from_error_code(boost::system::error_code e
) noexcept
162 auto c
= dynamic_cast<const converting_category
*>(&e
.category());
163 // For categories we define
165 return c
->from_code(e
.value());
167 // For categories matching values of errno
168 if (e
.category() == boost::system::system_category() ||
169 e
.category() == boost::system::generic_category() ||
170 // ASIO uses the system category for these and matches system
172 e
.category() == boost::asio::error::get_netdb_category() ||
173 e
.category() == boost::asio::error::get_addrinfo_category())
176 if (e
.category() == boost::asio::error::get_misc_category()) {
177 // These values are specific to asio
179 case boost::asio::error::already_open
:
181 case boost::asio::error::eof
:
183 case boost::asio::error::not_found
:
185 case boost::asio::error::fd_set_failure
:
189 // Add any other categories we use here.
191 // Marcus likes this as a sentinel for 'Error code? What error code?'
195 #pragma GCC diagnostic pop
196 #pragma clang diagnostic pop