SessionLog.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 #include <eyedbconfig.h>
00025 
00026 #include <stdlib.h>
00027 #include <fcntl.h>
00028 #include <signal.h>
00029 #include <sys/stat.h>
00030 #include <sys/mman.h>
00031 #include "SessionLog.h"
00032 #include <time.h>
00033 #include <eyedbsm/smd.h>
00034 #include <eyedblib/rpc_lib.h>
00035 #include <eyedblib/strutils.h>
00036 #include "comp_time.h"
00037 #include <lib/m_mem_p.h>
00038 #include <eyedbsm/eyedbsm_p.h>
00039 
00040 #define MAXPORTS 8
00041 #define PORTLEN 127
00042 #define DATDIRLEN 511
00043 #define LOGDEVLEN 511
00044 
00045 #define eyedbsm_mutexLock(X, Y) eyedbsm::mutexLock(X, Y)
00046 #define eyedbsm_mutexUnlock(X, Y) eyedbsm::mutexUnlock(X, Y)
00047 
00048 //#define TRACE
00049 
00050 namespace eyedb {
00051 
00052   struct SessionHead {
00053     unsigned int magic;
00054     eyedbsm::MutexP mp;
00055     char version[32];
00056     int up;
00057     time_t start;
00058     char smdport[PORTLEN+1];
00059     int nports;
00060     char hosts[MAXPORTS][PORTLEN+1];
00061     char ports[MAXPORTS][PORTLEN+1];
00062     int uid;
00063     int pid;
00064     char datdir[DATDIRLEN+1];
00065     char logdev[LOGDEVLEN+1];
00066     int loglevel;
00067     int nconns;
00068     eyedbsm::XMOffset conn_first;
00069   };
00070 
00071 #define MAXDBS 8
00072 
00073   struct ClientInfo {
00074     time_t start;
00075     char hostname[64];
00076     char portname[64];
00077     char username[64];
00078     char progname[128];
00079     int n_dbs;
00080     struct {
00081       char dbname[32];
00082       char userauth[10];
00083       int flags;
00084     } dbs[MAXDBS];
00085     int prog_pid;
00086     int backend_pid;
00087     eyedbsm::XMOffset conn_prev, conn_next;
00088   };
00089 
00090   SessionLog *SessionLog::sesslog;
00091 
00092 #include <pwd.h>
00093 
00094   static const char *
00095   getUserName(int uid)
00096   {
00097     struct passwd *p = getpwuid(uid);
00098     if (!p)
00099       return "<unknown>";
00100     return p->pw_name;
00101   }
00102 
00103 #define SE_CONNLOG_MAGIC ((unsigned int)0x3f1920ab)
00104 //#define CONNLOG_SIZE 0x10000
00105 #define CONNLOG_SIZE (sizeof(SessionHead) + 128 * sizeof(ClientInfo))
00106 
00107 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00108   Status
00109   SessionLog::init_sems()
00110   {
00111     vd = (void *)calloc(sizeof(eyedbsm::DbDescription), 1);
00112     int *semkeys = (int *)((eyedbsm::DbDescription *)vd)->semkeys;
00113     smdcli_conn_t *conn = smdcli_open(smd_get_port());
00114     if (!conn)
00115       return Exception::make(IDB_ERROR, "sessionlog: cannot connect to eyedbsmd ");
00116     smdcli_init_getsems(conn, ServerConfig::getSValue("default_dbm"), semkeys);
00117 
00118     if (semkeys[0] <= 0)
00119       return Exception::make(IDB_ERROR, "sessionlog: cannot create semaphores ");
00120     return Success;
00121   }
00122 #endif
00123 
00124   SessionLog::SessionLog(const SessionLog &sesslog)
00125   {
00126     init(sesslog.host, sesslog.port, sesslog.logdir, True);
00127   }
00128 
00129   SessionLog::SessionLog(const char *host, const char *port,
00130                          const char *logdir, Bool writing)
00131   {
00132     init(host, port, logdir, writing);
00133   }
00134 
00135   void SessionLog::init(const char *host, const char *port, const char *logdir,
00136                         Bool writing)
00137   {
00138 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00139     status = init_sems();
00140     if (status)
00141       return;
00142 #else
00143     vd = (void *)calloc(sizeof(eyedbsm::DbDescription), 1);
00144 #endif
00145     islocked = False;
00146     addr_connlog = 0;
00147     status = openRealize(host, port, logdir, False, writing);
00148     if (status)
00149       return;
00150 
00151     sesslog = this;
00152   }
00153 
00154   // create constructor
00155   SessionLog::SessionLog(const char *logdir, const char *version,
00156                          int nports, const char *hosts[], const char *ports[],
00157                          const char *datdir,
00158                          const char *logdev, int loglevel)
00159   {
00160     int i;
00161 
00162 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
00163     status = init_sems();
00164     if (status)
00165       return;
00166 #else
00167     vd = (void *)calloc(sizeof(eyedbsm::DbDescription), 1);
00168 #endif
00169     islocked = False;
00170     addr_connlog = 0;
00171     status = openRealize(hosts[0], ports[0], logdir, True, True);
00172 
00173     if (status)
00174       return;
00175 
00176     file_cnt = nports;
00177     if (file_cnt > 1) {
00178       files = (char **)realloc(files, file_cnt * sizeof(char *));
00179 
00180       for (i = 1; i < file_cnt; i++) {
00181         files[i] = makeFile(hosts[i], ports[i], logdir);
00182         symlink(files[0], files[i]);
00183       }
00184     }
00185 
00186     sesslog = this;
00187 
00188     memset(&connhead, sizeof(connhead), 0);
00189     connhead->magic = SE_CONNLOG_MAGIC;
00190     strcpy(connhead->version, version);
00191     time(&connhead->start);
00192     connhead->up = 1;
00193     strncpy(connhead->smdport, smd_get_port(), PORTLEN);
00194     connhead->smdport[PORTLEN] = 0;
00195     connhead->nports = nports;
00196     for (i = 0; i < nports; i++) {
00197       strncpy(connhead->hosts[i], hosts[i], PORTLEN);
00198       connhead->hosts[i][PORTLEN] = 0;
00199       strncpy(connhead->ports[i], ports[i], PORTLEN);
00200       connhead->ports[i][PORTLEN] = 0;
00201     }
00202 
00203     strncpy(connhead->datdir, datdir, DATDIRLEN);
00204     connhead->datdir[DATDIRLEN] = 0;
00205     connhead->pid = rpc_getpid();
00206     connhead->uid = getuid();
00207 
00208     if (logdev) {
00209       strncpy(connhead->logdev, logdev, LOGDEVLEN);
00210       connhead->logdev[LOGDEVLEN] = 0;
00211     }
00212 
00213     connhead->loglevel = loglevel;
00214     connhead->conn_first = XM_NULLOFFSET;
00215   }
00216 
00217   static char *truedir(const char *rs)
00218   {
00219     char *s, *os;
00220     s = strdup(rs);
00221 
00222     os = s;
00223     if (!strchr(s, '.'))
00224       return s;
00225 
00226     int sx_cnt = 0;
00227     int sx_alloc = 0;
00228     char **sx = 0;
00229     char *p;
00230     char *r = (char *)malloc(strlen(s)+1);
00231 
00232     if (*s == '/')
00233       s++;
00234 
00235     for (;;) {
00236       int stopafter = 0;
00237       if (!(p = strchr(s, '/'))) {
00238         p = s + strlen(s);
00239         stopafter = 1;
00240       }
00241 
00242       char *q = (char *)malloc(p-s+1);
00243       strncpy(q, s, p-s);
00244       q[p-s] = 0;
00245       if (!strcmp(q, "..")) {
00246         sx_cnt--;
00247         free(sx[sx_cnt]);
00248         free(q);
00249       }
00250       else {
00251         if (sx_cnt >= sx_alloc) {
00252           sx_alloc++;
00253           sx = (char **)realloc(sx, sx_alloc*sizeof(char *));
00254         }
00255         sx[sx_cnt] = q;
00256         sx_cnt++;
00257       }
00258 
00259       if (stopafter)
00260         break;
00261       s = p+1;
00262     }
00263 
00264     *r = 0;
00265     for (int i = 0; i < sx_cnt; i++) {
00266       strcat(r, "/");
00267       strcat(r, sx[i]);
00268       free(sx[i]);
00269     }
00270 
00271     free(sx);
00272     free(os);
00273     return r;
00274   }
00275 
00276   char *
00277   SessionLog::makeFile(const char *_host, const char *_port, const char *_logdir)
00278   {
00279     static const char conn_prefix[] = ".eyedb_";
00280     static const char conn_suffix[] = ".con";
00281     char hostname[256];
00282     char *file;
00283 
00284     if (!_logdir || !_port)
00285       return 0;
00286 
00287     port = strdup(_port);
00288     host = strdup(_host);
00289 
00290     char *port_file = truedir((std::string(host) + ":" + _port).c_str());
00291       
00292     char *p = port_file;
00293     while (p = strchr(p, '/'))
00294       *p = '_';
00295 
00296     logdir = strdup(_logdir ? _logdir : "/tmp");
00297 
00298     gethostname(hostname, sizeof(hostname)-1);
00299 
00300     file = (char *)malloc(strlen(logdir) +
00301                           1 + /* / */
00302                           strlen(conn_prefix) +
00303                           strlen(port_file) +
00304                           1 + /* : */
00305                           strlen(hostname) +
00306                           strlen(conn_suffix) +
00307                           1);
00308   
00309     sprintf(file, "%s/%s%s_%s%s", logdir, conn_prefix, port_file, hostname,
00310             conn_suffix);
00311 
00312     return file;
00313   }
00314 
00315   Status
00316   SessionLog::openRealize(const char *host, const char *port,
00317                           const char *logdir, Bool create,
00318                           Bool writing)
00319   {
00320     Error err = (create ? IDB_SESSION_LOG_CREATION_ERROR :
00321                  IDB_SESSION_LOG_OPEN_ERROR);
00322     int fd;
00323     file_cnt = 1;
00324     files = (char **)malloc(file_cnt * sizeof(char *));
00325     files[0] = makeFile(host, port, logdir);
00326 
00327     // 21/03/06: must be writable for pthread_mutex version
00328     writing = True;
00329 
00330     xm_connlog = 0;
00331 
00332     if (!files[0])
00333       return Exception::make(err, "eyedb environment error");
00334 
00335     if (create)
00336       fd = open(files[0], O_CREAT | O_TRUNC | O_RDWR,
00337                 0644 /*SE_DEFAULT_CREATION_MODE*/);
00338     else {
00339       if (access(files[0], F_OK) < 0)
00340         return Exception::make(IDB_CONNECTION_LOG_FILE_ERROR,
00341                                "cannot access connection file '%s'",
00342                                files[0]);
00343 
00344       if (access(files[0], R_OK) < 0)
00345         return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00346                                "cannot open connection file '%s' "
00347                                "for reading", files[0]);
00348 
00349       if (writing) {
00350         if (access(files[0], W_OK) < 0)
00351           return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00352                                  "cannot open connection file '%s' "
00353                                  "for writing", files[0]);
00354         
00355         fd = open(files[0], O_RDWR);
00356       }
00357       else
00358         fd = open(files[0], O_RDONLY);
00359     }
00360     
00361     if (fd < 0 && create)
00362       return Exception::make(err,
00363                              "cannot %s connection file '%s'",
00364                              (create ? "create" :
00365                               "open"), files[0]);
00366     if (fd < 0)
00367       return Exception::make(IDB_SESSION_LOG_OPEN_ERROR,
00368                              "cannot open connection file '%s'",
00369                              files[0]);
00370 
00371     if (create && ftruncate(fd, CONNLOG_SIZE) < 0) {
00372       close(fd);
00373       return Exception::make(err,
00374                              "cannot create connection file '%s'", files[0]);
00375     }
00376 
00377     unsigned int prot = PROT_READ;
00378     if (writing)
00379       prot |= PROT_WRITE;
00380     if (!(m_connlog = m_mmap(0, CONNLOG_SIZE, prot,
00381                              MAP_SHARED, fd, 0, (char **)&addr_connlog,
00382                              files[0], 0, 0))) {
00383       close(fd);
00384       return Exception::make(err,
00385                              "cannot map connection file '%s' for size %d",
00386                              files[0], CONNLOG_SIZE);
00387     }
00388     
00389     if (!create) {
00390       struct stat st;
00391       if (fstat(fd, &st) < 0) {
00392         close(fd);
00393         return Exception::make(err, "cannot stat connection "
00394                                "log file '%s'", files[0]);
00395       }
00396 
00397       if (st.st_size < CONNLOG_SIZE && ftruncate(fd, CONNLOG_SIZE) < 0) {
00398         close(fd);
00399         return Exception::make(err,
00400                                "cannot create connection "
00401                                "log file '%s'", files[0]);
00402       }
00403     }
00404 
00405     close(fd);
00406     m_lock(m_connlog);
00407 
00408     connhead = (SessionHead *)addr_connlog;
00409 
00410     if (create)
00411       xm_connlog = eyedbsm::XMCreate(addr_connlog + sizeof(SessionHead),
00412                                      CONNLOG_SIZE - sizeof(SessionHead), vd);
00413     else
00414       xm_connlog = eyedbsm::XMOpen(addr_connlog + sizeof(SessionHead), vd);
00415 
00416     if (!xm_connlog)
00417       return Exception::make(err,
00418                              "cannot map connection file '%s' for size %d",
00419                              files[0], CONNLOG_SIZE);
00420     return Success;
00421   }
00422 
00423   Status
00424   SessionLog::add(const char *hostname, const char *portname,
00425                   const char *username,
00426                   const char *progname, int pid,
00427                   ClientSessionLog*& clientLog)
00428   {
00429     ClientInfo *conninfo =
00430       (ClientInfo *)XMAlloc(xm_connlog, sizeof(ClientInfo));
00431 
00432     if (!conninfo)
00433       return Exception::make(IDB_SESSION_LOG_NO_SPACE_LEFT,
00434                              "no space left on connection file");
00435 
00436     memset(conninfo, 0, sizeof(*conninfo));
00437 
00438     time(&conninfo->start);
00439     strncpy(conninfo->hostname, hostname, sizeof(conninfo->hostname)-1);
00440     strncpy(conninfo->portname, portname, sizeof(conninfo->portname)-1);
00441     strncpy(conninfo->username, username, sizeof(conninfo->username)-1);
00442     strncpy(conninfo->progname, progname, sizeof(conninfo->progname)-1);
00443 
00444     conninfo->prog_pid = pid;
00445     conninfo->backend_pid = rpc_getpid();
00446 
00447 #ifdef TRACE
00448     fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00449 #endif
00450     eyedbsm_mutexLock(xm_connlog->mp, 0);
00451 #ifdef TRACE
00452     fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00453 #endif
00454     islocked = True;
00455 
00456     conninfo->conn_next = connhead->conn_first;
00457     conninfo->conn_prev = XM_NULLOFFSET;
00458 
00459     if (connhead->conn_first) {
00460       ClientInfo *first = (ClientInfo *)
00461         XM_ADDR(xm_connlog, connhead->conn_first);
00462       first->conn_prev = XM_OFFSET(xm_connlog, conninfo);
00463     }
00464 
00465     connhead->conn_first = XM_OFFSET(xm_connlog, conninfo);
00466     connhead->nconns++;
00467 
00468     eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00469 #ifdef TRACE
00470     fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00471 #endif
00472     islocked = False;
00473 
00474     clientLog = new ClientSessionLog(conninfo);
00475 
00476 #ifdef TRACE
00477     fprintf(stderr, "log add (%s, %s, %s, %d, %d)\n",
00478             hostname, username, progname, pid, rpc_getpid());
00479 #endif
00480 
00481     return Success;
00482   }
00483 
00484   void
00485   SessionLog::suppress(ClientSessionLog *clientLog)
00486   {
00487     ClientInfo *conninfo = clientLog->getClientInfo();
00488 
00489 #ifdef TRACE
00490     fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00491 #endif
00492     eyedbsm_mutexLock(xm_connlog->mp, 0);
00493 #ifdef TRACE
00494     fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00495 #endif
00496     islocked = True;
00497 
00498     if (conninfo->conn_next)
00499       ((ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next))->conn_prev =
00500         conninfo->conn_prev;
00501 
00502     if (conninfo->conn_prev)
00503       ((ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev))->conn_next =
00504         conninfo->conn_next;
00505     else
00506       connhead->conn_first = conninfo->conn_next;
00507 
00508 #ifdef TRACE
00509     fprintf(stderr, "log suppress (%s, %s, %s, %d, %d)\n",
00510             conninfo->hostname, conninfo->username, conninfo->progname,
00511             conninfo->prog_pid, conninfo->backend_pid);
00512 #endif
00513 
00514     connhead->nconns--;
00515     eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00516 #ifdef TRACE
00517     fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00518 #endif
00519     islocked = False;
00520 
00521     XMFree(xm_connlog, conninfo);
00522   }
00523 
00524   static Bool
00525   check_server(ClientInfo *conninfo)
00526   {
00527 #ifdef HAVE_SLASH_PROC
00528     if (access((std::string("/proc/") + str_convert((long)conninfo->backend_pid)).c_str(), 
00529                F_OK) >= 0)
00530       return True;
00531     return False;
00532 #else
00533     return True;
00534 #endif
00535   }
00536 
00537   int
00538   SessionLog::get_nb_clients()
00539   {
00540     ClientInfo *conninfo =
00541       (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00542 
00543     int nb_clients = 0;
00544     for (int n = connhead->nconns-1; n >= 1; n--)
00545       conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00546 
00547     while(conninfo) {
00548       if (check_server(conninfo))
00549         nb_clients++;
00550 
00551       conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev);
00552     }
00553 
00554     return nb_clients;
00555   }
00556 
00557   void SessionLog::display(FILE *fd, Bool nolock)
00558   {
00559     int n;
00560     ClientInfo *conninfo;
00561 
00562     if (!connhead)
00563       {
00564         fprintf(fd, "EyeDB Server %s:%s is down\n", host, port);
00565         return;
00566       }
00567 
00568     if (!nolock) {
00569 #ifdef TRACE
00570       fprintf(stderr, "SessionLog %d tries to locked\n", rpc_getpid());
00571 #endif
00572       eyedbsm_mutexLock(xm_connlog->mp, 0);
00573 #ifdef TRACE
00574       fprintf(stderr, "SessionLog %d is locked\n", rpc_getpid());
00575 #endif
00576       islocked = True;
00577     }
00578     else if (sesslog && sesslog->islocked) {
00579 #ifdef TRACE
00580       fprintf(stderr, "Warning SessionLog is locked by %d\n",
00581               sesslog->connhead->pid);
00582 #endif
00583     }
00584 
00585     if (!connhead->up) {
00586       fprintf(fd, "EyeDB Server %s:%s is down from %s", host, port,
00587               ctime(&connhead->start));
00588       if (!nolock) {
00589         eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00590 #ifdef TRACE
00591         fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00592 #endif
00593         islocked = False;
00594       }
00595       return;
00596     }
00597 
00598     fprintf(fd, "EyeDB Server running since %s\n",
00599             ctime(&connhead->start));
00600 
00601     fprintf(fd, "  Version       V%s\n", connhead->version);
00602     fprintf(fd, "  Date          %s\n", getCompilationTime());
00603     fprintf(fd, "  Architecture  %s\n", Architecture::getArchitecture()->getArch());
00604     fprintf(fd, "  Program Pid   %d\n", connhead->pid);
00605     fprintf(fd, "  Running Under %s\n\n", getUserName(connhead->uid));
00606 
00607 #ifdef HAVE_EYEDBSMD
00608     fprintf(fd, "  SMD Port      %s\n", connhead->smdport);
00609 #endif
00610     
00611     fprintf(fd, "  Listening on  ");
00612 
00613     const char *indent;
00614     if (connhead->nports > 1) {
00615       indent =  "\n                ";
00616     }
00617     else
00618       indent = "";
00619 
00620     for (n = 0; n < connhead->nports; n++) {
00621       fprintf(fd, "%s%s:%s", (n ? indent : ""), connhead->hosts[n],
00622               connhead->ports[n]);
00623     }
00624 
00625     fprintf(fd, "\n  Datafile Directory %s\n", connhead->datdir);
00626 
00627     if (*connhead->logdev) {
00628       fprintf(fd, "  Log Device '%s'\n", connhead->logdev);
00629       if (connhead->loglevel)
00630         fprintf(fd, "  Log Level %d\n", connhead->loglevel);
00631     }
00632 
00633     fprintf(fd, "\n");
00634 
00635     int nb_clients = get_nb_clients();
00636     if (!nb_clients) {
00637       fprintf(fd, "  No Clients connected.\n");
00638       if (!nolock) {
00639         eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00640 #ifdef TRACE
00641         fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00642 #endif
00643         islocked = False;
00644       }
00645       return;
00646     }
00647 
00648     fprintf(fd, "  %d Client%s connected\n\n", 
00649             nb_clients, nb_clients > 1 ? "s" : "");
00650 
00651     conninfo = (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00652 
00653     for (n = connhead->nconns-1; n >= 1; n--)
00654       conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00655 
00656     for (n = 0; conninfo;
00657          conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_prev)) {
00658 
00659       // solaris only?
00660       if (!check_server(conninfo))
00661         continue;
00662 
00663       fprintf(fd, "%sClient #%d\n", (n ? "\n" : ""), n);
00664       fprintf(fd, "  Connected on %s", ctime(&conninfo->start));
00665       if (*conninfo->hostname && *conninfo->portname)
00666         fprintf(fd, "  Host:Port    %s:%s\n", conninfo->hostname,
00667                 conninfo->portname);
00668       if (*conninfo->username)
00669         fprintf(fd, "  User Name    %s\n", conninfo->username);
00670       if (*conninfo->progname)
00671         fprintf(fd, "  Program Name %s\n", conninfo->progname);
00672       if (conninfo->prog_pid)
00673         fprintf(fd, "  Client Pid   %d\n",   conninfo->prog_pid);
00674       if (conninfo->backend_pid)
00675         fprintf(fd, "  EyeDB Server Pid %d\n",   conninfo->backend_pid);
00676 
00677       if (conninfo->n_dbs) {
00678         fprintf(fd, "  Open Database%s ", conninfo->n_dbs > 1 ? "s" : "");
00679         for (int j = 0; j < conninfo->n_dbs; j++) {
00680           fprintf(fd, "%s'%s' [mode=%s]", (j?"\n                   ":""),
00681                   conninfo->dbs[j].dbname,
00682                   Database::getStringFlag((Database::OpenFlag)conninfo->dbs[j].flags));
00683           if (*conninfo->dbs[j].userauth)
00684             fprintf(fd, " [userauth=%s]", conninfo->dbs[j].userauth);
00685         }
00686         fprintf(fd, "\n");
00687       }
00688       else
00689         fprintf(fd, "  No Opened Databases\n");
00690 
00691       n++;
00692     }
00693 
00694     if (!nolock) {
00695       eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00696 #ifdef TRACE
00697       fprintf(stderr, "SessionLog %d is UNlocked\n", rpc_getpid());
00698 #endif
00699       islocked = False;
00700     }
00701   }
00702 
00703   void SessionLog::remove()
00704   {
00705     connhead->up = 0;
00706     time(&connhead->start);
00707 
00708     for (int i = 0; i < file_cnt; i++)
00709       unlink(files[i]);
00710   }
00711 
00712   Bool SessionLog::isUp() const
00713   {
00714     return connhead && connhead->up ? True : False;
00715   }
00716 
00717   Status
00718   SessionLog::stopServers(Bool force)
00719   {
00720     if (!connhead || !xm_connlog)
00721       return Exception::make("EyeDB Server %s:%s is down", host, port);
00722 
00723     if (!connhead || !connhead->up)
00724       return Exception::make("EyeDB Server %s:%s is already down from %s",
00725                              host, port, ctime(&connhead->start));
00726 
00727     int nb_clients = get_nb_clients();
00728     if (nb_clients && !force) {
00729       return Exception::make
00730         (IDB_ERROR, "%d client%s %s connected.\n"
00731          "Use the `stop -f' option to force the servers to stop.",
00732          nb_clients,
00733          (nb_clients > 1 ? "s" : ""),
00734          (nb_clients > 1 ? "are" : "is"));
00735     }
00736 
00737     // eyedbsm_mutexLock(xm_connlog->mp, 0);
00738 
00739     ClientInfo *conninfo =
00740       (ClientInfo *)XM_ADDR(xm_connlog, connhead->conn_first);
00741 
00742     while (conninfo) {
00743       if (check_server(conninfo)) {
00744         fprintf(stderr, "Killing Client Backend Pid %d\n",
00745                 conninfo->backend_pid);
00746         kill(conninfo->backend_pid, SIGTERM);
00747       }
00748       conninfo = (ClientInfo *)XM_ADDR(xm_connlog, conninfo->conn_next);
00749     }
00750 
00751     fprintf(stderr, "Killing EyeDB Server Pid %d\n", connhead->pid);
00752     kill(connhead->pid, SIGTERM);
00753 
00754     // eyedbsm_mutexUnlock(xm_connlog->mp, 0);
00755     return Success;
00756   }
00757 
00758   void
00759   SessionLog::release()
00760   {
00761     /*
00762     if (sesslog && sesslog->islocked)
00763       eyedbsm_mutexUnlock(&sesslog->mp, 0);
00764     */
00765   }
00766 
00767   SessionLog::~SessionLog()
00768   {
00769     free(vd);
00770   }
00771 
00772   ClientSessionLog::ClientSessionLog(ClientInfo *_clinfo)
00773     : clinfo(_clinfo)
00774   {
00775   }
00776 
00777   void
00778   ClientSessionLog::addDatabase(const char *name, const char *userauth,
00779                                 int flags)
00780   {
00781     if (clinfo->n_dbs < MAXDBS) { 
00782       if (!userauth)
00783         userauth = "";
00784 
00785       strcpy(clinfo->dbs[clinfo->n_dbs].dbname, name);
00786       strcpy(clinfo->dbs[clinfo->n_dbs].userauth, userauth);
00787       clinfo->dbs[clinfo->n_dbs].flags = flags;
00788       clinfo->n_dbs++;
00789     }
00790   }
00791 
00792   void
00793   ClientSessionLog::suppressDatabase(const char *name, const char *userauth,
00794                                      int flags)
00795   {
00796     if (!userauth)
00797       userauth = "";
00798 
00799     for (int i = 0; i < clinfo->n_dbs; i++)
00800       if (!strcmp(clinfo->dbs[i].dbname, name) &&
00801           !strcmp(clinfo->dbs[i].userauth, userauth) &&
00802           clinfo->dbs[i].flags == flags) {
00803         for (int j = i; j < clinfo->n_dbs-1; j++) {
00804           strcpy(clinfo->dbs[j].dbname, clinfo->dbs[j+1].dbname);
00805           strcpy(clinfo->dbs[j].userauth, clinfo->dbs[j+1].userauth);
00806           clinfo->dbs[j].flags = clinfo->dbs[j+1].flags;
00807         }
00808 
00809         clinfo->n_dbs--;
00810         return;
00811       }
00812   }
00813 }

Generated on Mon Dec 22 18:16:08 2008 for eyedb by  doxygen 1.5.3