/ramfs.c (6d142befdbc559aa3b6089443a2988b054bc71de) (3180 bytes) (mode 100644) (type blob)

/*******************************************************************************
this code is protected by the GNU affero GPLv3
author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
*******************************************************************************/
#include <ulinux/compiler_types.h>
#include <ulinux/types.h>
#include <ulinux/error.h>
#include <ulinux/fs.h>
#include <ulinux/file.h>
#include <ulinux/dirent.h>
#include <ulinux/utils/mem.h>
#include <ulinux/utils/ascii/string/string.h>
#include <ulinux/sysc.h>

#include "out.h"
#include "ulinux_namespace.h"
#include "globals.h"

#define DIRENTS_BUF_SZ 8192

static u8 is_current(u8 *n)
{
  if(n[0]=='.'&&n[1]==0) return 1;
  return 0;
}

static u8 is_parent(u8 *n)
{
  if(n[0]=='.'&&n[1]=='.'&&n[2]==0) return 1;
  return 0;
}

static u8 is_newroot(u8 *n)
{
  #define NEWROOT (u8*)"newroot"
  return strncmp(n,NEWROOT,sizeof(NEWROOT)-1)?0:1;
}

static void unlink(i parent_fd,u8 *n,i flgs)
{
  l r=unlinkat(parent_fd,n,flgs);
  if(ISERR(r)){
    OUT("ERROR(%ld):unable to remove dir entry:%s\n",r,n);
    exit_group(-1);
  }
}

static void dir_del(i parent_fd);
static void dirent_del(i parent_fd,struct dirent64 *d)
{
  if(d->type==DT_DIR){
    if(!is_current(d->name)&&!is_parent(d->name)){
      i dir_fd;
      loop{
        dir_fd=(i)openat(parent_fd,d->name,ULINUX_O_RDONLY|ULINUX_O_NONBLOCK);
        if(dir_fd!=-EINTR) break;
      }
      if(ISERR(dir_fd)){
        OUT("ERROR(%d):unable to open subdir:%s\n",dir_fd,d->name);
        exit_group(-1);
      }else{
        l r;
        dir_del(dir_fd);
        loop{
          r=close(dir_fd);
          if(r!=-EINTR) break;
        }
        if(ISERR(r)){
          OUT("ERROR(%ld):unable to close dir fd\n",r);
          exit_group(-1);
        }
      }
      unlink(parent_fd,d->name,AT_REMOVEDIR);
    }
  }else unlink(parent_fd,d->name,0);
}

static void dir_del(i parent_fd)
{
  u8 dirents[DIRENTS_BUF_SZ];
  loop{
    l idx;
    l r=getdents64(parent_fd,dirents,DIRENTS_BUF_SZ);
    if(ISERR(r)){
      OUT("ERROR(%ld):getdents error\n",r);
      exit_group(-1);
    }

    if(!r) break;

    idx=0;
    loop{
      struct dirent64 *d;

      if(idx>=r) break;
      d=(struct dirent64*)(dirents+idx);
      dirent_del(parent_fd,d);
      idx+=d->rec_len;
    }
  }
}

void ramfs_cleanup(void)
{
  OUT(PRE "cleaning ramfs...");
  i root_fd;
  loop{
    root_fd=(i)open("/",ULINUX_O_RDONLY|ULINUX_O_NONBLOCK);
    if(root_fd!=-EINTR) break;
  }
  if(ISERR(root_fd)){
    OUT("ERROR(%d):unable to open root dir\n",root_fd);
    exit_group(-1);
  }

  u8 dirents[DIRENTS_BUF_SZ];
  loop{
    l idx;
    l r=getdents64(root_fd,dirents,DIRENTS_BUF_SZ);
    if(ISERR(r)){
      OUT("ERROR(%ld):getdents error\n",r);
      exit_group(-1);
    }

    if(!r) break;/*empty*/

    idx=0;
    loop{
      struct dirent64 *d;

      if(idx>=r) break;

      d=(struct dirent64*)(dirents+idx);
      if(!is_newroot(d->name)) dirent_del(root_fd,d);
      idx+=d->rec_len;
    }
  }
  l r;
  loop{
    r=close(root_fd);
    if(r!=-EINTR) break;
  }
  if(ISERR(r)){
    OUT("ERROR(%ld):unable to root dir fd\n",r);
    exit_group(-1);
  }
  OUT("done\n");
}


Mode Type Size Ref File
100644 blob 444 49d5064b5a60c1d457aaf871c71275eb962d83f2 3.16
100644 blob 558 3b1926aa2a9e5e4a8fa5c8a3d178a0ed02a01346 DEPENDENCIES
100644 blob 35147 94a9ed024d3859793618152ea559a168bbcbb5e2 LICENSE.md
100644 blob 768 32cae14d717baa6c88aab11a82663e0a2aefe652 README
100644 blob 644 598bf35b742147b3cc2bc1da0fd6d41aa282e77e TODO
100644 blob 432 2516d063ca695699c1ec3d755ef782bad84f203f cpio.in
100644 blob 587 1890391057120a83a6714310987be3ca82de46cc globals.h
100644 blob 5197 6caef253d4902e1c038135a156d42a847c89dddf init.c
100755 blob 12172 9f4bb09cd1e95ca807848a2445e8580f0a8b0aa6 make
100644 blob 5877 e849ba428752ea61144fe879792c8c68a65e3160 modules.c
100644 blob 503 f478bdeefa4ae3259dedfe0b4f78036492295d27 modules.h
100644 blob 674 7f272e25a25b4da12ad81f13b6eeff1bba4187af out.h
100644 blob 3180 6d142befdbc559aa3b6089443a2988b054bc71de ramfs.c
100644 blob 341 de9218a39777b8dd8feb5ee76cdf41af215ef473 ramfs.h
040000 tree - 87b8a0b9717f8367a1f8427da787968136f8aac9 script
100644 blob 3592 e6e7af84e5bd621843bfee6c9907ad85f789dccb uevent.c
100644 blob 348 cf07be71685703316f9522de37d466034d08e635 uevent.h
100644 blob 3970 cfe47059c2c26697fd02d2f18b0afe68dc7627fd uevents.c
100644 blob 413 896725abf8b5477eb7013e55429aa89a2bf97ed3 uevents.h
040000 tree - 62d63dbff565849898f1b5138d50a03774874906 ulinux
100644 blob 4060 feb12fd4fc27f1442198ea878911269a2b2e1215 ulinux_namespace.h
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/cinitramfs

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/cinitramfs

Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/cinitramfs

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main