1 /* $NetBSD: memlock.c,v 1.1.1.1 2008/12/22 00:18:13 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of LVM2. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "lib.h" 19 #include "memlock.h" 20 #include "defaults.h" 21 #include "config.h" 22 #include "toolcontext.h" 23 24 #include <limits.h> 25 #include <fcntl.h> 26 #include <unistd.h> 27 #include <sys/mman.h> 28 #include <sys/time.h> 29 #include <sys/resource.h> 30 31 #ifndef DEVMAPPER_SUPPORT 32 33 void memlock_inc(void) 34 { 35 return; 36 } 37 void memlock_dec(void) 38 { 39 return; 40 } 41 int memlock(void) 42 { 43 return 0; 44 } 45 void memlock_init(struct cmd_context *cmd) 46 { 47 return; 48 } 49 50 #else /* DEVMAPPER_SUPPORT */ 51 52 static size_t _size_stack; 53 static size_t _size_malloc_tmp; 54 static size_t _size_malloc = 2000000; 55 56 static void *_malloc_mem = NULL; 57 static int _memlock_count = 0; 58 static int _priority; 59 static int _default_priority; 60 61 static void _touch_memory(void *mem, size_t size) 62 { 63 size_t pagesize = lvm_getpagesize(); 64 void *pos = mem; 65 void *end = mem + size - sizeof(long); 66 67 while (pos < end) { 68 *(long *) pos = 1; 69 pos += pagesize; 70 } 71 } 72 73 static void _allocate_memory(void) 74 { 75 void *stack_mem, *temp_malloc_mem; 76 77 if ((stack_mem = alloca(_size_stack))) 78 _touch_memory(stack_mem, _size_stack); 79 80 if ((temp_malloc_mem = malloc(_size_malloc_tmp))) 81 _touch_memory(temp_malloc_mem, _size_malloc_tmp); 82 83 if ((_malloc_mem = malloc(_size_malloc))) 84 _touch_memory(_malloc_mem, _size_malloc); 85 86 free(temp_malloc_mem); 87 } 88 89 static void _release_memory(void) 90 { 91 free(_malloc_mem); 92 } 93 94 /* Stop memory getting swapped out */ 95 static void _lock_mem(void) 96 { 97 #ifdef MCL_CURRENT 98 if (mlockall(MCL_CURRENT | MCL_FUTURE)) 99 log_sys_error("mlockall", ""); 100 else 101 log_very_verbose("Locking memory"); 102 #endif 103 _allocate_memory(); 104 105 errno = 0; 106 if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno) 107 log_sys_error("getpriority", ""); 108 else 109 if (setpriority(PRIO_PROCESS, 0, _default_priority)) 110 log_error("setpriority %d failed: %s", 111 _default_priority, strerror(errno)); 112 } 113 114 static void _unlock_mem(void) 115 { 116 #ifdef MCL_CURRENT 117 if (munlockall()) 118 log_sys_error("munlockall", ""); 119 else 120 log_very_verbose("Unlocking memory"); 121 #endif 122 _release_memory(); 123 if (setpriority(PRIO_PROCESS, 0, _priority)) 124 log_error("setpriority %u failed: %s", _priority, 125 strerror(errno)); 126 } 127 128 void memlock_inc(void) 129 { 130 if (!_memlock_count++) 131 _lock_mem(); 132 log_debug("memlock_count inc to %d", _memlock_count); 133 } 134 135 void memlock_dec(void) 136 { 137 if (_memlock_count && (!--_memlock_count)) 138 _unlock_mem(); 139 log_debug("memlock_count dec to %d", _memlock_count); 140 } 141 142 int memlock(void) 143 { 144 return _memlock_count; 145 } 146 147 void memlock_init(struct cmd_context *cmd) 148 { 149 _size_stack = find_config_tree_int(cmd, 150 "activation/reserved_stack", 151 DEFAULT_RESERVED_STACK) * 1024; 152 _size_malloc_tmp = find_config_tree_int(cmd, 153 "activation/reserved_memory", 154 DEFAULT_RESERVED_MEMORY) * 1024; 155 _default_priority = find_config_tree_int(cmd, 156 "activation/process_priority", 157 DEFAULT_PROCESS_PRIORITY); 158 } 159 160 #endif 161