549 if (ret == 0 && !isopen && |
549 if (ret == 0 && !isopen && |
550 (strncmp(pool, "mirror", 6) == 0 || |
550 (strncmp(pool, "mirror", 6) == 0 || |
551 strncmp(pool, "raidz", 5) == 0 || |
551 strncmp(pool, "raidz", 5) == 0 || |
552 strncmp(pool, "spare", 5) == 0 || |
552 strncmp(pool, "spare", 5) == 0 || |
553 strcmp(pool, "log") == 0)) { |
553 strcmp(pool, "log") == 0)) { |
554 zfs_error_aux(hdl, |
554 if (hdl != NULL) |
555 dgettext(TEXT_DOMAIN, "name is reserved")); |
555 zfs_error_aux(hdl, |
|
556 dgettext(TEXT_DOMAIN, "name is reserved")); |
556 return (B_FALSE); |
557 return (B_FALSE); |
557 } |
558 } |
558 |
559 |
559 |
560 |
560 if (ret != 0) { |
561 if (ret != 0) { |
2655 |
2656 |
2656 (void) close(fd); |
2657 (void) close(fd); |
2657 efi_free(vtoc); |
2658 efi_free(vtoc); |
2658 return (0); |
2659 return (0); |
2659 } |
2660 } |
|
2661 |
|
2662 static boolean_t |
|
2663 supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf) |
|
2664 { |
|
2665 char *type; |
|
2666 nvlist_t **child; |
|
2667 uint_t children, c; |
|
2668 |
|
2669 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0); |
|
2670 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 || |
|
2671 strcmp(type, VDEV_TYPE_FILE) == 0 || |
|
2672 strcmp(type, VDEV_TYPE_LOG) == 0 || |
|
2673 strcmp(type, VDEV_TYPE_MISSING) == 0) { |
|
2674 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |
|
2675 "vdev type '%s' is not supported"), type); |
|
2676 (void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf); |
|
2677 return (B_FALSE); |
|
2678 } |
|
2679 if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN, |
|
2680 &child, &children) == 0) { |
|
2681 for (c = 0; c < children; c++) { |
|
2682 if (!supported_dump_vdev_type(hdl, child[c], errbuf)) |
|
2683 return (B_FALSE); |
|
2684 } |
|
2685 } |
|
2686 return (B_TRUE); |
|
2687 } |
|
2688 |
|
2689 /* |
|
2690 * check if this zvol is allowable for use as a dump device; zero if |
|
2691 * it is, > 0 if it isn't, < 0 if it isn't a zvol |
|
2692 */ |
|
2693 int |
|
2694 zvol_check_dump_config(char *arg) |
|
2695 { |
|
2696 zpool_handle_t *zhp = NULL; |
|
2697 nvlist_t *config, *nvroot; |
|
2698 char *p, *volname; |
|
2699 nvlist_t **top; |
|
2700 uint_t toplevels; |
|
2701 libzfs_handle_t *hdl; |
|
2702 char errbuf[1024]; |
|
2703 char poolname[ZPOOL_MAXNAMELEN]; |
|
2704 int pathlen = strlen(ZVOL_FULL_DEV_DIR); |
|
2705 int ret = 1; |
|
2706 |
|
2707 if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) { |
|
2708 return (-1); |
|
2709 } |
|
2710 |
|
2711 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, |
|
2712 "dump is not supported on device '%s'"), arg); |
|
2713 |
|
2714 if ((hdl = libzfs_init()) == NULL) |
|
2715 return (1); |
|
2716 libzfs_print_on_error(hdl, B_TRUE); |
|
2717 |
|
2718 volname = arg + pathlen; |
|
2719 |
|
2720 /* check the configuration of the pool */ |
|
2721 if ((p = strchr(volname, '/')) == NULL) { |
|
2722 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |
|
2723 "malformed dataset name")); |
|
2724 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); |
|
2725 return (1); |
|
2726 } else if (p - volname >= ZFS_MAXNAMELEN) { |
|
2727 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |
|
2728 "dataset name is too long")); |
|
2729 (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf); |
|
2730 return (1); |
|
2731 } else { |
|
2732 (void) strncpy(poolname, volname, p - volname); |
|
2733 poolname[p - volname] = '\0'; |
|
2734 } |
|
2735 |
|
2736 if ((zhp = zpool_open(hdl, poolname)) == NULL) { |
|
2737 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |
|
2738 "could not open pool '%s'"), poolname); |
|
2739 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf); |
|
2740 goto out; |
|
2741 } |
|
2742 config = zpool_get_config(zhp, NULL); |
|
2743 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, |
|
2744 &nvroot) != 0) { |
|
2745 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |
|
2746 "could not obtain vdev configuration for '%s'"), poolname); |
|
2747 (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf); |
|
2748 goto out; |
|
2749 } |
|
2750 |
|
2751 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, |
|
2752 &top, &toplevels) == 0); |
|
2753 if (toplevels != 1) { |
|
2754 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, |
|
2755 "'%s' has multiple top level vdevs"), poolname); |
|
2756 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf); |
|
2757 goto out; |
|
2758 } |
|
2759 |
|
2760 if (!supported_dump_vdev_type(hdl, top[0], errbuf)) { |
|
2761 goto out; |
|
2762 } |
|
2763 ret = 0; |
|
2764 |
|
2765 out: |
|
2766 if (zhp) |
|
2767 zpool_close(zhp); |
|
2768 libzfs_fini(hdl); |
|
2769 return (ret); |
|
2770 } |