예제 #1
0
파일: service.c 프로젝트: tg-x/gnunet
/**
 * Run a service startup sequence within an existing
 * initialized system.
 *
 * @param service_name our service name
 * @param cfg configuration to use
 * @param options service options
 * @return NULL on error, service handle
 */
struct GNUNET_SERVICE_Context *
GNUNET_SERVICE_start (const char *service_name,
                      const struct GNUNET_CONFIGURATION_Handle *cfg,
		      enum GNUNET_SERVICE_Options options)
{
  int i;
  struct GNUNET_SERVICE_Context *sctx;

  sctx = GNUNET_new (struct GNUNET_SERVICE_Context);
  sctx->ready_confirm_fd = -1;  /* no daemonizing */
  sctx->ret = GNUNET_OK;
  sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
  sctx->service_name = service_name;
  sctx->cfg = cfg;
  sctx->options = options;

  /* setup subsystems */
  if (GNUNET_OK != setup_service (sctx))
  {
    GNUNET_SERVICE_stop (sctx);
    return NULL;
  }
  if (NULL != sctx->lsocks)
    sctx->server =
        GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
                                           sctx->timeout, sctx->require_found);
  else
    sctx->server =
        GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
                              sctx->timeout, sctx->require_found);

  if (NULL == sctx->server)
  {
    GNUNET_SERVICE_stop (sctx);
    return NULL;
  }
#ifndef WINDOWS
  if (NULL != sctx->addrs)
    for (i = 0; NULL != sctx->addrs[i]; i++)
      if ((AF_UNIX == sctx->addrs[i]->sa_family)
          && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
        GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
                                     sctx->match_uid,
                                     sctx->match_gid);
#endif
  sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
  memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
  i = 0;
  while ((sctx->my_handlers[i].callback != NULL))
    sctx->my_handlers[i++].callback_cls = sctx;
  GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
  return sctx;
}
예제 #2
0
int main(void) {
    /* typical in 10000 service scenario: 150..1000 concurrently scheduled async jobs. */
    const int num_checks_at_once = MAX_CONCURRENT_CHECKS;
    void* neb_handle;
    int i;
    char ok = 1;
    char * test_nebargs[] = { "config=extras/shared.conf", };

    struct nebstruct_process_struct data_process_events;
    data_process_events.type = NEBTYPE_PROCESS_EVENTLOOPSTART;

    init_externals();

    init_host();
    init_svc();
    init_svc_check();

    neb_handle = load_neb("./mod_gearman2.o", test_nebargs[0]);
    neb_make_callbacks(NEBCALLBACK_PROCESS_DATA, &data_process_events);

    while (ok) {
        printf("Sending %i service checks.\n", num_checks_at_once);
        for (i = 0; i < num_checks_at_once; i++) {
            nebstruct_service_check_data* data_service_check;
            char host_name[16];
            char service_name[16];
            sprintf(host_name, "%i", i / 10);
            sprintf(service_name, "%i", i);
            data_service_check = setup_service(host_name, service_name);
            neb_make_callbacks(NEBCALLBACK_SERVICE_CHECK_DATA,
                    data_service_check);
        }

        ok = (reap_cr_from_neb(num_checks_at_once) >= num_checks_at_once);
    }

    unload_neb(neb_handle);

    return 0;
}
예제 #3
0
파일: capfsd.c 프로젝트: mnv104/capfs
int main(int argc, char **argv)
{
	int err;
	struct capfs_upcall up;
	struct capfs_downcall down;
	struct capfs_dirent *dent = NULL;
	char *link_name = NULL;
	int opt = 0;
	int capfsd_log_level = CRITICAL_MSG | WARNING_MSG;
	char options[256];
	struct cas_options cas_options = {
doInstrumentation:0,
use_sockets:0,
	};

#ifdef DEBUG
	capfsd_log_level |= INFO_MSG;
	capfsd_log_level |= DEBUG_MSG;
#endif
	set_log_level(capfsd_log_level);
	/* capfsd must register a callback with the meta-data server at the time of mount */
	check_for_registration = 1;
	while((opt = getopt(argc, argv, "dhsn:p:")) != EOF) {
		switch(opt){
			case 's':
				cas_options.use_sockets = 1;
				break;
			case  'd':
				is_daemon = 0;
				break;
			case 'p':
				err = sscanf(optarg, "%x", &capfs_debug);
				if(err != 1){
					usage();
					exiterror("bad arguments");
					exit(1);
				}
				break;
			case 'n':
				num_threads = atoi(optarg);
				break;
			case 'h':
				usage();
				exit(0);
			case '?':
			default:
				usage();
				exiterror("bad arguments");
				exit(1);
		}
	}
		
	if (getuid() != 0 && geteuid() != 0) {
		exiterror("must be run as root");
		exit(1);
	}

	if (setup_capfsdev() < 0) {
		exiterror("setup_capfsdev() failed");
		exit(1);
	}

	if ((dev_fd = open_capfsdev()) < 0) {
		exiterror("open_capfsdev() failed");
		exit(1);
	}
	
	startup(argc, argv);
	/* Initialize the plugin interface */
	capfsd_plugin_init();

	capfs_comm_init();


	/* allocate a 64K, page-aligned buffer for small operations */
	capfs_opt_io_size = ROUND_UP(CAPFS_OPT_IO_SIZE);
	if ((orig_iobuf = (char *) valloc(capfs_opt_io_size)) == NULL) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(orig_iobuf, 0, capfs_opt_io_size);
	capfs_dent_size = ROUND_UP((FETCH_DENTRY_COUNT * sizeof(struct capfs_dirent)));
	/* allocate a suitably large dent buffer for getdents speed up */
	if ((dent = (struct capfs_dirent *) valloc(capfs_dent_size)) == NULL) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(dent, 0, capfs_dent_size);
	/* maximum size of a link target cannot be > 4096 */
	capfs_link_size = ROUND_UP(4096);
	link_name = (char *) valloc(capfs_link_size);
	if(!link_name) {
		exiterror("calloc failed");
		capfsd_plugin_cleanup();
		exit(1);
	}
	memset(link_name, 0, capfs_link_size);
	
	fprintf(stderr, "------------ Starting client daemon servicing VFS requests using a thread pool [%d threads] ----------\n",
			num_threads);
	/*
	 * Start up the local RPC service on both TCP/UDP 
	 * for callbacks.
	 */
	pmap_unset(CAPFS_CAPFSD, clientv1);
	if (setup_service(CAPFS_CAPFSD /* program number */,
				clientv1 /* version */,
				-1 /* both tcp/udp */,
				-1 /* any available port */,
				CAPFS_DISPATCH_FN(clientv1) /* dispatch routine */,
				&info) < 0) {
		exiterror("Could not setup local RPC service!\n");
		capfsd_plugin_cleanup();
		exit(1);
	}
	/*
	 * Initialize the hash cache.
	 * Note that we are using default values of cache sizes,
	 * and this should probably be an exposed knob to the user.
	 * CMGR_BSIZE is == CAPFS_MAXHASHLENGTH for SHA1-hash. So we dont need to set
	 * that. We use environment variables to communicate the parameters
	 * to the caches.
	 */
	snprintf(options, 256, "%d", CAPFS_CHUNK_SIZE);
	setenv("CMGR_CHUNK_SIZE", options, 1);
	snprintf(options, 256, "%d", CAPFS_HCACHE_COUNT);
	setenv("CMGR_BCOUNT", options, 1);
	init_hashes();
#if 0
	/*
	 * Initialize the client-side data cache.
	 * Note that we are not using this layer
	 * right now. It is getting fairly complicated already.
	 */
	snprintf(options, 256, "%d", CAPFS_DCACHE_BSIZE);
	setenv("CMGR_BSIZE", options, 1);
	snprintf(options, 256, "%d", CAPFS_DCACHE_COUNT);
	setenv("CMGR_BCOUNT", options, 1);
#endif
	/*
	 * Initialize the client-side data server communication
	 * stuff.
	 */
	clnt_init(&cas_options, num_threads, CAPFS_CHUNK_SIZE);
	
	/* loop forever, doing:
	 * - read from device
	 * - service request
	 * - write back response
	 */
	for (;;) {
		struct timeval begin, end;

		err = read_capfsdev(dev_fd, &up, 30);
		if (err < 0) {
			/* cleanup the hash cache */
			cleanup_hashes();
			/* Cleanup the RPC service */
			cleanup_service(&info);
			capfs_comm_shutdown();
			close_capfsdev(dev_fd);
			/* cleanup the plugins */
			capfsd_plugin_cleanup();
			/* cleanup the client-side stuff */
			clnt_finalize();
			exiterror("read failed\n");
			exit(1);
		}
		if (err == 0) {
			/* timed out */
			capfs_comm_idle();
			continue;
		}
		gettimeofday(&begin, NULL);
		/* the do_capfs_op() call does this already; can probably remove */
		init_downcall(&down, &up);

		err = 0;
		switch (up.type) {
			/* all the easy operations */
		case GETMETA_OP:
		case SETMETA_OP:
		case LOOKUP_OP:
		case CREATE_OP:
		case REMOVE_OP:
		case RENAME_OP:
		case SYMLINK_OP:
		case MKDIR_OP:
		case RMDIR_OP:
		case STATFS_OP:
		case HINT_OP:
		case FSYNC_OP:
		case LINK_OP:
		{
			PDEBUG(D_UPCALL, "read upcall; type = %d, name = %s\n", up.type,
					 up.v1.fhname);
			err = do_capfs_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for type %d\n", up.type);
			}
			break;
			/* the more interesting ones */
		}
		case GETDENTS_OP:
			/* need to pass location and size of buffer to do_capfs_op() */
			up.xfer.ptr = dent;
			up.xfer.size = capfs_dent_size;
			err = do_capfs_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for getdents\n");
			}
			break;
		case READLINK_OP:
			/* need to pass location and size of buffer to hold the target name */
			up.xfer.ptr = link_name;
			up.xfer.size = capfs_link_size;
			err = do_capfs_op(&up, &down);
			if(err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed for readlink\n");
			}
			break;
		case READ_OP:
			err = read_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "read_op failed\n");
			}
			break;
		case WRITE_OP:
			err = write_op(&up, &down);
			if (err < 0) {
				PDEBUG(D_LIB, "do_capfs_op failed\n");
			}
			break;
			/* things that aren't done yet */
		default:
			err = -ENOSYS;
			break;
		}
		gettimeofday(&end, NULL);
		/* calculate the total time spent servicing this call */
		if (end.tv_usec < begin.tv_usec) {
			end.tv_usec += 1000000;
			end.tv_sec--;
		}
		end.tv_sec -= begin.tv_sec;
		end.tv_usec -= begin.tv_usec;
		down.total_time = (end.tv_sec * 1000000 + end.tv_usec);
		down.error = err;

		switch(up.type)
		{
		case HINT_OP:
			/* this is a one shot hint, we don't want a response in case of HINT_OPEN/HINT_CLOSE */
			if (up.u.hint.hint == HINT_CLOSE || up.u.hint.hint == HINT_OPEN) {
				err = 0;
				break;
			}
			/* fall through */
		default:
			/* the default behavior is to write a response to the device */
			err = write_capfsdev(dev_fd, &down, -1);
			if (err < 0) {
				/* cleanup the hash cache */
				cleanup_hashes();
				/* Cleanup the RPC service */
				cleanup_service(&info);
				capfs_comm_shutdown();
				close_capfsdev(dev_fd);
				/* Cleanup the plugins */
				capfsd_plugin_cleanup();
				/* cleanup the client-side stuff */
				clnt_finalize();
				exiterror("write failed");
				exit(1);
			}
			break;
		}

		/* If we used a big I/O buffer, free it after we have successfully
		 * returned the downcall.
		 */
		if (big_iobuf != NULL) {
			free(big_iobuf);
			big_iobuf = NULL;
		}
	}
	/* Not reached */
	/* cleanup the hash cache */
	cleanup_hashes();
	/* Cleanup the RPC service */
	cleanup_service(&info);
	capfs_comm_shutdown();
	close_capfsdev(dev_fd);
	/* cleanup the plugins */
	capfsd_plugin_cleanup();
	/* cleanup the client-side stuff */
	clnt_finalize();
	exit(1);
}
예제 #4
0
파일: service.c 프로젝트: tg-x/gnunet
/**
 * Run a standard GNUnet service startup sequence (initialize loggers
 * and configuration, parse options).
 *
 * @param argc number of command line arguments
 * @param argv command line arguments
 * @param service_name our service name
 * @param options service options
 * @param task main task of the service
 * @param task_cls closure for @a task
 * @return #GNUNET_SYSERR on error, #GNUNET_OK
 *         if we shutdown nicely
 */
int
GNUNET_SERVICE_run (int argc, char *const *argv,
                    const char *service_name,
                    enum GNUNET_SERVICE_Options options,
                    GNUNET_SERVICE_Main task,
                    void *task_cls)
{
#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)

  int err;
  int ret;
  char *cfg_fn;
  char *opt_cfg_fn;
  char *loglev;
  char *logfile;
  int do_daemonize;
  unsigned int i;
  unsigned long long skew_offset;
  unsigned long long skew_variance;
  long long clock_offset;
  struct GNUNET_SERVICE_Context sctx;
  struct GNUNET_CONFIGURATION_Handle *cfg;
  const char *xdg;

  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
    GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn),
    {'d', "daemonize", NULL,
     gettext_noop ("do daemonize (detach from terminal)"), 0,
     GNUNET_GETOPT_set_one, &do_daemonize},
    GNUNET_GETOPT_OPTION_HELP (NULL),
    GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
    GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
    GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
    GNUNET_GETOPT_OPTION_END
  };
  err = 1;
  do_daemonize = 0;
  logfile = NULL;
  loglev = NULL;
  opt_cfg_fn = NULL;
  xdg = getenv ("XDG_CONFIG_HOME");
  if (NULL != xdg)
    GNUNET_asprintf (&cfg_fn,
                     "%s%s%s",
                     xdg,
                     DIR_SEPARATOR_STR,
                     "gnunet.conf");
  else
    cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_USER_CONFIG_FILE);
  memset (&sctx, 0, sizeof (sctx));
  sctx.options = options;
  sctx.ready_confirm_fd = -1;
  sctx.ret = GNUNET_OK;
  sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
  sctx.task = task;
  sctx.task_cls = task_cls;
  sctx.service_name = service_name;
  sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();

  /* setup subsystems */
  ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
  if (GNUNET_SYSERR == ret)
    goto shutdown;
  if (GNUNET_NO == ret)
  {
    err = 0;
    goto shutdown;
  }
  if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
    HANDLE_ERROR;
  if (NULL == opt_cfg_fn)
    opt_cfg_fn = GNUNET_strdup (cfg_fn);
  if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
  {
    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Malformed configuration file `%s', exit ...\n"),
                  opt_cfg_fn);
      goto shutdown;
    }
  }
  else
  {
    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Malformed configuration, exit ...\n"));
      goto shutdown;
    }
    if (0 != strcmp (opt_cfg_fn, cfg_fn))
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		  _("Could not access configuration file `%s'\n"),
		  opt_cfg_fn);
  }
  if (GNUNET_OK != setup_service (&sctx))
    goto shutdown;
  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
    HANDLE_ERROR;
  if (GNUNET_OK != set_user_id (&sctx))
    goto shutdown;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Service `%s' runs with configuration from `%s'\n",
       service_name,
       opt_cfg_fn);
  if ((GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
                                              "SKEW_OFFSET", &skew_offset)) &&
      (GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
                                              "SKEW_VARIANCE", &skew_variance)))
  {
    clock_offset = skew_offset - skew_variance;
    GNUNET_TIME_set_offset (clock_offset);
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
  }
  /* actually run service */
  err = 0;
  GNUNET_SCHEDULER_run (&service_task, &sctx);
  /* shutdown */
  if ((1 == do_daemonize) && (NULL != sctx.server))
    pid_file_delete (&sctx);
  GNUNET_free_non_null (sctx.my_handlers);

shutdown:
  if (-1 != sctx.ready_confirm_fd)
  {
    if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
    GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
  }
#if HAVE_MALLINFO
  {
    char *counter;

    if ( (GNUNET_YES ==
	  GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name,
					   "GAUGER_HEAP")) &&
	 (GNUNET_OK ==
	  GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name,
						 "GAUGER_HEAP",
						 &counter)) )
    {
      struct mallinfo mi;

      mi = mallinfo ();
      GAUGER (service_name, counter, mi.usmblks, "blocks");
      GNUNET_free (counter);
    }
  }
#endif
  GNUNET_SPEEDUP_stop_ ();
  GNUNET_CONFIGURATION_destroy (cfg);
  i = 0;
  if (NULL != sctx.addrs)
    while (NULL != sctx.addrs[i])
      GNUNET_free (sctx.addrs[i++]);
  GNUNET_free_non_null (sctx.addrs);
  GNUNET_free_non_null (sctx.addrlens);
  GNUNET_free_non_null (logfile);
  GNUNET_free_non_null (loglev);
  GNUNET_free (cfg_fn);
  GNUNET_free_non_null (opt_cfg_fn);
  GNUNET_free_non_null (sctx.v4_denied);
  GNUNET_free_non_null (sctx.v6_denied);
  GNUNET_free_non_null (sctx.v4_allowed);
  GNUNET_free_non_null (sctx.v6_allowed);

  return err ? GNUNET_SYSERR : sctx.ret;
}