/*
* This programs intends to replace some basic linuxrc scripts found in initrd
* This one is made for my old configuration with lvm
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <linux/unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <linux/kdev_t.h>
_syscall2(int,pivot_root,const char *,new_root,const char *,put_old);
//Like system(), but more controllable (especially regarding signals)
void launch(char *commande) {
int pid=fork();
if(pid ==0 ) {
int nb;
char *cmd=strdup(commande);
char *cmd2=strdup(cmd);
nb= (strtok(cmd, " ") != NULL) ? 1 : 0;
if(nb==0)
exit(-1);
for(nb=1;strtok(NULL, " ")!=NULL;nb++);
char **args=malloc(sizeof(char*)*nb+1);
free(cmd);
cmd=cmd2;
if(!args)
exit(-1);
args[1]=NULL;
args[0]=strtok(cmd, " ");
for(nb=1;(args[nb]=strtok(NULL, " "))!=NULL;nb++) {
args=realloc(args, sizeof(char*)*nb+1);
}
args[nb]=NULL;
execvp(args[0], args);
exit(-1);
}
int ret;
waitpid(pid, &ret, 0);
}
//Q&D error check
void check_errno(char *what) {
if(errno==EINTR)
errno=0;
if(errno>0) {
perror(what);
exit(1);
}
}
//Look at dm-dev.c for more information about this function
void create_mapper_control() {
FILE *file=fopen("/proc/misc", "r");
char *buf=NULL;
size_t len=-1;
while(getline(&buf, &len, file)>0) {
char dev_name[256];
int dev_nb=-1;
sscanf(buf, "\t%d %255s\n", &dev_nb, dev_name);
if(strcmp(dev_name, "device-mapper")==0) {
printf("%d:%s\n", dev_nb, dev_name);
unlink("/dev/mapper/control");
mknod("/dev/mapper/control", S_IFCHR|0700,MKDEV(/*misc devices */10,dev_nb));
}
buf=NULL;
}
fclose(file);
}
//Prepare resume (or at least suspend for later) with suspend2 (syntax may have changed)
void launch_resume() {
FILE *file=fopen("/proc/software_suspend/resume2", "w");
char *str;
str="swap:0x0301\n";
fwrite(str, strlen(str),1,file);
fclose(file);
file=fopen("/proc/software_suspend/do_resume", "w");
fwrite("\n", 2,1,file);
fclose(file);
}
//All this should be explicit, if not just email me
int main(int argc, char **argv, char **envp) {
mount("procfs", "/proc", "proc", 0,NULL);
check_errno("mount /proc");
create_mapper_control();
launch("/bin/lvm vgscan");
check_errno("vgscan");
launch("/bin/lvm vgchange -a y");
check_errno("vgchange");
launch("/bin/lvm vgmknodes");
check_errno("vgmknodes");
launch_resume();
mount("/dev/pierre/fnux", "/sysroot", "reiserfs", 0, "user_xattr,acl");
check_errno("mount /sysroot");
struct stat stat_buf;
if(stat("/dev/mapper/pierre-fnux", &stat_buf)==0)
printf("pierre/fnux = %x\n", (unsigned int)stat_buf.st_rdev);
umount("/proc");
check_errno("umount /proc");
chdir("/sysroot");
check_errno("cd /sysroot");
if(pivot_root(".", "initrd")!=0) {
check_errno("pivot_root");
exit(-1);
}
argv[0]="init";
chroot(".");
execve("/sbin/init", argv, envp);
return 0;
}