[pve-devel] r5538 - in pve-common/trunk/data: . PVE
svn-commits at proxmox.com
svn-commits at proxmox.com
Wed Feb 16 06:36:56 CET 2011
Author: dietmar
Date: 2011-02-16 06:36:56 +0100 (Wed, 16 Feb 2011)
New Revision: 5538
Removed:
pve-common/trunk/data/PVE/RPCEnvironment.pm
Modified:
pve-common/trunk/data/ChangeLog
pve-common/trunk/data/Makefile
Log:
* PVE/RPCEnvironment.pm: moved to pve-access-control
Modified: pve-common/trunk/data/ChangeLog
===================================================================
--- pve-common/trunk/data/ChangeLog 2011-02-16 05:33:31 UTC (rev 5537)
+++ pve-common/trunk/data/ChangeLog 2011-02-16 05:36:56 UTC (rev 5538)
@@ -1,3 +1,7 @@
+2011-02-16 Proxmox Support Team <support at proxmox.com>
+
+ * PVE/RPCEnvironment.pm: moved to pve-access-control
+
2011-02-15 Proxmox Support Team <support at proxmox.com>
* PVE/Tools.pm (template_replace): support simple uri templates
Modified: pve-common/trunk/data/Makefile
===================================================================
--- pve-common/trunk/data/Makefile 2011-02-16 05:33:31 UTC (rev 5537)
+++ pve-common/trunk/data/Makefile 2011-02-16 05:36:56 UTC (rev 5538)
@@ -8,7 +8,6 @@
LIB_SOURCES= \
ProcFSTools.pm \
- RPCEnvironment.pm \
CLIHandler.pm \
RESTHandler.pm \
JSONSchema.pm \
Deleted: pve-common/trunk/data/PVE/RPCEnvironment.pm
===================================================================
--- pve-common/trunk/data/PVE/RPCEnvironment.pm 2011-02-16 05:33:31 UTC (rev 5537)
+++ pve-common/trunk/data/PVE/RPCEnvironment.pm 2011-02-16 05:36:56 UTC (rev 5538)
@@ -1,331 +0,0 @@
-package PVE::RPCEnvironment;
-
-use strict;
-use warnings;
-use POSIX ":sys_wait_h";
-use IO::File;
-use Fcntl qw(:flock);
-use PVE::SafeSyslog;
-use PVE::INotify;
-use PVE::ProcFSTools;
-
-# we use this singleton class to pass RPC related environment value
-
-my $pve_env;
-
-# save $SIG{CHLD} handler implementation.
-# simply set $SIG{CHLD} = $worker_reaper;
-# and register forked processes with &$register_worker(pid)
-# Note: using $SIG{CHLD} = 'IGNORE' or $SIG{CHLD} = sub { wait (); } or ...
-# has serious side effects, because perls built in system() and open()
-# functions can't get the correct exit status of a child. So we cant use
-# that (also see perlipc)
-
-my $WORKER_PIDS;
-
-my $worker_reaper = sub {
- local $!; local $?;
- foreach my $pid (keys %$WORKER_PIDS) {
- my $waitpid = waitpid ($pid, WNOHANG);
- if (defined($waitpid) && ($waitpid == $pid)) {
- delete ($WORKER_PIDS->{$pid});
- }
- }
-};
-
-my $register_worker = sub {
- my $pid = shift;
-
- return if !$pid;
-
- # do not register if already finished
- my $waitpid = waitpid ($pid, WNOHANG);
- if (defined($waitpid) && ($waitpid == $pid)) {
- delete ($WORKER_PIDS->{$pid});
- return;
- }
-
- $WORKER_PIDS->{$pid} = 1;
-};
-
-sub get {
-
- die "not initialized" if !$pve_env;
-
- return $pve_env;
-}
-
-sub init {
- my ($class, $type, %params) = @_;
-
- $class = ref($class) || $class;
-
- die "already initialized" if $pve_env;
-
- die "unknown environment type" if !$type || $type !~ m/^(cli|pub|priv)$/;
-
- $SIG{CHLD} = $worker_reaper;
-
- # environment types
- # cli ... command started fron command line
- # pub ... access from public server (apache)
- # priv ... access from private server (pvedaemon)
-
- my $self = {
- type => $type,
- };
-
- bless $self, $class;
-
- foreach my $p (keys %params) {
- if ($p eq 'atfork') {
- $self->{$p} = $params{$p};
- } else {
- die "unknown option '$p'";
- }
- }
-
- $pve_env = $self;
-
- my ($sysname, $nodename) = POSIX::uname();
-
- $nodename =~ s/\..*$//; # strip domain part, if any
-
- $self->{nodename} = $nodename;
-
- return $self;
-};
-
-sub set_language {
- my ($self, $lang) = @_;
-
- # fixme: initialize I18N
-
- $self->{language} = $lang;
-}
-
-sub set_user {
- my ($self, $user) = @_;
-
- # fixme: get ACLs
-
- $self->{user} = $user;
-}
-
-sub get_user {
- my ($self) = @_;
-
- die "user name not set\n" if !$self->{user};
-
- return $self->{user};
-}
-
-# UPID helper
-# WARN: $res->{filename} must not depend on PID, because we
-# use it before we know the PID
-
-sub upid_decode {
- my $upid = shift;
-
- my $res;
-
- # "UPID:$node:$pid:$start:$type:$data"
- if ($upid =~ m/^UPID:(\w+):(\d+)(-(\d+))?:(\d+):([^:\s]+):(.*)$/) {
- $res->{node} = $1;
- $res->{pid} = $2;
- $res->{pstart} = $4 || 0;
- $res->{starttime} = $5;
- $res->{type} = $6;
- $res->{data} = $7;
-
- if ($res->{type} eq 'vmops') {
- if ($res->{data} =~ m/^([^:\s]+):(\d+):(\S+)$/) {
- $res->{command} = $1;
- $res->{veid} = $2;
- $res->{user} = $3;
-
- $res->{filename} = "/tmp/vmops-$res->{veid}.out";
- } else {
- return undef;
- }
- } elsif ($res->{type} eq 'apldownload') {
- if ($res->{data} =~ m/^([^:\s]+):(.+)$/) {
- $res->{user} = $1;
- $res->{apl} = $2;
- $res->{filename} = "/tmp/apldownload-$res->{user}.out";
- } else {
- return undef;
- }
- }
- }
-
- return $res;
-}
-
-sub upid_encode {
- my $uip_hash = shift;
-
- my $d = $uip_hash; # shortcut
-
- return "UPID:$d->{node}:$d->{pid}-$d->{pstart}:$d->{starttime}:$d->{type}:$d->{data}";
-}
-
-# start long running workers
-# $data append to the returned uniquely identifier, which
-# has the following format: "UPID:$node:$pid-$pstart:$startime:$dtype:$data"
-# STDIN is redirected to /dev/null
-# STDOUT,STDERR are redirected to the filename returned by upid_decode
-# that file is locked wit flock to make sure only one process
-# is writing it
-
-sub fork_worker {
- my ($self, $dtype, $data, $function) = @_;
-
- $dtype = 'unknown' if !defined ($dtype);
-
- $data = '' if !defined ($data);
-
- my $starttime = time ();
-
- my @psync = POSIX::pipe();
-
- my $node = $self->{nodename};
-
- # detect filename with faked PID
- my $tmp = upid_decode ("UPID:$node:0-0:0:$dtype:$data");
- my $filename = $tmp->{filename};
-
- my $lockfh;
- # lock output file
- if ($filename) {
-
- $lockfh = IO::File->new ($filename, O_WRONLY|O_CREAT) ||
- die "unable to open output file - $!\n";
-
- my $wwwid = getpwnam('www-data');
- chown $wwwid, $filename;
-
- if (!flock ($lockfh, LOCK_EX|LOCK_NB)) {
- undef $lockfh; # close
- die "unable to lock output file\n";
- }
-
- if (!truncate ($lockfh, 0)) {
- die "unable to truncate output file - $!\n";
- }
- }
-
- my $cpid = fork();
- if (!defined($cpid)) {
- undef $lockfh; # close
- die "unable to fork worker - $!";
- }
-
- if ($cpid == 0) {
-
- $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { die "received interrupt\n"; };
-
- $SIG{CHLD} = $SIG{PIPE} = 'DEFAULT';
-
- # set sess/process group - we want to be able to kill the
- # whole process group
- POSIX::setsid();
-
- POSIX::close ($psync[0]);
-
- PVE::INotify::inotify_close();
-
- if (my $atfork = $self->{atfork}) {
- &$atfork();
- }
-
- # same algorythm as used inside SA
-
- # STDIN = /dev/null
- my $fd = fileno (STDIN);
- close STDIN;
- POSIX::close(0) if $fd != 0;
-
- if (!open (STDIN, "</dev/null")) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- # redirect STDOUT
- $fd = fileno(STDOUT);
- close STDOUT;
- POSIX::close (1) if $fd != 1;
-
- if ($filename) {
- if (!open (STDOUT, ">&", $lockfh)) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- STDOUT->autoflush (1);
- } else {
- if (!open (STDOUT, ">/dev/null")) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
- }
-
- # redirect STDERR to STDOUT
- $fd = fileno (STDERR);
- close STDERR;
- POSIX::close(2) if $fd != 2;
-
- if (!open (STDERR, ">&1")) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- STDERR->autoflush (1);
-
- my $pstart = PVE::ProcFSTools::read_proc_starttime ($$) ||
- die "unable to read process starttime";
-
- my $upid = upid_encode ({
- node => $node, pid => $$, pstart => $pstart,
- starttime => $starttime, type => $dtype, data => $data });
-
- # sync with parent
- POSIX::write ($psync[1], $upid, length ($upid));
- POSIX::close ($psync[1]);
-
- eval { &$function ($upid); };
- my $err = $@;
- if ($err) {
- my $msg = "worker function failed: $err";
- syslog('err', $msg);
- print STDERR "$msg\n";
- POSIX::_exit(-1);
- } else {
- POSIX::_exit (0);
- }
- kill ('KILL', $$);
- }
-
- POSIX::close ($psync[1]);
-
- # sync with child (wait until child starts)
- my $upid = '';
- POSIX::read($psync[0], $upid, 4096);
- POSIX::close ($psync[0]);
-
- undef $lockfh; # close
-
- &$register_worker($cpid);
-
- my $uh = upid_decode ($upid);
- if (!$uh ||
- !($uh->{node} eq $node && $uh->{pid} == $cpid &&
- $uh->{starttime} == $starttime &&
- $uh->{type} eq $dtype && $uh->{data} eq $data)) {
- die "got strange worker upid '$upid'\n";
- }
-
- return $upid;
-}
-
-1;
More information about the pve-devel
mailing list