Changeset 120
- Timestamp:
- 07/26/05 03:54:14 (3 years ago)
- Files:
-
- TODO (modified) (2 diffs)
- debian/changelog (modified) (1 diff)
- doc/swapspace.8 (modified) (2 diffs)
- src/log.c (modified) (3 diffs)
- src/log.h (modified) (1 diff)
- src/main.c (modified) (6 diffs)
- src/memory.c (modified) (13 diffs)
- src/memory.h (modified) (1 diff)
- src/opts.c (modified) (2 diffs)
- src/state.c (modified) (2 diffs)
- src/swaps.c (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
TODO
r103 r120 6 6 sure this is a bad thing, but it might create a risk of leaking files. 7 7 8 Describe the algorithm's finite state machine in Dot format. 8 Describe the algorithm's finite state machine in Dot format, and convert to some 9 readable format. 9 10 10 11 Adaptive cooldown times: recognize pattern of consistent policy reversals too … … 18 19 allow acquired state to be saved so as to reduce warmup time. 19 20 20 Rephrase "meekness" as "elasticity".21 debian/changelog
r105 r120 19 19 * Checks swapdir's filesystem size on startup 20 20 * Rewritten swapfile sizing formula 21 * Cleaned up logging system 22 * Rephrased "meekness" as "elasticity" 21 23 22 24 -- Jeroen T. Vermeulen <jtv@sipa.or.th> Thu, 14 July 2005 19:30:00 +0700 doc/swapspace.8
r106 r120 63 63 behaviour in the face of varying memory requirements. 64 64 .TP 65 \fB\-B\fR \fIp\fR, \fB\-\-buffer_ meekness\fR=\fIp\fR65 \fB\-B\fR \fIp\fR, \fB\-\-buffer_elasticity\fR=\fIp\fR 66 66 Consider \fIp\fR% of system-allocated I/O buffers to be available for other use. 67 67 .TP … … 69 69 Read \fIfile\fR instead of the default configuration file. 70 70 .TP 71 \fB\-C\fR \fIp\fR, \fB\-\-cache_ meekness\fR=\fIp\fR71 \fB\-C\fR \fIp\fR, \fB\-\-cache_elasticity\fR=\fIp\fR 72 72 Consider \fIp\fR% of filesystem cache to be available for other use. 73 73 .TP src/log.c
r102 r120 17 17 */ 18 18 #include <errno.h> 19 #include <stdarg.h> 19 20 #include <stdio.h> 20 21 #include <string.h> … … 72 73 73 74 74 void log_msg(int priority, const char msg[])75 static void vlog(int priority, const char fmt[], va_list ap) 75 76 { 76 if (logging) syslog(priority, "%s", msg); 77 else fprintf(stream(priority), "%s%s\n", prefix(priority), msg); 78 } 79 80 81 void log_perr(int priority, const char msg[]) 82 { 83 log_perrno(priority, msg, errno); 84 } 85 86 87 void log_perrno(int priority, const char msg[], int fault_errno) 88 { 89 if (!fault_errno) 90 log_msg(priority, msg); 77 if (logging) 78 { 79 vsyslog(priority, fmt, ap); 80 } 91 81 else 92 82 { 93 const char *std = strerror(fault_errno); 94 if (logging) syslog(priority, "%s: %s", msg, std); 95 else fprintf(stream(priority), "%s%s: %s\n", prefix(priority), msg, std); 83 FILE *const out = stream(priority); 84 fprintf(out, "%s", prefix(priority)); 85 vfprintf(out, fmt, ap); 86 fprintf(out, "\n"); 96 87 } 97 88 } 98 89 99 90 100 void log _str(int priority, const char msg[], const char arg[])91 void logm(int priority, const char fmt[], ...) 101 92 { 102 if (logging) syslog(priority, "%s '%s'", msg, arg); 103 else fprintf(stream(priority), "%s%s '%s'\n", prefix(priority), msg, arg); 93 va_list ap; 94 va_start(ap, fmt); 95 vlog(priority, fmt, ap); 96 va_end(ap); 104 97 } 105 98 106 99 107 void log_perr no_str(int priority, const char msg[], const char arg[], int err)100 void log_perr(int priority, const char msg[], int fault_errno) 108 101 { 109 if (!err) 110 { 111 log_str(priority, msg, arg); 112 } 113 else 114 { 115 const char *std = strerror(err); 116 if (logging) 117 syslog(priority, "%s '%s': %s", msg, arg, std); 118 else 119 fprintf(stream(priority),"%s%s '%s': %s\n",prefix(priority),msg,arg,std); 120 } 102 if (!fault_errno) logm(priority, "%s", msg); 103 else logm(priority, "%s: %s", msg, strerror(fault_errno)); 121 104 } 122 105 123 106 124 void log_perr_str(int priority, const char msg[], const char arg[] )107 void log_perr_str(int priority, const char msg[], const char arg[], int err) 125 108 { 126 log_perrno_str(priority, msg, arg, errno); 127 } 128 129 130 void log_int(int priority, const char msg[], int arg) 131 { 132 if (logging) syslog(priority, "%s '%d'", msg, arg); 133 else fprintf(stream(priority), "%s%s '%d'\n", prefix(priority), msg, arg); 109 if (!err) logm(priority, "%s '%s'", msg, arg); 110 else logm(priority, "%s '%s': %s", msg, arg, strerror(err)); 134 111 } 135 112 … … 142 119 memsize_t found) 143 120 { 144 if (logging) 145 syslog(priority, 146 "Discrepancy in swapfile %d: %s (%lld bytes vs. %lld)", 147 swapfile, 148 msg, 149 expected, 150 found); 151 else 152 fprintf(stream(priority), 153 "%sDiscrepancy in swapfile %d: %s (%lld bytes vs. %lld)\n", 154 prefix(priority), 155 swapfile, 156 msg, 157 expected, 158 found); 121 logm(priority, 122 "Discrepancy in swapfile %d: %s (%lld bytes vs. %lld)", 123 swapfile, 124 msg, 125 (long long)expected, 126 (long long)found); 159 127 } 160 128 #endif src/log.h
r102 r120 30 30 void log_close(); 31 31 32 /// Write plain message to log, or standard output/error as appropriate 33 void log_msg(int priority, const char msg[]); 34 35 /// Log plain message followed by quoted string 36 void log_str(int priority, const char msg[], const char arg[]); 37 38 /// Log message in perror() style (i.e. with errno-based message appended) 39 void log_perr(int priority, const char msg[]); 32 /// Log formatted message to log, or stdout/sterr as appropriate 33 void logm(int priority, const char fmt[], ...); 40 34 41 35 /// Log message with given errno (or ignore error number if it is zero) 42 void log_perr no(int priority, const char msg[], int fault_errno);36 void log_perr(int priority, const char msg[], int fault_errno); 43 37 44 38 /// Log message, perror()-style, but appending a quoted string 45 void log_perr_str(int priority, const char msg[], const char arg[]); 46 47 /// Log message, perror()-style, but appending a quoted string 48 void log_perrno_str(int priority, const char msg[], const char arg[], int err); 49 50 /// Log message, but appending a quoted integer argument 51 void log_int(int priority, const char msg[], int arg); 52 53 /// Log message, but appending an (unquoted) long long argument 54 void log_longlong(int priority, const char msg[], long long arg); 39 void log_perr_str(int priority, const char msg[], const char arg[], int err); 55 40 56 41 #ifndef NO_CONFIG src/main.c
r107 r120 117 117 if (unlikely(write(pidfd, localbuf, len) < len)) 118 118 { 119 log_perr_str(LOG_ERR, "Could not write pidfile", pidfile );119 log_perr_str(LOG_ERR, "Could not write pidfile", pidfile, errno); 120 120 return false; 121 121 } … … 137 137 { 138 138 if (errno == EEXIST) 139 log_str(LOG_ERR, "Daemon already running, or leftover pidfile", pidfile); 139 logm(LOG_ERR, 140 "Daemon already running, or leftover pidfile: '%s'", 141 pidfile); 140 142 else 141 log_perr_str(LOG_ERR, "Could not create pidfile", pidfile );143 log_perr_str(LOG_ERR, "Could not create pidfile", pidfile, errno); 142 144 return false; 143 145 } … … 360 362 if (swapfs_size() < minswapfile) 361 363 { 362 log _msg(LOG_CRIT,364 logm(LOG_CRIT, 363 365 "The filesystem holding swapspace's swap directory isn't big enough " 364 366 "to hold useful swapfiles."); 365 log _msg(LOG_CRIT,367 logm(LOG_CRIT, 366 368 "Please try to expand this partition or relocate it to a larger one, " 367 369 "if possible; or if all else fails, choose a different swap directory " … … 371 373 372 374 if (swapfs_free() < minswapfile) 373 log _msg(LOG_WARNING,375 logm(LOG_WARNING, 374 376 "Not enough free space on swap directory. As things stand now, " 375 377 "swapspace will not be able to create swap files."); … … 417 419 { 418 420 #ifndef NO_CONFIG 419 if (verbose) log _msg(LOG_DEBUG, "daemonizing...");421 if (verbose) logm(LOG_DEBUG, "daemonizing..."); 420 422 #endif 421 423 const pid_t pid = daemonize(); … … 433 435 lseek(pidfd, 0, SEEK_SET); 434 436 #ifndef NO_CONFIG 435 if (verbose) log _int(LOG_DEBUG, "got process id", pid);437 if (verbose) logm(LOG_DEBUG, "got process id %d", pid); 436 438 #endif 437 439 return writepid(pid) ? EXIT_SUCCESS : EXIT_FAILURE; src/memory.c
r105 r120 40 40 41 41 /// Configuration item: what percentage of buffer space do we consider "free"? 42 static int buffer_ meekness=30;42 static int buffer_elasticity=30; 43 43 44 44 // TODO: Make this adaptive based on actual cache usage, to avoid thrashing? 45 45 // TODO: Any way of detecting actual cache flexibility or minimum size? 46 46 /// Configuration item: what percentage of cache space do we consider "free"? 47 static int cache_ meekness=80;47 static int cache_elasticity=80; 48 48 49 49 #ifndef NO_CONFIG … … 63 63 return NULL; 64 64 } 65 char *set_buffer_ meekness(long long pct)66 { 67 buffer_ meekness= (int)pct;65 char *set_buffer_elasticity(long long pct) 66 { 67 buffer_elasticity = (int)pct; 68 68 return NULL; 69 69 } 70 char *set_cache_ meekness(long long pct)71 { 72 cache_ meekness= (int)pct;70 char *set_cache_elasticity(long long pct) 71 { 72 cache_elasticity = (int)pct; 73 73 return NULL; 74 74 } … … 245 245 if (unlikely(!fp)) 246 246 { 247 log_perr(LOG_ERR, "Could not open /proc/meminfo for reading" );247 log_perr(LOG_ERR, "Could not open /proc/meminfo for reading", errno); 248 248 return false; 249 249 } … … 254 254 if (unlikely(inf.entry[0])) 255 255 { 256 log_perr no(LOG_ERR, inf.entry, inf.value);256 log_perr(LOG_ERR, inf.entry, inf.value); 257 257 return false; 258 258 } … … 260 260 if (unlikely(!s->MemTotal)) 261 261 { 262 log _msg(LOG_ERR,262 logm(LOG_ERR, 263 263 "No memory detected! Perhaps /proc/meminfo is in an unexpected format"); 264 264 return false; … … 266 266 if (unlikely(s->MemTotal < s->MemFree+s->Buffers+s->Cached+s->SwapCached)) 267 267 { 268 log _msg(LOG_ERR, "Memory statistics read from /proc/meminfo don't add up");268 logm(LOG_ERR, "Memory statistics read from /proc/meminfo don't add up"); 269 269 return false; 270 270 } … … 283 283 printf("Initial memory status: "); 284 284 if (init_req > 0) 285 sprintf(localbuf, "would prefer %lld extra bytes", init_req);285 logm(LOG_INFO, "would prefer %lld extra bytes", init_req); 286 286 else 287 sprintf(localbuf, "%lld bytes to spare", -init_req); 288 log_msg(LOG_INFO, localbuf); 287 logm(LOG_INFO, "%lld bytes to spare", -init_req); 289 288 } 290 289 #endif … … 296 295 static inline memsize_t buffers_free(const struct memstate *st) 297 296 { 298 return (st->Buffers/100) * buffer_ meekness;297 return (st->Buffers/100) * buffer_elasticity; 299 298 } 300 299 … … 304 303 { 305 304 const memsize_t cache = st->Cached - (st->Dirty + st->Writeback); 306 return (cache > 0) ? (cache/100)*cache_ meekness: 0;305 return (cache > 0) ? (cache/100)*cache_elasticity : 0; 307 306 } 308 307 … … 449 448 long long cached) 450 449 { 451 sprintf(localbuf,450 logm(LOG_INFO, 452 451 "%s: %lld total, %lld free (%lld used); %lld cached", 453 452 category, … … 456 455 (total - free), 457 456 cached); 458 log_msg(LOG_INFO, localbuf);459 457 } 460 458 … … 472 470 st.Cached + st.SwapCached); 473 471 474 sprintf(localbuf,472 logm(LOG_INFO, 475 473 "bufs: %lld, dirty: %lld, writeback: %lld", 476 474 st.Buffers, 477 475 st.Dirty, 478 476 st.Writeback); 479 log_msg(LOG_INFO, localbuf);480 477 481 478 const int pf = pct_free(&st); 482 sprintf(localbuf,479 logm(LOG_INFO, 483 480 "estimate free: %lld cache, %lld bufs, %lld total (%d%%)", 484 481 cache_free(&st), … … 486 483 space_free(&st), 487 484 pf); 488 log_msg(LOG_INFO, localbuf); 489 sprintf(localbuf, 485 logm(LOG_INFO, 490 486 "thresholds: %d%% < %d%% < %d%%", 491 487 lower_freelimit, 492 488 pf, 493 489 upper_freelimit); 494 log_msg(LOG_INFO, localbuf); 495 } 496 497 490 } 491 492 src/memory.h
r105 r120 69 69 char *set_upper_freelimit(long long pct); 70 70 char *set_freetarget(long long pct); 71 char *set_buffer_ meekness(long long pct);72 char *set_cache_ meekness(long long pct);71 char *set_buffer_elasticity(long long pct); 72 char *set_cache_elasticity(long long pct); 73 73 74 74 bool memory_check_config(void); src/opts.c
r105 r120 77 77 static const struct option options[] = 78 78 { 79 { "buffer_ meekness", 'B', at_num, 0, 100, set_buffer_meekness,79 { "buffer_elasticity",'B', at_num, 0, 100, set_buffer_elasticity, 80 80 "Consider n% of buffer memory to be \"available\"" }, 81 { "cache_ meekness", 'C', at_num, 0, 100, set_cache_meekness,81 { "cache_elasticity", 'C', at_num, 0, 100, set_cache_elasticity, 82 82 "Consider n% of cache memory to be \"available\"" }, 83 83 { "configfile", 'c', at_str, 1, PATH_MAX, set_configfile, … … 205 205 assert(ptlen < strlen(pad)); 206 206 207 printf(" -%c%s,%s--%s%s%*s\t%s\n",207 printf(" -%c%s,%s--%s%s%*s\t%s\n", 208 208 options[i].shortopt, 209 209 pt, src/state.c
r102 r120 87 87 { 88 88 #ifndef NO_CONFIG 89 if (verbose) 90 { 91 sprintf(localbuf, "%s -> %s", Statenames[the_state], Statenames[s]); 92 log_msg(LOG_DEBUG, localbuf); 93 } 89 if (verbose) logm(LOG_DEBUG,"%s -> %s",Statenames[the_state],Statenames[s]); 94 90 #endif 95 91 the_state = s; … … 167 163 void dump_state(void) 168 164 { 169 sprintf(localbuf, "state: %s", Statenames[the_state]); 170 log_msg(LOG_INFO, localbuf); 171 if (timer > 0) 172 { 173 sprintf(localbuf, "timer: %ld", (long)timer); 174 log_msg(LOG_INFO, localbuf); 175 } 165 logm(LOG_INFO, "state: %s", Statenames[the_state]); 166 if (timer > 0) logm(LOG_INFO, "timer: %ld", (long)timer); 176 167 } 177 168 src/swaps.c
r108 r120 100 100 if (swappath[0] != '/') 101 101 { 102 log_str(LOG_ERR,"Swap path is not absolute (must start with '/')",swappath); 102 logm(LOG_ERR, 103 "Swap path is not absolute (must start with '/'): '%s'", 104 swappath); 103 105 return false; 104 106 } … … 116 118 const int err = errno; 117 119 bool please_reinstall = false; 118 log_perr_str(LOG_ERR, "Could not cd to swap directory", swappath );120 log_perr_str(LOG_ERR, "Could not cd to swap directory", swappath, errno); 119 121 switch (err) 120 122 { … … 133 135 } 134 136 if (please_reinstall) 135 log _msg(LOG_ERR, "swapspace installed incorrectly. Please reinstall!");137 logm(LOG_ERR, "swapspace installed incorrectly. Please reinstall!"); 136 138 return false; 137 139 } … … 145 147 if (!getcwd(swappath, sizeof(swappath))) 146 148 { 147 log _msg(LOG_CRIT, "Swap path too long");149 logm(LOG_CRIT, "Swap path too long"); 148 150 return false; 149 151 } … … 157 159 for (int i=swappath_len-1; i >= 0; --i) if (isspace(swappath[i])) 158 160 { 159 log _msg(LOG_ERR, "Not supported: swap path contains whitespace");161 logm(LOG_ERR, "Not supported: swap path contains whitespace"); 160 162 return false; 161 163 } … … 197 199 void dump_stats(void) 198 200 { 199 sprintf(localbuf, "clock: %lld", (long long)clock); 200 log_msg(LOG_INFO, localbuf); 201 logm(LOG_INFO, "clock: %lld", (long long)clock); 201 202 202 203 dump_state(); … … 208 209 int activeswaps = 0; 209 210 for (int i=0; i<MAX_SWAPFILES; ++i) if (swapfiles[i].size) ++activeswaps; 210 sprintf(localbuf, "swapfiles in use: %d", activeswaps); 211 log_msg(LOG_INFO, localbuf); 211 logm(LOG_INFO, "swapfiles in use: %d", activeswaps); 212 212 if (activeswaps) 213 213 { 214 log _msg(LOG_INFO,214 logm(LOG_INFO, 215 215 "file size used created seen"); 216 216 for (int i=0; i<MAX_SWAPFILES; ++i) if (swapfiles[i].size) 217 { 218 sprintf(localbuf, 217 logm(LOG_INFO, 219 218 "%4d%16lld%16lld%16lld %d", 220 219 i, … … 223 222 swapfiles[i].created, 224 223 (int)swapfiles[i].observed_in_wild); 225 log_msg(LOG_INFO, localbuf);226 }227 224 } 228 225 } … … 245 242 log_perr_str(LOG_ERR, 246 243 "Could not get filesystem information for swap directory", 247 swappath); 244 swappath, 245 errno); 248 246 249 247 return !fail; … … 293 291 runcommand("mkswap", file); 294 292 const bool ok = (swapon(file, 0) == 0); 295 if (unlikely(!ok)) log_perr_str(LOG_ERR, "Could not enable swapfile", file); 293 if (unlikely(!ok)) 294 log_perr_str(LOG_ERR, "Could not enable swapfile", file, errno); 296 295 return ok; 297 296 } … … 358 357 { 359 358 const int err = errno; 360 log_perr_str(LOG_ERR, "Error writing swapfile", file );359 log_perr_str(LOG_ERR, "Error writing swapfile", file, errno); 361 360 switch (err) 362 361 { … … 368 367 #ifndef NO_CONFIG 369 368 if (verbose) 370 { 371 sprintf(localbuf, "Restricting swapfile size to %lld", bytes); 372 log_msg(LOG_INFO, localbuf); 373 } 369 logm(LOG_INFO, "Restricting swapfile size to %lld", (long long)bytes); 374 370 #endif 375 371 } … … 381 377 break; 382 378 default: 383 log _msg(LOG_WARNING, "Unexpected error writing swap file");379 logm(LOG_WARNING, "Unexpected error writing swap file"); 384 380 } 385 381 bytes = 0; … … 413 409 if (unlikely(fd == -1)) 414 410 { 415 log_perr_str(LOG_ERR, "Could not create swapfile", file );411 log_perr_str(LOG_ERR, "Could not create swapfile", file, errno); 416 412 return 0; 417 413 } … … 455 451 if (unlikely(fd == -1)) 456 452 { 457 log_perr_str(LOG_WARNING, "Can't determine size of", name );453 log_perr_str(LOG_WARNING, "Can't determine size of", name, errno); 458 454 return -1; 459 455 } … … 461 457 memsize_t pos = SEEK(fd, 0, SEEK_END); 462 458 if (unlikely(pos == -1)) 463 log_perr_str(LOG_WARNING, "Can't determine size of", name );459 log_perr_str(LOG_WARNING, "Can't determine size of", name, errno); 464 460 465 461 return pos; … … 472 468 if (unlikely(!dir)) 473 469 { 474 log_perr(LOG_ERR, "Cannot read swap directory" );470 log_perr(LOG_ERR, "Cannot read swap directory", errno); 475 471 return false; 476 472 } … … 481 477 { 482 478 #ifndef NO_CONFIG 483 if (!quiet) log _int(LOG_INFO, "Found old swapfile", seqno);479 if (!quiet) logm(LOG_INFO, "Found old swapfile '%d'", seqno); 484 480 #endif 485 481 const memsize_t size = filesize(d->d_name); … … 491 487 { 492 488 #ifndef NO_CONFIG 493 if (!quiet) log _int(LOG_NOTICE, "Deleting unusable swapfile", seqno);489 if (!quiet) logm(LOG_NOTICE, "Deleting unusable swapfile '%d'", seqno); 494 490 #endif 495 491 unlink(d->d_name); … … 508 504 { 509 505 FILE *fp = fopen("/proc/swaps", "r"); 510 if (unlikely(!fp)) log_perr(LOG_ERR, "Could not open /proc/swaps" );506 if (unlikely(!fp)) log_perr(LOG_ERR, "Could not open /proc/swaps", errno); 511 507 return fp; 512 508 } … … 517 513 { 518 514 char c; 519 if (unlikely(sscanf( localbuf, "Filename Type Size Used %c",&c) < 1))520 { 521 log _msg(LOG_ERR, "/proc/swaps is not in the expected format");515 if (unlikely(sscanf(buf, "Filename Type Size Used %c",&c) < 1)) 516 { 517 logm(LOG_ERR, "/proc/swaps is not in the expected format"); 522 518 return false; 523 519 } … … 566 562 if (!check_proc_swaps_header(localbuf)) 567 563 { 568 log _str(LOG_ERR, "Parse error in /proc/swaps:", localbuf);564 logm(LOG_ERR, "Parse error in /proc/swaps: '%s'", localbuf); 569 565 return false; 570 566 } … … 585 581 // We didn't know about this swapfile yet. Adopt it. 586 582 #ifndef NO_CONFIG 587 if (!quiet) log _int(LOG_NOTICE, "Detected swapfile", result->seqno);583 if (!quiet) logm(LOG_NOTICE, "Detected swapfile '%d'", result->seqno); 588 584 #endif 589 585 swapfiles[result->seqno].created = clock; … … 677 673 snprintf(namebuf, sizeof(namebuf), "%d", file); 678 674 #ifndef NO_CONFIG 679 if (!quiet) log _int(LOG_NOTICE, "Retiring swapfile", file);675 if (!quiet) logm(LOG_NOTICE, "Retiring swapfile '%d'", file); 680 676 #endif 681 677 if (unlikely(swapoff(namebuf) == -1)) return false; … … 759 755 // We can allocate another swapfile. Great. 760 756 #ifndef NO_CONFIG 761 if (!quiet) log _int(LOG_NOTICE, "Allocating swapfile", newswap);757 if (!quiet) logm(LOG_NOTICE, "Allocating swapfile '%d'", newswap); 762 758 #endif 763 759 char file[30];
