# 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
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
================
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)
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@
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 \
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));
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));
}
/* 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;
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;
}
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)
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. */
/* 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;
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",
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));
}
}
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) {
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();
+ }
}
}
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;
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;
}
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 */
}
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;
}
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;
return AFPERR_PARAM;
}
}
-
+ AFP_CNID_DONE();
return err;
}
/* 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 */
/* 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
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))
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 */
}
/* 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:
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*/
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);
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:
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) {
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:
Makefile
Makefile.in
*.o
-lockrpc.gen.h
\ No newline at end of file
+afp_dtrace.h
# Makefile.am for include/atalk/
atalkincludedir = $(includedir)/atalk
+BUILT_SOURCES =
+CLEANFILES =
atalkinclude_HEADERS = \
adouble.h \
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
--- /dev/null
+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();
+};
#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 */
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;
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;
}
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));
}
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:
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)
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])
@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