Print this page
6063 pkgadd breaks with too many mountpoints
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/svr4pkg/libinst/mntinfo.c
+++ new/usr/src/cmd/svr4pkg/libinst/mntinfo.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27
28 28 /*
29 29 * System includes
30 30 */
31 31
32 32 #include <stdio.h>
33 33 #include <limits.h>
34 34 #include <errno.h>
35 35 #include <stdlib.h>
36 36 #include <unistd.h>
37 37 #include <libgen.h>
38 38 #include <string.h>
39 39 #include <wait.h>
40 40 #include <signal.h>
41 41 #include <malloc.h>
42 42 #include <sys/types.h>
43 43 #include <sys/mount.h>
44 44 #include <sys/stat.h>
45 45 #include <fcntl.h>
46 46 #include <sys/systeminfo.h>
47 47 #include <pkgstrct.h>
48 48 #include <pkginfo.h>
49 49 #include <locale.h>
50 50 #include <libintl.h>
51 51
52 52 #include <sys/mnttab.h>
53 53 #include <sys/mntent.h>
54 54 #include <sys/vfstab.h>
55 55
56 56 /*
57 57 * consolidation pkg command library includes
58 58 */
59 59
60 60 #include <pkglib.h>
61 61
62 62 /*
63 63 * local pkg command library includes
64 64 */
65 65
66 66 #include "install.h"
67 67 #include "libinst.h"
68 68 #include "libadm.h"
69 69 #include "messages.h"
70 70
71 71 extern char **environ;
72 72
73 73 static int match_mount; /* This holds the mount of interest. */
74 74
75 75 int fs_tab_used = 0;
76 76 int fs_tab_alloc = 0;
77 77 static int fs_list = -1;
78 78
79 79 struct fstable **fs_tab = NULL;
80 80
81 81 #define PKGDBROOT "/var/sadm"
82 82 #define MOUNT "/sbin/mount"
83 83 #define UMOUNT "/sbin/umount"
84 84
85 85 #define setmntent fopen
86 86 #define endmntent fclose
87 87 #define MOUNT_TABLE MNTTAB
88 88
89 89 /* returned by already_mounted() */
90 90 #define MNT_NOT 0
91 91 #define MNT_EXACT 1
92 92 #define MNT_AVAIL 2
93 93
94 94 /* used with is_remote_src() */
95 95 #define NOT_REMOTE 0
96 96 #define REAL_REMOTE 1
97 97 #define SELF_SERVE 2
98 98
99 99 /*
100 100 * Due to /etc/mnttab files containing entries for multiple nfs hosts
101 101 * HOST_NM_LN needs to be accommodating. The recommended value in the sysinfo
102 102 * man page of 257 needs to be expanded. See bugid 4076513.
103 103 * 1024 chars is defined in the mnttab.h header as the max size of an entry.
104 104 */
105 105
106 106 #define HOST_NM_LN MNT_LINE_MAX
107 107
108 108 /* These cachefs definitions should be in mntent.h. Maybe some day. */
109 109 #define MNTTYPE_CFS "cachefs"
110 110 #define MNTOPT_BACKFSTYPE "backfstype"
111 111 #define MNTTYPE_AUTO "autofs"
112 112
113 113 /*
114 114 * Utilities for getting filesystem information from the mount table.
115 115 *
116 116 * Note: vanilla SVr4 code (pkginstall/dockspace.c) used the output from
117 117 * popen() on the "/etc/mount" command. However, we need to get more
118 118 * information about mounted filesystems, so we use the C interfaces to
119 119 * the mount table, which also happens to be much faster than running
120 120 * another process. Since several of the pkg commands need access to the
121 121 * the code has been placed here, to be included in the libinst library.
122 122 */
123 123
124 124 #define ALLOC_CHUNK 30
125 125
126 126 /*
127 127 * fs_tab_ent_comp - compare fstable entries first by length in reverse
128 128 * order, then alphabetically.
129 129 */
130 130 static int
131 131 fs_tab_ent_comp(const void *e1, const void *e2)
132 132 {
133 133 struct fstable *fs1 = *((struct fstable **)e1);
134 134 struct fstable *fs2 = *((struct fstable **)e2);
135 135
136 136 if (fs1->namlen == fs2->namlen)
137 137 return (strcmp(fs1->name, fs2->name));
138 138 else
139 139 return (fs2->namlen - fs1->namlen);
140 140 }
141 141
142 142 /*
143 143 * This determines if the source of the mount is from another host. If it's
144 144 * from this host, then it might be writable. This returns NOT_REMOTE if it's
145 145 * pure local, REAL_REMOTE if it's being served from another host and
146 146 * SELF_SERVE if it's being served by the current host.
147 147 */
148 148 static int
149 149 is_remote_src(char *source)
150 150 {
151 151 static char host_name[HOST_NM_LN];
152 152 char source_host[HOST_NM_LN], *src_ptr, *src_host_ptr;
153 153 static int hn_len;
154 154
155 155 if (hn_len == 0) {
156 156 /* Find out what host this is. */
157 157 (void) sysinfo(SI_HOSTNAME, host_name, HOST_NM_LN);
158 158 hn_len = strlen(host_name);
159 159 }
160 160
161 161 if (source[0] == '/')
162 162 return (NOT_REMOTE); /* No server name, so it's local. */
163 163
164 164 if (strchr(source, ':') == NULL)
165 165 return (NOT_REMOTE); /* it's a floppy disk or something */
166 166
167 167 src_ptr = source;
168 168 src_host_ptr = source_host;
169 169
170 170 /* Scan to the end of the hostname (find the ":"). */
171 171 while (*src_ptr != ':')
172 172 *src_host_ptr++ = *src_ptr++;
173 173 *src_host_ptr = '\0';
174 174
175 175 /* Multiple hosts: failover with multiple servers; this is remote. */
176 176 if (strchr(source_host, ',') != NULL)
177 177 return (REAL_REMOTE);
178 178
179 179 if (strncmp(source, host_name, hn_len) == 0 &&
180 180 *(source+hn_len) == ':' || is_local_host(source_host))
181 181 return (SELF_SERVE); /* Exporting from itself, it's local. */
182 182
183 183 return (REAL_REMOTE);
184 184 }
185 185
186 186 /*
187 187 * This determines if an apparently writeable filesystem is really writeable
188 188 * or if it's been shared over the network with root-restrictive options.
189 189 */
190 190 static int
191 191 really_write(char *mountpt)
192 192 {
193 193 char testfile[PATH_MAX];
194 194 int fd, retval = 0;
195 195 struct stat status;
196 196
197 197 (void) snprintf(testfile, sizeof (testfile), "%s/testXXXXXX", mountpt);
198 198
199 199 if (mktemp(testfile) == NULL)
200 200 return (0); /* may as well be read-only */
201 201 /* LINTED do not use creat(); use open(path,... */
202 202 else if ((fd = creat(testfile, 0777)) == -1)
203 203 return (0); /* can't write */
204 204 else if (fstat(fd, &status) == -1)
205 205 retval = 0; /* may as well be read-only */
206 206 else if (status.st_uid != 0)
207 207 retval = 0; /* too many restrictions */
208 208 else
↓ open down ↓ |
208 lines elided |
↑ open up ↑ |
209 209 retval = 1;
210 210
211 211 (void) close(fd);
212 212 (void) unlink(testfile);
213 213
214 214 return (retval);
215 215 }
216 216
217 217 /* This returns the hostname portion of a remote path. */
218 218 char *
219 -get_server_host(short n)
219 +get_server_host(uint32_t n)
220 220 {
221 221 static char hostname[HOST_NM_LN], *host_end;
222 222
223 223 if (fs_tab_used == 0) {
224 224 return ("unknown source");
225 225 }
226 226
227 - if (n >= 0 && n < fs_tab_used) {
227 + if (n < fs_tab_used) {
228 228 (void) strcpy(hostname, fs_tab[n]->remote_name);
229 229 if ((host_end = strchr(hostname, ':')) == NULL) {
230 230 if ((strcmp(fs_tab[n]->fstype, MNTTYPE_AUTO)) == NULL)
231 231 return ("automounter");
232 232 else
233 233 return (fs_tab[n]->fstype);
234 234 } else {
235 235 *host_end = '\0';
236 236 return (hostname);
237 237 }
238 238 }
239 239
240 240 return ("unknown source");
241 241 }
242 242
243 243 /*
244 244 * This pulls the path out of a hostpath which may be of the form host:path
245 245 * where path is an absolute path. NOTE: If path turns out to be relative,
246 246 * this returns NULL.
247 247 */
248 248 static char *
249 249 path_part(char *hostpath)
250 250 {
251 251 char *host_end;
252 252
253 253 if ((host_end = strchr(hostpath, ':')) == NULL && hostpath[0] == '/')
254 254 return (hostpath); /* It's already legit. */
255 255
256 256 if (*(host_end+1) == '/')
257 257 return (host_end+1); /* Here's the path part. */
258 258
259 259 return (NULL);
260 260 }
261 261
262 262 /*
263 263 * This scans the filesystems already mounted to see if this remote mount is
264 264 * already in place on the server. This scans the fs_tab for a remote_name
265 265 * exactly matching the client's. It stores the current entry number
266 266 * corresponding to this mount in the static match_mount.
267 267 *
268 268 * Returns:
269 269 * MNT_NOT Couldn't find it.
270 270 * MNT_EXACT This has actually been manually mounted for us
271 271 * MNT_AVAIL This is mounted for the server, but needs to be
272 272 * loopback mounted from the client's perspective.
273 273 */
274 274 static int
275 275 already_mounted(struct vfstab *vfs, int is_local_host, char *client_path,
276 276 char *host_path)
277 277 {
278 278 int i;
279 279
280 280 match_mount = -1;
281 281
282 282 if (fs_tab_used == 0) {
283 283 return (MNT_NOT);
284 284 }
285 285
286 286 for (i = 0; i < fs_tab_used; i++) {
287 287 /*
288 288 * Determine if this has been manually mounted exactly as we
289 289 * require. Begin by finding a mount on our current
290 290 * mountpoint.
291 291 */
292 292 if (strcmp(fs_tab[i]->name, client_path) == 0) {
293 293 /*
294 294 * Now see if it is really the same mount. This isn't
295 295 * smart enough to find mounts on top of mounts, but
296 296 * assuming there is no conspiracy to fool this
297 297 * function, it will be good enough.
298 298 */
299 299 if (is_local_host &&
300 300 strcmp(fs_tab[i]->remote_name, host_path) == 0) {
301 301 match_mount = i;
302 302 return (MNT_EXACT);
303 303 }
304 304 }
305 305
306 306 /* Determine if this mount is available to the server. */
307 307 if (strcmp(fs_tab[i]->remote_name, vfs->vfs_special) == 0) {
308 308 match_mount = i;
309 309 return (MNT_AVAIL);
310 310 }
311 311 }
312 312 return (MNT_NOT);
313 313 }
314 314
315 315 /*
316 316 * This function unmounts all of the loopback mounts created for the client.
317 317 * If no client stuff is mounted, this is completely benign, it finds that
318 318 * nothing is mounted up and returns. It returns "1" for unmounted everything
319 319 * OK and "0" for failure.
320 320 */
321 321 int
322 322 unmount_client()
323 323 {
324 324 int errcode;
325 325 int exit_no;
326 326 int n;
327 327 int retcode = 1;
328 328 int status;
329 329 pid_t pid;
330 330 pid_t pid_return;
331 331
332 332 if (fs_tab_used == 0) {
333 333 return (1);
334 334 }
335 335
336 336 for (n = 0; n < fs_tab_used-1; n++) {
337 337 /* If the filesystem is mounted and this utility did it ... */
338 338 if (fs_tab[n]->cl_mounted && fs_tab[n]->srvr_map) {
339 339 char *arg[3];
340 340
341 341 /* create arglist for umount command */
342 342
343 343 arg[0] = UMOUNT;
344 344 arg[1] = fs_tab[n]->name;
345 345 arg[2] = (char *)NULL;
346 346
347 347 /* flush standard i/o before creating new process */
348 348
349 349 (void) fflush(stderr);
350 350 (void) fflush(stdout);
351 351
352 352 /*
353 353 * create new process to execute command in;
354 354 * vfork is being used to avoid duplicating the parents
355 355 * memory space - this means that the child process may
356 356 * not modify any of the parents memory including the
357 357 * standard i/o descriptors - all the child can do is
358 358 * adjust interrupts and open files as a prelude to a
359 359 * call to exec().
360 360 */
361 361
362 362 pid = vfork();
363 363 if (pid < 0) {
364 364 /* fork failed! */
365 365
366 366 logerr(WRN_BAD_FORK, errno, strerror(errno));
367 367 retcode = 0;
368 368 } else if (pid > 0) {
369 369 /*
370 370 * this is the parent process
371 371 */
372 372
373 373 status = 0;
374 374 pid_return = waitpid(pid, &status, 0);
375 375
376 376 if (pid_return != pid) {
377 377 logerr(WRN_BAD_WAIT, pid, pid_return,
378 378 (unsigned long)status, errno,
379 379 strerror(errno));
380 380 retcode = 0;
381 381 }
382 382
383 383 /*
384 384 * If the child was stopped or killed by a
385 385 * signal or exied with any code but 0, we
386 386 * assume the mount has failed.
387 387 */
388 388
389 389 if (!WIFEXITED(status) ||
390 390 (errcode = WEXITSTATUS(status))) {
391 391 retcode = 0;
392 392 logerr(WRN_FSTAB_UMOUNT,
393 393 fs_tab[n]->name, errcode);
394 394 } else {
395 395 fs_tab[n]->cl_mounted = 0;
396 396 }
397 397 } else {
398 398 /*
399 399 * this is the child process
400 400 */
401 401
402 402 int i;
403 403
404 404 /* reset any signals to default */
405 405
406 406 for (i = 0; i < NSIG; i++) {
407 407 (void) sigset(i, SIG_DFL);
408 408 }
409 409
410 410 /*
411 411 * Redirect output to /dev/null because the
412 412 * umount error message may be confusing to
413 413 * the user.
414 414 */
415 415
416 416 i = open("/dev/null", O_WRONLY);
417 417 if (i >= 0) {
418 418 dup2(2, STDERR_FILENO);
419 419 }
420 420
421 421 /* close all file descriptors except stdio */
422 422
423 423 closefrom(3);
424 424
425 425 exit_no = execve(arg[0], arg, environ);
426 426 _exit(exit_no);
427 427 }
428 428 }
429 429 }
430 430
431 431 return (retcode);
432 432 }
433 433
434 434 /*
435 435 * This function creates the necessary loopback mounts to emulate the client
436 436 * configuration with respect to the server. If this is being run on a
437 437 * standalone or the installation is actually to the local system, this call
438 438 * is benign since srvr_map won't be set anywhere. It returns "1" for mounted
439 439 * everything OK and "0" for failure.
440 440 */
441 441 int
442 442 mount_client()
443 443 {
444 444 int errcode;
445 445 int exit_no;
446 446 int n;
447 447 int retcode = 1;
448 448 int status;
449 449 pid_t pid;
450 450 pid_t pid_return;
451 451
452 452 if (fs_tab_used == 0) {
453 453 return (1);
454 454 }
455 455
456 456 for (n = fs_tab_used-1; n >= 0; n--) {
457 457 /*
458 458 * If the filesystem is mounted (meaning available) and the
459 459 * apparent filesystem can be mapped to a local filesystem
460 460 * AND the local filesystem is not the same as the target
461 461 * filesystem, mount it.
462 462 */
463 463 if (fs_tab[n]->mounted && fs_tab[n]->srvr_map) {
464 464 char *arg[6];
465 465
466 466 /* create arglist for mount command */
467 467
468 468 arg[0] = MOUNT;
469 469 arg[1] = "-F";
470 470 arg[2] = "lofs";
471 471 arg[3] = fs_tab[n]->remote_name;
472 472 arg[4] = fs_tab[n]->name;
473 473 arg[5] = (char *)NULL;
474 474
475 475 /* flush standard i/o before creating new process */
476 476
477 477 (void) fflush(stderr);
478 478 (void) fflush(stdout);
479 479
480 480 /*
481 481 * create new process to execute command in;
482 482 * vfork is being used to avoid duplicating the parents
483 483 * memory space - this means that the child process may
484 484 * not modify any of the parents memory including the
485 485 * standard i/o descriptors - all the child can do is
486 486 * adjust interrupts and open files as a prelude to a
487 487 * call to exec().
488 488 */
489 489
490 490 pid = vfork();
491 491 if (pid < 0) {
492 492 /* fork failed! */
493 493
494 494 logerr(WRN_BAD_FORK, errno, strerror(errno));
495 495 retcode = 0;
496 496 } else if (pid > 0) {
497 497 /*
498 498 * this is the parent process
499 499 */
500 500
501 501 pid_return = waitpid(pid, &status, 0);
502 502
503 503 if (pid_return != pid) {
504 504 logerr(WRN_BAD_WAIT, pid, pid_return,
505 505 (unsigned long)status, errno,
506 506 strerror(errno));
507 507 retcode = 0;
508 508 }
509 509
510 510 /*
511 511 * If the child was stopped or killed by a
512 512 * signal or exied with any code but 0, we
513 513 * assume the mount has failed.
514 514 */
515 515
516 516 if (!WIFEXITED(status) ||
517 517 (errcode = WEXITSTATUS(status))) {
518 518 retcode = 0;
519 519 fs_tab[n]->mnt_failed = 1;
520 520 logerr(WRN_FSTAB_MOUNT,
521 521 fs_tab[n]->name, errcode);
522 522 } else {
523 523 fs_tab[n]->cl_mounted = 1;
524 524 }
525 525 } else {
526 526 /*
527 527 * this is the child process
528 528 */
529 529
530 530 int i;
531 531
532 532 /* reset all signals to default */
533 533
534 534 for (i = 0; i < NSIG; i++) {
535 535 (void) sigset(i, SIG_DFL);
536 536 }
537 537
538 538 /*
539 539 * Redirect output to /dev/null because the
540 540 * mount error message may be confusing to
541 541 * the user.
542 542 */
543 543
544 544 i = open("/dev/null", O_WRONLY);
545 545 if (i >= 0) {
546 546 dup2(i, STDERR_FILENO);
547 547 }
548 548
549 549 /* close all file descriptors except stdio */
550 550
551 551 closefrom(3);
552 552
553 553 exit_no = execve(arg[0], arg, environ);
554 554 _exit(exit_no);
555 555 /*NOTREACHED*/
556 556 }
557 557 }
558 558 }
↓ open down ↓ |
321 lines elided |
↑ open up ↑ |
559 559 return (retcode);
560 560 }
561 561
562 562 /*
563 563 * This function maps path, on a loopback filesystem, back to the real server
564 564 * filesystem. fsys_value is the fs_tab[] entry to which the loopback'd path is
565 565 * mapped. This returns a pointer to a static area. If the result is needed
566 566 * for further processing, it should be strdup()'d or something.
567 567 */
568 568 char *
569 -server_map(char *path, short fsys_value)
569 +server_map(char *path, uint32_t fsys_value)
570 570 {
571 571 static char server_construction[PATH_MAX];
572 572
573 573 if (fs_tab_used == 0) {
574 574 (void) strcpy(server_construction, path);
575 - } else if (fsys_value >= 0 && fsys_value < fs_tab_used) {
575 + } else if (fsys_value < fs_tab_used) {
576 576 (void) snprintf(server_construction,
577 577 sizeof (server_construction),
578 578 "%s%s", fs_tab[fsys_value]->remote_name,
579 579 path+strlen(fs_tab[fsys_value]->name));
580 580 } else {
581 581 (void) strcpy(server_construction, path);
582 582 }
583 583
584 584 return (server_construction);
585 585 }
586 586
587 587 /* This function sets up the standard parts of the fs_tab. */
588 588 static struct fstable *
589 589 fs_tab_init(char *mountp, char *fstype)
590 590 {
591 591 struct fstable *nfte;
592 592
593 593 /* Create the array if necessary. */
594 594 if (fs_list == -1) {
595 595 fs_list = ar_create(ALLOC_CHUNK,
596 596 (unsigned)sizeof (struct fstable),
597 597 "filesystem mount data");
598 598 if (fs_list == -1) {
599 599 progerr(ERR_MALLOC, "fs_list", errno, strerror(errno));
600 600 return (NULL);
601 601 }
602 602 }
603 603
604 604 /*
605 605 * Allocate an fstable entry for this mnttab entry.
606 606 */
607 607 if ((nfte = *(struct fstable **)ar_next_avail(fs_list))
608 608 == NULL) {
609 609 progerr(ERR_MALLOC, "nfte", errno, strerror(errno));
610 610 return (NULL);
611 611 }
612 612
613 613 /*
614 614 * Point fs_tab at the head of the array again, since it may have
615 615 * moved due to realloc in ar_next_avail(). If ar_next_avail() realizes
616 616 * that there is no more room to grow the array, it reallocates the
617 617 * array. Because we stored pointer to that array in fs_tab, we need
618 618 * to make sure that it is updated as well.
619 619 */
620 620 if ((fs_tab = (struct fstable **)ar_get_head(fs_list)) == NULL) {
621 621 progerr(ERR_NOTABLE, "mount", MOUNT_TABLE, strerror(errno));
622 622 return (NULL);
623 623 }
624 624
625 625 /*
626 626 * Get the length of the 'mount point' name.
627 627 */
628 628 nfte->namlen = strlen(mountp);
629 629 /*
630 630 * Allocate space for the 'mount point' name.
631 631 */
632 632 if ((nfte->name = malloc(nfte->namlen+1)) == NULL) {
633 633 progerr(ERR_MALLOC, "name", errno, strerror(errno));
634 634 return (NULL);
635 635 }
636 636 (void) strcpy(nfte->name, mountp);
637 637
638 638 if ((nfte->fstype = malloc(strlen(fstype)+1)) == NULL) {
639 639 progerr(ERR_MALLOC, "fstype", errno, strerror(errno));
640 640 return (NULL);
641 641 }
642 642 (void) strcpy(nfte->fstype, fstype);
643 643
644 644 fs_tab_used++;
645 645
646 646 return (nfte);
647 647 }
648 648
649 649 /* This function frees all memory associated with the filesystem table. */
650 650 void
651 651 fs_tab_free(void)
652 652 {
653 653 int n;
654 654
655 655 if (fs_tab_used == 0) {
656 656 return;
657 657 }
658 658
659 659 for (n = 0; n < fs_tab_used; n++) {
660 660 free(fs_tab[n]->fstype);
661 661 free(fs_tab[n]->name);
662 662 free(fs_tab[n]->remote_name);
663 663 }
664 664
665 665 ar_free(fs_list);
666 666 }
667 667
668 668 /* This function scans a string of mount options for a specific keyword. */
669 669 static int
670 670 hasopt(char *options, char *keyword)
671 671 {
672 672 char vfs_options[VFS_LINE_MAX], *optptr;
673 673
674 674 if (!options) {
675 675 (void) strcpy(vfs_options, "ro");
676 676 } else {
677 677 (void) strcpy(vfs_options, options);
678 678 }
679 679
680 680 while (optptr = strrchr(vfs_options, ',')) {
681 681 *optptr++ = '\0';
682 682
683 683 if (strcmp(optptr, keyword) == 0)
684 684 return (1);
685 685 }
686 686
687 687 /* Now deal with the remainder. */
688 688 if (strcmp(vfs_options, keyword) == 0)
689 689 return (1);
690 690
691 691 return (0);
692 692 }
693 693
694 694 /*
695 695 * This function constructs a new filesystem table (fs_tab[]) entry based on
696 696 * an /etc/mnttab entry. When it returns, the new entry has been inserted
697 697 * into fs_tab[].
698 698 */
699 699 static int
700 700 construct_mt(struct mnttab *mt)
701 701 {
702 702 struct fstable *nfte;
703 703
704 704 /*
705 705 * Initialize fstable structure and make the standard entries.
706 706 */
707 707 if ((nfte = fs_tab_init(mt->mnt_mountp, mt->mnt_fstype)) == NULL)
708 708 return (1);
709 709
710 710 /*
711 711 * See if this is served from another host.
712 712 * Testing the type is cheap; finding the hostname is not.
713 713 * At this point, we're using the REAL mnttab; since we're not
714 714 * allowed to mount ourself with "NFS", "NFS" must be remote.
715 715 * The automount will translate "nfs:self" to a lofs mount.
716 716 */
717 717 if (strcmp(mt->mnt_fstype, MNTTYPE_AUTO) == 0 ||
718 718 strcmp(mt->mnt_fstype, MNTTYPE_NFS) == 0 ||
719 719 is_remote_src(mt->mnt_special) == REAL_REMOTE)
720 720 nfte->remote = 1;
721 721 else
722 722 nfte->remote = 0;
723 723
724 724 /* It's mounted now (by definition), so we don't have to remap it. */
725 725 nfte->srvr_map = 0;
726 726 nfte->mounted = 1;
727 727
728 728 nfte->remote_name = strdup(mt->mnt_special);
729 729
730 730 /*
731 731 * This checks the mount commands which establish the most
732 732 * basic level of access. Later further tests may be
733 733 * necessary to fully qualify this. We set this bit
734 734 * preliminarily because we have access to the mount data
735 735 * now.
736 736 */
737 737 nfte->writeable = 0; /* Assume read-only. */
738 738 if (hasmntopt(mt, MNTOPT_RO) == NULL) {
739 739 nfte->writeable = 1;
740 740 if (!(nfte->remote))
741 741 /*
742 742 * There's no network involved, so this
743 743 * assessment is confirmed.
744 744 */
745 745 nfte->write_tested = 1;
746 746 } else
747 747 /* read-only is read-only */
748 748 nfte->write_tested = 1;
749 749
750 750 /* Is this coming to us from a server? */
751 751 if (nfte->remote && !(nfte->writeable))
752 752 nfte->served = 1;
753 753
754 754 return (0);
755 755 }
756 756
757 757 /*
758 758 * This function modifies an existing fs_tab[] entry. It was found mounted up
759 759 * exactly the way we would have mounted it in mount_client() only at the
760 760 * time we didn't know it was for the client. Now we do, so we're setting the
761 761 * various permissions to conform to the client view.
762 762 */
763 763 static void
764 764 mod_existing(struct vfstab *vfsent, int fstab_entry, int is_remote)
765 765 {
766 766 /*
767 767 * Establish whether the client will see this as served.
768 768 */
769 769 if (is_remote && hasopt(vfsent->vfs_mntopts, MNTOPT_RO))
770 770 fs_tab[fstab_entry]->served = 1;
771 771
772 772 fs_tab[fstab_entry]->cl_mounted = 1;
773 773 }
774 774
775 775 /*
776 776 * This function constructs a new fs_tab[] entry based on
777 777 * an /etc/vfstab entry. When it returns, the new entry has been inserted
778 778 * into fstab[].
779 779 */
780 780 static int
781 781 construct_vfs(struct vfstab *vfsent, char *client_path, char *link_name,
782 782 int is_remote, int mnt_stat)
783 783 {
784 784 int use_link;
785 785 struct fstable *nfte;
786 786
787 787 if ((nfte = fs_tab_init(client_path, vfsent->vfs_fstype)) == NULL)
788 788 return (1);
789 789
790 790 nfte->remote = (is_remote == REAL_REMOTE);
791 791
792 792 /*
793 793 * The file system mounted on the client may or may not be writeable.
794 794 * So we hand it over to fsys() to evaluate. This will have the same
795 795 * read/write attributes as the corresponding mounted filesystem.
796 796 */
797 797 use_link = 0;
798 798 if (nfte->remote) {
799 799 /*
800 800 * Deal here with mount points actually on a system remote
801 801 * from the server.
802 802 */
803 803 if (mnt_stat == MNT_NOT) {
804 804 /*
805 805 * This filesystem isn't in the current mount table
806 806 * meaning it isn't mounted, the current host can't
807 807 * write to it and there's no point to mapping it for
808 808 * the server.
809 809 */
810 810 link_name = NULL;
811 811 nfte->mounted = 0;
812 812 nfte->srvr_map = 0;
813 813 nfte->writeable = 0;
814 814 } else { /* It's MNT_AVAIL. */
815 815 /*
816 816 * This filesystem is associated with a current
817 817 * mountpoint. Since it's mounted, it needs to be
818 818 * remapped and it is writable if the real mounted
819 819 * filesystem is writeable.
820 820 */
821 821 use_link = 1;
822 822 link_name = strdup(fs_tab[match_mount]->name);
823 823 nfte->mounted = 1;
824 824 nfte->srvr_map = 1;
825 825 nfte->writeable = fs_tab[match_mount]->writeable;
826 826 nfte->write_tested = fs_tab[match_mount]->write_tested;
827 827 }
828 828 } else { /* local filesystem */
829 829 use_link = 1;
830 830 nfte->mounted = 1;
831 831 nfte->srvr_map = 1;
832 832 nfte->writeable = fs_tab[fsys(link_name)]->writeable;
833 833 nfte->write_tested = 1;
834 834 }
835 835
836 836 /*
837 837 * Now we establish whether the client will see this as served.
838 838 */
839 839 if (is_remote && hasopt(vfsent->vfs_mntopts, MNTOPT_RO))
840 840 nfte->served = 1;
841 841
842 842 if (use_link) {
843 843 nfte->remote_name = link_name;
844 844 } else {
845 845 nfte->remote_name = strdup(vfsent->vfs_special);
846 846 }
847 847
848 848 return (0);
849 849 }
850 850
851 851 /*
852 852 * get_mntinfo - get the mount table, now dynamically allocated. Returns 0 if
853 853 * no problem and 1 if there's a fatal error.
854 854 */
855 855 int
856 856 get_mntinfo(int map_client, char *vfstab_file)
857 857 {
858 858 static char *rn = "/";
859 859 FILE *pp;
860 860 struct mnttab mtbuf;
861 861 struct mnttab *mt = &mtbuf;
862 862 char *install_root;
863 863 int is_remote;
864 864
865 865 /*
866 866 * Open the mount table for the current host and establish a global
867 867 * table that holds data about current mount status.
868 868 */
869 869 if ((pp = setmntent(MOUNT_TABLE, "r")) == NULL) {
870 870 progerr(ERR_NOTABLE, "mount", MOUNT_TABLE, strerror(errno));
871 871 return (1);
872 872 }
873 873
874 874 /*
875 875 * First, review the mounted filesystems on the managing host. This
876 876 * may also be the target host but we haven't decided that for sure
877 877 * yet.
878 878 */
879 879 while (!getmntent(pp, mt))
880 880 if (construct_mt(mt))
881 881 return (1);
882 882
883 883 (void) endmntent(pp);
884 884
885 885 /*
886 886 * Now, we see if this installation is to a client. If it is, we scan
887 887 * the client's vfstab to determine what filesystems are
888 888 * inappropriate to write to. This simply adds the vfstab entries
889 889 * representing what will be remote file systems for the client.
890 890 * Everything that isn't remote to the client is already accounted
891 891 * for in the fs_tab[] so far. If the remote filesystem is really on
892 892 * this server, we will write through to the server from this client.
893 893 */
894 894 install_root = get_inst_root();
895 895 if (install_root && strcmp(install_root, "/") != 0 && map_client) {
896 896 /* OK, this is a legitimate remote client. */
897 897 struct vfstab vfsbuf;
898 898 struct vfstab *vfs = &vfsbuf;
899 899 char VFS_TABLE[PATH_MAX];
900 900
901 901 /*
902 902 * Since we use the fsys() function later, and it depends on
903 903 * an ordered list, we have to sort the list here.
904 904 */
905 905 qsort(fs_tab, fs_tab_used,
906 906 sizeof (struct fstable *), fs_tab_ent_comp);
907 907
908 908 /*
909 909 * Here's where the vfstab for the target is. If we can get
910 910 * to it, we'll scan it for what the client will see as
911 911 * remote filesystems, otherwise, we'll just skip this.
912 912 */
913 913 if (vfstab_file) {
914 914 (void) snprintf(VFS_TABLE, sizeof (VFS_TABLE), "%s",
915 915 vfstab_file);
916 916 } else {
917 917 (void) snprintf(VFS_TABLE, sizeof (VFS_TABLE), "%s%s",
918 918 install_root, VFSTAB);
919 919 }
920 920
921 921 if (access(VFS_TABLE, R_OK) == 0) {
922 922 char *link_name;
923 923
924 924 /*
925 925 * Open the vfs table for the target host.
926 926 */
927 927 if ((pp = setmntent(VFS_TABLE, "r")) == NULL) {
928 928 progerr(ERR_NOTABLE, "vfs", VFS_TABLE,
929 929 strerror(errno));
930 930 return (1);
931 931 }
932 932
933 933 /* Do this for each entry in the vfstab. */
934 934 while (!getvfsent(pp, vfs)) {
935 935 char client_mountp[PATH_MAX];
936 936 int mnt_stat;
937 937
938 938 /*
939 939 * We put it into the fs table if it's
940 940 * remote mounted (even from this server) or
941 941 * loopback mounted from the client's point
942 942 * of view.
943 943 */
944 944 if (!(is_remote =
945 945 is_remote_src(vfs->vfs_special)) &&
946 946 strcmp(vfs->vfs_fstype, MNTTYPE_LOFS) !=
947 947 0)
948 948 continue; /* not interesting */
949 949
950 950 /*
951 951 * Construct client_mountp by prepending the
952 952 * install_root to the 'mount point' name.
953 953 */
954 954 if (strcmp(vfs->vfs_mountp, "/") == 0) {
955 955 (void) strcpy(client_mountp,
956 956 install_root);
957 957 } else {
958 958 (void) snprintf(client_mountp,
959 959 sizeof (client_mountp), "%s%s",
960 960 install_root, vfs->vfs_mountp);
961 961 }
962 962
963 963 /*
964 964 * We also skip the entry if the vfs_special
965 965 * path and the client_path are the same.
966 966 * There's no need to mount it, it's just a
967 967 * cachefs optimization that mounts a
968 968 * directory over itself from this server.
969 969 */
970 970 if ((is_remote == SELF_SERVE) &&
971 971 strcmp(path_part(vfs->vfs_special),
972 972 client_mountp) == 0)
973 973 continue;
974 974
975 975 /* Determine if this is already mounted. */
976 976 link_name = strdup(path_part(vfs->vfs_special));
977 977 mnt_stat = already_mounted(vfs,
978 978 (is_remote != REAL_REMOTE), client_mountp,
979 979 link_name);
980 980
981 981 if (mnt_stat == MNT_EXACT) {
982 982 mod_existing(vfs, match_mount,
983 983 is_remote);
984 984 } else { /* MNT_NOT */
985 985 if (construct_vfs(vfs, client_mountp,
986 986 link_name, is_remote, mnt_stat))
987 987 return (1);
988 988 }
989 989 }
990 990 (void) endmntent(pp);
991 991 } /* end of if(access()) */
992 992 } /* end of if(install_root) */
993 993
994 994 /* This next one may look stupid, but it can really happen. */
995 995 if (fs_tab_used <= 0) {
996 996 progerr(ERR_MNT_NOMOUNTS);
997 997 return (1);
998 998 }
999 999
1000 1000 /*
1001 1001 * Now that we have the complete list of mounted (or virtually
1002 1002 * mounted) filesystems, we sort the mountpoints in reverse order
1003 1003 * based on the length of the 'mount point' name.
1004 1004 */
1005 1005 qsort(fs_tab, fs_tab_used, sizeof (struct fstable *), fs_tab_ent_comp);
1006 1006 if (strcmp(fs_tab[fs_tab_used-1]->name, rn) != 0) {
1007 1007 progerr(ERR_MNT_NOROOT, fs_tab[fs_tab_used-1]->name, rn, errno,
1008 1008 strerror(errno));
1009 1009 return (1);
1010 1010 } else {
1011 1011 return (0);
1012 1012 }
1013 1013 }
1014 1014
1015 1015 /*
1016 1016 * This function supports dryrun mode by allowing the filesystem table to be
1017 1017 * directly loaded from the continuation file.
1018 1018 */
1019 1019 int
1020 1020 load_fsentry(struct fstable *fs_entry, char *name, char *fstype,
1021 1021 char *remote_name)
1022 1022 {
1023 1023 struct fstable *nfte;
1024 1024
1025 1025 if ((nfte = fs_tab_init(name, fstype)) == NULL)
1026 1026 return (1);
1027 1027
1028 1028 /* Grab the name and fstype from the new structure. */
1029 1029 fs_entry->name = nfte->name;
1030 1030 fs_entry->fstype = nfte->fstype;
1031 1031
1032 1032 /* Copy the basic structure into place. */
1033 1033 (void) memcpy(nfte, fs_entry, sizeof (struct fstable));
1034 1034
1035 1035 /*
1036 1036 * Allocate space for the 'special' name.
1037 1037 */
1038 1038 if ((nfte->remote_name = malloc(strlen(remote_name)+1)) == NULL) {
1039 1039 progerr(ERR_MALLOC, "remote_name", errno, strerror(errno));
1040 1040 return (1);
1041 1041 }
1042 1042
1043 1043 (void) strcpy(nfte->remote_name, remote_name);
↓ open down ↓ |
458 lines elided |
↑ open up ↑ |
1044 1044
1045 1045 return (0);
1046 1046 }
1047 1047
1048 1048 /*
1049 1049 * Given a path, return the table index of the filesystem the file apparently
1050 1050 * resides on. This doesn't put any time into resolving filesystems that
1051 1051 * refer to other filesystems. It just returns the entry containing this
1052 1052 * path.
1053 1053 */
1054 -short
1054 +uint32_t
1055 1055 fsys(char *path)
1056 1056 {
1057 1057 register int i;
1058 1058 char real_path[PATH_MAX];
1059 1059 char path_copy[PATH_MAX];
1060 1060 char *path2use;
1061 1061 char *cp;
1062 1062 int pathlen;
1063 1063 boolean_t found = B_FALSE;
1064 1064
1065 1065 /*
1066 1066 * The loop below represents our best effort to identify real path of
1067 1067 * a file, which doesn't need to exist. realpath() returns error for
1068 1068 * nonexistent path, therefore we need to cut off trailing components
1069 1069 * of path until we get path which exists and can be resolved by
1070 1070 * realpath(). Lookup of "/dir/symlink/nonexistent-file" would fail
1071 1071 * to resolve symlink without this.
1072 1072 */
1073 1073 (void) strlcpy(path_copy, path, PATH_MAX);
1074 1074 for (cp = dirname(path_copy); strlen(cp) > 1; cp = dirname(cp)) {
1075 1075 if (realpath(cp, real_path) != NULL) {
1076 1076 found = B_TRUE;
1077 1077 break;
1078 1078 } else if (errno != ENOENT)
1079 1079 break;
1080 1080 }
1081 1081 if (found)
1082 1082 path2use = real_path;
1083 1083 else
1084 1084 /* fall back to original path in case of unexpected failure */
1085 1085 path2use = path;
1086 1086
1087 1087 pathlen = strlen(path2use);
1088 1088
1089 1089 /*
1090 1090 * The following algorithm scans the list of attached file systems
1091 1091 * for the one containing path. At this point the file names in
1092 1092 * fs_tab[] are sorted by decreasing length to facilitate the scan.
1093 1093 * The first for() scans past all the file system names too short to
1094 1094 * contain path. The second for() does the actual string comparison.
1095 1095 * It tests first to assure that the comparison is against a complete
1096 1096 * token by assuring that the end of the filesystem name aligns with
1097 1097 * the end of a token in path2use (ie: '/' or NULL) then it does a
1098 1098 * string compare. -- JST
1099 1099 */
1100 1100
1101 1101 if (fs_tab_used == 0) {
1102 1102 return (-1);
1103 1103 }
1104 1104
1105 1105 for (i = 0; i < fs_tab_used; i++)
1106 1106 if (fs_tab[i] == NULL)
1107 1107 continue;
1108 1108 else if (fs_tab[i]->namlen <= pathlen)
1109 1109 break;
1110 1110 for (; i < fs_tab_used; i++) {
1111 1111 int fs_namelen;
1112 1112 char term_char;
1113 1113
1114 1114 if (fs_tab[i] == NULL)
1115 1115 continue;
1116 1116
1117 1117 fs_namelen = fs_tab[i]->namlen;
1118 1118 term_char = path2use[fs_namelen];
1119 1119
1120 1120 /*
1121 1121 * If we're putting the file "/a/kernel" into the filesystem
1122 1122 * "/a", then fs_namelen == 2 and term_char == '/'. If, we're
1123 1123 * putting "/etc/termcap" into "/", fs_namelen == 1 and
1124 1124 * term_char (unfortunately) == 'e'. In the case of
1125 1125 * fs_namelen == 1, we check to make sure the filesystem is
1126 1126 * "/" and if it is, we have a guaranteed fit, otherwise we
1127 1127 * do the string compare. -- JST
1128 1128 */
1129 1129 if ((fs_namelen == 1 && *(fs_tab[i]->name) == '/') ||
1130 1130 ((term_char == '/' || term_char == NULL) &&
1131 1131 strncmp(fs_tab[i]->name, path2use, fs_namelen) == 0))
1132 1132 return (i);
1133 1133 }
1134 1134
1135 1135 /*
1136 1136 * It only gets here if the root filesystem is fundamentally corrupt.
1137 1137 * (This can happen!)
1138 1138 */
1139 1139 progerr(ERR_FSYS_FELLOUT, path2use);
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
1140 1140
1141 1141 return (-1);
1142 1142 }
1143 1143
1144 1144 /*
1145 1145 * This function returns the entry in the fs_tab[] corresponding to the
1146 1146 * actual filesystem of record. It won't return a loopback filesystem entry,
1147 1147 * it will return the filesystem that the loopback filesystem is mounted
1148 1148 * over.
1149 1149 */
1150 -short
1150 +uint32_t
1151 1151 resolved_fsys(char *path)
1152 1152 {
1153 1153 int i = -1;
1154 1154 char path2use[PATH_MAX];
1155 1155
1156 1156 (void) strcpy(path2use, path);
1157 1157
1158 1158 /* If this isn't a "real" filesystem, resolve the map. */
1159 1159 do {
1160 1160 (void) strcpy(path2use, server_map(path2use, i));
1161 1161 i = fsys(path2use);
1162 1162 } while (fs_tab[i]->srvr_map);
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
1163 1163
1164 1164 return (i);
1165 1165 }
1166 1166
1167 1167 /*
1168 1168 * This function returns the srvr_map status based upon the fs_tab entry
1169 1169 * number. This tells us if the server path constructed from the package
1170 1170 * install root is really the target filesystem.
1171 1171 */
1172 1172 int
1173 -use_srvr_map_n(short n)
1173 +use_srvr_map_n(uint32_t n)
1174 1174 {
1175 1175 return ((int)fs_tab[n]->srvr_map);
1176 1176 }
1177 1177
1178 1178 /*
1179 1179 * This function returns the mount status based upon the fs_tab entry
1180 1180 * number. This tells us if there is any hope of gaining access
1181 1181 * to this file system.
1182 1182 */
1183 1183 int
1184 -is_mounted_n(short n)
1184 +is_mounted_n(uint32_t n)
1185 1185 {
1186 1186 return ((int)fs_tab[n]->mounted);
1187 1187 }
1188 1188
1189 1189 /*
1190 1190 * is_fs_writeable_n - given an fstab index, return 1
1191 1191 * if it's writeable, 0 if read-only.
1192 1192 */
1193 1193 int
1194 -is_fs_writeable_n(short n)
1194 +is_fs_writeable_n(uint32_t n)
1195 1195 {
1196 1196 /*
1197 1197 * If the write access permissions haven't been confirmed, do that
1198 1198 * now. Note that the only reason we need to do the special check is
1199 1199 * in the case of an NFS mount (remote) because we can't determine if
1200 1200 * root has access in any other way.
1201 1201 */
1202 1202 if (fs_tab[n]->remote && fs_tab[n]->mounted &&
1203 1203 !fs_tab[n]->write_tested) {
1204 1204 if (fs_tab[n]->writeable && !really_write(fs_tab[n]->name))
1205 1205 fs_tab[n]->writeable = 0; /* not really */
1206 1206
1207 1207 fs_tab[n]->write_tested = 1; /* confirmed */
1208 1208 }
1209 1209
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
1210 1210 return ((int)fs_tab[n]->writeable);
1211 1211 }
1212 1212
1213 1213 /*
1214 1214 * is_remote_fs_n - given an fstab index, return 1
1215 1215 * if it's a remote filesystem, 0 if local.
1216 1216 *
1217 1217 * Note: Upon entry, a valid fsys() is required.
1218 1218 */
1219 1219 int
1220 -is_remote_fs_n(short n)
1220 +is_remote_fs_n(uint32_t n)
1221 1221 {
1222 1222 return ((int)fs_tab[n]->remote);
1223 1223 }
1224 1224
1225 1225 /* index-driven is_served() */
1226 1226 int
1227 -is_served_n(short n)
1227 +is_served_n(uint32_t n)
1228 1228 {
1229 1229 return ((int)fs_tab[n]->served);
1230 1230 }
1231 1231
1232 1232 /*
1233 1233 * This returns the number of blocks available on the indicated filesystem.
1234 1234 *
1235 1235 * Note: Upon entry, a valid fsys() is required.
1236 1236 */
1237 1237 fsblkcnt_t
1238 -get_blk_free_n(short n)
1238 +get_blk_free_n(uint32_t n)
1239 1239 {
1240 1240 return (fs_tab[n]->bfree);
1241 1241 }
1242 1242
1243 1243 /*
1244 1244 * This returns the number of blocks being used on the indicated filesystem.
1245 1245 *
1246 1246 * Note: Upon entry, a valid fsys() is required.
1247 1247 */
1248 1248 fsblkcnt_t
1249 -get_blk_used_n(short n)
1249 +get_blk_used_n(uint32_t n)
1250 1250 {
1251 1251 return (fs_tab[n]->bused);
1252 1252 }
1253 1253
1254 1254 /*
1255 1255 * This returns the number of inodes available on the indicated filesystem.
1256 1256 *
1257 1257 * Note: Upon entry, a valid fsys() is required.
1258 1258 */
1259 1259 fsblkcnt_t
1260 -get_inode_free_n(short n)
1260 +get_inode_free_n(uint32_t n)
1261 1261 {
1262 1262 return (fs_tab[n]->ffree);
1263 1263 }
1264 1264
1265 1265 /*
1266 1266 * This returns the number of inodes being used on the indicated filesystem.
1267 1267 *
1268 1268 * Note: Upon entry, a valid fsys() is required.
1269 1269 */
1270 1270 fsblkcnt_t
1271 -get_inode_used_n(short n)
1271 +get_inode_used_n(uint32_t n)
1272 1272 {
1273 1273 return (fs_tab[n]->fused);
1274 1274 }
1275 1275
1276 1276 /*
1277 1277 * Sets the number of blocks being used on the indicated filesystem.
1278 1278 *
1279 1279 * Note: Upon entry, a valid fsys() is required.
1280 1280 */
1281 1281 void
1282 -set_blk_used_n(short n, fsblkcnt_t value)
1282 +set_blk_used_n(uint32_t n, fsblkcnt_t value)
1283 1283 {
1284 1284 fs_tab[n]->bused = value;
1285 1285 }
1286 1286
1287 1287 /* Get the filesystem block size. */
1288 1288 fsblkcnt_t
1289 -get_blk_size_n(short n)
1289 +get_blk_size_n(uint32_t n)
1290 1290 {
1291 1291 return (fs_tab[n]->bsize);
1292 1292 }
1293 1293
1294 1294 /* Get the filesystem fragment size. */
1295 1295 fsblkcnt_t
1296 -get_frag_size_n(short n)
1296 +get_frag_size_n(uint32_t n)
1297 1297 {
1298 1298 return (fs_tab[n]->bsize);
1299 1299 }
1300 1300
1301 1301 /*
1302 1302 * This returns the name of the indicated filesystem.
1303 1303 */
1304 1304 char *
1305 -get_fs_name_n(short n)
1305 +get_fs_name_n(uint32_t n)
1306 1306 {
1307 1307 if (fs_tab_used == 0) {
1308 1308 return (NULL);
1309 1309 } else if (n >= fs_tab_used) {
1310 1310 return (NULL);
1311 1311 } else {
1312 1312 return (fs_tab[n]->name);
1313 1313 }
1314 1314 }
1315 1315
1316 1316 /*
1317 1317 * This returns the remote name of the indicated filesystem.
1318 1318 *
1319 1319 * Note: Upon entry, a valid fsys() is required.
1320 1320 */
1321 1321 char *
1322 -get_source_name_n(short n)
1322 +get_source_name_n(uint32_t n)
1323 1323 {
1324 1324 return (fs_tab[n]->remote_name);
1325 1325 }
1326 1326
1327 1327 /*
1328 1328 * This function returns the srvr_map status based upon the path.
1329 1329 */
1330 1330 int
1331 -use_srvr_map(char *path, short *fsys_value)
1331 +use_srvr_map(char *path, uint32_t *fsys_value)
1332 1332 {
1333 1333 if (*fsys_value == BADFSYS)
1334 1334 *fsys_value = fsys(path);
1335 1335
1336 1336 return (use_srvr_map_n(*fsys_value));
1337 1337 }
1338 1338
1339 1339 /*
1340 1340 * This function returns the mount status based upon the path.
1341 1341 */
1342 1342 int
1343 -is_mounted(char *path, short *fsys_value)
1343 +is_mounted(char *path, uint32_t *fsys_value)
1344 1344 {
1345 1345 if (*fsys_value == BADFSYS)
1346 1346 *fsys_value = fsys(path);
1347 1347
1348 1348 return (is_mounted_n(*fsys_value));
1349 1349 }
1350 1350
1351 1351 /*
1352 1352 * is_fs_writeable - given a cfent entry, return 1
1353 1353 * if it's writeable, 0 if read-only.
1354 1354 *
1355 1355 * Note: Upon exit, a valid fsys() is guaranteed. This is
1356 1356 * an interface requirement.
1357 1357 */
1358 1358 int
1359 -is_fs_writeable(char *path, short *fsys_value)
1359 +is_fs_writeable(char *path, uint32_t *fsys_value)
1360 1360 {
1361 1361 if (*fsys_value == BADFSYS)
1362 1362 *fsys_value = fsys(path);
1363 1363
1364 1364 return (is_fs_writeable_n(*fsys_value));
1365 1365 }
1366 1366
1367 1367 /*
1368 1368 * is_remote_fs - given a cfent entry, return 1
1369 1369 * if it's a remote filesystem, 0 if local.
1370 1370 *
1371 1371 * Also Note: Upon exit, a valid fsys() is guaranteed. This is
1372 1372 * an interface requirement.
1373 1373 */
1374 1374 int
1375 -is_remote_fs(char *path, short *fsys_value)
1375 +is_remote_fs(char *path, uint32_t *fsys_value)
1376 1376 {
1377 1377 if (*fsys_value == BADFSYS)
1378 1378 *fsys_value = fsys(path);
1379 1379
1380 1380 return (is_remote_fs_n(*fsys_value));
1381 1381 }
1382 1382
1383 1383 /*
1384 1384 * This function returns the served status of the filesystem. Served means a
1385 1385 * client is getting this file from a server and it is not writeable by the
1386 1386 * client. It has nothing to do with whether or not this particular operation
1387 1387 * (eg: pkgadd or pkgrm) will be writing to it.
1388 1388 */
1389 1389 int
1390 -is_served(char *path, short *fsys_value)
1390 +is_served(char *path, uint32_t *fsys_value)
1391 1391 {
1392 1392 if (*fsys_value == BADFSYS)
1393 1393 *fsys_value = fsys(path);
1394 1394
1395 1395 return (is_served_n(*fsys_value));
1396 1396 }
1397 1397
1398 1398 /*
1399 1399 * get_remote_path - given a filesystem table index, return the
1400 1400 * path of the filesystem on the remote system. Otherwise,
1401 1401 * return NULL if it's a local filesystem.
1402 1402 */
1403 1403 char *
1404 -get_remote_path(short n)
1404 +get_remote_path(uint32_t n)
1405 1405 {
1406 1406 char *p;
1407 1407
1408 1408 if (!is_remote_fs_n(n))
1409 1409 return (NULL); /* local */
1410 1410 p = strchr(fs_tab[n]->remote_name, ':');
1411 1411 if (!p)
1412 1412 p = fs_tab[n]->remote_name; /* Loopback */
1413 1413 else
1414 1414 p++; /* remote */
1415 1415 return (p);
1416 1416 }
1417 1417
1418 1418 /*
1419 1419 * get_mount_point - given a filesystem table index, return the
1420 1420 * path of the mount point. Otherwise,
1421 1421 * return NULL if it's a local filesystem.
1422 1422 */
1423 1423 char *
1424 -get_mount_point(short n)
1424 +get_mount_point(uint32_t n)
1425 1425 {
1426 1426 if (!is_remote_fs_n(n))
1427 1427 return (NULL); /* local */
1428 1428 return (fs_tab[n]->name);
1429 1429 }
1430 1430
1431 1431 struct fstable *
1432 -get_fs_entry(short n)
1432 +get_fs_entry(uint32_t n)
1433 1433 {
1434 1434 if (fs_tab_used == 0) {
1435 1435 return (NULL);
1436 1436 } else if (n >= fs_tab_used) {
1437 1437 return (NULL);
1438 1438 } else {
1439 1439 return (fs_tab[n]);
1440 1440 }
1441 1441 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX