]> arthur.barton.de Git - netatalk.git/commitdiff
Add dtrace provider 'afp' and dtrace probes
authorRalph Boehme <sloowfranklin@gmail.com>
Mon, 11 Feb 2013 13:42:12 +0000 (14:42 +0100)
committerRalph Boehme <sloowfranklin@gmail.com>
Tue, 19 Feb 2013 17:50:12 +0000 (18:50 +0100)
There are three dtrace probes:
- all AFP functions, passing the function name as argument
- AFP read and write, passing the IO size as argument
- all CNID functions

In order to be able to simply differintiate between disk IO and
network IO, replace all occurences of read and write on sockets
with send/recv, and replace the use of writev in the logging code
with two calls to write.
As a result, using dtrace probes for read() and write() syscalls
can be used to gather metrics for disk IO, while probing send(),
recv() and writev() probe network IO.

22 files changed:
Makefile.am
NEWS
configure.ac
etc/afpd/Makefile.am
etc/afpd/afp_dsi.c
etc/afpd/appl.c
etc/afpd/catsearch.c
etc/afpd/directory.c
etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/filedir.c
etc/afpd/fork.c
include/atalk/.gitignore
include/atalk/Makefile.am
include/atalk/afp_dtrace.d [new file with mode: 0644]
include/atalk/globals.h
libatalk/dsi/dsi_stream.c
libatalk/util/logger.c
libatalk/util/socket.c
macros/netatalk.m4
macros/summary.m4
test/afpd/Makefile.am

index 0100598597364a3d8483a2686979afb9e1ad1d29..36a8c3cd3be5fcf8058916014c59682d6cf5a9af 100644 (file)
@@ -1,9 +1,9 @@
 # Makefile.am for top level of netatalk package
 
 if USE_BUILTIN_LIBEVENT
-SUBDIRS = libevent libatalk bin config etc man contrib distrib include doc macros test
+SUBDIRS = libevent include libatalk bin config etc man contrib distrib doc macros test
 else
-SUBDIRS = libatalk bin config etc man contrib distrib include doc macros test
+SUBDIRS = include libatalk bin config etc man contrib distrib doc macros test
 endif
 
 EXTRA_DIST = CONTRIBUTORS COPYRIGHT COPYING NEWS VERSION
diff --git a/NEWS b/NEWS
index df015fa52d5f62c271e270a78395dbc28dbff3b5..c0ec36194aaff6ab63d4c446755ae101d4cdf107 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,8 @@ Changes in 3.0.3
        program `afpstats`. Requires dbus, dbus-glib any python-dbus.
        configure option --dbus-sysconf-dir for specifying dbus
        system security configuration files.       
+* NEW: dtrace probes, cf include/atalk/afp_dtrace.d for available
+       probes.
 
 Changes in 3.0.2
 ================
index 88f81aaf067b2ee0cbc6caf68e384774fcbd63c6..566df4f4618623ab246041b84185063b6fe59ec4 100644 (file)
@@ -183,16 +183,19 @@ AC_NETATALK_LIBEVENT
 dnl libatalk API checks
 AC_DEVELOPER
 
+dnl Check for dtrace
+AC_NETATALK_DTRACE
+
+dnl Check for dbus-glib, for AFP stats on dbus
+AC_NETATALK_DBUS_GLIB
+
 dnl FHS stuff has to be done last because it overrides other defaults
 AC_NETATALK_FHS
 
 dnl netatalk lockfile path, must come after AC_NETATALK_FHS
 AC_NETATALK_LOCKFILE
 
-dnl Check for dbus-glib, for AFP stats on dbus
-AC_NETATALK_DBUS_GLIB
-
-CFLAGS="-I\$(top_srcdir)/include -I\$(top_srcdir)/sys $CFLAGS"
+CFLAGS="-I\$(top_srcdir)/include -I\$(top_builddir)/include $CFLAGS"
 UAMS_PATH="${uams_path}"
 
 AC_SUBST(LIBS)
index 1612344a5132232ba3b06262d6e31c4762022f39..335f4293e9b6546ab6028da90cac34dc4a3d8280 100644 (file)
@@ -46,6 +46,7 @@ afpd_SOURCES = \
        unix.c \
        volume.c
 
+
 afpd_LDADD =  \
        $(top_builddir)/libatalk/libatalk.la \
        @LIBGCRYPT_LIBS@ @QUOTA_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @ZEROCONF_LIBS@ @PTHREAD_LIBS@ @GSSAPI_LIBS@ @KRB5_LIBS@
@@ -83,6 +84,15 @@ afpd_CFLAGS  += $(DBUS_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_COMPILATION
 afpd_LDFLAGS += $(DBUS_LIBS) $(DBUS_GLIB_LIBS) -ldbus-glib-1
 endif
 
+if WITH_DTRACE
+DTRACE_OBJ = afpd-afp_dsi.o afpd-fork.o afpd-appl.o afpd-catsearch.o afpd-directory.o afpd-enumerate.o afpd-file.o afpd-filedir.o
+afp_dtrace.o: $(top_srcdir)/include/atalk/afp_dtrace.d $(DTRACE_OBJ)
+       if test -f afp_dtrace.o ; then rm -f afp_dtrace.o ; fi
+       $(LIBTOOL) --mode=execute dtrace -G -s $(top_srcdir)/include/atalk/afp_dtrace.d -o afp_dtrace.o $(DTRACE_OBJ)
+afpd_LDADD += afp_dtrace.o @DTRACE_LIBS@
+CLEANFILES += afp_dtrace.o
+endif
+
 noinst_HEADERS = auth.h afp_config.h desktop.h directory.h fce_api_internal.h file.h \
         filedir.h fork.h icon.h mangle.h misc.h status.h switch.h \
         uam_auth.h uid.h unix.h volume.h hash.h acls.h acl_mappings.h extattrs.h \
index 646e8d12f4e3bd555ef9bf9d9a8564b4ee025be1..5082ee70fea0f83d6d528fcc49a875520376d99c 100644 (file)
@@ -603,10 +603,12 @@ void afp_over_dsi(AFPObj *obj)
 
                     LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
 
+                    AFP_AFPFUNC_START(function, (char *)AfpNum2name(function));
                     err = (*afp_switch[function])(obj,
                                                   (char *)dsi->commands, dsi->cmdlen,
                                                   (char *)&dsi->data, &dsi->datalen);
 
+                    AFP_AFPFUNC_DONE(function, (char *)AfpNum2name(function));
                     LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
                         AfpNum2name(function), AfpErr2name(err));
 
@@ -644,10 +646,14 @@ void afp_over_dsi(AFPObj *obj)
 
                 LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
 
+                AFP_AFPFUNC_START(function, (char *)AfpNum2name(function));
+
                 err = (*afp_switch[function])(obj,
                                               (char *)dsi->commands, dsi->cmdlen,
                                               (char *)&dsi->data, &dsi->datalen);
 
+                AFP_AFPFUNC_DONE(function, (char *)AfpNum2name(function));
+
                 LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
                     AfpNum2name(function), AfpErr2name(err));
 
index 04dd92d612b61cb2e2dae143a7f438ae13962d0c..f53803e0dfc5f92ebcb5188ede9a146d2922a7b9 100644 (file)
@@ -170,7 +170,11 @@ makemacpath(const struct vol *vol, char *mpath, int mpathlen, struct dir *dir, c
         }
 
         /* next part */
-        if ((uname = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen)) == NULL ) {
+        AFP_CNID_START("cnid_resolve");
+        uname = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen);
+        AFP_CNID_DONE();
+
+        if (uname == NULL) {
             afp_errno = AFPERR_NOOBJ;
             ret = NULL;
             goto exit;
index 9ffea6e21415c3b0299efbdd6e6fdb863a95a974..63a9607cdc130acd32faba44906678cfdfc3510e 100644 (file)
@@ -743,11 +743,14 @@ static int catsearch_db(const AFPObj *obj,
 
         LOG(log_debug, logtype_afpd, "catsearch_db: %s", buffer);
 
-        if ((num_matches = cnid_find(vol->v_cdb,
-                                     buffer,
-                                     strlen(uname),
-                                     resbuf,
-                                     sizeof(resbuf))) == -1) {
+        AFP_CNID_START("cnid_find");
+        num_matches = cnid_find(vol->v_cdb,
+                                buffer,
+                                strlen(uname),
+                                resbuf,
+                                sizeof(resbuf));
+        AFP_CNID_DONE();
+        if (num_matches == -1) {
             result = AFPERR_MISC;
             goto catsearch_end;
         }
@@ -763,8 +766,12 @@ static int catsearch_db(const AFPObj *obj,
         memcpy(&cnid, resbuf + cur_pos * sizeof(cnid_t), sizeof(cnid_t));
         did = cnid;
 
-        if ((name = cnid_resolve(vol->v_cdb, &did, resolvebuf, 12 + MAXPATHLEN + 1)) == NULL)
+        AFP_CNID_START("cnid_resolve");
+        name = cnid_resolve(vol->v_cdb, &did, resolvebuf, 12 + MAXPATHLEN + 1);
+        AFP_CNID_DONE();
+        if (name == NULL)
             goto next;
+
         LOG(log_debug, logtype_afpd, "catsearch_db: {pos: %u, name:%s, cnid: %u}",
             cur_pos, name, ntohl(cnid));
         if ((dir = dirlookup(vol, did)) == NULL)
index eb1cdf581285171df9cfb090e5c9b1cd3e8d1907..d58023e2ac6e9b40408f1b869363206738dcbcbd 100644 (file)
@@ -497,12 +497,15 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
                                            cfrombstr(l->entry[i]),
                                            blength(l->entry[i]))) == NULL) {
 
-            if ((cnid = cnid_add(vol->v_cdb,             /* 6. */
-                                 &st,
-                                 did,
-                                 cfrombstr(l->entry[i]),
-                                 blength(l->entry[i]),
-                                 0)) == CNID_INVALID)
+            AFP_CNID_START("cnid_add");
+            cnid = cnid_add(vol->v_cdb,             /* 6. */
+                            &st,
+                            did,
+                            cfrombstr(l->entry[i]),
+                            blength(l->entry[i]),
+                            0);
+            AFP_CNID_DONE();
+            if (cnid == CNID_INVALID)
                 EC_FAIL;
 
             if ((dir = dirlookup(vol, cnid)) == NULL) /* 7. */
@@ -607,7 +610,11 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
     /* Get it from the database */
     cnid = did;
     LOG(log_debug, logtype_afpd, "dirlookup(did: %u): querying CNID database", ntohl(did));
-    if ((upath = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen)) == NULL) {
+
+    AFP_CNID_START("cnid_resolve");
+    upath = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen);
+    AFP_CNID_DONE();
+    if (upath == NULL) {
         afp_errno = AFPERR_NOOBJ;
         err = 1;
         goto exit;
@@ -2329,7 +2336,9 @@ int deletecurdir(struct vol *vol)
 
     err = netatalk_rmdir_all_errors(-1, cfrombstr(fdir->d_u_name));
     if ( err ==  AFP_OK || err == AFPERR_NOOBJ) {
+        AFP_CNID_START("cnid_delete");
         cnid_delete(vol->v_cdb, fdir->d_did);
+        AFP_CNID_DONE();
         dir_remove( vol, fdir );
     } else {
         LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): netatalk_rmdir_all_errors error",
index 5f0e1644a849e52efdfd059bb2467087dbd1dfb9..340f79aed6738676acd8341f7c1d7a46171324da 100644 (file)
@@ -365,9 +365,14 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
         if (ad_convert(sd.sd_last, &s_path.st, vol, &convname) == 0) {
             if (convname) {
                 s_path.u_name = (char *)convname;
+                AFP_CNID_START("cnid_lookup");
                 s_path.id = cnid_lookup(vol->v_cdb, &s_path.st, curdir->d_did, sd.sd_last, strlen(sd.sd_last));
+                AFP_CNID_DONE();
                 if (s_path.id != CNID_INVALID) {
-                    if (cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, (char *)convname, strlen(convname)) != 0)
+                    AFP_CNID_START("cnid_update");
+                    int cnid_up_ret = cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, (char *)convname, strlen(convname));
+                    AFP_CNID_DONE();
+                    if (cnid_up_ret != 0)
                         LOG(log_error, logtype_afpd, "enumerate: error updating CNID of \"%s\"", fullpathname(convname));
                 }
             }
index e7859659bd05ba996b91bd5c052ed6153cddef58..bd516087a78debe218e6d0654b38f2ceea1b251e 100644 (file)
@@ -219,7 +219,10 @@ restart:
            catching moved files */
         adcnid = ad_getid(adp, st->st_dev, st->st_ino, 0, vol->v_stamp); /* (1) */
 
+        AFP_CNID_START("cnid_add");
            dbcnid = cnid_add(vol->v_cdb, st, did, upath, len, adcnid); /* (2) */
+        AFP_CNID_DONE();
+
            /* Throw errors if cnid_add fails. */
            if (dbcnid == CNID_INVALID) {
             switch (errno) {
@@ -1602,8 +1605,15 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib)
         err = AFPERR_BUSY;
     } else if (!(err = vol->vfs->vfs_deletefile(vol, dirfd, file)) && !(err = netatalk_unlinkat(dirfd, file )) ) {
         cnid_t id;
-        if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) {
-            cnid_delete(vol->v_cdb, id);
+        if (checkAttrib) {
+            AFP_CNID_START("cnid_get");
+            id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file));
+            AFP_CNID_DONE();
+            if (id) {
+                AFP_CNID_START("cnid_delete");
+                cnid_delete(vol->v_cdb, id);
+                AFP_CNID_DONE();
+            }
         }
     }
 
@@ -1676,7 +1686,10 @@ int afp_createid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
             return AFPERR_PARAM;
     }
     st = &s_path->st;
-    if ((id = cnid_lookup(vol->v_cdb, st, did, upath, len = strlen(upath)))) {
+    AFP_CNID_START("cnid_lookup");
+    id = cnid_lookup(vol->v_cdb, st, did, upath, len = strlen(upath));
+    AFP_CNID_DONE();
+    if (id) {
         memcpy(rbuf, &id, sizeof(id));
         *rbuflen = sizeof(id);
         return AFPERR_EXISTID;
@@ -1709,7 +1722,9 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data)
         return 0;
     
     /* update or add to cnid */
+    AFP_CNID_START("cnid_add");
     aint = cnid_add(vol->v_cdb, &path.st, did, de->d_name, strlen(de->d_name), 0); /* ignore errors */
+    AFP_CNID_DONE();
 
     return 0;
 }
@@ -1788,7 +1803,10 @@ int afp_resolveid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
         return AFPERR_NOID;
     }
 retry:
-    if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
+    AFP_CNID_START("cnid_resolve");
+    upath = cnid_resolve(vol->v_cdb, &id, buffer, len);
+    AFP_CNID_DONE();
+    if (upath == NULL) {
         return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */
     }
 
@@ -1891,7 +1909,10 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
     ibuf += sizeof(id);
     fileid = id;
 
-    if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
+    AFP_CNID_START("cnid_resolve");
+    upath = cnid_resolve(vol->v_cdb, &id, buffer, len);
+    AFP_CNID_DONE();
+        if (upath == NULL) {
         return AFPERR_NOID;
     }
 
@@ -1924,7 +1945,9 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
         return AFPERR_BADTYPE;
 
 delete:
+    AFP_CNID_START("cnid_delete");
     if (cnid_delete(vol->v_cdb, fileid)) {
+        AFP_CNID_DONE();
         switch (errno) {
         case EROFS:
             return AFPERR_VLOCK;
@@ -1935,7 +1958,7 @@ delete:
             return AFPERR_PARAM;
         }
     }
-
+    AFP_CNID_DONE();
     return err;
 }
 
@@ -2063,7 +2086,9 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
     
     /* look for the source cnid. if it doesn't exist, don't worry about
      * it. */
+    AFP_CNID_START("cnid_lookup");
     sid = cnid_lookup(vol->v_cdb, &srcst, sdir->d_did, supath,slen = strlen(supath));
+    AFP_CNID_DONE();
 
     if (NULL == ( dir = dirlookup( vol, did )) ) {
         err = afp_errno; /* was AFPERR_PARAM */
@@ -2106,7 +2131,9 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
 
     /* look for destination id. */
     upath = path->u_name;
+    AFP_CNID_START("cnid_lookup");
     did = cnid_lookup(vol->v_cdb, &destst, curdir->d_did, upath, dlen = strlen(upath));
+    AFP_CNID_DONE();
 
     /* construct a temp name.
      * NOTE: the temp file will be in the dest file's directory. it
@@ -2140,13 +2167,20 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
         goto err_dest_to_src;
     of_rename(vol, s_of, curdir, temp, curdir, path->m_name);
 
-    /* id's need switching. src -> dest and dest -> src. 
+    /* 
+     * id's need switching. src -> dest and dest -> src. 
      * we need to re-stat() if it was a cross device copy.
-    */
-    if (sid)
+     */
+    if (sid) {
+        AFP_CNID_START("cnid_delete");        
         cnid_delete(vol->v_cdb, sid);
-    if (did)
+        AFP_CNID_DONE();
+    }
+    if (did) {
+        AFP_CNID_START("cnid_delete");
         cnid_delete(vol->v_cdb, did);
+        AFP_CNID_DONE();
+    }
 
     if ((did && ( (crossdev && ostat(upath, &srcst, vol_syml_opt(vol)) < 0) || 
                 cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0))
index 5a23f28e4f2e2a631cca759654d138777303f83d..c349f5322e1c4db5e51c810387ea8cdc6ece77c0 100644 (file)
@@ -248,7 +248,9 @@ static int moveandrename(struct vol *vol,
     if (!isdir) {
         if ((oldunixname = strdup(mtoupath(vol, oldname, sdir->d_did, utf8_encoding(vol->v_obj)))) == NULL)
             return AFPERR_PARAM; /* can't convert */
+        AFP_CNID_START("cnid_get");
         id = cnid_get(vol->v_cdb, sdir->d_did, oldunixname, strlen(oldunixname));
+        AFP_CNID_DONE();
 
 #ifndef HAVE_ATFUNCS
         /* Need full path */
@@ -378,7 +380,9 @@ static int moveandrename(struct vol *vol,
         }
 
         /* fix up the catalog entry */
+        AFP_CNID_START("cnid_update");
         cnid_update(vol->v_cdb, id, st, curdir->d_did, upath, strlen(upath));
+        AFP_CNID_DONE();
     }
 
 exit:
@@ -521,10 +525,16 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
                 delcnid = deldir->d_did;
                 dir_remove(vol, deldir);
             }
-            if (delcnid == CNID_INVALID)
+            if (delcnid == CNID_INVALID) {
+                AFP_CNID_START("cnid_get");
                 delcnid = cnid_get(vol->v_cdb, curdir->d_did, upath, strlen(upath));
-            if (delcnid != CNID_INVALID)
+                AFP_CNID_DONE();
+            }
+            if (delcnid != CNID_INVALID) {
+                AFP_CNID_START("cnid_delete");
                 cnid_delete(vol->v_cdb, delcnid);
+                AFP_CNID_DONE();
+            }
             fce_register(FCE_DIR_DELETE, fullpathname(upath), NULL, fce_dir);
         } else {
             /* we have to cache this, the structs are lost in deletcurdir*/
index 7b24b7f26b99e26a5c648b9686021be229967eea..776d2f63198e7e9f364183aab56f880cb2b3578b 100644 (file)
@@ -791,6 +791,8 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         goto afp_read_err;
     }
 
+    AFP_READ_START((long)reqcount);
+
     /* reqcount isn't always truthful. we need to deal with that. */
     size = ad_size(ofork->of_ad, eid);
 
@@ -883,6 +885,8 @@ afp_read_exit:
 afp_read_done:
     if (obj->options.flags & OPTION_AFP_READ_LOCK)
         ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount, ofork->of_refnum);
+
+    AFP_READ_DONE();
     return err;
 
 afp_read_err:
@@ -1153,6 +1157,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
         goto afp_write_err;
     }
 
+    AFP_WRITE_START((long)reqcount);
+
     saveoff = offset;
     if (obj->options.flags & OPTION_AFP_READ_LOCK) {
         if (ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, saveoff, reqcount, ofork->of_refnum) < 0) {
@@ -1227,6 +1233,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
     ofork->of_vol->v_appended += (newsize > oldsize) ? (newsize - oldsize) : 0;
 
     *rbuflen = set_off_t (offset, rbuf, is64);
+    AFP_WRITE_DONE();
     return( AFP_OK );
 
 afp_write_err:
index 4ee8385436cbec5213219bccb5d72809e7b024c4..d935e1e696431facdc09f3910ad194e8805faca7 100644 (file)
@@ -1,4 +1,4 @@
 Makefile
 Makefile.in
 *.o
-lockrpc.gen.h
\ No newline at end of file
+afp_dtrace.h
index 93d28929a0f96d2e7cbc385c5255377a30846297..42085187de9665cefac9ca580b6c2ce541b59270 100644 (file)
@@ -1,6 +1,8 @@
 # Makefile.am for include/atalk/
 
 atalkincludedir = $(includedir)/atalk
+BUILT_SOURCES = 
+CLEANFILES =
 
 atalkinclude_HEADERS = \
        adouble.h \
@@ -40,4 +42,13 @@ noinst_HEADERS = \
        ftw.h \
        dsi.h \
        ldapconfig.h \
-       fce_api.h
\ No newline at end of file
+       fce_api.h
+
+EXTRA_DIST = afp_dtrace.d
+
+if WITH_DTRACE
+BUILT_SOURCES += afp_dtrace.h
+CLEANFILES += afp_dtrace.h
+afp_dtrace.h: $(top_srcdir)/include/atalk/afp_dtrace.d
+       $(LIBTOOL) --mode=execute dtrace -o afp_dtrace.h -h -s $(top_srcdir)/include/atalk/afp_dtrace.d
+endif
diff --git a/include/atalk/afp_dtrace.d b/include/atalk/afp_dtrace.d
new file mode 100644 (file)
index 0000000..e9ee989
--- /dev/null
@@ -0,0 +1,10 @@
+provider afp {
+   probe afpfunc__start(int func, char *funcname);
+   probe afpfunc__done(int func, char *funcname);
+   probe read__start(long size);
+   probe read__done();
+   probe write__start(long size);
+   probe write__done();
+   probe cnid__start(char *cnidfunc);
+   probe cnid__done();
+};
index 925f4560c5991dab6e5d0d8d77aa74c67dd799c1..e5fbb292f9ba1cf561141d3e18c8eabfe37d6629 100644 (file)
 #include <atalk/unicode.h>
 #include <atalk/uam.h>
 #include <atalk/iniparser.h>
+#ifdef WITH_DTRACE
+#include <atalk/afp_dtrace.h>
+#else
+/* List of empty dtrace macros */
+#define AFP_AFPFUNC_START(a,b)
+#define AFP_AFPFUNC_DONE(a, b)
+#define AFP_CNID_START(a)
+#define AFP_CNID_DONE()
+#define AFP_READ_START(a)
+#define AFP_READ_DONE()
+#define AFP_WRITE_START(a)
+#define AFP_WRITE_DONE()
+#endif
 
 /* #define DOSFILELEN 12 */             /* Type1, DOS-compat*/
 #define MACFILELEN 31                   /* Type2, HFS-compat */
index 6c502b0bcea37796af1c71fe03c5aaa05b0b1442..da58f87cf8178a63e31418d84b78b16cdb9cae45 100644 (file)
@@ -115,7 +115,7 @@ static int dsi_peek(DSI *dsi)
         if (FD_ISSET(dsi->socket, &readfds)) {
             len = dsi->end - dsi->eof; /* it's ensured above that there's space */
 
-            if ((len = read(dsi->socket, dsi->eof, len)) <= 0) {
+            if ((len = recv(dsi->socket, dsi->eof, len, 0)) <= 0) {
                 if (len == 0) {
                     LOG(log_error, logtype_dsi, "dsi_peek: EOF");
                     return -1;
@@ -213,7 +213,7 @@ static size_t dsi_buffered_stream_read(DSI *dsi, uint8_t *data, const size_t len
   buflen = MIN(8192, dsi->end - dsi->eof);
   if (buflen > 0) {
       ssize_t ret;
-      ret = read(dsi->socket, dsi->eof, buflen);
+      ret = recv(dsi->socket, dsi->eof, buflen, 0);
       if (ret > 0)
           dsi->eof += ret;
   }
index 55630d1b0d7ebe5a059dc6ae543a54901a14d09f..944234266eb4dc716144d5b1dc3f74021c341e49 100644 (file)
@@ -594,11 +594,8 @@ log:
                                  loglevel, logtype);
 
         /* If default wasnt setup its fd is -1 */
-        iov[0].iov_base = log_details_buffer;
-        iov[0].iov_len = strlen(log_details_buffer);
-        iov[1].iov_base = temp_buffer;
-        iov[1].iov_len = strlen(temp_buffer);
-        writev( fd,  iov, 2);
+        write(fd, log_details_buffer, strlen(log_details_buffer));
+        write(fd, temp_buffer, strlen(temp_buffer));
     } else {
         write(fd, temp_buffer, strlen(temp_buffer));
     }
index eda69c6c7e078c583e031add2aad2bd89d95d020..1df0b96bc2890bdf4e8bd9bb360211e1daecf93d 100644 (file)
@@ -104,7 +104,7 @@ ssize_t readt(int socket, void *data, const size_t length, int setnonblocking, i
     end.tv_sec += timeout;
 
     while (stored < length) {
-        len = read(socket, (char *) data + stored, length - stored);
+        len = recv(socket, (char *) data + stored, length - stored, 0);
         if (len == -1) {
             switch (errno) {
             case EINTR:
index b0f3d8e2396b5359171086a9fabe1814bb27b5fa..55c6d9e48da1554b0676c1aca5342751c3e36d33 100644 (file)
@@ -1,5 +1,38 @@
 dnl Kitchen sink for configuration macros
 
+dnl Check for dtrace
+AC_DEFUN([AC_NETATALK_DTRACE], [
+  AC_ARG_WITH(dtrace,
+    AS_HELP_STRING(
+      [--with-dtrace],
+      [Enable dtrace probes (default: enabled if dtrace found)]
+    ),
+    [WDTRACE=$withval],
+    [WDTRACE=auto]
+  )
+  if test "x$WDTRACE" = "xyes" -o "x$WDTRACE" = "xauto" ; then
+    AC_CHECK_PROG([atalk_cv_have_dtrace], [dtrace], [yes], [no])
+    if test "x$atalk_cv_have_dtrace" = "xno" ; then
+      if test "x$WDTRACE" = "xyes" ; then
+        AC_MSG_FAILURE([dtrace requested but not found])
+      fi
+      WDTRACE="no"
+    else
+      WDTRACE="yes"
+    fi
+  fi
+
+  if test x"$WDTRACE" = x"yes" ; then
+    AC_DEFINE([WITH_DTRACE], [1], [dtrace probes])
+    DTRACE_LIBS=""
+    if test x"$this_os" = x"freebsd" ; then
+      DTRACE_LIBS="-lelf"
+    fi
+    AC_SUBST(DTRACE_LIBS)
+  fi
+  AM_CONDITIONAL(WITH_DTRACE, test "x$WDTRACE" = "xyes")
+])
+
 dnl Check for dbus-glib, for AFP stats
 AC_DEFUN([AC_NETATALK_DBUS_GLIB], [
     PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.1, have_dbus=yes, have_dbus=no)
index 460efc6671f25b8af40f63c48258696854fbb778..2b682a466c2d6d522a560db683260f003425887c 100644 (file)
@@ -57,6 +57,7 @@ dnl   AC_MSG_RESULT([         Samba sharemode interop: $neta_cv_have_smbshmd])
        AC_MSG_RESULT([         LDAP support:            $netatalk_cv_ldap])
        AC_MSG_RESULT([         dbus support:            $have_dbus_glib])
        AC_MSG_RESULT([         dbus system directory:   $ac_cv_dbus_sysdir])
+       AC_MSG_RESULT([         dtrace probes:           $WDTRACE])
        if test x"$use_pam_so" = x"yes" -a x"$netatalk_cv_install_pam" = x"no"; then
                AC_MSG_RESULT([])
                AC_MSG_WARN([ PAM support was configured for your system, but the netatalk PAM configuration file])
index 01278ecd55a22555e620a8e6640729a42132abf5..34e28f484a371874a1c5a2f57e0ed554980d78b9 100644 (file)
@@ -64,3 +64,12 @@ test_LDADD = \
        @LIBGCRYPT_LIBS@ @QUOTA_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @ZEROCONF_LIBS@ @PTHREAD_LIBS@ @GSSAPI_LIBS@ @KRB5_LIBS@
 
 test_LDFLAGS = -export-dynamic
+
+if WITH_DTRACE
+DTRACE_OBJ = test-afp_dsi.o test-fork.o test-appl.o test-catsearch.o test-directory.o test-enumerate.o test-file.o test-filedir.o
+afp_dtrace.o: $(top_srcdir)/include/atalk/afp_dtrace.d $(DTRACE_OBJ)
+       if test -f afp_dtrace.o ; then rm -f afp_dtrace.o ; fi
+       $(LIBTOOL) --mode=execute dtrace -G -s $(top_srcdir)/include/atalk/afp_dtrace.d -o afp_dtrace.o $(DTRACE_OBJ)
+test_LDADD += afp_dtrace.o @DTRACE_LIBS@
+CLEANFILES += afp_dtrace.o
+endif