Commit cd71906b authored by Franco Lanza's avatar Franco Lanza

import latest git version from debian

parent 92e1fef2
This diff is collapsed.
This diff is collapsed.
SHELL=/bin/bash
BINARY=libcowdancer.so cow-shell cowbuilder qemubuilder cowdancer-ilistcreate \
cowdancer-ilistdump
INSTALL_DIR=install -d -o root -g root -m 755
INSTALL_FILE=install -o root -g root -m 644
INSTALL_PROGRAM=install -o root -g root -m 755
DESTDIR=
PREFIX=/usr
LIBDIR=$(PREFIX)/lib
CFLAGS=-O2 -Wall -g -fno-strict-aliasing
CFLAGS_LFS=$(CFLAGS) $(shell getconf LFS_CFLAGS)
PWD=$(shell pwd)
export VERSION=$(shell sed -n '1s/.*(\(.*\)).*$$/\1/p' < debian/changelog )
all: $(BINARY)
install: $(BINARY)
$(INSTALL_DIR) $(DESTDIR)${PREFIX}/bin
$(INSTALL_DIR) $(DESTDIR)${LIBDIR}/cowdancer
$(INSTALL_DIR) $(DESTDIR)${PREFIX}/share/man/man1
$(INSTALL_DIR) $(DESTDIR)${PREFIX}/share/man/man8
$(INSTALL_FILE) cow-shell.1 $(DESTDIR)/usr/share/man/man1/cow-shell.1
$(INSTALL_FILE) cowdancer-ilistcreate.1 $(DESTDIR)/usr/share/man/man1/cowdancer-ilistcreate.1
$(INSTALL_FILE) cowdancer-ilistdump.1 $(DESTDIR)/usr/share/man/man1/cowdancer-ilistdump.1
$(INSTALL_FILE) cowbuilder.8 $(DESTDIR)/usr/share/man/man8/cowbuilder.8
$(INSTALL_FILE) qemubuilder.8 $(DESTDIR)/usr/share/man/man8/qemubuilder.8
$(INSTALL_FILE) libcowdancer.so $(DESTDIR)${LIBDIR}/cowdancer/libcowdancer.so
$(INSTALL_PROGRAM) cow-shell $(DESTDIR)/usr/bin/cow-shell
$(INSTALL_PROGRAM) cowbuilder $(DESTDIR)/usr/sbin/cowbuilder
$(INSTALL_PROGRAM) qemubuilder $(DESTDIR)/usr/sbin/qemubuilder
$(INSTALL_PROGRAM) cowdancer-ilistcreate $(DESTDIR)/usr/bin/cowdancer-ilistcreate
$(INSTALL_PROGRAM) cowdancer-ilistdump $(DESTDIR)/usr/bin/cowdancer-ilistdump
$(INSTALL_DIR) $(DESTDIR)/etc/bash_completion.d
$(INSTALL_FILE) bash_completion.qemubuilder $(DESTDIR)/etc/bash_completion.d/qemubuilder
$(INSTALL_FILE) bash_completion.cowbuilder $(DESTDIR)/etc/bash_completion.d/cowbuilder
libcowdancer.so: cowdancer.lo ilistcreate.lo
$(CC) $(CFLAGS) -shared -o $@ $^ -ldl
cow-shell: cow-shell.o ilistcreate.o
$(CC) $(CFLAGS) -o $@ $^
cowdancer-ilistcreate: cowdancer-ilistcreate.o ilistcreate.o
$(CC) $(CFLAGS) -o $@ $^
cowbuilder: cowbuilder.o parameter.o forkexec.o ilistcreate.o main.o cowbuilder_util.o
$(CC) $(CFLAGS) -o $@ $^
qemubuilder: qemubuilder.lfso parameter.lfso forkexec.lfso qemuipsanitize.lfso qemuarch.lfso file.lfso main.lfso
$(CC) $(CFLAGS) -o $@ $^
%.lo: %.c
$(CC) $(CFLAGS) -fPIC $< -o $@ -c
%.lfso: %.c
$(CC) $(CFLAGS_LFS) $< -o $@ -c
%.o: %.c parameter.h
$(CC) $(CFLAGS) $< -o $@ -c -D LIBDIR="\"${LIBDIR}\""
clean:
-rm -f *~ *.o *.lo *.lfso $(BINARY)
-make -C initrd clean
upload-dist-all:
scp ../cowdancer_$(VERSION).tar.gz aegis.netfort.gr.jp:public_html/software/downloads
fastcheck:
set -e; set -o pipefail; for A in ./test_*.c; do echo $$A; \
./tests/run_c.sh $$A 2>&1 | \
tee tests/log/$${A/*\//}.log; done
slowcheck: cowdancer-ilistdump qemubuilder cow-shell
# FIXME: The tests are running installed cowdancer, not the just-built
set -e; set -o pipefail; for A in tests/[0-9][0-9][0-9]_*.sh; \
do echo $$A; \
PATH="$(PWD):$(PWD)/tests:/usr/bin/:/bin" \
COWDANCER_SO=$(PWD)/libcowdancer.so \
bash $$A 2>&1 | \
sed -e's,/tmp/[^/]*,/tmp/XXXX,g' \
-e "s,^Current time:.*,Current time: TIME," \
-e "s,^pbuilder-time-stamp: .*,pbuilder-time-stamp: XXXX," \
-e "s,^Fetched .*B in .*s (.*B/s),Fetched XXXB in Xs (XXXXXB/s)," \
| tee tests/log/$${A/*\//}.log; done
check: fastcheck slowcheck
check-syntax:
$(CC) -c $(CFLAGS) $(CHK_SOURCES) -o/dev/null -D LIBDIR="\"${LIBDIR}\""
.PHONY: clean check upload-dist-all check-syntax fastcheck slowcheck
0.26 4 Mar 2007
+ add RPM spec file.
0.22 26 Aug 2006
+ cowbuilder documentation update.
0.21 20 Aug 2006
+ cowbuilder bugfix
0.15 29 May 2006
+ add help message to cowbuilder.
+ fix --basepath handling, --distribution handling
+ fix other option handling
+ update testsuite
0.14 24 May 2006
+ introducing an application "cowbuilder", a pbuilder frontend to use
cowdancer.
0.13 5 Mar 2006
+ Fix: support quote and space in filenames
(use exec instead of system.)
0.12 5 Mar 2006
+ Fix: support space in filenames.
Currently still doesn't support filename with "'", is there a need?
0.11 25 Jan 2006
+ Check for error values on COW operation, and return error to application, with ENOMEM.
0.10 14 Jan 2006
+ fixes hangs with applications that are using pthread.
+ Added more checks in the testsuite.
0.9 8 Jan 2006
+ Change order of copying. for the case when /lib/ld.so binary is
written to; I cannot fork/exec shared binaries while ld.so does not
exist.
0.8 28 Dec 2005
+ Speed improvement 1: save binary ilist in cow-shell and load the binary data
with mmap in cowdancer.
+ Speed improvement 2: sort ilist and do a binary search within it.
+ Make code a bit more thread-safe than it was.
0.7 23 Nov 2005
+ Bug fix: Work around 5.3.0 coreutils 'feature' which stat no longer
emits a newline for --format option.
+ Bug fix: Work around recent coreutils failing to do
cp -al 1/ 2/
when 2/ does not already exist.
+ Environment variable COWDANCER_DEBUG can now be used for debugging
e.g. COWDANCER_DEBUG=1 make -k check (warning, log is massive)
0.6 28 Oct 2005
+ Add support for chown and chmod
+ Fix problem with powerpc, fill structs with memset.
0.5 21 Sep 2005
+ Support the case when SHELL is not a full path
0.4 30 Aug 2005
+ Fix Error checking so that it does more than kill(SIGSEGV) to self.
0.3 20 Aug 2005
+ Add regression testsuite.
+ Support symbollic links
+ fopen/fopen64 is now trapped
+ only COW regular files
+ do not try to cross device boundaries when creating the ilink list.
+ Now it is able to run pbuilder 0.130.
0.2 13 Aug 2005
+ Buffer overflow bug fixed.
0.1 13 Aug 2005
+ Initial Public Release.
# Debian GNU/Linux cowbuilder(1) completion
# Copyright 2007 Cyril Brulebois <cyril.brulebois@enst-bretagne.fr>
# Copyright 2011 David Paleino <dapal@debian.org>
#
# This script can be distributed under the same license as the
# cowdancer or bash packages.
have cowbuilder &&
_cowbuilder()
{
local initialcommand initialcommand_options cur prev words other_options distribution
COMPREPLY=()
_get_comp_words_by_ref cur prev words
initialcommand=${words[1]}
initialcommand_options='--create --update --build --login --execute'
other_options='--dumpconfig --distribution --mirror --basepath --architecture'
distribution='sid sarge etch woody lenny squeeze'
case $prev in
--distribution)
COMPREPLY=( $(compgen -W "$distribution" | grep "^$cur" ) )
return 0
;;
--basepath)
_filedir -d
return 0
;;
*)
;;
esac
case $initialcommand in
--build)
COMPREPLY=( $( compgen -W "$other_options" -- "$cur" )
$( compgen -o filenames -G "$cur*.dsc" ) )
;;
--execute)
COMPREPLY=( $( compgen -W "$other_options" -- "$cur" )
$( compgen -o filenames -G "$cur*" ) )
;;
*)
COMPREPLY=( $( compgen -W "$initialcommand_options $other_options" -- "$cur" ) )
;;
esac
return 0
} &&
complete -F _cowbuilder cowbuilder
#!/bin/bash
# Debian GNU/Linux cowbuilder(1) completion
# Copyright 2007 Cyril Brulebois <cyril.brulebois@enst-bretagne.fr>
# Copyright 2009 Junichi Uekawa
#
# This script can be distributed under the same license as the
# cowdancer or bash packages.
have qemubuilder &&
_qemubuilder()
{
local initialcommand initialcommand_options cur prev other_options distribution
COMPREPLY=()
cur=$(_get_cword)
prev=${COMP_WORDS[COMP_CWORD-1]}
initialcommand=${COMP_WORDS[1]}
initialcommand_options='--create --update --build --login --execute'
other_options='--dumpconfig --distribution --mirror --basepath --architecture'
distribution='sid sarge etch woody lenny squeeze'
case $initialcommand in
--build)
COMPREPLY=( $( compgen -W "$other_options" | grep "^$cur" )
$( compgen -o filenames -G "$cur*.dsc" ) )
;;
--execute)
COMPREPLY=( $( compgen -W "$other_options" | grep "^$cur" )
$( compgen -o filenames -G "$cur*" ) )
;;
*)
COMPREPLY=( $( compgen -W "$initialcommand_options" | grep "^$cur" )
$( compgen -W "$other_options" | grep "^$cur" )
)
;;
esac
case $prev in
--distribution)
COMPREPLY=( $(compgen -W "$distribution" | grep "^$cur" ) )
;;
*)
esac
return 0
}
[ "$have" ] && complete -F _qemubuilder -o filenames qemubuilder
This directory contains files which are useful when benchmarking
cowdancer and qemubuilder.
[Just a memo on how to profile stuff.]
debuild -e DEB_BUILD_OPTIONS=nostrip,noopt
opreport -lg #function level
opreport -lgd #instruction level
/*
__builtin_expect(!initialized,0)
00001020 9 0.0061 cowdancer.c:134 libcowdancer.so find initialize_functions
00001021 1 11.1111 cowdancer.c:134
00001023 1 11.1111 cowdancer.c:134
00001024 1 11.1111 cowdancer.c:134
0000102b 1 11.1111 cowdancer.c:134
0000103d 1 11.1111 cowdancer.c:140
00001048 2 22.2222 cowdancer.c:187
00001051 2 22.2222 cowdancer.c:187
__builtin_expect(!initialized,1)
00001020 16 0.0131 cowdancer.c:134 libcowdancer.so find initialize_functions
00001021 1 6.2500 cowdancer.c:134
0000102b 3 18.7500 cowdancer.c:134
00001037 1 6.2500 cowdancer.c:140
0000103d 2 12.5000 cowdancer.c:140
000011d9 1 6.2500 cowdancer.c:187
000011df 7 43.7500 cowdancer.c:187
000011fa 1 6.2500 cowdancer.c:194
*/
set -e
WORKDIR=/tmp/oprofwork
rm -rf "$WORKDIR" || true
mkdir "$WORKDIR"
cd "$WORKDIR"
sudo apt-get build-dep apt dpkg
apt-get source apt
apt-get source dpkg
(cd apt-*; debuild -e DEB_BUILD_OPTIONS=nostrip)
(cd dpkg-*; debuild -e DEB_BUILD_OPTIONS=nostrip)
sudo dpkg -i *.deb
#!/bin/bash
# compare file $1 and $2, ignoring the time difference.
diff -u <(
sed 's/^\[[0-9]\+\] //' < $1
) <(
sed 's/^\[[0-9]\+\] //' < $2
)
/*BINFMTC:
Pipe through this program to get time information on each line of text.
Use it like:
sudo cowbuilder --update | ./time-output.c [optional: file-to-tee]
*/
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
void fix_terminal()
{
struct termios t;
if (isatty(1))
{
tcgetattr(1, &t);
t.c_lflag |= ECHO;
tcsetattr(1, TCSANOW, &t);
}
}
int main(int argc, char** argv)
{
time_t start = time(NULL);
char b[4096];
FILE* f = NULL;
if (argc == 2)
{
printf("Output tee to extra file %s\n", argv[1]);
f = fopen(argv[1], "w");
}
while(fgets(b,sizeof(b),stdin)!=0)
{
printf("[%i] %s",
(int)difftime(time(NULL), start),
b);
fflush(stdout);
if (f)
{
fprintf(f, "[%i] %s",
(int)difftime(time(NULL), start),
b);
fflush(f);
}
}
if (f) fclose(f);
fix_terminal();
return 0;
}
.TH "cow\-shell" 1 "2006 Jan 25" "cowdancer" "cowdancer"
.SH "NAME"
cow\-shell \- Start a copy-on-write session and invoke a shell.
.SH SYNOPSIS
.BI "cow-shell [" "commandline" "]"
.SH DESCRIPTION
.B cow\-shell
Executes specified command with
.B cowdancer
or a shell if no command-line option is given.
Inside the cowdancer session, files under the current directory
are protected in a way so that a write operation to an i-node
which existed at the point of running cow-shell
is not modified.
Useful for managing hard-linked source-trees and
scratch-filesystems.
.SH "EXAMPLES"
.TP
.B "cp -al cowdancer/ cowdancer.new && cd cowdancer.new && cow-shell "
Create a hardlinked tree, and cd into the newly created tree.
After invoking cow-shell inside that tree, a write operation
against a file that is hardlinked with the original tree
will be copied to a new file before write.
.TP
.B "cp -al cowdancer/ cowdancer.new && cd cowdancer.new && cow-shell debuild"
Tries to run dpkg-buildpackage on the new tree,
to avoid damage to the original tree.
Configure debuild to ignore
.B ".ilist"
files, through
.B "-i"
or
.B "-I"
option.
.PP
.SH "FILES"
.TP
.B ".ilist"
Generated dynamically in the current directory.
The file contains the list of i-node numbers that should be
protected from write operation.
.TP
.B "/usr/lib/cowdancer/libcowdancer.so"
The shared library used internally that overrides some functions
that potentially write to files.
This library implements the COW feature and is preloaded with
LD_PRELOAD.
.TP
.B "/bin/cp"
Used for copying.
Requires GNU option
.B "\-a"
to be functional.
.SH "ENVIRONMENT"
.TP
.B "COWDANCER_ILISTFILE"
The path to the current
.B .ilist
file.
.TP
.B "COWDANCER_IGNORE"
Used internally to work around infinite loops.
It will be unset.
.TP
.B "LD_PRELOAD"
Utilized to preload
.B libcowdancer.so
.TP
.B "COWDANCER_DEBUG"
Debugging option.
Enables debug messages.
cowdancer will give verbose debug messages in standard error output.
.TP
.B "COWDANCER_SO"
Debugging option.
Specifies a different path for libcowdancer.so.
.TP
.B "COWDANCER_REUSE=yes"
Enables reuse of cowdancer .ilist file found for consecutive runs of
cow-shell.
.SH "RETURN VALUE"
The functions that are overridden with cowdancer will give an errno
value of
.B ENOMEM
when there is a problem.
System isn't really out of memory, but this error code is chosen
because this error is usually handled gracefully by applications.
.SH "RESTRICTIONS"
Can only support directories that are scanned by
.B cow-shell
command.
The operation is not semantically correct when files are originally
hardlinked, hardlinks are always broken.
Does not support anything when LD_PRELOAD trick does not work.
Does not work unless hardlinks are supported on the filesystem.
Not very user-friendly.
Leaves
.B ".ilist"
file around.
.SH "AUTHOR"
Junichi Uekawa (dancer@debian.org)
Upstream page is available at
.B "http://www.netfort.gr.jp/~dancer/software/cowdancer.html"
.SH "SEE ALSO"
.BR "cowdancer-ilistcreate (" 1 ")"
/*BINFMTC: -DLIBDIR='"/usr/lib"' ilistcreate.c
Copy-on-write filesystem invocation.
GPL v2 or later
Copyright 2005-2009 Junichi Uekawa.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/wait.h>
#include "ilist.h"
const char* ilist_PRGNAME="cow-shell";
static const char* ilistpath="./.ilist";
/*
* remove ilist after use.
*/
static void ilist_deleter(const char* ilistfile)
{
if(fork()==0)
{
/* I am the child process */
pid_t parent_pid=getppid();
if (daemon(0,1) < 0)
{
perror("cow-shell daemon");
exit (-1);
}
while (kill(parent_pid,0) >= 0)
{
sleep(1);
}
if (unlink(ilistfile)==-1)
{
perror("cow-shell unlink .ilist");
exit(1);
}
exit(0);
}
}
/**
* Set environment variables.
*/
static void set_env_vars() {
char* buf;
// For sending down as environment variable, use a canonicalized version.
char* canonicalized_ilistpath=canonicalize_file_name(ilistpath);
setenv("COWDANCER_ILISTFILE",
canonicalized_ilistpath,1);
unsetenv("COWDANCER_IGNORE");
free(canonicalized_ilistpath);
asprintf(&buf, "%s%s%s",
getenv("LD_PRELOAD")?:"",
getenv("LD_PRELOAD")?" ":"",
getenv("COWDANCER_SO") ?: LIBDIR "/cowdancer/libcowdancer.so");
setenv("LD_PRELOAD", buf, 1);
free(buf);
}
/* give me a command-line to exec,
and I will cow-keep what's under this directory. */
int main(int ac, char** av)
{
struct stat st;
int cowdancer_reuse;
cowdancer_reuse=getenv("COWDANCER_REUSE") &&
!strcmp(getenv("COWDANCER_REUSE"),"yes") ;
if (cowdancer_reuse && !stat(ilistpath, &st))
{
/* if reuse flag is on and file already exists
do nothing */
}
else
{
if (unlink(ilistpath)==-1)
{
if (errno == ENOENT)
{
/* expected */
}
else
{
perror("cow-shell: unlink of .ilist failed");
return 1;
}
}
if(ilistcreate(ilistpath, NULL))
{
ilist_outofmemory(".ilist creation failed");
return 1;
}
}
set_env_vars();
if (!cowdancer_reuse)
{
/* if reuse flag is not on, remove the file */
ilist_deleter(ilistpath);
}
if (ac>1)
execvp(av[1], av+1);
else
{
const char* myshell=getenv("SHELL")?:"/bin/sh";
fprintf(stderr, "Invoking %s\n", myshell);
execlp(myshell,
myshell,
NULL);
perror("cow-shell: exec");
fprintf(stderr, "Falling back to /bin/sh\n");
execlp("/bin/sh",
"/bin/sh",
NULL);
}
perror("cow-shell: exec");
return 1;
}
.TH "cowbuilder" 8 "2007 Jun 17" "cowdancer" "cowdancer"
.SH "NAME"
cowbuilder \- a pbuilder wrapper for cowdancer.
.SH SYNOPSIS
.BI "cowbuilder [" "commands" "] [" "options" "]"
.SH DESCRIPTION
.B cowbuilder
Executes the specified pbuilder operation with
.B cowdancer
.SH "COMMANDS"
Most commands invoke pbuilder with the specified commands, see
pbuilder manual for details.
.TP
.B "\-\-create"
Create the base.cow image.
The directory for base.cow should be empty, or this command will fail.
.TP
.B "\-\-update"
Update the base.cow image.
.TP
.BI "\-\-build " ".dsc-file"