P4dctl

From PDWiki

Jump to: navigation, search

Contents

About p4dctl

I was always frustrated by how hard it was to get a good (init) script for starting and stopping Perforce Services: one that worked on most UNIX platforms, and allowed for the fact that while the servers wouldn't run as root, both root and non-root users could start and stop them. Then there's the issue of 'pidfiles': if your startup script creates a pidfile owned by root, the pidfile can become stale if another user (perhaps 'perforce') stops and restarts the server; often the permissions on these files mean that even if the other user wants to do the right thing, they can be thwarted.

Most Perforce sites will also run more than one type of Perforce server (P4D/P4Web/P4FTPD etc.), and the problem is compounded the more servers you run.

So I wrote p4dctl. It allows the administrator to specify all the Perforce services running on a machine in a single, simple text file and allows root and non-root users to start and stop the services. Naturally, non-root users can only affect servers they own. Since p4dctl is a setuid root executable, it uses its root privileges to manage the pid files (for security reasons, it drops these privileges for all other actions), so even if a non-root user is restarting a service, the pidfile will be correctly maintained. This is important for those services that must be stopped using a SIGTERM.

Recent Changes RSS_Feed.gif

  • Change 6319 on 2008/04/21 by tony_smith@tony_smith-blast-public
      Fix to segfault on bad command syntax. If someone ran almost any
      command without specifying either the -a flag, or a server name
      then p4dctl would segfault. This changes reworks the command line
      handling to throw a usage-message in that case
  • Change 6285 on 2008/03/18 by tony_smith@tony_smith-barney-public
      Add support for starting arbitrary daemons through this framework
      using configuration entries like this:
      other <name>
      {
      Execute = <binary>
      Owner = <username>
      [ Port = <listen port (if any)> ]
      [ Umask = <umask> ]
      PATH = "/usr/bin: etc. etc."
      }
  • Change 6240 on 2008/02/27 by tony_smith@tony_smith-home
      Correct copyright dates in LICENSE file.
  • Change 6184 on 2008/02/12 by tony_smith@tony_smith-finbar
      Some minor changes to debugging output
  • Change 6152 on 2008/01/21 by tony_smith@tony_smith-barney-public
      Add support for configuring the umask with which Perforce
      services should run to p4dctl. If unspecified, the default umask
      is 022.

Features

  • Common interface for root and non-root users
  • Non-root users limited to services they own
  • Central configuration of all services
  • Bulk start/stop of services
    • all services
    • all services of a particular type
    • all services by name
  • Easy way to check status of all services
  • Maintains pidfiles under /var/run
  • Sets process name intelligently (e.g. 'p4d [main/1666]' )
  • Designed to be a secure setuid root executable

Configuration

For security reasons, the configuration file path is hard-coded into p4dctl: /etc/p4d.conf. This ensures that only a privileged user can create or edit the file.

A sample configuration looks like this:

#-------------------------------------------------------------------------------
# Global environment variables - passed to ALL services
#-------------------------------------------------------------------------------
P4DEBUG =       server=3
P4LOG   =       log
P4CONFIG =      .p4config

#-------------------------------------------------------------------------------
# Server specifications
#-------------------------------------------------------------------------------
p4d main
{
    Owner       =       perforce
    Execute     =       /usr/local/bin/p4d
    Umask       =       077

    P4ROOT      =       /home/perforce/p4-main
    P4JOURNAL   =       journal
    P4PORT      =       1666
    PATH        =       /bin:/usr/bin:/usr/local/bin
}

p4web main
{ 
    Owner       =       perforce
    Execute     =       /usr/local/bin/p4web
    Args        =       "-b"

    P4WEBPORT   =       8080
    P4PORT      =       1666
    P4CLIENT    =       p4webclient
    PATH        =       /bin:/usr/bin:/usr/local/bin
}

Notice that the service is given a name (in this case both services use 'main'), and an owner. The idea is that only root, and the user 'perforce' can manipulate the main servers, and the environments of the servers are tightly controlled.

Support

This software is not an officially supported Perforce product. Please contact me directly for help.

Example Usage

Using the configuration file above, here are some example commands showing how p4dctl can be used:

Starting All Services

p4dctl start -a

Starting All P4D Servers

p4dctl start -a -t p4d

Starting All Servers by Name

p4dctl start main

Note that the example above would start both the P4D and P4Web servers - quite a simple way of managing groups of servers.

Sample Init Script

This is where it all started, so there wouldn't be much point in doing this if I didn't show you how to use this in an init script! Here's the one I use on Debian boxes:

PROG=/usr/local/bin/p4dctl
[ -x $PROG ] || exit 0

case "$1" in
start)  log_begin_msg "Starting Perforce services..."
        $PROG -q start -a
        log_end_msg $?
        ;;
stop)   log_begin_msg "Stopping Perforce services..."
        $PROG -q stop -a
        log_end_msg $?
        ;;
restart) log_begin_msg "Restarting Perforce servicesa..."
        $PROG -q restart -a
        log_end_msg $?
        ;;
*)      log_success_msg "Usage: /etc/init.d/p4d start|stop|restart"
        exit 1
        ;;
esac
exit 0

Obviously there's some Debian-specific stuff in there, but the main point is that the simple act of starting and stopping all services is reduced to a one-liner.

Downloads

Most people should build p4dctl from the source. To do so, you'll need the Perforce C++ API for your platform, a suitable C++ compiler, and Perforce Jam.

There are a couple of Linux binaries available from the Public Depot that people are welcome to use. If other platforms are required, please contact me.

Command Line Syntax

Global Syntax

p4dctl [global options] <command> [options] [<service name>]

Where 'global options' are:

   -c <path>       Path to configuration file (/etc/p4d.conf)
   -p <pid path>   Path to pid file directory (/var/run) 
   -q              Quiet mode
   -v              Verbose output

Recognised commands are:

   start           Start specified servers
   stop            Stop specified servers
   restart         Restart specified servers
   status          Check the status of specified servers
   checkpoint      Checkpoint specified P4D servers
   journal         Rotate journals of specified P4D servers

Start Command Syntax

 p4dctl [global options] start [options] [<name>]

 Where [options] are:

   -a              Start all servers
   -t <type>       Start only servers of specified type

If <name> is specified, then the operation is limited to servers with that name.

Stop Command Syntax

 p4dctl [global options] stop [options] [<name>]

 Where [options] are:

   -a              Stop all servers
   -t <type>       Stop only servers of specified type

If <name> is specified, then the operation is limited to servers with that name.

Restart Command Syntax

 p4dctl [global options] restart [options] [<name>]

 Where [options] are:

   -a              Restart all servers
   -t <type>       Restart only servers of specified type

If <name> is specified, then the operation is limited to servers with that name.

Status Command Syntax

 p4dctl [global options] status [options] [<name>]

 Where [options] are:

   -a              Check status of all servers
   -t <type>       Check only servers of specified type

If <name> is specified, then the operation is limited to servers with that name.

Checkpoint Command Syntax

 p4dctl [global options] checkpoint [options] [<name>]

 Where [options] are:

   -a              Checkpoint all P4D servers

If <name> is specified, then the operation is limited to servers with that name.

Journal Command Syntax

 p4dctl [global options] journal [options] [<name>]

 Where [options] are:

   -a              Rotate journals for all P4D servers

LICENSE

Copyright (c) Perforce Software, Inc., 1997-2008. All rights reserved

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1.  Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

2.  Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE
SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
Personal tools