Re: [AVFS] resurrection of AVFS
Miklos Szeredi <[email protected]> Mon, 28 Feb 2005 13:56:13 +0100
| Newsgroups | gmane.comp.file-systems.avfs.user |
|---|---|
| Message-ID | <[email protected]> |
> Source code is nearly uncommented :( No tutorial, no API
> documentation, this situation could not attract more developers to
> use this library in their projects. I could write a basic tutorial
> with examples of use with some help from you. Investigating
> runtest.c is a good start point, are there more examples anywhere
> else?
Libavfs is mainly used by 'avfscoda' and 'preload' neither of which is
a very good example.
> Well, as an API I could count functions from "virtual.h". Correct me
> if I'm wrong. There is no documentation but functions from
> virtual.h seem s to behave like their libc counterpards. Function
> virt_read() behaves like read() but with support for reading from
> archives, it takes the same arguments, it return the same error
> codes and so on.
Yes, that is how it's supposed to work.
> Can I use AVFS for reading ordinary (real) files from local?
> I hope I can.
Yes though there are problems with this (see discussion with Ralf
Hoffmann).
> How to set temporary directory for archive cache?
/tmp is used, and this can't be changed currently. There's a patch by
Peter Kundrat that fixes this (attached), but there's a possible
buffer overflow in this, and I haven't yet integrated a fixed version.
> When is cache cleaned? Am I supposed to do it explicitly?
> fd = virt_open("/#avfsstat/cache/clear", O_WRONLY, 0);
> res = virt_write(fd, "1", 1);
> res = virt_close(fd);
> ..striped function flush_cache() in runtest.c
Yes. This is equivalent to "echo 1 > /#avfsstat/cache/clear"
> How you test archive change the situation someone copy file into the
> ZIP file. In which sourcefile, which function I can foud it? Is
> there something like 'dirty flag'?
The file modification time and other parameters are checked. The
function is arch_same() in archive.c.
> Is some kind of server started to keep tracks of opened archives?
> (suppose using avfs as library, no avfscoda, preload or fuse)
No. If you want to have persistent cache, then you must create a
server which uses libfuse, and client library which communicates with
the server. Basically this is what preload does.
> >From sourcecode organisation it looks like AVFS comes in four flavour.
> - library (layer libary above some functions from glibc)
> - avfscoda
> - preload (overload some methods in libc/glibc, so applications use avfs transparetly without)
> - fuse module
>
> In documentation only flavours 2 and 3 are mentioned!
>
> >From further investigation of mail-lists - only flavour 1 is fully
> >operational now, flavours 2 - 4 seems not to be fully operational
> >(or not operational at all) in newer glibc and kernels (>2.6.x).
1 (libavfs) is system independent, and hence should work in any UNIX
like environment.
2 (avfscoda) works on 2.4 kernels, and there's an effort by Olivier
Valentin to make it work on 2.6 kernels too. Attached his patch which
makes avfscoda compile under 2.6.
3 (avfs-preload) worked on older Solaris versions (I don't have a
Solaris machine anymore, so I can't test newer versions).
4 (avfs-fuse) works on 2.4 and 2.6, but is in an experimental state.
Thanks,
Miklos
avfs-tmpdir.patch
(application/octet-stream, 1.2 KB)
diff -ur avfs-0.9.3.orig/avfscoda/dispatch.c avfs-0.9.3/avfscoda/dispatch.c
--- avfs-0.9.3.orig/avfscoda/dispatch.c 2001-10-24 11:51:25.000000000 +0200
+++ avfs-0.9.3/avfscoda/dispatch.c 2004-11-22 01:48:20.000000000 +0100
@@ -1301,10 +1301,13 @@
open_file(req, of);
}
else {
- char tmpname[64];
+ char tmpname[64], *tmp;
int fd;
- strcpy(tmpname, "/tmp/.avfs_coda_XXXXXX");
+ tmp = getenv("TMPDIR");
+ if (!tmp)
+ tmp="/tmp";
+ sprintf(tmpname, "%s/.avfs_coda_XXXXXX", tmp);
fd = mkstemp(tmpname);
if(fd == -1) {
diff -ur avfs-0.9.3.orig/src/tmpfile.c avfs-0.9.3/src/tmpfile.c
--- avfs-0.9.3.orig/src/tmpfile.c 2001-12-26 19:12:23.000000000 +0100
+++ avfs-0.9.3/src/tmpfile.c 2004-11-22 01:45:45.000000000 +0100
@@ -115,9 +115,13 @@
AV_LOCK(tmplock);
if(tmpdir == NULL) {
- char *path;
+ char *path, *tmp;
- path = av_strdup("/tmp/.avfs_tmp_XXXXXX");
+ tmp = getenv("TMPDIR");
+ if (!tmp)
+ tmp="/tmp";
+ sprintf(buf, "%s/.avfs_tmp_XXXXXX", tmp);
+ path = av_strdup(buf);
res = make_tmp_dir(path);
if(res < 0)
av_free(path);
avfs-0.9.3-to-2.6-kernel-woRedir.patch
(application/octet-stream, 8.7 KB)
diff -Naur ./avfscoda/avfscoda.h ../../avfs-0.9.3/avfscoda/avfscoda.h
--- ./avfscoda/avfscoda.h 2001-05-11 19:29:01.000000000 +0200
+++ ../../avfs-0.9.3/avfscoda/avfscoda.h 2005-02-08 10:43:09.000000000 +0100
@@ -14,6 +14,12 @@
int path2size;
};
+struct AvfsFid { /* maps the content of opaque CodaFid for Avfs */
+ u_int32_t Unused0;
+ u_int32_t Unused1;
+ u_int32_t Unused2;
+ u_int32_t Unique;
+};
extern void run(int cfs, const char *codadir, int dm);
extern void child_process(int infd, int outfd);
diff -Naur ./avfscoda/child.c ../../avfs-0.9.3/avfscoda/child.c
--- ./avfscoda/child.c 2001-10-24 11:51:24.000000000 +0200
+++ ../../avfs-0.9.3/avfscoda/child.c 2005-02-08 10:54:59.000000000 +0100
@@ -16,8 +16,8 @@
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
-
#include <sys/stat.h>
+#include <signal.h>
/* #include "KERNINCLUDE/linux/coda.h" */
#include CODAINCLUDE
@@ -59,7 +59,7 @@
}
-static void st2attr(struct stat *s, struct coda_vattr *a, ViceFid *id)
+static void st2attr(struct stat *s, struct coda_vattr *a, struct CodaFid *id)
{
memset(a, 0, sizeof(struct coda_vattr));
a->va_type = st2type(s);
@@ -434,10 +434,12 @@
if(ret == -1)
rep->oh.result = errno;
else {
+ struct AvfsFid *id = (struct AvfsFid *)&rep->coda_lookup.VFid;
/* We don't know these */
- rep->coda_lookup.VFid.Volume = 0;
- rep->coda_lookup.VFid.Vnode = 0;
- rep->coda_lookup.VFid.Unique = 0;
+ id->Unused0 = 0;
+ id->Unused1 = 0;
+ id->Unused2 = 0;
+ id->Unique = 0;
rep->coda_lookup.vtype = st2type(&stbuf);
}
break;
diff -Naur ./avfscoda/dispatch.c ../../avfs-0.9.3/avfscoda/dispatch.c
--- ./avfscoda/dispatch.c 2001-10-24 11:51:25.000000000 +0200
+++ ../../avfs-0.9.3/avfscoda/dispatch.c 2005-02-08 10:43:11.000000000 +0100
@@ -98,6 +98,7 @@
struct openfile *ofs;
};
+
#define FMAPSIZE 65536
static struct fileinfo *fmap[FMAPSIZE];
static unsigned int nextunique = 0;
@@ -319,13 +320,17 @@
return fi;
}
-static struct fileinfo *look_info(ViceFid *id)
+static struct fileinfo *look_info(struct CodaFid *cid)
{
+ struct AvfsFid *id = (struct AvfsFid *)cid;
struct fileinfo *fi;
- if ((id->Volume != 0) || (id->Vnode != 0)) {
- logerr("Bad handle passed %lx/%lx/%lx\n",
- id->Volume, id->Vnode, id->Unique );
+ if ((id->Unused0 != 0) || (id->Unused1 != 0) || (id->Unused2 != 0)) {
+ logerr("Bad handle passed %lx/%lx/%lx/%lx\n",
+ (long unsigned int)id->Unused0,
+ (long unsigned int)id->Unused1,
+ (long unsigned int)id->Unused2,
+ (long unsigned int)id->Unique );
clean_exit(1);
}
@@ -345,7 +350,7 @@
}
}
-static char *look_name(ViceFid *id)
+static char *look_name(struct CodaFid *id)
{
struct fileinfo *fi;
@@ -358,7 +363,7 @@
return fi->path;
}
-static void ref_fid(ViceFid *fid)
+static void ref_fid(struct CodaFid *fid)
{
struct fileinfo *fi = look_info(fid);
@@ -366,7 +371,7 @@
fi->use ++;
}
-static void unref_fid(ViceFid *fid)
+static void unref_fid(struct CodaFid *fid)
{
struct fileinfo *fi = look_info(fid);
@@ -398,9 +403,10 @@
}
}
-static struct fileinfo *create_file(const char *filename, ViceFid *parentid,
- ViceFid *newid)
+static struct fileinfo *create_file(const char *filename, struct CodaFid *parentid,
+ struct CodaFid *newcid)
{
+ struct AvfsFid *newid = (struct AvfsFid *)newcid;
struct fileinfo *fi;
fi = look_info(parentid);
@@ -408,8 +414,9 @@
return NULL;
fi = get_file(fi, filename);
- newid->Volume = 0;
- newid->Vnode = 0;
+ newid->Unused0 = 0;
+ newid->Unused1 = 0;
+ newid->Unused2 = 0;
newid->Unique = fi->unique;
return fi;
@@ -418,6 +425,7 @@
static void purge_file(struct fileinfo *fi)
{
union outputArgs rep;
+ struct AvfsFid *id;
log("=================================================================\n");
log_date();
@@ -427,15 +435,18 @@
rep.oh.opcode = CODA_PURGEFID;
rep.oh.result = 0;
rep.oh.unique = 0;
- rep.coda_purgefid.CodaFid.Volume = 0;
- rep.coda_purgefid.CodaFid.Vnode = 0;
- rep.coda_purgefid.CodaFid.Unique = fi->unique;
+ id = (struct AvfsFid *)&rep.coda_purgefid.CodaFid;
+ id->Unused0 = 0;
+ id->Unused1 = 0;
+ id->Unused2 = 0;
+ id->Unique = fi->unique;
send_to_kernel(&rep, sizeof(rep.coda_purgefid));
}
static void zap_file(struct fileinfo *fi)
{
+ struct AvfsFid *id;
union outputArgs rep;
log("=================================================================\n");
@@ -446,9 +457,11 @@
rep.oh.opcode = CODA_ZAPFILE;
rep.oh.result = 0;
rep.oh.unique = 0;
- rep.coda_zapfile.CodaFid.Volume = 0;
- rep.coda_zapfile.CodaFid.Vnode = 0;
- rep.coda_zapfile.CodaFid.Unique = fi->unique;
+ id = (struct AvfsFid *)&rep.coda_zapfile.CodaFid;
+ id->Unused0 = 0;
+ id->Unused1 = 0;
+ id->Unused2 = 0;
+ id->Unique = fi->unique;
send_to_kernel(&rep, sizeof(rep.coda_zapfile));
}
@@ -582,7 +595,7 @@
}
static void close_file(struct openfile *of, struct openfile **ofp,
- ViceFid *fid)
+ struct CodaFid *fid)
{
if(of->use > 0) of->use --;
@@ -681,7 +694,10 @@
user->uid, user->gid, user->serverpid);
log_date();
log("%i (%i) bytes: opcode: %li, result: %i, unique: %li\n",
- numread, insize, rep->oh.opcode, (int) rep->oh.result, rep->oh.unique);
+ numread, insize,
+ (unsigned long int)rep->oh.opcode,
+ (unsigned int)rep->oh.result,
+ (unsigned long int)rep->oh.unique);
for(opp = &user->ops; *opp != NULL; opp = &(*opp)->next)
if((*opp)->req->ih.unique == rep->oh.unique) break;
@@ -691,7 +707,7 @@
if(op == NULL)
logerr("Operation not found!!!!\n");
else {
- log("Found operation: %li\n", op->req->ih.unique);
+ log("Found operation: %li\n", (unsigned long int)op->req->ih.unique);
switch(rep->oh.opcode) {
#ifdef CODA_OPEN_BY_FD
@@ -819,7 +835,7 @@
if(user->ops != NULL) {
log("Remaining operations: ");
for(op = user->ops; op != NULL; op = op->next)
- log("%li ", op->req->ih.unique);
+ log("%li ", (unsigned long int)op->req->ih.unique);
log("\n");
}
}
@@ -1058,8 +1074,8 @@
char *path2)
{
struct operation *op;
- uid_t uid = req->ih.cred.cr_fsuid;
- gid_t gid = req->ih.cred.cr_fsgid;
+ uid_t uid = req->ih.uid;
+ gid_t gid = req->ih.pgid;
struct userinfo *user;
int msgsize;
struct child_message msg;
@@ -1109,7 +1125,7 @@
memcpy(mp, req, msg.reqsize);
mp += msg.reqsize;
- log("****** opcode: %li\n", req->ih.opcode);
+ log("****** opcode: %li\n", (unsigned long int)req->ih.opcode);
log("****** msgsize: %i, msgoff: %i, msg.reqsize: %i, \n",
msgsize, msgoff, msg.reqsize);
@@ -1140,7 +1156,7 @@
}
static void send_with_path(union inputArgs *req, int reqsize, char *filename,
- ViceFid *id, char *path2)
+ struct CodaFid *id, char *path2)
{
char pathbuf[1024];
struct fileinfo *fi;
@@ -1239,19 +1255,25 @@
log("=================================================================\n");
log_date();
log("%i bytes: opcode: %li, unique: %li\n",
- numread, req->ih.opcode, req->ih.unique);
+ numread,
+ (unsigned long int)req->ih.opcode,
+ (unsigned long int)req->ih.unique);
switch (req->ih.opcode) {
case CODA_ROOT:
log("CODA_ROOT\n");
-
+
rep.oh.opcode = req->ih.opcode;
rep.oh.unique = req->ih.unique;
rep.oh.result = 0;
- rep.coda_root.VFid.Volume = 0;
- rep.coda_root.VFid.Vnode = 0;
- rep.coda_root.VFid.Unique = 0; /* 0 means root */
-
+ {
+ struct AvfsFid *fid;
+ fid = (struct AvfsFid *)&rep.coda_root.VFid;
+ fid->Unused0 = 0;
+ fid->Unused1 = 0;
+ fid->Unused2 = 0;
+ fid->Unique = 0; /* 0 means root */
+ }
send_to_kernel(&rep, sizeof(rep.coda_root));
break;
@@ -1312,7 +1334,7 @@
reply(req, ENFILE);
}
else {
- fchown(fd, req->ih.cred.cr_fsuid, req->ih.cred.cr_fsgid);
+ fchown(fd, req->ih.uid, req->ih.pgid);
close(fd);
of = malloc(sizeof(struct openfile));
@@ -1523,6 +1545,7 @@
break;
default:
+ logerr("Unknown opcode!!!!\n");
}
release_fids(op->req);