| 2501 | |
| 2502 | #define DEVCTL_LEN 1024 |
| 2503 | static void |
| 2504 | mount_devctl_event(const char *type, struct mount *mp, bool donew) |
| 2505 | { |
| 2506 | const uint8_t *cp; |
| 2507 | struct mntoptnames *fp; |
| 2508 | struct sbuf sb; |
| 2509 | struct statfs *sfp = &mp->mnt_stat; |
| 2510 | char *buf; |
| 2511 | |
| 2512 | buf = malloc(DEVCTL_LEN, M_MOUNT, M_NOWAIT); |
| 2513 | if (buf == NULL) |
| 2514 | return; |
| 2515 | sbuf_new(&sb, buf, DEVCTL_LEN, SBUF_FIXEDLEN); |
| 2516 | sbuf_cpy(&sb, "mount-point=\""); |
| 2517 | devctl_safe_quote_sb(&sb, sfp->f_mntonname); |
| 2518 | sbuf_cat(&sb, "\" mount-dev=\""); |
| 2519 | devctl_safe_quote_sb(&sb, sfp->f_mntfromname); |
| 2520 | sbuf_cat(&sb, "\" mount-type=\""); |
| 2521 | devctl_safe_quote_sb(&sb, sfp->f_fstypename); |
| 2522 | sbuf_cat(&sb, "\" fsid=0x"); |
| 2523 | cp = (const uint8_t *)&sfp->f_fsid.val[0]; |
| 2524 | for (int i = 0; i < sizeof(sfp->f_fsid); i++) |
| 2525 | sbuf_printf(&sb, "%02x", cp[i]); |
| 2526 | sbuf_printf(&sb, " owner=%u flags=\"", sfp->f_owner); |
| 2527 | for (fp = optnames; fp->o_opt != 0; fp++) { |
| 2528 | if ((mp->mnt_flag & fp->o_opt) != 0) { |
| 2529 | sbuf_cat(&sb, fp->o_name); |
| 2530 | sbuf_putc(&sb, ';'); |
| 2531 | } |
| 2532 | } |
| 2533 | sbuf_putc(&sb, '"'); |
| 2534 | mount_devctl_event_mntopt(&sb, "opt", mp->mnt_opt); |
| 2535 | if (donew) |
| 2536 | mount_devctl_event_mntopt(&sb, "optnew", mp->mnt_optnew); |
| 2537 | sbuf_finish(&sb); |
| 2538 | |
| 2539 | if (sbuf_error(&sb) == 0) |
| 2540 | devctl_notify("VFS", "FS", type, sbuf_data(&sb)); |
| 2541 | sbuf_delete(&sb); |
| 2542 | free(buf, M_MOUNT); |
| 2543 | } |
| 2544 | |
| 2545 | /* |
| 2546 | * Suspend write operations on all local writeable filesystems. Does |
no test coverage detected