| 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 | |