Hello,

In my opinion early init is too late as we need /tmp sooner - for example to be 
able
to mount overlayfs (even init & procd needs writeable /tmp!). Maybe we can 
temporaily
mount "something" (RAMFS/TMPFS depending on kernel configuration) on /tmp and 
then
remount ZRAM but I do not think it will be better as we will have to copy stuff 
over...
I can provide patch using correct coding style if you need.

Please find answers to your comments below.

Regards,

Thomas

W dniu 22.10.2014 o 12:39, John Crispin pisze:
> Hi,
> 
> a few comments inline. i am not sure if we want this inside procd
> directly. maybe we should put this into fstools and then call that code
> from early init. i need to think about that before i can make a decision.
> 
>       John
> 
> 
> 
> On 22/10/2014 10:30, Tomasz Wasiak wrote:
>> Hello,
>>
>> Here you are (of course it is just 1/3 of the original patch).
>> ---
>> diff --git a/initd/early.c b/initd/early.c
>> index a9f6afb..b4a375f 100644
>> --- a/initd/early.c
>> +++ b/initd/early.c
>> @@ -12,34 +12,130 @@
>>   * GNU General Public License for more details.
>>   */
>>  
>> -#include <sys/mount.h>
>> -#include <sys/types.h>
>> -#include <sys/stat.h>
>> -
>> -#include <stdio.h>
>> +#include <errno.h>
>>  #include <fcntl.h>
>> -#include <unistd.h>
>> +#include <stdio.h>
>>  #include <stdlib.h>
>> +#include <string.h>
>> +#include <strings.h>
>> +#include <unistd.h>
>> +#include <sys/mount.h>
>> +#include <sys/stat.h>
>> +#include <sys/types.h>
>> +#include <sys/wait.h>
>>  
>>  #include "../log.h"
>>  #include "init.h"
>>  
>> +static long
>> +check_ramsize(void)
>> +{
>> +    FILE *fp;
>> +    char line[256];
>> +    char *key;
>> +    long val = 0;
>> +
>> +    fp = fopen("/proc/meminfo", "r");
>> +    if(fp == NULL)
>> +    {
> 
> please use this coding style ->
> 
> if (fp == NULL) {
> 
> }
> 
> 
>> +            ERROR("Can't open /proc/meminfo: %s\n", strerror(errno));
>> +            return errno;
>> +    }
>> +
>> +    while(fgets(line, sizeof(line), fp))
>> +    {
> 
> and here aswell
> 
> while () {
> 
> }
> 
>> +            key = strtok(line, ":");
>> +            val = atol(strtok(NULL, " kB\n"));
> 
> what happens if strtok return NULL ?
SIGSEGV :(
But that means that /proc/meminfo does not contain information about total 
memory.
Safer solution would be:

        char *key, *val;

        (...)

                key = strtok(line, ":");
                val = strtok(NULL, " kB\n");

                (...)
                        break;

        fclose(fp);

        if(val != NULL)
                return(atol(val));
        else
                return 0;
        fi
}
> 
>> +
>> +            if (!key || !val)
>> +                    continue;
>> +
>> +            if (!strcasecmp(key, "MemTotal"))
>> +                    break;
>> +    }
>> +
>> +    fclose(fp);
>> +
>> +    return val;
>> +}
>> +
>> +static int
>> +mount_zram_on_tmp(void)
>> +{
>> +    FILE *fp;
>> +    long zramsize = (check_ramsize() / 2);
> 
> where does the /2 come from ? is this just "a good value to use" or is
> there a technical reason that is must always be /2 and not /X

/2 is here because I would like to limit memory used by /tmp filesystem to half 
of RAM.
Now it is not limited so it can eat all memory! IMHO even if a device has only 
16 MB
of RAM 8 MB would be sufficient for /tmp (even when it will be pure 
RAMFS/TMPFS).

> 
>> +    pid_t pid;
>> +
>> +    if(!zramsize)
>> +    {
>> +            ERROR("Can't read size of RAM. Assuming 16 MB.\n");
>> +            zramsize = 8192;
> 
> dangerous, if the memory was not detected properly we have mayor issues
> and should not do any magic with the memory. in this case we should just
> continue without zram

Of course but that way we are not able to limit /tmp memory usage. IMHO 
assumption that
device has at least 16 MB of RAM is not harmful as I do not think one can run 
newer builds
(based on 3.x kernels and modern toolchains) on any device equipped with 8 (or 
even less)
MB of RAM.

> 
>> +    }
>> +
>> +    fp = fopen("/sys/block/zram0/disksize", "r+");
>> +    if(fp == NULL)
>> +    {
>> +            ERROR("Can't open /sys/block/zram0/disksize: %s\n", 
>> strerror(errno));
>> +            return errno;
>> +    }
>> +
>> +    fprintf(fp, "%ld", (zramsize * 1024));
>> +
>> +    fclose(fp);
>> +
>> +    pid = fork();
>> +
>> +    if (!pid)
>> +    {
>> +            char *mkfs[] = { "/sbin/mke2fs", "-b", "4096", "-F", "-L", 
>> "TEMP", "-m", "0", "/dev/zram0", NULL };
>> +            int fd = open("/dev/null", O_RDWR);
>> +
>> +            if (fd > -1) {
>> +                    dup2(fd, STDIN_FILENO);
>> +                    dup2(fd, STDOUT_FILENO);
>> +                    dup2(fd, STDERR_FILENO);
>> +                    if (fd > STDERR_FILENO)
>> +                            close(fd);
>> +            }
>> +
>> +            execvp(mkfs[0], mkfs);
>> +            ERROR("Can't exec /sbin/mke2fs\n");
>> +            exit(-1);
>> +    }
>> +
>> +    if (pid <= 0)
>> +    {
>> +            ERROR("Can't exec /sbin/mke2fs\n");
>> +            return -1;
>> +    } else {
>> +            waitpid(pid, NULL, 0);
>> +    }
>> +
>> +    if(mount("/dev/zram0", "/tmp", "ext2", MS_NOSUID | MS_NODEV | 
>> MS_NOATIME, "check=none,errors=continue,noquota") < 0)
>> +    {
>> +            ERROR("Can't mount /dev/zram0 on /tmp: %s\n", strerror(errno));
>> +            return errno;
>> +    }
>> +
>> +    LOG("Using up to %ld kB of RAM as ZRAM storage on /mnt\n", zramsize);
>> +    return 0;
>> +}
>> +
>>  static void
>> -early_mounts(void)
>> +mount_tmpfs_on_tmp(void)
>>  {
>> -    mount("proc", "/proc", "proc", MS_NOATIME, 0);
>> -    mount("sysfs", "/sys", "sysfs", MS_NOATIME, 0);
>> +    char line[256];
>> +    long tmpfssize = (check_ramsize() / 2);
> 
> same here
> 
>>  
>> -    mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOATIME, 
>> NULL);
>> -    mkdir("/tmp/run", 0777);
>> -    mkdir("/tmp/lock", 0777);
>> -    mkdir("/tmp/state", 0777);
>> -    symlink("/tmp", "/var");
>> +    if(!tmpfssize)
>> +    {
>> +            ERROR("Can't read size of RAM. Assuming 16 MB.\n");
>> +            tmpfssize = 8192;
> 
> same here
> 
>> +    }
>>  
>> -    mount("tmpfs", "/dev", "tmpfs", MS_NOATIME, "mode=0755,size=512K");
>> -    mkdir("/dev/shm", 0755);
>> -    mkdir("/dev/pts", 0755);
>> -    mount("devpts", "/dev/pts", "devpts", MS_NOATIME, "mode=600");
>> +    snprintf(line, 256, "size=%ldk", tmpfssize);
>> +    mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOATIME, 
>> line);
>> +    LOG("Using up to %ld kB of RAM as TMPFS storage on /tmp\n", tmpfssize);
>>  }
>>  
>>  static void
>> @@ -50,6 +146,25 @@ early_dev(void)
>>  }
>>  
>>  static void
>> +early_mounts(void)
>> +{
>> +    mount("proc", "/proc", "proc", MS_NOATIME, 0);
>> +    mount("sysfs", "/sys", "sysfs", MS_NOATIME, 0);
>> +    mount("tmpfs", "/dev", "tmpfs", MS_NOATIME, "mode=0755,size=512K");
>> +    mkdir("/dev/shm", 0755);
>> +    mkdir("/dev/pts", 0755);
>> +    mount("devpts", "/dev/pts", "devpts", MS_NOATIME, "mode=600");
>> +    early_dev();
>> +
>> +    if(mount_zram_on_tmp() !=0)
>> +            mount_tmpfs_on_tmp();
>> +    mkdir("/tmp/run", 0777);
>> +    mkdir("/tmp/lock", 0777);
>> +    mkdir("/tmp/state", 0777);
>> +    symlink("/tmp", "/var");
>> +}
>> +
>> +static void
>>  early_console(const char *dev)
>>  {
>>      struct stat s;
>> @@ -89,7 +204,6 @@ early(void)
>>              return;
>>  
>>      early_mounts();
>> -    early_dev();
>>      early_env();
>>      early_console("/dev/console");
>>  
>>
>>
>> W dniu 22.10.2014 o 09:38, John Crispin pisze:
>>> Hi,
>>>
>>> please send patches directly against the procd git tree.
>>>
>>>     John
>>>
>>> On 22/10/2014 09:20, Tomasz Wasiak wrote:
>>>> Devices with less memory are still common so why limit ZRAM usage
>>>> just to swap when it could be very useful as for /tmp storage.
>>>>
>>>> This patch changes 3 things: - sets default number of ZRAM devices
>>>> to 2 (1st for /tmp, 2nd for swap) - adds ZRAM (default) support to
>>>> procd's init (TMPFS is used when ZRAM is not available - changes
>>>> zram-swap so it will use /dev/zram1 for 1st CPU, /dev/zram2 for
>>>> 2nd and so on as /dev/zram0 is in use for /tmp.
>>>>
>>>> Signed-off-by: Tomasz Wasiak <tjwas...@gmail.com> --- 
>>>> package/system/procd/patches/procd-support_for_tmp_on_zram.patch
>>>> |  185 ++++++++++ package/system/zram-swap/files/zram.init
>>>> |   15 
>>>> target/linux/generic/patches-3.10/998_zram_make_2_devices_by_default.patch
>>>> |   11 3 files changed, 203 insertions(+), 8 deletions(-)
>>>>
>>>> ---
>>>> a/package/system/procd/patches/procd-support_for_tmo_on_zram.patch 
>>>> +++
>>>> b/package/system/procd/patches/procd-support_for_tmp_on_zram.patch 
>>>> @@ -0,0 +1,185 @@ +--- a/initd/early.c ++++ b/initd/early.c +@@
>>>> -12,34 +12,130 @@ +  * GNU General Public License for more
>>>> details. +  */ + +-#include <sys/mount.h> +-#include <sys/types.h> 
>>>> +-#include <sys/stat.h> +- +-#include <stdio.h> ++#include
>>>> <errno.h> + #include <fcntl.h> +-#include <unistd.h> ++#include
>>>> <stdio.h> + #include <stdlib.h> ++#include <string.h> ++#include
>>>> <strings.h> ++#include <unistd.h> ++#include <sys/mount.h> 
>>>> ++#include <sys/stat.h> ++#include <sys/types.h> ++#include
>>>> <sys/wait.h> + + #include "../log.h" + #include "init.h" + ++static
>>>> long ++check_ramsize(void) ++{ ++  FILE *fp; ++    char line[256]; ++
>>>> char *key; ++      long val = 0; ++ ++     fp = fopen("/proc/meminfo",
>>>> "r"); ++   if(fp == NULL) ++       { ++            ERROR("Can't open 
>>>> /proc/meminfo:
>>>> %s\n", strerror(errno)); ++                return errno; ++        } ++ ++
>>>> while(fgets(line, sizeof(line), fp)) ++    { ++            key = 
>>>> strtok(line,
>>>> ":"); ++           val = atol(strtok(NULL, " kB\n")); ++ ++                
>>>> if (!key ||
>>>> !val) ++                   continue; ++ ++         if (!strcasecmp(key, 
>>>> "MemTotal")) ++
>>>> break; ++  } ++ ++ fclose(fp); ++ ++       return val; ++} ++ ++static
>>>> int ++mount_zram_on_tmp(void) ++{ ++       FILE *fp; ++    long zramsize =
>>>> (check_ramsize() / 2); ++  pid_t pid; ++ ++        if(!zramsize) ++        
>>>> { ++
>>>> ERROR("Can't read size of RAM. Assuming 16 MB.\n"); ++             
>>>> zramsize =
>>>> 8192; ++   } ++ ++ fp = fopen("/sys/block/zram0/disksize", "r+"); ++
>>>> if(fp == NULL) ++  { ++            ERROR("Can't open
>>>> /sys/block/zram0/disksize: %s\n", strerror(errno)); ++             return
>>>> errno; ++  } ++ ++ fprintf(fp, "%ld", (zramsize * 1024)); ++ ++
>>>> fclose(fp); ++ ++  pid = fork(); ++ ++     if (!pid) ++    { ++            
>>>> char
>>>> *mkfs[] = { "/sbin/mke2fs", "-b", "4096", "-F", "-L", "TEMP", "-m",
>>>> "0", "/dev/zram0", NULL }; ++              int fd = open("/dev/null", 
>>>> O_RDWR); 
>>>> ++ ++              if (fd > -1) { ++                       dup2(fd, 
>>>> STDIN_FILENO); ++                      dup2(fd,
>>>> STDOUT_FILENO); ++                 dup2(fd, STDERR_FILENO); ++             
>>>>         if (fd >
>>>> STDERR_FILENO) ++                          close(fd); ++           } ++ ++ 
>>>>         execvp(mkfs[0],
>>>> mkfs); ++          ERROR("Can't exec /sbin/mke2fs\n"); ++          
>>>> exit(-1); ++    } 
>>>> ++ ++      if (pid <= 0) ++        { ++            ERROR("Can't exec 
>>>> /sbin/mke2fs\n"); ++
>>>> return -1; ++      } else { ++             waitpid(pid, NULL, 0); ++       
>>>> } ++ ++
>>>> if(mount("/dev/zram0", "/tmp", "ext2", MS_NOSUID | MS_NODEV |
>>>> MS_NOATIME, "check=none,errors=continue,noquota") < 0) ++  { ++
>>>> ERROR("Can't mount /dev/zram0 on /tmp: %s\n", strerror(errno)); ++
>>>> return errno; ++   } ++ ++ LOG("Using up to %ld kB of RAM as ZRAM
>>>> storage on /mnt\n", zramsize); ++  return 0; ++} ++ + static void 
>>>> +-early_mounts(void) ++mount_tmpfs_on_tmp(void) + { +-
>>>> mount("proc", "/proc", "proc", MS_NOATIME, 0); +-  mount("sysfs",
>>>> "/sys", "sysfs", MS_NOATIME, 0); ++        char line[256]; ++      long
>>>> tmpfssize = (check_ramsize() / 2); + +-    mount("tmpfs", "/tmp",
>>>> "tmpfs", MS_NOSUID | MS_NODEV | MS_NOATIME, NULL); +-
>>>> mkdir("/tmp/run", 0777); +-        mkdir("/tmp/lock", 0777); +-
>>>> mkdir("/tmp/state", 0777); +-      symlink("/tmp", "/var"); ++
>>>> if(!tmpfssize) ++  { ++            ERROR("Can't read size of RAM. Assuming 
>>>> 16
>>>> MB.\n"); ++                tmpfssize = 8192; ++    } + +-  mount("tmpfs", 
>>>> "/dev",
>>>> "tmpfs", MS_NOATIME, "mode=0755,size=512K"); +-    mkdir("/dev/shm",
>>>> 0755); +-  mkdir("/dev/pts", 0755); +-     mount("devpts", "/dev/pts",
>>>> "devpts", MS_NOATIME, "mode=600"); ++      snprintf(line, 256,
>>>> "size=%ldk", tmpfssize); ++        mount("tmpfs", "/tmp", "tmpfs",
>>>> MS_NOSUID | MS_NODEV | MS_NOATIME, line); ++       LOG("Using up to %ld
>>>> kB of RAM as TMPFS storage on /tmp\n", tmpfssize); + } + + static
>>>> void +@@ -50,6 +146,25 @@ early_dev(void) + } + + static void 
>>>> ++early_mounts(void) ++{ ++        mount("proc", "/proc", "proc",
>>>> MS_NOATIME, 0); ++ mount("sysfs", "/sys", "sysfs", MS_NOATIME, 0); 
>>>> ++ mount("tmpfs", "/dev", "tmpfs", MS_NOATIME,
>>>> "mode=0755,size=512K"); ++ mkdir("/dev/shm", 0755); ++
>>>> mkdir("/dev/pts", 0755); ++        mount("devpts", "/dev/pts", "devpts",
>>>> MS_NOATIME, "mode=600"); ++        early_dev(); ++ ++
>>>> if(mount_zram_on_tmp() !=0) ++             mount_tmpfs_on_tmp(); ++
>>>> mkdir("/tmp/run", 0777); ++        mkdir("/tmp/lock", 0777); ++
>>>> mkdir("/tmp/state", 0777); ++      symlink("/tmp", "/var"); ++} ++ 
>>>> ++static void + early_console(const char *dev) + { +       struct stat
>>>> s; +@@ -87,7 +202,6 @@ early(void) +               return; + +
>>>> early_mounts(); +- early_dev(); +  early_env(); +
>>>> early_console("/dev/console"); + ---
>>>> a/package/system/zram-swap/files/zram.init +++
>>>> b/package/system/zram-swap/files/zram.init @@ -15,10 +15,10 @@
>>>> zram_size()        # in megabytes local ram_size="$( ram_size )"
>>>>
>>>> if [ -z "$zram_size" ]; then -             # e.g. 6mb for 16mb-routers or 
>>>> 61mb
>>>> for 128mb-routers -                echo $(( $ram_size / 2048 )) +          
>>>> # e.g. 3200kb
>>>> for 16mb-routers or 25600kb for 128mb-routers +            echo $(( 
>>>> $ram_size
>>>> * 2 / 10 )) else -         echo "$zram_size" +             echo $(( 
>>>> $zram_size * 1024
>>>> )) fi }
>>>>
>>>> @@ -54,9 +54,9 @@ zram_applicable()
>>>>
>>>> zram_dev() { -     local core="$1" +       local core=$(( $1 + 1 ))
>>>>
>>>> -  echo "/dev/zram${core:-0}" +    echo "/dev/zram${core:-1}" }
>>>>
>>>> zram_reset() @@ -95,10 +95,10 @@ start() zram_dev="$( zram_dev
>>>> "$core" )" zram_applicable "$zram_dev" || return 1
>>>>
>>>> -          logger -s -t zram_start -p daemon.debug "activating '$zram_dev'
>>>> for swapping ($zram_size MegaBytes)" +             logger -s -t zram_start 
>>>> -p
>>>> daemon.debug "activating '$zram_dev' for swapping ($zram_size
>>>> KiloBytes)"
>>>>
>>>> zram_reset "$zram_dev" "enforcing defaults" -              echo $(( 
>>>> $zram_size
>>>> * 1024 * 1024 )) >"/sys/block/$( basename $zram_dev )/disksize" +
>>>> echo $(( $zram_size * 1024 )) >"/sys/block/$( basename $zram_dev
>>>> )/disksize" mkswap "$zram_dev" swapon "$zram_dev" } done @@ -120,4
>>>> +120,3 @@ stop() zram_reset "$zram_dev" "claiming memory back" }
>>>> done } - ---
>>>> a/target/linux/generic/patches-3.10/998_zram_make_2_devices_by_default.patch
>>>>
>>>>
>>> +++
>>> b/target/linux/generic/patches-3.10/998_zram_make_2_devices_by_default.patch
>>>> @@ -0,0 +1,11 @@ +--- a/drivers/staging/zram/zram_drv.c ++++
>>>> b/drivers/staging/zram/zram_drv.c +@@ -40,7 +40,7 @@ static int
>>>> zram_major; + struct zram *zram_devices; + + /* Module params
>>>> (documentation at end) */ +-static unsigned int num_devices = 1; 
>>>> ++static unsigned int num_devices = 2; + + static void
>>>> zram_stat64_add(struct zram *zram, u64 *v, u64 inc) + { 
>>>> _______________________________________________ openwrt-devel
>>>> mailing list openwrt-devel@lists.openwrt.org 
>>>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
>>>>
>>> _______________________________________________
>>> openwrt-devel mailing list
>>> openwrt-devel@lists.openwrt.org
>>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
>>>
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to