diff -ruN bcache-tools-1.0.8/69-bcache.rules bcache-tools-1.0.8.2/69-bcache.rules --- bcache-tools-1.0.8/69-bcache.rules 2014-12-04 23:51:24.000000000 +0100 +++ bcache-tools-1.0.8.2/69-bcache.rules 2015-02-07 22:32:35.000000000 +0100 @@ -22,11 +22,14 @@ RUN+="bcache-register $tempnode" LABEL="bcache_backing_end" -# Cached devices: symlink -DRIVER=="bcache", ENV{CACHED_UUID}=="?*", \ - SYMLINK+="bcache/by-uuid/$env{CACHED_UUID}" -DRIVER=="bcache", ENV{CACHED_LABEL}=="?*", \ - SYMLINK+="bcache/by-label/$env{CACHED_LABEL}" +# Handling of cached devices +DRIVER!="bcache", GOTO="bcache_end" + +# Apply kernel cmdline parameters +RUN+="bcache-params $kernel" +# Symlink +ENV{CACHED_UUID}=="?*", SYMLINK+="bcache/by-uuid/$env{CACHED_UUID}" +ENV{CACHED_LABEL}=="?*", SYMLINK+="bcache/by-label/$env{CACHED_LABEL}" LABEL="bcache_end" diff -ruN bcache-tools-1.0.8/bcache-params.c bcache-tools-1.0.8.2/bcache-params.c --- bcache-tools-1.0.8/bcache-params.c 1970-01-01 01:00:00.000000000 +0100 +++ bcache-tools-1.0.8.2/bcache-params.c 2015-02-07 22:32:35.000000000 +0100 @@ -0,0 +1,196 @@ +/* + * Author: Rolf Fokkens + * + * GPLv2 + * + * For experimenting (or production) it may be useful to set bcache + * parameters in an early stage during boot, for example to tune the + * boot performance when the root fs is on a bcache device. The best + * moment is right before the root fs is actually mounted, which means + * it may need to be done in the initramfs. + * + * The bcache kernel driver does not support passing kernel cmdline + * arguments to it. This udev helper can be excuted from udev rules to + * take care of cmdline arguments by changing bcache parameters using + * the /sys interface right after a bcache device is brought up. This + * works both in the initramfs and later. + * + * It recognizes cmdline arguments like these: + * bcache=sco:0,crdthr:0,cache/congested_write_threshold_us:0 + * This means: + * - for any bcache device set the following parameters: + * - sequential_cutoff (sco) is set to 0 + * - cache/congested_read_threshold_us (crdthr) is set to 0 + * - cache/congested_write_threshold_us (cwrthr) is set to 0 + * Both short aliases (for user convenience) and full parameters can be used, + * they are defined in the parm_map below. + * + * Other parameters are not accepted, because they're not useful or + * potentially harmful (e.g. changing the label, stopping bcache devices) + * + * Parsing of each kernel cmdline argument is done in a simple way: + * - does the argument start with "bcache="? If not: next argument. + * - for the rest of the argument, identify "subarguments": + * - is what follows of the form :? If not: next argument + * - is a know parameter name? If not: next subargument + * - process the subargument + * - next subargument + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef TESTING +# define CMDLINE "/proc/cmdline" +# define SYSPFX "/sys/block" +#else +# define CMDLINE "/tmp/cmdline" +# define SYSPFX "/tmp" +#endif + +struct parm_map { + char *id; + char *full; +}; + +/* + * The list of kernel cmdline patameters that can be processed by + * bcache-patams. + */ +struct parm_map parm_map[] = { + { "crdthr", "cache/congested_read_threshold_us" } +, { "cwrthr", "cache/congested_write_threshold_us" } +, { "rdahed", "readahead" } +, { "sctoff", "sequential_cutoff" } +, { "wrbdly", "writeback_delay" } +, { "wrbpct", "writeback_percent" } +, { "wrbupd", "writeback_rate_update_seconds" } +, { NULL , NULL } +}; + +/* + * Read characters from fp (/proc/cmdline) into buf until maxlen characters are + * read or until a character is read that is in the list of terminators. + * + * lookaheadp points to the current lookahead symbol, and is returned as such to + * the caller. + * + * When a characters is read that is a terminator charachter, the lookehead is moved + * one character ahead and the encountered terminator is returned. + * + * If for another reason reading characters stops, 0 is returned. + */ +int read_until (int *lookaheadp, FILE *fp, char *buf, int maxlen, char *terminators) +{ + char *cp = buf, *ep = buf + maxlen; + int lookahead = *lookaheadp; + + while ( cp < ep + && lookahead != EOF + && isprint (lookahead) + && !strchr (terminators, lookahead)) { + *cp++ = lookahead; + lookahead = fgetc (fp); + } + + *lookaheadp = lookahead; + + *cp = '\0'; + + if (strchr (terminators, lookahead)) { + *lookaheadp = fgetc (fp); + return lookahead; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + char buf[256]; + int la, bufsz = sizeof (buf); + FILE *fp; + + if (argc != 2) { + fprintf (stderr, "bcache-params takes exactly one argument\n"); + return 1; + } + + fp = fopen (CMDLINE, "r"); + if (fp == NULL) { + perror ("Error opening /proc/cmdline"); + return 1; + } + /* la is our lookahead character */ + la = fgetc (fp); + + while (la != EOF) { + /* skip any spaces */ + while (la == ' ') { + la = fgetc (fp); + } + /* stop ehen end of the line */ + if (la == EOF) break; + + /* process until '=' */ + if (read_until (&la, fp, buf, bufsz, " =") != '=') goto nextarg; + /* did we get a "bcache=" prefix? */ + if (strcmp (buf, "bcache") != 0) goto nextarg; + + /* process subarguments */ + for (;;) { + struct parm_map *pmp; + char sysfile[256]; + int term, fd; + + /* all subargs start with ":" */ + if (read_until (&la, fp, buf, bufsz, " :") != ':') goto nextarg; + + /* now identify */ + for (pmp = parm_map; pmp->id != NULL; pmp++) { + if (strcmp (buf, pmp->id) == 0) break; + if (strcmp (buf, pmp->full) == 0) break; + } + /* no match for ? next subargument */ + if (pmp->id == NULL) { + error (0, 0, "Unknown bcache parameter %s", buf); + } else { + /* Now we know what /sys file to write to */ + sprintf (sysfile, "%s/%s/bcache/%s", SYSPFX, argv[1], pmp->full); + } + + /* What follows is the data to be written */ + term = read_until (&la, fp, buf, bufsz, " ,"); + + if (pmp->id == NULL) goto nextsubarg; + + /* no data identified? next subargument */ + if (buf[0] == '\0') { + error (0, 0, "Missing data for parameter %s(%s)", pmp->full, pmp->id); + goto nextsubarg; + } + /* we're ready to actually write the data */ + fd = open (sysfile, O_WRONLY); + if (fd < 0) { + error (0, errno, "Error opening %s", sysfile); + goto nextsubarg; + } + if (dprintf (fd, "%s\n", buf) < 0) { + error (0, errno, "Error writing %s to %s", buf, sysfile); + } + close (fd); + /* From here there's the hope for another subargument */ + nextsubarg: + if (term != ',') break; + } + nextarg: + while (la != EOF && la != ' ') la = fgetc (fp); + } + return 0; +} + diff -ruN bcache-tools-1.0.8/dracut/module-setup.sh bcache-tools-1.0.8.2/dracut/module-setup.sh --- bcache-tools-1.0.8/dracut/module-setup.sh 2014-12-04 23:51:24.000000000 +0100 +++ bcache-tools-1.0.8.2/dracut/module-setup.sh 2015-02-07 22:32:35.000000000 +0100 @@ -29,6 +29,9 @@ } install() { - inst_multiple ${udevdir}/probe-bcache ${udevdir}/bcache-register + inst_multiple \ + ${udevdir}/probe-bcache \ + ${udevdir}/bcache-register \ + ${udevdir}/bcache-params inst_rules 69-bcache.rules } diff -ruN bcache-tools-1.0.8/.gitignore bcache-tools-1.0.8.2/.gitignore --- bcache-tools-1.0.8/.gitignore 2014-12-04 23:51:24.000000000 +0100 +++ bcache-tools-1.0.8.2/.gitignore 2015-02-07 22:32:35.000000000 +0100 @@ -1,6 +1,7 @@ /bcache-super-show /bcache-test /bcache-register +/bcache-params /make-bcache /probe-bcache .* diff -ruN bcache-tools-1.0.8/Makefile bcache-tools-1.0.8.2/Makefile --- bcache-tools-1.0.8/Makefile 2014-12-04 23:51:24.000000000 +0100 +++ bcache-tools-1.0.8.2/Makefile 2015-02-07 22:32:35.000000000 +0100 @@ -5,11 +5,11 @@ INSTALL=install CFLAGS+=-O2 -Wall -g -all: make-bcache probe-bcache bcache-super-show bcache-register +all: make-bcache probe-bcache bcache-super-show bcache-register bcache-params -install: make-bcache probe-bcache bcache-super-show +install: make-bcache probe-bcache bcache-super-show bcache-register bcache-params $(INSTALL) -m0755 make-bcache bcache-super-show $(DESTDIR)${PREFIX}/sbin/ - $(INSTALL) -m0755 probe-bcache bcache-register $(DESTDIR)$(UDEVLIBDIR)/ + $(INSTALL) -m0755 probe-bcache bcache-register bcache-params $(DESTDIR)$(UDEVLIBDIR)/ $(INSTALL) -m0644 69-bcache.rules $(DESTDIR)$(UDEVLIBDIR)/rules.d/ $(INSTALL) -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8/ $(INSTALL) -D -m0755 initramfs/hook $(DESTDIR)/usr/share/initramfs-tools/hooks/bcache @@ -30,3 +30,4 @@ bcache-super-show: CFLAGS += -std=gnu99 bcache-super-show: bcache.o bcache-register: bcache-register.o +bcache-params: bcache-params.o