summaryrefslogtreecommitdiff
path: root/src/common/admin_socket.h
blob: e0e06f0b6a659346e0b5732fdb722e18b54fbcc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 New Dream Network
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software 
 * Foundation.  See file COPYING.
 * 
 */

#ifndef CEPH_COMMON_ADMIN_SOCKET_H
#define CEPH_COMMON_ADMIN_SOCKET_H

#include <string>
#include <map>

#include "include/buffer.h"
#include "common/Thread.h"
#include "common/Mutex.h"

class AdminSocket;
class CephContext;

#define CEPH_ADMIN_SOCK_VERSION "2"

class AdminSocketHook {
public:
  virtual bool call(std::string command, std::string args, bufferlist& out) = 0;
  virtual ~AdminSocketHook() {};
};

class AdminSocket : public Thread
{
public:
  AdminSocket(CephContext *cct);
  virtual ~AdminSocket();

  /**
   * register an admin socket command
   *
   * The command is registered under a command string.  Incoming
   * commands are split by space and matched against the longest
   * registered command.  For example, if 'foo' and 'foo bar' are
   * registered, and an incoming command is 'foo bar baz', it is
   * matched with 'foo bar', while 'foo fud' will match 'foo'.
   *
   * The entire incoming command string is passed to the registred
   * hook.
   *
   * @param command command string
   * @param hook implementaiton
   * @param help help text.  if empty, command will not be included in 'help' output.
   *
   * @return 0 for success, -EEXIST if command already registered.
   */
  int register_command(std::string command, AdminSocketHook *hook, std::string help);

  /**
   * unregister an admin socket command
   *
   * @param command command string
   * @return 0 on succest, -ENOENT if command dne.
   */
  int unregister_command(std::string command);

  bool init(const std::string &path);
  
private:
  AdminSocket(const AdminSocket& rhs);
  AdminSocket& operator=(const AdminSocket &rhs);

  void shutdown();

  std::string create_shutdown_pipe(int *pipe_rd, int *pipe_wr);
  std::string bind_and_listen(const std::string &sock_path, int *fd);

  void *entry();
  bool do_accept();

  CephContext *m_cct;
  std::string m_path;
  int m_sock_fd;
  int m_shutdown_rd_fd;
  int m_shutdown_wr_fd;

  Mutex m_lock;    // protects m_hooks, m_help
  AdminSocketHook *m_version_hook, *m_help_hook;

  std::map<std::string,AdminSocketHook*> m_hooks;
  std::map<std::string,std::string> m_help;

  friend class AdminSocketTest;
  friend class HelpHook;
};

#endif