diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-06-29 13:28:56 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-06-29 13:28:56 +0000 |
commit | e9686f2048541f02e63b97976f385b6efa0f4831 (patch) | |
tree | a6f0ccfd3f6eba847c5e23e1b9d0f75a90d07a3c | |
parent | 9f27b084492b24583dbcc44e59ce9eaacd78ed68 (diff) | |
parent | c7832f2df55c7f8d07e31fd48692e0cb47da34a2 (diff) | |
download | illumos-joyent-e9686f2048541f02e63b97976f385b6efa0f4831.tar.gz |
[illumos-gate merge]
commit c7832f2df55c7f8d07e31fd48692e0cb47da34a2
11218 loader: load vga text font
commit d646956405faf5fdc9460e6b19af1bcb7a5c11ae
11171 pam_modules: NULL pointer errors
commit da7753c428994e4e6c715886c93d7b49390c3705
11052 ZFS Reads may result in unneccesary calls to zil_commit
commit a1d63828c2e12098f43bb49de5b78a6bafc80979
11212 loader: console c_probe callback must be reusable
commit ffca9b6bef40a4b4cb6c2739812326c6234f7984
11090 libconv: NULL pointer errors
commit 097aa9ce8122e2a595b37e2c87d970fec0d5fcbb
11217 gfx_private vga font setup should use set_font() to search for vga font
commit a60ca23dc52059ace3f92bb9a63e723ac49e649b
11276 Allow unencrypted children of encrypted datasets
commit b70e94852cee03960a3aed9ab79cbd643b648628
11216 unix: always load font module
commit 45cf6faa16c9889e61cbdb6ee3758cdf856dd994
11215 loader: always pass font module to kernel
Conflicts:
usr/src/cmd/sgs/libconv/common/corenote.c
30 files changed, 946 insertions, 282 deletions
diff --git a/usr/src/boot/sys/boot/common/multiboot2.c b/usr/src/boot/sys/boot/common/multiboot2.c index 4f6098e764..fbd9107214 100644 --- a/usr/src/boot/sys/boot/common/multiboot2.c +++ b/usr/src/boot/sys/boot/common/multiboot2.c @@ -893,10 +893,8 @@ multiboot2_exec(struct preloaded_file *fp) /* mb_kernel_cmdline() updates the environment. */ build_environment_module(); - if (have_framebuffer == true) { - /* Pass the loaded console font for kernel. */ - build_font_module(); - } + /* Pass the loaded console font for kernel. */ + build_font_module(); size = mbi_size(fp, cmdline); /* Get the size for MBI. */ diff --git a/usr/src/boot/sys/boot/efi/libefi/efi_console.c b/usr/src/boot/sys/boot/efi/libefi/efi_console.c index 1ad97635f1..a4bc6a27ec 100644 --- a/usr/src/boot/sys/boot/efi/libefi/efi_console.c +++ b/usr/src/boot/sys/boot/efi/libefi/efi_console.c @@ -444,10 +444,20 @@ efi_framebuffer_setup(void) static void efi_cons_probe(struct console *cp) { + cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; +} + +static int +efi_cons_init(struct console *cp, int arg __unused) +{ struct efi_console_data *ecd; + void *coninex; EFI_STATUS status; UINTN i, max_dim, best_mode, cols, rows; + if (cp->c_private != NULL) + return (0); + ecd = calloc(1, sizeof (*ecd)); /* * As console probing is called very early, the only reason for @@ -457,9 +467,12 @@ efi_cons_probe(struct console *cp) panic("efi_cons_probe: This system has not enough memory\n"); cp->c_private = ecd; - conout = ST->ConOut; ecd->ecd_conin = ST->ConIn; - cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; + conout = ST->ConOut; + + conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR, + DEFAULT_BGCOLOR)); + memset(keybuf, 0, KEYBUFSZ); status = BS->LocateProtocol(&ccontrol_protocol_guid, NULL, (VOID **)&console_control); @@ -509,21 +522,7 @@ efi_cons_probe(struct console *cp) /* some firmware enables the cursor when switching modes */ conout->EnableCursor(conout, FALSE); -} - -static int -efi_cons_init(struct console *cp, int arg __unused) -{ - struct efi_console_data *ecd; - void *coninex; - EFI_STATUS status; - int rc; - conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR, - DEFAULT_BGCOLOR)); - memset(keybuf, 0, KEYBUFSZ); - - ecd = cp->c_private; coninex = NULL; /* * Try to set up for SimpleTextInputEx protocol. If not available, @@ -535,9 +534,8 @@ efi_cons_init(struct console *cp, int arg __unused) ecd->ecd_coninex = coninex; gfx_framework_init(&fb_ops); - rc = tem_info_init(cp); - if (rc == 0 && tem == NULL) { + if (tem_info_init(cp) == 0 && tem == NULL) { tem = tem_init(); if (tem != NULL) tem_activate(tem, B_TRUE); diff --git a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c index 2927c3cabb..e6a1f62a8e 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c +++ b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c @@ -79,8 +79,8 @@ static struct vis_modechg_arg *modechg_arg; static tem_vt_state_t tem; #define KEYBUFSZ 10 -#define DEFAULT_FGCOLOR 7 -#define DEFAULT_BGCOLOR 0 +#define DEFAULT_FGCOLOR 7 +#define DEFAULT_BGCOLOR 0 static uint8_t keybuf[KEYBUFSZ]; /* keybuf for extended codes */ @@ -132,7 +132,7 @@ plat_stdout_is_framebuffer(void) if (vbe_available() && VBE_VALID_MODE(vbe_get_mode())) { return (1); } - return (0); + return (0); } void @@ -151,8 +151,8 @@ plat_tem_get_prom_pos(uint32_t *row, uint32_t *col) *col = 0; } else { vidc_text_get_cursor(&y, &x); - *row = (uint32_t) y; - *col = (uint32_t) x; + *row = (uint32_t)y; + *col = (uint32_t)x; } } @@ -434,7 +434,7 @@ vga_get_cp437(tem_char_t c) int min, mid, max; min = 0; - max = (sizeof(cp437table) / sizeof(struct unicp437)) - 1; + max = (sizeof (cp437table) / sizeof (struct unicp437)) - 1; if (c < cp437table[0].unicode_base || c > cp437table[max].unicode_base + cp437table[max].length) @@ -447,10 +447,10 @@ vga_get_cp437(tem_char_t c) else if (c > cp437table[mid].unicode_base + cp437table[mid].length) min = mid + 1; - else + else return (c - cp437table[mid].unicode_base + cp437table[mid].cp437_base); - } + } return ('?'); } @@ -469,7 +469,7 @@ vidc_text_cons_display(struct vis_consdisplay *da) data = (tem_char_t *)da->data; attr = (solaris_color_to_pc_color[da->bg_color & 0xf] << 4) | solaris_color_to_pc_color[da->fg_color & 0xf]; - addr = (struct cgatext *) vgatext + (da->row * TEXT_COLS + da->col); + addr = (struct cgatext *)vgatext + (da->row * TEXT_COLS + da->col); for (i = 0; i < da->width; i++) { addr[i].ch = vga_get_cp437(data[i]); @@ -630,8 +630,184 @@ vidc_probe(struct console *cp) /* XXX for now, always assume we can do BIOS screen output */ cp->c_flags |= C_PRESENTOUT; - vbe_init(); - tem = NULL; +} + +/* + * Binary searchable table for CP437 to Unicode conversion. + */ +struct cp437uni { + uint8_t cp437_base; + uint16_t unicode_base; + uint8_t length; +}; + +static const struct cp437uni cp437unitable[] = { + { 0, 0x0000, 0 }, { 1, 0x263A, 1 }, { 3, 0x2665, 1 }, + { 5, 0x2663, 0 }, { 6, 0x2660, 0 }, { 7, 0x2022, 0 }, + { 8, 0x25D8, 0 }, { 9, 0x25CB, 0 }, { 10, 0x25D9, 0 }, + { 11, 0x2642, 0 }, { 12, 0x2640, 0 }, { 13, 0x266A, 1 }, + { 15, 0x263C, 0 }, { 16, 0x25BA, 0 }, { 17, 0x25C4, 0 }, + { 18, 0x2195, 0 }, { 19, 0x203C, 0 }, { 20, 0x00B6, 0 }, + { 21, 0x00A7, 0 }, { 22, 0x25AC, 0 }, { 23, 0x21A8, 0 }, + { 24, 0x2191, 0 }, { 25, 0x2193, 0 }, { 26, 0x2192, 0 }, + { 27, 0x2190, 0 }, { 28, 0x221F, 0 }, { 29, 0x2194, 0 }, + { 30, 0x25B2, 0 }, { 31, 0x25BC, 0 }, { 32, 0x0020, 0x5e }, + { 127, 0x2302, 0 }, { 128, 0x00C7, 0 }, { 129, 0x00FC, 0 }, + { 130, 0x00E9, 0 }, { 131, 0x00E2, 0 }, { 132, 0x00E4, 0 }, + { 133, 0x00E0, 0 }, { 134, 0x00E5, 0 }, { 135, 0x00E7, 0 }, + { 136, 0x00EA, 1 }, { 138, 0x00E8, 0 }, { 139, 0x00EF, 0 }, + { 140, 0x00EE, 0 }, { 141, 0x00EC, 0 }, { 142, 0x00C4, 1 }, + { 144, 0x00C9, 0 }, { 145, 0x00E6, 0 }, { 146, 0x00C6, 0 }, + { 147, 0x00F4, 0 }, { 148, 0x00F6, 0 }, { 149, 0x00F2, 0 }, + { 150, 0x00FB, 0 }, { 151, 0x00F9, 0 }, { 152, 0x00FF, 0 }, + { 153, 0x00D6, 0 }, { 154, 0x00DC, 0 }, { 155, 0x00A2, 1 }, + { 157, 0x00A5, 0 }, { 158, 0x20A7, 0 }, { 159, 0x0192, 0 }, + { 160, 0x00E1, 0 }, { 161, 0x00ED, 0 }, { 162, 0x00F3, 0 }, + { 163, 0x00FA, 0 }, { 164, 0x00F1, 0 }, { 165, 0x00D1, 0 }, + { 166, 0x00AA, 0 }, { 167, 0x00BA, 0 }, { 168, 0x00BF, 0 }, + { 169, 0x2310, 0 }, { 170, 0x00AC, 0 }, { 171, 0x00BD, 0 }, + { 172, 0x00BC, 0 }, { 173, 0x00A1, 0 }, { 174, 0x00AB, 0 }, + { 175, 0x00BB, 0 }, { 176, 0x2591, 2 }, { 179, 0x2502, 0 }, + { 180, 0x2524, 0 }, { 181, 0x2561, 1 }, { 183, 0x2556, 0 }, + { 184, 0x2555, 0 }, { 185, 0x2563, 0 }, { 186, 0x2551, 0 }, + { 187, 0x2557, 0 }, { 188, 0x255D, 0 }, { 189, 0x255C, 0 }, + { 190, 0x255B, 0 }, { 191, 0x2510, 0 }, { 192, 0x2514, 0 }, + { 193, 0x2534, 0 }, { 194, 0x252C, 0 }, { 195, 0x251C, 0 }, + { 196, 0x2500, 0 }, { 197, 0x253C, 0 }, { 198, 0x255E, 1 }, + { 200, 0x255A, 0 }, { 201, 0x2554, 0 }, { 202, 0x2569, 0 }, + { 203, 0x2566, 0 }, { 204, 0x2560, 0 }, { 205, 0x2550, 0 }, + { 206, 0x256C, 0 }, { 207, 0x2567, 1 }, { 209, 0x2564, 1 }, + { 211, 0x2559, 0 }, { 212, 0x2558, 0 }, { 213, 0x2552, 1 }, + { 215, 0x256B, 0 }, { 216, 0x256A, 0 }, { 217, 0x2518, 0 }, + { 218, 0x250C, 0 }, { 219, 0x2588, 0 }, { 220, 0x2584, 0 }, + { 221, 0x258C, 0 }, { 222, 0x2590, 0 }, { 223, 0x2580, 0 }, + { 224, 0x03B1, 0 }, { 225, 0x00DF, 0 }, { 226, 0x0393, 0 }, + { 227, 0x03C0, 0 }, { 228, 0x03A3, 0 }, { 229, 0x03C3, 0 }, + { 230, 0x00B5, 0 }, { 231, 0x03C4, 0 }, { 232, 0x03A6, 0 }, + { 233, 0x0398, 0 }, { 234, 0x03A9, 0 }, { 235, 0x03B4, 0 }, + { 236, 0x221E, 0 }, { 237, 0x03C6, 0 }, { 238, 0x03B5, 0 }, + { 239, 0x2229, 0 }, { 240, 0x2261, 0 }, { 241, 0x00B1, 0 }, + { 242, 0x2265, 0 }, { 243, 0x2264, 0 }, { 244, 0x2320, 1 }, + { 246, 0x00F7, 0 }, { 247, 0x2248, 0 }, { 248, 0x00B0, 0 }, + { 249, 0x2219, 0 }, { 250, 0x00B7, 0 }, { 251, 0x221A, 0 }, + { 252, 0x207F, 0 }, { 253, 0x00B2, 0 }, { 254, 0x25A0, 0 }, + { 255, 0x00A0, 0 } +}; + +static uint16_t +vga_cp437_to_uni(uint8_t c) +{ + int min, mid, max; + + min = 0; + max = (sizeof (cp437unitable) / sizeof (struct cp437uni)) - 1; + + while (max >= min) { + mid = (min + max) / 2; + if (c < cp437unitable[mid].cp437_base) + max = mid - 1; + else if (c > cp437unitable[mid].cp437_base + + cp437unitable[mid].length) + min = mid + 1; + else + return (c - cp437unitable[mid].cp437_base + + cp437unitable[mid].unicode_base); + } + + return ('?'); +} + +/* + * install font for text mode, borrowed from gfxp_vgatext.c + */ +static void +vidc_install_font(tem_modechg_cb_arg_t arg __unused) +{ + static uchar_t fsreg[8] = {0x0, 0x30, 0x5, 0x35, 0xa, 0x3a, 0xf, 0x3f}; + const uchar_t *from; + uchar_t volatile *to; + uint16_t c; + int i, j, s; + int bpc, f_offset; + + if (plat_stdout_is_framebuffer()) + return; + + /* Sync-reset the sequencer registers */ + vga_set_seq(VGA_REG_ADDR, 0x00, 0x01); + /* + * enable write to plane2, since fonts + * could only be loaded into plane2 + */ + vga_set_seq(VGA_REG_ADDR, 0x02, 0x04); + /* + * sequentially access data in the bit map being + * selected by MapMask register (index 0x02) + */ + vga_set_seq(VGA_REG_ADDR, 0x04, 0x07); + /* Sync-reset ended, and allow the sequencer to operate */ + vga_set_seq(VGA_REG_ADDR, 0x00, 0x03); + + /* + * select plane 2 on Read Mode 0 + */ + vga_set_grc(VGA_REG_ADDR, 0x04, 0x02); + /* + * system addresses sequentially access data, follow + * Memory Mode register bit 2 in the sequencer + */ + vga_set_grc(VGA_REG_ADDR, 0x05, 0x00); + /* + * set range of host memory addresses decoded by VGA + * hardware -- A0000h-BFFFFh (128K region) + */ + vga_set_grc(VGA_REG_ADDR, 0x06, 0x00); + + /* + * This assumes 8x16 characters, which yield the traditional 80x25 + * screen. It really should support other character heights. + */ + bpc = 16; + s = 0; /* font slot, maybe should use tunable there. */ + f_offset = s * 8 * 1024; + for (i = 0; i < 256; i++) { + c = vga_cp437_to_uni(i); + from = font_lookup(&tems.ts_font, c); + to = (unsigned char *)PTOV(VGA_MEM_ADDR) + f_offset + + i * 0x20; + for (j = 0; j < bpc; j++) + *to++ = *from++; + } + + /* Sync-reset the sequencer registers */ + vga_set_seq(VGA_REG_ADDR, 0x00, 0x01); + /* enable write to plane 0 and 1 */ + vga_set_seq(VGA_REG_ADDR, 0x02, 0x03); + /* + * enable character map selection + * and odd/even addressing + */ + vga_set_seq(VGA_REG_ADDR, 0x04, 0x03); + /* + * select font map + */ + vga_set_seq(VGA_REG_ADDR, 0x03, fsreg[s]); + /* Sync-reset ended, and allow the sequencer to operate */ + vga_set_seq(VGA_REG_ADDR, 0x00, 0x03); + + /* restore graphic registers */ + + /* select plane 0 */ + vga_set_grc(VGA_REG_ADDR, 0x04, 0x00); + /* enable odd/even addressing mode */ + vga_set_grc(VGA_REG_ADDR, 0x05, 0x10); + /* + * range of host memory addresses decoded by VGA + * hardware -- B8000h-BFFFFh (32K region) + */ + vga_set_grc(VGA_REG_ADDR, 0x06, 0x0e); + /* enable all color plane */ + vga_set_atr(VGA_REG_ADDR, 0x12, 0x0f); } static int @@ -643,6 +819,7 @@ vidc_init(struct console *cp, int arg) return (0); vidc_started = 1; + vbe_init(); /* * Check Miscellaneous Output Register (Read at 3CCh, Write at 3C2h) @@ -650,9 +827,9 @@ vidc_init(struct console *cp, int arg) * color/graphics adapter. */ if (vga_get_reg(VGA_REG_ADDR, VGA_MISC_R) & VGA_MISC_IOA_SEL) - vgatext = (uint16_t *) PTOV(VGA_MEM_ADDR + VGA_COLOR_BASE); + vgatext = (uint16_t *)PTOV(VGA_MEM_ADDR + VGA_COLOR_BASE); else - vgatext = (uint16_t *) PTOV(VGA_MEM_ADDR + VGA_MONO_BASE); + vgatext = (uint16_t *)PTOV(VGA_MEM_ADDR + VGA_MONO_BASE); /* set 16bit colors */ i = vga_get_atr(VGA_REG_ADDR, VGA_ATR_MODE); @@ -679,6 +856,8 @@ vidc_init(struct console *cp, int arg) } gfx_framework_init(&fb_ops); + /* set up callback before calling tem_info_init(). */ + tem_register_modechg_cb(vidc_install_font, (tem_modechg_cb_arg_t)cp); rc = tem_info_init(cp); if (rc != 0) { @@ -693,9 +872,9 @@ vidc_init(struct console *cp, int arg) } for (i = 0; i < 10 && vidc_ischar(cp); i++) - (void)vidc_getchar(cp); + (void) vidc_getchar(cp); - return (0); /* XXX reinit? */ + return (0); } static void @@ -802,21 +981,19 @@ vidc_devinfo(struct console *cp __unused) #if KEYBOARD_PROBE -#define PROBE_MAXRETRY 5 -#define PROBE_MAXWAIT 400 -#define IO_DUMMY 0x84 -#define IO_KBD 0x060 /* 8042 Keyboard */ +#define PROBE_MAXRETRY 5 +#define PROBE_MAXWAIT 400 +#define IO_DUMMY 0x84 +#define IO_KBD 0x060 /* 8042 Keyboard */ /* selected defines from kbdio.h */ #define KBD_STATUS_PORT 4 /* status port, read */ -#define KBD_DATA_PORT 0 /* data port, read/write - * also used as keyboard command - * and mouse command port - */ -#define KBDC_ECHO 0x00ee -#define KBDS_ANY_BUFFER_FULL 0x0001 -#define KBDS_INPUT_BUFFER_FULL 0x0002 -#define KBD_ECHO 0x00ee +/* data port, read/write also used as keyboard command and mouse command port */ +#define KBD_DATA_PORT 0 +#define KBDC_ECHO 0x00ee +#define KBDS_ANY_BUFFER_FULL 0x0001 +#define KBDS_INPUT_BUFFER_FULL 0x0002 +#define KBD_ECHO 0x00ee /* 7 microsec delay necessary for some keyboard controllers */ static void @@ -845,7 +1022,7 @@ delay1ms(void) { int i = 800; while (--i >= 0) - (void)inb(0x84); + (void) inb(0x84); } /* diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c index ce923bb039..f86d534450 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.c +++ b/usr/src/cmd/sgs/libconv/common/corenote.c @@ -2479,7 +2479,7 @@ conv_cnote_fileflags(uint32_t fileflags, Conv_fmt_flags_t fmt_flags, { 0x2000, MSG_PR_O_LARGEFILE }, { 0x20000, MSG_PR_O_NOFOLLOW }, { 0x40000, MSG_PR_O_NOLINKS }, - { 0, NULL }, + { 0, 0 }, }; arg.oflags = arg.rflags = fileflags; @@ -2531,7 +2531,7 @@ conv_cnote_filemode(uint32_t mode, Conv_fmt_flags_t fmt_flags, { 0004, MSG_S_IROTH }, { 0002, MSG_S_IWOTH }, { 0001, MSG_S_IXOTH }, - { 0, NULL }, + { 0, 0 }, }; arg.oflags = arg.rflags = mode & ~(0xf000); @@ -2570,7 +2570,7 @@ conv_cnote_filemode(uint32_t mode, Conv_fmt_flags_t fmt_flags, s = MSG_S_IFPORT; break; default: - s = NULL; + s = 0; break; } diff --git a/usr/src/lib/libzfs/common/libzfs_crypto.c b/usr/src/lib/libzfs/common/libzfs_crypto.c index 4533ed8111..7c16207a58 100644 --- a/usr/src/lib/libzfs/common/libzfs_crypto.c +++ b/usr/src/lib/libzfs/common/libzfs_crypto.c @@ -787,14 +787,6 @@ zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props, pcrypt = ZIO_CRYPT_OFF; } - /* Check for encryption being explicitly truned off */ - if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) { - ret = EINVAL; - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "Invalid encryption value. Dataset must be encrypted.")); - goto out; - } - /* Get the inherited encryption property if we don't have it locally */ if (!local_crypt) crypt = pcrypt; @@ -885,10 +877,6 @@ int zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp, char *parent_name, nvlist_t *props) { - int ret; - zfs_handle_t *pzhp = NULL; - uint64_t pcrypt, ocrypt; - /* * No encryption properties should be specified. They will all be * inherited from the origin dataset. @@ -897,40 +885,12 @@ zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp, nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION)) || nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_ENCRYPTION)) || nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS))) { - ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Encryption properties must inherit from origin dataset.")); - goto out; - } - - /* get a reference to parent dataset, should never be NULL */ - pzhp = make_dataset_handle(hdl, parent_name); - if (pzhp == NULL) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "Failed to lookup parent.")); - return (ENOENT); - } - - /* Lookup parent's crypt */ - pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION); - ocrypt = zfs_prop_get_int(origin_zhp, ZFS_PROP_ENCRYPTION); - - /* all children of encrypted parents must be encrypted */ - if (pcrypt != ZIO_CRYPT_OFF && ocrypt == ZIO_CRYPT_OFF) { - ret = EINVAL; - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "Cannot create unencrypted clone as a child " - "of encrypted parent.")); - goto out; + return (EINVAL); } - zfs_close(pzhp); return (0); - -out: - if (pzhp != NULL) - zfs_close(pzhp); - return (ret); } typedef struct loadkeys_cbdata { diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index dee622b5de..9fd133c00a 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -4514,16 +4514,9 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive, "with the new name")); (void) zfs_error(hdl, EZFS_EXISTS, errbuf); } else if (errno == EACCES) { - if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) == - ZIO_CRYPT_OFF) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "cannot rename an unencrypted dataset to " - "be a decendent of an encrypted one")); - } else { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "cannot move encryption child outside of " - "its encryption root")); - } + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "cannot move encrypted child outside of " + "its encryption root")); (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf); } else { (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf); diff --git a/usr/src/lib/libzfs/common/libzfs_sendrecv.c b/usr/src/lib/libzfs/common/libzfs_sendrecv.c index c933a24e89..a25574cc19 100644 --- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c +++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c @@ -63,7 +63,7 @@ extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *); static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *, recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int, - uint64_t *, const char *); + uint64_t *, const char *, nvlist_t *); static int guid_to_name(libzfs_handle_t *, const char *, uint64_t, boolean_t, char *); @@ -2645,7 +2645,7 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *destname, is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0'; (void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL); - /* we don't need to do anything for unencrypted filesystems */ + /* we don't need to do anything for unencrypted datasets */ if (crypt == ZIO_CRYPT_OFF) { zfs_close(zhp); continue; @@ -2997,7 +2997,8 @@ again: static int zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname, recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc, - char **top_zfs, int cleanup_fd, uint64_t *action_handlep) + char **top_zfs, int cleanup_fd, uint64_t *action_handlep, + nvlist_t *cmdprops) { nvlist_t *stream_nv = NULL; avl_tree_t *stream_avl = NULL; @@ -3174,7 +3175,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname, */ error = zfs_receive_impl(hdl, destname, NULL, flags, fd, sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd, - action_handlep, sendsnap); + action_handlep, sendsnap, cmdprops); if (error == ENODATA) { error = 0; break; @@ -3350,7 +3351,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr, dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd, - uint64_t *action_handlep, const char *finalsnap) + uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops) { zfs_cmd_t zc = { 0 }; time_t begin_time; @@ -3371,6 +3372,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, char *snapname = NULL; nvlist_t *props = NULL; char tmp_keylocation[MAXNAMELEN]; + nvlist_t *rcvprops = NULL; /* props received from the send stream */ + nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */ begin_time = time(NULL); bzero(tmp_keylocation, MAXNAMELEN); @@ -3721,8 +3724,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, zfs_close(zhp); } else { - zfs_handle_t *zhp; - /* * Destination filesystem does not exist. Therefore we better * be creating a new filesystem (either from a full backup, or @@ -3752,39 +3753,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, goto out; } - /* - * It is invalid to receive a properties stream that was - * unencrypted on the send side as a child of an encrypted - * parent. Technically there is nothing preventing this, but - * it would mean that the encryption=off property which is - * locally set on the send side would not be received correctly. - * We can infer encryption=off if the stream is not raw and - * properties were included since the send side will only ever - * send the encryption property in a raw nvlist header. - */ - if (!raw && props != NULL) { - uint64_t crypt; - - zhp = zfs_open(hdl, zc.zc_name, ZFS_TYPE_DATASET); - if (zhp == NULL) { - err = zfs_error(hdl, EZFS_BADRESTORE, - errbuf); - goto out; - } - - crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION); - zfs_close(zhp); - - if (crypt != ZIO_CRYPT_OFF) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "parent '%s' must not be encrypted to " - "receive unencrypted property"), - zc.zc_name); - err = zfs_error(hdl, EZFS_BADPROP, errbuf); - goto out; - } - } - newfs = B_TRUE; *cp = '/'; } @@ -3807,6 +3775,24 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap, goto out; } + /* + * When sending with properties (zfs send -p), the encryption property + * is not included because it is a SETONCE property and therefore + * treated as read only. However, we are always able to determine its + * value because raw sends will include it in the DRR_BDEGIN payload + * and non-raw sends with properties are not allowed for encrypted + * datasets. Therefore, if this is a non-raw properties stream, we can + * infer that the value should be ZIO_CRYPT_OFF and manually add that + * to the received properties. + */ + if (stream_wantsnewfs && !raw && rcvprops != NULL && + !nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) { + if (oxprops == NULL) + oxprops = fnvlist_alloc(); + fnvlist_add_uint64(oxprops, + zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF); + } + zc.zc_nvlist_dst = (uint64_t)(uintptr_t)prop_errbuf; zc.zc_nvlist_dst_size = sizeof (prop_errbuf); zc.zc_cleanup_fd = cleanup_fd; @@ -4080,7 +4066,7 @@ static int zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, const char *originsnap, recvflags_t *flags, int infd, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd, - uint64_t *action_handlep, const char *finalsnap) + uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops) { int err; dmu_replay_record_t drr, drr_noswap; @@ -4182,12 +4168,12 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, } return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags, &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs, - cleanup_fd, action_handlep, finalsnap)); + cleanup_fd, action_handlep, finalsnap, cmdprops)); } else { assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_COMPOUNDSTREAM); return (zfs_receive_package(hdl, infd, tosnap, flags, &drr, - &zcksum, top_zfs, cleanup_fd, action_handlep)); + &zcksum, top_zfs, cleanup_fd, action_handlep, cmdprops)); } } @@ -4217,7 +4203,7 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props, VERIFY(cleanup_fd >= 0); err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL, - stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL); + stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL, props); VERIFY(0 == close(cleanup_fd)); diff --git a/usr/src/lib/pam_modules/dhkeys/dhkeys.c b/usr/src/lib/pam_modules/dhkeys/dhkeys.c index b37e422296..bcde37a8b3 100644 --- a/usr/src/lib/pam_modules/dhkeys/dhkeys.c +++ b/usr/src/lib/pam_modules/dhkeys/dhkeys.c @@ -257,8 +257,9 @@ establish_key(pam_handle_t *pamh, int flags, int debug, char *netname) if (passwd) { (void) strlcpy(short_pass, passwd, sizeof (short_pass)); short_passp = short_pass; - } else + } else { short_passp = NULL; + } if (mechs = __nis_get_mechanisms(FALSE)) { @@ -408,7 +409,7 @@ remove_key(pam_handle_t *pamh, int flags, int debug) pthread_t tid; (void) pam_get_item(pamh, PAM_USER, (void **)&uname); - if (uname == NULL || *uname == NULL) { + if (uname == NULL || *uname == '\0') { if (debug) syslog(LOG_DEBUG, "pam_dhkeys: user NULL or empty in remove_key()"); @@ -442,8 +443,9 @@ remove_key(pam_handle_t *pamh, int flags, int debug) pwu_rep->type = auth_rep->type; pwu_rep->scope = auth_rep->scope; pwu_rep->scope_len = auth_rep->scope_len; - } else + } else { pwu_rep = PWU_DEFAULT_REP; + } /* Retrieve user's uid/gid from the password repository */ attr_pw[0].type = ATTR_UID; attr_pw[0].next = &attr_pw[1]; diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf index c0a85644aa..e2a3c9fa2f 100644 --- a/usr/src/pkg/manifests/system-test-zfstest.mf +++ b/usr/src/pkg/manifests/system-test-zfstest.mf @@ -196,6 +196,7 @@ file path=opt/zfs-tests/bin/rm_lnkcnt_zero_file mode=0555 file path=opt/zfs-tests/bin/zfstest mode=0555 file path=opt/zfs-tests/callbacks/zfs_dbgmsg mode=0555 file path=opt/zfs-tests/callbacks/zfs_mmp mode=0555 +file path=opt/zfs-tests/include/blkdev.shlib mode=0444 file path=opt/zfs-tests/include/commands.cfg mode=0444 file path=opt/zfs-tests/include/default.cfg mode=0444 file path=opt/zfs-tests/include/libtest.shlib mode=0444 @@ -2806,6 +2807,8 @@ file path=opt/zfs-tests/tests/functional/rsend/send-c_volume mode=0555 file path=opt/zfs-tests/tests/functional/rsend/send-c_zstreamdump mode=0555 file path=opt/zfs-tests/tests/functional/rsend/send-cpL_varied_recsize \ mode=0555 +file path=opt/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol \ + mode=0555 file path=opt/zfs-tests/tests/functional/rsend/send_encrypted_files mode=0555 file path=opt/zfs-tests/tests/functional/rsend/send_encrypted_hierarchy \ mode=0555 diff --git a/usr/src/test/zfs-tests/include/blkdev.shlib b/usr/src/test/zfs-tests/include/blkdev.shlib new file mode 100644 index 0000000000..bf4bfbbd87 --- /dev/null +++ b/usr/src/test/zfs-tests/include/blkdev.shlib @@ -0,0 +1,449 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# Copyright (c) 2012, 2016 by Delphix. All rights reserved. +# Copyright 2016 Nexenta Systems, Inc. +# Copyright (c) 2016, 2017 by Intel Corporation. All rights reserved. +# Copyright (c) 2017 Lawrence Livermore National Security, LLC. +# Copyright (c) 2017 Datto Inc. +# Copyright (c) 2017 Open-E, Inc. All Rights Reserved. +# + +# +# Returns SCSI host number for the given disk +# +function get_scsi_host #disk +{ + typeset disk=$1 + ls /sys/block/${disk}/device/scsi_device | cut -d : -f 1 +} + +# +# Cause a scan of all scsi host adapters by default +# +# $1 optional host number +# +function scan_scsi_hosts +{ + typeset hostnum=${1} + + if is_linux; then + if [[ -z $hostnum ]]; then + for host in /sys/class/scsi_host/host*; do + log_must eval "echo '- - -' > $host/scan" + done + else + log_must eval \ + "echo /sys/class/scsi_host/host$hostnum/scan" \ + > /dev/null + log_must eval \ + "echo '- - -' > /sys/class/scsi_host/host$hostnum/scan" + fi + fi +} + +# +# Wait for newly created block devices to have their minors created. +# +function block_device_wait +{ + if is_linux; then + udevadm trigger + udevadm settle + fi +} + +# +# Check if the given device is physical device +# +function is_physical_device #device +{ + typeset device=${1#$DEV_DSKDIR} + device=${device#$DEV_RDSKDIR} + + if is_linux; then + [[ -b "$DEV_DSKDIR/$device" ]] && \ + [[ -f /sys/module/loop/parameters/max_part ]] + return $? + else + echo $device | egrep "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1 + return $? + fi +} + +# +# Check if the given device is a real device (ie SCSI device) +# +function is_real_device #disk +{ + typeset disk=$1 + [[ -z $disk ]] && log_fail "No argument for disk given." + + if is_linux; then + lsblk $DEV_RDSKDIR/$disk -o TYPE 2>/dev/null | \ + egrep disk >/dev/null + return $? + fi +} + +# +# Check if the given device is a loop device +# +function is_loop_device #disk +{ + typeset disk=$1 + [[ -z $disk ]] && log_fail "No argument for disk given." + + if is_linux; then + lsblk $DEV_RDSKDIR/$disk -o TYPE 2>/dev/null | \ + egrep loop >/dev/null + return $? + fi +} + +# +# Check if the given device is a multipath device and if there is a symbolic +# link to a device mapper and to a disk +# Currently no support for dm devices alone without multipath +# +function is_mpath_device #disk +{ + typeset disk=$1 + [[ -z $disk ]] && log_fail "No argument for disk given." + + if is_linux; then + lsblk $DEV_MPATHDIR/$disk -o TYPE 2>/dev/null | \ + egrep mpath >/dev/null + if (($? == 0)); then + readlink $DEV_MPATHDIR/$disk > /dev/null 2>&1 + return $? + else + return $? + fi + fi +} + +# Set the slice prefix for disk partitioning depending +# on whether the device is a real, multipath, or loop device. +# Currently all disks have to be of the same type, so only +# checks first disk to determine slice prefix. +# +function set_slice_prefix +{ + typeset disk + typeset -i i=0 + + if is_linux; then + while (( i < $DISK_ARRAY_NUM )); do + disk="$(echo $DISKS | nawk '{print $(i + 1)}')" + if ( is_mpath_device $disk ) && [[ -z $(echo $disk | awk 'substr($1,18,1)\ + ~ /^[[:digit:]]+$/') ]] || ( is_real_device $disk ); then + export SLICE_PREFIX="" + return 0 + elif ( is_mpath_device $disk || is_loop_device \ + $disk ); then + export SLICE_PREFIX="p" + return 0 + else + log_fail "$disk not supported for partitioning." + fi + (( i = i + 1)) + done + fi +} + +# +# Set the directory path of the listed devices in $DISK_ARRAY_NUM +# Currently all disks have to be of the same type, so only +# checks first disk to determine device directory +# default = /dev (linux) +# real disk = /dev (linux) +# multipath device = /dev/mapper (linux) +# +function set_device_dir +{ + typeset disk + typeset -i i=0 + + if is_linux; then + while (( i < $DISK_ARRAY_NUM )); do + disk="$(echo $DISKS | nawk '{print $(i + 1)}')" + if is_mpath_device $disk; then + export DEV_DSKDIR=$DEV_MPATHDIR + return 0 + else + export DEV_DSKDIR=$DEV_RDSKDIR + return 0 + fi + (( i = i + 1)) + done + else + export DEV_DSKDIR=$DEV_RDSKDIR + fi +} + +# +# Get the directory path of given device +# +function get_device_dir #device +{ + typeset device=$1 + + if ! $(is_physical_device $device) ; then + if [[ $device != "/" ]]; then + device=${device%/*} + fi + if [[ -b "$DEV_DSKDIR/$device" ]]; then + device="$DEV_DSKDIR" + fi + echo $device + else + echo "$DEV_DSKDIR" + fi +} + +# +# Get persistent name for given disk +# +function get_persistent_disk_name #device +{ + typeset device=$1 + typeset dev_id + + if is_linux; then + if is_real_device $device; then + dev_id="$(udevadm info -q all -n $DEV_DSKDIR/$device \ + | egrep disk/by-id | nawk '{print $2; exit}' \ + | nawk -F / '{print $3}')" + echo $dev_id + elif is_mpath_device $device; then + dev_id="$(udevadm info -q all -n $DEV_DSKDIR/$device \ + | egrep disk/by-id/dm-uuid \ + | nawk '{print $2; exit}' \ + | nawk -F / '{print $3}')" + echo $dev_id + else + echo $device + fi + else + echo $device + fi +} + +# +# Online or offline a disk on the system +# +# First checks state of disk. Test will fail if disk is not properly onlined +# or offlined. Online is a full rescan of SCSI disks by echoing to every +# host entry. +# +function on_off_disk # disk state{online,offline} host +{ + typeset disk=$1 + typeset state=$2 + typeset host=$3 + + [[ -z $disk ]] || [[ -z $state ]] && \ + log_fail "Arguments invalid or missing" + + if is_linux; then + if [[ $state == "offline" ]] && ( is_mpath_device $disk ); then + dm_name="$(readlink $DEV_DSKDIR/$disk \ + | nawk -F / '{print $2}')" + slave="$(ls /sys/block/${dm_name}/slaves \ + | nawk '{print $1}')" + while [[ -n $slave ]]; do + #check if disk is online + lsscsi | egrep $slave > /dev/null + if (($? == 0)); then + slave_dir="/sys/block/${dm_name}" + slave_dir+="/slaves/${slave}/device" + ss="${slave_dir}/state" + sd="${slave_dir}/delete" + log_must eval "echo 'offline' > ${ss}" + log_must eval "echo '1' > ${sd}" + lsscsi | egrep $slave > /dev/null + if (($? == 0)); then + log_fail "Offlining" \ + "$disk failed" + fi + fi + slave="$(ls /sys/block/$dm_name/slaves \ + 2>/dev/null | nawk '{print $1}')" + done + elif [[ $state == "offline" ]] && ( is_real_device $disk ); then + #check if disk is online + lsscsi | egrep $disk > /dev/null + if (($? == 0)); then + dev_state="/sys/block/$disk/device/state" + dev_delete="/sys/block/$disk/device/delete" + log_must eval "echo 'offline' > ${dev_state}" + log_must eval "echo '1' > ${dev_delete}" + lsscsi | egrep $disk > /dev/null + if (($? == 0)); then + log_fail "Offlining $disk" \ + "failed" + fi + else + log_note "$disk is already offline" + fi + elif [[ $state == "online" ]]; then + #force a full rescan + scan_scsi_hosts $host + block_device_wait + if is_mpath_device $disk; then + dm_name="$(readlink $DEV_DSKDIR/$disk \ + | nawk -F / '{print $2}')" + slave="$(ls /sys/block/$dm_name/slaves \ + | nawk '{print $1}')" + lsscsi | egrep $slave > /dev/null + if (($? != 0)); then + log_fail "Onlining $disk failed" + fi + elif is_real_device $disk; then + block_device_wait + typeset -i retries=0 + while ! lsscsi | egrep -q $disk; do + if (( $retries > 2 )); then + log_fail "Onlining $disk failed" + break + fi + (( ++retries )) + sleep 1 + done + else + log_fail "$disk is not a real dev" + fi + else + log_fail "$disk failed to $state" + fi + fi +} + +# +# Simulate disk removal +# +function remove_disk #disk +{ + typeset disk=$1 + on_off_disk $disk "offline" + block_device_wait +} + +# +# Simulate disk insertion for the given SCSI host +# +function insert_disk #disk scsi_host +{ + typeset disk=$1 + typeset scsi_host=$2 + on_off_disk $disk "online" $scsi_host + block_device_wait +} + +# +# Load scsi_debug module with specified parameters +# $blksz can be either one of: < 512b | 512e | 4Kn > +# +function load_scsi_debug # dev_size_mb add_host num_tgts max_luns blksz +{ + typeset devsize=$1 + typeset hosts=$2 + typeset tgts=$3 + typeset luns=$4 + typeset blksz=$5 + + [[ -z $devsize ]] || [[ -z $hosts ]] || [[ -z $tgts ]] || \ + [[ -z $luns ]] || [[ -z $blksz ]] && \ + log_fail "Arguments invalid or missing" + + case "$5" in + '512b') + typeset sector=512 + typeset blkexp=0 + ;; + '512e') + typeset sector=512 + typeset blkexp=3 + ;; + '4Kn') + typeset sector=4096 + typeset blkexp=0 + ;; + *) log_fail "Unsupported blksz value: $5" ;; + esac + + if is_linux; then + modprobe -n scsi_debug + if (($? != 0)); then + log_unsupported "Platform does not have scsi_debug" + "module" + fi + lsmod | egrep scsi_debug > /dev/null + if (($? == 0)); then + log_fail "scsi_debug module already installed" + else + log_must modprobe scsi_debug dev_size_mb=$devsize \ + add_host=$hosts num_tgts=$tgts max_luns=$luns \ + sector_size=$sector physblk_exp=$blkexp + block_device_wait + lsscsi | egrep scsi_debug > /dev/null + if (($? == 1)); then + log_fail "scsi_debug module install failed" + fi + fi + fi +} + +# +# Unload scsi_debug module, if needed. +# +function unload_scsi_debug +{ + log_must_retry "in use" 5 modprobe -r scsi_debug +} + +# +# Get scsi_debug device name. +# Returns basename of scsi_debug device (for example "sdb"). +# +function get_debug_device +{ + for i in {1..10} ; do + val=$(lsscsi | nawk '/scsi_debug/ {print $6; exit}' | cut -d / -f3) + + # lsscsi can take time to settle + if [ "$val" != "-" ] ; then + break + fi + sleep 1 + done + echo "$val" +} + +# +# Get actual devices used by the pool (i.e. linux sdb1 not sdb). +# +function get_pool_devices #testpool #devdir +{ + typeset testpool=$1 + typeset devdir=$2 + typeset out="" + + if is_linux; then + out=$(zpool status -P $testpool |grep ${devdir} | awk '{print $1}') + out=$(echo $out | sed -e "s|${devdir}/||g" | tr '\n' ' ') + fi + echo $out +} diff --git a/usr/src/test/zfs-tests/include/default.cfg b/usr/src/test/zfs-tests/include/default.cfg index cf61660b76..a4e0e28bee 100644 --- a/usr/src/test/zfs-tests/include/default.cfg +++ b/usr/src/test/zfs-tests/include/default.cfg @@ -141,3 +141,10 @@ export ZFS_ALL_VERSIONS="1 2 3 4 5" for i in $ZFS_ALL_VERSIONS; do eval 'export ZFS_VERSION_$i="v${i}-fs"' done + +export ZVOL_DEVDIR="/dev/zvol/dsk" +export ZVOL_RDEVDIR="/dev/zvol/rdsk" +export DEV_DSKDIR="/dev/dsk" +export DEV_RDSKDIR="/dev/rdsk" + +export NEWFS_DEFAULT_FS="ufs" diff --git a/usr/src/test/zfs-tests/include/libtest.shlib b/usr/src/test/zfs-tests/include/libtest.shlib index bf21e9da33..fbdcc85d1c 100644 --- a/usr/src/test/zfs-tests/include/libtest.shlib +++ b/usr/src/test/zfs-tests/include/libtest.shlib @@ -29,6 +29,20 @@ # . ${STF_TOOLS}/contrib/include/logapi.shlib +. ${STF_SUITE}/include/blkdev.shlib + +# Determine if this is a Linux test system +# +# Return 0 if platform Linux, 1 if otherwise + +function is_linux +{ + if [[ $(uname -o) == "GNU/Linux" ]]; then + return 0 + else + return 1 + fi +} # Determine whether a dataset is mounted # diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run index fb5c8e7bbe..c1563223ec 100644 --- a/usr/src/test/zfs-tests/runfiles/delphix.run +++ b/usr/src/test/zfs-tests/runfiles/delphix.run @@ -606,7 +606,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy', 'send_encrypted_truncated_files', 'send_realloc_encrypted_files', - 'send_mixed_raw'] + 'send_mixed_raw', 'send-wDR_encrypted_zvol'] [/opt/zfs-tests/tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run index 5d3571307e..8c26d6dfbd 100644 --- a/usr/src/test/zfs-tests/runfiles/omnios.run +++ b/usr/src/test/zfs-tests/runfiles/omnios.run @@ -605,7 +605,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy', 'send_encrypted_truncated_files', 'send_realloc_encrypted_files', - 'send_mixed_raw'] + 'send_mixed_raw', 'send-wDR_encrypted_zvol'] [/opt/zfs-tests/tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run index 451852e863..5ee4230f66 100644 --- a/usr/src/test/zfs-tests/runfiles/openindiana.run +++ b/usr/src/test/zfs-tests/runfiles/openindiana.run @@ -605,7 +605,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos', 'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy', 'send_encrypted_truncated_files', 'send_realloc_encrypted_files', - 'send_mixed_raw'] + 'send_mixed_raw', 'send-wDR_encrypted_zvol'] [/opt/zfs-tests/tests/functional/scrub_mirror] tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos', diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh index 9d5ecab0df..7e5072f0d5 100644 --- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh @@ -51,10 +51,10 @@ # yes unspec 0 1 no no keyformat specified # yes unspec 1 0 yes new encryption root, crypt inherited # yes unspec 1 1 yes new encryption root, crypt inherited -# yes off 0 0 no unencrypted child of encrypted parent -# yes off 0 1 no unencrypted child of encrypted parent -# yes off 1 0 no unencrypted child of encrypted parent -# yes off 1 1 no unencrypted child of encrypted parent +# yes off 0 0 yes unencrypted child of encrypted parent +# yes off 0 1 no keylocation given, but crypt off +# yes off 1 0 no keyformat given, but crypt off +# yes off 1 1 no keyformat given, but crypt off # yes on 0 0 yes inherited encryption, local crypt # yes on 0 1 no no keyformat specified for new key # yes on 1 0 yes new encryption root @@ -113,7 +113,9 @@ log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \ log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \ "-o keylocation=prompt $TESTPOOL/$TESTFS2/c4" -log_mustnot zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5 +log_must zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5 +log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS2/c5)" == "off" + log_mustnot zfs create -o encryption=off -o keylocation=prompt \ $TESTPOOL/$TESTFS2/c5 log_mustnot zfs create -o encryption=off -o keyformat=passphrase \ @@ -122,13 +124,13 @@ log_mustnot zfs create -o encryption=off -o keyformat=passphrase \ -o keylocation=prompt $TESTPOOL/$TESTFS2/c5 log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ - "$TESTPOOL/$TESTFS2/c5" + "$TESTPOOL/$TESTFS2/c6" log_mustnot zfs create -o encryption=on -o keylocation=prompt \ - $TESTPOOL/$TESTFS2/c6 + $TESTPOOL/$TESTFS2/c7 log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ - "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c6" + "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c7" log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ - "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c7" + "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c8" log_pass "ZFS creates datasets only if they have a valid combination of" \ "encryption properties set." diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh index 57896c6fd3..3ce5ddc36c 100644 --- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh @@ -46,7 +46,7 @@ function cleanup log_onexit cleanup -log_assert "ZFS should receive to an encrypted child dataset" +log_assert "ZFS should receive encrypted filesystems into child dataset" typeset passphrase="password" typeset snap="$TESTPOOL/$TESTFS@snap" @@ -57,14 +57,21 @@ log_must zfs snapshot $snap log_must eval "echo $passphrase | zfs create -o encryption=on" \ "-o keyformat=passphrase $TESTPOOL/$TESTFS1" +# XXX - on illumos we're currently conflicting on mount prop +log_must zfs set mountpoint=none $TESTPOOL/$TESTFS + log_note "Verifying ZFS will receive to an encrypted child" log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1" -log_note "Verifying 'send -p' will not receive to an encrypted child" -log_mustnot eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2" +log_note "Verifying 'send -p' will receive to an encrypted child" +log_must eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2" +# XXX - on illumos, not sending encryption prop yet +# log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c2)" == "off" -log_note "Verifying 'send -R' will not receive to an encrypted child" -log_mustnot eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3" +log_note "Verifying 'send -R' will receive to an encrypted child" +log_must eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3" +# XXX - on illumos, not sending encryption prop yet +# log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c3)" == "off" log_note "Verifying ZFS will not receive to an encrypted child when the" \ "parent key is unloaded" @@ -72,4 +79,4 @@ log_must zfs unmount $TESTPOOL/$TESTFS1 log_must zfs unload-key $TESTPOOL/$TESTFS1 log_mustnot eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c4" -log_pass "ZFS can receive to an encrypted child dataset" +log_pass "ZFS can receive encrypted filesystems into child dataset" diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh index 400592aaca..1b9c6e3c70 100644 --- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh +++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh @@ -23,12 +23,13 @@ # # DESCRIPTION: -# 'zfs rename' should not rename an unencrypted dataset to a child +# 'zfs rename' should be able to move an unencrypted dataset to a child # of an encrypted dataset # # STRATEGY: # 1. Create an encrypted dataset -# 2. Attempt to rename the default dataset to a child of the encrypted dataset +# 2. Rename the default dataset to a child of the encrypted dataset +# 3. Confirm the child dataset doesn't have any encryption properties # verify_runnable "both" @@ -36,16 +37,17 @@ verify_runnable "both" function cleanup { datasetexists $TESTPOOL/$TESTFS2 && \ - log_must zfs destroy $TESTPOOL/$TESTFS2 + log_must zfs destroy -r $TESTPOOL/$TESTFS2 } log_onexit cleanup -log_assert "'zfs rename' should not rename an unencrypted dataset to a" \ +log_assert "'zfs rename' should allow renaming an unencrypted dataset to a" \ "child of an encrypted dataset" log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2" -log_mustnot zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS +log_must zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS +log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS2/$TESTFS)" == "off" -log_pass "'zfs rename' does not rename an unencrypted dataset to a child" \ +log_pass "'zfs rename' allows renaming an unencrypted dataset to a child" \ "of an encrypted dataset" diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh new file mode 100755 index 0000000000..83fe3556d4 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh @@ -0,0 +1,103 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# + +# +# Copyright (c) 2018 by Datto Inc. All rights reserved. +# Copyright 2019 Joyent, Inc. +# + +. $STF_SUITE/tests/functional/rsend/rsend.kshlib + +# +# DESCRIPTION: +# Verify that zvols with dedup=on and encryption=on can be sent and received +# with a deduplicated raw send stream. +# +# STRATEGY: +# 1. Create a zvol with dedup and encryption on and put a filesystem on it +# 2. Copy a file into the zvol a few times and take a snapshot +# 3. Repeat step 2 a few times to create more snapshots +# 4. Send all snapshots in a recursive, raw, deduplicated send stream +# 5. Mount the received zvol and verify that all of the data there is correct +# + +verify_runnable "both" + +function cleanup +{ + if is_linux; then + ismounted $recvmnt ext4 && log_must umount $recvmnt + ismounted $mntpnt ext4 && log_must umount $mntpnt + else + ismounted $recvmnt ufs && log_must umount $recvmnt + ismounted $mntpnt ufs && log_must umount $mntpnt + fi + [[ -d $recvmnt ]] && log_must rm -rf $keyfile + [[ -d $mntpnt ]] && log_must rm -rf $keyfile + destroy_dataset $TESTPOOL/recv "-r" + destroy_dataset $TESTPOOL/$TESTVOL "-r" + [[ -f $keyfile ]] && log_must rm $keyfile + [[ -f $sendfile ]] && log_must rm $sendfile +} +log_onexit cleanup + +log_assert "Verify zfs can receive raw, recursive, and deduplicated send streams" + +typeset keyfile=/$TESTPOOL/pkey +typeset snap_count=5 +typeset zdev=$ZVOL_DEVDIR/$TESTPOOL/$TESTVOL +typeset mntpnt=$TESTDIR/$TESTVOL +typeset recvdev=$ZVOL_DEVDIR/$TESTPOOL/recv +typeset recvmnt=$TESTDIR/recvmnt +typeset sendfile=$TESTDIR/sendfile + +log_must eval "echo 'password' > $keyfile" + +log_must zfs create -o dedup=on -o encryption=on -o keyformat=passphrase \ + -o keylocation=file://$keyfile -V 128M $TESTPOOL/$TESTVOL +log_must block_device_wait + +if is_linux; then + log_must eval "echo 'y' | newfs -t ext4 -v $zdev" +else + log_must eval "echo 'y' | newfs $zdev" +fi +log_must mkdir -p $mntpnt +log_must mkdir -p $recvmnt +log_must mount $zdev $mntpnt + +for ((i = 1; i <= $snap_count; i++)); do + log_must dd if=/dev/urandom of=$mntpnt/file bs=1M count=1 + for ((j = 0; j < 10; j++)); do + log_must cp $mntpnt/file $mntpnt/file$j + done + + log_must sync + log_must zfs snap $TESTPOOL/$TESTVOL@snap$i +done + +log_must eval "zfs send -wDR $TESTPOOL/$TESTVOL@snap$snap_count > $sendfile" +log_must eval "zfs recv $TESTPOOL/recv < $sendfile" +log_must zfs load-key $TESTPOOL/recv +log_must block_device_wait + +log_must mount $recvdev $recvmnt + +md5_1=$(cat $mntpnt/* | md5sum | awk '{print $1}') +md5_2=$(cat $recvmnt/* | md5sum | awk '{print $1}') +[[ "$md5_1" == "$md5_2" ]] || log_fail "md5 mismatch: $md5_1 != $md5_2" + +log_pass "zfs can receive raw, recursive, and deduplicated send streams" diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c index 56eca3baa8..eb574105a7 100644 --- a/usr/src/uts/common/fs/zfs/arc.c +++ b/usr/src/uts/common/fs/zfs/arc.c @@ -1711,6 +1711,9 @@ arc_cksum_free(arc_buf_hdr_t *hdr) static boolean_t arc_hdr_has_uncompressed_buf(arc_buf_hdr_t *hdr) { + ASSERT(hdr->b_l1hdr.b_state == arc_anon || + MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr)); + for (arc_buf_t *b = hdr->b_l1hdr.b_buf; b != NULL; b = b->b_next) { if (!ARC_BUF_COMPRESSED(b)) { return (B_TRUE); @@ -1733,15 +1736,13 @@ arc_cksum_verify(arc_buf_t *buf) if (!(zfs_flags & ZFS_DEBUG_MODIFY)) return; - if (ARC_BUF_COMPRESSED(buf)) { - ASSERT(hdr->b_l1hdr.b_freeze_cksum == NULL || - arc_hdr_has_uncompressed_buf(hdr)); + if (ARC_BUF_COMPRESSED(buf)) return; - } ASSERT(HDR_HAS_L1HDR(hdr)); mutex_enter(&hdr->b_l1hdr.b_freeze_lock); + if (hdr->b_l1hdr.b_freeze_cksum == NULL || HDR_IO_ERROR(hdr)) { mutex_exit(&hdr->b_l1hdr.b_freeze_lock); return; @@ -1845,11 +1846,7 @@ arc_cksum_compute(arc_buf_t *buf) ASSERT(HDR_HAS_L1HDR(hdr)); mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock); - if (hdr->b_l1hdr.b_freeze_cksum != NULL) { - ASSERT(arc_hdr_has_uncompressed_buf(hdr)); - mutex_exit(&hdr->b_l1hdr.b_freeze_lock); - return; - } else if (ARC_BUF_COMPRESSED(buf)) { + if (hdr->b_l1hdr.b_freeze_cksum != NULL || ARC_BUF_COMPRESSED(buf)) { mutex_exit(&hdr->b_l1hdr.b_freeze_lock); return; } @@ -1953,14 +1950,10 @@ arc_buf_thaw(arc_buf_t *buf) arc_cksum_verify(buf); /* - * Compressed buffers do not manipulate the b_freeze_cksum or - * allocate b_thawed. + * Compressed buffers do not manipulate the b_freeze_cksum. */ - if (ARC_BUF_COMPRESSED(buf)) { - ASSERT(hdr->b_l1hdr.b_freeze_cksum == NULL || - arc_hdr_has_uncompressed_buf(hdr)); + if (ARC_BUF_COMPRESSED(buf)) return; - } ASSERT(HDR_HAS_L1HDR(hdr)); arc_cksum_free(hdr); @@ -1982,26 +1975,14 @@ arc_buf_thaw(arc_buf_t *buf) void arc_buf_freeze(arc_buf_t *buf) { - arc_buf_hdr_t *hdr = buf->b_hdr; - kmutex_t *hash_lock; - if (!(zfs_flags & ZFS_DEBUG_MODIFY)) return; - if (ARC_BUF_COMPRESSED(buf)) { - ASSERT(hdr->b_l1hdr.b_freeze_cksum == NULL || - arc_hdr_has_uncompressed_buf(hdr)); + if (ARC_BUF_COMPRESSED(buf)) return; - } - - hash_lock = HDR_LOCK(hdr); - mutex_enter(hash_lock); - ASSERT(HDR_HAS_L1HDR(hdr)); - ASSERT(hdr->b_l1hdr.b_freeze_cksum != NULL || - hdr->b_l1hdr.b_state == arc_anon); + ASSERT(HDR_HAS_L1HDR(buf->b_hdr)); arc_cksum_compute(buf); - mutex_exit(hash_lock); } /* @@ -2129,7 +2110,7 @@ arc_hdr_authenticate(arc_buf_hdr_t *hdr, spa_t *spa, uint64_t dsobj) void *tmpbuf = NULL; abd_t *abd = hdr->b_l1hdr.b_pabd; - ASSERT(HDR_LOCK(hdr) == NULL || MUTEX_HELD(HDR_LOCK(hdr))); + ASSERT(MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr)); ASSERT(HDR_AUTHENTICATED(hdr)); ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL); @@ -2199,7 +2180,7 @@ arc_hdr_decrypt(arc_buf_hdr_t *hdr, spa_t *spa, const zbookmark_phys_t *zb) boolean_t no_crypt = B_FALSE; boolean_t bswap = (hdr->b_l1hdr.b_byteswap != DMU_BSWAP_NUMFUNCS); - ASSERT(HDR_LOCK(hdr) == NULL || MUTEX_HELD(HDR_LOCK(hdr))); + ASSERT(MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr)); ASSERT(HDR_ENCRYPTED(hdr)); arc_hdr_alloc_pabd(hdr, B_FALSE); @@ -2319,7 +2300,7 @@ arc_buf_untransform_in_place(arc_buf_t *buf, kmutex_t *hash_lock) ASSERT(HDR_ENCRYPTED(hdr)); ASSERT3U(hdr->b_crypt_hdr.b_ot, ==, DMU_OT_DNODE); - ASSERT(HDR_LOCK(hdr) == NULL || MUTEX_HELD(HDR_LOCK(hdr))); + ASSERT(MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr)); ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL); zio_crypt_copy_dnode_bonus(hdr->b_l1hdr.b_pabd, buf->b_data, diff --git a/usr/src/uts/common/fs/zfs/dbuf.c b/usr/src/uts/common/fs/zfs/dbuf.c index 824624a3d9..e96cd84928 100644 --- a/usr/src/uts/common/fs/zfs/dbuf.c +++ b/usr/src/uts/common/fs/zfs/dbuf.c @@ -1037,7 +1037,6 @@ dbuf_read_verify_dnode_crypt(dmu_buf_impl_t *db, uint32_t flags) !DMU_OT_IS_ENCRYPTED(dn->dn_bonustype)))) err = 0; - DB_DNODE_EXIT(db); return (err); diff --git a/usr/src/uts/common/fs/zfs/dmu.c b/usr/src/uts/common/fs/zfs/dmu.c index 528b82141f..beecf4c43f 100644 --- a/usr/src/uts/common/fs/zfs/dmu.c +++ b/usr/src/uts/common/fs/zfs/dmu.c @@ -1711,6 +1711,7 @@ dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset, dmu_buf_t *dst_handle; dmu_buf_impl_t *dstdb; dmu_buf_impl_t *srcdb = (dmu_buf_impl_t *)handle; + dmu_object_type_t type; arc_buf_t *abuf; uint64_t datalen; boolean_t byteorder; @@ -1726,11 +1727,15 @@ dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset, dstdb = (dmu_buf_impl_t *)dst_handle; datalen = arc_buf_size(srcdb->db_buf); + DB_DNODE_ENTER(dstdb); + type = DB_DNODE(dstdb)->dn_type; + DB_DNODE_EXIT(dstdb); + /* allocated an arc buffer that matches the type of srcdb->db_buf */ if (arc_is_encrypted(srcdb->db_buf)) { arc_get_raw_params(srcdb->db_buf, &byteorder, salt, iv, mac); abuf = arc_loan_raw_buf(os->os_spa, dmu_objset_id(os), - byteorder, salt, iv, mac, DB_DNODE(dstdb)->dn_type, + byteorder, salt, iv, mac, type, datalen, arc_buf_lsize(srcdb->db_buf), arc_get_compression(srcdb->db_buf)); } else { @@ -1738,7 +1743,7 @@ dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset, ASSERT3U(arc_get_compression(srcdb->db_buf), ==, ZIO_COMPRESS_OFF); abuf = arc_loan_buf(os->os_spa, - DMU_OT_IS_METADATA(DB_DNODE(dstdb)->dn_type), datalen); + DMU_OT_IS_METADATA(type), datalen); } ASSERT3U(datalen, ==, arc_buf_size(abuf)); diff --git a/usr/src/uts/common/fs/zfs/dmu_objset.c b/usr/src/uts/common/fs/zfs/dmu_objset.c index 4d0a5d2fd5..8174222826 100644 --- a/usr/src/uts/common/fs/zfs/dmu_objset.c +++ b/usr/src/uts/common/fs/zfs/dmu_objset.c @@ -1259,13 +1259,6 @@ dmu_objset_clone_check(void *arg, dmu_tx_t *tx) return (SET_ERROR(EINVAL)); } - error = dmu_objset_clone_crypt_check(pdd, origin->ds_dir); - if (error != 0) { - dsl_dataset_rele(origin, FTAG); - dsl_dir_rele(pdd, FTAG); - return (error); - } - dsl_dataset_rele(origin, FTAG); dsl_dir_rele(pdd, FTAG); diff --git a/usr/src/uts/common/fs/zfs/dmu_recv.c b/usr/src/uts/common/fs/zfs/dmu_recv.c index b6f63e7e22..b72aa21922 100644 --- a/usr/src/uts/common/fs/zfs/dmu_recv.c +++ b/usr/src/uts/common/fs/zfs/dmu_recv.c @@ -306,7 +306,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) /* Open the parent of tofs */ ASSERT3U(strlen(tofs), <, sizeof (buf)); (void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1); - error = dsl_dataset_hold_flags(dp, buf, dsflags, FTAG, &ds); + error = dsl_dataset_hold(dp, buf, FTAG, &ds); if (error != 0) return (error); @@ -324,13 +324,13 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) error = dmu_objset_create_crypt_check(ds->ds_dir, drba->drba_dcp, &will_encrypt); if (error != 0) { - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(ds, FTAG); return (error); } if (will_encrypt && (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) { - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(ds, FTAG); return (SET_ERROR(EINVAL)); } } @@ -343,46 +343,46 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) error = dsl_fs_ss_limit_check(ds->ds_dir, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL, drba->drba_cred); if (error != 0) { - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(ds, FTAG); return (error); } error = dsl_fs_ss_limit_check(ds->ds_dir, 1, ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred); if (error != 0) { - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(ds, FTAG); return (error); } if (drba->drba_origin != NULL) { dsl_dataset_t *origin; - error = dsl_dataset_hold_flags(dp, drba->drba_origin, - dsflags, FTAG, &origin); + error = dsl_dataset_hold(dp, drba->drba_origin, + FTAG, &origin); if (error != 0) { - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(ds, FTAG); return (error); } if (!origin->ds_is_snapshot) { - dsl_dataset_rele_flags(origin, dsflags, FTAG); - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(origin, FTAG); + dsl_dataset_rele(ds, FTAG); return (SET_ERROR(EINVAL)); } if (dsl_dataset_phys(origin)->ds_guid != fromguid && fromguid != 0) { - dsl_dataset_rele_flags(origin, dsflags, FTAG); - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(origin, FTAG); + dsl_dataset_rele(ds, FTAG); return (SET_ERROR(ENODEV)); } if (origin->ds_dir->dd_crypto_obj != 0 && (featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) { - dsl_dataset_rele_flags(origin, dsflags, FTAG); - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(origin, FTAG); + dsl_dataset_rele(ds, FTAG); return (SET_ERROR(EINVAL)); } - dsl_dataset_rele_flags(origin, dsflags, FTAG); + dsl_dataset_rele(origin, FTAG); } - dsl_dataset_rele_flags(ds, dsflags, FTAG); + dsl_dataset_rele(ds, FTAG); error = 0; } return (error); diff --git a/usr/src/uts/common/fs/zfs/dsl_crypt.c b/usr/src/uts/common/fs/zfs/dsl_crypt.c index 3937d3cb51..3896efbc76 100644 --- a/usr/src/uts/common/fs/zfs/dsl_crypt.c +++ b/usr/src/uts/common/fs/zfs/dsl_crypt.c @@ -1588,15 +1588,8 @@ dsl_dir_rename_crypt_check(dsl_dir_t *dd, dsl_dir_t *newparent) int ret; uint64_t curr_rddobj, parent_rddobj; - if (dd->dd_crypto_obj == 0) { - /* children of encrypted parents must be encrypted */ - if (newparent->dd_crypto_obj != 0) { - ret = SET_ERROR(EACCES); - goto error; - } - + if (dd->dd_crypto_obj == 0) return (0); - } ret = dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj); if (ret != 0) @@ -1726,34 +1719,6 @@ dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin, } int -dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd) -{ - int ret; - uint64_t pcrypt, crypt; - - /* - * Check that we are not making an unencrypted child of an - * encrypted parent. - */ - ret = dsl_dir_get_crypt(parentdd, &pcrypt); - if (ret != 0) - return (ret); - - ret = dsl_dir_get_crypt(origindd, &crypt); - if (ret != 0) - return (ret); - - ASSERT3U(pcrypt, !=, ZIO_CRYPT_INHERIT); - ASSERT3U(crypt, !=, ZIO_CRYPT_INHERIT); - - if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) - return (SET_ERROR(EINVAL)); - - return (0); -} - - -int dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp, boolean_t *will_encrypt) { @@ -1783,13 +1748,6 @@ dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp, ASSERT3U(pcrypt, !=, ZIO_CRYPT_INHERIT); ASSERT3U(crypt, !=, ZIO_CRYPT_INHERIT); - /* - * We can't create an unencrypted child of an encrypted parent - * under any circumstances. - */ - if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) - return (SET_ERROR(EINVAL)); - /* check for valid dcp with no encryption (inherited or local) */ if (crypt == ZIO_CRYPT_OFF) { /* Must not specify encryption params */ diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h index 360a69b329..cf19665aae 100644 --- a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h +++ b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h @@ -209,7 +209,6 @@ void dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd, struct dsl_dataset *origin, dsl_crypto_params_t *dcp, dmu_tx_t *tx); uint64_t dsl_crypto_key_create_sync(uint64_t crypt, dsl_wrapping_key_t *wkey, dmu_tx_t *tx); -int dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd); uint64_t dsl_crypto_key_clone_sync(dsl_dir_t *origindd, dmu_tx_t *tx); void dsl_crypto_key_destroy_sync(uint64_t dckobj, dmu_tx_t *tx); diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 2ff37afb8a..2940769eb4 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -513,6 +513,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) zfsvfs_t *zfsvfs = zp->z_zfsvfs; ssize_t n, nbytes; int error = 0; + boolean_t frsync = B_FALSE; xuio_t *xuio = NULL; ZFS_ENTER(zfsvfs); @@ -550,10 +551,20 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) } } +#ifdef FRSYNC /* * If we're in FRSYNC mode, sync out this znode before reading it. + * Only do this for non-snapshots. + * + * Some platforms do not support FRSYNC and instead map it + * to FSYNC, which results in unnecessary calls to zil_commit. We + * only honor FRSYNC requests on platforms which support it. */ - if (ioflag & FRSYNC || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) + frsync = !!(ioflag & FRSYNC); +#endif + + if (zfsvfs->z_log && + (frsync || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)) zil_commit(zfsvfs->z_log, zp->z_id); /* diff --git a/usr/src/uts/i86pc/boot/boot_fb.c b/usr/src/uts/i86pc/boot/boot_fb.c index 72198f5845..1ac4789af7 100644 --- a/usr/src/uts/i86pc/boot/boot_fb.c +++ b/usr/src/uts/i86pc/boot/boot_fb.c @@ -158,13 +158,12 @@ xbi_fb_init(struct xboot_info *xbi, bcons_dev_t *bcons_dev) fb_info.cursor.visible = xbi_fb->cursor.visible; #endif + xbi_init_font(xbi); tag = (multiboot_tag_framebuffer_t *)(uintptr_t)xbi_fb->framebuffer; if (tag == NULL) { return (B_FALSE); } - xbi_init_font(xbi); - fb_info.paddr = tag->framebuffer_common.framebuffer_addr; fb_info.pitch = tag->framebuffer_common.framebuffer_pitch; fb_info.depth = tag->framebuffer_common.framebuffer_bpp; diff --git a/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h b/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h index dc49a628b0..6c6cc5e8bf 100644 --- a/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h +++ b/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h @@ -77,6 +77,7 @@ struct gfx_vga { unsigned char blue; } colormap[VGA8_CMAP_ENTRIES]; unsigned char attrib_palette[VGA_ATR_NUM_PLT]; + struct font font; }; union gfx_console { diff --git a/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c b/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c index ee0db4ef92..de48a9fe00 100644 --- a/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c +++ b/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c @@ -945,7 +945,10 @@ static void vgatext_init(struct gfxp_fb_softc *softc) { union gfx_console *console = softc->console; + bitmap_data_t *font_data; unsigned char atr_mode; + short width, height; + int i; atr_mode = vga_get_atr(&console->vga.regs, VGA_ATR_MODE); if (atr_mode & VGA_ATR_MODE_GRAPH) @@ -961,7 +964,21 @@ vgatext_init(struct gfxp_fb_softc *softc) vga_set_atr(&console->vga.regs, VGA_ATR_BDR_CLR, vga_get_atr(&console->vga.regs, pc_black)); #endif - vgatext_setfont(softc); /* need selectable font? */ + + width = VGA_TEXT_COLS; + height = VGA_TEXT_ROWS; + font_data = set_font(&height, &width, + 16 * height + BORDER_PIXELS, + 8 * width + BORDER_PIXELS); + for (i = 0; i < VFNT_MAPS; i++) { + console->vga.font.vf_map[i] = font_data->font->vf_map[i]; + console->vga.font.vf_map_count[i] = + font_data->font->vf_map_count[i]; + } + console->vga.font.vf_bytes = font_data->font->vf_bytes; + console->vga.font.vf_width = font_data->font->vf_width; + console->vga.font.vf_height = font_data->font->vf_height; + vgatext_setfont(softc); } #if defined(USE_BORDERS) @@ -1109,7 +1126,7 @@ vgatext_setfont(struct gfxp_fb_softc *softc) f_offset = s * 8 * 1024; for (i = 0; i < 256; i++) { c = vga_cp437_to_uni(i); - from = font_lookup(font_data_8x16.font, c); + from = font_lookup(&console->vga.font, c); to = (unsigned char *)console->vga.fb.addr + f_offset + i * 0x20; for (j = 0; j < bpc; j++) |