1. linux中fcntl()函数的使用
前面的这5个基本函数实现了文件的打开、读写等基本操作,这一节将讨论的是,在文 件已经共享的情况下如何操作,也就是当多个用户共同使用、操作一个文件的情况,这时,Linux 通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。
文件锁包括建议性锁和强制性锁。
建议性锁要求每个上锁文件的进程都要检查是否有锁存,并且尊重已有的锁。在一般情况下,内核和系统都不使用建议性锁。强制性锁是由内 核执行的锁,当一个文件被上锁进行写入操作的时候,内核将阻止其他任何文件对其进行读写操作。采用强制性锁对性能的影响很大,每次读写操作都必须检查是否有锁存在。
在 Linux 中,实现文件上锁的函数有lock和fcntl,其中flock用于对文件施加建议性锁,而fcntl不仅可以施加建议性锁,还可以施加强制锁。同时,fcntl还能对文件的某一记录进行上锁,也就是记录锁。
记录锁又可分为读取锁和写入锁,其中读取锁又称为共享锁,它能够使多个进程都能在文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个进程在文件的某个部分上建立写入锁。当然,在文件的同一部分不能同时建立读取锁和写入锁。
2. LINUX设置密码复杂度的文件/etc/pam.d/system-auth,具体需要怎么改
一、准备工作:
安装 PAM 的 cracklib 模块,cracklib 能提供额外的密码检查能力。
二、具体操作:
Debian、Ubuntu 或 Linux Mint 系统上:
代码如下:
$ sudo apt-get install libpam-cracklib
CentOS、Fedora、RHEL 系统已经默认安装了 cracklib PAM 模块,所以在这些系统上无需执行上面的操作。
为了强制实施密码策略,需要修改 /etc/pam.d 目录下的 PAM 配置文件。一旦修改,策略会马上生效。
注意:此教程中的密码策略只对非 root 用户有效,对 root 用户无效。
策略设置:
1、禁止使用旧密码
找到同时有 “password” 和 “pam_unix.so” 字段并且附加有 “remember=5” 的那行,它表示禁止使用最近用过的5个密码(己使用过的密码会被保存在 /etc/security/opasswd 下面)。
Debian、Ubuntu 或 Linux Mint 系统上:
代码如下:
$ sudo vi /etc/pam.d/common-password
password [success=1 default=ignore] pam_unix.so obscure sha512 remember=5
CentOS、Fedora、RHEL 系统上:
代码如下:
$ sudo vi /etc/pam.d/system-auth
password sufficient pamunix.so sha512 shadow nullok tryfirstpass useauthtok remember=5
二、设置最短密码长度
找到同时有 “password” 和 “pam_cracklib.so” 字段并且附加有 “minlen=10” 的那行,它表示最小密码长度为(10 - 类型数量)。这里的 “类型数量” 表示不同的字符类型数量。PAM 提供4种类型符号作为密码(大写字母、小写字母、数字和标点符号)。如果密码同时用上了这4种类型的符号,并且 minlen 设为10,那么最短的密码长度允许是6个字符。
Debian、Ubuntu 或 Linux Mint 系统上:
代码如下:
$ sudo vi /etc/pam.d/common-password
password requisite pam_cracklib.so retry=3 minlen=10 difok=3
CentOS、Fedora、RHEL 系统上:
代码如下:
$ sudo vi /etc/pam.d/system-auth
password requisite pam_cracklib.so retry=3 difok=3 minlen=10
三、设置密码复杂度
找到同时有 “password” 和 “pam_cracklib.so” 字段并且附加有 “ucredit=-1 lcredit=-2 dcredit=-1 ocredit=-1” 的那行,表示密码必须至少包含一个大写字母(ucredit),两个小写字母(lcredit),一个数字(dcredit)和一个标点符号(ocredit)。
Debian、Ubuntu 或 Linux Mint 系统上:
代码如下:
$ sudo vi /etc/pam.d/common-password
password requisite pam_cracklib.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-2 dcredit=-1 ocredit=-1
CentOS、Fedora、RHEL 系统上:
代码如下:
$ sudo vi /etc/pam.d/system-auth
password requisite pam_cracklib.so retry=3 difok=3 minlen=10 ucredit=-1 lcredit=-2 dcredit=-1 ocredit=-1
四、设置密码过期期限
编辑 /etc/login.defs 文件,可以设置当前密码的有效期限,具体变量如下所示:
代码如下:
$ sudo vi /etc/login.defs
PASSMAXDAYS 150 PASSMINDAYS 0 PASSWARNAGE 7
这些设置要求用户每6个月改变密码,并且会提前7天提醒用户密码快到期了。
如果想为每个用户设置不同的密码期限,使用 chage 命令。下面的命令可以查看某个用户的密码限期:
代码如下:
$ sudo chage -l xmolo
Last password change : Dec 30, 2013 Password expires :
never Password inactive : never Account expires :
never Minimum number of days between password change :
0 Maximum number of days between password change :
99999 Number of days of warning before password expires : 7
默认情况下,用户的密码永不过期。
五、下面的命令用于修改 xmolo 用户的密码期限:
代码如下:
$ sudo chage -E 6/30/2014 -m 5 -M 90 -I 30 -W 14 xmolo
上面的命令将密码期限设为2014年6月3日。另外,修改密码的最短周期为5天,最长周期为90天。密码过期前14天会发送消息提醒用户,过期后帐号会被锁住30天。
设置完后,验证效果如下:
3. 如何在Linux上使用命令行管理密码
passwd命令用于设置用户的认证信息,包括用户密码、密码过期时间等。系统管理者则能用它管理系统用户的密码。只有管理者可以指定用户名称,一般用户只能变更自己的密码。
语法 passwd(选项)(参数)
-d:删除密码,仅有系统管理者才能使用;
-f:强制执行;
-k:设置只有在密码过期失效后,方能更新;
-l:锁住密码;
-s:列出密码的相关信息,仅有系统管理者才能使用;
-u:解开已上锁的帐号
用户名:需要设置密码的用户名。
存放用户信息: /etc/passwd
/etc/shadow
存放组信息: /etc/group
/etc/gshadow
4. 操作系统,linux中 lockf(1,1,0);和 lockf(1,0,0); 是什么作用
ockf(fd,1,0)是给fd文件上锁,lockf(fd,0,0)是解锁,配合使用,实现进程的互斥。
头文件
#include <sys/file.h>
函数:
int lockf(int fd, int cmd, off_t len);
fd -- 文件id.
fcntl(2)的接口(inteface)函数
返回1表示调用lockf成功.
lockf用于锁定或打开锁定一个共享文件.
操作有:
F_LOCK(锁定),F_TLOCK,F_ULOCK(打开锁定),F_TEST
注意事项
lockf()函数允许将文件区域用作信号量(监视锁),或用于控制对锁定进程的访问(强制模式记录锁定)。试图访问已锁定资源的其他进程将返回错误或进入休眠状态,直到资源解除锁定为止。当关闭文件时,将释放进程的所有锁定,即使进程仍然有打开的文件。当进程终止时,将释放进程保留的所有锁定。
函数声明:
/* 'lockf' is a simpler interface to the locking facilities of 'fcntl'. LEN is always relative to the current file position. The CMD argument is one of the following. This function is a cancellation point and therefore not marked with __THROW. */
#include <unistd.h>
int lockf(int fd, int cmd, off_t len);
5. linux上flock用独占锁运行的shell脚本超时后,如何让它自动强制结束
大前提,你用的是bash,其他shell应该也有类似的任务管理功能,具体你自己去查。
简单说一下思路,假定你那个有 flock 的脚本叫 a.sh, 你不要直接在crontab中调用 a.sh,而是调用另外一个脚本,比如 main.sh,main.sh 应该长成这个样子
#!/bin/bash
#启动a.sh
/path/to/a.sh&
#每秒钟检查一下a.sh是否结束,如果结束,则退出当前进程,如果10秒钟后a.sh仍未结束,则kill掉它
for((x=0;x<10;x++));do
sleep1
#检查a.sh任务是否存在
jobs%12>/dev/null
if[$?-ne0];then
#a.sh已经结束
exit0
fi
done
#超时,kill掉a.sh
kill-9%1
如上面的注释,main.sh 后台启动 a.sh 后,在10秒内不断的检查这个任务是否还在运行,如果不在了,那说明 a.sh 已经结束了,那 main.sh 也可以结束。如果超时,则强行杀掉 a.sh。
6. python log 文件锁判断是否有锁
Python的文件锁目前使用的是fcntl这个库,它实际上为 Unix上的ioctl,flock和fcntl 函数提供了一个接口。
1.fcntl库的简单使用
[python] view plain
import fcntl
import os, time
FILE = "counter.txt"
if not os.path.exists(FILE):
# create the counter file if it doesn't exist
file = open(FILE, "w")
file.write("0")
file.close()
for i in range(20):
file = open(FILE, "r+") #由于flock生成的是劝告锁,不能阻止进程对文件的操作,所以这里可以正常打开文件
fcntl.flock(file.fileno(), fcntl.LOCK_EX) #为了避免同时操作文件,需要程序自己来检查该文件是否已经被加锁。这里如果检查到加锁了,进程会被阻塞
print 'acquire lock'
counter = int(file.readline()) + 1
file.seek(0)
file.write(str(counter))
print os.getpid(), "=>", counter
time.sleep(10)
file.close() # unlocks the file
print 'release lock'
time.sleep(3)
分别启动2个进程来同时运行这个脚本,我们可以很明显的看到2者互相之间交替阻塞。同一时刻只有一个进程能够对counter.txt文件进行操作。
2.对fcntl.flock()函数的说明:
linux的flock() 的函数原型如下所示:
int flock(int fd, int operation);
其中,参数 fd 表示文件描述符;参数 operation 指定要进行的锁操作,该参数的取值有如下几种:
LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有;
LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有;
LOCK_UN:表示删除该进程创建的锁;
LOCK_MAND:它主要是用于共享模式强制锁,它可以与 LOCK_READ 或者 LOCK_WRITE联合起来使用,从而表示是否允许并发的读操作或者并发的写操作;
通常情况下,如果加锁请求不能被立即满足,那么系统调用 flock()会阻塞当前进程。比如,进程想要请求一个排他锁,但此时,已经由其他进程获取了这个锁,那么该进程将会被阻塞。如果想要在没有获得这个排他锁的情况下不阻塞该进程,可以将LOCK_NB 和 LOCK_SH 或者 LOCK_EX 联合使用,那么系统就不会阻塞该进程。flock()所加的锁会对整个文件起作用。
注意:
1. 对于文件的 close() 操作会使文件锁失效;
2. 同理,进程结束后文件锁失效;
3. flock() 的 LOCK_EX是“劝告锁”,系统内核不会强制检查锁的状态,需要在代码中进行文件操作的地方显式检查才能生效。
7. linux强制锁和自旋锁的关系
没听过linux有强制锁。
与自旋锁有点相似的是互斥量。它们都是为了解决对某项资源的互斥使用。同一时间,只能有一个线程或进程持有资源。
自旋锁特点:当资源被锁住时,它会反复的去看锁是否被释放,一直占用CPU。属于忙等待。
互斥量特点:当资源被锁住时,它会调用调度函数把CPU使用权释放给其他进程。
8. linux系统 在安装jdk时总是出现E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) 怎么办
解决办法如下:
1。终端输入 ps -aux ,列出进程。找到含有apt‘-get的进程,直接sudo kill PID。解决。
2。强制解锁,命令
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock
9. linux用户登录三次被锁了,这设置在哪配置的.
锁用户的设定
/etc/pam.d/下包含各种认证程序或服务的配置文件。编辑这些可限制认证失败次数,当失败次数超过指定值时用户会被锁住。
在此,以run
level为3的时候,多次登录登录失败即锁用户为例:
在/etc/pam.d/login文件中追加如下两行:
auth
required
/lib/security/pam_tally.so
onerr=fail
no_magic_root
account
required
/lib/security/pam_tally.so
deny=3
no_magic_root
reset
deny=3
设置登录失败3次就将用户锁住,该值可任意设定。
如下为全文见设定例:
auth
required
pam_securetty.so
auth
required
pam_stack.so
service=system-auth
auth
required
pam_nologin.so
auth
required
pam_tally.so
onerr=fail
no_magic_root
account
required
pam_stack.so
service=system-auth
account
required
pam_tally.so
deny=3
no_magic_root
reset
password
required
pam_stack.so
service=system-auth
session
required
pam_stack.so
service=system-auth
session
optional
pam_console.so
这样当用户在run
level=3的情况下登录时,/var/log/faillog会自动生成,裏面记录用户登录失败次数等信息。
可用"faillog
-u
用户名"命令来查看。
当用户登录成功时,以前的登录失败信息会重置。
2)用户的解锁
用户因多次登录失败而被锁的情况下,可用faillog命令来解锁。具体如下:
faillog
-u
用户名
-r
此命令实行后,faillog里记录的失败信息即被重置,用户又可用了。
关于faillog的其他命令。。参见man
failog。
二:手动锁定用户禁止使用
可以用usermod命令来锁定用户密码,使密码无效,该用户名将不能使用。
如:
usermod
-L
用户名
解锁命令:usermod
-U
用户名
......
要想强制用户下次登录更改密码就使用chage
-d
0
username
强制把上次更改密码的日期归零.
定义用户密码变更天数在/etc/shadow
这个文件中定义
对新建的用户在/etc/login.defs这个文件中定义
10. Linux下怎么创建锁文件及相关命令
方法 锁文件仅仅是充当一个指示器的角色,程序间需要通过相互协作来使用它们。锁文件只是建议性锁,与此对立的是强制性锁。 为创建一个用作指示器的文件,我们使用带O_CREATE和O_EXCL标志的open系统调用。这将使我们以一个原子操作同时完成两项工作:确定文件不存在,然后创建它。 实现 //file : lock.c #i nclude #i nclude #i nclude #i nclude #i nclude int main() { int file_desc; int save_errno; file_desc = open(/tmp/LockFile.test, O_RDWR O_CREAT O_EXCL, 0444); if (file_desc < 0) { save_errno = errno; printf(Open failed with error is %dn, save_errno); } else { printf(Open succeededn); } exit(EXIT_SUCCESS); } 第一次运行程序: $ lock 输出如下: Open succeeded 我们再次运行程序: $ lock 输出如下: Open failed with error is 17 分析: 第一次运行程序时,由于文件并不存在,所以执行成功。对于后续的执行,因为文件已经存在而失败了。若想程序再次执行成功,必须删除锁文件。 在Linux系统中,通常错误号码17代表的是EEXIST,此错误用以表示一个文件已存在。错误号定义在头文件errno.h或(更常见的)它所包含的头文件中。