YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/errno.cc
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
33
#include "yb/util/errno.h"
34
#include <errno.h>
35
36
#include <string.h>
37
38
#include "yb/util/flag_tags.h"
39
#include "yb/util/status.h"
40
41
DEFINE_bool(suicide_on_eio, true,
42
            "Kill the process if an I/O operation results in EIO");
43
TAG_FLAG(suicide_on_eio, advanced);
44
45
namespace yb {
46
47
1.42M
void ErrnoToCString(int err, char *buf, size_t buf_len) {
48
1.42M
  CHECK_GT(buf_len, 0);
49
1.42M
#if !defined(__GLIBC__) || \
50
1.42M
  ((_POSIX_C_SOURCE >= 200112 || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE))
51
  // Using POSIX version 'int strerror_r(...)'.
52
1.42M
  int ret = strerror_r(err, buf, buf_len);
53
1.42M
  if (ret && ret != ERANGE && ret != EINVAL) {
54
0
    strncpy(buf, "unknown error", buf_len);
55
0
    buf[buf_len - 1] = '\0';
56
0
  }
57
#else
58
  // Using GLIBC version
59
  char* ret = strerror_r(err, buf, buf_len);
60
  if (ret != buf) {
61
    strncpy(buf, ret, buf_len);
62
    buf[buf_len - 1] = '\0';
63
  }
64
#endif
65
1.42M
}
66
67
static const std::string kErrnoCategoryName = "system error";
68
69
static StatusCategoryRegisterer errno_category_registerer(
70
    StatusCategoryDescription::Make<ErrnoTag>(&kErrnoCategoryName));
71
72
namespace internal {
73
74
1.07M
Status StatusFromErrno(const std::string& context, int err_number, const char* file, int line) {
75
1.07M
  if (err_number == 0)
76
0
    return Status::OK();
77
78
1.07M
  Errno err(err_number);
79
1.07M
  switch (err_number) {
80
55.0k
    case ENOENT:
81
55.0k
      return Status(Status::kNotFound, file, line, context, err);
82
1.01M
    case EEXIST:
83
1.01M
      return Status(Status::kAlreadyPresent, file, line, context, err);
84
0
    case EOPNOTSUPP:
85
0
      return Status(Status::kNotSupported, file, line, context, err);
86
3.77k
  }
87
3.77k
  return Status(Status::kIOError, file, line, context, err);
88
3.77k
}
89
90
// TODO: reconsider this approach to handling EIO.
91
Status StatusFromErrnoSpecialEioHandling(
92
1.07M
    const std::string& context, int err_number, const char* file, int line) {
93
1.07M
  if (err_number == EIO && FLAGS_suicide_on_eio) {
94
    // TODO: This is very, very coarse-grained. A more comprehensive
95
    // approach is described in KUDU-616.
96
0
    LOG(FATAL) << "Fatal I/O error, context: " << context;
97
0
  }
98
1.07M
  return internal::StatusFromErrno(context, err_number, file, line);
99
1.07M
}
100
101
// A lot of C library functions return zero on success and non-zero on failure, with the actual
102
// error code stored in errno. This helper constructs a Status based on errno but only if the return
103
// value (the rv parameter) is non-zero.
104
8.02k
Status StatusFromErrnoIfNonZero(const std::string& context, int rv, const char* file, int line) {
105
8.02k
  if (rv == 0)
106
8.01k
    return Status::OK();
107
4
  decltype(errno) cached_errno = errno;
108
4
  if (cached_errno == 0) {
109
0
    return Status(
110
0
        Status::kIllegalState, file, line, Format("$0: return value is $1 but errno is zero",
111
0
        context, rv));
112
0
  }
113
4
  return StatusFromErrno(context, cached_errno, file, line);
114
4
}
115
116
}  // namespace internal
117
} // namespace yb