LCOV - code coverage report
Current view: top level - source4/samba - process_single.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 27 34 79.4 %
Date: 2024-04-21 15:09:00 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    process model: process (1 process handles all client connections)
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) James J Myers 2003 <myersjj@samba.org>
       8             :    Copyright (C) Stefan (metze) Metzmacher 2004
       9             :    
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             :    
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             :    
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "samba/process_model.h"
      26             : #include "system/filesys.h"
      27             : #include "cluster/cluster.h"
      28             : 
      29             : NTSTATUS process_model_single_init(TALLOC_CTX *);
      30             : 
      31             : /*
      32             :   called when the process model is selected
      33             : */
      34          70 : static void single_model_init(void)
      35             : {
      36          70 : }
      37             : 
      38             : /*
      39             :   called when a listening socket becomes readable. 
      40             : */
      41       27753 : static void single_accept_connection(struct tevent_context *ev, 
      42             :                                      struct loadparm_context *lp_ctx,
      43             :                                      struct socket_context *listen_socket,
      44             :                                      void (*new_conn)(struct tevent_context *, 
      45             :                                                       struct loadparm_context *,
      46             :                                                       struct socket_context *, 
      47             :                                                       struct server_id, void *,
      48             :                                                       void *),
      49             :                                      void *private_data,
      50             :                                      void *process_context)
      51             : {
      52         607 :         NTSTATUS status;
      53         607 :         struct socket_context *connected_socket;
      54       27753 :         pid_t pid = getpid();
      55             : 
      56             :         /* accept an incoming connection. */
      57       27753 :         status = socket_accept(listen_socket, &connected_socket);
      58       27753 :         if (!NT_STATUS_IS_OK(status)) {
      59           0 :                 DBG_ERR("single_accept_connection: accept: %s\n",
      60             :                         nt_errstr(status));
      61             :                 /* this looks strange, but is correct. 
      62             : 
      63             :                    We can only be here if woken up from select, due to
      64             :                    an incoming connection.
      65             : 
      66             :                    We need to throttle things until the system clears
      67             :                    enough resources to handle this new socket. 
      68             : 
      69             :                    If we don't then we will spin filling the log and
      70             :                    causing more problems. We don't panic as this is
      71             :                    probably a temporary resource constraint */
      72           0 :                 sleep(1);
      73           0 :                 return;
      74             :         }
      75             : 
      76       27753 :         talloc_steal(private_data, connected_socket);
      77             : 
      78             :         /*
      79             :          * We use the PID so we cannot collide in with cluster ids
      80             :          * generated in other single mode tasks, and, and won't
      81             :          * collide with PIDs from process model standard because the
      82             :          * combination of pid/fd should be unique system-wide
      83             :          */
      84       27753 :         new_conn(ev, lp_ctx, connected_socket,
      85       27753 :                  cluster_id(pid, socket_get_fd(connected_socket)), private_data,
      86             :                             process_context);
      87             : }
      88             : 
      89             : /*
      90             :   called to startup a new task
      91             : */
      92          98 : static void single_new_task(struct tevent_context *ev,
      93             :                             struct loadparm_context *lp_ctx,
      94             :                             const char *service_name,
      95             :                             struct task_server *(*new_task)(struct tevent_context *,
      96             :                                              struct loadparm_context *,
      97             :                                              struct server_id, void *, void *),
      98             :                             void *private_data,
      99             :                             const struct service_details *service_details,
     100             :                             int from_parent_fd)
     101             : {
     102          98 :         pid_t pid = getpid();
     103             :         /* start our taskids at MAX_INT32, the first 2^31 tasks are is reserved for fd numbers */
     104           0 :         static uint32_t taskid = INT32_MAX;
     105          98 :         struct task_server *task = NULL;
     106             :         /*
     107             :          * We use the PID so we cannot collide in with cluster ids
     108             :          * generated in other single mode tasks, and, and won't
     109             :          * collide with PIDs from process model standard because the
     110             :          * combination of pid/task_id should be unique system-wide
     111             :          *
     112             :          * Using the pid unaltered makes debugging of which process
     113             :          * owns the messaging socket easier.
     114             :          */
     115          98 :         task = new_task(ev, lp_ctx, cluster_id(pid, taskid++), private_data, NULL);
     116          98 :         if (task != NULL && service_details->post_fork != NULL) {
     117          19 :                 struct process_details pd = initial_process_details;
     118          19 :                 service_details->post_fork(task, &pd);
     119             :         }
     120          98 :         if (task != NULL && service_details->before_loop != NULL) {
     121           7 :                 service_details->before_loop(task);
     122             :         }
     123          98 : }
     124             : 
     125             : /*
     126             :  * Called when a task goes down
     127             :  */
     128           0 : static void single_terminate_task(struct tevent_context *ev,
     129             :                                   struct loadparm_context *lp_ctx,
     130             :                                   const char *reason,
     131             :                                   bool fatal,
     132             :                                   void *process_context)
     133             : {
     134           0 :         DBG_NOTICE("single_terminate: reason[%s]\n",reason);
     135           0 : }
     136             : 
     137             : /*
     138             :  * Called when a connection has ended
     139             :  */
     140       27736 : static void single_terminate_connection(struct tevent_context *ev,
     141             :                                         struct loadparm_context *lp_ctx,
     142             :                                         const char *reason,
     143             :                                         void *process_context)
     144             : {
     145       27736 : }
     146             : 
     147             : /* called to set a title of a task or connection */
     148       27851 : static void single_set_title(struct tevent_context *ev, const char *title) 
     149             : {
     150       27851 : }
     151             : 
     152             : const struct model_ops single_ops = {
     153             :         .name                   = "single",
     154             :         .model_init             = single_model_init,
     155             :         .new_task               = single_new_task,
     156             :         .accept_connection      = single_accept_connection,
     157             :         .terminate_task         = single_terminate_task,
     158             :         .terminate_connection   = single_terminate_connection,
     159             :         .set_title              = single_set_title,
     160             : };
     161             : 
     162             : /*
     163             :   initialise the single process model, registering ourselves with the
     164             :   process model subsystem
     165             :  */
     166          68 : NTSTATUS process_model_single_init(TALLOC_CTX *ctx)
     167             : {
     168          68 :         return register_process_model(&single_ops);
     169             : }

Generated by: LCOV version 1.14