#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
+#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <sys/un.h>
-#define _XPG4_2 1
+// #define _XPG4_2 1
#include <sys/socket.h>
#include <stdio.h>
#include <time.h>
#include <atalk/cnid_dbd_private.h>
#include <atalk/paths.h>
#include <atalk/volinfo.h>
+#include <atalk/compat.h>
#include "usockfd.h"
static int srvfd;
static int rqstfd;
static volatile sig_atomic_t sigchild = 0;
+static uint maxvol;
#define MAXSPAWN 3 /* Max times respawned in.. */
#define TESTTIME 42 /* this much seconds apfd client tries to *
* to reconnect every 5 secondes, catch it */
-#define MAXVOLS 512
+#define MAXVOLS 4096
#define DEFAULTHOST "localhost"
#define DEFAULTPORT "4700"
static struct server *test_usockfn(struct volinfo *volinfo)
{
int i;
- for (i = 0; i < MAXVOLS; i++) {
+ for (i = 0; i < maxvol; i++) {
if ((srv[i].volinfo) && (strcmp(srv[i].volinfo->v_path, volinfo->v_path) == 0)) {
return &srv[i];
}
time(&t);
if (!up) {
- /* find an empty slot */
- for (i = 0; i < MAXVOLS; i++) {
- if (srv[i].volinfo == NULL) {
+ /* find an empty slot (i < maxvol) or the first free slot (i == maxvol)*/
+ for (i = 0; i <= maxvol; i++) {
+ if (srv[i].volinfo == NULL && i < MAXVOLS) {
up = &srv[i];
up->volinfo = volinfo;
retainvolinfo(volinfo);
up->tm = t;
up->count = 0;
+ if (i == maxvol)
+ maxvol++;
break;
}
}
sprintf(buf2, "%i", rqstfd);
if (up->count == MAXSPAWN) {
- /* there's a pb with the db inform child
- * it will run recover, delete the db whatever
- */
- LOG(log_error, logtype_cnid, "try with -d %s", up->volinfo->v_path);
+ /* there's a pb with the db inform child, it will delete the db */
+ LOG(log_warning, logtype_cnid,
+ "Multiple attempts to start CNID db daemon for \"%s\" failed, wiping the slate clean...",
+ up->volinfo->v_path);
ret = execlp(dbdpn, dbdpn, "-d", volpath, buf1, buf2, logconfig, NULL);
- }
- else {
+ } else {
ret = execlp(dbdpn, dbdpn, volpath, buf1, buf2, logconfig, NULL);
}
/* Yikes! We're still here, so exec failed... */
sigprocmask(SIG_BLOCK, &set, NULL);
}
+static int setlimits(void)
+{
+ struct rlimit rlim;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+ LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
+ exit(1);
+ }
+ if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < 65535) {
+ rlim.rlim_cur = 65535;
+ if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < 65535)
+ rlim.rlim_max = 65535;
+ if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+ LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
+ exit(1);
+ }
+ }
+ return 0;
+}
+
/* ------------------ */
int main(int argc, char *argv[])
{
set_processname("cnid_metad");
- while (( cc = getopt( argc, argv, "ds:p:h:u:g:l:f:")) != -1 ) {
+ while (( cc = getopt( argc, argv, "vVds:p:h:u:g:l:f:")) != -1 ) {
switch (cc) {
+ case 'v':
+ case 'V':
+ printf("cnid_metad (Netatalk %s)\n", VERSION);
+ return -1;
case 'd':
debug = 1;
break;
}
}
+ /* Check for PID lockfile */
+ if (check_lockfile("cnid_metad", _PATH_CNID_METAD_LOCK))
+ return -1;
+
+ if (!debug && daemonize(0, 0) != 0)
+ exit(EXITERR_SYS);
+
+ /* Create PID lockfile */
+ if (create_lockfile("cnid_metad", _PATH_CNID_METAD_LOCK))
+ return -1;
+
if (loglevel) {
strlcpy(logconfig + 8, loglevel, 13);
free(loglevel);
daemon_exit(1);
}
- /* Check PID lockfile and become a daemon */
- switch(server_lock("cnid_metad", _PATH_CNID_METAD_LOCK, debug)) {
- case -1: /* error */
- daemon_exit(EXITERR_SYS);
- case 0: /* child */
- break;
- default: /* server */
- exit(0);
- }
+ (void)setlimits();
if ((srvfd = tsockfd_create(host, port, 10)) < 0)
daemon_exit(1);
rqstfd = usockfd_check(srvfd, &set);
/* Collect zombie processes and log what happened to them */
if (sigchild) while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
- for (i = 0; i < MAXVOLS; i++) {
+ for (i = 0; i < maxvol; i++) {
if (srv[i].pid == pid) {
srv[i].pid = 0;
close(srv[i].control_fd);