Рейтинг@Mail.ru

Наши друзья и партнеры

купить дешевый 
компьютер родом из Dhgate.com






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Linux System Administrator's Survival Guide lsg33.htm

Previous Page TOC Next Page



Chapter 33


NFS and NIS


Network File System (NFS) has a reputation for being difficult to set up and install. The truth is that NFS is quite easy to implement on Linux systems, and if your machine is one of a few Linux systems on a local area network (LAN), NFS can give you enormous flexibility.

This chapter explains the benefits of NFS, and how you can set up your system to act as both a client and server for other machines on your LAN. If you are running as a stand-alone Linux machine, NFS will be of no value (other than academic) to you, but if you are part of a LAN (whether composed of PC, Mac, UNIX, or Linux machines doesn't matter), you should at least find out what NFS has to offer.

The second part of this chapter looks at the Network Information Service (NIS), an early version of which was previously called Yellow Pages, and how it works over a network. Although you probably will not need NIS unless you are part of a very large network, you can see how the system works. The chapter also looks at some system administration tools for managing NFS (Network File System), NIS (Network Information Service), and RPC (Remote Procedure Call).

What Is NFS?


NFS was developed to help solve a common problem on UNIX-based networks. With the trend to distributed processing and client-server networks, many users end up with small, powerful machines that communicate with a server. The applications users need are often located in places other than on their desktop, so some method of accessing remote files is needed. Although utilities such as Telnet enable users to use remote machines, they don't take advantage of the desktop machine's CPU, transferring the load to the remote. Another important aspect of the shift to distributed computing was peripheral sharing and the need to provide access for many users to some devices. To help integrate workstations into local area networks, as well as to simplify remote file access and peripheral sharing, Sun Microsystems introduced the Network File System (NFS). NFS uses a system called RPC (Remote Procedure Calls).

Sun designed NFS to enable machines from different manufacturers to work together independent of their operating systems. By publishing the NFS specifications, Sun allowed other vendors to modify their systems to work with NFS, resulting in a completely homogeneous network. NFS is now a de facto standard among UNIX environments, with strong support in other operating systems.

NFS actually refers to two different things: a product and a protocol. The NFS product is a set of protocols for different tasks. The NFS protocol is the single protocol of the NFS product that deals with file access. NFS is now intimately tied with UNIX and TCP/IP. For other operating systems (such as Novell NetWare), NFS is an extension that is added by the system administrator. Linux (and most UNIX versions) uses the process nfsd to manage NFS access.

NFS allows an application to read and write files that reside on NFS servers. Access to the NFS server is transparent to the application and the user. Transparent access to another machine's file structure is achieved by logically mounting the NFS server to the client. You can mount the NFS server's filesystem in whole or in part. The mount is handled in the same way as any other filesystem mount (see Chapter 18, "Filesystems and Disks," for information on the mount command), although a special keyword is added to the command to show that NFS is being used. For example, to mount the directory /usr/database/data on the remote machine wizard onto your directory /usr/data, you would issue the following command:


mount -t nfs wizard:/usr/database/data /usr/data

When the command is issued, the local machine checks with the remote machine for permission to access the directory. If all is well, the remote machine sends a file handle that is used to redirect all requests for that directory from the local machine. Whenever the user of an NFS-mounted directory issues a request, a daemon called nfsd handles the transfers.

NFS uses the term client to represent any machine that requests a file from another machine, which is the server. Multitasking operating systems can act as both client and server simultaneously. Usually, restrictions are imposed on the files or portions of a filesystem that can be shared, both for security and speed considerations.

A typical NFS installation uses personal computers or diskless workstations as clients accessing a powerful server system. (Since personal computer operating systems such as MS-DOS are single-tasking, PCs usually act as clients only, unless they run a multitasking operating system such as Windows NT, Windows 95, or OS/2.) For Linux-based networks, you can have several Linux systems sharing their drives with other machines on the network. It is possible to have an entire network of multitasking computers sharing their drives with each other, although in practice this works well only with small networks.

Due to the requirement transferring files quickly with NFS, network speed becomes important. When it was designed, the original goal for an NFS-mounted filesystem was to provide performance equivalent to 80 percent of the performance expected from a locally mounted hard disk. This goal puts the performance emphasis on both the NFS disk drive and the network. Typically, NFS disk drives on a dedicated server are amongst the fastest available in order to reduce bottlenecks at the drive end. In practice for most networks, the NFS systems use standard equipment, which isn't a problem for sharing a few directories among a small network.

Typically, for a small Linux network, NFS offers a few useful benefits. Primarily, it allows data and large applications to be kept on a single drive on the network that all other machines have access to (hence saving the disk space independent copies would require). For a system administrator, NFS offers the option of keeping applications in one location (or even placing all user directories on one machine) for ease of updating, backups, and management.

The Linux version of FTP differs slightly from the standard UNIX versions, in that many of the features of the NFS system are embedded in the code for the Virtual File System (VFS) kernel layer. Early versions of Linux have a problem with Linux FTP because of the maximum size of TCP datagrams, which must be reduced in size to function properly. This had the effect of slowing performance dramatically.

Because NFS is UNIX-based, the security offered is rudimentary. For this reason, Sun has introduced Secure NFS, which implements an encrypted messaging protocol for added protection against unauthorized access to NFS-mounted file systems. This version is not available in a Linux implementation yet.

Installing NFS


The first step to installing NFS on your Linux system is to ensure that the NFS support is compiled into the kernel. Most later Linux versions have this by default, but if you are running an early version you should verify the NFS code. Versions of Linux after 1.1 can confirm support for NFS by examining the /proc/filesystems file. An entry in this file should show nfs with the command nodev. An extract from the /proc/filesystems file looks like this:


 minix

 ext2

 umsdos

 msods

nodev proc

nodev nfs

 iso9660

The second line from the bottom shows that the NFS code is included in the kernel. If the NFS code is not included, you will have to rebuild the kernel including the NFS drivers.

Versions of Linux before 1.1 are more difficult to easily check for NFS code. The best way to perform the check is to try to mount an NFS directory. If it fails, it is likely the NFS code is missing (assuming the mount commands are correct, of course). As a fast check, you can mount a local directory onto your own machine (which is perfectly legal with all versions of NFS, although it can be confusing at times). To perform this check, create a new subdirectory and issue the mount command with an existing directory. For example, these commands try to mount /usr on the empty directory /tmp/nfstest:


mkdir /tmp/nfstest

mount localhost:/usr /tmp/nfstest

If the mount command is successful (you can go into the /tmp/nfstest directory and examine the same file listing as in /usr), your kernel has the NFS code embedded in it. If you get an error message similar to this:


fs type nfs not supported

then the NFS code is missing and you should rebuild a new kernel with the NFS drivers added.



<NOTE>When you perform this NFS code check you may see many error messages. The only message that matters is nfs not supported. The rest of the messages have to do with the lack of NFS configuration.<NOTE>

The NFS daemons need to be set up on your system. If you are going to act as an NFS server (allow your directories to be mounted by others), you must install both the nfsd and mountd daemons. These daemons start when your machine boots, reading the rc files. Both daemons need the program rpc.portmap to function because they both register themselves with the portmapper utility.

The startup commands for the daemons usually are placed in the /etc/rc.d/rc.inet2 file (or wherever you have installed the rc files). Most newer versions of Linux will have the proper section already in the /etc/rc.d/rc.inet2 file. For example, the section dealing with NFS will look much like this:


# # Start the various SUN RPC servers.

if [ -f ${NET}/rpc.portmap ]; then

 # Start the NFS server daemons.

 if [ -f ${NET}/rpc.mountd ]; then

 echo -n " mountd"

 ${NET}/rpc.mountd

 fi

 if [ -f ${NET}/rpc.nfsd ]; then

 echo -n " nfsd"

 ${NET}/rpc.nfsd

 fi

# # Fire up the PC-NFS daemon(s).

# if [ -f ${NET}/rpc.pcnfsd ]; then

# echo -n " pcnfsd"

# ${NET}/rpc.pcnfsd ${LPSPOOL}

# fi

# if [ -f ${NET}/rpc.bwnfsd ]; then

# echo -n " bwnfsd"

# ${NET}/rpc.bwnfsd ${LPSPOOL}

# fi

fi # Done starting various SUN RPC servers.

If your inet2 file doesn't have any lines similar to these, find a location below the rpc.portmapper startup command. The portmapper startup section will look similar to this:


# Start the SUN RPC Portmapper.

if [ -f ${NET}/rpc.portmap ]; then

 echo -n " portmap"

 ${NET}/rpc.portmap

fi

Below these lines, enter the following commands to start the rpcd and mountd daemons:


 if [ -x /usr/sbin/rpc.mountd ]; then

 echo -n " mountd"

 /usr/sbin/rpc.mountd

 fi

 if [ -x /usr/sbin/rpc.nfsd ]; then

 echo -n " nfsd"

 /usr/sbin/rpc.nfsd

 fi

If the rpc.nfsd and rpc.mountd daemons are not in /usr/sbin, enter the proper pathnames. These lines don't make use of a prior defined path. The paths to the deamons should be explicitly specified.

The next step in configuring your system for NFS server duty is to set up a file listing all the clients who can attach to your system and mount directories. This is done through the /etc/exports file. The /etc/exports file is read every time the mountd daemon receives a request to mount a directory. The file contains a list of directories that you want to allow to be mounted, and the remote systems that can mount them followed by a permission indication.

The best way to explain the /etc/exports file is to examine a sample. The following file shows several systems allowed to mount directories on the local machine:


# /etc/exports for merlin

/usr/database/data chatton(rw) big_roy (rw) wizard (rw)

/usr/book chatton(rw) wizard (ro)

/usr/bin/bigapp big_roy(rw) wizard (ro)

/usr/ftp (ro)

This file shows that the three machines chatton, big_roy, and wizard can all mount the local directory /usr/database/data in read-write mode (meaning they can modify the contents). The directory /usr/book can be mounted read-write by remote machine chatton, and read-only (no writing allowed) by wizard. The /usr/ftp directory can be mounted read-only by any machine that wants to.

When you are specifying machine names in the /etc/exports file, you can use explicit names, or a combination of asterisk and question mark wildcards to match multiple machines. For example, the entry


/usr/tim/book big_*(rw)

allows any machine starting with big_ to mount the directory as read-write. When no hostname is provided (as with the /usr/ftp directory in the previous example), any machine can mount the directory.

The /etc/exports file allows a long list of possible permissions for a remote machine to mount a local directory. Although most systems use only rw and ro (for read-write and read-only respectively), you may need more permissions occasionally. The following are valid permissions:

      insecure Allows non-authenticated access for the specified machine (overrides authentication requirements)

      kerberos Forces Kerberos authentication from the remote (not implemented for Linux NFS)

      link_absolute Leaves symbolic links as they are

      link_relative Converts absolute symbolic links to relative links by prepending ../ as necessary

      root_squash Denies root users on remote machines root access on local machine

      secure-rpc Forces RPC authentication from the remote (on by default, although not implemented in most Linux NFS versions)

How does NFS handle file and user permissions across mountings? When the NFS daemon transfers files or requests, it passes the user and group ID numbers. If the client and the server have the same user and group ID numbers (called sharing the same uid/gid space), there is no problem with permissions. When the UID and GID numbers do not match, the daemon can handle translations between them.

Mounting NFS Directories


Once NFS is configured, you can use it to mount remote directories on your local filesystem. This is done with the mount command. The general format of the mount command when dealing with NFS is


mount -t nfs remote_dir local_dir [-o options]

where remote_dir is the name of the remote machine and directory to be NFS mounted, local_dir is where you want to mount the remote directory, and options can be any of the permissible flags used by NFS. The remote_dir is always specified by the format


remote_name:remote_dir

such as wizard:/usr/lib. Many administrators leave off the -t nfs component of the mount command since this format is unique to NFS. Others feel it is good practice to leave the -t option in as it is a constant reminder that the remote is NFS mounted.

Although many options are possible for the mount command in NFS mode, only a few are ever used in real situations. You can select valid options from the following list:

hard This option explicitly tags the directory as hard-mounted. This is a default action.
intr This option allows interrupts to the NFS call.
rsize This option specifies the datagram size used for read requests (default is 1024 bytes).
soft This option soft-mounts the directory (instead of hard mounting).
timeo This option specifies the timeout in tenths of a second for completion of an NFS request (default is 7/10ths).
wsize This option specifies the datagram size used for write requests (default is 1024 bytes).

The rsize, timeo, and wsize options are followed by an equal sign and the value they are to be assigned. The rsize and wsize options are used primarily to switch the remote machine to another datagram size (in case it uses a larger size than Linux can handle). All NFS options must follow the -o switch on the command line, if the options are set there. For example, to set the timeout to 2 seconds on the remote mount of a directory and allow interrupts, you could issue the command:


mount -t nfs wizard:/usr/data /usr/data -o timeo=20,intr

Alternatively, if you don't want to specify the options on the command line for frequently mounted volumes, you can use the /etc/fstab file to provide them. The same command line as above can be placed in the /etc/fstab file like this:


wizard:/usr/data /usr/data nfs timeo=20,intr

When you use the /etc/fstab file to specify options and mount points, you can mount the remote volume much more easily by issuing the command:


mount wizard:/usr/data

The mount command examines the /etc/fstab file for the mount point and options to use, as well as recognizes the command as an NFS mount. For remote directories you will need often, this command is much easier than typing the entire command line every time.

Two of the NFS mount options deal with hard and soft mounting. The default with NFS is to hard mount a directory. What this means is that if NFS is unable to mount a requested volume, it times out, generates an error message, and tries again with double the timeout value. This goes on forever until the remote directory is mounted (generating error messages each time a timeout occurs). Any remote directory that is repeatedly tried until successfully mounted is called a hard mount. A soft mount is one that acts the same way but generates error messages only after a major timeout, which is every 60 seconds. The error messages are not displayed, since they are in the I/O queue, but you can usually gain control of the system more easily with a soft mount after a major timeout.

NFS Administration


NFS (and RPC, which NFS depends on) has two primary administration tools available for providing status updates and indications of trouble within the system. Running any single tool is usually not sufficient to isolate a problem. It often happens that one tool reports a problem with a port, but, upon closer examination, you find out that the port is functioning and the process at the other end has died. Therefore, these tools are designed to be used as a complement to each other until an accurate diagnosis can be produced.

rpcinfo


The rpcinfo program monitors the port mapper of the machine on which it is running and, through the network, the port mappers of servers. Because the port mapper is the program that controls access to RPCs, this type of information is important in tracking problems. The rpcinfo program can display the contents of the mapping tables, showing the port and program numbers for each connection, and is able to activate remote servers for testing a connection.

Typically, rpcinfo is called with the -p option to show the list of RPC programs that are currently tracked by the port mapper. An optional machine name can be added to display only connections with one machine. A typical output from the rpcinfo program is shown below:


$ rpcinfo -p

 program vers proto port

 100000 2 tcp 111 portmapper

 100000 2 udp 111 portmapper

 100008 1 udp 1026 walld

 150001 1 udp 1027 pcnfsd

 150001 2 udp 1027 pcnfsd

 100002 1 udp 1028 rusersd

 100002 2 udp 1028 rusersd

 100024 1 udp 1029 status

 100024 1 tcp 1024 status

 100020 1 udp 1034 llockmgr

 100020 1 tcp 1025 llockmgr

 100021 2 tcp 1026 nlockmgr

 100021 1 tcp 1027 nlockmgr

 100021 1 udp 1038 nlockmgr

 100021 3 tcp 1028 nlockmgr

 100021 3 udp 1039 nlockmgr

In case of a problem contacting the port mapper, rpcinfo returns an error message. In such a case, the port mapper is not functioning correctly and there may be no contact with other machines. A check using ping will verify this. An example of this kind of fatal error message is:


$ rpcinfo -p

rpcinfo: can't contact port mapper:

RFC: Remote system errer -125

Specific connections can be tested with rpcinfo by using the machine and process name, as the following example shows:


$ rpcinfo -u merlin walld

program 100008 version 1 is ready and waiting

Note that the -u option is used for UDP connections, while -t must be used with TCP connections. In this example, the client rpcinfo sent a request to the program specified and waited for a reply. A successful reply results in the message shown above. If a reply is not received before a timer expires, an error message is displayed.

In the sample output above, there is a process called pcnfsd, which is an RPC server developed for use with DOS-based machines. It handles access rights and spooling services for the DOS side, while simplifying the DOS machine's access to NFS services.

nfsstat


The nfsstat program, as its name suggests, provides statistics about the number and type of RPC requests that are made. Although this command is usually called without an option, several options exist (depending on the implementation and version) to show specific statistics or sample only certain parts of the connection. The nfsstat program is not part of most Linux distributions, but you can find it on some Linux FTP and BBS sites and as part of some system administration utility packages. The output from nfsstat is shown below for a typical small network:


Server rpc:

calls badcalls nullrecv badlen xdrcall

10465 0 0 0 0

Server nfs:

calls badcalls

10432 0

null getattr setattr root lookup readlink read

1 0% 24 0% 1 0% 0 0% 10123 0% 0 0% 5 0%

wrcache write create remove rename link symlink

0 0% 2 0% 0 0% 1 0% 0 0% 1 0% 0 0%

Client rpc:

calls badcalls retrans badxid timeout wait newcred

8273 2 0 0 0 0 0

Client nfs:

calls badcalls

8263 0

null getattr setattr root lookup readlink read

1 0% 24 0% 1 0% 0 0% 10123 0% 0 0% 5 0%

wrcache write create remove rename link symlink

0 0% 2 0% 0 0% 1 0% 0 0% 1 0% 0 0%

The output from nfsstat is useful for diagnosing connection problems. The number shown as badcalls shows the number of defective RPC messages processed by the system. The numbers for nullrecv and badlen show the number of empty or incomplete messages. The number for xdrcall shows the number of errors in understanding messages.

For the client side, badxid shows the number of received messages that did not match with a sent request (based on the identification numbers). The timeout and retrans numbers show the number of times a message had to be resent. If these numbers are high it usually means the connection is too slow or there is a fault with UDP. The wait number shows the number of times a process had to be delayed due to a lack of available ports.

These types of statistics are useful for configuring RPC properly. System administrators can adjust (tweak) values for the NFS system and monitor their effect on performance over time.

What Are NIS and YP?


The Yellow Pages (YP) protocol is an RPC application service (like NFS) that provides a directory service. Due to copyright requirements, Yellow Pages was renamed to Network Information Service (NIS), although both terms are in common use and mean much the same thing. YP was developed for several reasons, but the one that affects users the most is access permissions.

If you are a user on a large network and you connect to other machines (through Telnet or FTP, for example), you must maintain accounts on each machine you connect to. You therefore would need user accounts on every machine you could conceivably want to access. Maintaining the passwords on a large number of machines is awkward, because you must log in to each one to perform password changes. Yellow Pages was developed to allow one central password file to be shared over the network.

NIS is a distributed access system in that each machine on the network that uses NIS accesses a central server, called the NIS master or ypmaster, for access permission. On larger networks, a number of other machines can be designated as slaves or ypslaves, maintaining up-to-date access information. In case of a failure of the master server, a slave takes up the validation functions.



<NOTE>Two versions of YP or NIS are in general use. The first release (Version 1) had serious problems under certain circumstances, so Version 2 was quickly released. However, some systems use the older version.<NOTE>

The YP or NIS protocol (both names are valid, although NIS should be used if you have a choice) has a set of procedures that allow a search for master servers, access to the user files, and system management functions. Another procedure is used to transfer copies of master access files. With NIS, a number of machines are grouped together into one NIS subnetwork called a "domain" (not to be confused with the Internet domain). Each domain has master and slave machines of their own.

NIS keeps access information in a set of "maps," each map corresponding to a particular area or domain of a network. This allows several groups to use the same NIS master but have different access permissions. The NIS maps do not have to correspond to DNS domains, which allows more versatility in configuration. Maps consist of a set of records in ASCII format, each with an index for fast lookup (the index is usually the user name). The records have the same structure as a normal /etc/passwd file), for compatibility and simplicity.



<NOTE>The use of NIS does not negate the need for a complete set of access files on each machine, since NIS or YP is loaded after the machine has been booted. The stand-alone files should have access for a system administrator at least, although it is good practice to also include the most frequent users in case of a network crash preventing access to the NIS directories.<NOTE>

NIS is not restricted to just users. Any file can be set up to use NIS, such as the list of machines on a network (/etc/hosts file). Thus, only one change needs to be made to these files on any network. A set of aliases can also be managed by NIS or YP.

Several YP/NIS-specific commands are involved with the protocol, although most system administrators set up aliases to minimize the impact on users. For most users, only one command is necessary on a regular basis: yppasswd to change a password. This is usually aliased to passwd, the normal password change command.

Some implementations of NIS for Linux are better than others. A new release is appearing, called NYS, that offers the most flexibility. NYS (or an earlier version of one of the Linux NIS versions) is included with most CD-ROM distributions of Linux.

Installing NIS


NIS has two components: the server and the client. If an NIS server is already on your network, you need only to install the client portions. However, to set up a Linux server system, you need both.

You can choose between two NIS server products currently in general distribution for Linux: ypserv and yps. The choice of which server to use is not important, since both provide complete services. If anything, though, the ypserv system has a slightly better security system than yps. You can obtain the NIS software from Linux FTP and BBS sites.

To install either server program, copy it to /usr/sbin (or some other commonly accessed binary file location). Next, create a directory specifically to hold the map files for your domain (remember, that's an NIS domain, not an Internet domain). Usually, the map files go in a directory such as /var/yp/tpci (the last component of the pathname is the name of your domain).

Your NIS server can support several map files. In general, the files are mirrors of standard Linux files, but named to reflect whether they are accessed by name or by some other criteria (such as IP address or user name). For example, there are two copies of the /etc/passwd file maintained by NIS: passwd.byname and passwd.byuid. The following files are handled by NIS and their corresponding maps:

/etc/group group.byname, group.bygid
/etc/hosts hosts.byname, hosts.byaddr
/etc/networks networks.byname, networks.byaddr
/etc/passwd passwd.byname, passwd.byuid
/etc/protocols protocols.byname, protocols.bynumber
/etc/rpc rpc.byname, rpc.bynumber
/etc/services service.byname, services.bynumber

All these map files are stored in a format called DBM (a simple database program). Linux systems often include a GNU version of DBM called gdbm.

If you are using ypserv, use the ypMakefile utility to build the database files for NIS. Copy the file to the directory containing the map files, rename it to Makefile, and edit it to show the maps you want on your domain. This is handled by one of the first few lines, which looks like this:


all: hosts networks protocols rpc services passwd group

Remove the entries you don't want map files for. If you choose to use the yps server, you have to use the makedbm program to build the indexes from the map files.

To set up the client software on your Linux system (allowing it to connect through a ypmaster on another server), you have to instruct your kernel to use the NIS system. Begin by setting up the name of the ypmaster in the /etc/yp.conf file. This file will have a line that looks like this:


ypserver wizard.tpci.com

This line tells the local machine where to reach the ypserver. (Some versions of Linux use the word server interchangeably with ypserver in the yp.conf file.) Some older Linux systems use a two-line /etc/yp.conf file that lists the domain name and the server on separate lines, like this:


domainname tpci.com

server wizard

Set the yp.conf file to readable by user, group, and other. Then test the NIS installation by using the ypcat command:


ypcat passwd.byname

This command should list the master server's passwd.byname map. If you get error messages, it is probably because the local machine has not contacted the remote server properly. If you see the message:


Can't bind to server which serves domain

you either have a faulty server or the wrong name in the /etc/yp.conf file. To check the server, use the ping command to verify that the network connection is intact.

Once you are sure the NIS connection is functioning properly, you can decide which files you want to retrieve from the ypmaster and which are to be kept local. In most cases, you want to get the passwd and group files from the server, but the rest of the files can be kept locally. The order in which the local and NIS server machines are checked for each type of map file is controlled by the file /etc/nsswitch.conf. This file looks like this:


hosts: nis files

networks: nis files

services: files

rpc: files

protocols: files

Each line starts with the name of a file, followed by keywords that control where the Linux system looks for the file. The following are valid values in the list (which are read and processed in order):

dbm Use a file in the DBM files under /var/dbm
dns Use the domain name server
files Use local files
nis Use NIS server

Many more options are available with some feature-laden versions of NIS, but these are the primary choices (and should be sufficient for most Linux systems).

Summary


As you have seen, NFS is quite easy to implement on a local area network. It is especially handy for sharing files between machines if you have two or more networked together. In most cases, there is no reason not to use NFS with a LAN, especially since the code is linked into the server anyway. NFS does provide a flexible way of transferring files across operating systems, too, if you can find a TCP/IP NFS implementation for the other operating systems (such as DOS or Windows).

NIS is often useful on large networks, but is seldom necessary for small Linux-based systems, except when you move around your LAN a lot. However, NIS is quite easy to install and use, so it remains an option for those with larger networks.

Previous Page Page Top TOC Next Page

Если вам понравилась статья, поделитесь ею с друзьями: