1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
|
/*
*
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Module: plugfuncs.h
*/
#ifndef EVMS_PLUGFUNCS_H_INCLUDED
#define EVMS_PLUGFUNCS_H_INCLUDED 1
#include <dlist.h>
#include <common.h>
#include <options.h>
#include <enginestructs.h>
#define ENGINE_PLUGIN_API_MAJOR_VERION 3
#define ENGINE_PLUGIN_API_MINOR_VERION 0
#define ENGINE_PLUGIN_API_PATCH_LEVEL 0
/*
* For all can_????() functions, the function returns 0 if "yes", else a reason code.
*/
typedef struct engine_functions_s {
/*
* Get a list of the user space plug-ins that are loaded, optionally
* filtering by type and flags. If the type parameter is not 0, only
* plug-ins of that type will be returned. If type is 0, all plug-ins will
* be returned. See common.h for the definitions of plugin_search_flags_t.
*/
int (*get_plugin_list)(plugin_type_t type,
plugin_search_flags_t flags,
dlist_t * plugins);
/*
* Get the plugin_record_t for a given plug-in ID.
*/
int (*get_plugin_by_ID)(plugin_id_t plugin_id,
plugin_record_t * * plugin);
/*
* Get the plugin_record_t for a given plug-in short name.
*/
int (*get_plugin_by_name)(char * plugin_short_name,
plugin_record_t * * plugin);
/*
* Get a list of volumes, optionally filtering by FSIM. If FSIM is
* specified, only volumes managed by that FSIM will be returned. If FSIM
* is NULL, all volumes will be returned.
*/
int (*get_volume_list)(plugin_record_t * fsim,
dlist_t * volume_list);
/*
* Get a list of objects, optionally filtering by object type, data type,
* and plug-in. See the object_type_t, data_type_t, and
* object_search_flags_t enums in common.h. If object_type is 0, objects of
* any type will be returned. If data_type is 0, objects of any data type
* will be returned. If plugin is NULL, objects managed by any plug-in will
* be returned.
*/
int (*get_object_list)(object_type_t object_type,
data_type_t data_type,
plugin_record_t * plugin,
object_search_flags_t flags,
dlist_t * objects);
/*
* Get a list of storage containers, optionally filtering by plug-in.
* If plugin is specified, only containers managed by that plug-in
* will be returned. If plugin is NULL, all containers will be returned.
*/
int (*get_container_list)(plugin_record_t * plugin,
dlist_t * container_list);
/*
* Issue an ioctl to the EVMS kernel block device. The Engine opens
* and locks the EVMS kernel block device. While the Engine is open
* for writing, no other application, not even Engine plug-ins, can
* open the EVMS kernel block device. Plug-ins use this service
* to have the Engine issue an ioctl to the EVMS kernel block device
* on their behalf.
*/
int (*ioctl_evms_kernel)(unsigned long cmd,
void * arg);
/*
* Allocate a storage_object_t for a logical disk structure.
*/
int (*allocate_logical_disk)(char * name,
storage_object_t * * new_disk);
/*
* Free a storage_object_t for a logical disk.
*/
int (*free_logical_disk)(storage_object_t * disk);
/*
* Allocate a storage_object_t for a disk_segment. The caller is
* responsible for putting the storage_object_t for the logical disk from
* which this segment comes into the child_objects list in the
* storage_object_t for the segment. Additionally, the caller must add the
* storage_object_t for the disk segment to the parent_objects list in the
* storage_object_t for the logical disk.
*/
int (*allocate_segment)(char * name,
storage_object_t * * new_segment);
/*
* Free a storage_object_t for a disk_segment.
*/
int (*free_segment)(storage_object_t * segment);
/*
* Allocate a storage_container_t structure. The caller fills in the
* objects_consumed and objects_produced lists in the container. The caller
* fills in the appropriate consuming_container and producing_container
* fields in the storage_object_t(s) that are consumed or produced by the
* container.
*/
int (*allocate_container)(char * name,
storage_container_t * * new_container);
/*
* Free a storage_container_t structure.
*/
int (*free_container)(storage_container_t * container);
/*
* Allocate a storage_object_t for a storage_region. The caller is
* responsible for putting the storage_object_t from which this region comes
* into the child_objects list in the storage_object_t for the region.
* Additionally, the caller must add the storage_object_t for the region to
* the parent_objects list in the storage_object_t from which this region
* comes.
*/
int (*allocate_region)(char * name,
storage_object_t * * new_region);
/*
* Free the storage_region structure.
*/
int (*free_region)(storage_object_t * region);
/*
* Allocate a storage_object_t for an EVMS object. The caller is
* responsible for putting the storage_object_t from which this EVMS object
* comes into the child_objects list in the storage_object_t for the EVMS
* object. Additionally, the caller must add the storage_object_t for the
* EVMS object to the parent_objects list in the storage_object_t from which
* this EVMS object comes.
*/
int (*allocate_evms_object)(char * name,
storage_object_t * * new_object);
/*
* Free a storage_object_t for an EVMS object.
*/
int (*free_evms_object)(storage_object_t * object);
/*
* engine_alloc is the generic memory allocation service provided by the
* Engine. Fro any memory that plug-ins return to the Engine, the plug-in
* must use the same malloc() that the Engine uses so that the Engine can
* properly free() the memory. To assist the plug-ins, the Engine provides
* a common allocation function which the plug-ins can use so that all
* memory allocations are managed by the same memory manager. Memory will
* be zero filled.
*/
void * (*engine_alloc)(u_int32_t size);
/*
* engine_free is the generic memory deallocation service provided by the
* Engine.
*/
void (*engine_free)(void *);
/*
* Check if there are any changes pending in the Engine.
*/
BOOLEAN (*changes_pending)(void);
/*
* Tell the Engine that there are changes pending, i.e., there is stuff to
* be committed to disk.
*/
void (*set_changes_pending)(void);
/*
* Check if the Engine is in the process of committing changes.
*/
BOOLEAN (*commit_in_progress)(void);
/*
* Write data to the Engine's log file.
*/
int (*write_log_entry)(debug_level_t level,
plugin_record_t * plugin,
char * fmt,
...);
/*
* Calculate a 32-bit CRC for a buffer of a given size.
* On the first call to calculate_CRC() the CRC parameter must be
* 0xffffffff.
* calculate_CRC() can be called multiple times to get the CRC for an
* aggregate of buffers. To do so, subsequent calls set the CRC parameter
* to the resulting CRC that was returned from the previous call.
* To calculate a new CRC, the CRC parameter must be set to 0xffffffff.
*/
u_int32_t (*calculate_CRC)(u_int32_t crc,
void * buffer,
u_int32_t buffer_size);
/*
* Calculate a checksum on a buffer of given size. This Engine service
* actually issues an ioctl() to the EVMS kernel to use the kernel's
* checksum function so that checksums are consistent with the runtime
* code. An error code is returned if the ioctl to the kernel fails.
* "insum" is the initial checksum value, useful if you are doing a
* single checksum on a series of multiple data blocks.
*/
int (*calculate_checksum)(unsigned char * buffer,
int buffer_size,
unsigned int insum,
unsigned int * outsum);
/*
* Add sectors that are to be written with zeros to the Engine's Kill Sector
* list. Should only be called by device managers
*/
int (*add_sectors_to_kill_list)(storage_object_t * disk, /* Disk on which the sectors reside */
lba_t lba, /* Sector number of the first sector */
/* to wipe out */
sector_count_t count); /* Number of sectors to wipe out */
/*
* Tell the Engine that this volume should be rediscovered when the changes
* are committed. Call this function if you make changes to the volume's
* underlying objects, regions, etc. that will have to be discovered by the
* kernel runtime code in order to build the volume correctly.
* Set sync_fs to TRUE if you want the file system on the volume to
* be synced in a safe state before the volume is rediscovered.
*/
int (*rediscover_volume)(logical_volume_t * volume,
BOOLEAN sync_fs);
/*
* Check to make sure this name is valid and no other object has the same
* name.
*/
int (*validate_name)(char * name);
/*
* Register the name for an object. The Engine will make sure that there is
* no other object with the same name. If the name is not valid (e.g., it's
* too long) or another object has already registered the name, an error
* will be returned.
*/
int (*register_name)(char * name);
/*
* Unregister the name of an object.
*/
int (*unregister_name)(char * name);
/*
* Ask all the parent objects of this object if they can handle this object
* expanding by the specified amount. Parent plug-ins may modify the size
* according to any constrains they have. If the size has not been changed
* by any of the parents, the Engine will return 0. If all the parents
* don't return an error but the size has been updated, the Engine will
* return EAGAIN.
*/
int (*can_expand_by)(storage_object_t * object,
sector_count_t * delta_size);
/*
* Ask all the parent objects of this object if they can handle this object
* shrinking by the specified amount. Parent plug-ins may modify the size
* according to any constrains they have. If the size has not been changed
* by any of the parents, the Engine will return 0. If all the parents
* don't return an error but the size has been updated, the Engine will
* return EAGAIN.
*/
int (*can_shrink_by)(storage_object_t * object,
sector_count_t * delta_size);
/*
* Send a message to the user interface. This service can be used in three
* ways.
*
* 1) Send a notification message to the user expecting no response.
*
* user_message(plugin_record, NULL, NULL, message_fmt, ...);
*
* 2) Ask a question and get one item selected from a list of two or more
* items.
*
* char * choices = {string1, string2, ..., NULL};
* user_message(plugin_record, &answer, choices, message_fmt, ...);
*
* The "choices" parameter is a NULL terminated array of strings that
* describe each of the choices. "*answer" *must* be initialized to the
* default response. The UI will present the message and the choices to
* the user. On return, *answer will contain the index of the selected
* choice string.
*/
int (*user_message)(plugin_record_t * plugin,
int * answer,
char * * choice_text,
char * message_fmt,
...);
/*
* user_communication() uses the option_descriptor_t structures to convey a
* group of choices to the user. Use this service when you have a complex
* list of things to ask of the user, e.g., they are of several different
* types (strings, ints, etc), they have constraints on their selection, or
* they may have dependencies on each other.
*
* The Engine will create a EVMS_Task_Message task for the UI. The UI will
* use the task when calling the evms_get_option_descriptor(),
* evms_set_option_value(), etc. APIs for getting and setting options.
* Your plug-in will be called on its set_option() function with the task
* context. The action will be EVMS_Task_Message, the task object will be
* set to the object_instance parameter that you provide on the call to
* user_communication().
*
* The "message_text" will be treated by the UI as a title for the options
* that are presented. "options" is an array of option_descriptor_t
* structures. Each of the option descriptors *must* have an initial value.
*/
int (*user_communication)(void * object_instance,
char * message_text,
option_desc_array_t * options);
/*
* Can this object be renamed? The Engine will figure out if there are any
* restrictions that would prevent the object from being renamed, e.g., the
* object is the topmost object of a compatibility volume (the volume name
* will have been derived from the object) and the volume is mounted. The
* Engine won't allow a volume that is mounted to be renamed. If the
* object cannot be renamed, the Engine will return an error code that
* (hopefully) gives some indication as to why the rename is not allowed.
* Plug-ins call this Engine service before allowing their object name to
* be changed by a set_info() call.
*/
int (*can_rename)(storage_object_t * object);
/*
* Is this volume mounted? If you want to know the name of the mount point,
* specify a location in mount_name where the service will place a pointer
* to malloced memory that contains the mount point name. Remember to free
* the string when you are finished with it. If you do not want to know the
* mount point and not have the hassle of freeing the memory, specify NULL
* for mount_name.
*/
BOOLEAN (*is_mounted)(char * volume_name,
char * * mount_name);
} engine_functions_t;
typedef struct fsim_functions_s {
int (*setup_evms_plugin)(engine_mode_t mode,
engine_functions_t * functions);
void (*cleanup_evms_plugin)(void);
/*
* Does this FSIM manage the file system on this volume?
* Return 0 for "yes", else a reason code.
*/
int (*is_this_yours)(logical_volume_t * volume);
/*
* Get the current size of the file system on this volume.
*/
int (*get_fs_size)(logical_volume_t * volume,
sector_count_t * fs_size);
/*
* Get the file system size limits for this volume.
*/
int (*get_fs_limits)(logical_volume_t * volume,
sector_count_t * fs_min_size,
sector_count_t * fs_max_size,
sector_count_t * vol_max_size);
/*
* Can you install your file system on this volume?
*/
int (*can_mkfs)(logical_volume_t * volume);
/*
* Can you remove your file system from this volume?
*/
int (*can_unmkfs)(logical_volume_t * volume);
/*
* Can you fsck this volume?
*/
int (*can_fsck)(logical_volume_t * volume);
/*
* Can you defrag this volume?
*/
int (*can_defrag)(logical_volume_t * volume);
/*
* Can you expand this volume by the amount specified?
* If your file system cannot handle expansion at all, return an
* error code that indicates why it cannot be expanded..
* If your file system can expand but cannot handle having unused
* space after the end of your file system, adjust the *delta_size
* to the maximum you allow and return 0.
* If your file system cannot fill the resulting size but your file
* system can handle extra unused space after the end of the file
* system, then do not change the *delta_size and return 0.
*/
int (*can_expand_by)(logical_volume_t * volume,
sector_count_t * delta_size);
/*
* Can you shrink this volume by the amount specified?
* If your file system cannot handle shrinking at all, return an
* error code that indicates why it cannot be shrunk.
* If your file system can shrink but the *delta_size is too much to
* shrink by, adjust the *delta_size to the maximum shrinkage you allow and
* return 0.
*/
int (*can_shrink_by)(logical_volume_t * volume,
sector_count_t * delta_size);
/*
* Install your file system on the volume.
*/
int (*mkfs)(logical_volume_t * volume,
option_array_t * options);
/*
* Remove your file system from the volume. This could be as simple as
* wiping out critical sectors, such as a superblock, so that you will
* no longer detect that your file system is installed on the volume.
*/
int (*unmkfs)(logical_volume_t * volume);
/*
* Run fsck on the volume.
*/
int (*fsck)(logical_volume_t * volume,
option_array_t * options);
/*
* Defragment on the volume.
*/
int (*defrag)(logical_volume_t * volume,
option_array_t * options);
/*
* Expand the volume to new_size. If the volume is not expanded exactly to
* new_size, set new_sie to the new_size of the volume.
*/
int (*expand)(logical_volume_t * volume,
sector_count_t * new_size);
/*
* Shrink the volume to new_size. If the volume is not expanded exactly to
* new_size, set new_size to the new_size of the volume.
*/
int (*shrink)(logical_volume_t * volume,
sector_count_t requested_size,
sector_count_t * new_size);
/*
* Return the total number of supported options for the specified task.
*/
int (*get_option_count)(task_context_t * context);
/*
* Fill in the initial list of acceptable objects. Fill in the minimum and
* maximum number of objects that must/can be selected. Set up all initial
* values in the option_descriptors in the context record for the given
* task. Some fields in the option_descriptor may be dependent on a
* selected object. Leave such fields blank for now, and fill in during the
* set_objects call.
*/
int (*init_task)(task_context_t * context);
/*
* Examine the specified value, and determine if it is valid for the task
* and option_descriptor index. If it is acceptable, set that value in the
* appropriate entry in the option_descriptor. The value may be adjusted
* if necessary/allowed. If so, set the effect return value accordingly.
*/
int (*set_option)(task_context_t * context,
u_int32_t index,
value_t * value,
task_effect_t * effect);
/*
* Validate the volumes in the selected_objects dlist in the task context.
* Remove from the selected objects lists any volumes which are not
* acceptable. For unacceptable volumes, create a declined_handle_t
* structure with the reason why it is not acceptable, and add it to the
* declined_volumes dlist. Modify the acceptable_objects dlist in the task
* context as necessary based on the selected objects and the current
* settings of the options. Modify any option settings as necessary based
* on the selected objects. Return the appropriate task_effect_t settings
* if the object list(s), minimum or maximum objects selected, or option
* settings have changed.
*/
int (*set_volumes)(task_context_t * context,
dlist_t declined_volumes, /* of type declined_handle_t */
task_effect_t * effect);
/*
* Return any additional information that you wish to provide about the
* volume. The Engine provides an external API to get the information
* stored in the logical_volume_t. This call is to get any other
* information about the volume that is not specified in the
* logical_volume_t. Any piece of information you wish to provide must be
* in an extended_info_t structure. Use the Engine's engine_alloc() to
* allocate the memory for the extended_info_t. Also use engine_alloc() to
* allocate any strings that may go into the extended_info_t. Then use
* engine_alloc() to allocate an extended_info_array_t with enough entries
* for the number of extended_info_t structures you are returning. Fill
* in the array and return it in *info.
* If you have extended_info_t descriptors that themselves may have more
* extended information, set the EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag
* in the extended_info_t flags field. If the caller wants more information
* about a particular extended_info_t item, this API will be called with a
* pointer to the storage_object_t and with a pointer to the name of the
* extended_info_t item. In that case, return an extended_info_array_t with
* further information about the item. Each of those items may have the
* EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag set if you desire. It is your
* responsibility to give the items unique names so that you know which item
* the caller is asking additional information for. If info_name is NULL,
* the caller just wants top level information about the object.
*/
int (*get_volume_info)(logical_volume_t * volume,
char * info_name,
extended_info_array_t * * info);
/*
* Apply the settings of the options to the given volume.
*/
int (*set_volume_info)(logical_volume_t * volume,
option_array_t * options);
/*
* Return any additional information that you wish to provide about your
* plug-in. The Engine provides an external API to get the information
* stored in the plugin_record_t. This call is to get any other
* information about the plug-in that is not specified in the
* plugin_record_t. Any piece of information you wish to provide must be
* in an extended_info_t structure. Use the Engine's engine_alloc() to
* allocate the memory for the extended_info_t. Also use engine_alloc() to
* allocate any strings that may go into the extended_info_t. Then use
* engine_alloc() to allocate an extended_info_array_t with enough entries
* for the number of extended_info_t structures you are returning. Fill
* in the array and return it in *info.
* If you have extended_info_t descriptors that themselves may have more
* extended information, set the EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag
* in the extended_info_t flags field. If the caller wants more information
* about a particular extended_info_t item, this API will be called with a
* pointer to the storage_object_t and with a pointer to the name of the
* extended_info_t item. In that case, return an extended_info_array_t with
* further information about the item. Each of those items may have the
* EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag set if you desire. It is your
* responsibility to give the items unique names so that you know which item
* the caller is asking additional information for. If info_name is NULL,
* the caller just wants top level information about the object.
*/
int (*get_plugin_info)(char * info_name,
extended_info_array_t * * info);
/*
*
*/
int (*direct_plugin_communication)(void * thing,
BOOLEAN target_kernel_plugin,
void * arg);
} fsim_functions_t;
typedef struct plugin_functions_s {
int (*setup_evms_plugin)(engine_mode_t mode,
engine_functions_t * functions);
void (*cleanup_evms_plugin)(void);
/*
* Can you delete this object?
*/
int (*can_delete)(storage_object_t * object);
/*
* Can you expand this object? If yes, build an expand_object_info_t and
* add it to the expand_points list. If you can't expand, but allow one of
* your children to expand, call can_expand on whichever child you will
* allow to expand. If you can not handle expanding below you, do not pass
* the command down to your child.
*/
int (*can_expand)(storage_object_t * object,
sector_count_t * expand_limit, // a delta size
dlist_t expand_points); // of type expand_object_info_t,
// tag = EXPAND_OBJECT_TAG
/*
* Can you allow your child object to expand by "size"? Return 0 if yes,
* else an error code. "size" is the delta expand BY size, not the
* resulting size. Update the "size" if your object would expand by a
* different delta size when your child object expanded by the given size.
*/
int (*can_expand_by)(storage_object_t * object,
sector_count_t * size);
/*
* Can you shrink this object? If yes, build an shrink_object_info_t and
* add it to the shrink_points list. If you can't shrink, but allow one of
* your children to shrink, call can_shrink on whichever child you will
* allow to shrink. If you can not handle shrinking below you, do not pass
* the command down to your child.
*/
int (*can_shrink)(storage_object_t * object,
sector_count_t * shrink_limit, // a delta size
dlist_t shrink_points); // of type shrink_object_info_t,
// tag = SHRINK_OBJECT_TAG
/*
* Can you allow your child object to shrink by "size"? Return 0 if yes,
* else an error code. "size" is the delta shrink BY size, not the
* resulting size. Update the "size" if your object would shrink by a
* different delta size when your child object shrunk by the given size.
*/
int (*can_shrink_by)(storage_object_t * object,
sector_count_t * size);
/*
* Can you move this object?
*/
int (*can_move)(storage_object_t * object);
/*
* Will you allow your object to be made into a volume? (We don't see
* any reason why you wouldn't.) Will you allow a volume to be reverted
* off the top of your object? The "flag" parameter says whether the
* volume is to be created (TRUE) or removed (FALSE).
*/
int (*can_set_volume)(storage_object_t * object,
BOOLEAN flag);
/*
* Claim objects by removing them from the list. Create a storage_object_t
* for the object you are discovering, fill in the appropriate fields and
* put the new object on the output_objects list. If you do not claim an
* object from the input list, then just copy/move it to the output list.
* The input list can be modified at will. The output list must contain
* all the storage objects in the system after yours are discovered, i.e.,
* it is the input list, minus the objects you claim, plus the objects you
* produce.
*/
int (*discover)(dlist_t input_objects,
dlist_t output_objects,
BOOLEAN final_call);
/*
* Create storage_object_t(s) from the list of objects using the given
* options. Return the newly allocated storage_object_t(s) in new_objects
* list.
*/
int (*create)(dlist_t input_objects,
option_array_t * options,
dlist_t output_objects);
/*
* Delete the object. Free any privately allocated data. Remove your
* parent pointer from your child objects. Do any cleanup necessary to
* remove your plug-in from your child objects. Put your object's children
* from the object's child_objects dlist_t onto the dlist_t provided in the
* second parameter. Call the Engine's free_?????t() to free the object.
*/
int (*delete)(storage_object_t * object,
dlist_t child_objects);
/*
* If the "object" is not the "expand_object", then your child is going to
* expand. Do any necessary work to get ready for your child to expand,
* e.g., read in meta data, then call expand() on your child object which
* will expand. Upon return from the call to your child's expand(), do
* any work necessary to adjust this object to account for the child
* object's new size, e.g., update the location of meta data.
* If the "object" is the same as the "expand_object", then this is the
* object targeted for expanding. Expand the object according to the
* input_objects given and the options selected.
*/
int (*expand)(storage_object_t * object,
storage_object_t * expand_object,
dlist_t input_objects,
option_array_t * options);
/*
* If the "object" is not the "shrink_object", then your child is going to
* shrink. Do any necessary work to get ready for your child to shrink,
* e.g., read in meta data, then call shrink() on your child object which
* will shrink. Upon return from the call to your child's shrink(), do
* any work necessary to adjust this object to account for the child
* object's new size, e.g., update the location of meta data.
* If the "object" is the same as the "shrink_object", then this is the
* object targeted for shrinking. Shrink the object according to the
* input_objects given and the options selected.
*/
int (*shrink)(storage_object_t * object,
storage_object_t * shrink_object,
dlist_t input_objects,
option_array_t * options);
/*
* Move the contents of the source object to the target object using the
* given options.
*/
int (*move)(storage_object_t * source,
storage_object_t * target,
option_array_t * options);
/*
* This call notifies you that your object is being made into (or part of)
* a volume or that your object is no longer part of a volume. The "flag"
* parameter indicates whether the volume is being created (TRUE) or
* removed (FALSE).
*/
void (*set_volume)(storage_object_t * object,
BOOLEAN flag);
/*
* Put sectors on the kill list. The plug-in translates the lsn and count
* into lsn(s) and count(s) for its child object(s) and calls the child
* object's add_sectors_to_kill_list().
* The Device Manager calls the Engine's add_sectors_to_kill_list service
* to put the sectors on the Engine's kill list.
*/
int (*add_sectors_to_kill_list)(storage_object_t * object,
lsn_t lsn,
sector_count_t count);
/*
* Write your plug-ins data, e.g., feature header and feature meta data, to
* disk. Clear the SOFLAG_DIRTY in the storage_object_t(s).
* Committing changes in done in several (two for now) phases. "phase"
* says which phase of the commit is being performed.
* Write your first copy of meta data during phase 1; write your second
* copy of meta data (if you have one) during phase 2.
*/
int (*commit_changes)(storage_object_t * object,
uint phase);
/*
* Return the total number of supported options for the specified task.
*/
int (*get_option_count)(task_context_t * context);
/*
* Fill in the initial list of acceptable objects. Fill in the minimum and
* maximum number of objects that must/can be selected. Set up all initial
* values in the option_descriptors in the context record for the given
* task. Some fields in the option_descriptor may be dependent on a
* selected object. Leave such fields blank for now, and fill in during the
* set_objects call.
*/
int (*init_task)(task_context_t * context);
/*
* Examine the specified value, and determine if it is valid for the task
* and option_descriptor index. If it is acceptable, set that value in the
* appropriate entry in the option_descriptor. The value may be adjusted
* if necessary/allowed. If so, set the effect return value accordingly.
*/
int (*set_option)(task_context_t * context,
u_int32_t index,
value_t * value,
task_effect_t * effect);
/*
* Validate the objects in the selected_objects dlist in the task context.
* Remove from the selected objects lists any objects which are not
* acceptable. For unacceptable objects, create a declined_handle_t
* structure with the reason why it is not acceptable, and add it to the
* declined_objects dlist. Modify the acceptable_objects dlist in the task
* context as necessary based on the selected objects and the current
* settings of the options. Modify any option settings as necessary based
* on the selected objects. Return the appropriate task_effect_t settings
* if the object list(s), minimum or maximum objects selected, or option
* settings have changed.
*/
int (*set_objects)(task_context_t * context,
dlist_t declined_objects, /* of type declined_handle_t */
task_effect_t * effect);
/*
* Return any additional information that you wish to provide about the
* object. The Engine provides an external API to get the information
* stored in the storage_object_t. This call is to get any other
* information about the object that is not specified in the
* storage_object_t. Any piece of information you wish to provide must be
* in an extended_info_t structure. Use the Engine's engine_alloc() to
* allocate the memory for the extended_info_t. Also use engine_alloc() to
* allocate any strings that may go into the extended_info_t. Then use
* engine_alloc() to allocate an extended_info_array_t with enough entries
* for the number of extended_info_t structures you are returning. Fill
* in the array and return it in *info.
* If you have extended_info_t descriptors that themselves may have more
* extended information, set the EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag
* in the extended_info_t flags field. If the caller wants more information
* about a particular extended_info_t item, this API will be called with a
* pointer to the storage_object_t and with a pointer to the name of the
* extended_info_t item. In that case, return an extended_info_array_t with
* further information about the item. Each of those items may have the
* EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag set if you desire. It is your
* responsibility to give the items unique names so that you know which item
* the caller is asking additional information for. If info_name is NULL,
* the caller just wants top level information about the object.
*/
int (*get_info)(storage_object_t * object,
char * info_name,
extended_info_array_t * * info);
/*
* Apply the settings of the options to the given object.
*/
int (*set_info)(storage_object_t * object,
option_array_t * options);
/*
* Return any additional information that you wish to provide about your
* plug-in. The Engine provides an external API to get the information
* stored in the plugin_record_t. This call is to get any other
* information about the plug-in that is not specified in the
* plugin_record_t. Any piece of information you wish to provide must be
* in an extended_info_t structure. Use the Engine's engine_alloc() to
* allocate the memory for the extended_info_t. Also use engine_alloc() to
* allocate any strings that may go into the extended_info_t. Then use
* engine_alloc() to allocate an extended_info_array_t with enough entries
* for the number of extended_info_t structures you are returning. Fill
* in the array and return it in *info.
* If you have extended_info_t descriptors that themselves may have more
* extended information, set the EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag
* in the extended_info_t flags field. If the caller wants more information
* about a particular extended_info_t item, this API will be called with a
* pointer to the storage_object_t and with a pointer to the name of the
* extended_info_t item. In that case, return an extended_info_array_t with
* further information about the item. Each of those items may have the
* EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag set if you desire. It is your
* responsibility to give the items unique names so that you know which item
* the caller is asking additional information for. If info_name is NULL,
* the caller just wants top level information about the object.
*/
int (*get_plugin_info)(char * info_name,
extended_info_array_t * * info);
/*
* Convert lsn and count to lsn and count on the child object(s) and and
* call the read function of child objects.
*/
int (*read)(storage_object_t * object,
lsn_t lsn,
sector_count_t count,
void * buffer);
/*
* Convert lsn and count to lsn and count on the child object(s) and and
* call the write function of child objects.
*/
int (*write)(storage_object_t * object,
lsn_t lsn,
sector_count_t count,
void * buffer);
/*
*
*/
int (*direct_plugin_communication)(void * thing,
BOOLEAN target_kernel_plugin,
void * arg);
} plugin_functions_t;
typedef struct container_functions_s {
/*
* Can you create a container from this list of EVMS_Data_Segments?
*/
int (*can_create_container)(dlist_t objects);
/*
* Can you destroy the container and move all segments into a default
* (or unassigned) container? Must check to be sure that no regions are
* exported from this container.
*/
int (*can_delete_container)(storage_container_t * container);
/*
* Can you add this object to the container?
* Return 0 if you can, else return an error code.
*/
int (*can_add_object)(storage_object_t * object,
storage_container_t * container);
/*
* Can you remove this object from the container that currently consumes
* it? Return 0 if you can, else return an error code.
*/
int (*can_remove_object)(storage_object_t * object);
/*
* Create and fill in the container adding newly created unallocated objects
* produced as appropriate. The plug-in must claim the objects, as it does
* in discovery. Mark the container dirty. Must use allocate_container
* engine API to allocate the container structure.
*/
int (*create_container)(dlist_t objects,
option_array_t * options,
storage_container_t * * container);
/*
* Engine will remove the object from its current container before calling
* this API. Claim the object and add it to a container objects_consumed
* list. Mark the container dirty. Update/allocate the unallocated object
* that is exported from the container. If container is NULL, add the
* object to default (or unassigned) container.
*/
int (*add_object)(storage_object_t * object,
storage_container_t * container,
option_array_t * options);
/*
* Transfer the object from its current container to the specified
* container. Mark the container dirty. If container is NULL, transfer
* the object to the default (or unassigned) container.
*/
int (*transfer_object)(storage_object_t * object,
storage_container_t * container,
option_array_t * options);
/*
* Remove object from its current container. Make sure there are no
* allocated objects produced by the container that are using space in the
* object. Does not destroy segment.
*/
int (*remove_object)(storage_object_t * object);
/*
* Destroy the container. Make sure there are no allocated objects being
* produced by the container. Put your consumed objects from the
* container's objects_consumed dlist_t onto the dlist_t provided in the
* second parameter. Free any private data, then use the Engine's
* free_container() to deallocate the container object.
*/
int (*delete_container)(storage_container_t * container,
dlist_t objects_consumed);
/*
* Write any container meta data, to disk. Clear the SCFLAG_DIRTY in the
* container.
* Committing changes in done in several (two for now) phases. "phase"
* says which phase of the commit is being performed.
* Write your first copy of meta data during phase 1; write your second
* copy of meta data (if you have one) during phase 2.
*/
int (*commit_container_changes)(storage_container_t * container,
uint phase);
/*
* Return any additional information that you wish to provide about the
* container. The Engine provides an external API to get the information
* stored in the storage_container_t. This call is to get any other
* information about the container that is not specified in the
* storage_container_t. Any piece of information you wish to provide must
* be in an extended_info_t structure. Use the Engine's engine_alloc() to
* allocate the memory for the extended_info_t. Also use engine_alloc() to
* allocate any strings that may go into the extended_info_t. Then use
* engine_alloc() to allocate an extended_info_array_t with enough entries
* for the number of extended_info_t structures you are returning. Fill
* in the array and return it in *info.
* If you have extended_info_t descriptors that themselves may have more
* extended information, set the EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag
* in the extended_info_t flags field. If the caller wants more information
* about a particular extended_info_t item, this API will be called with a
* pointer to the storage_container_t and with a pointer to the name of the
* extended_info_t item. In that case, return an extended_info_array_t with
* further information about the item. Each of those items may have the
* EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE flag set if you desire. It is your
* responsibility to give the items unique names so that you know which item
* the caller is asking additional information for. If info_name is NULL,
* the caller just wants top level information about the object.
*/
int (*get_container_info)(storage_container_t * container,
char * info_name,
extended_info_array_t * * info);
/*
* Apply the settings of the options to the given container.
*/
int (*set_container_info)(storage_container_t * container,
option_array_t * options);
} container_functions_t;
#endif
|