1 | /* |
2 | Copyright (c) 2000, 2010, Oracle and/or its affiliates |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | #include "mysys_priv.h" |
18 | #include "my_static.h" |
19 | #include <m_string.h> |
20 | |
21 | /* |
22 | set how many open files we want to be able to handle |
23 | |
24 | SYNOPSIS |
25 | set_maximum_open_files() |
26 | max_file_limit Files to open |
27 | |
28 | NOTES |
29 | The request may not fulfilled becasue of system limitations |
30 | |
31 | RETURN |
32 | Files available to open. |
33 | May be more or less than max_file_limit! |
34 | */ |
35 | |
36 | #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) |
37 | |
38 | #ifndef RLIM_INFINITY |
39 | #define RLIM_INFINITY ((uint) 0xffffffff) |
40 | #endif |
41 | |
42 | static uint set_max_open_files(uint max_file_limit) |
43 | { |
44 | struct rlimit rlimit; |
45 | uint old_cur; |
46 | DBUG_ENTER("set_max_open_files" ); |
47 | DBUG_PRINT("enter" ,("files: %u" , max_file_limit)); |
48 | |
49 | if (!getrlimit(RLIMIT_NOFILE,&rlimit)) |
50 | { |
51 | old_cur= (uint) rlimit.rlim_cur; |
52 | DBUG_PRINT("info" , ("rlim_cur: %u rlim_max: %u" , |
53 | (uint) rlimit.rlim_cur, |
54 | (uint) rlimit.rlim_max)); |
55 | if ((ulonglong) rlimit.rlim_cur == (ulonglong) RLIM_INFINITY) |
56 | rlimit.rlim_cur = max_file_limit; |
57 | if (rlimit.rlim_cur >= max_file_limit) |
58 | DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */ |
59 | rlimit.rlim_cur= rlimit.rlim_max= max_file_limit; |
60 | if (setrlimit(RLIMIT_NOFILE, &rlimit)) |
61 | max_file_limit= old_cur; /* Use original value */ |
62 | else |
63 | { |
64 | rlimit.rlim_cur= 0; /* Safety if next call fails */ |
65 | (void) getrlimit(RLIMIT_NOFILE,&rlimit); |
66 | DBUG_PRINT("info" , ("rlim_cur: %u" , (uint) rlimit.rlim_cur)); |
67 | if (rlimit.rlim_cur) /* If call didn't fail */ |
68 | max_file_limit= (uint) rlimit.rlim_cur; |
69 | } |
70 | } |
71 | DBUG_PRINT("exit" ,("max_file_limit: %u" , max_file_limit)); |
72 | DBUG_RETURN(max_file_limit); |
73 | } |
74 | |
75 | #else |
76 | static uint set_max_open_files(uint max_file_limit) |
77 | { |
78 | /* We don't know the limit. Return best guess */ |
79 | return MY_MIN(max_file_limit, OS_FILE_LIMIT); |
80 | } |
81 | #endif |
82 | |
83 | |
84 | /* |
85 | Change number of open files |
86 | |
87 | SYNOPSIS: |
88 | my_set_max_open_files() |
89 | files Number of requested files |
90 | |
91 | RETURN |
92 | number of files available for open |
93 | */ |
94 | |
95 | uint my_set_max_open_files(uint files) |
96 | { |
97 | struct st_my_file_info *tmp; |
98 | DBUG_ENTER("my_set_max_open_files" ); |
99 | DBUG_PRINT("enter" ,("files: %u my_file_limit: %u" , files, my_file_limit)); |
100 | |
101 | files+= MY_FILE_MIN; |
102 | files= set_max_open_files(MY_MIN(files, OS_FILE_LIMIT)); |
103 | if (files <= MY_NFILE) |
104 | DBUG_RETURN(files); |
105 | |
106 | if (!(tmp= (struct st_my_file_info*) my_malloc(sizeof(*tmp) * files, |
107 | MYF(MY_WME)))) |
108 | DBUG_RETURN(MY_NFILE); |
109 | |
110 | /* Copy any initialized files */ |
111 | memcpy((char*) tmp, (char*) my_file_info, |
112 | sizeof(*tmp) * MY_MIN(my_file_limit, files)); |
113 | bzero((char*) (tmp + my_file_limit), |
114 | MY_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp)); |
115 | my_free_open_file_info(); /* Free if already allocated */ |
116 | my_file_info= tmp; |
117 | my_file_limit= files; |
118 | DBUG_PRINT("exit" ,("files: %u" , files)); |
119 | DBUG_RETURN(files); |
120 | } |
121 | |
122 | |
123 | void my_free_open_file_info() |
124 | { |
125 | DBUG_ENTER("my_free_file_info" ); |
126 | if (my_file_info != my_file_info_default) |
127 | { |
128 | /* Copy data back for my_print_open_files */ |
129 | memcpy((char*) my_file_info_default, my_file_info, |
130 | sizeof(*my_file_info_default)* MY_NFILE); |
131 | my_free(my_file_info); |
132 | my_file_info= my_file_info_default; |
133 | my_file_limit= MY_NFILE; |
134 | } |
135 | DBUG_VOID_RETURN; |
136 | } |
137 | |