Added a new dbd backend function dbd_getstamp to handle cnid_getstamp requests.
cnid_dbd_SOURCES = dbif.c pack.c comm.c usockfd.c db_param.c main.c \
dbd_add.c dbd_get.c dbd_resolve.c dbd_lookup.c \
- dbd_update.c dbd_delete.c
+ dbd_update.c dbd_delete.c dbd_getstamp.c
cnid_dbd_LDADD = $(top_builddir)/libatalk/libatalk.la
the option -cnidscheme:dbd in your AppleVolumes.default file or
equivalent. The default for this parameter is -cnidscheme:cdb.
-There are two executeables that will be built in etc/cnid_dbd and
+There are two executeables that will be built in etc/cnid_dbd and
installed into the systems binaries directories of netatalk
-(e.g. /usr/local/netatalk/sbin or whatever you specify with
---sbindir to configure): cnid_metad and cnid_dbd. cnid_metad should
-run all the time with root permissions. It will be notified when an
-instance of afpd starts up and will in turn make sure that a cnid_dbd
-daemon is started for the volume that afpd wishes to access. The
-daemon runs forever and services any other instances of afpd that
-access the volume. You can safely kill it with SIGTERM, it will be
-restarted automatically by cnid_metad as soon as the volume is
-accessed again.
+(e.g. /usr/local/netatalk/sbin or whatever you specify with --sbindir
+to configure): cnid_metad and cnid_dbd. cnid_metad should run all the
+time with root permissions. It will be notified when an instance of
+afpd starts up and will in turn make sure that a cnid_dbd daemon is
+started for the volume that afpd wishes to access. The daemon runs as
+long as necessary (see the idle_timeout option below) and services any
+other instances of afpd that access the volume. You can safely kill it
+with SIGTERM, it will be restarted automatically by cnid_metad as soon
+as the volume is accessed again.
cnid_metad needs one command line argument, the name of the cnid_dbd
executeable. You can either specify "cnid_dbd" if it is in the path
flush_interval 30
usock_file <databasedirectory>/usock
fd_table_size 16
+idle_timeout 600
"backlog" specifies the maximum number of connection requests that can
/*
- * $Id: dbd.h,v 1.1.4.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: dbd.h,v 1.1.4.2 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
extern int dbd_lookup __P((struct cnid_dbd_rqst *, struct cnid_dbd_rply *));
extern int dbd_update __P((struct cnid_dbd_rqst *, struct cnid_dbd_rply *));
extern int dbd_delete __P((struct cnid_dbd_rqst *, struct cnid_dbd_rply *));
+extern int dbd_getstamp __P((struct cnid_dbd_rqst *, struct cnid_dbd_rply *));
#endif /* CNID_DBD_DBD_H */
/*
- * $Id: dbd_add.c,v 1.1.4.2 2003-10-21 16:24:58 didg Exp $
+ * $Id: dbd_add.c,v 1.1.4.3 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
#include "pack.h"
#include "dbd.h"
-/* FIXME assume dev_t == ino_t == 8 */
/* cnid - dev - inode - type - did - name */
#define ROOTINFO_DATA "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0RootInfo"
#define ROOTINFO_DATALEN (3*4 +2*8 +9)
rply->result = CNID_DBD_RES_ERR_DUPLCNID;
break;
case -1:
+ /* FIXME: Should that not be logged for case 1:? */
LOG(log_error, logtype_cnid, "add_cnid: duplicate %x %s", rply->cnid
, data.data + CNID_NAME_OFS);
--- /dev/null
+/*
+ * $Id: dbd_getstamp.c,v 1.1.2.1 2003-11-25 00:41:31 lenneis Exp $
+ *
+ * Copyright (C) Joerg Lenneis 2003
+ * All Rights Reserved. See COPYRIGHT.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <atalk/logger.h>
+#include <errno.h>
+#include <netatalk/endian.h>
+#include <atalk/cnid_dbd_private.h>
+
+#include "dbif.h"
+#include "dbd.h"
+#include "pack.h"
+
+/* Return the unique stamp associated with this database */
+
+int dbd_getstamp(struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
+{
+ DBT key, data;
+ int rc;
+
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ rply->namelen = 0;
+
+ key.data = ROOTINFO_KEY;
+ key.size = ROOTINFO_KEYLEN;
+
+ if ((rc = dbif_get(DBIF_IDX_CNID, &key, &data, 0)) < 0) {
+ LOG(log_error, logtype_cnid, "dbd_getstamp: Error getting rootinfo record");
+ rply->result = CNID_DBD_RES_ERR_DB;
+ return -1;
+ }
+
+ if (rc == 0) {
+ LOG(log_error, logtype_cnid, "dbd_getstamp: No rootinfo record found");
+ rply->result = CNID_DBD_RES_NOTFOUND;
+ return 1;
+ }
+
+ rply->namelen = CNID_DEV_LEN;
+ rply->name = data.data + CNID_DEV_OFS;
+
+#ifdef DEBUG
+ LOG(log_info, logtype_cnid, "cnid_getstamp: Returning stamp");
+#endif
+ rply->result = CNID_DBD_RES_OK;
+ return 1;
+}
/*
- * $Id: dbd_lookup.c,v 1.1.4.3 2003-10-30 10:03:19 bfernhomberg Exp $
+ * $Id: dbd_lookup.c,v 1.1.4.4 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
{
char *buf;
DBT key, devdata, diddata;
- dev_t dev;
- ino_t ino;
+ char dev[CNID_DEV_LEN];
+ char ino[CNID_INO_LEN];
int devino = 1, didname = 1;
int rc;
cnid_t id_devino, id_didname;
rply->cnid = 0;
buf = pack_cnid_data(rqst);
- memcpy(&dev, buf + CNID_DEV_OFS, sizeof(dev));
- memcpy(&ino, buf + CNID_INO_OFS, sizeof(ino));
+ memcpy(dev, buf + CNID_DEV_OFS, CNID_DEV_LEN);
+ /* FIXME: ino is not needed later on, remove? */
+ memcpy(ino, buf + CNID_INO_OFS, CNID_INO_LEN);
/* Look for a CNID. We have two options: dev/ino or did/name. If we
only get a match in one of them, that means a file has moved. */
type_devino = ntohl(type_devino);
}
+ /* FIXME: This second call to pack_cnid_data() is redundant, any reason it is here? */
buf = pack_cnid_data(rqst);
key.data = buf +CNID_DID_OFS;
key.size = CNID_DID_LEN + rqst->namelen + 1;
* if it's the same dev or not the same type
* just delete it
*/
- if (!memcmp(&dev, (char *)diddata.data + CNID_DEV_OFS, sizeof(dev)) ||
+ if (!memcmp(dev, (char *)diddata.data + CNID_DEV_OFS, CNID_DEV_LEN) ||
type_didname != rqst->type) {
if (dbd_delete(rqst, rply) < 0) {
return -1;
/*
- * $Id: dbd_resolve.c,v 1.1.4.3 2003-10-30 10:03:19 bfernhomberg Exp $
+ * $Id: dbd_resolve.c,v 1.1.4.4 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
rply->result = CNID_DBD_RES_NOTFOUND;
return 1;
}
- /* FIXME hack */
- if (!rqst->cnid) {
- memcpy(&rply->did, (char *) data.data + CNID_DEV_OFS, sizeof(cnid_t));
- }
- else {
- memcpy(&rply->did, (char *) data.data + CNID_DID_OFS, sizeof(cnid_t));
- }
+
+ memcpy(&rply->did, (char *) data.data + CNID_DID_OFS, sizeof(cnid_t));
+
rply->namelen = data.size - CNID_NAME_OFS;
rply->name = data.data + CNID_NAME_OFS;
/*
- * $Id: dbd_update.c,v 1.1.4.4 2003-10-30 10:03:19 bfernhomberg Exp $
+ * $Id: dbd_update.c,v 1.1.4.5 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
if ((rc = dbif_pget(DBIF_IDX_DEVINO, &key, &pkey, &data, 0)) < 0 ) {
goto err_db;
}
- else if (rc > 0) {
+ else if (rc > 0) {
+ /* FIXME: pkey.data points to the CNID? */
if ((rc = dbif_del(DBIF_IDX_DEVINO, &pkey, 0)) < 0 ) {
goto err_db;
}
goto err_db;
}
else if (rc > 0) {
+ /* FIXME: pkey.data points to the CNID? */
if ((rc = dbif_del(DBIF_IDX_DIDNAME, &pkey, 0)) < 0) {
goto err_db;
}
/*
- * $Id: main.c,v 1.1.4.3 2003-11-03 20:56:59 lenneis Exp $
+ * $Id: main.c,v 1.1.4.4 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
case CNID_DBD_OP_DELETE:
ret = dbd_delete(&rqst, &rply);
break;
+ case CNID_DBD_OP_GETSTAMP:
+ ret = dbd_getstamp(&rqst, &rply);
+ break;
default:
LOG(log_error, logtype_cnid, "loop: unknow op %d", rqst.op);
break;
/*
- * $Id: pack.c,v 1.1.4.3 2003-10-30 10:03:19 bfernhomberg Exp $
+ * $Id: pack.c,v 1.1.4.4 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
#include <netatalk/endian.h>
#include "pack.h"
+/* --------------- */
+static void pack_devino(unsigned char *buf, dev_t dev, ino_t ino)
+{
+ buf[CNID_DEV_LEN - 1] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 2] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 3] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 4] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 5] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 6] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 7] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 8] = dev;
+
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 1] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 2] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 3] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 4] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 5] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 6] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 7] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 8] = ino;
+}
+
/* --------------- */
int didname(dbp, pkey, pdata, skey)
DB *dbp;
char *buf = start +CNID_LEN;
u_int32_t i;
- memcpy(buf, &rqst->dev, sizeof(rqst->dev));
- buf += sizeof(rqst->dev);
-
- memcpy(buf, &rqst->ino, sizeof(rqst->ino));
- buf += sizeof(rqst->ino);
+ pack_devino(buf, rqst->dev, rqst->ino);
+ buf += CNID_DEVINO_LEN;
i = htonl(rqst->type);
memcpy(buf, &i, sizeof(i));
#define CNID_DBD_OP_DELETE 0x08
#define CNID_DBD_OP_MANGLE_ADD 0x09
#define CNID_DBD_OP_MANGLE_GET 0x0a
+#define CNID_DBD_OP_GETSTAMP 0x0b
#define CNID_DBD_RES_OK 0x00
#define CNID_DBD_RES_NOTFOUND 0x01
/*
- * $Id: cnid_dbd.c,v 1.1.4.7 2003-11-12 16:00:10 didg Exp $
+ * $Id: cnid_dbd.c,v 1.1.4.8 2003-11-25 00:41:31 lenneis Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
return name;
}
-/* ---------------------- */
-int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const int len)
-{
- CNID_private *db;
- struct cnid_dbd_rqst rqst;
- struct cnid_dbd_rply rply;
- cnid_t id = 0;
- char temp[12 + MAXPATHLEN + 1];
-
- if (!cdb || !(db = cdb->_private)) {
- LOG(log_error, logtype_cnid, "cnid_getstamp: Parameter error");
- errno = CNID_ERR_PARAM;
- return -1;
- }
-
- /* TODO: We should maybe also check len. At the moment we rely on the caller
- to provide a buffer that is large enough for MAXPATHLEN plus
- CNID_HEADER_LEN plus 1 byte, which is large enough for the maximum that
- can come from the database. */
-
- RQST_RESET(&rqst);
- rqst.op = CNID_DBD_OP_RESOLVE;
- rqst.cnid = id;
-
- memset(buffer, 0, len);
-
- /* This mimicks the behaviour of the "regular" cnid_resolve. So far,
- nobody uses the content of buffer. It only provides space for the
- name in the caller. */
- rply.name = temp + CNID_HEADER_LEN;
-
- if (transmit(db, &rqst, &rply) < 0) {
- errno = CNID_ERR_DB;
- return -1;
- }
-
- switch (rply.result) {
- case CNID_DBD_RES_OK:
- memcpy(buffer, &rply.did, sizeof(cnid_t));
- break;
- case CNID_DBD_RES_NOTFOUND:
- return -1;
- case CNID_DBD_RES_ERR_DB:
- errno = CNID_ERR_DB;
- return -1;
- default:
- abort();
- }
-
- return 0;
-}
-
/* ---------------------- */
cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
const char *name, const int len)
}
}
+/* ---------------------- */
+int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const int len)
+{
+ CNID_private *db;
+ struct cnid_dbd_rqst rqst;
+ struct cnid_dbd_rply rply;
+
+ /* FIXME: We rely on len == ADEDLEN_PRIVSYN == CNID_DEV_LEN here as well as
+ in the backend. There should really be a constant for that value that is
+ used throughout. Also, returning the stamp via the name field is somewhat
+ fishy. */
+
+ if (!cdb || !(db = cdb->_private)) {
+ LOG(log_error, logtype_cnid, "cnid_getstamp: Parameter error");
+ errno = CNID_ERR_PARAM;
+ return -1;
+ }
+
+
+ RQST_RESET(&rqst);
+ rqst.op = CNID_DBD_OP_GETSTAMP;
+
+ memset(buffer, 0, len);
+
+ rply.name = buffer;
+
+ if (transmit(db, &rqst, &rply) < 0) {
+ errno = CNID_ERR_DB;
+ return -1;
+ }
+
+ switch (rply.result) {
+ case CNID_DBD_RES_OK:
+ break;
+ case CNID_DBD_RES_NOTFOUND:
+ return -1;
+ case CNID_DBD_RES_ERR_DB:
+ errno = CNID_ERR_DB;
+ return -1;
+ default:
+ abort();
+ }
+
+ return 0;
+}
+
struct _cnid_module cnid_dbd_module = {
"dbd",
{NULL, NULL},
};
#endif /* CNID_DBD */
-