In addition to network communication, the server program must also take into account many other details of the problem, fragmented, but basically the template-style. ——— cited
- Linux server programs typically run in the background. Daemon is also known as the daemon process. It does not control the terminal and therefore does not accidentally accept user input. The parent process of the daemon is typically the init process (pid=1).
- Linux server programs usually have a set of log systems, which can output logs to a file at least, and some advanced servers can output logs to a dedicated UDP server. Most background processes have their own log directory under/var/log.
- Linux server programs typically run with a specific non-root identity. Mysqld, httpd, syslogd and other background processes, and respectively have their own running account MySQL, Apache, syslog. ‘
- Linux servers are usually configurable. Server programs typically handle many of the command options, and if there are too many options to run at one time, Carat is managed with a configuration file. Most server programs have configuration files and are stored in/etc
- Linux server programs typically generate a PID file at startup and are stored in the/var/run directory to record the PID of the background process.
- Linux server programs often need to take into account system resources and constraints to predict how much load they can withstand, such as the total number of file descriptors and the total amount of memory used by the process.
1. Log1.Linux System log:
- Linux provides a daemon to handle system log –SYSLOGD, upgraded version –rsyslogd.
- The RSYSLOGD daemon can receive user process output logs and can accept kernel logs.
- The system log is generated by invoking a syslog function when the user processes.
- The function outputs the log to a UNIX local domain socket type (af_unix) file/dev/log, Rsyslogd listens to the file to get the output of the user process.
- The kernel log is managed by another daemon rklogd on the previous system, and RSYSLOGD uses the additional modules to achieve the same functionality. The kernel log is printed to the kernel ring cache by PRINTK, such as a swap tree. The contents of the ring cache are mapped directly to the/proc/kmsg.
- Rsyslogd by reading the file to obtain the kernel log, the default debugging information is saved in/var/log/debug, the general information is saved to/var/log/messages, kernel information:/var/log/kern.log. Configuration file:/etc/rsyslog.conf, mainly set the kernel log input path, whether to accept the UDP log, and its listening port (the default 514/etc/services) whether to accept the TCP log and its listening port, log file permissions, including which configuration files.
2.syslog ()
The application uses the syslog () to communicate with the daemon rsyslogd.
#include<syslog.h>voidintconstchar * message, ***);
The function takes a variable parameter (the second parameter, message, and the third argument ...). ) to structure the output.
Priority: Facility Value (bitwise XOR) log level. Facility value Default: Log_user, the following for the default facility value, discusses the log level.
#include<syslog.h>#define LOG_EMERG 0 //系统不可用#define LOG_ALERT 1 //报警,需要立刻采取动作#define LOG_CRIT 2 //非常严重的情况#define LOG_ERR 3 //错误#define LOG_WARNING 4 //警告#define LOG_NOTICE 5 //通知#define LOG_INFO 6 //信息#define LOG_DEBUG 7 //调试
1. The following function can change the default output mode of syslog and further structure the log contents
#include<syslog.h>void openlog(constcharintint facility);
(1) Ident: Specifies that the string will be added to the date and time of the log message, usually set to the name of the program.
(2) Logopt: To configure the behavior of subsequent syslog calls, it is preferable to bitwise XOR of the following values
#define LOG_PID 0x01 //日志消息包含PID#define LOG_CONS 0x02 //如果消息不能记录到日志文件,则打印到终端#define LOG_ODELAY 0x03 //延迟打开日志功能直到第一次调用syslog#define LOG_NDELAY 0x04 //不延迟
(3) Facility: Used to modify ysyslog default facility value
In addition, log filtering is also important, the program re-development phase may need to output a lot of debugging information, and after the release, we have to shut down these debugging information, the solution to this problem is not after the program is released, delete the debug code (may be used later), but to set up the log mask, Logs that have a log level greater than the log mask are ignored by the system.
2. The following function is used to set the log mask for the syslog.
#include<syslog.h>intint maskpri );
MASKPRI: Specifies the log mask value, which is always back to success, which returns the previous log mask value of the calling process.
3. Turn off log function:
#include<syslog.h>void closelog();
2. User Information
1.UID, Euid, GID, Egid
User information is important for server security, most of which says the server is root-initiated, non-root run
Tables |
| is
Get & Set |
Uid |
Real User ID |
Getuid ()/setuid (uid_t uid) |
Euid |
Valid User ID |
Geteuid ()/setuid (uid_t uid) |
Gid |
Real Group ID |
Getgid ()/setuid (gid_t GID) |
Egid |
Valid Group ID |
Getgeid ()/setuid (gid_t GID) |
Basic knowledge:
A process with two user IDs, UID, Euid, Euid exists for the purpose of facilitating access to resources, which allows the user running the program to have valid user rights for the program, for example, SU is used to change the account information, but the owner of the SU program when modifying the account is root, When a normal user runs the SU program, its valid user is the program's owner root, the process of effective user root is called the privileged process, egid and Euid Similar, the following demonstrates UID, Euid difference:
#include<stdio.h>#include<unistd.h>int main(){ uid_t uid = getuid(); uid_t euid = geteuid(); printf("uid is %d , euid is %d \n", uid, euid); return0;}
The resulting executable file, the owner is set to root, and the file Set-user-id flag is set and then run.
From the test output, the UID of the process is the user ID of the launcher, and Euid is root.
2. Switch Users
Static BOOLSwitch_to_user (uid_t user_id, gid_t gp_id) {if(user_id = =0) && (gp_id = =0))return false; gid_t gid = Getgid (); uid_t uid = Getuid ();if(GID! =0) || (uid!=0) && (gid! = gp_id) | | (uid = user_id)) )return false;if(UID! =0)return false;if((Setgid (gp_id) <0) || Setuid (USER_ID) <0))return false;return true;}
3. Inter-process Relations
1. Process Group:
Each process under Linux belongs to a process group, so they have a process group ID (pgid) In addition to the PID. We use the following function to get the specified process group Pgid.
#include<unistd.h>pid_d getpgid(pid_t pid);
successfully returned PID, failed-1, set errno.
If the PID is the same as Pgid, the process specified by the PID is set to the process group leader: If the PID is 0, the pgid of the current process is pgid, and if Pgid is 0, the PID is used as the target pgid. When the Setpid function succeeds, it returns 0, failure-1, setting errno.
A process can only set the pgid of itself or its child processes. Also, when a child process calls the Exec series function, we can no longer set Pgid to him in the parent process.
2. Session
(1) Some associated processes will compose a session, and the following function is used to create a session:
#include<unistd.h>pid_t setsid(void);
The function cannot be called by the process group's leader process, or an error will result. For non-boss processes, calling this function creates not only new sessions, but also the following additional effects.
The calling process becomes the leader of the session, when the process is the only member of the new session.
Create a new process group whose pgid is the PID of the calling process, and the calling process becomes the leader of the group.
The calling process will throw off the terminal (if any)
The function succeeds when returning a new process group Pgid, failed-1, errno.
The Linux process does not provide the concept of a so-called session ID, but the Linux system considers it equal to the pgid of the process group where the conversation leader resides,
(2) and provides the following function to read the SID
#include<unistd.h>pid_t getsid(pid_t pid);
3. Viewing process relationships with the PS command
Perform the PS command to view the relationships between processes, process groups, and sessions.
The PS and less commands are executed under Bash_shell, so the PS and less commands are the parent process when the Bash command, which can be seen from the ppid (parent process PID) column.
These three commands create a session (SID is 2962) and two process groups (pgid:2962, 3102) Bash command pid,pgid and Sid are the same, obviously it is the leader of the conversation, that is, the head of group 2962. PS when 3102 of the Chiefs,
4. System Resource Limitations
Programs running on Linux are affected by resource constraints, such as physical device limits (number of CPUs, amount of memory, etc.), System Policy restrictions (cup time, and so on), and specific implementation restrictions (maximum file name length) Linux system resource limits can be read and set by the following pair of functions:
Getrlimit, Setrlimit
#include<sys/resource.h>int getrlimit(intstruct rlimit * rlim);int setrlimit(intconststruct rlimit * rlim);
The RLIMIT structure is defined as follows:
struct rlimit{ rlim_t rlim_cur; rlim_t rlim_max;};
Successfully returned 0, failed-1, errno
rlim_t is an integer type that describes the resource level
rlim_cur members Specify the soft limit of resources, the recommended, preferably do not exceed the limits, if beyond, the system may send signals to the process and terminate the run, if the current process CPU time exceeds the soft limit, the system will send the SIGXCPU signal to the process When the file size exceeds its soft limit, the system sends a SIZEXFSZ signal to the process.
The Rlim_max member specifies a hard limit for the resource. The hard limit is generally the upper limit of the soft limit, the normal program can reduce the limit, and only the program running as root can increase the hard limit, in addition we can use the Ulimit command to modify the current Shell environment resource limit (soft/hard) This modification to the shell initiated by all subsequent programs are valid, We can also modify the configuration file to change the system soft limit and should be limited, and this modification is permanent.
The resource parameter specifies the resource restriction type. As the following table
Resource restriction Type |
meaning |
Rlimit_as |
Process virtual memory (in bytes) exceeding this limit will cause some functions (mmap) to produce enomen errors |
Rlimit_core |
The size limit (in bytes) of the process core dump file (in unit byte) with a value of 0 means that no core dump file is generated |
Rlimit_cpu |
Process CPU time limit (in seconds) |
Rlimit_data |
Process segment (data, BSS, heap) limit (per byte) |
Rlimit_fsize |
A file size limit (in bytes) that exceeds the limit will be a function (write) that produces a efbig error |
Rlimit_nofile |
A limit on the number of file descriptors that exceeds the limit will be some functions (such as pipe) producing mefile errors |
Rlimit_nproc |
The number of processes a user can create limits, exceeding which allows certain functions (such as fork) to produce eagin errors |
Rlimit_stack |
Process stack memory limit (in bytes) exceeding this limit will cause SIGSEGV signal |
5. Change the working directory and root directory
Some server programs need to change the working directory and root directory (WEB/VAR/WWW).
Gets the current process working directory and the function that alters the working directory of the process:
#include<unistd.h>char * getcwd(char * buf, size_t size);int chdir(constchar * path);
The memory pointed to by the BUF parameter is used to store the absolute path of the current working directory, size specifies its
If the absolute path of the current directory crosses (+1 (') ') exceeds size, then GETCWD returns Null,errno:erang.
The path in ChDir points to the directory you want to switch to. Success 0, Failure-1 errno.
Change process root directory:chroot
#include<unistd.h>int chroot(constchar * path);
Chroot does not change the current working directory of the process, after calling Chroot, it is still necessary to call ChDir ("/") to move the work to the new working directory, after which the original file descriptor is still in effect. So you can use the file descriptor that you opened earlier to access files (directories) that cannot be accessed directly after calling Chroot.
6. Daemon of server Programs
Finally, how to let a process in the code to prevent the daemon to run, the daemon is written to follow a certain step, the following instance.
BOOLDaemonize () {pid_t pid = fork ();//Create child process if(PID <0) {return false; }Else if(PID >0) {exit(0);//Parent process exits} pit_t sid = Setsid ();if(Sid <0) {return false; }if(ChDir ("/") <0)//change process working directory to root{return false; }//redirect output output, error output Close(Stdin_fileno);Close(Stdout_fileno);Close(Stderr_fileno); Open"/dev/null", o_rdonly); Open"/dev/null", O_RDWR); Open"/dev/null", O_RDWR);return true}
In fact, Linux provides library functions that perform the same functions:
#include<unistd.h>int deamon(intint noclose);
Nochdir: Pass 0 The working directory will be set to "/", otherwise continue to use the current working directory.
Noclose: Pass 0 standard input and output, standard error output is redirected to, Dev/null, otherwise continue to use original device, success 0, failure-1 error.
Finally, the summer vacation begins! Let ' s play!
Linux Server program specification