Linux 服务器程序规范——《Linux高性能服务器编程》第7章——读书笔记

1、概述

在这里插入图片描述

2、日志

2.1 Linux 系统日志

Linux使用一个守护进程(后台进程)rsyslogd来处理系统日志。

Linux系统产生的日志大概可以分为两种,内核日志 和 用户进程输出的日志。

  • ① 用户进程调用syslog函数生成(系统)日志,该函数把日志输出到/dev/log文件中,rsyslogd监听该文件 并获取用户进程的输出,把他们输出到特定的日志文件(/var/log/*文件)。
  • ② 内核日志由printk等函数打印至内核的环状缓存中,环状缓存的内容直接映射到/proc/kmsg文件中。rsyslog通过读取该文件获得内核日志,把他们输出到特定的日志文件(/var/log/*文件)。
    在这里插入图片描述

2.2 syslogopenlogcloselog函数

① 用途

记录日志。Linux C提供一套日志写入接口,就是他们仨。
openlog可选的,若不调用openlog,则在第一次调用syslog时,自动调用openlogcloselog也是可选的,它用于关闭syslog日志功能(关闭与syslog守护进程通信的描述符)。

openlog函数

openlog用于打开一个到系统日志记录程序的连接,打开之后就可以用syslog向系统日志里添加信息了。此外,该函数还能改变syslog的默认输出方式(其facility参数)。而closelog就是用于关闭此连接。openlog定义如下:

#include<syslog.h>
void openlog(const char* ident, int logopt, int facility);
  • ident所表示的字符串通常就是当前程序的名字,它固定的加在每行日志消息的日期和时间之后,以作为标记。调用openlog指定一个ident后,此ident会被加到每行日志消息中。
  • logopt参数对后续调用的 syslog函数的行为进行控制(或配置),它可取下列值的按位或与在这里插入图片描述
  • facility指明记录日志的程序(后续的syslog函数)的类型。
    另一种解释:facility参数用来修改syslog函数中的默认设施值。
    我们在讨论syslog函数的时候讨论设施值的含义及其具体取值。

syslog函数

开启日志功能。syslog函数用于把日志消息发送给系统程序rsyslogd去记录。也就是:用于程序使用syslog函数rsyslogd守护进程通信syslog函数的定义如下:

#include<syslog.h>
void syslog(int priority, const char* message, ...);	该函数采用可变参数(第二个'message'和第三个参数'...'
  • priority表示消息的紧急级别。它的值是设施值日志级别按位或与。其中,设施值的默认值是LOG_USER ,下面的讨论也只限于这一种设施值。日志级别的值如下:在这里插入图片描述
  • 第二个参数是一个格式化表达式,第三个参数是格式化表达式对应的参数,两个参数共同结构化输出。(这两个参数的关系,就类似于printf函数的两个参数那样)

closelog函数

#include<syslog.h>
void close();

关闭日志功能。

⑤ 日志过滤——setlogmask函数

在这里插入图片描述

3、用户信息

什么是用户ID,什么是组ID
其他用户:陌生的用户,不属于当前的用户组。

3.2 UID、EUID、GID 和 EGID 都是啥

① UID:实际用户ID

登陆时候的ID。当一个用户登陆到这个系统后就唯一确定了他的UID。(实际用户组ID类似)
该值在login函数执行时,取自口令文件/etc/passwd中,一般由用户标识号(第三列)标识。这个ID在登陆期间一般不会改变,除非有root权限用setuid改变。

② EUID:有效用户ID

有效ID就是用于权限检查的ID

③ GID:实际组ID

一个用户登录时其所属的组ID。

④ EGIO:有效组ID

有效组ID就是用于权限检查的组ID

3.3 获取和设置当前进程的 上面四种ID

在这里插入图片描述

3.4 特权进程

有效用户为root的进程称为特权进程。

3.5 set-user-id标志

这个标志表示,任何普通用户运行 设置了该标志的程序时,其有效用户就是该程序的所有者

sudo chmod +s 文件名			设置文件的 set-user-id 标志

4、切换用户

下面的代码将以root身份启动的进程切换为 普通用户身份运行:

static bool switch_to_user(uid_t user_id, git_t gp_id)
{
	/* 先确保目标用户不是root */
	if (user_id == 0 && gp_id == 0)
	{
		return false;
	}
	
	/* 确保当前用户是合法淞沪:root 或者目标用户 */
	git_t gid = getgid();
	uid_t uid = getuid():
	if ((gid != 0 || uid != 0) && (gid != gp_id || uid != user_id))
	{
		return false;
	}

	/* 如果不是root,则已经是目标用户*/
	if (uid != 0)
	{
		return true;
	}

	/* 切换到目标用户 */
	if (setgid(gp_id) < 0 || setuid(user_id) < 0)
	{
		return false;
	}
	return true;
}

这个代码等以后用到的时候再来看吧,现在不明所以,先不管了。

5、进程间关系

5.1 进程组

在这里插入图片描述

在这里插入图片描述

5.2 会话

在这里插入图片描述
在这里插入图片描述

5.3 用ps命令查看进程关系

在这里插入图片描述

6、系统资源限制

Linux上运行的程序都会受到资源限制的影响,比如物理设备闲置(CPU数量、内存数量等)、系统策略限制(CPU时间等),以及具体实现的限制(比如文件名的最大长度)。Linux系统资源限制可以通过如下一对函数来读取设置

#include<sys/resource.h>
int getrlimit(int resource, struct rlimit* rlim);
int setrlimit(int resource, const struct rlimit* rlim);

rlim参数是指向rlimit结构体类型的指针,rlimit结构体定义如下:

struct rlimit
{
	rlim_t rlim_cur;
	rlim_t rlim_max;
};

在这里插入图片描述

7、改变工作目录 和 根目录

在这里插入图片描述

获取进程当前工作目录改变进程工作目录的函数分别是:

#include<unistd.h>
char* getcwd(char* buf, size_t size);
int chdir(const char* path);
getcwd

参数:
buf参数指向的字符串 存储了进程当前工作目录的绝对路径名,其大小由size参数指定

  • ——若绝对路径长度(还要加上空字符\0超过了size,则getcwd返回NULL,并设置errnoERANGE
  • ——若 buf为NULL,并且 size非0,则getcwd可能在内部使用malloc动态分配内存,并将当前工作目录的绝对路径存在其中。如果是这种情况,我们必须自己释放getcwd在内部创建的这块内存

返回值:
getcwd函数成功时返回一个指向目标存储区的指针buf指向的缓存区或是getcwd动态创建的缓存区),失败返回BULL并设置errno

chdir

chdir函数的path参数指定要切换到的目标目录。成功时返回0,失败返回-1并设置errno

改变进程根目录的函数是chroot

#include<unistd.h>
int chroot(const char* path);

path参数指定要切换到的目标根目录。成功返回0,失败返回-1并设置errno
在这里插入图片描述
chroot就是把当前程序所在的路径整个 直接变成新的根目录。举个例子:现在有个.c源文件,他的路径是/home/xl22/桌面/trash/chroot.c,其中trash目录的其他内容如下:

.
|-- chroot.c
|-- chroot.out
`-- test
    `-- 111.txt

文件111.txt的路径是:/home/xl22/桌面/trash/test/111.txt
如果在chroot.c中进行了如下调用:

chroot("./test");

那么新的111.txt的路径变为:/111.txt,也就是包括test在内的前面多有路径一起被替换为了根目录,即/

如果只想把test文件夹之前的部分更改为根目录,那么chroot.c文件中的调用如下:

chroot("./");

注:使用chroot函数的程序必须是特权进程,否则该函数会调用失败,所以,当该函数调用失败的时候先检查你有没有超级权限。

8、服务器程序后台化

在这里插入图片描述
在这里插入图片描述
上面的函数能够让一个程序在后台运行
Linux提供了完成同样功能的函数:

#include<ubistd.h>
int deamon(int nochdir, int noclose);
  • nochdir参数用于指定是否改变工作目录。
    ——若给他传递0,则工作目录被设置为根目录/,否则继续使用当前工作目录。
  • noclose参数为0时,标准输入、标准输出和标准错误输出都被重定向到dev/null文件,也就是不输出任何信息,否则仍然照样输出。

deamon调用了fork,如果fork成功,那么父进程就调用_exit(2)退出,所以看到的错误信息 全部是子进程产生的。
deamon如果成功返回0,失败返回-1并设置errno

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值